From c0dba8197058d32fce1f10677157b6fb57af92c5 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 23 Dec 2015 13:32:40 -0500 Subject: [PATCH 0001/1644] CF-960 Use StartablePort interface to support programmatic start/stop of BurstIO ports --- .../src/java/burstio/BurstIn.java.template | 14 ++++++++++++-- burstioInterfaces/src/java/burstio/InPort.java | 2 -- burstioInterfaces/src/java/burstio/OutPort.java | 14 ++++++++++++-- 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/burstioInterfaces/src/java/burstio/BurstIn.java.template b/burstioInterfaces/src/java/burstio/BurstIn.java.template index 1929b8b76..53d303cc8 100644 --- a/burstioInterfaces/src/java/burstio/BurstIn.java.template +++ b/burstioInterfaces/src/java/burstio/BurstIn.java.template @@ -7,9 +7,9 @@ package burstio; import burstio.traits.@name@Traits; -import org.ossie.component.PortBase; +import org.ossie.component.StartablePort; -public class Burst@name@In extends BURSTIO.jni.burst@name@POA implements InPort, PortBase +public class Burst@name@In extends BURSTIO.jni.burst@name@POA implements InPort, StartablePort { private final InPortImpl impl_; @@ -23,6 +23,16 @@ public class Burst@name@In extends BURSTIO.jni.burst@name@POA implements InPort< return this.impl_.getName(); } + public void startPort () + { + start(); + } + + public void stopPort () + { + stop(); + } + public void start () { this.impl_.start(); diff --git a/burstioInterfaces/src/java/burstio/InPort.java b/burstioInterfaces/src/java/burstio/InPort.java index cf20861f5..16c2f74e7 100644 --- a/burstioInterfaces/src/java/burstio/InPort.java +++ b/burstioInterfaces/src/java/burstio/InPort.java @@ -19,8 +19,6 @@ */ package burstio; -import org.ossie.component.PortBase; - public interface InPort { diff --git a/burstioInterfaces/src/java/burstio/OutPort.java b/burstioInterfaces/src/java/burstio/OutPort.java index f09d9aac2..66c66a3e1 100644 --- a/burstioInterfaces/src/java/burstio/OutPort.java +++ b/burstioInterfaces/src/java/burstio/OutPort.java @@ -33,15 +33,15 @@ import org.apache.log4j.Logger; +import org.ossie.component.StartablePort; import org.ossie.properties.IProperty; import org.ossie.properties.StructDef; import burstio.stats.SenderStatistics; import burstio.traits.BurstTraits; -import org.ossie.component.PortBase; -abstract class OutPort extends BULKIO.UsesPortStatisticsProviderPOA implements PortBase { +abstract class OutPort extends BULKIO.UsesPortStatisticsProviderPOA implements StartablePort { public static final int DEFAULT_MAX_BURSTS = 100; public static final int DEFAULT_LATENCY_THRESHOLD = 10000; // 10000 us = 10ms @@ -444,6 +444,11 @@ public synchronized void start () this.running_ = true; } + public void startPort () + { + start(); + } + public void stop () { synchronized (this) { @@ -456,6 +461,11 @@ public void stop () this.flush(); } + public void stopPort () + { + stop(); + } + public BULKIO.PortUsageType state () { synchronized (this.connections_) { From a424ad9f63c059da062ddfc91efe2147bf1e727c Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 30 Dec 2015 16:55:45 -0500 Subject: [PATCH 0002/1644] Use the IDL constant for direction for Java ports --- .../src/java/burstio/BurstIn.java.template | 18 +++++++++--------- .../src/java/burstio/OutPort.java | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/burstioInterfaces/src/java/burstio/BurstIn.java.template b/burstioInterfaces/src/java/burstio/BurstIn.java.template index 53d303cc8..2a8f038e2 100644 --- a/burstioInterfaces/src/java/burstio/BurstIn.java.template +++ b/burstioInterfaces/src/java/burstio/BurstIn.java.template @@ -98,13 +98,13 @@ public class Burst@name@In extends BURSTIO.jni.burst@name@POA implements InPort< this.impl_.flush(); } - public String getRepid () - { - return BURSTIO.burst@name@Helper.id(); - } - - public String getDirection () - { - return "Provides"; - } + public String getRepid () + { + return BURSTIO.burst@name@Helper.id(); + } + + public String getDirection () + { + return CF.PortSet.DIRECTION_PROVIDES; + } } diff --git a/burstioInterfaces/src/java/burstio/OutPort.java b/burstioInterfaces/src/java/burstio/OutPort.java index 66c66a3e1..4588bf1aa 100644 --- a/burstioInterfaces/src/java/burstio/OutPort.java +++ b/burstioInterfaces/src/java/burstio/OutPort.java @@ -538,7 +538,7 @@ public String getRepid () public String getDirection () { - return "Uses"; + return CF.PortSet.DIRECTION_USES; } protected void sendBursts(B[] bursts, long startTime, float queueDepth, final String streamID) From 8878525ccdf2de7ec7589070472ce4d5918c52ff Mon Sep 17 00:00:00 2001 From: Ryan Bauman Date: Fri, 18 Mar 2016 14:18:27 -0400 Subject: [PATCH 0003/1644] CF-1443 RELENG-401 - adjust release field for 2.0.1-rc1 --- burstioInterfaces/burstioInterfaces.spec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/burstioInterfaces/burstioInterfaces.spec b/burstioInterfaces/burstioInterfaces.spec index bc995892b..0fb1b2ab2 100644 --- a/burstioInterfaces/burstioInterfaces.spec +++ b/burstioInterfaces/burstioInterfaces.spec @@ -28,8 +28,8 @@ Prefix: %{_prefix} %bcond_without java Name: burstioInterfaces -Version: 2.0.4 -Release: 1%{?dist} +Version: 2.0.1 +Release: 2%{?dist} Summary: BURSTIO interfaces for REDHAWK Group: Applications/Engineering From 3677f9f9155068d21a620389a61adf629a3dc158 Mon Sep 17 00:00:00 2001 From: Ryan Bauman Date: Tue, 16 Aug 2016 11:09:34 -0400 Subject: [PATCH 0004/1644] RELENG-433 - update development versions --- burstioInterfaces/burstioInterfaces.spec | 4 ++-- burstioInterfaces/configure.ac | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/burstioInterfaces/burstioInterfaces.spec b/burstioInterfaces/burstioInterfaces.spec index 0fb1b2ab2..186613453 100644 --- a/burstioInterfaces/burstioInterfaces.spec +++ b/burstioInterfaces/burstioInterfaces.spec @@ -28,8 +28,8 @@ Prefix: %{_prefix} %bcond_without java Name: burstioInterfaces -Version: 2.0.1 -Release: 2%{?dist} +Version: 2.1.0 +Release: 1%{?dist} Summary: BURSTIO interfaces for REDHAWK Group: Applications/Engineering diff --git a/burstioInterfaces/configure.ac b/burstioInterfaces/configure.ac index 355075d31..ef318307b 100644 --- a/burstioInterfaces/configure.ac +++ b/burstioInterfaces/configure.ac @@ -18,7 +18,7 @@ # along with this program. If not, see http://www.gnu.org/licenses/. # -AC_INIT(burstio, 2.0.4) +AC_INIT(burstio, 2.1.0) AC_CONFIG_SRCDIR([src/cpp/Makefile.am]) AC_CONFIG_MACRO_DIR([m4]) @@ -42,7 +42,7 @@ fi AC_LANG_PUSH([C++]) PKG_CHECK_MODULES([OMNIORB], [omniORB4 >= 4.1.0]) -PKG_CHECK_MODULES(OSSIE, ossie >= 2.0.4,,exit) +PKG_CHECK_MODULES(OSSIE, ossie >= 2.1.0,,exit) RH_PKG_IDLDIR([OSSIE], [ossie]) PKG_CHECK_MODULES([BULKIO], [bulkioInterfaces >= 2.0]) From 9d91cd42a2f395ff08b2b1c3c4cf635ffd10b3f8 Mon Sep 17 00:00:00 2001 From: Ryan Bauman Date: Fri, 16 Sep 2016 10:37:49 -0400 Subject: [PATCH 0005/1644] CF-1566 - Allow acceptance of Java 8 source code --- burstioInterfaces/configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/burstioInterfaces/configure.ac b/burstioInterfaces/configure.ac index ef318307b..f65f11b35 100644 --- a/burstioInterfaces/configure.ac +++ b/burstioInterfaces/configure.ac @@ -60,7 +60,7 @@ AC_ARG_ENABLE([java], AS_HELP_STRING([--disable-java], [Disable java support])) HAVE_JAVASUPPORT=no if test "x$enable_java" != "xno"; then # configure was run with java enabled - java_source_version=1.6 + java_source_version=1.8 RH_JAVA_HOME RH_PROG_JAVAC([$java_source_version]) From d84f7128efd2f6744e459f3bb0cce953b134c85c Mon Sep 17 00:00:00 2001 From: Ryan Bauman Date: Thu, 22 Oct 2015 12:35:10 -0400 Subject: [PATCH 0006/1644] Bump RPM release field --- bulkioInterfaces/bulkioInterfaces.spec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bulkioInterfaces/bulkioInterfaces.spec b/bulkioInterfaces/bulkioInterfaces.spec index 28de886ae..c145aad28 100644 --- a/bulkioInterfaces/bulkioInterfaces.spec +++ b/bulkioInterfaces/bulkioInterfaces.spec @@ -28,8 +28,8 @@ Prefix: %{_prefix} %bcond_without java Name: bulkioInterfaces -Version: 2.0.4 -Release: 1%{?dist} +Version: 2.0.0 +Release: 5%{?dist} Summary: The bulkio library for REDHAWK Group: Applications/Engineering From 78c40ea0ea9bece38a7b4d7483bec9d49714d05a Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 30 Dec 2015 16:52:17 -0500 Subject: [PATCH 0007/1644] Use the IDL constant for direction for Java ports --- bulkioInterfaces/libsrc/java/src/bulkio/InDoublePort.java | 2 +- bulkioInterfaces/libsrc/java/src/bulkio/InFilePort.java | 2 +- bulkioInterfaces/libsrc/java/src/bulkio/InFloatPort.java | 2 +- bulkioInterfaces/libsrc/java/src/bulkio/InInt16Port.java | 2 +- bulkioInterfaces/libsrc/java/src/bulkio/InInt32Port.java | 2 +- bulkioInterfaces/libsrc/java/src/bulkio/InInt64Port.java | 2 +- bulkioInterfaces/libsrc/java/src/bulkio/InInt8Port.java | 2 +- bulkioInterfaces/libsrc/java/src/bulkio/InSDDSPort.java | 2 +- bulkioInterfaces/libsrc/java/src/bulkio/InUInt16Port.java | 2 +- bulkioInterfaces/libsrc/java/src/bulkio/InUInt32Port.java | 2 +- bulkioInterfaces/libsrc/java/src/bulkio/InUInt64Port.java | 2 +- bulkioInterfaces/libsrc/java/src/bulkio/InUInt8Port.java | 2 +- bulkioInterfaces/libsrc/java/src/bulkio/InVITA49Port.java | 2 +- bulkioInterfaces/libsrc/java/src/bulkio/InXMLPort.java | 2 +- bulkioInterfaces/libsrc/java/src/bulkio/OutPortBase.java | 2 +- 15 files changed, 15 insertions(+), 15 deletions(-) diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/InDoublePort.java b/bulkioInterfaces/libsrc/java/src/bulkio/InDoublePort.java index 113f9a64e..b50f3e1ba 100644 --- a/bulkioInterfaces/libsrc/java/src/bulkio/InDoublePort.java +++ b/bulkioInterfaces/libsrc/java/src/bulkio/InDoublePort.java @@ -521,7 +521,7 @@ public String getRepid() public String getDirection() { - return "Provides"; + return CF.PortSet.DIRECTION_PROVIDES; } } diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/InFilePort.java b/bulkioInterfaces/libsrc/java/src/bulkio/InFilePort.java index 11fdc8896..ea30be8f5 100644 --- a/bulkioInterfaces/libsrc/java/src/bulkio/InFilePort.java +++ b/bulkioInterfaces/libsrc/java/src/bulkio/InFilePort.java @@ -518,7 +518,7 @@ public Packet getPacket(long wait) } public String getDirection() { - return "Provides"; + return CF.PortSet.DIRECTION_PROVIDES; } public String getRepid() { diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/InFloatPort.java b/bulkioInterfaces/libsrc/java/src/bulkio/InFloatPort.java index 449abd9e2..2825f84a3 100644 --- a/bulkioInterfaces/libsrc/java/src/bulkio/InFloatPort.java +++ b/bulkioInterfaces/libsrc/java/src/bulkio/InFloatPort.java @@ -527,7 +527,7 @@ public String getRepid() public String getDirection() { - return "Provides"; + return CF.PortSet.DIRECTION_PROVIDES; } } diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/InInt16Port.java b/bulkioInterfaces/libsrc/java/src/bulkio/InInt16Port.java index 55222be69..98ea7558b 100644 --- a/bulkioInterfaces/libsrc/java/src/bulkio/InInt16Port.java +++ b/bulkioInterfaces/libsrc/java/src/bulkio/InInt16Port.java @@ -514,7 +514,7 @@ public String getRepid() public String getDirection() { - return "Provides"; + return CF.PortSet.DIRECTION_PROVIDES; } } diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/InInt32Port.java b/bulkioInterfaces/libsrc/java/src/bulkio/InInt32Port.java index 4664f5cfb..3f0978dab 100644 --- a/bulkioInterfaces/libsrc/java/src/bulkio/InInt32Port.java +++ b/bulkioInterfaces/libsrc/java/src/bulkio/InInt32Port.java @@ -519,7 +519,7 @@ public String getRepid() public String getDirection() { - return "Provides"; + return CF.PortSet.DIRECTION_PROVIDES; } } diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/InInt64Port.java b/bulkioInterfaces/libsrc/java/src/bulkio/InInt64Port.java index a6923e32c..b0b846d57 100644 --- a/bulkioInterfaces/libsrc/java/src/bulkio/InInt64Port.java +++ b/bulkioInterfaces/libsrc/java/src/bulkio/InInt64Port.java @@ -519,7 +519,7 @@ public String getRepid() public String getDirection() { - return "Provides"; + return CF.PortSet.DIRECTION_PROVIDES; } } diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/InInt8Port.java b/bulkioInterfaces/libsrc/java/src/bulkio/InInt8Port.java index ce4631701..023cc52a3 100644 --- a/bulkioInterfaces/libsrc/java/src/bulkio/InInt8Port.java +++ b/bulkioInterfaces/libsrc/java/src/bulkio/InInt8Port.java @@ -524,7 +524,7 @@ public String getRepid() public String getDirection() { - return "Provides"; + return CF.PortSet.DIRECTION_PROVIDES; } } diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/InSDDSPort.java b/bulkioInterfaces/libsrc/java/src/bulkio/InSDDSPort.java index 05ceca48f..e3be266fd 100644 --- a/bulkioInterfaces/libsrc/java/src/bulkio/InSDDSPort.java +++ b/bulkioInterfaces/libsrc/java/src/bulkio/InSDDSPort.java @@ -453,7 +453,7 @@ public String getRepid() public String getDirection() { - return "Provides"; + return CF.PortSet.DIRECTION_PROVIDES; } } diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/InUInt16Port.java b/bulkioInterfaces/libsrc/java/src/bulkio/InUInt16Port.java index 077f13f2c..bfcb20f87 100644 --- a/bulkioInterfaces/libsrc/java/src/bulkio/InUInt16Port.java +++ b/bulkioInterfaces/libsrc/java/src/bulkio/InUInt16Port.java @@ -514,7 +514,7 @@ public String getRepid() public String getDirection() { - return "Provides"; + return CF.PortSet.DIRECTION_PROVIDES; } } diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/InUInt32Port.java b/bulkioInterfaces/libsrc/java/src/bulkio/InUInt32Port.java index 53119a7e1..4634abf5c 100644 --- a/bulkioInterfaces/libsrc/java/src/bulkio/InUInt32Port.java +++ b/bulkioInterfaces/libsrc/java/src/bulkio/InUInt32Port.java @@ -518,7 +518,7 @@ public String getRepid() public String getDirection() { - return "Provides"; + return CF.PortSet.DIRECTION_PROVIDES; } } diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/InUInt64Port.java b/bulkioInterfaces/libsrc/java/src/bulkio/InUInt64Port.java index 7c26a048d..d17e7d4d4 100644 --- a/bulkioInterfaces/libsrc/java/src/bulkio/InUInt64Port.java +++ b/bulkioInterfaces/libsrc/java/src/bulkio/InUInt64Port.java @@ -519,7 +519,7 @@ public String getRepid() public String getDirection() { - return "Provides"; + return CF.PortSet.DIRECTION_PROVIDES; } } diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/InUInt8Port.java b/bulkioInterfaces/libsrc/java/src/bulkio/InUInt8Port.java index c341bc130..f514ed780 100644 --- a/bulkioInterfaces/libsrc/java/src/bulkio/InUInt8Port.java +++ b/bulkioInterfaces/libsrc/java/src/bulkio/InUInt8Port.java @@ -528,7 +528,7 @@ public String getRepid() public String getDirection() { - return "Provides"; + return CF.PortSet.DIRECTION_PROVIDES; } } diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/InVITA49Port.java b/bulkioInterfaces/libsrc/java/src/bulkio/InVITA49Port.java index 203340517..0dce296e8 100644 --- a/bulkioInterfaces/libsrc/java/src/bulkio/InVITA49Port.java +++ b/bulkioInterfaces/libsrc/java/src/bulkio/InVITA49Port.java @@ -453,7 +453,7 @@ public String getRepid() public String getDirection() { - return "Provides"; + return CF.PortSet.DIRECTION_PROVIDES; } } diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/InXMLPort.java b/bulkioInterfaces/libsrc/java/src/bulkio/InXMLPort.java index 22708341d..e0d30df30 100644 --- a/bulkioInterfaces/libsrc/java/src/bulkio/InXMLPort.java +++ b/bulkioInterfaces/libsrc/java/src/bulkio/InXMLPort.java @@ -518,7 +518,7 @@ public String getRepid() public String getDirection() { - return "Provides"; + return CF.PortSet.DIRECTION_PROVIDES; } } diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/OutPortBase.java b/bulkioInterfaces/libsrc/java/src/bulkio/OutPortBase.java index 286359dfa..69a43ccc8 100644 --- a/bulkioInterfaces/libsrc/java/src/bulkio/OutPortBase.java +++ b/bulkioInterfaces/libsrc/java/src/bulkio/OutPortBase.java @@ -208,6 +208,6 @@ public String getRepid() public String getDirection() { - return "Uses"; + return CF.PortSet.DIRECTION_USES; } } From e50b2a3345af22bb046b7fffa5f8f68dfd38591d Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 31 Dec 2015 08:44:26 -0500 Subject: [PATCH 0008/1644] Generate Java input port implementations using sed and a template file, so that all input ports are consistent and maintenance is simplified --- bulkioInterfaces/libsrc/Makefile.am | 31 +- bulkioInterfaces/libsrc/java/sed/Double.sed | 3 + bulkioInterfaces/libsrc/java/sed/Float.sed | 3 + bulkioInterfaces/libsrc/java/sed/Int16.sed | 3 + bulkioInterfaces/libsrc/java/sed/Int32.sed | 3 + bulkioInterfaces/libsrc/java/sed/Int64.sed | 3 + bulkioInterfaces/libsrc/java/sed/Int8.sed | 3 + bulkioInterfaces/libsrc/java/sed/UInt16.sed | 3 + bulkioInterfaces/libsrc/java/sed/UInt32.sed | 3 + bulkioInterfaces/libsrc/java/sed/UInt64.sed | 3 + bulkioInterfaces/libsrc/java/sed/UInt8.sed | 3 + .../libsrc/java/src/bulkio/.gitignore | 10 + .../libsrc/java/src/bulkio/InDoublePort.java | 528 ----------------- .../libsrc/java/src/bulkio/InFloatPort.java | 534 ----------------- .../libsrc/java/src/bulkio/InInt16Port.java | 520 ----------------- .../libsrc/java/src/bulkio/InInt32Port.java | 526 ----------------- .../libsrc/java/src/bulkio/InInt64Port.java | 526 ----------------- .../libsrc/java/src/bulkio/InInt8Port.java | 531 ----------------- ...InUInt64Port.java => InPort.java.template} | 30 +- .../libsrc/java/src/bulkio/InUInt16Port.java | 521 ----------------- .../libsrc/java/src/bulkio/InUInt32Port.java | 525 ----------------- .../libsrc/java/src/bulkio/InUInt8Port.java | 535 ------------------ 22 files changed, 76 insertions(+), 4771 deletions(-) create mode 100644 bulkioInterfaces/libsrc/java/sed/Double.sed create mode 100644 bulkioInterfaces/libsrc/java/sed/Float.sed create mode 100644 bulkioInterfaces/libsrc/java/sed/Int16.sed create mode 100644 bulkioInterfaces/libsrc/java/sed/Int32.sed create mode 100644 bulkioInterfaces/libsrc/java/sed/Int64.sed create mode 100644 bulkioInterfaces/libsrc/java/sed/Int8.sed create mode 100644 bulkioInterfaces/libsrc/java/sed/UInt16.sed create mode 100644 bulkioInterfaces/libsrc/java/sed/UInt32.sed create mode 100644 bulkioInterfaces/libsrc/java/sed/UInt64.sed create mode 100644 bulkioInterfaces/libsrc/java/sed/UInt8.sed create mode 100644 bulkioInterfaces/libsrc/java/src/bulkio/.gitignore delete mode 100644 bulkioInterfaces/libsrc/java/src/bulkio/InDoublePort.java delete mode 100644 bulkioInterfaces/libsrc/java/src/bulkio/InFloatPort.java delete mode 100644 bulkioInterfaces/libsrc/java/src/bulkio/InInt16Port.java delete mode 100644 bulkioInterfaces/libsrc/java/src/bulkio/InInt32Port.java delete mode 100644 bulkioInterfaces/libsrc/java/src/bulkio/InInt64Port.java delete mode 100644 bulkioInterfaces/libsrc/java/src/bulkio/InInt8Port.java rename bulkioInterfaces/libsrc/java/src/bulkio/{InUInt64Port.java => InPort.java.template} (94%) delete mode 100644 bulkioInterfaces/libsrc/java/src/bulkio/InUInt16Port.java delete mode 100644 bulkioInterfaces/libsrc/java/src/bulkio/InUInt32Port.java delete mode 100644 bulkioInterfaces/libsrc/java/src/bulkio/InUInt8Port.java diff --git a/bulkioInterfaces/libsrc/Makefile.am b/bulkioInterfaces/libsrc/Makefile.am index d0c0876f9..65677bc33 100644 --- a/bulkioInterfaces/libsrc/Makefile.am +++ b/bulkioInterfaces/libsrc/Makefile.am @@ -112,23 +112,13 @@ JAVA_SRCDIR := $(JAVA_DIR)/src JAVA_SRCS := Const.java \ DataTransfer.java \ InCharPort.java \ -InDoublePort.java \ InFilePort.java \ -InFloatPort.java \ -InInt16Port.java \ -InInt32Port.java \ -InInt64Port.java \ -InInt8Port.java \ InLongLongPort.java \ InLongPort.java \ InOctetPort.java \ InSDDSPort.java \ InVITA49Port.java \ InShortPort.java \ -InUInt16Port.java \ -InUInt32Port.java \ -InUInt64Port.java \ -InUInt8Port.java \ InULongLongPort.java \ InULongPort.java \ InUShortPort.java \ @@ -179,10 +169,26 @@ time/Comparator.java \ time/DefaultComparator.java \ time/utils.java +# Input ports are generated via sed for ease of maintenance +$(JAVA_SRCDIR)/bulkio/In%Port.java : $(JAVA_DIR)/sed/%.sed $(JAVA_SRCDIR)/bulkio/InPort.java.template + $(AM_V_GEN)sed -f $< $(JAVA_SRCDIR)/bulkio/InPort.java.template > $@ + +JAVA_BUILT_SOURCE = $(JAVA_SRCDIR)/bulkio/InDoublePort.java +JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/InFloatPort.java +JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/InInt16Port.java +JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/InInt32Port.java +JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/InInt64Port.java +JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/InInt8Port.java +JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/InUInt16Port.java +JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/InUInt32Port.java +JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/InUInt64Port.java +JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/InUInt8Port.java + + java_JARFILES = bulkio.jar java_DATA = bulkio.src.jar -bulkio_jar_SOURCE = $(addprefix $(JAVA_SRCDIR)/bulkio/,$(JAVA_SRCS)) +bulkio_jar_SOURCE = $(addprefix $(JAVA_SRCDIR)/bulkio/,$(JAVA_SRCS)) $(JAVA_BUILT_SOURCE) bulkio_jar_CLASSPATH = $(OSSIE_CLASSPATH):$(top_builddir)/BULKIOInterfaces.jar bulkio_jar_MANIFEST = $(JAVA_DIR)/META-INF/MANIFEST.MF @@ -191,7 +197,8 @@ bulkio.jar: $(top_builddir)/BULKIOInterfaces.jar bulkio.src.jar: $(JAVA_DIR)/META-INF/MANIFEST.MF.src $(bulkio_jar_SOURCE) $(RH_V_JAR)$(JAR) cmf $< $@ -C $(JAVA_SRCDIR) . -CLEANFILES = bulkio.src.jar +BUILT_SOURCES = $(JAVA_BUILT_SOURCE) +CLEANFILES = bulkio.src.jar $(BUILT_SOURCES) endif diff --git a/bulkioInterfaces/libsrc/java/sed/Double.sed b/bulkioInterfaces/libsrc/java/sed/Double.sed new file mode 100644 index 000000000..07d55f6b0 --- /dev/null +++ b/bulkioInterfaces/libsrc/java/sed/Double.sed @@ -0,0 +1,3 @@ +s/@name@/Double/g +s/@type@/double/g +s/@idl@/dataDouble/g diff --git a/bulkioInterfaces/libsrc/java/sed/Float.sed b/bulkioInterfaces/libsrc/java/sed/Float.sed new file mode 100644 index 000000000..f5c59c51c --- /dev/null +++ b/bulkioInterfaces/libsrc/java/sed/Float.sed @@ -0,0 +1,3 @@ +s/@name@/Float/g +s/@type@/float/g +s/@idl@/dataFloat/g diff --git a/bulkioInterfaces/libsrc/java/sed/Int16.sed b/bulkioInterfaces/libsrc/java/sed/Int16.sed new file mode 100644 index 000000000..64612fec2 --- /dev/null +++ b/bulkioInterfaces/libsrc/java/sed/Int16.sed @@ -0,0 +1,3 @@ +s/@name@/Int16/g +s/@type@/short/g +s/@idl@/dataShort/g diff --git a/bulkioInterfaces/libsrc/java/sed/Int32.sed b/bulkioInterfaces/libsrc/java/sed/Int32.sed new file mode 100644 index 000000000..e2473aa1b --- /dev/null +++ b/bulkioInterfaces/libsrc/java/sed/Int32.sed @@ -0,0 +1,3 @@ +s/@name@/Int32/g +s/@type@/int/g +s/@idl@/dataLong/g diff --git a/bulkioInterfaces/libsrc/java/sed/Int64.sed b/bulkioInterfaces/libsrc/java/sed/Int64.sed new file mode 100644 index 000000000..d04501e0b --- /dev/null +++ b/bulkioInterfaces/libsrc/java/sed/Int64.sed @@ -0,0 +1,3 @@ +s/@name@/Int64/g +s/@type@/long/g +s/@idl@/dataLongLong/g diff --git a/bulkioInterfaces/libsrc/java/sed/Int8.sed b/bulkioInterfaces/libsrc/java/sed/Int8.sed new file mode 100644 index 000000000..446b19c29 --- /dev/null +++ b/bulkioInterfaces/libsrc/java/sed/Int8.sed @@ -0,0 +1,3 @@ +s/@name@/Int8/g +s/@type@/char/g +s/@idl@/dataChar/g diff --git a/bulkioInterfaces/libsrc/java/sed/UInt16.sed b/bulkioInterfaces/libsrc/java/sed/UInt16.sed new file mode 100644 index 000000000..4ba66acd9 --- /dev/null +++ b/bulkioInterfaces/libsrc/java/sed/UInt16.sed @@ -0,0 +1,3 @@ +s/@name@/UInt16/g +s/@type@/short/g +s/@idl@/dataUshort/g diff --git a/bulkioInterfaces/libsrc/java/sed/UInt32.sed b/bulkioInterfaces/libsrc/java/sed/UInt32.sed new file mode 100644 index 000000000..6bb5cd070 --- /dev/null +++ b/bulkioInterfaces/libsrc/java/sed/UInt32.sed @@ -0,0 +1,3 @@ +s/@name@/UInt32/g +s/@type@/int/g +s/@idl@/dataUlong/g diff --git a/bulkioInterfaces/libsrc/java/sed/UInt64.sed b/bulkioInterfaces/libsrc/java/sed/UInt64.sed new file mode 100644 index 000000000..da2d78671 --- /dev/null +++ b/bulkioInterfaces/libsrc/java/sed/UInt64.sed @@ -0,0 +1,3 @@ +s/@name@/UInt64/g +s/@type@/long/g +s/@idl@/dataUlongLong/g diff --git a/bulkioInterfaces/libsrc/java/sed/UInt8.sed b/bulkioInterfaces/libsrc/java/sed/UInt8.sed new file mode 100644 index 000000000..244f86243 --- /dev/null +++ b/bulkioInterfaces/libsrc/java/sed/UInt8.sed @@ -0,0 +1,3 @@ +s/@name@/UInt8/g +s/@type@/byte/g +s/@idl@/dataOctet/g diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/.gitignore b/bulkioInterfaces/libsrc/java/src/bulkio/.gitignore new file mode 100644 index 000000000..244973867 --- /dev/null +++ b/bulkioInterfaces/libsrc/java/src/bulkio/.gitignore @@ -0,0 +1,10 @@ +InDoublePort.java +InFloatPort.java +InInt16Port.java +InInt32Port.java +InInt64Port.java +InInt8Port.java +InUInt16Port.java +InUInt32Port.java +InUInt64Port.java +InUInt8Port.java diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/InDoublePort.java b/bulkioInterfaces/libsrc/java/src/bulkio/InDoublePort.java deleted file mode 100644 index b50f3e1ba..000000000 --- a/bulkioInterfaces/libsrc/java/src/bulkio/InDoublePort.java +++ /dev/null @@ -1,528 +0,0 @@ -/* - * This file is protected by Copyright. Please refer to the COPYRIGHT file - * distributed with this source distribution. - * - * This file is part of REDHAWK bulkioInterfaces. - * - * REDHAWK bulkioInterfaces is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * REDHAWK bulkioInterfaces is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see http://www.gnu.org/licenses/. - */ -package bulkio; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Iterator; -import java.util.Map; -import org.omg.CORBA.TCKind; -import org.ossie.properties.AnyUtils; -import CF.DataType; -import java.util.ArrayDeque; -import java.util.concurrent.Semaphore; -import java.util.concurrent.TimeUnit; -import BULKIO.PrecisionUTCTime; -import BULKIO.StreamSRI; -import BULKIO.PortStatistics; -import BULKIO.PortUsageType; -import org.apache.log4j.Logger; - -import bulkio.sriState; -import bulkio.linkStatistics; -import bulkio.DataTransfer; -import bulkio.DoubleSize; - -import org.ossie.component.PortBase; - -/** - * - */ -public class InDoublePort extends BULKIO.jni.dataDoublePOA implements org.ossie.component.PortBase { - - /** - * A class to hold packet data. - * - */ - public class Packet extends DataTransfer < double[] > { - - public Packet(double[] data, PrecisionUTCTime time, boolean endOfStream, String streamID, StreamSRI H, boolean sriChanged, boolean inputQueueFlushed ) { - super(data,time,endOfStream,streamID,H,sriChanged,inputQueueFlushed); - }; - }; - - /** - * - */ - protected String name; - - /** - * - */ - protected linkStatistics stats; - - /** - * - */ - protected Object sriUpdateLock; - - /** - * - */ - protected Object statUpdateLock; - - /** - * - */ - protected Map currentHs; - - /** - * - */ - protected Object dataBufferLock; - - /** - * - */ - protected int maxQueueDepth; - - /** - * - */ - protected Semaphore queueSem; - - /** - * - */ - protected Semaphore dataSem; - - /** - * - */ - protected boolean blocking; - - - protected bulkio.sri.Comparator sri_cmp; - - protected bulkio.SriListener sriCallback; - - - protected Logger logger = null; - - - /** - * This queue stores all packets received from pushPacket. - * - */ - private ArrayDeque< Packet > workQueue; - - - - /** - * - */ - public InDoublePort( String portName ) { - this( portName, null, new bulkio.sri.DefaultComparator(), null ); - } - - public InDoublePort( String portName, bulkio.sri.Comparator compareSRI ) { - this( portName, null, compareSRI, null ); - } - - public InDoublePort( String portName, - bulkio.sri.Comparator compareSRI, - bulkio.SriListener sriCallback - ) { - this( portName, null, compareSRI, null ); - } - - public InDoublePort( String portName, Logger logger ) { - this( portName, logger, new bulkio.sri.DefaultComparator(), null ); - } - - public InDoublePort( String portName, - Logger logger, - bulkio.sri.Comparator compareSRI, - bulkio.SriListener sriCallback ) { - - this.name = portName; - this.logger = logger; - this.stats = new linkStatistics(this.name, new DoubleSize() ); - this.sriUpdateLock = new Object(); - this.statUpdateLock = new Object(); - this.currentHs = new HashMap(); - this.dataBufferLock = new Object(); - this.maxQueueDepth = 100; - this.queueSem = new Semaphore(this.maxQueueDepth); - this.dataSem = new Semaphore(0); - this.blocking = false; - - this.workQueue = new ArrayDeque< Packet >(); - - sri_cmp = compareSRI; - sriCallback = sriCallback; - - if ( this.logger != null ) { - this.logger.debug( "bulkio::InPort CTOR port: " + portName ); - } - - } - - public void setLogger( Logger newlogger ){ - synchronized (this.sriUpdateLock) { - logger = newlogger; - } - } - - - - /** - * - */ - public void setSriListener( bulkio.SriListener sriCallback ) { - synchronized(this.sriUpdateLock) { - this.sriCallback = sriCallback; - } - } - - /** - * - */ - public String getName() { - return this.name; - } - - /** - * - */ - public void enableStats(boolean enable) { - this.stats.setEnabled(enable); - } - - /** - * - */ - public PortStatistics statistics() { - synchronized (statUpdateLock) { - return this.stats.retrieve(); - } - } - - /** - * - */ - public PortUsageType state() { - int queueSize = 0; - synchronized (dataBufferLock) { - queueSize = workQueue.size(); - if (queueSize == maxQueueDepth) { - return PortUsageType.BUSY; - } else if (queueSize == 0) { - return PortUsageType.IDLE; - } - return PortUsageType.ACTIVE; - } - } - - /** - * - */ - public StreamSRI[] activeSRIs() { - synchronized (this.sriUpdateLock) { - ArrayList sris = new ArrayList(); - Iterator iter = this.currentHs.values().iterator(); - while(iter.hasNext()) { - sris.add(iter.next().getSRI()); - } - return sris.toArray(new StreamSRI[sris.size()]); - } - } - - /** - * - */ - public int getCurrentQueueDepth() { - synchronized (this.dataBufferLock) { - return workQueue.size(); - } - } - - /** - * - */ - public int getMaxQueueDepth() { - synchronized (this.dataBufferLock) { - return this.maxQueueDepth; - } - } - - /** - * - */ - public void setMaxQueueDepth(int newDepth) { - synchronized (this.dataBufferLock) { - this.maxQueueDepth = newDepth; - queueSem = new Semaphore(newDepth); - } - } - - - /** - * - */ - public void pushSRI(StreamSRI header) { - - if ( logger != null ) { - logger.trace("bulkio.InPort pushSRI ENTER (port=" + name +")" ); - } - - synchronized (sriUpdateLock) { - if (!currentHs.containsKey(header.streamID)) { - if ( logger != null ) { - logger.debug("pushSRI PORT:" + name + " NEW SRI:" + - header.streamID ); - } - if ( sriCallback != null ) { sriCallback.newSRI(header); } - currentHs.put(header.streamID, new sriState(header, true)); - if (header.blocking) { - //If switching to blocking we have to set the semaphore - synchronized (dataBufferLock) { - if (!blocking) { - try { - queueSem.acquire(workQueue.size()); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - blocking = true; - } - } - } else { - StreamSRI oldSri = currentHs.get(header.streamID).getSRI(); - boolean cval = false; - if ( sri_cmp != null ) { - cval = sri_cmp.compare( header, oldSri ); - } - if ( cval == false ) { - if ( sriCallback != null ) { sriCallback.changedSRI(header); } - this.currentHs.put(header.streamID, new sriState(header, true)); - if (header.blocking) { - //If switching to blocking we have to set the semaphore - synchronized (dataBufferLock) { - if (!blocking) { - try { - queueSem.acquire(workQueue.size()); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - blocking = true; - } - } - } - } - } - - if ( logger != null ) { - logger.trace("bulkio.InPort pushSRI EXIT (port=" + name +")" ); - } - } - - - - /** - * - */ - public void pushPacket(double[] data, PrecisionUTCTime time, boolean eos, String streamID) - { - - if ( logger != null ) { - logger.trace("bulkio.InPort pushPacket ENTER (port=" + name +")" ); - } - - synchronized (this.dataBufferLock) { - if (this.maxQueueDepth == 0) { - if ( logger != null ) { - logger.trace("bulkio.InPort pushPacket EXIT (port=" + name +")" ); - } - return; - } - } - - boolean portBlocking = false; - StreamSRI tmpH = null; - boolean sriChanged = false; - synchronized (this.sriUpdateLock) { - if (this.currentHs.containsKey(streamID)) { - tmpH = this.currentHs.get(streamID).getSRI(); - sriChanged = this.currentHs.get(streamID).isChanged(); - if ( eos == false ) { - this.currentHs.get(streamID).setChanged(false); - } - portBlocking = blocking; - } else { - if (logger != null) { - logger.warn("bulkio.InPort pushPacket received data from stream '" + streamID + "' with no SRI"); - } - tmpH = new StreamSRI(1, 0.0, 1.0, (short)1, 0, 0.0, 0.0, (short)0, (short)0, streamID, false, new DataType[0]); - if (sriCallback != null) { - sriCallback.newSRI(tmpH); - } - sriChanged = true; - currentHs.put(streamID, new sriState(tmpH, false)); - } - } - - // determine whether to block and wait for an empty space in the queue - Packet p = null; - - if (portBlocking) { - p = new Packet(data, time, eos, streamID, tmpH, sriChanged, false); - - try { - queueSem.acquire(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - - synchronized (this.dataBufferLock) { - this.stats.update(data.length, this.workQueue.size()/(float)this.maxQueueDepth, eos, streamID, false); - this.workQueue.add(p); - this.dataSem.release(); - } - } else { - synchronized (this.dataBufferLock) { - if (this.workQueue.size() == this.maxQueueDepth) { - if ( logger != null ) { - logger.debug( "bulkio::InPort pushPacket PURGE INPUT QUEUE (SIZE" + this.workQueue.size() + ")" ); - } - boolean sriChangedHappened = false; - boolean flagEOS = false; - for (Iterator< Packet > itr = this.workQueue.iterator(); itr.hasNext();) { - if (sriChangedHappened && flagEOS) { - break; - } - Packet currentPacket = itr.next(); - if (currentPacket.sriChanged) { - sriChangedHappened = true; - } - if (currentPacket.EOS) { - flagEOS = true; - } - } - if (sriChangedHappened) { - sriChanged = true; - } - if (flagEOS) { - eos = true; - } - this.workQueue.clear(); - p = new Packet( data, time, eos, streamID, tmpH, sriChanged, true); - this.stats.update(data.length, 0, eos, streamID, true); - } else { - p = new Packet(data, time, eos, streamID, tmpH, sriChanged, false); - this.stats.update(data.length, this.workQueue.size()/(float)this.maxQueueDepth, eos, streamID, false); - } - if ( logger != null ) { - logger.trace( "bulkio::InPort pushPacket NEW Packet (QUEUE=" + workQueue.size() + ")"); - } - this.workQueue.add(p); - this.dataSem.release(); - } - } - - if ( logger != null ) { - logger.trace("bulkio.InPort pushPacket EXIT (port=" + name +")" ); - } - return; - - } - - /** - * - */ - public Packet getPacket(long wait) - { - - if ( logger != null ) { - logger.trace("bulkio.InPort getPacket ENTER (port=" + name +")" ); - } - try { - if (wait < 0) { - if ( logger != null ) { - logger.trace("bulkio.InPort getPacket PORT:" + name +" Block until data arrives" ); - } - this.dataSem.acquire(); - } else { - if ( logger != null ) { - logger.trace("bulkio.InPort getPacket PORT:" + name +" TIMED WAIT:" + wait ); - } - this.dataSem.tryAcquire(wait, TimeUnit.MILLISECONDS); - } - } catch (InterruptedException ex) { - if ( logger != null ) { - logger.trace("bulkio.InPort getPacket EXIT (port=" + name +")" ); - } - return null; - } - - Packet p = null; - synchronized (this.dataBufferLock) { - p = this.workQueue.poll(); - } - - if (p != null) { - if (p.getEndOfStream()) { - synchronized (this.sriUpdateLock) { - if (this.currentHs.containsKey(p.getStreamID())) { - sriState rem = this.currentHs.remove(p.getStreamID()); - - if (rem.getSRI().blocking) { - boolean stillBlocking = false; - Iterator iter = currentHs.values().iterator(); - while (iter.hasNext()) { - if (iter.next().getSRI().blocking) { - stillBlocking = true; - break; - } - } - - if (!stillBlocking) { - blocking = false; - } - } - } - } - } - - if (blocking) { - queueSem.release(); - } - } - - if ( logger != null ) { - logger.trace("bulkio.InPort getPacket EXIT (port=" + name +")" ); - } - return p; - } - - public String getRepid() - { - return BULKIO.dataDoubleHelper.id(); - } - - public String getDirection() - { - return CF.PortSet.DIRECTION_PROVIDES; - } - -} - diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/InFloatPort.java b/bulkioInterfaces/libsrc/java/src/bulkio/InFloatPort.java deleted file mode 100644 index 2825f84a3..000000000 --- a/bulkioInterfaces/libsrc/java/src/bulkio/InFloatPort.java +++ /dev/null @@ -1,534 +0,0 @@ -/* - * This file is protected by Copyright. Please refer to the COPYRIGHT file - * distributed with this source distribution. - * - * This file is part of REDHAWK bulkioInterfaces. - * - * REDHAWK bulkioInterfaces is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * REDHAWK bulkioInterfaces is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see http://www.gnu.org/licenses/. - */ -package bulkio; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Iterator; -import java.util.Map; -import org.omg.CORBA.TCKind; -import org.ossie.properties.AnyUtils; -import CF.DataType; -import java.util.ArrayDeque; -import java.util.concurrent.Semaphore; -import java.util.concurrent.TimeUnit; -import BULKIO.PrecisionUTCTime; -import BULKIO.StreamSRI; -import BULKIO.PortStatistics; -import BULKIO.PortUsageType; -import org.apache.log4j.Logger; - -import bulkio.sriState; -import bulkio.linkStatistics; -import bulkio.DataTransfer; -import bulkio.DoubleSize; - -import org.ossie.component.PortBase; - -/** - * - */ -public class InFloatPort extends BULKIO.jni.dataFloatPOA implements org.ossie.component.PortBase { - - /** - * A class to hold packet data. - * - */ - public class Packet extends DataTransfer < float[] > { - - public Packet(float[] data, PrecisionUTCTime time, boolean endOfStream, String streamID, StreamSRI H, boolean sriChanged, boolean inputQueueFlushed ) { - super(data,time,endOfStream,streamID,H,sriChanged,inputQueueFlushed); - }; - }; - - /** - * - */ - protected String name; - - /** - * - */ - protected linkStatistics stats; - - /** - * - */ - protected Object sriUpdateLock; - - /** - * - */ - protected Object statUpdateLock; - - /** - * - */ - protected Map currentHs; - - /** - * - */ - protected Object dataBufferLock; - - /** - * - */ - protected int maxQueueDepth; - - /** - * - */ - protected Semaphore queueSem; - - /** - * - */ - protected Semaphore dataSem; - - /** - * - */ - protected boolean blocking; - - /** - * - */ - protected Logger logger = null; - - protected bulkio.sri.Comparator sri_cmp; - - protected bulkio.SriListener sriCallback; - - - /** - * This queue stores all packets received from pushPacket. - * - */ - private ArrayDeque< Packet > workQueue; - - - - /** - * - */ - public InFloatPort( String portName ) { - this( portName, null, new bulkio.sri.DefaultComparator(), null ); - } - - public InFloatPort( String portName, - bulkio.sri.Comparator compareSRI ) { - this( portName, null, compareSRI, null ); - } - - public InFloatPort( String portName, - bulkio.sri.Comparator compareSRI, - bulkio.SriListener sriCallback - ) { - this( portName, null, compareSRI, sriCallback ); - } - - public InFloatPort( String portName, Logger logger ) { - this( portName, logger, new bulkio.sri.DefaultComparator(), null ); - } - - public InFloatPort( String portName, - Logger logger, - bulkio.sri.Comparator compareSRI, - bulkio.SriListener sriCallback ) { - - this.name = portName; - this.logger = logger; - this.stats = new linkStatistics(this.name, new FloatSize() ); - this.sriUpdateLock = new Object(); - this.statUpdateLock = new Object(); - this.currentHs = new HashMap(); - this.dataBufferLock = new Object(); - this.maxQueueDepth = 100; - this.queueSem = new Semaphore(this.maxQueueDepth); - this.dataSem = new Semaphore(0); - this.blocking = false; - - this.workQueue = new ArrayDeque< Packet >(); - - sri_cmp = compareSRI; - sriCallback = sriCallback; - - if ( this.logger != null ) { - this.logger.debug( "bulkio::InPort CTOR port: " + portName ); - } - } - - /** - * - */ - public void setSriListener( bulkio.SriListener sriCallback ) { - synchronized(this.sriUpdateLock) { - this.sriCallback = sriCallback; - } - } - - public void setLogger( Logger newlogger ){ - synchronized (this.sriUpdateLock) { - logger = newlogger; - } - } - - - - /** - * - */ - public String getName() { - return this.name; - } - - - - /** - * - */ - public void enableStats(boolean enable) { - this.stats.setEnabled(enable); - } - - /** - * - */ - public PortStatistics statistics() { - synchronized (statUpdateLock) { - return this.stats.retrieve(); - } - } - - /** - * - */ - public PortUsageType state() { - int queueSize = 0; - synchronized (dataBufferLock) { - queueSize = workQueue.size(); - if (queueSize == maxQueueDepth) { - return PortUsageType.BUSY; - } else if (queueSize == 0) { - return PortUsageType.IDLE; - } - return PortUsageType.ACTIVE; - } - } - - /** - * - */ - public StreamSRI[] activeSRIs() { - synchronized (this.sriUpdateLock) { - ArrayList sris = new ArrayList(); - Iterator iter = this.currentHs.values().iterator(); - while(iter.hasNext()) { - sris.add(iter.next().getSRI()); - } - return sris.toArray(new StreamSRI[sris.size()]); - } - } - - /** - * - */ - public int getCurrentQueueDepth() { - synchronized (this.dataBufferLock) { - return workQueue.size(); - } - } - - /** - * - */ - public int getMaxQueueDepth() { - synchronized (this.dataBufferLock) { - return this.maxQueueDepth; - } - } - - /** - * - */ - public void setMaxQueueDepth(int newDepth) { - synchronized (this.dataBufferLock) { - this.maxQueueDepth = newDepth; - queueSem = new Semaphore(newDepth); - } - } - - - /** - * - */ - public void pushSRI(StreamSRI header) { - - if ( logger != null ) { - logger.trace("bulkio.InPort pushSRI ENTER (port=" + name +")" ); - } - synchronized (sriUpdateLock) { - if (!currentHs.containsKey(header.streamID)) { - if ( logger != null ) { - logger.debug("pushSRI PORT:" + name + " NEW SRI:" + - header.streamID ); - } - if ( sriCallback != null ) { sriCallback.newSRI(header); } - currentHs.put(header.streamID, new sriState(header, true)); - if (header.blocking) { - //If switching to blocking we have to set the semaphore - synchronized (dataBufferLock) { - if (!blocking) { - try { - queueSem.acquire(workQueue.size()); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - blocking = true; - } - } - } else { - StreamSRI oldSri = currentHs.get(header.streamID).getSRI(); - boolean cval = false; - if ( sri_cmp != null ) { - cval = sri_cmp.compare( header, oldSri ); - } - if ( cval == false ) { - if ( sriCallback != null ) { sriCallback.changedSRI(header); } - this.currentHs.put(header.streamID, new sriState(header, true)); - if (header.blocking) { - //If switching to blocking we have to set the semaphore - synchronized (dataBufferLock) { - if (!blocking) { - try { - queueSem.acquire(workQueue.size()); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - blocking = true; - } - } - } - } - } - if ( logger != null ) { - logger.trace("bulkio.InPort pushSRI EXIT (port=" + name +")" ); - } - } - - - - /** - * - */ - public void pushPacket(float[] data, PrecisionUTCTime time, boolean eos, String streamID) - { - - if ( logger != null ) { - logger.trace("bulkio.InPort pushPacket ENTER (port=" + name +")" ); - } - - synchronized (this.dataBufferLock) { - if (this.maxQueueDepth == 0) { - if ( logger != null ) { - logger.trace("bulkio.InPort pushPacket EXIT (port=" + name +")" ); - } - return; - } - } - - boolean portBlocking = false; - StreamSRI tmpH = null; - boolean sriChanged = false; - synchronized (this.sriUpdateLock) { - if (this.currentHs.containsKey(streamID)) { - tmpH = this.currentHs.get(streamID).getSRI(); - sriChanged = this.currentHs.get(streamID).isChanged(); - if ( eos == false ) { - this.currentHs.get(streamID).setChanged(false); - } - portBlocking = blocking; - } else { - if (logger != null) { - logger.warn("bulkio.InPort pushPacket received data from stream '" + streamID + "' with no SRI"); - } - tmpH = new StreamSRI(1, 0.0, 1.0, (short)1, 0, 0.0, 0.0, (short)0, (short)0, streamID, false, new DataType[0]); - if (sriCallback != null) { - sriCallback.newSRI(tmpH); - } - sriChanged = true; - currentHs.put(streamID, new sriState(tmpH, false)); - } - } - - // determine whether to block and wait for an empty space in the queue - Packet p = null; - - if (portBlocking) { - p = new Packet(data, time, eos, streamID, tmpH, sriChanged, false); - - try { - queueSem.acquire(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - - synchronized (this.dataBufferLock) { - this.stats.update(data.length, this.workQueue.size()/(float)this.maxQueueDepth, eos, streamID, false); - this.workQueue.add(p); - this.dataSem.release(); - } - } else { - synchronized (this.dataBufferLock) { - if (this.workQueue.size() == this.maxQueueDepth) { - if ( logger != null ) { - logger.debug( "bulkio::InPort pushPacket PURGE INPUT QUEUE (SIZE" + this.workQueue.size() + ")" ); - } - boolean sriChangedHappened = false; - boolean flagEOS = false; - for (Iterator< Packet > itr = this.workQueue.iterator(); itr.hasNext();) { - if (sriChangedHappened && flagEOS) { - break; - } - Packet currentPacket = itr.next(); - if (currentPacket.sriChanged) { - sriChangedHappened = true; - } - if (currentPacket.EOS) { - flagEOS = true; - } - } - if (sriChangedHappened) { - sriChanged = true; - } - if (flagEOS) { - eos = true; - } - this.workQueue.clear(); - p = new Packet( data, time, eos, streamID, tmpH, sriChanged, true); - this.stats.update(data.length, 0, eos, streamID, true); - } else { - p = new Packet(data, time, eos, streamID, tmpH, sriChanged, false); - this.stats.update(data.length, this.workQueue.size()/(float)this.maxQueueDepth, eos, streamID, false); - } - if ( logger != null ) { - logger.trace( "bulkio::InPort pushPacket NEW Packet (QUEUE=" + workQueue.size() + ")"); - } - this.workQueue.add(p); - this.dataSem.release(); - } - } - - if ( logger != null ) { - logger.trace("bulkio.InPort pushPacket EXIT (port=" + name +")" ); - } - return; - - } - - /** - * - */ - public Packet getPacket(long wait) - { - - if ( logger != null ) { - logger.trace("bulkio.InPort getPacket ENTER (port=" + name +")" ); - } - - try { - if (wait < 0) { - if ( logger != null ) { - logger.trace("bulkio.InPort getPacket PORT:" + name +" Block until data arrives" ); - } - this.dataSem.acquire(); - } else { - if ( logger != null ) { - logger.trace("bulkio.InPort getPacket PORT:" + name +" TIMED WAIT:" + wait ); - } - this.dataSem.tryAcquire(wait, TimeUnit.MILLISECONDS); - } - } catch (InterruptedException ex) { - if ( logger != null ) { - logger.trace("bulkio.InPort getPacket EXIT (port=" + name +")" ); - } - return null; - } - - Packet p = null; - synchronized (this.dataBufferLock) { - p = this.workQueue.poll(); - } - - if (p != null) { - if (p.getEndOfStream()) { - synchronized (this.sriUpdateLock) { - if ( logger != null ) { - logger.trace("bulkio.InPort getPacket containsKey " + p.getStreamID() + " res:" + - this.currentHs.containsKey(p.getStreamID()) ); - } - if (this.currentHs.containsKey(p.getStreamID())) { - sriState rem = this.currentHs.remove(p.getStreamID()); - - if (rem.getSRI().blocking) { - boolean stillBlocking = false; - Iterator iter = currentHs.values().iterator(); - while (iter.hasNext()) { - if (iter.next().getSRI().blocking) { - stillBlocking = true; - break; - } - } - - if (!stillBlocking) { - blocking = false; - } - } - } - } - } - - if (blocking) { - queueSem.release(); - } - } - - if ( logger != null ) { - logger.trace("bulkio.InPort getPacket EXIT (port=" + name +")" ); - } - return p; - } - - public String getRepid() - { - return BULKIO.dataFloatHelper.id(); - } - - public String getDirection() - { - return CF.PortSet.DIRECTION_PROVIDES; - } - -} - diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/InInt16Port.java b/bulkioInterfaces/libsrc/java/src/bulkio/InInt16Port.java deleted file mode 100644 index 98ea7558b..000000000 --- a/bulkioInterfaces/libsrc/java/src/bulkio/InInt16Port.java +++ /dev/null @@ -1,520 +0,0 @@ -/* - * This file is protected by Copyright. Please refer to the COPYRIGHT file - * distributed with this source distribution. - * - * This file is part of REDHAWK bulkioInterfaces. - * - * REDHAWK bulkioInterfaces is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * REDHAWK bulkioInterfaces is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see http://www.gnu.org/licenses/. - */ -package bulkio; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Iterator; -import java.util.Map; -import org.omg.CORBA.TCKind; -import org.ossie.properties.AnyUtils; -import CF.DataType; -import java.util.ArrayDeque; -import java.util.concurrent.Semaphore; -import java.util.concurrent.TimeUnit; -import BULKIO.PrecisionUTCTime; -import BULKIO.StreamSRI; -import BULKIO.PortStatistics; -import BULKIO.PortUsageType; -import org.apache.log4j.Logger; - -import bulkio.sriState; -import bulkio.linkStatistics; -import bulkio.DataTransfer; -import bulkio.Int16Size; - -import org.ossie.component.PortBase; - -/** - * - */ -public class InInt16Port extends BULKIO.jni.dataShortPOA implements org.ossie.component.PortBase { - - /** - * A class to hold packet data. - * - */ - public class Packet extends DataTransfer < short[] > { - - public Packet(short[] data, PrecisionUTCTime time, boolean endOfStream, String streamID, StreamSRI H, boolean sriChanged, boolean inputQueueFlushed ) { - super(data,time,endOfStream,streamID,H,sriChanged,inputQueueFlushed); - }; - }; - - /** - * - */ - protected String name; - - /** - * - */ - protected linkStatistics stats; - - /** - * - */ - protected Object sriUpdateLock; - - /** - * - */ - protected Object statUpdateLock; - - /** - * - */ - protected Map currentHs; - - /** - * - */ - protected Object dataBufferLock; - - /** - * - */ - protected int maxQueueDepth; - - /** - * - */ - protected Semaphore queueSem; - - /** - * - */ - protected Semaphore dataSem; - - /** - * - */ - protected boolean blocking; - - /** - * - */ - protected Logger logger = null; - - protected bulkio.sri.Comparator sri_cmp; - - protected bulkio.SriListener sriCallback; - - - /** - * This queue stores all packets received from pushPacket. - * - */ - private ArrayDeque< Packet > workQueue; - - - /** - * - */ - public InInt16Port( String portName ) { - this( portName, null, new bulkio.sri.DefaultComparator(), null ); - } - - public InInt16Port( String portName, - bulkio.sri.Comparator compareSRI ){ - this( portName, null, compareSRI, null ); - } - - public InInt16Port( String portName, - bulkio.sri.Comparator compareSRI, - bulkio.SriListener sriCallback - ) { - this( portName, null, compareSRI, sriCallback ); - } - - public InInt16Port( String portName, Logger logger ) { - this( portName, logger, new bulkio.sri.DefaultComparator(), null ); - } - - public InInt16Port( String portName, - Logger logger, - bulkio.sri.Comparator compareSRI, - bulkio.SriListener sriCallback ) { - this.name = portName; - this.logger = logger; - this.stats = new linkStatistics(this.name, new Int16Size() ); - this.sriUpdateLock = new Object(); - this.statUpdateLock = new Object(); - this.currentHs = new HashMap(); - this.dataBufferLock = new Object(); - this.maxQueueDepth = 100; - this.queueSem = new Semaphore(this.maxQueueDepth); - this.dataSem = new Semaphore(0); - this.blocking = false; - - this.workQueue = new ArrayDeque< Packet >(); - - sri_cmp = compareSRI; - sriCallback = sriCallback; - if ( this.logger != null ) { - this.logger.debug( "bulkio::InPort CTOR port: " + portName ); - } - } - - public void setLogger( Logger newlogger ){ - synchronized (this.sriUpdateLock) { - logger = newlogger; - } - } - - - /** - * - */ - public void setSriListener( bulkio.SriListener sriCallback ) { - synchronized(this.sriUpdateLock) { - this.sriCallback = sriCallback; - } - } - - /** - * - */ - public String getName() { - return this.name; - } - - - - /** - * - */ - public void enableStats(boolean enable) { - this.stats.setEnabled(enable); - } - - /** - * - */ - public PortStatistics statistics() { - synchronized (statUpdateLock) { - return this.stats.retrieve(); - } - } - - /** - * - */ - public PortUsageType state() { - int queueSize = 0; - synchronized (dataBufferLock) { - queueSize = workQueue.size(); - if (queueSize == maxQueueDepth) { - return PortUsageType.BUSY; - } else if (queueSize == 0) { - return PortUsageType.IDLE; - } - return PortUsageType.ACTIVE; - } - } - - /** - * - */ - public StreamSRI[] activeSRIs() { - synchronized (this.sriUpdateLock) { - ArrayList sris = new ArrayList(); - Iterator iter = this.currentHs.values().iterator(); - while(iter.hasNext()) { - sris.add(iter.next().getSRI()); - } - return sris.toArray(new StreamSRI[sris.size()]); - } - } - - /** - * - */ - public int getCurrentQueueDepth() { - synchronized (this.dataBufferLock) { - return workQueue.size(); - } - } - - /** - * - */ - public int getMaxQueueDepth() { - synchronized (this.dataBufferLock) { - return this.maxQueueDepth; - } - } - - /** - * - */ - public void setMaxQueueDepth(int newDepth) { - synchronized (this.dataBufferLock) { - this.maxQueueDepth = newDepth; - queueSem = new Semaphore(newDepth); - } - } - - - /** - * - */ - public void pushSRI(StreamSRI header) { - - if ( logger != null ) { - logger.trace("bulkio.InPort pushSRI ENTER (port=" + name +")" ); - } - synchronized (sriUpdateLock) { - if (!currentHs.containsKey(header.streamID)) { - if ( logger != null ) { - logger.debug("pushSRI PORT:" + name + " NEW SRI:" + - header.streamID ); - } - if ( sriCallback != null ) { sriCallback.newSRI(header); } - currentHs.put(header.streamID, new sriState(header, true)); - if (header.blocking) { - //If switching to blocking we have to set the semaphore - synchronized (dataBufferLock) { - if (!blocking) { - try { - queueSem.acquire(workQueue.size()); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - blocking = true; - } - } - } else { - StreamSRI oldSri = currentHs.get(header.streamID).getSRI(); - boolean cval = false; - if ( sri_cmp != null ) { - cval = sri_cmp.compare( header, oldSri ); - } - if ( cval == false ) { - if ( sriCallback != null ) { sriCallback.changedSRI(header); } - this.currentHs.put(header.streamID, new sriState(header, true)); - if (header.blocking) { - //If switching to blocking we have to set the semaphore - synchronized (dataBufferLock) { - if (!blocking) { - try { - queueSem.acquire(workQueue.size()); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - blocking = true; - } - } - } - } - } - if ( logger != null ) { - logger.trace("bulkio.InPort pushSRI EXIT (port=" + name +")" ); - } - } - - - - /** - * - */ - public void pushPacket(short[] data, PrecisionUTCTime time, boolean eos, String streamID) - { - if ( logger != null ) { - logger.trace("bulkio.InPort pushPacket ENTER (port=" + name +")" ); - } - synchronized (this.dataBufferLock) { - if (this.maxQueueDepth == 0) { - return; - } - } - - boolean portBlocking = false; - StreamSRI tmpH = null; - boolean sriChanged = false; - synchronized (this.sriUpdateLock) { - if (this.currentHs.containsKey(streamID)) { - tmpH = this.currentHs.get(streamID).getSRI(); - sriChanged = this.currentHs.get(streamID).isChanged(); - if ( eos == false ) { - this.currentHs.get(streamID).setChanged(false); - } - portBlocking = blocking; - } else { - if (logger != null) { - logger.warn("bulkio.InPort pushPacket received data from stream '" + streamID + "' with no SRI"); - } - tmpH = new StreamSRI(1, 0.0, 1.0, (short)1, 0, 0.0, 0.0, (short)0, (short)0, streamID, false, new DataType[0]); - if (sriCallback != null) { - sriCallback.newSRI(tmpH); - } - sriChanged = true; - currentHs.put(streamID, new sriState(tmpH, false)); - } - } - - // determine whether to block and wait for an empty space in the queue - Packet p = null; - - if (portBlocking) { - p = new Packet(data, time, eos, streamID, tmpH, sriChanged, false); - - try { - queueSem.acquire(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - - synchronized (this.dataBufferLock) { - this.stats.update(data.length, this.workQueue.size()/(float)this.maxQueueDepth, eos, streamID, false); - this.workQueue.add(p); - this.dataSem.release(); - } - } else { - synchronized (this.dataBufferLock) { - if (this.workQueue.size() == this.maxQueueDepth) { - if ( logger != null ) { - logger.debug( "bulkio::InPort pushPacket PURGE INPUT QUEUE (SIZE" + this.workQueue.size() + ")" ); - } - boolean sriChangedHappened = false; - boolean flagEOS = false; - for (Iterator< Packet > itr = this.workQueue.iterator(); itr.hasNext();) { - if (sriChangedHappened && flagEOS) { - break; - } - Packet currentPacket = itr.next(); - if (currentPacket.sriChanged) { - sriChangedHappened = true; - } - if (currentPacket.EOS) { - flagEOS = true; - } - } - if (sriChangedHappened) { - sriChanged = true; - } - if (flagEOS) { - eos = true; - } - this.workQueue.clear(); - p = new Packet( data, time, eos, streamID, tmpH, sriChanged, true); - this.stats.update(data.length, 0, eos, streamID, true); - } else { - p = new Packet(data, time, eos, streamID, tmpH, sriChanged, false); - this.stats.update(data.length, this.workQueue.size()/(float)this.maxQueueDepth, eos, streamID, false); - } - if ( logger != null ) { - logger.trace( "bulkio::InPort pushPacket NEW Packet (QUEUE=" + workQueue.size() + ")"); - } - this.workQueue.add(p); - this.dataSem.release(); - } - } - - if ( logger != null ) { - logger.trace("bulkio.InPort pushPacket EXIT (port=" + name +")" ); - } - return; - - } - - /** - * - */ - public Packet getPacket(long wait) - { - - if ( logger != null ) { - logger.trace("bulkio.InPort getPacket ENTER (port=" + name +")" ); - } - - try { - if (wait < 0) { - if ( logger != null ) { - logger.trace("bulkio.InPort getPacket PORT:" + name +" Block until data arrives" ); - } - this.dataSem.acquire(); - } else { - if ( logger != null ) { - logger.trace("bulkio.InPort getPacket PORT:" + name +" TIMED WAIT:" + wait ); - } - this.dataSem.tryAcquire(wait, TimeUnit.MILLISECONDS); - } - } catch (InterruptedException ex) { - if ( logger != null ) { - logger.trace("bulkio.InPort getPacket EXIT (port=" + name +")" ); - } - return null; - } - - Packet p = null; - synchronized (this.dataBufferLock) { - p = this.workQueue.poll(); - } - - if (p != null) { - if (p.getEndOfStream()) { - synchronized (this.sriUpdateLock) { - if (this.currentHs.containsKey(p.getStreamID())) { - sriState rem = this.currentHs.remove(p.getStreamID()); - - if (rem.getSRI().blocking) { - boolean stillBlocking = false; - Iterator iter = currentHs.values().iterator(); - while (iter.hasNext()) { - if (iter.next().getSRI().blocking) { - stillBlocking = true; - break; - } - } - - if (!stillBlocking) { - blocking = false; - } - } - } - } - } - - if (blocking) { - queueSem.release(); - } - } - - if ( logger != null ) { - logger.trace("bulkio.InPort getPacket EXIT (port=" + name +")" ); - } - return p; - } - - public String getRepid() - { - return BULKIO.dataShortHelper.id(); - } - - public String getDirection() - { - return CF.PortSet.DIRECTION_PROVIDES; - } -} - diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/InInt32Port.java b/bulkioInterfaces/libsrc/java/src/bulkio/InInt32Port.java deleted file mode 100644 index 3f0978dab..000000000 --- a/bulkioInterfaces/libsrc/java/src/bulkio/InInt32Port.java +++ /dev/null @@ -1,526 +0,0 @@ -/* - * This file is protected by Copyright. Please refer to the COPYRIGHT file - * distributed with this source distribution. - * - * This file is part of REDHAWK bulkioInterfaces. - * - * REDHAWK bulkioInterfaces is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * REDHAWK bulkioInterfaces is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see http://www.gnu.org/licenses/. - */ -package bulkio; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Iterator; -import java.util.Map; -import org.omg.CORBA.TCKind; -import org.ossie.properties.AnyUtils; -import CF.DataType; -import java.util.ArrayDeque; -import java.util.concurrent.Semaphore; -import java.util.concurrent.TimeUnit; -import BULKIO.PrecisionUTCTime; -import BULKIO.StreamSRI; -import BULKIO.PortStatistics; -import BULKIO.PortUsageType; -import org.apache.log4j.Logger; - -import bulkio.sriState; -import bulkio.linkStatistics; -import bulkio.DataTransfer; -import bulkio.Int32Size; - -import org.ossie.component.PortBase; - -/** - * - */ -public class InInt32Port extends BULKIO.jni.dataLongPOA implements org.ossie.component.PortBase { - - /** - * A class to hold packet data. - * - */ - public class Packet extends DataTransfer < int[] > { - - public Packet(int[] data, PrecisionUTCTime time, boolean endOfStream, String streamID, StreamSRI H, boolean sriChanged, boolean inputQueueFlushed ) { - super(data,time,endOfStream,streamID,H,sriChanged,inputQueueFlushed); - }; - }; - - /** - * - */ - protected String name; - - /** - * - */ - protected linkStatistics stats; - - /** - * - */ - protected Object sriUpdateLock; - - /** - * - */ - protected Object statUpdateLock; - - /** - * - */ - protected Map currentHs; - - /** - * - */ - protected Object dataBufferLock; - - /** - * - */ - protected int maxQueueDepth; - - /** - * - */ - protected Semaphore queueSem; - - /** - * - */ - protected Semaphore dataSem; - - /** - * - */ - protected boolean blocking; - - /** - * - */ - protected Logger logger = null; - - protected bulkio.sri.Comparator sri_cmp; - - protected bulkio.SriListener sriCallback; - - - /** - * This queue stores all packets received from pushPacket. - * - */ - private ArrayDeque< Packet > workQueue; - - /** - * - */ - public InInt32Port( String portName ) { - this( portName, null, new bulkio.sri.DefaultComparator(), null ); - } - - public InInt32Port( String portName, - bulkio.sri.Comparator compareSRI ){ - this( portName, null, compareSRI, null ); - } - - public InInt32Port( String portName, - bulkio.sri.Comparator compareSRI, - bulkio.SriListener sriCallback - ) { - this( portName, null, compareSRI, sriCallback ); - } - - public InInt32Port( String portName, Logger logger ) { - this( portName, logger, new bulkio.sri.DefaultComparator(), null ); - } - - public InInt32Port( String portName, - Logger logger, - bulkio.sri.Comparator compareSRI, - bulkio.SriListener sriCallback ) { - this.name = portName; - this.logger = logger; - this.stats = new linkStatistics(this.name, new Int32Size() ); - this.sriUpdateLock = new Object(); - this.statUpdateLock = new Object(); - this.currentHs = new HashMap(); - this.dataBufferLock = new Object(); - this.maxQueueDepth = 100; - this.queueSem = new Semaphore(this.maxQueueDepth); - this.dataSem = new Semaphore(0); - this.blocking = false; - - this.workQueue = new ArrayDeque< Packet >(); - - sri_cmp = compareSRI; - sriCallback = sriCallback; - - if ( this.logger != null ) { - this.logger.debug( "bulkio::InPort CTOR port: " + portName ); - } - } - - - public void setLogger( Logger newlogger ){ - synchronized (this.sriUpdateLock) { - logger = newlogger; - } - } - - - /** - * - */ - public void setSriListener( bulkio.SriListener sriCallback ) { - synchronized(this.sriUpdateLock) { - this.sriCallback = sriCallback; - } - } - - /** - * - */ - public String getName() { - return this.name; - } - - - /** - * - */ - public void enableStats(boolean enable) { - this.stats.setEnabled(enable); - } - - /** - * - */ - public PortStatistics statistics() { - synchronized (statUpdateLock) { - return this.stats.retrieve(); - } - } - - /** - * - */ - public PortUsageType state() { - int queueSize = 0; - synchronized (dataBufferLock) { - queueSize = workQueue.size(); - if (queueSize == maxQueueDepth) { - return PortUsageType.BUSY; - } else if (queueSize == 0) { - return PortUsageType.IDLE; - } - return PortUsageType.ACTIVE; - } - } - - /** - * - */ - public StreamSRI[] activeSRIs() { - synchronized (this.sriUpdateLock) { - ArrayList sris = new ArrayList(); - Iterator iter = this.currentHs.values().iterator(); - while(iter.hasNext()) { - sris.add(iter.next().getSRI()); - } - return sris.toArray(new StreamSRI[sris.size()]); - } - } - - /** - * - */ - public int getCurrentQueueDepth() { - synchronized (this.dataBufferLock) { - return workQueue.size(); - } - } - - /** - * - */ - public int getMaxQueueDepth() { - synchronized (this.dataBufferLock) { - return this.maxQueueDepth; - } - } - - /** - * - */ - public void setMaxQueueDepth(int newDepth) { - synchronized (this.dataBufferLock) { - this.maxQueueDepth = newDepth; - queueSem = new Semaphore(newDepth); - } - } - - - /** - * - */ - public void pushSRI(StreamSRI header) { - - if ( logger != null ) { - logger.trace("bulkio.InPort pushSRI ENTER (port=" + name +")" ); - } - - synchronized (sriUpdateLock) { - if (!currentHs.containsKey(header.streamID)) { - if ( logger != null ) { - logger.debug("pushSRI PORT:" + name + " NEW SRI:" + - header.streamID ); - } - if ( sriCallback != null ) { sriCallback.newSRI(header); } - currentHs.put(header.streamID, new sriState(header, true)); - if (header.blocking) { - //If switching to blocking we have to set the semaphore - synchronized (dataBufferLock) { - if (!blocking) { - try { - queueSem.acquire(workQueue.size()); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - blocking = true; - } - } - } else { - StreamSRI oldSri = currentHs.get(header.streamID).getSRI(); - boolean cval = false; - if ( sri_cmp != null ) { - cval = sri_cmp.compare( header, oldSri ); - } - if ( cval == false ) { - if ( sriCallback != null ) { sriCallback.changedSRI(header); } - this.currentHs.put(header.streamID, new sriState(header, true)); - if (header.blocking) { - //If switching to blocking we have to set the semaphore - synchronized (dataBufferLock) { - if (!blocking) { - try { - queueSem.acquire(workQueue.size()); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - blocking = true; - } - } - } - } - } - if ( logger != null ) { - logger.trace("bulkio.InPort pushSRI EXIT (port=" + name +")" ); - } - } - - - - /** - * - */ - public void pushPacket(int[] data, PrecisionUTCTime time, boolean eos, String streamID) - { - if ( logger != null ) { - logger.trace("bulkio.InPort pushPacket ENTER (port=" + name +")" ); - } - synchronized (this.dataBufferLock) { - if (this.maxQueueDepth == 0) { - if ( logger != null ) { - logger.trace("bulkio.InPort pushPacket EXIT (port=" + name +")" ); - } - return; - } - } - - boolean portBlocking = false; - StreamSRI tmpH = null; - boolean sriChanged = false; - synchronized (this.sriUpdateLock) { - if (this.currentHs.containsKey(streamID)) { - tmpH = this.currentHs.get(streamID).getSRI(); - sriChanged = this.currentHs.get(streamID).isChanged(); - if ( eos == false ) { - this.currentHs.get(streamID).setChanged(false); - } - portBlocking = blocking; - } else { - if (logger != null) { - logger.warn("bulkio.InPort pushPacket received data from stream '" + streamID + "' with no SRI"); - } - tmpH = new StreamSRI(1, 0.0, 1.0, (short)1, 0, 0.0, 0.0, (short)0, (short)0, streamID, false, new DataType[0]); - if (sriCallback != null) { - sriCallback.newSRI(tmpH); - } - sriChanged = true; - currentHs.put(streamID, new sriState(tmpH, false)); - } - } - - - // determine whether to block and wait for an empty space in the queue - Packet p = null; - - if (portBlocking) { - p = new Packet(data, time, eos, streamID, tmpH, sriChanged, false); - - try { - queueSem.acquire(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - - synchronized (this.dataBufferLock) { - this.stats.update(data.length, this.workQueue.size()/(float)this.maxQueueDepth, eos, streamID, false); - this.workQueue.add(p); - this.dataSem.release(); - } - } else { - synchronized (this.dataBufferLock) { - if (this.workQueue.size() == this.maxQueueDepth) { - if ( logger != null ) { - logger.debug( "bulkio::InPort pushPacket PURGE INPUT QUEUE (SIZE" + this.workQueue.size() + ")" ); - } - boolean sriChangedHappened = false; - boolean flagEOS = false; - for (Iterator< Packet > itr = this.workQueue.iterator(); itr.hasNext();) { - if (sriChangedHappened && flagEOS) { - break; - } - Packet currentPacket = itr.next(); - if (currentPacket.sriChanged) { - sriChangedHappened = true; - } - if (currentPacket.EOS) { - flagEOS = true; - } - } - if (sriChangedHappened) { - sriChanged = true; - } - if (flagEOS) { - eos = true; - } - this.workQueue.clear(); - p = new Packet( data, time, eos, streamID, tmpH, sriChanged, true); - this.stats.update(data.length, 0, eos, streamID, true); - } else { - p = new Packet(data, time, eos, streamID, tmpH, sriChanged, false); - this.stats.update(data.length, this.workQueue.size()/(float)this.maxQueueDepth, eos, streamID, false); - } - if ( logger != null ) { - logger.trace( "bulkio::InPort pushPacket NEW Packet (QUEUE=" + workQueue.size() + ")"); - } - this.workQueue.add(p); - this.dataSem.release(); - } - } - - if ( logger != null ) { - logger.trace("bulkio.InPort pushPacket EXIT (port=" + name +")" ); - } - return; - - } - - /** - * - */ - public Packet getPacket(long wait) - { - - if ( logger != null ) { - logger.trace("bulkio.InPort getPacket ENTER (port=" + name +")" ); - } - - try { - if (wait < 0) { - if ( logger != null ) { - logger.trace("bulkio.InPort getPacket PORT:" + name +" Block until data arrives" ); - } - this.dataSem.acquire(); - } else { - if ( logger != null ) { - logger.trace("bulkio.InPort getPacket PORT:" + name +" TIMED WAIT:" + wait ); - } - this.dataSem.tryAcquire(wait, TimeUnit.MILLISECONDS); - } - } catch (InterruptedException ex) { - if ( logger != null ) { - logger.trace("bulkio.InPort getPacket EXIT (port=" + name +")" ); - } - return null; - } - - Packet p = null; - synchronized (this.dataBufferLock) { - p = this.workQueue.poll(); - } - - if (p != null) { - if (p.getEndOfStream()) { - synchronized (this.sriUpdateLock) { - if (this.currentHs.containsKey(p.getStreamID())) { - sriState rem = this.currentHs.remove(p.getStreamID()); - - if (rem.getSRI().blocking) { - boolean stillBlocking = false; - Iterator iter = currentHs.values().iterator(); - while (iter.hasNext()) { - if (iter.next().getSRI().blocking) { - stillBlocking = true; - break; - } - } - - if (!stillBlocking) { - blocking = false; - } - } - } - } - } - - if (blocking) { - queueSem.release(); - } - } - - if ( logger != null ) { - logger.trace("bulkio.InPort getPacket EXIT (port=" + name +")" ); - } - return p; - } - - public String getRepid() - { - return BULKIO.dataLongHelper.id(); - } - - public String getDirection() - { - return CF.PortSet.DIRECTION_PROVIDES; - } - -} - diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/InInt64Port.java b/bulkioInterfaces/libsrc/java/src/bulkio/InInt64Port.java deleted file mode 100644 index b0b846d57..000000000 --- a/bulkioInterfaces/libsrc/java/src/bulkio/InInt64Port.java +++ /dev/null @@ -1,526 +0,0 @@ -/* - * This file is protected by Copyright. Please refer to the COPYRIGHT file - * distributed with this source distribution. - * - * This file is part of REDHAWK bulkioInterfaces. - * - * REDHAWK bulkioInterfaces is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * REDHAWK bulkioInterfaces is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see http://www.gnu.org/licenses/. - */ -package bulkio; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Iterator; -import java.util.Map; -import org.omg.CORBA.TCKind; -import org.ossie.properties.AnyUtils; -import CF.DataType; -import java.util.ArrayDeque; -import java.util.concurrent.Semaphore; -import java.util.concurrent.TimeUnit; -import BULKIO.PrecisionUTCTime; -import BULKIO.StreamSRI; -import BULKIO.PortStatistics; -import BULKIO.PortUsageType; -import org.apache.log4j.Logger; - -import bulkio.sriState; -import bulkio.linkStatistics; -import bulkio.DataTransfer; -import bulkio.Int64Size; - -import org.ossie.component.PortBase; - -/** - * - */ -public class InInt64Port extends BULKIO.jni.dataLongLongPOA implements org.ossie.component.PortBase { - - /** - * A class to hold packet data. - * - */ - public class Packet extends DataTransfer < long[] > { - - public Packet(long[] data, PrecisionUTCTime time, boolean endOfStream, String streamID, StreamSRI H, boolean sriChanged, boolean inputQueueFlushed ) { - super(data,time,endOfStream,streamID,H,sriChanged,inputQueueFlushed); - }; - }; - - /** - * - */ - protected String name; - - /** - * - */ - protected linkStatistics stats; - - /** - * - */ - protected Object sriUpdateLock; - - /** - * - */ - protected Object statUpdateLock; - - /** - * - */ - protected Map currentHs; - - /** - * - */ - protected Object dataBufferLock; - - /** - * - */ - protected int maxQueueDepth; - - /** - * - */ - protected Semaphore queueSem; - - /** - * - */ - protected Semaphore dataSem; - - /** - * - */ - protected boolean blocking; - - /** - * - */ - protected Logger logger = null; - - protected bulkio.sri.Comparator sri_cmp; - - protected bulkio.SriListener sriCallback; - - - /** - * This queue stores all packets received from pushPacket. - * - */ - private ArrayDeque< Packet > workQueue; - - /** - * - */ - public InInt64Port( String portName ) { - this( portName, null, new bulkio.sri.DefaultComparator(), null ); - } - - public InInt64Port( String portName, - bulkio.sri.Comparator compareSRI ){ - this( portName, null, compareSRI, null ); - } - - public InInt64Port( String portName, - bulkio.sri.Comparator compareSRI, - bulkio.SriListener sriCallback - ) { - this( portName, null, compareSRI, sriCallback ); - } - - public InInt64Port( String portName, Logger logger ) { - this( portName, logger, new bulkio.sri.DefaultComparator(), null ); - } - - public InInt64Port( String portName, - Logger logger, - bulkio.sri.Comparator compareSRI, - bulkio.SriListener sriCallback ) { - this.name = portName; - this.logger = logger; - this.stats = new linkStatistics(this.name, new Int64Size() ); - this.sriUpdateLock = new Object(); - this.statUpdateLock = new Object(); - this.currentHs = new HashMap(); - this.dataBufferLock = new Object(); - this.maxQueueDepth = 100; - this.queueSem = new Semaphore(this.maxQueueDepth); - this.dataSem = new Semaphore(0); - this.blocking = false; - - this.workQueue = new ArrayDeque< Packet >(); - - sri_cmp = compareSRI; - sriCallback = sriCallback; - - if ( this.logger != null ) { - this.logger.debug( "bulkio::InPort CTOR port: " + portName ); - } - } - - public void setLogger( Logger newlogger ){ - synchronized (this.sriUpdateLock) { - logger = newlogger; - } - } - - - /** - * - */ - public void setSriListener( bulkio.SriListener sriCallback ) { - synchronized(this.sriUpdateLock) { - this.sriCallback = sriCallback; - } - } - - /** - * - */ - public String getName() { - return this.name; - } - - - - /** - * - */ - public void enableStats(boolean enable) { - this.stats.setEnabled(enable); - } - - /** - * - */ - public PortStatistics statistics() { - synchronized (statUpdateLock) { - return this.stats.retrieve(); - } - } - - /** - * - */ - public PortUsageType state() { - int queueSize = 0; - synchronized (dataBufferLock) { - queueSize = workQueue.size(); - if (queueSize == maxQueueDepth) { - return PortUsageType.BUSY; - } else if (queueSize == 0) { - return PortUsageType.IDLE; - } - return PortUsageType.ACTIVE; - } - } - - /** - * - */ - public StreamSRI[] activeSRIs() { - synchronized (this.sriUpdateLock) { - ArrayList sris = new ArrayList(); - Iterator iter = this.currentHs.values().iterator(); - while(iter.hasNext()) { - sris.add(iter.next().getSRI()); - } - return sris.toArray(new StreamSRI[sris.size()]); - } - } - - /** - * - */ - public int getCurrentQueueDepth() { - synchronized (this.dataBufferLock) { - return workQueue.size(); - } - } - - /** - * - */ - public int getMaxQueueDepth() { - synchronized (this.dataBufferLock) { - return this.maxQueueDepth; - } - } - - /** - * - */ - public void setMaxQueueDepth(int newDepth) { - synchronized (this.dataBufferLock) { - this.maxQueueDepth = newDepth; - queueSem = new Semaphore(newDepth); - } - } - - - /** - * - */ - public void pushSRI(StreamSRI header) { - - if ( logger != null ) { - logger.trace("bulkio.InPort pushSRI ENTER (port=" + name +")" ); - } - - synchronized (sriUpdateLock) { - if (!currentHs.containsKey(header.streamID)) { - if ( logger != null ) { - logger.debug("pushSRI PORT:" + name + " NEW SRI:" + - header.streamID ); - } - if ( sriCallback != null ) { sriCallback.newSRI(header); } - currentHs.put(header.streamID, new sriState(header, true)); - if (header.blocking) { - //If switching to blocking we have to set the semaphore - synchronized (dataBufferLock) { - if (!blocking) { - try { - queueSem.acquire(workQueue.size()); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - blocking = true; - } - } - } else { - StreamSRI oldSri = currentHs.get(header.streamID).getSRI(); - boolean cval = false; - if ( sri_cmp != null ) { - cval = sri_cmp.compare( header, oldSri ); - } - if ( cval == false ) { - if ( sriCallback != null ) { sriCallback.changedSRI(header); } - this.currentHs.put(header.streamID, new sriState(header, true)); - if (header.blocking) { - //If switching to blocking we have to set the semaphore - synchronized (dataBufferLock) { - if (!blocking) { - try { - queueSem.acquire(workQueue.size()); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - blocking = true; - } - } - } - } - } - if ( logger != null ) { - logger.trace("bulkio.InPort pushSRI EXIT (port=" + name +")" ); - } - } - - - - /** - * - */ - public void pushPacket(long[] data, PrecisionUTCTime time, boolean eos, String streamID) - { - if ( logger != null ) { - logger.trace("bulkio.InPort pushPacket ENTER (port=" + name +")" ); - } - synchronized (this.dataBufferLock) { - if (this.maxQueueDepth == 0) { - if ( logger != null ) { - logger.trace("bulkio.InPort pushPacket EXIT (port=" + name +")" ); - } - return; - } - } - - boolean portBlocking = false; - StreamSRI tmpH = null; - boolean sriChanged = false; - synchronized (this.sriUpdateLock) { - if (this.currentHs.containsKey(streamID)) { - tmpH = this.currentHs.get(streamID).getSRI(); - sriChanged = this.currentHs.get(streamID).isChanged(); - if ( eos == false ) { - this.currentHs.get(streamID).setChanged(false); - } - portBlocking = blocking; - } else { - if (logger != null) { - logger.warn("bulkio.InPort pushPacket received data from stream '" + streamID + "' with no SRI"); - } - tmpH = new StreamSRI(1, 0.0, 1.0, (short)1, 0, 0.0, 0.0, (short)0, (short)0, streamID, false, new DataType[0]); - if (sriCallback != null) { - sriCallback.newSRI(tmpH); - } - sriChanged = true; - currentHs.put(streamID, new sriState(tmpH, false)); - } - } - - - // determine whether to block and wait for an empty space in the queue - Packet p = null; - - if (portBlocking) { - p = new Packet(data, time, eos, streamID, tmpH, sriChanged, false); - - try { - queueSem.acquire(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - - synchronized (this.dataBufferLock) { - this.stats.update(data.length, this.workQueue.size()/(float)this.maxQueueDepth, eos, streamID, false); - this.workQueue.add(p); - this.dataSem.release(); - } - } else { - synchronized (this.dataBufferLock) { - if (this.workQueue.size() == this.maxQueueDepth) { - if ( logger != null ) { - logger.debug( "bulkio::InPort pushPacket PURGE INPUT QUEUE (SIZE" + this.workQueue.size() + ")" ); - } - boolean sriChangedHappened = false; - boolean flagEOS = false; - for (Iterator< Packet > itr = this.workQueue.iterator(); itr.hasNext();) { - if (sriChangedHappened && flagEOS) { - break; - } - Packet currentPacket = itr.next(); - if (currentPacket.sriChanged) { - sriChangedHappened = true; - } - if (currentPacket.EOS) { - flagEOS = true; - } - } - if (sriChangedHappened) { - sriChanged = true; - } - if (flagEOS) { - eos = true; - } - this.workQueue.clear(); - p = new Packet( data, time, eos, streamID, tmpH, sriChanged, true); - this.stats.update(data.length, 0, eos, streamID, true); - } else { - p = new Packet(data, time, eos, streamID, tmpH, sriChanged, false); - this.stats.update(data.length, this.workQueue.size()/(float)this.maxQueueDepth, eos, streamID, false); - } - if ( logger != null ) { - logger.trace( "bulkio::InPort pushPacket NEW Packet (QUEUE=" + workQueue.size() + ")"); - } - this.workQueue.add(p); - this.dataSem.release(); - } - } - - if ( logger != null ) { - logger.trace("bulkio.InPort pushPacket EXIT (port=" + name +")" ); - } - return; - - } - - /** - * - */ - public Packet getPacket(long wait) - { - - if ( logger != null ) { - logger.trace("bulkio.InPort getPacket ENTER (port=" + name +")" ); - } - - try { - if (wait < 0) { - if ( logger != null ) { - logger.trace("bulkio.InPort getPacket PORT:" + name +" Block until data arrives" ); - } - this.dataSem.acquire(); - } else { - if ( logger != null ) { - logger.trace("bulkio.InPort getPacket PORT:" + name +" TIMED WAIT:" + wait ); - } - this.dataSem.tryAcquire(wait, TimeUnit.MILLISECONDS); - } - } catch (InterruptedException ex) { - if ( logger != null ) { - logger.trace("bulkio.InPort getPacket EXIT (port=" + name +")" ); - } - return null; - } - - Packet p = null; - synchronized (this.dataBufferLock) { - p = this.workQueue.poll(); - } - - if (p != null) { - if (p.getEndOfStream()) { - synchronized (this.sriUpdateLock) { - if (this.currentHs.containsKey(p.getStreamID())) { - sriState rem = this.currentHs.remove(p.getStreamID()); - - if (rem.getSRI().blocking) { - boolean stillBlocking = false; - Iterator iter = currentHs.values().iterator(); - while (iter.hasNext()) { - if (iter.next().getSRI().blocking) { - stillBlocking = true; - break; - } - } - - if (!stillBlocking) { - blocking = false; - } - } - } - } - } - - if (blocking) { - queueSem.release(); - } - } - - if ( logger != null ) { - logger.trace("bulkio.InPort getPacket EXIT (port=" + name +")" ); - } - return p; - } - - public String getRepid() - { - return BULKIO.dataLongLongHelper.id(); - } - - public String getDirection() - { - return CF.PortSet.DIRECTION_PROVIDES; - } - -} - diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/InInt8Port.java b/bulkioInterfaces/libsrc/java/src/bulkio/InInt8Port.java deleted file mode 100644 index 023cc52a3..000000000 --- a/bulkioInterfaces/libsrc/java/src/bulkio/InInt8Port.java +++ /dev/null @@ -1,531 +0,0 @@ -/* - * This file is protected by Copyright. Please refer to the COPYRIGHT file - * distributed with this source distribution. - * - * This file is part of REDHAWK bulkioInterfaces. - * - * REDHAWK bulkioInterfaces is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * REDHAWK bulkioInterfaces is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see http://www.gnu.org/licenses/. - */ -package bulkio; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Iterator; -import java.util.Map; -import org.omg.CORBA.TCKind; -import org.ossie.properties.AnyUtils; -import org.apache.log4j.Logger; -import CF.DataType; -import java.util.ArrayDeque; -import java.util.concurrent.Semaphore; -import java.util.concurrent.TimeUnit; -import BULKIO.PrecisionUTCTime; -import BULKIO.StreamSRI; -import BULKIO.PortStatistics; -import BULKIO.PortUsageType; - - -import bulkio.sriState; -import bulkio.linkStatistics; -import bulkio.DataTransfer; -import bulkio.Int8Size; - -import org.ossie.component.PortBase; - -/** - * - */ -public class InInt8Port extends BULKIO.jni.dataCharPOA implements org.ossie.component.PortBase { - - /** - * A class to hold packet data. - * - */ - public class Packet extends DataTransfer < char[] > { - - public Packet( char[] data, PrecisionUTCTime time, boolean endOfStream, String streamID, StreamSRI H, boolean sriChanged, boolean inputQueueFlushed ) { - super(data,time,endOfStream,streamID,H,sriChanged,inputQueueFlushed); - }; - }; - - /** - * - */ - protected String name; - - /** - * - */ - protected linkStatistics stats; - - /** - * - */ - protected Object sriUpdateLock; - - /** - * - */ - protected Object statUpdateLock; - - /** - * - */ - protected Map currentHs; - - /** - * - */ - protected Object dataBufferLock; - - /** - * - */ - protected int maxQueueDepth; - - /** - * - */ - protected Semaphore queueSem; - - /** - * - */ - protected Semaphore dataSem; - - /** - * - */ - protected boolean blocking; - - - /** - * - */ - protected Logger logger = null; - - protected bulkio.sri.Comparator sri_cmp; - - protected bulkio.SriListener sriCallback; - - /** - * This queue stores all packets received from pushPacket. - * - */ - private ArrayDeque< Packet > workQueue; - - /** - * - */ - public InInt8Port( String portName ) { - this( portName, null, new bulkio.sri.DefaultComparator(), null ); - } - - public InInt8Port( String portName, - bulkio.sri.Comparator compareSRI ){ - this( portName, null, compareSRI, null ); - } - - public InInt8Port( String portName, - bulkio.sri.Comparator compareSRI, - bulkio.SriListener sriCallback - ) { - this( portName, null, compareSRI, sriCallback ); - } - - public InInt8Port( String portName, Logger logger ) { - this( portName, logger, new bulkio.sri.DefaultComparator(), null ); - } - - public InInt8Port( String portName, - Logger logger, - bulkio.sri.Comparator compareSRI, - bulkio.SriListener sriCallback ) { - - this.name = portName; - this.logger = logger; - this.stats = new linkStatistics(this.name, new Int8Size() ); - this.sriUpdateLock = new Object(); - this.statUpdateLock = new Object(); - this.currentHs = new HashMap(); - this.dataBufferLock = new Object(); - this.maxQueueDepth = 100; - this.queueSem = new Semaphore(this.maxQueueDepth); - this.dataSem = new Semaphore(0); - this.blocking = false; - - this.workQueue = new ArrayDeque< Packet >(); - - sri_cmp = compareSRI; - sriCallback = sriCallback; - - if ( this.logger != null ) { - this.logger.debug( "bulkio::InPort CTOR port: " + portName ); - } - - } - - public void setLogger( Logger newlogger ){ - synchronized (this.sriUpdateLock) { - logger = newlogger; - } - } - - - /** - * - */ - public void setSriListener( bulkio.SriListener sriCallback ) { - synchronized(this.sriUpdateLock) { - this.sriCallback = sriCallback; - } - } - - /** - * - */ - public String getName() { - return this.name; - } - - /** - * - */ - public void enableStats(boolean enable) { - this.stats.setEnabled(enable); - } - - /** - * - */ - public PortStatistics statistics() { - synchronized (statUpdateLock) { - return this.stats.retrieve(); - } - } - - /** - * - */ - public PortUsageType state() { - int queueSize = 0; - synchronized (dataBufferLock) { - queueSize = workQueue.size(); - if (queueSize == maxQueueDepth) { - return PortUsageType.BUSY; - } else if (queueSize == 0) { - return PortUsageType.IDLE; - } - return PortUsageType.ACTIVE; - } - } - - /** - * - */ - public StreamSRI[] activeSRIs() { - synchronized (this.sriUpdateLock) { - ArrayList sris = new ArrayList(); - Iterator iter = this.currentHs.values().iterator(); - while(iter.hasNext()) { - sris.add(iter.next().getSRI()); - } - return sris.toArray(new StreamSRI[sris.size()]); - } - } - - /** - * - */ - public int getCurrentQueueDepth() { - synchronized (this.dataBufferLock) { - return workQueue.size(); - } - } - - /** - * - */ - public int getMaxQueueDepth() { - synchronized (this.dataBufferLock) { - return this.maxQueueDepth; - } - } - - /** - * - */ - public void setMaxQueueDepth(int newDepth) { - synchronized (this.dataBufferLock) { - this.maxQueueDepth = newDepth; - queueSem = new Semaphore(newDepth); - } - } - - /** - * - */ - public void pushSRI(StreamSRI header) { - - if ( logger != null ) { - logger.trace("bulkio.InPort pushSRI ENTER (port=" + name +")" ); - } - - synchronized (sriUpdateLock) { - if (!currentHs.containsKey(header.streamID)) { - if ( logger != null ) { - logger.debug("pushSRI PORT:" + name + " NEW SRI:" + - header.streamID ); - } - if ( sriCallback != null ) { sriCallback.newSRI(header); } - currentHs.put(header.streamID, new sriState(header, true)); - if (header.blocking) { - //If switching to blocking we have to set the semaphore - synchronized (dataBufferLock) { - if (!blocking) { - try { - queueSem.acquire(workQueue.size()); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - blocking = true; - } - } - } else { - StreamSRI oldSri = currentHs.get(header.streamID).getSRI(); - boolean cval = false; - if ( sri_cmp != null ) { - cval = sri_cmp.compare( header, oldSri ); - } - if ( cval == false ) { - if ( sriCallback != null ) { sriCallback.changedSRI(header); } - this.currentHs.put(header.streamID, new sriState(header, true)); - if (header.blocking) { - //If switching to blocking we have to set the semaphore - synchronized (dataBufferLock) { - if (!blocking) { - try { - queueSem.acquire(workQueue.size()); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - blocking = true; - } - } - } - } - } - - if ( logger != null ) { - logger.trace("bulkio.InPort pushSRI EXIT (port=" + name +")" ); - } - } - - - - /** - * - */ - public void pushPacket( char[] data, PrecisionUTCTime time, boolean eos, String streamID) - { - if ( logger != null ) { - logger.trace("bulkio.InPort pushPacket ENTER (port=" + name +")" ); - } - - synchronized (this.dataBufferLock) { - if (this.maxQueueDepth == 0) { - if ( logger != null ) { - logger.trace("bulkio.InPort pushPacket EXIT (port=" + name +")" ); - } - return; - } - } - - boolean portBlocking = false; - StreamSRI tmpH = null; - boolean sriChanged = false; - synchronized (this.sriUpdateLock) { - if (this.currentHs.containsKey(streamID)) { - tmpH = this.currentHs.get(streamID).getSRI(); - sriChanged = this.currentHs.get(streamID).isChanged(); - if ( eos == false ) { - this.currentHs.get(streamID).setChanged(false); - } - portBlocking = blocking; - } else { - if (logger != null) { - logger.warn("bulkio.InPort pushPacket received data from stream '" + streamID + "' with no SRI"); - } - tmpH = new StreamSRI(1, 0.0, 1.0, (short)1, 0, 0.0, 0.0, (short)0, (short)0, streamID, false, new DataType[0]); - if (sriCallback != null) { - sriCallback.newSRI(tmpH); - } - sriChanged = true; - currentHs.put(streamID, new sriState(tmpH, false)); - } - } - - // determine whether to block and wait for an empty space in the queue - Packet p = null; - - if (portBlocking) { - p = new Packet(data, time, eos, streamID, tmpH, sriChanged, false); - - try { - queueSem.acquire(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - - synchronized (this.dataBufferLock) { - this.stats.update(data.length, this.workQueue.size()/(float)this.maxQueueDepth, eos, streamID, false); - this.workQueue.add(p); - this.dataSem.release(); - } - } else { - synchronized (this.dataBufferLock) { - if (this.workQueue.size() == this.maxQueueDepth) { - - if ( logger != null ) { - logger.debug( "bulkio::InPort pushPacket PURGE INPUT QUEUE (SIZE" + this.workQueue.size() + ")" ); - } - - boolean sriChangedHappened = false; - boolean flagEOS = false; - for (Iterator< Packet > itr = this.workQueue.iterator(); itr.hasNext();) { - if (sriChangedHappened && flagEOS) { - break; - } - Packet currentPacket = itr.next(); - if (currentPacket.sriChanged) { - sriChangedHappened = true; - } - if (currentPacket.EOS) { - flagEOS = true; - } - } - if (sriChangedHappened) { - sriChanged = true; - } - if (flagEOS) { - eos = true; - } - this.workQueue.clear(); - p = new Packet( data, time, eos, streamID, tmpH, sriChanged, true); - this.stats.update(data.length, 0, eos, streamID, true); - } else { - p = new Packet(data, time, eos, streamID, tmpH, sriChanged, false); - this.stats.update(data.length, this.workQueue.size()/(float)this.maxQueueDepth, eos, streamID, false); - } - - if ( logger != null ) { - logger.trace( "bulkio::InPort pushPacket NEW Packet (QUEUE=" + workQueue.size() + ")"); - } - this.workQueue.add(p); - this.dataSem.release(); - } - } - - - if ( logger != null ) { - logger.trace("bulkio.InPort pushPacket EXIT (port=" + name +")" ); - } - return; - - } - - /** - * - */ - public Packet getPacket(long wait) - { - - if ( logger != null ) { - logger.trace("bulkio.InPort getPacket ENTER (port=" + name +")" ); - } - - try { - if (wait < 0) { - if ( logger != null ) { - logger.trace("bulkio.InPort getPacket PORT:" + name +" Block until data arrives" ); - } - this.dataSem.acquire(); - } else { - if ( logger != null ) { - logger.trace("bulkio.InPort getPacket PORT:" + name +" TIMED WAIT:" + wait ); - } - this.dataSem.tryAcquire(wait, TimeUnit.MILLISECONDS); - } - } catch (InterruptedException ex) { - if ( logger != null ) { - logger.trace("bulkio.InPort getPacket EXIT (port=" + name +")" ); - } - return null; - } - - Packet p = null; - synchronized (this.dataBufferLock) { - p = this.workQueue.poll(); - } - - if (p != null) { - if (p.getEndOfStream()) { - synchronized (this.sriUpdateLock) { - if (this.currentHs.containsKey(p.getStreamID())) { - sriState rem = this.currentHs.remove(p.getStreamID()); - - if (rem.getSRI().blocking) { - boolean stillBlocking = false; - Iterator iter = currentHs.values().iterator(); - while (iter.hasNext()) { - if (iter.next().getSRI().blocking) { - stillBlocking = true; - break; - } - } - - if (!stillBlocking) { - blocking = false; - } - } - } - } - } - - if (blocking) { - queueSem.release(); - } - } - - if ( logger != null ) { - logger.trace("bulkio.InPort getPacket EXIT (port=" + name +")" ); - } - return p; - } - - public String getRepid() - { - return BULKIO.dataCharHelper.id(); - } - - public String getDirection() - { - return CF.PortSet.DIRECTION_PROVIDES; - } - -} - diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/InUInt64Port.java b/bulkioInterfaces/libsrc/java/src/bulkio/InPort.java.template similarity index 94% rename from bulkioInterfaces/libsrc/java/src/bulkio/InUInt64Port.java rename to bulkioInterfaces/libsrc/java/src/bulkio/InPort.java.template index d17e7d4d4..7a9ed35e5 100644 --- a/bulkioInterfaces/libsrc/java/src/bulkio/InUInt64Port.java +++ b/bulkioInterfaces/libsrc/java/src/bulkio/InPort.java.template @@ -17,6 +17,10 @@ * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see http://www.gnu.org/licenses/. */ +/* + * WARNING: This file is generated from InPort.java.template. + * Do not modify directly. + */ package bulkio; import java.util.ArrayList; @@ -39,22 +43,22 @@ import bulkio.sriState; import bulkio.linkStatistics; import bulkio.DataTransfer; -import bulkio.UInt64Size; +import bulkio.@name@Size; import org.ossie.component.PortBase; /** * */ -public class InUInt64Port extends BULKIO.jni.dataUlongLongPOA implements org.ossie.component.PortBase { +public class In@name@Port extends BULKIO.jni.@idl@POA implements org.ossie.component.PortBase { /** * A class to hold packet data. * */ - public class Packet extends DataTransfer < long[] > { + public class Packet extends DataTransfer < @type@[] > { - public Packet(long[] data, PrecisionUTCTime time, boolean endOfStream, String streamID, StreamSRI H, boolean sriChanged, boolean inputQueueFlushed ) { + public Packet(@type@[] data, PrecisionUTCTime time, boolean endOfStream, String streamID, StreamSRI H, boolean sriChanged, boolean inputQueueFlushed ) { super(data,time,endOfStream,streamID,H,sriChanged,inputQueueFlushed); }; }; @@ -129,34 +133,34 @@ public Packet(long[] data, PrecisionUTCTime time, boolean endOfStream, String st /** * */ - public InUInt64Port( String portName ) { + public In@name@Port( String portName ) { this( portName, null, new bulkio.sri.DefaultComparator(), null ); } - public InUInt64Port( String portName, + public In@name@Port( String portName, bulkio.sri.Comparator compareSRI ){ this( portName, null, compareSRI, null ); } - public InUInt64Port( String portName, + public In@name@Port( String portName, bulkio.sri.Comparator compareSRI, bulkio.SriListener sriCallback ) { this( portName, null, compareSRI, sriCallback ); } - public InUInt64Port( String portName, Logger logger ) { + public In@name@Port( String portName, Logger logger ) { this( portName, logger, new bulkio.sri.DefaultComparator(), null ); } - public InUInt64Port( String portName, + public In@name@Port( String portName, Logger logger, bulkio.sri.Comparator compareSRI, bulkio.SriListener sriCallback ) { this.name = portName; this.logger = logger; - this.stats = new linkStatistics(this.name, new UInt64Size() ); + this.stats = new linkStatistics(this.name, new @name@Size() ); this.sriUpdateLock = new Object(); this.statUpdateLock = new Object(); this.currentHs = new HashMap(); @@ -340,7 +344,7 @@ public void pushSRI(StreamSRI header) { /** * */ - public void pushPacket(long[] data, PrecisionUTCTime time, boolean eos, String streamID) + public void pushPacket(@type@[] data, PrecisionUTCTime time, boolean eos, String streamID) { if ( logger != null ) { logger.trace("bulkio.InPort pushPacket ENTER (port=" + name +")" ); @@ -514,13 +518,13 @@ public Packet getPacket(long wait) public String getRepid() { - return BULKIO.dataUlongLongHelper.id(); + return BULKIO.@idl@Helper.id(); } public String getDirection() { return CF.PortSet.DIRECTION_PROVIDES; } - + } diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/InUInt16Port.java b/bulkioInterfaces/libsrc/java/src/bulkio/InUInt16Port.java deleted file mode 100644 index bfcb20f87..000000000 --- a/bulkioInterfaces/libsrc/java/src/bulkio/InUInt16Port.java +++ /dev/null @@ -1,521 +0,0 @@ -/* - * This file is protected by Copyright. Please refer to the COPYRIGHT file - * distributed with this source distribution. - * - * This file is part of REDHAWK bulkioInterfaces. - * - * REDHAWK bulkioInterfaces is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * REDHAWK bulkioInterfaces is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see http://www.gnu.org/licenses/. - */ -package bulkio; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Iterator; -import java.util.Map; -import org.omg.CORBA.TCKind; -import org.ossie.properties.AnyUtils; -import CF.DataType; -import java.util.ArrayDeque; -import java.util.concurrent.Semaphore; -import java.util.concurrent.TimeUnit; -import BULKIO.PrecisionUTCTime; -import BULKIO.StreamSRI; -import BULKIO.PortStatistics; -import BULKIO.PortUsageType; -import org.apache.log4j.Logger; - -import bulkio.sriState; -import bulkio.linkStatistics; -import bulkio.DataTransfer; -import bulkio.UInt16Size; - -import org.ossie.component.PortBase; - -/** - * - */ -public class InUInt16Port extends BULKIO.jni.dataUshortPOA implements org.ossie.component.PortBase { - - /** - * A class to hold packet data. - * - */ - public class Packet extends DataTransfer < short[] > { - - public Packet(short[] data, PrecisionUTCTime time, boolean endOfStream, String streamID, StreamSRI H, boolean sriChanged, boolean inputQueueFlushed ) { - super(data,time,endOfStream,streamID,H,sriChanged,inputQueueFlushed); - }; - }; - - /** - * - */ - protected String name; - - /** - * - */ - protected linkStatistics stats; - - /** - * - */ - protected Object sriUpdateLock; - - /** - * - */ - protected Object statUpdateLock; - - /** - * - */ - protected Map currentHs; - - /** - * - */ - protected Object dataBufferLock; - - /** - * - */ - protected int maxQueueDepth; - - /** - * - */ - protected Semaphore queueSem; - - /** - * - */ - protected Semaphore dataSem; - - /** - * - */ - protected boolean blocking; - - /** - * - */ - protected Logger logger = null; - - protected bulkio.sri.Comparator sri_cmp; - - protected bulkio.SriListener sriCallback; - - - /** - * This queue stores all packets received from pushPacket. - * - */ - private ArrayDeque< Packet > workQueue; - - - /** - * - */ - public InUInt16Port( String portName ) { - this( portName, null, new bulkio.sri.DefaultComparator(), null ); - } - - public InUInt16Port( String portName, - bulkio.sri.Comparator compareSRI ){ - this( portName, null, compareSRI, null ); - } - - public InUInt16Port( String portName, - bulkio.sri.Comparator compareSRI, - bulkio.SriListener sriCallback - ) { - this( portName, null, compareSRI, sriCallback ); - } - - public InUInt16Port( String portName, Logger logger ) { - this( portName, logger, new bulkio.sri.DefaultComparator(), null ); - } - - public InUInt16Port( String portName, - Logger logger, - bulkio.sri.Comparator compareSRI, - bulkio.SriListener sriCallback ) { - - this.name = portName; - this.stats = new linkStatistics(this.name, new UInt16Size() ); - this.sriUpdateLock = new Object(); - this.statUpdateLock = new Object(); - this.currentHs = new HashMap(); - this.dataBufferLock = new Object(); - this.maxQueueDepth = 100; - this.queueSem = new Semaphore(this.maxQueueDepth); - this.dataSem = new Semaphore(0); - this.blocking = false; - - this.workQueue = new ArrayDeque< Packet >(); - - sri_cmp = compareSRI; - sriCallback = sriCallback; - if ( this.logger != null ) { - this.logger.debug( "bulkio::InPort CTOR port: " + portName ); - } - } - - public void setLogger( Logger newlogger ){ - synchronized (this.sriUpdateLock) { - logger = newlogger; - } - } - - - /** - * - */ - public void setSriListener( bulkio.SriListener sriCallback ) { - synchronized(this.sriUpdateLock) { - this.sriCallback = sriCallback; - } - } - - /** - * - */ - public String getName() { - return this.name; - } - - - - /** - * - */ - public void enableStats(boolean enable) { - this.stats.setEnabled(enable); - } - - /** - * - */ - public PortStatistics statistics() { - synchronized (statUpdateLock) { - return this.stats.retrieve(); - } - } - - /** - * - */ - public PortUsageType state() { - int queueSize = 0; - synchronized (dataBufferLock) { - queueSize = workQueue.size(); - if (queueSize == maxQueueDepth) { - return PortUsageType.BUSY; - } else if (queueSize == 0) { - return PortUsageType.IDLE; - } - return PortUsageType.ACTIVE; - } - } - - /** - * - */ - public StreamSRI[] activeSRIs() { - synchronized (this.sriUpdateLock) { - ArrayList sris = new ArrayList(); - Iterator iter = this.currentHs.values().iterator(); - while(iter.hasNext()) { - sris.add(iter.next().getSRI()); - } - return sris.toArray(new StreamSRI[sris.size()]); - } - } - - /** - * - */ - public int getCurrentQueueDepth() { - synchronized (this.dataBufferLock) { - return workQueue.size(); - } - } - - /** - * - */ - public int getMaxQueueDepth() { - synchronized (this.dataBufferLock) { - return this.maxQueueDepth; - } - } - - /** - * - */ - public void setMaxQueueDepth(int newDepth) { - synchronized (this.dataBufferLock) { - this.maxQueueDepth = newDepth; - queueSem = new Semaphore(newDepth); - } - } - - - /** - * - */ - public void pushSRI(StreamSRI header) { - - if ( logger != null ) { - logger.trace("bulkio.InPort pushSRI ENTER (port=" + name +")" ); - } - synchronized (sriUpdateLock) { - if (!currentHs.containsKey(header.streamID)) { - if ( logger != null ) { - logger.debug("pushSRI PORT:" + name + " NEW SRI:" + - header.streamID ); - } - if ( sriCallback != null ) { sriCallback.newSRI(header); } - currentHs.put(header.streamID, new sriState(header, true)); - if (header.blocking) { - //If switching to blocking we have to set the semaphore - synchronized (dataBufferLock) { - if (!blocking) { - try { - queueSem.acquire(workQueue.size()); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - blocking = true; - } - } - } else { - StreamSRI oldSri = currentHs.get(header.streamID).getSRI(); - boolean cval = false; - if ( sri_cmp != null ) { - cval = sri_cmp.compare( header, oldSri ); - } - if ( cval == false ) { - if ( sriCallback != null ) { sriCallback.changedSRI(header); } - this.currentHs.put(header.streamID, new sriState(header, true)); - if (header.blocking) { - //If switching to blocking we have to set the semaphore - synchronized (dataBufferLock) { - if (!blocking) { - try { - queueSem.acquire(workQueue.size()); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - blocking = true; - } - } - } - } - } - if ( logger != null ) { - logger.trace("bulkio.InPort pushSRI EXIT (port=" + name +")" ); - } - } - - - - /** - * - */ - public void pushPacket(short[] data, PrecisionUTCTime time, boolean eos, String streamID) - { - if ( logger != null ) { - logger.trace("bulkio.InPort pushPacket ENTER (port=" + name +")" ); - } - synchronized (this.dataBufferLock) { - if (this.maxQueueDepth == 0) { - return; - } - } - - boolean portBlocking = false; - StreamSRI tmpH = null; - boolean sriChanged = false; - synchronized (this.sriUpdateLock) { - if (this.currentHs.containsKey(streamID)) { - tmpH = this.currentHs.get(streamID).getSRI(); - sriChanged = this.currentHs.get(streamID).isChanged(); - if ( eos == false ) { - this.currentHs.get(streamID).setChanged(false); - } - portBlocking = blocking; - } else { - if (logger != null) { - logger.warn("bulkio.InPort pushPacket received data from stream '" + streamID + "' with no SRI"); - } - tmpH = new StreamSRI(1, 0.0, 1.0, (short)1, 0, 0.0, 0.0, (short)0, (short)0, streamID, false, new DataType[0]); - if (sriCallback != null) { - sriCallback.newSRI(tmpH); - } - sriChanged = true; - currentHs.put(streamID, new sriState(tmpH, false)); - } - } - - // determine whether to block and wait for an empty space in the queue - Packet p = null; - - if (portBlocking) { - p = new Packet(data, time, eos, streamID, tmpH, sriChanged, false); - - try { - queueSem.acquire(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - - synchronized (this.dataBufferLock) { - this.stats.update(data.length, this.workQueue.size()/(float)this.maxQueueDepth, eos, streamID, false); - this.workQueue.add(p); - this.dataSem.release(); - } - } else { - synchronized (this.dataBufferLock) { - if (this.workQueue.size() == this.maxQueueDepth) { - if ( logger != null ) { - logger.debug( "bulkio::InPort pushPacket PURGE INPUT QUEUE (SIZE" + this.workQueue.size() + ")" ); - } - boolean sriChangedHappened = false; - boolean flagEOS = false; - for (Iterator< Packet > itr = this.workQueue.iterator(); itr.hasNext();) { - if (sriChangedHappened && flagEOS) { - break; - } - Packet currentPacket = itr.next(); - if (currentPacket.sriChanged) { - sriChangedHappened = true; - } - if (currentPacket.EOS) { - flagEOS = true; - } - } - if (sriChangedHappened) { - sriChanged = true; - } - if (flagEOS) { - eos = true; - } - this.workQueue.clear(); - p = new Packet( data, time, eos, streamID, tmpH, sriChanged, true); - this.stats.update(data.length, 0, eos, streamID, true); - } else { - p = new Packet(data, time, eos, streamID, tmpH, sriChanged, false); - this.stats.update(data.length, this.workQueue.size()/(float)this.maxQueueDepth, eos, streamID, false); - } - if ( logger != null ) { - logger.trace( "bulkio::InPort pushPacket NEW Packet (QUEUE=" + workQueue.size() + ")"); - } - this.workQueue.add(p); - this.dataSem.release(); - } - } - - if ( logger != null ) { - logger.trace("bulkio.InPort pushPacket EXIT (port=" + name +")" ); - } - return; - - } - - /** - * - */ - public Packet getPacket(long wait) - { - - if ( logger != null ) { - logger.trace("bulkio.InPort getPacket ENTER (port=" + name +")" ); - } - - try { - if (wait < 0) { - if ( logger != null ) { - logger.trace("bulkio.InPort getPacket PORT:" + name +" Block until data arrives" ); - } - this.dataSem.acquire(); - } else { - if ( logger != null ) { - logger.trace("bulkio.InPort getPacket PORT:" + name +" TIMED WAIT:" + wait ); - } - this.dataSem.tryAcquire(wait, TimeUnit.MILLISECONDS); - } - } catch (InterruptedException ex) { - if ( logger != null ) { - logger.trace("bulkio.InPort getPacket EXIT (port=" + name +")" ); - } - return null; - } - - Packet p = null; - synchronized (this.dataBufferLock) { - p = this.workQueue.poll(); - } - - if (p != null) { - if (p.getEndOfStream()) { - synchronized (this.sriUpdateLock) { - if (this.currentHs.containsKey(p.getStreamID())) { - sriState rem = this.currentHs.remove(p.getStreamID()); - - if (rem.getSRI().blocking) { - boolean stillBlocking = false; - Iterator iter = currentHs.values().iterator(); - while (iter.hasNext()) { - if (iter.next().getSRI().blocking) { - stillBlocking = true; - break; - } - } - - if (!stillBlocking) { - blocking = false; - } - } - } - } - } - - if (blocking) { - queueSem.release(); - } - } - - if ( logger != null ) { - logger.trace("bulkio.InPort getPacket EXIT (port=" + name +")" ); - } - return p; - } - - public String getRepid() - { - return BULKIO.dataUshortHelper.id(); - } - - public String getDirection() - { - return CF.PortSet.DIRECTION_PROVIDES; - } - -} - diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/InUInt32Port.java b/bulkioInterfaces/libsrc/java/src/bulkio/InUInt32Port.java deleted file mode 100644 index 4634abf5c..000000000 --- a/bulkioInterfaces/libsrc/java/src/bulkio/InUInt32Port.java +++ /dev/null @@ -1,525 +0,0 @@ -/* - * This file is protected by Copyright. Please refer to the COPYRIGHT file - * distributed with this source distribution. - * - * This file is part of REDHAWK bulkioInterfaces. - * - * REDHAWK bulkioInterfaces is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * REDHAWK bulkioInterfaces is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see http://www.gnu.org/licenses/. - */ -package bulkio; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Iterator; -import java.util.Map; -import org.omg.CORBA.TCKind; -import org.ossie.properties.AnyUtils; -import CF.DataType; -import java.util.ArrayDeque; -import java.util.concurrent.Semaphore; -import java.util.concurrent.TimeUnit; -import BULKIO.PrecisionUTCTime; -import BULKIO.StreamSRI; -import BULKIO.PortStatistics; -import BULKIO.PortUsageType; -import org.apache.log4j.Logger; - -import bulkio.sriState; -import bulkio.linkStatistics; -import bulkio.DataTransfer; -import bulkio.UInt32Size; - -import org.ossie.component.PortBase; - -/** - * - */ -public class InUInt32Port extends BULKIO.jni.dataUlongPOA implements org.ossie.component.PortBase { - - /** - * A class to hold packet data. - * - */ - public class Packet extends DataTransfer < int[] > { - - public Packet(int[] data, PrecisionUTCTime time, boolean endOfStream, String streamID, StreamSRI H, boolean sriChanged, boolean inputQueueFlushed ) { - super(data,time,endOfStream,streamID,H,sriChanged,inputQueueFlushed); - }; - }; - - /** - * - */ - protected String name; - - /** - * - */ - protected linkStatistics stats; - - /** - * - */ - protected Object sriUpdateLock; - - /** - * - */ - protected Object statUpdateLock; - - /** - * - */ - protected Map currentHs; - - /** - * - */ - protected Object dataBufferLock; - - /** - * - */ - protected int maxQueueDepth; - - /** - * - */ - protected Semaphore queueSem; - - /** - * - */ - protected Semaphore dataSem; - - /** - * - */ - protected boolean blocking; - - /** - * - */ - protected Logger logger = null; - - protected bulkio.sri.Comparator sri_cmp; - - protected bulkio.SriListener sriCallback; - - - /** - * This queue stores all packets received from pushPacket. - * - */ - private ArrayDeque< Packet > workQueue; - - /** - * - */ - public InUInt32Port( String portName ) { - this( portName, null, new bulkio.sri.DefaultComparator(), null ); - } - - public InUInt32Port( String portName, - bulkio.sri.Comparator compareSRI ){ - this( portName, null, compareSRI, null ); - } - - public InUInt32Port( String portName, - bulkio.sri.Comparator compareSRI, - bulkio.SriListener sriCallback - ) { - this( portName, null, compareSRI, sriCallback ); - } - - public InUInt32Port( String portName, Logger logger ) { - this( portName, logger, new bulkio.sri.DefaultComparator(), null ); - } - - public InUInt32Port( String portName, - Logger logger, - bulkio.sri.Comparator compareSRI, - bulkio.SriListener sriCallback ) { - this.name = portName; - this.logger = logger; - this.stats = new linkStatistics(this.name, new UInt32Size() ); - this.sriUpdateLock = new Object(); - this.statUpdateLock = new Object(); - this.currentHs = new HashMap(); - this.dataBufferLock = new Object(); - this.maxQueueDepth = 100; - this.queueSem = new Semaphore(this.maxQueueDepth); - this.dataSem = new Semaphore(0); - this.blocking = false; - - this.workQueue = new ArrayDeque< Packet >(); - - sri_cmp = compareSRI; - sriCallback = sriCallback; - - if ( this.logger != null ) { - this.logger.debug( "bulkio::InPort CTOR port: " + portName ); - } - } - - public void setLogger( Logger newlogger ){ - synchronized (this.sriUpdateLock) { - logger = newlogger; - } - } - - /** - * - */ - public void setSriListener( bulkio.SriListener sriCallback ) { - synchronized(this.sriUpdateLock) { - this.sriCallback = sriCallback; - } - } - - /** - * - */ - public String getName() { - return this.name; - } - - - - /** - * - */ - public void enableStats(boolean enable) { - this.stats.setEnabled(enable); - } - - /** - * - */ - public PortStatistics statistics() { - synchronized (statUpdateLock) { - return this.stats.retrieve(); - } - } - - /** - * - */ - public PortUsageType state() { - int queueSize = 0; - synchronized (dataBufferLock) { - queueSize = workQueue.size(); - if (queueSize == maxQueueDepth) { - return PortUsageType.BUSY; - } else if (queueSize == 0) { - return PortUsageType.IDLE; - } - return PortUsageType.ACTIVE; - } - } - - /** - * - */ - public StreamSRI[] activeSRIs() { - synchronized (this.sriUpdateLock) { - ArrayList sris = new ArrayList(); - Iterator iter = this.currentHs.values().iterator(); - while(iter.hasNext()) { - sris.add(iter.next().getSRI()); - } - return sris.toArray(new StreamSRI[sris.size()]); - } - } - - /** - * - */ - public int getCurrentQueueDepth() { - synchronized (this.dataBufferLock) { - return workQueue.size(); - } - } - - /** - * - */ - public int getMaxQueueDepth() { - synchronized (this.dataBufferLock) { - return this.maxQueueDepth; - } - } - - /** - * - */ - public void setMaxQueueDepth(int newDepth) { - synchronized (this.dataBufferLock) { - this.maxQueueDepth = newDepth; - queueSem = new Semaphore(newDepth); - } - } - - - /** - * - */ - public void pushSRI(StreamSRI header) { - - if ( logger != null ) { - logger.trace("bulkio.InPort pushSRI ENTER (port=" + name +")" ); - } - - synchronized (sriUpdateLock) { - if (!currentHs.containsKey(header.streamID)) { - if ( logger != null ) { - logger.debug("pushSRI PORT:" + name + " NEW SRI:" + - header.streamID ); - } - if ( sriCallback != null ) { sriCallback.newSRI(header); } - currentHs.put(header.streamID, new sriState(header, true)); - if (header.blocking) { - //If switching to blocking we have to set the semaphore - synchronized (dataBufferLock) { - if (!blocking) { - try { - queueSem.acquire(workQueue.size()); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - blocking = true; - } - } - } else { - StreamSRI oldSri = currentHs.get(header.streamID).getSRI(); - boolean cval = false; - if ( sri_cmp != null ) { - cval = sri_cmp.compare( header, oldSri ); - } - if ( cval == false ) { - if ( sriCallback != null ) { sriCallback.changedSRI(header); } - this.currentHs.put(header.streamID, new sriState(header, true)); - if (header.blocking) { - //If switching to blocking we have to set the semaphore - synchronized (dataBufferLock) { - if (!blocking) { - try { - queueSem.acquire(workQueue.size()); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - blocking = true; - } - } - } - } - } - if ( logger != null ) { - logger.trace("bulkio.InPort pushSRI EXIT (port=" + name +")" ); - } - } - - - - /** - * - */ - public void pushPacket(int[] data, PrecisionUTCTime time, boolean eos, String streamID) - { - if ( logger != null ) { - logger.trace("bulkio.InPort pushPacket ENTER (port=" + name +")" ); - } - synchronized (this.dataBufferLock) { - if (this.maxQueueDepth == 0) { - if ( logger != null ) { - logger.trace("bulkio.InPort pushPacket EXIT (port=" + name +")" ); - } - return; - } - } - - boolean portBlocking = false; - StreamSRI tmpH = null; - boolean sriChanged = false; - synchronized (this.sriUpdateLock) { - if (this.currentHs.containsKey(streamID)) { - tmpH = this.currentHs.get(streamID).getSRI(); - sriChanged = this.currentHs.get(streamID).isChanged(); - if ( eos == false ) { - this.currentHs.get(streamID).setChanged(false); - } - portBlocking = blocking; - } else { - if (logger != null) { - logger.warn("bulkio.InPort pushPacket received data from stream '" + streamID + "' with no SRI"); - } - tmpH = new StreamSRI(1, 0.0, 1.0, (short)1, 0, 0.0, 0.0, (short)0, (short)0, streamID, false, new DataType[0]); - if (sriCallback != null) { - sriCallback.newSRI(tmpH); - } - sriChanged = true; - currentHs.put(streamID, new sriState(tmpH, false)); - } - } - - - // determine whether to block and wait for an empty space in the queue - Packet p = null; - - if (portBlocking) { - p = new Packet(data, time, eos, streamID, tmpH, sriChanged, false); - - try { - queueSem.acquire(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - - synchronized (this.dataBufferLock) { - this.stats.update(data.length, this.workQueue.size()/(float)this.maxQueueDepth, eos, streamID, false); - this.workQueue.add(p); - this.dataSem.release(); - } - } else { - synchronized (this.dataBufferLock) { - if (this.workQueue.size() == this.maxQueueDepth) { - if ( logger != null ) { - logger.debug( "bulkio::InPort pushPacket PURGE INPUT QUEUE (SIZE" + this.workQueue.size() + ")" ); - } - boolean sriChangedHappened = false; - boolean flagEOS = false; - for (Iterator< Packet > itr = this.workQueue.iterator(); itr.hasNext();) { - if (sriChangedHappened && flagEOS) { - break; - } - Packet currentPacket = itr.next(); - if (currentPacket.sriChanged) { - sriChangedHappened = true; - } - if (currentPacket.EOS) { - flagEOS = true; - } - } - if (sriChangedHappened) { - sriChanged = true; - } - if (flagEOS) { - eos = true; - } - this.workQueue.clear(); - p = new Packet( data, time, eos, streamID, tmpH, sriChanged, true); - this.stats.update(data.length, 0, eos, streamID, true); - } else { - p = new Packet(data, time, eos, streamID, tmpH, sriChanged, false); - this.stats.update(data.length, this.workQueue.size()/(float)this.maxQueueDepth, eos, streamID, false); - } - if ( logger != null ) { - logger.trace( "bulkio::InPort pushPacket NEW Packet (QUEUE=" + workQueue.size() + ")"); - } - this.workQueue.add(p); - this.dataSem.release(); - } - } - - if ( logger != null ) { - logger.trace("bulkio.InPort pushPacket EXIT (port=" + name +")" ); - } - return; - - } - - /** - * - */ - public Packet getPacket(long wait) - { - - if ( logger != null ) { - logger.trace("bulkio.InPort getPacket ENTER (port=" + name +")" ); - } - - try { - if (wait < 0) { - if ( logger != null ) { - logger.trace("bulkio.InPort getPacket PORT:" + name +" Block until data arrives" ); - } - this.dataSem.acquire(); - } else { - if ( logger != null ) { - logger.trace("bulkio.InPort getPacket PORT:" + name +" TIMED WAIT:" + wait ); - } - this.dataSem.tryAcquire(wait, TimeUnit.MILLISECONDS); - } - } catch (InterruptedException ex) { - if ( logger != null ) { - logger.trace("bulkio.InPort getPacket EXIT (port=" + name +")" ); - } - return null; - } - - Packet p = null; - synchronized (this.dataBufferLock) { - p = this.workQueue.poll(); - } - - if (p != null) { - if (p.getEndOfStream()) { - synchronized (this.sriUpdateLock) { - if (this.currentHs.containsKey(p.getStreamID())) { - sriState rem = this.currentHs.remove(p.getStreamID()); - - if (rem.getSRI().blocking) { - boolean stillBlocking = false; - Iterator iter = currentHs.values().iterator(); - while (iter.hasNext()) { - if (iter.next().getSRI().blocking) { - stillBlocking = true; - break; - } - } - - if (!stillBlocking) { - blocking = false; - } - } - } - } - } - - if (blocking) { - queueSem.release(); - } - } - - if ( logger != null ) { - logger.trace("bulkio.InPort getPacket EXIT (port=" + name +")" ); - } - return p; - } - - public String getRepid() - { - return BULKIO.dataUlongHelper.id(); - } - - public String getDirection() - { - return CF.PortSet.DIRECTION_PROVIDES; - } - -} - diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/InUInt8Port.java b/bulkioInterfaces/libsrc/java/src/bulkio/InUInt8Port.java deleted file mode 100644 index f514ed780..000000000 --- a/bulkioInterfaces/libsrc/java/src/bulkio/InUInt8Port.java +++ /dev/null @@ -1,535 +0,0 @@ -/* - * This file is protected by Copyright. Please refer to the COPYRIGHT file - * distributed with this source distribution. - * - * This file is part of REDHAWK bulkioInterfaces. - * - * REDHAWK bulkioInterfaces is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * REDHAWK bulkioInterfaces is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see http://www.gnu.org/licenses/. - */ -package bulkio; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Iterator; -import java.util.Map; -import org.omg.CORBA.TCKind; -import org.ossie.properties.AnyUtils; -import CF.DataType; -import java.util.ArrayDeque; -import java.util.concurrent.Semaphore; -import java.util.concurrent.TimeUnit; -import BULKIO.PrecisionUTCTime; -import BULKIO.StreamSRI; -import BULKIO.PortStatistics; -import BULKIO.PortUsageType; -import org.apache.log4j.Logger; - -import bulkio.sriState; -import bulkio.linkStatistics; -import bulkio.DataTransfer; -import bulkio.UInt8Size; - -import org.ossie.component.PortBase; - -/** - * - */ -public class InUInt8Port extends BULKIO.jni.dataOctetPOA implements org.ossie.component.PortBase { - - /** - * A class to hold packet data. - * - */ - public class Packet extends DataTransfer < byte[] > { - - public Packet( byte[] data, PrecisionUTCTime time, boolean endOfStream, String streamID, StreamSRI H, boolean sriChanged, boolean inputQueueFlushed ) { - super(data,time,endOfStream,streamID,H,sriChanged,inputQueueFlushed); - }; - }; - - /** - * - */ - protected String name; - - /** - * - */ - protected linkStatistics stats; - - /** - * - */ - protected Object sriUpdateLock; - - /** - * - */ - protected Object statUpdateLock; - - /** - * - */ - protected Map currentHs; - - /** - * - */ - protected Object dataBufferLock; - - /** - * - */ - protected int maxQueueDepth; - - /** - * - */ - protected Semaphore queueSem; - - /** - * - */ - protected Semaphore dataSem; - - /** - * - */ - protected boolean blocking; - - - /** - * - */ - protected Logger logger = null; - - protected bulkio.sri.Comparator sri_cmp; - - protected bulkio.SriListener sriCallback; - - - /** - * This queue stores all packets received from pushPacket. - * - */ - private ArrayDeque< Packet > workQueue; - - - - /** - * - */ - public InUInt8Port( String portName ) { - this( portName, null, new bulkio.sri.DefaultComparator(), null ); - } - - public InUInt8Port( String portName, - bulkio.sri.Comparator compareSRI ){ - this( portName, null, compareSRI, null ); - } - - public InUInt8Port( String portName, - bulkio.sri.Comparator compareSRI, - bulkio.SriListener sriCallback - ) { - this( portName, null, compareSRI, sriCallback ); - } - - public InUInt8Port( String portName, Logger logger ) { - this( portName, logger, new bulkio.sri.DefaultComparator(), null ); - } - - public InUInt8Port( String portName, - Logger logger, - bulkio.sri.Comparator compareSRI, - bulkio.SriListener sriCallback ) { - - this.name = portName; - this.logger = logger; - this.stats = new linkStatistics(this.name, new UInt8Size() ); - this.sriUpdateLock = new Object(); - this.statUpdateLock = new Object(); - this.currentHs = new HashMap(); - this.dataBufferLock = new Object(); - this.maxQueueDepth = 100; - this.queueSem = new Semaphore(this.maxQueueDepth); - this.dataSem = new Semaphore(0); - this.blocking = false; - - this.workQueue = new ArrayDeque< Packet >(); - - sri_cmp = compareSRI; - sriCallback = sriCallback; - - if ( this.logger != null ) { - this.logger.debug( "bulkio::InPort CTOR port: " + portName ); - } - - } - - public void setLogger( Logger newlogger ){ - synchronized (this.sriUpdateLock) { - logger = newlogger; - } - } - - /** - * - */ - public void setSriListener( bulkio.SriListener sriCallback ) { - synchronized(this.sriUpdateLock) { - this.sriCallback = sriCallback; - } - } - - /** - * - */ - public String getName() { - return this.name; - } - - - - /** - * - */ - public void enableStats(boolean enable) { - this.stats.setEnabled(enable); - } - - /** - * - */ - public PortStatistics statistics() { - synchronized (statUpdateLock) { - return this.stats.retrieve(); - } - } - - /** - * - */ - public PortUsageType state() { - int queueSize = 0; - synchronized (dataBufferLock) { - queueSize = workQueue.size(); - if (queueSize == maxQueueDepth) { - return PortUsageType.BUSY; - } else if (queueSize == 0) { - return PortUsageType.IDLE; - } - return PortUsageType.ACTIVE; - } - } - - /** - * - */ - public StreamSRI[] activeSRIs() { - synchronized (this.sriUpdateLock) { - ArrayList sris = new ArrayList(); - Iterator iter = this.currentHs.values().iterator(); - while(iter.hasNext()) { - sris.add(iter.next().getSRI()); - } - return sris.toArray(new StreamSRI[sris.size()]); - } - } - - /** - * - */ - public int getCurrentQueueDepth() { - synchronized (this.dataBufferLock) { - return workQueue.size(); - } - } - - /** - * - */ - public int getMaxQueueDepth() { - synchronized (this.dataBufferLock) { - return this.maxQueueDepth; - } - } - - /** - * - */ - public void setMaxQueueDepth(int newDepth) { - synchronized (this.dataBufferLock) { - this.maxQueueDepth = newDepth; - queueSem = new Semaphore(newDepth); - } - } - - - /** - * - */ - public void pushSRI(StreamSRI header) { - - if ( logger != null ) { - logger.trace("bulkio.InPort pushSRI ENTER (port=" + name +")" ); - } - - synchronized (sriUpdateLock) { - if (!currentHs.containsKey(header.streamID)) { - if ( logger != null ) { - logger.debug("pushSRI PORT:" + name + " NEW SRI:" + - header.streamID ); - } - if ( sriCallback != null ) { sriCallback.newSRI(header); } - currentHs.put(header.streamID, new sriState(header, true)); - if (header.blocking) { - //If switching to blocking we have to set the semaphore - synchronized (dataBufferLock) { - if (!blocking) { - try { - queueSem.acquire(workQueue.size()); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - blocking = true; - } - } - } else { - StreamSRI oldSri = currentHs.get(header.streamID).getSRI(); - boolean cval = false; - if ( sri_cmp != null ) { - cval = sri_cmp.compare( header, oldSri ); - } - if ( cval == false ) { - if ( sriCallback != null ) { sriCallback.changedSRI(header); } - this.currentHs.put(header.streamID, new sriState(header, true)); - if (header.blocking) { - //If switching to blocking we have to set the semaphore - synchronized (dataBufferLock) { - if (!blocking) { - try { - queueSem.acquire(workQueue.size()); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - blocking = true; - } - } - } - } - } - - if ( logger != null ) { - logger.trace("bulkio.InPort pushSRI EXIT (port=" + name +")" ); - } - } - - - - /** - * - */ - public void pushPacket( byte[] data, PrecisionUTCTime time, boolean eos, String streamID) - { - if ( logger != null ) { - logger.trace("bulkio.InPort pushPacket ENTER (port=" + name +")" ); - } - - synchronized (this.dataBufferLock) { - if (this.maxQueueDepth == 0) { - if ( logger != null ) { - logger.trace("bulkio.InPort pushPacket EXIT (port=" + name +")" ); - } - return; - } - } - - boolean portBlocking = false; - StreamSRI tmpH = null; - boolean sriChanged = false; - synchronized (this.sriUpdateLock) { - if (this.currentHs.containsKey(streamID)) { - tmpH = this.currentHs.get(streamID).getSRI(); - sriChanged = this.currentHs.get(streamID).isChanged(); - if ( eos == false ) { - this.currentHs.get(streamID).setChanged(false); - } - portBlocking = blocking; - } else { - if (logger != null) { - logger.warn("bulkio.InPort pushPacket received data from stream '" + streamID + "' with no SRI"); - } - tmpH = new StreamSRI(1, 0.0, 1.0, (short)1, 0, 0.0, 0.0, (short)0, (short)0, streamID, false, new DataType[0]); - if (sriCallback != null) { - sriCallback.newSRI(tmpH); - } - sriChanged = true; - currentHs.put(streamID, new sriState(tmpH, false)); - } - } - - // determine whether to block and wait for an empty space in the queue - Packet p = null; - - if (portBlocking) { - p = new Packet(data, time, eos, streamID, tmpH, sriChanged, false); - - try { - queueSem.acquire(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - - synchronized (this.dataBufferLock) { - this.stats.update(data.length, this.workQueue.size()/(float)this.maxQueueDepth, eos, streamID, false); - this.workQueue.add(p); - this.dataSem.release(); - } - } else { - synchronized (this.dataBufferLock) { - if (this.workQueue.size() == this.maxQueueDepth) { - - if ( logger != null ) { - logger.debug( "bulkio::InPort pushPacket PURGE INPUT QUEUE (SIZE" + this.workQueue.size() + ")" ); - } - - boolean sriChangedHappened = false; - boolean flagEOS = false; - for (Iterator< Packet > itr = this.workQueue.iterator(); itr.hasNext();) { - if (sriChangedHappened && flagEOS) { - break; - } - Packet currentPacket = itr.next(); - if (currentPacket.sriChanged) { - sriChangedHappened = true; - } - if (currentPacket.EOS) { - flagEOS = true; - } - } - if (sriChangedHappened) { - sriChanged = true; - } - if (flagEOS) { - eos = true; - } - this.workQueue.clear(); - p = new Packet( data, time, eos, streamID, tmpH, sriChanged, true); - this.stats.update(data.length, 0, eos, streamID, true); - } else { - p = new Packet(data, time, eos, streamID, tmpH, sriChanged, false); - this.stats.update(data.length, this.workQueue.size()/(float)this.maxQueueDepth, eos, streamID, false); - } - - if ( logger != null ) { - logger.trace( "bulkio::InPort pushPacket NEW Packet (QUEUE=" + workQueue.size() + ")"); - } - this.workQueue.add(p); - this.dataSem.release(); - } - } - - - if ( logger != null ) { - logger.trace("bulkio.InPort pushPacket EXIT (port=" + name +")" ); - } - return; - - } - - /** - * - */ - public Packet getPacket(long wait) - { - - if ( logger != null ) { - logger.trace("bulkio.InPort getPacket ENTER (port=" + name +")" ); - } - - try { - if (wait < 0) { - if ( logger != null ) { - logger.trace("bulkio.InPort getPacket PORT:" + name +" Block until data arrives" ); - } - this.dataSem.acquire(); - } else { - if ( logger != null ) { - logger.trace("bulkio.InPort getPacket PORT:" + name +" TIMED WAIT:" + wait ); - } - this.dataSem.tryAcquire(wait, TimeUnit.MILLISECONDS); - } - } catch (InterruptedException ex) { - if ( logger != null ) { - logger.trace("bulkio.InPort getPacket EXIT (port=" + name +")" ); - } - return null; - } - - Packet p = null; - synchronized (this.dataBufferLock) { - p = this.workQueue.poll(); - } - - if (p != null) { - if (p.getEndOfStream()) { - synchronized (this.sriUpdateLock) { - if (this.currentHs.containsKey(p.getStreamID())) { - sriState rem = this.currentHs.remove(p.getStreamID()); - - if (rem.getSRI().blocking) { - boolean stillBlocking = false; - Iterator iter = currentHs.values().iterator(); - while (iter.hasNext()) { - if (iter.next().getSRI().blocking) { - stillBlocking = true; - break; - } - } - - if (!stillBlocking) { - blocking = false; - } - } - } - } - } - - if (blocking) { - queueSem.release(); - } - } - - if ( logger != null ) { - logger.trace("bulkio.InPort getPacket EXIT (port=" + name +")" ); - } - return p; - } - - public String getRepid() - { - return BULKIO.dataOctetHelper.id(); - } - - public String getDirection() - { - return CF.PortSet.DIRECTION_PROVIDES; - } - -} - From 00ef57cb69cfba8f28bfb6b875e8a2275880cdc6 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 31 Dec 2015 08:53:43 -0500 Subject: [PATCH 0009/1644] Generate Java output port implementations via sed and a template file --- bulkioInterfaces/libsrc/Makefile.am | 25 ++++--- .../libsrc/java/src/bulkio/.gitignore | 10 +++ .../libsrc/java/src/bulkio/OutFloatPort.java | 72 ------------------ .../libsrc/java/src/bulkio/OutInt16Port.java | 73 ------------------- .../libsrc/java/src/bulkio/OutInt32Port.java | 71 ------------------ .../libsrc/java/src/bulkio/OutInt64Port.java | 72 ------------------ .../libsrc/java/src/bulkio/OutInt8Port.java | 72 ------------------ ...tDoublePort.java => OutPort.java.template} | 33 +++++---- .../libsrc/java/src/bulkio/OutUInt16Port.java | 71 ------------------ .../libsrc/java/src/bulkio/OutUInt32Port.java | 72 ------------------ .../libsrc/java/src/bulkio/OutUInt64Port.java | 72 ------------------ .../libsrc/java/src/bulkio/OutUInt8Port.java | 72 ------------------ 12 files changed, 43 insertions(+), 672 deletions(-) delete mode 100644 bulkioInterfaces/libsrc/java/src/bulkio/OutFloatPort.java delete mode 100644 bulkioInterfaces/libsrc/java/src/bulkio/OutInt16Port.java delete mode 100644 bulkioInterfaces/libsrc/java/src/bulkio/OutInt32Port.java delete mode 100644 bulkioInterfaces/libsrc/java/src/bulkio/OutInt64Port.java delete mode 100644 bulkioInterfaces/libsrc/java/src/bulkio/OutInt8Port.java rename bulkioInterfaces/libsrc/java/src/bulkio/{OutDoublePort.java => OutPort.java.template} (63%) delete mode 100644 bulkioInterfaces/libsrc/java/src/bulkio/OutUInt16Port.java delete mode 100644 bulkioInterfaces/libsrc/java/src/bulkio/OutUInt32Port.java delete mode 100644 bulkioInterfaces/libsrc/java/src/bulkio/OutUInt64Port.java delete mode 100644 bulkioInterfaces/libsrc/java/src/bulkio/OutUInt8Port.java diff --git a/bulkioInterfaces/libsrc/Makefile.am b/bulkioInterfaces/libsrc/Makefile.am index 65677bc33..ed2982262 100644 --- a/bulkioInterfaces/libsrc/Makefile.am +++ b/bulkioInterfaces/libsrc/Makefile.am @@ -126,13 +126,7 @@ InXMLPort.java \ linkStatistics.java \ OutCharPort.java \ OutDataPort.java \ -OutDoublePort.java \ OutFilePort.java \ -OutFloatPort.java \ -OutInt16Port.java \ -OutInt32Port.java \ -OutInt64Port.java \ -OutInt8Port.java \ OutLongLongPort.java \ OutLongPort.java \ OutOctetPort.java \ @@ -140,10 +134,6 @@ OutPortBase.java \ OutSDDSPort.java \ OutVITA49Port.java \ OutShortPort.java \ -OutUInt16Port.java \ -OutUInt32Port.java \ -OutUInt64Port.java \ -OutUInt8Port.java \ OutULongLongPort.java \ OutULongPort.java \ OutUShortPort.java \ @@ -169,10 +159,13 @@ time/Comparator.java \ time/DefaultComparator.java \ time/utils.java -# Input ports are generated via sed for ease of maintenance +# Numeric ports are generated via sed for ease of maintenance $(JAVA_SRCDIR)/bulkio/In%Port.java : $(JAVA_DIR)/sed/%.sed $(JAVA_SRCDIR)/bulkio/InPort.java.template $(AM_V_GEN)sed -f $< $(JAVA_SRCDIR)/bulkio/InPort.java.template > $@ +$(JAVA_SRCDIR)/bulkio/Out%Port.java : $(JAVA_DIR)/sed/%.sed $(JAVA_SRCDIR)/bulkio/OutPort.java.template + $(AM_V_GEN)sed -f $< $(JAVA_SRCDIR)/bulkio/OutPort.java.template > $@ + JAVA_BUILT_SOURCE = $(JAVA_SRCDIR)/bulkio/InDoublePort.java JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/InFloatPort.java JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/InInt16Port.java @@ -183,6 +176,16 @@ JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/InUInt16Port.java JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/InUInt32Port.java JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/InUInt64Port.java JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/InUInt8Port.java +JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/OutDoublePort.java +JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/OutFloatPort.java +JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/OutInt16Port.java +JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/OutInt32Port.java +JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/OutInt64Port.java +JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/OutInt8Port.java +JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/OutUInt16Port.java +JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/OutUInt32Port.java +JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/OutUInt64Port.java +JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/OutUInt8Port.java java_JARFILES = bulkio.jar diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/.gitignore b/bulkioInterfaces/libsrc/java/src/bulkio/.gitignore index 244973867..228274de3 100644 --- a/bulkioInterfaces/libsrc/java/src/bulkio/.gitignore +++ b/bulkioInterfaces/libsrc/java/src/bulkio/.gitignore @@ -8,3 +8,13 @@ InUInt16Port.java InUInt32Port.java InUInt64Port.java InUInt8Port.java +OutDoublePort.java +OutFloatPort.java +OutInt16Port.java +OutInt32Port.java +OutInt64Port.java +OutInt8Port.java +OutUInt16Port.java +OutUInt32Port.java +OutUInt64Port.java +OutUInt8Port.java diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/OutFloatPort.java b/bulkioInterfaces/libsrc/java/src/bulkio/OutFloatPort.java deleted file mode 100644 index e72f7aa6a..000000000 --- a/bulkioInterfaces/libsrc/java/src/bulkio/OutFloatPort.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * This file is protected by Copyright. Please refer to the COPYRIGHT file - * distributed with this source distribution. - * - * This file is part of REDHAWK bulkioInterfaces. - * - * REDHAWK bulkioInterfaces is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * REDHAWK bulkioInterfaces is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see http://www.gnu.org/licenses/. - */ -package bulkio; - -import java.util.Arrays; -import org.apache.log4j.Logger; -import BULKIO.PrecisionUTCTime; -import BULKIO.dataFloatOperations; - -/** - * - */ -public class OutFloatPort extends OutDataPort { - - public OutFloatPort(String portName) { - this(portName, null, null); - } - - public OutFloatPort(String portName, Logger logger) { - this(portName, logger, null); - } - - public OutFloatPort(String portName, Logger logger, ConnectionEventListener eventCB) { - super(portName, logger, eventCB, new FloatSize()); - if (this.logger != null) { - this.logger.debug("bulkio.OutPort CTOR port: " + portName); - } - } - - protected dataFloatOperations narrow(final org.omg.CORBA.Object obj) { - return BULKIO.jni.dataFloatHelper.narrow(obj); - } - - protected void sendPacket(dataFloatOperations port, float[] data, PrecisionUTCTime time, - boolean endOfStream, String streamID) { - port.pushPacket(data, time, endOfStream, streamID); - } - - protected float[] copyOfRange(float[] array, int start, int end) { - return Arrays.copyOfRange(array, start, end); - } - - protected int arraySize(float[] array) { - return array.length; - } - - protected float[] emptyArray() { - return new float[0]; - } - - public String getRepid() { - return BULKIO.dataFloatHelper.id(); - } -} - diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/OutInt16Port.java b/bulkioInterfaces/libsrc/java/src/bulkio/OutInt16Port.java deleted file mode 100644 index 255b7c7c1..000000000 --- a/bulkioInterfaces/libsrc/java/src/bulkio/OutInt16Port.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * This file is protected by Copyright. Please refer to the COPYRIGHT file - * distributed with this source distribution. - * - * This file is part of REDHAWK bulkioInterfaces. - * - * REDHAWK bulkioInterfaces is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * REDHAWK bulkioInterfaces is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see http://www.gnu.org/licenses/. - */ -package bulkio; - -import java.util.Arrays; -import org.apache.log4j.Logger; -import BULKIO.PrecisionUTCTime; -import BULKIO.dataShortOperations; - -/** - * - */ -public class OutInt16Port extends OutDataPort { - - public OutInt16Port(String portName) { - this(portName, null, null); - } - - public OutInt16Port(String portName, Logger logger) { - this(portName, logger, null); - } - - public OutInt16Port(String portName, Logger logger, ConnectionEventListener eventCB) { - super(portName, logger, eventCB, new Int16Size()); - if (this.logger != null) { - this.logger.debug("bulkio.OutPort CTOR port: " + portName); - } - - } - - protected dataShortOperations narrow(final org.omg.CORBA.Object obj) { - return BULKIO.jni.dataShortHelper.narrow(obj); - } - - protected void sendPacket(dataShortOperations port, short[] data, PrecisionUTCTime time, - boolean endOfStream, String streamID) { - port.pushPacket(data, time, endOfStream, streamID); - } - - protected short[] copyOfRange(short[] array, int start, int end) { - return Arrays.copyOfRange(array, start, end); - } - - protected int arraySize(short[] array) { - return array.length; - } - - protected short[] emptyArray() { - return new short[0]; - } - - public String getRepid() { - return BULKIO.dataShortHelper.id(); - } -} - diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/OutInt32Port.java b/bulkioInterfaces/libsrc/java/src/bulkio/OutInt32Port.java deleted file mode 100644 index 85b17a06f..000000000 --- a/bulkioInterfaces/libsrc/java/src/bulkio/OutInt32Port.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * This file is protected by Copyright. Please refer to the COPYRIGHT file - * distributed with this source distribution. - * - * This file is part of REDHAWK bulkioInterfaces. - * - * REDHAWK bulkioInterfaces is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * REDHAWK bulkioInterfaces is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see http://www.gnu.org/licenses/. - */ -package bulkio; - -import java.util.Arrays; -import org.apache.log4j.Logger; -import BULKIO.PrecisionUTCTime; -import BULKIO.dataLongOperations; - -/** - * - */ -public class OutInt32Port extends OutDataPort { - - public OutInt32Port(String portName) { - this(portName, null, null); - } - - public OutInt32Port(String portName, Logger logger) { - this(portName, logger, null); - } - - public OutInt32Port(String portName, Logger logger, ConnectionEventListener eventCB) { - super(portName, logger, eventCB, new Int32Size()); - if (this.logger != null) { - this.logger.debug("bulkio.OutPort CTOR port: " + portName); - } - } - - protected dataLongOperations narrow(final org.omg.CORBA.Object obj) { - return BULKIO.jni.dataLongHelper.narrow(obj); - } - - protected void sendPacket(dataLongOperations port, int[] data, PrecisionUTCTime time, - boolean endOfStream, String streamID) { - port.pushPacket(data, time, endOfStream, streamID); - } - - protected int[] copyOfRange(int[] array, int start, int end) { - return Arrays.copyOfRange(array, start, end); - } - - protected int arraySize(int[] array) { - return array.length; - } - - protected int[] emptyArray() { - return new int[0]; - } - - public String getRepid() { - return BULKIO.dataLongHelper.id(); - } -} diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/OutInt64Port.java b/bulkioInterfaces/libsrc/java/src/bulkio/OutInt64Port.java deleted file mode 100644 index b771ff496..000000000 --- a/bulkioInterfaces/libsrc/java/src/bulkio/OutInt64Port.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * This file is protected by Copyright. Please refer to the COPYRIGHT file - * distributed with this source distribution. - * - * This file is part of REDHAWK bulkioInterfaces. - * - * REDHAWK bulkioInterfaces is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * REDHAWK bulkioInterfaces is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see http://www.gnu.org/licenses/. - */ -package bulkio; - -import java.util.Arrays; -import org.apache.log4j.Logger; -import BULKIO.PrecisionUTCTime; -import BULKIO.dataLongLongOperations; - -/** - * - */ -public class OutInt64Port extends OutDataPort { - - public OutInt64Port(String portName) { - this(portName, null, null); - } - - public OutInt64Port(String portName, Logger logger) { - this(portName, logger, null); - } - - public OutInt64Port(String portName, Logger logger, ConnectionEventListener eventCB) { - super(portName, logger, eventCB, new Int64Size()); - if (this.logger != null) { - this.logger.debug("bulkio.OutPort CTOR port: " + portName); - } - } - - protected dataLongLongOperations narrow(final org.omg.CORBA.Object obj) { - return BULKIO.jni.dataLongLongHelper.narrow(obj); - } - - protected void sendPacket(dataLongLongOperations port, long[] data, PrecisionUTCTime time, - boolean endOfStream, String streamID) { - port.pushPacket(data, time, endOfStream, streamID); - } - - protected long[] copyOfRange(long[] array, int start, int end) { - return Arrays.copyOfRange(array, start, end); - } - - protected int arraySize(long[] array) { - return array.length; - } - - protected long[] emptyArray() { - return new long[0]; - } - - public String getRepid() { - return BULKIO.dataLongLongHelper.id(); - } -} - diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/OutInt8Port.java b/bulkioInterfaces/libsrc/java/src/bulkio/OutInt8Port.java deleted file mode 100644 index 7e2a9c2ed..000000000 --- a/bulkioInterfaces/libsrc/java/src/bulkio/OutInt8Port.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * This file is protected by Copyright. Please refer to the COPYRIGHT file - * distributed with this source distribution. - * - * This file is part of REDHAWK bulkioInterfaces. - * - * REDHAWK bulkioInterfaces is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * REDHAWK bulkioInterfaces is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see http://www.gnu.org/licenses/. - */ -package bulkio; - -import java.util.Arrays; -import org.apache.log4j.Logger; -import BULKIO.PrecisionUTCTime; -import BULKIO.dataCharOperations; - -/** - * - */ -public class OutInt8Port extends OutDataPort { - - public OutInt8Port(String portName) { - this(portName, null, null); - } - - public OutInt8Port(String portName, Logger logger) { - this(portName, logger, null); - } - - public OutInt8Port(String portName, Logger logger, ConnectionEventListener eventCB) { - super(portName, logger, eventCB, new Int8Size()); - if (this.logger != null) { - this.logger.debug("bulkio.OutPort CTOR port: " + portName); - } - } - - protected dataCharOperations narrow(final org.omg.CORBA.Object obj) { - return BULKIO.jni.dataCharHelper.narrow(obj); - } - - protected void sendPacket(dataCharOperations port, char[] data, PrecisionUTCTime time, - boolean endOfStream, String streamID) { - port.pushPacket(data, time, endOfStream, streamID); - } - - protected char[] copyOfRange(char[] array, int start, int end) { - return Arrays.copyOfRange(array, start, end); - } - - protected int arraySize(char[] array) { - return array.length; - } - - protected char[] emptyArray() { - return new char[0]; - } - - public String getRepid() { - return BULKIO.dataCharHelper.id(); - } -} - diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/OutDoublePort.java b/bulkioInterfaces/libsrc/java/src/bulkio/OutPort.java.template similarity index 63% rename from bulkioInterfaces/libsrc/java/src/bulkio/OutDoublePort.java rename to bulkioInterfaces/libsrc/java/src/bulkio/OutPort.java.template index 0cac87ae8..18a321f73 100644 --- a/bulkioInterfaces/libsrc/java/src/bulkio/OutDoublePort.java +++ b/bulkioInterfaces/libsrc/java/src/bulkio/OutPort.java.template @@ -17,55 +17,60 @@ * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see http://www.gnu.org/licenses/. */ +/* + * WARNING: This file is generated from OutPort.java.template. + * Do not modify directly. + */ package bulkio; import java.util.Arrays; import org.apache.log4j.Logger; import BULKIO.PrecisionUTCTime; -import BULKIO.dataDoubleOperations; +import BULKIO.@idl@Operations; /** * */ -public class OutDoublePort extends OutDataPort { +public class Out@name@Port extends OutDataPort<@idl@Operations,@type@[]> { - public OutDoublePort(String portName) { + public Out@name@Port(String portName) { this(portName, null, null); } - public OutDoublePort(String portName, Logger logger) { + public Out@name@Port(String portName, Logger logger) { this(portName, logger, null); } - public OutDoublePort(String portName, Logger logger, ConnectionEventListener eventCB) { - super(portName, logger, eventCB, new DoubleSize()); + public Out@name@Port(String portName, Logger logger, ConnectionEventListener eventCB) { + super(portName, logger, eventCB, new @name@Size()); if (this.logger != null) { this.logger.debug("bulkio.OutPort CTOR port: " + portName); } } - protected dataDoubleOperations narrow(final org.omg.CORBA.Object obj) { - return BULKIO.jni.dataDoubleHelper.narrow(obj); + protected @idl@Operations narrow(final org.omg.CORBA.Object obj) { + return BULKIO.jni.@idl@Helper.narrow(obj); } - protected void sendPacket(dataDoubleOperations port, double[] data, PrecisionUTCTime time, + protected void sendPacket(@idl@Operations port, @type@[] data, PrecisionUTCTime time, boolean endOfStream, String streamID) { port.pushPacket(data, time, endOfStream, streamID); } - protected double[] copyOfRange(double[] array, int start, int end) { + protected @type@[] copyOfRange(@type@[] array, int start, int end) { return Arrays.copyOfRange(array, start, end); } - protected int arraySize(double[] array) { + protected int arraySize(@type@[] array) { return array.length; } - protected double[] emptyArray() { - return new double[0]; + protected @type@[] emptyArray() { + return new @type@[0]; } public String getRepid() { - return BULKIO.dataDoubleHelper.id(); + return BULKIO.@idl@Helper.id(); } } + diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/OutUInt16Port.java b/bulkioInterfaces/libsrc/java/src/bulkio/OutUInt16Port.java deleted file mode 100644 index 8510136c7..000000000 --- a/bulkioInterfaces/libsrc/java/src/bulkio/OutUInt16Port.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * This file is protected by Copyright. Please refer to the COPYRIGHT file - * distributed with this source distribution. - * - * This file is part of REDHAWK bulkioInterfaces. - * - * REDHAWK bulkioInterfaces is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * REDHAWK bulkioInterfaces is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see http://www.gnu.org/licenses/. - */ -package bulkio; - -import java.util.Arrays; -import org.apache.log4j.Logger; -import BULKIO.PrecisionUTCTime; -import BULKIO.dataUshortOperations; - -/** - * - */ -public class OutUInt16Port extends OutDataPort { - - public OutUInt16Port(String portName) { - this(portName, null, null); - } - - public OutUInt16Port(String portName, Logger logger) { - this(portName, logger, null); - } - - public OutUInt16Port(String portName, Logger logger, ConnectionEventListener eventCB) { - super(portName, logger, eventCB, new UInt16Size()); - if (this.logger != null) { - this.logger.debug("bulkio.OutPort CTOR port: " + portName); - } - } - - protected dataUshortOperations narrow(final org.omg.CORBA.Object obj) { - return BULKIO.jni.dataUshortHelper.narrow(obj); - } - - protected void sendPacket(dataUshortOperations port, short[] data, PrecisionUTCTime time, - boolean endOfStream, String streamID) { - port.pushPacket(data, time, endOfStream, streamID); - } - - protected short[] copyOfRange(short[] array, int start, int end) { - return Arrays.copyOfRange(array, start, end); - } - - protected int arraySize(short[] array) { - return array.length; - } - - protected short[] emptyArray() { - return new short[0]; - } - - public String getRepid() { - return BULKIO.dataUshortHelper.id(); - } -} diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/OutUInt32Port.java b/bulkioInterfaces/libsrc/java/src/bulkio/OutUInt32Port.java deleted file mode 100644 index 3cc007d2f..000000000 --- a/bulkioInterfaces/libsrc/java/src/bulkio/OutUInt32Port.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * This file is protected by Copyright. Please refer to the COPYRIGHT file - * distributed with this source distribution. - * - * This file is part of REDHAWK bulkioInterfaces. - * - * REDHAWK bulkioInterfaces is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * REDHAWK bulkioInterfaces is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see http://www.gnu.org/licenses/. - */ -package bulkio; - -import java.util.Arrays; -import org.apache.log4j.Logger; -import BULKIO.PrecisionUTCTime; -import BULKIO.dataUlongOperations; - -/** - * - */ -public class OutUInt32Port extends OutDataPort { - - public OutUInt32Port(String portName) { - this(portName, null, null); - } - - public OutUInt32Port(String portName, Logger logger) { - this(portName, logger, null); - } - - public OutUInt32Port(String portName, Logger logger, ConnectionEventListener eventCB) { - super(portName, logger, eventCB, new UInt32Size()); - if (this.logger != null) { - this.logger.debug("bulkio.OutPort CTOR port: " + portName); - } - } - - protected dataUlongOperations narrow(final org.omg.CORBA.Object obj) { - return BULKIO.jni.dataUlongHelper.narrow(obj); - } - - protected void sendPacket(dataUlongOperations port, int[] data, PrecisionUTCTime time, - boolean endOfStream, String streamID) { - port.pushPacket(data, time, endOfStream, streamID); - } - - protected int[] copyOfRange(int[] array, int start, int end) { - return Arrays.copyOfRange(array, start, end); - } - - protected int arraySize(int[] array) { - return array.length; - } - - protected int[] emptyArray() { - return new int[0]; - } - - public String getRepid() { - return BULKIO.dataUlongHelper.id(); - } -} - diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/OutUInt64Port.java b/bulkioInterfaces/libsrc/java/src/bulkio/OutUInt64Port.java deleted file mode 100644 index 16d4da67d..000000000 --- a/bulkioInterfaces/libsrc/java/src/bulkio/OutUInt64Port.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * This file is protected by Copyright. Please refer to the COPYRIGHT file - * distributed with this source distribution. - * - * This file is part of REDHAWK bulkioInterfaces. - * - * REDHAWK bulkioInterfaces is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * REDHAWK bulkioInterfaces is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see http://www.gnu.org/licenses/. - */ -package bulkio; - -import java.util.Arrays; -import org.apache.log4j.Logger; -import BULKIO.PrecisionUTCTime; -import BULKIO.dataUlongLongOperations; - -/** - * - */ -public class OutUInt64Port extends OutDataPort { - - public OutUInt64Port(String portName) { - this(portName, null, null); - } - - public OutUInt64Port(String portName, Logger logger) { - this(portName, logger, null); - } - - public OutUInt64Port(String portName, Logger logger, ConnectionEventListener eventCB) { - super(portName, logger, eventCB, new UInt64Size()); - if (this.logger != null) { - this.logger.debug("bulkio.OutPort CTOR port: " + portName); - } - } - - protected dataUlongLongOperations narrow(final org.omg.CORBA.Object obj) { - return BULKIO.jni.dataUlongLongHelper.narrow(obj); - } - - protected void sendPacket(dataUlongLongOperations port, long[] data, PrecisionUTCTime time, - boolean endOfStream, String streamID) { - port.pushPacket(data, time, endOfStream, streamID); - } - - protected long[] copyOfRange(long[] array, int start, int end) { - return Arrays.copyOfRange(array, start, end); - } - - protected int arraySize(long[] array) { - return array.length; - } - - protected long[] emptyArray() { - return new long[0]; - } - - public String getRepid() { - return BULKIO.dataUlongLongHelper.id(); - } -} - diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/OutUInt8Port.java b/bulkioInterfaces/libsrc/java/src/bulkio/OutUInt8Port.java deleted file mode 100644 index b8510d3b4..000000000 --- a/bulkioInterfaces/libsrc/java/src/bulkio/OutUInt8Port.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * This file is protected by Copyright. Please refer to the COPYRIGHT file - * distributed with this source distribution. - * - * This file is part of REDHAWK bulkioInterfaces. - * - * REDHAWK bulkioInterfaces is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * REDHAWK bulkioInterfaces is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see http://www.gnu.org/licenses/. - */ -package bulkio; - -import java.util.Arrays; -import org.apache.log4j.Logger; -import BULKIO.PrecisionUTCTime; -import BULKIO.dataOctetOperations; - -/** - * - */ -public class OutUInt8Port extends OutDataPort { - - public OutUInt8Port(String portName) { - this(portName, null, null); - } - - public OutUInt8Port(String portName, Logger logger) { - this(portName, logger, null); - } - - public OutUInt8Port(String portName, Logger logger, ConnectionEventListener eventCB) { - super(portName, logger, eventCB, new UInt8Size()); - if (this.logger != null) { - this.logger.debug("bulkio.OutPort CTOR port: " + portName); - } - } - - protected dataOctetOperations narrow(final org.omg.CORBA.Object obj) { - return BULKIO.jni.dataOctetHelper.narrow(obj); - } - - protected void sendPacket(dataOctetOperations port, byte[] data, PrecisionUTCTime time, - boolean endOfStream, String streamID) { - port.pushPacket(data, time, endOfStream, streamID); - } - - protected byte[] copyOfRange(byte[] array, int start, int end) { - return Arrays.copyOfRange(array, start, end); - } - - protected int arraySize(byte[] array) { - return array.length; - } - - protected byte[] emptyArray() { - return new byte[0]; - } - - public String getRepid() { - return BULKIO.dataOctetHelper.id(); - } -} - From 7e6e7feb7ddaf422f8d9b9b0097bc1191445fddd Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 31 Dec 2015 09:08:59 -0500 Subject: [PATCH 0010/1644] Clean up whitespace and imports for Java templates --- .../java/src/bulkio/InPort.java.template | 231 +++++++++--------- .../java/src/bulkio/OutPort.java.template | 12 +- 2 files changed, 117 insertions(+), 126 deletions(-) diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/InPort.java.template b/bulkioInterfaces/libsrc/java/src/bulkio/InPort.java.template index 7a9ed35e5..15889ccb1 100644 --- a/bulkioInterfaces/libsrc/java/src/bulkio/InPort.java.template +++ b/bulkioInterfaces/libsrc/java/src/bulkio/InPort.java.template @@ -28,25 +28,21 @@ import java.util.HashMap; import java.util.List; import java.util.Iterator; import java.util.Map; -import org.omg.CORBA.TCKind; -import org.ossie.properties.AnyUtils; -import CF.DataType; import java.util.ArrayDeque; import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; -import BULKIO.PrecisionUTCTime; -import BULKIO.StreamSRI; -import BULKIO.PortStatistics; -import BULKIO.PortUsageType; -import org.apache.log4j.Logger; -import bulkio.sriState; -import bulkio.linkStatistics; -import bulkio.DataTransfer; -import bulkio.@name@Size; +import org.apache.log4j.Logger; +import CF.DataType; import org.ossie.component.PortBase; +import BULKIO.PortStatistics; +import BULKIO.PortUsageType; +import BULKIO.PrecisionUTCTime; +import BULKIO.StreamSRI; + + /** * */ @@ -58,16 +54,16 @@ public class In@name@Port extends BULKIO.jni.@idl@POA implements org.ossie.compo */ public class Packet extends DataTransfer < @type@[] > { - public Packet(@type@[] data, PrecisionUTCTime time, boolean endOfStream, String streamID, StreamSRI H, boolean sriChanged, boolean inputQueueFlushed ) { - super(data,time,endOfStream,streamID,H,sriChanged,inputQueueFlushed); - }; + public Packet(@type@[] data, PrecisionUTCTime time, boolean endOfStream, String streamID, StreamSRI H, boolean sriChanged, boolean inputQueueFlushed ) { + super(data,time,endOfStream,streamID,H,sriChanged,inputQueueFlushed); + }; }; /** * */ protected String name; - + /** * */ @@ -92,12 +88,12 @@ public class In@name@Port extends BULKIO.jni.@idl@POA implements org.ossie.compo * */ protected Object dataBufferLock; - + /** * */ protected int maxQueueDepth; - + /** * */ @@ -128,38 +124,37 @@ public class In@name@Port extends BULKIO.jni.@idl@POA implements org.ossie.compo * */ private ArrayDeque< Packet > workQueue; - /** * */ public In@name@Port( String portName ) { - this( portName, null, new bulkio.sri.DefaultComparator(), null ); + this( portName, null, new bulkio.sri.DefaultComparator(), null ); } public In@name@Port( String portName, - bulkio.sri.Comparator compareSRI ){ - this( portName, null, compareSRI, null ); + bulkio.sri.Comparator compareSRI ){ + this( portName, null, compareSRI, null ); } - public In@name@Port( String portName, - bulkio.sri.Comparator compareSRI, - bulkio.SriListener sriCallback - ) { - this( portName, null, compareSRI, sriCallback ); + public In@name@Port( String portName, + bulkio.sri.Comparator compareSRI, + bulkio.SriListener sriCallback + ) { + this( portName, null, compareSRI, sriCallback ); } public In@name@Port( String portName, Logger logger ) { - this( portName, logger, new bulkio.sri.DefaultComparator(), null ); + this( portName, logger, new bulkio.sri.DefaultComparator(), null ); } - public In@name@Port( String portName, - Logger logger, - bulkio.sri.Comparator compareSRI, - bulkio.SriListener sriCallback ) { + public In@name@Port( String portName, + Logger logger, + bulkio.sri.Comparator compareSRI, + bulkio.SriListener sriCallback ) { this.name = portName; - this.logger = logger; + this.logger = logger; this.stats = new linkStatistics(this.name, new @name@Size() ); this.sriUpdateLock = new Object(); this.statUpdateLock = new Object(); @@ -170,20 +165,20 @@ public class In@name@Port extends BULKIO.jni.@idl@POA implements org.ossie.compo this.dataSem = new Semaphore(0); this.blocking = false; - this.workQueue = new ArrayDeque< Packet >(); + this.workQueue = new ArrayDeque< Packet >(); - sri_cmp = compareSRI; - sriCallback = sriCallback; + sri_cmp = compareSRI; + sriCallback = sriCallback; - if ( this.logger != null ) { - this.logger.debug( "bulkio::InPort CTOR port: " + portName ); - } + if ( this.logger != null ) { + this.logger.debug( "bulkio::InPort CTOR port: " + portName ); + } } public void setLogger( Logger newlogger ){ synchronized (this.sriUpdateLock) { - logger = newlogger; - } + logger = newlogger; + } } /** @@ -191,8 +186,8 @@ public class In@name@Port extends BULKIO.jni.@idl@POA implements org.ossie.compo */ public void setSriListener( bulkio.SriListener sriCallback ) { synchronized(this.sriUpdateLock) { - this.sriCallback = sriCallback; - } + this.sriCallback = sriCallback; + } } /** @@ -201,8 +196,6 @@ public class In@name@Port extends BULKIO.jni.@idl@POA implements org.ossie.compo public String getName() { return this.name; } - - /** * @@ -227,13 +220,13 @@ public class In@name@Port extends BULKIO.jni.@idl@POA implements org.ossie.compo int queueSize = 0; synchronized (dataBufferLock) { queueSize = workQueue.size(); - if (queueSize == maxQueueDepth) { - return PortUsageType.BUSY; - } else if (queueSize == 0) { - return PortUsageType.IDLE; - } - return PortUsageType.ACTIVE; - } + if (queueSize == maxQueueDepth) { + return PortUsageType.BUSY; + } else if (queueSize == 0) { + return PortUsageType.IDLE; + } + return PortUsageType.ACTIVE; + } } /** @@ -249,7 +242,7 @@ public class In@name@Port extends BULKIO.jni.@idl@POA implements org.ossie.compo return sris.toArray(new StreamSRI[sris.size()]); } } - + /** * */ @@ -258,7 +251,7 @@ public class In@name@Port extends BULKIO.jni.@idl@POA implements org.ossie.compo return workQueue.size(); } } - + /** * */ @@ -267,7 +260,7 @@ public class In@name@Port extends BULKIO.jni.@idl@POA implements org.ossie.compo return this.maxQueueDepth; } } - + /** * */ @@ -278,22 +271,21 @@ public class In@name@Port extends BULKIO.jni.@idl@POA implements org.ossie.compo } } - /** * */ public void pushSRI(StreamSRI header) { - if ( logger != null ) { - logger.trace("bulkio.InPort pushSRI ENTER (port=" + name +")" ); - } + if ( logger != null ) { + logger.trace("bulkio.InPort pushSRI ENTER (port=" + name +")" ); + } synchronized (sriUpdateLock) { if (!currentHs.containsKey(header.streamID)) { - if ( logger != null ) { - logger.debug("pushSRI PORT:" + name + " NEW SRI:" + - header.streamID ); - } + if ( logger != null ) { + logger.debug("pushSRI PORT:" + name + " NEW SRI:" + + header.streamID ); + } if ( sriCallback != null ) { sriCallback.newSRI(header); } currentHs.put(header.streamID, new sriState(header, true)); if (header.blocking) { @@ -311,12 +303,12 @@ public class In@name@Port extends BULKIO.jni.@idl@POA implements org.ossie.compo } } else { StreamSRI oldSri = currentHs.get(header.streamID).getSRI(); - boolean cval = false; - if ( sri_cmp != null ) { - cval = sri_cmp.compare( header, oldSri ); - } + boolean cval = false; + if ( sri_cmp != null ) { + cval = sri_cmp.compare( header, oldSri ); + } if ( cval == false ) { - if ( sriCallback != null ) { sriCallback.changedSRI(header); } + if ( sriCallback != null ) { sriCallback.changedSRI(header); } this.currentHs.put(header.streamID, new sriState(header, true)); if (header.blocking) { //If switching to blocking we have to set the semaphore @@ -334,26 +326,24 @@ public class In@name@Port extends BULKIO.jni.@idl@POA implements org.ossie.compo } } } - if ( logger != null ) { - logger.trace("bulkio.InPort pushSRI EXIT (port=" + name +")" ); - } + if ( logger != null ) { + logger.trace("bulkio.InPort pushSRI EXIT (port=" + name +")" ); + } } - - /** * */ - public void pushPacket(@type@[] data, PrecisionUTCTime time, boolean eos, String streamID) + public void pushPacket(@type@[] data, PrecisionUTCTime time, boolean eos, String streamID) { - if ( logger != null ) { - logger.trace("bulkio.InPort pushPacket ENTER (port=" + name +")" ); - } + if ( logger != null ) { + logger.trace("bulkio.InPort pushPacket ENTER (port=" + name +")" ); + } synchronized (this.dataBufferLock) { if (this.maxQueueDepth == 0) { - if ( logger != null ) { - logger.trace("bulkio.InPort pushPacket EXIT (port=" + name +")" ); - } + if ( logger != null ) { + logger.trace("bulkio.InPort pushPacket EXIT (port=" + name +")" ); + } return; } } @@ -365,9 +355,9 @@ public class In@name@Port extends BULKIO.jni.@idl@POA implements org.ossie.compo if (this.currentHs.containsKey(streamID)) { tmpH = this.currentHs.get(streamID).getSRI(); sriChanged = this.currentHs.get(streamID).isChanged(); - if ( eos == false ) { - this.currentHs.get(streamID).setChanged(false); - } + if ( eos == false ) { + this.currentHs.get(streamID).setChanged(false); + } portBlocking = blocking; } else { if (logger != null) { @@ -402,9 +392,9 @@ public class In@name@Port extends BULKIO.jni.@idl@POA implements org.ossie.compo } else { synchronized (this.dataBufferLock) { if (this.workQueue.size() == this.maxQueueDepth) { - if ( logger != null ) { - logger.debug( "bulkio::InPort pushPacket PURGE INPUT QUEUE (SIZE" + this.workQueue.size() + ")" ); - } + if ( logger != null ) { + logger.debug( "bulkio::InPort pushPacket PURGE INPUT QUEUE (SIZE" + this.workQueue.size() + ")" ); + } boolean sriChangedHappened = false; boolean flagEOS = false; for (Iterator< Packet > itr = this.workQueue.iterator(); itr.hasNext();) { @@ -432,50 +422,50 @@ public class In@name@Port extends BULKIO.jni.@idl@POA implements org.ossie.compo p = new Packet(data, time, eos, streamID, tmpH, sriChanged, false); this.stats.update(data.length, this.workQueue.size()/(float)this.maxQueueDepth, eos, streamID, false); } - if ( logger != null ) { - logger.trace( "bulkio::InPort pushPacket NEW Packet (QUEUE=" + workQueue.size() + ")"); - } + if ( logger != null ) { + logger.trace( "bulkio::InPort pushPacket NEW Packet (QUEUE=" + workQueue.size() + ")"); + } this.workQueue.add(p); this.dataSem.release(); } } - if ( logger != null ) { - logger.trace("bulkio.InPort pushPacket EXIT (port=" + name +")" ); - } + if ( logger != null ) { + logger.trace("bulkio.InPort pushPacket EXIT (port=" + name +")" ); + } return; } - + /** * */ - public Packet getPacket(long wait) + public Packet getPacket(long wait) { - if ( logger != null ) { - logger.trace("bulkio.InPort getPacket ENTER (port=" + name +")" ); - } + if ( logger != null ) { + logger.trace("bulkio.InPort getPacket ENTER (port=" + name +")" ); + } try { if (wait < 0) { - if ( logger != null ) { - logger.trace("bulkio.InPort getPacket PORT:" + name +" Block until data arrives" ); - } + if ( logger != null ) { + logger.trace("bulkio.InPort getPacket PORT:" + name +" Block until data arrives" ); + } this.dataSem.acquire(); } else { - if ( logger != null ) { - logger.trace("bulkio.InPort getPacket PORT:" + name +" TIMED WAIT:" + wait ); - } + if ( logger != null ) { + logger.trace("bulkio.InPort getPacket PORT:" + name +" TIMED WAIT:" + wait ); + } this.dataSem.tryAcquire(wait, TimeUnit.MILLISECONDS); } } catch (InterruptedException ex) { - if ( logger != null ) { - logger.trace("bulkio.InPort getPacket EXIT (port=" + name +")" ); - } + if ( logger != null ) { + logger.trace("bulkio.InPort getPacket EXIT (port=" + name +")" ); + } return null; } - + Packet p = null; synchronized (this.dataBufferLock) { p = this.workQueue.poll(); @@ -491,7 +481,7 @@ public class In@name@Port extends BULKIO.jni.@idl@POA implements org.ossie.compo boolean stillBlocking = false; Iterator iter = currentHs.values().iterator(); while (iter.hasNext()) { - if (iter.next().getSRI().blocking) { + if (iter.next().getSRI().blocking) { stillBlocking = true; break; } @@ -504,27 +494,26 @@ public class In@name@Port extends BULKIO.jni.@idl@POA implements org.ossie.compo } } } - + if (blocking) { queueSem.release(); } } - if ( logger != null ) { - logger.trace("bulkio.InPort getPacket EXIT (port=" + name +")" ); - } + if ( logger != null ) { + logger.trace("bulkio.InPort getPacket EXIT (port=" + name +")" ); + } return p; } - public String getRepid() - { - return BULKIO.@idl@Helper.id(); - } + public String getRepid() + { + return BULKIO.@idl@Helper.id(); + } - public String getDirection() - { - return CF.PortSet.DIRECTION_PROVIDES; - } + public String getDirection() + { + return CF.PortSet.DIRECTION_PROVIDES; + } } - diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/OutPort.java.template b/bulkioInterfaces/libsrc/java/src/bulkio/OutPort.java.template index 18a321f73..4c5fecceb 100644 --- a/bulkioInterfaces/libsrc/java/src/bulkio/OutPort.java.template +++ b/bulkioInterfaces/libsrc/java/src/bulkio/OutPort.java.template @@ -24,12 +24,14 @@ package bulkio; import java.util.Arrays; + import org.apache.log4j.Logger; + import BULKIO.PrecisionUTCTime; import BULKIO.@idl@Operations; /** - * + * BulkIO output port implementation for @idl@. */ public class Out@name@Port extends OutDataPort<@idl@Operations,@type@[]> { @@ -44,7 +46,7 @@ public class Out@name@Port extends OutDataPort<@idl@Operations,@type@[]> { public Out@name@Port(String portName, Logger logger, ConnectionEventListener eventCB) { super(portName, logger, eventCB, new @name@Size()); if (this.logger != null) { - this.logger.debug("bulkio.OutPort CTOR port: " + portName); + this.logger.debug("bulkio.OutPort CTOR port: " + portName); } } @@ -69,8 +71,8 @@ public class Out@name@Port extends OutDataPort<@idl@Operations,@type@[]> { return new @type@[0]; } - public String getRepid() { - return BULKIO.@idl@Helper.id(); - } + public String getRepid() { + return BULKIO.@idl@Helper.id(); + } } From d169f442877ae0d453e61f6ea9088e38d4538986 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 31 Dec 2015 09:46:15 -0500 Subject: [PATCH 0011/1644] Fold Java source into main JAR file and drop source JARs; correct some warnings from -Xlint in Java implementations and minor cleanup --- bulkioInterfaces/Makefile.am | 18 +++------------ bulkioInterfaces/bulkioInterfaces.spec | 2 -- bulkioInterfaces/configure.ac | 2 +- bulkioInterfaces/libsrc/Makefile.am | 8 +++---- .../libsrc/java/META-INF/MANIFEST.MF.src.in | 7 ------ .../libsrc/java/src/bulkio/OutDataPort.java | 4 ++-- .../libsrc/java/src/bulkio/OutPortBase.java | 22 +++++++++---------- .../libsrc/java/src/bulkio/OutSDDSPort.java | 1 - .../libsrc/java/src/bulkio/OutVITA49Port.java | 1 - .../java/src/bulkio/linkStatistics.java | 2 +- .../java/src/bulkio/sdds/SDDSStream.java | 2 +- .../java/src/bulkio/vita49/VITA49Stream.java | 2 +- 12 files changed, 23 insertions(+), 48 deletions(-) delete mode 100644 bulkioInterfaces/libsrc/java/META-INF/MANIFEST.MF.src.in diff --git a/bulkioInterfaces/Makefile.am b/bulkioInterfaces/Makefile.am index 77f55ae8a..700eb4473 100644 --- a/bulkioInterfaces/Makefile.am +++ b/bulkioInterfaces/Makefile.am @@ -240,7 +240,6 @@ build/java/META-INF/MANIFEST.MF: Makefile.am BULKIOInterfaces.filelist @find $(IDLJ_SRC_DEST) -mindepth 1 -type d | sed 's/src\/java\///' | sed 's/\//./g' | sed 's/^/ /' | sed -e '$$ ! s/$$/,/' >> $@ java_JARFILES = BULKIOInterfaces.jar -java_DATA = BULKIOInterfaces.src.jar IDLJFLAGS = -i idl -i $(OSSIE_IDLDIR) -I $(OMNICOS_IDLDIR) -I $(OMNIORB_IDLDIR) IDLJNIFLAGS = -I idl -I $(OSSIE_IDLDIR) -I $(OMNICOS_IDLDIR) -I $(OMNIORB_IDLDIR) -Wblibname=bulkiojni @@ -256,21 +255,10 @@ idljni_IDLSRC = $(IDL_FILES) BULKIOInterfaces_jar_SOURCE = $(idlj_SOURCE) $(idljni_SOURCE) BULKIOInterfaces_jar_CLASSPATH = $(OSSIE_CLASSPATH) BULKIOInterfaces_jar_MANIFEST = build/java/META-INF/MANIFEST.MF +BULKIOInterfaces_jar_JAVACFLAGS = -g +BULKIOInterfaces_jar_JARADD = -C $(IDLJ_SRC_DEST) . -src/java/META-INF/MANIFEST.MF: Makefile - @mkdir -p src/java/META-INF - @rm -f $@ - @echo "Bundle-ManifestVersion: 2" >> $@ - @echo "Bundle-Name: $(BUNDLE_NAME) Source" >> $@ - @echo "Bundle-SymbolicName: $(BUNDLE_SYMBOLIC_NAME).src" >> $@ - @echo "Bundle-Version: $(BUNDLE_VERSION).$(BUNDLE_QUALIFIER)" >> $@ - @echo "Bundle-Vendor: $(BUNDLE_VENDOR)" >> $@ - @echo "Eclipse-SourceBundle: $(BUNDLE_SYMBOLIC_NAME);version=$(BUNDLE_VERSION).$(BUNDLE_QUALIFIER)" >> $@ - -CLEANFILES = BULKIOInterfaces.src.jar src/java/META-INF/MANIFEST.MF $(BULKIOInterfaces_jar_MANIFEST) - -BULKIOInterfaces.src.jar: src/java/META-INF/MANIFEST.MF $(BULKIOInterfaces_jar_SOURCE) - $(RH_V_JAR)$(JAR) cMf $@ -C $(IDLJ_SRC_DEST) . +CLEANFILES = $(BULKIOInterfaces_jar_MANIFEST) # JNI library must be built after the current directory (see SUBDIRS above) SUBDIRS += jni diff --git a/bulkioInterfaces/bulkioInterfaces.spec b/bulkioInterfaces/bulkioInterfaces.spec index c145aad28..ce3230c0e 100644 --- a/bulkioInterfaces/bulkioInterfaces.spec +++ b/bulkioInterfaces/bulkioInterfaces.spec @@ -83,9 +83,7 @@ rm -rf --preserve-root $RPM_BUILD_ROOT %endif %if %{with java} %{_prefix}/lib/BULKIOInterfaces.jar -%{_prefix}/lib/BULKIOInterfaces.src.jar %{_prefix}/lib/bulkio.jar -%{_prefix}/lib/bulkio.src.jar %{_prefix}/%{_lib}/libbulkiojni.* %endif diff --git a/bulkioInterfaces/configure.ac b/bulkioInterfaces/configure.ac index f5c09f242..bdc3a2f16 100644 --- a/bulkioInterfaces/configure.ac +++ b/bulkioInterfaces/configure.ac @@ -139,7 +139,7 @@ AM_CONDITIONAL(HAVE_JAVASUPPORT, test $HAVE_JAVASUPPORT = yes) AC_CONFIG_FILES([bulkioInterfaces.pc setup.py Makefile jni/Makefile]) if test "$enable_base_classes" != "no"; then if test "$HAVE_JAVASUPPORT = yes"; then - AC_CONFIG_FILES([libsrc/java/META-INF/MANIFEST.MF libsrc/java/META-INF/MANIFEST.MF.src]) + AC_CONFIG_FILES([libsrc/java/META-INF/MANIFEST.MF]) fi AC_CONFIG_FILES([libsrc/Makefile libsrc/bulkio.pc]) fi diff --git a/bulkioInterfaces/libsrc/Makefile.am b/bulkioInterfaces/libsrc/Makefile.am index ed2982262..cf7222aad 100644 --- a/bulkioInterfaces/libsrc/Makefile.am +++ b/bulkioInterfaces/libsrc/Makefile.am @@ -189,19 +189,17 @@ JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/OutUInt8Port.java java_JARFILES = bulkio.jar -java_DATA = bulkio.src.jar bulkio_jar_SOURCE = $(addprefix $(JAVA_SRCDIR)/bulkio/,$(JAVA_SRCS)) $(JAVA_BUILT_SOURCE) bulkio_jar_CLASSPATH = $(OSSIE_CLASSPATH):$(top_builddir)/BULKIOInterfaces.jar bulkio_jar_MANIFEST = $(JAVA_DIR)/META-INF/MANIFEST.MF +bulkio_jar_JARADD = -C $(JAVA_SRCDIR) bulkio +bulkio_jar_JAVACFLAGS = -g -Xlint bulkio.jar: $(top_builddir)/BULKIOInterfaces.jar -bulkio.src.jar: $(JAVA_DIR)/META-INF/MANIFEST.MF.src $(bulkio_jar_SOURCE) - $(RH_V_JAR)$(JAR) cmf $< $@ -C $(JAVA_SRCDIR) . - BUILT_SOURCES = $(JAVA_BUILT_SOURCE) -CLEANFILES = bulkio.src.jar $(BUILT_SOURCES) +CLEANFILES = $(BUILT_SOURCES) endif diff --git a/bulkioInterfaces/libsrc/java/META-INF/MANIFEST.MF.src.in b/bulkioInterfaces/libsrc/java/META-INF/MANIFEST.MF.src.in deleted file mode 100644 index 470d5afd6..000000000 --- a/bulkioInterfaces/libsrc/java/META-INF/MANIFEST.MF.src.in +++ /dev/null @@ -1,7 +0,0 @@ -Bundle-ManifestVersion: 2 -Bundle-Name: BULKIO Base Class Library Source -Bundle-SymbolicName: bulkio.src -Bundle-Version: @BULKIO_API_VERSION@ -Bundle-RequiredExecutionEnvironment: JavaSE-1.6 -Bundle-Vendor: REDHAWK -Eclipse-SourceBundle: bulkio;version=@BULKIO_API_VERSION@ diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/OutDataPort.java b/bulkioInterfaces/libsrc/java/src/bulkio/OutDataPort.java index 2da94844b..54cdd48d9 100644 --- a/bulkioInterfaces/libsrc/java/src/bulkio/OutDataPort.java +++ b/bulkioInterfaces/libsrc/java/src/bulkio/OutDataPort.java @@ -39,7 +39,7 @@ public abstract class OutDataPort extend /** * Size of a single element */ - protected final SizeOf sizeof; + protected final SizeOf< ? > sizeof; /** * CORBA transfer limit in samples @@ -48,7 +48,7 @@ public abstract class OutDataPort extend protected List filterTable = null; - protected OutDataPort(String portName, Logger logger, ConnectionEventListener connectionListener, SizeOf size) { + protected OutDataPort(String portName, Logger logger, ConnectionEventListener connectionListener, SizeOf< ? > size) { super(portName, logger, connectionListener); this.sizeof = size; // Make sure max samples per push is even so that complex data case is diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/OutPortBase.java b/bulkioInterfaces/libsrc/java/src/bulkio/OutPortBase.java index 69a43ccc8..ff896a3c7 100644 --- a/bulkioInterfaces/libsrc/java/src/bulkio/OutPortBase.java +++ b/bulkioInterfaces/libsrc/java/src/bulkio/OutPortBase.java @@ -28,14 +28,13 @@ import org.apache.log4j.Logger; import ExtendedCF.UsesConnection; +import org.ossie.component.PortBase; import BULKIO.PortUsageType; import BULKIO.StreamSRI; import BULKIO.UsesPortStatistics; -import org.ossie.component.PortBase; - -public abstract class OutPortBase extends BULKIO.UsesPortStatisticsProviderPOA implements org.ossie.component.PortBase { +public abstract class OutPortBase extends BULKIO.UsesPortStatisticsProviderPOA implements PortBase { /** * Name within the component */ @@ -129,6 +128,7 @@ public void setConnectionEventListener(ConnectionEventListener newListener){ /** * @deprecated */ + @Deprecated public HashMap getPorts() { return new HashMap(); } @@ -201,13 +201,13 @@ public StreamSRI[] activeSRIs() return sriList.toArray(new StreamSRI[0]); } - public String getRepid() - { - return "IDL:CORBA/Object:1.0"; - } + public String getRepid() + { + return "IDL:CORBA/Object:1.0"; + } - public String getDirection() - { - return CF.PortSet.DIRECTION_USES; - } + public String getDirection() + { + return CF.PortSet.DIRECTION_USES; + } } diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/OutSDDSPort.java b/bulkioInterfaces/libsrc/java/src/bulkio/OutSDDSPort.java index c823c84b8..b51219b00 100644 --- a/bulkioInterfaces/libsrc/java/src/bulkio/OutSDDSPort.java +++ b/bulkioInterfaces/libsrc/java/src/bulkio/OutSDDSPort.java @@ -351,7 +351,6 @@ public void updateSRIForAllConnections() { String streamId; Set streamConnIds = new HashSet(); Set currentSRIConnIds = new HashSet(); - Iterator connIdIter; // Iterate through all registered streams for (SDDSStream s: this.streamContainer.getStreams()){ diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/OutVITA49Port.java b/bulkioInterfaces/libsrc/java/src/bulkio/OutVITA49Port.java index d7fa0b6d6..004e8805b 100644 --- a/bulkioInterfaces/libsrc/java/src/bulkio/OutVITA49Port.java +++ b/bulkioInterfaces/libsrc/java/src/bulkio/OutVITA49Port.java @@ -351,7 +351,6 @@ public void updateSRIForAllConnections() { String streamId; Set streamConnIds = new HashSet(); Set currentSRIConnIds = new HashSet(); - Iterator connIdIter; // Iterate through all registered streams for (VITA49Stream s: this.streamContainer.getStreams()){ diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/linkStatistics.java b/bulkioInterfaces/libsrc/java/src/bulkio/linkStatistics.java index 731a0f479..378c543be 100644 --- a/bulkioInterfaces/libsrc/java/src/bulkio/linkStatistics.java +++ b/bulkioInterfaces/libsrc/java/src/bulkio/linkStatistics.java @@ -156,7 +156,7 @@ public PortStatistics retrieve() { this.runningStats.timeSinceLastCall = (float)(secs - front_sec); this.runningStats.bitsPerSecond = (float)((totalData * this.bitSize) / totalTime); this.runningStats.elementsPerSecond = (float)(totalData / totalTime); - this.runningStats.averageQueueDepth = (float)(queueSize / receivedSize); + this.runningStats.averageQueueDepth = queueSize / receivedSize; this.runningStats.callsPerSecond = (float)((receivedSize - 1) / totalTime); this.runningStats.streamIDs = this.activeStreamIDs.toArray(new String[0]); if (flushTime != 0.0) { diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/sdds/SDDSStream.java b/bulkioInterfaces/libsrc/java/src/bulkio/sdds/SDDSStream.java index 4f1c46b92..e4f740836 100644 --- a/bulkioInterfaces/libsrc/java/src/bulkio/sdds/SDDSStream.java +++ b/bulkioInterfaces/libsrc/java/src/bulkio/sdds/SDDSStream.java @@ -261,7 +261,7 @@ public void updateAttachments(SDDSStreamAttachment[] expectedAttachments) throws String existingConnectionId = nextAttachment.getConnectionId(); boolean detachConnection = true; - Iterator expectedConnIdIter = expectedConnectionIds.iterator(); + Iterator expectedConnIdIter = expectedConnectionIds.iterator(); while (expectedConnIdIter.hasNext()){ if (existingConnectionId.equals(expectedConnIdIter.next())){ detachConnection = false; diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/vita49/VITA49Stream.java b/bulkioInterfaces/libsrc/java/src/bulkio/vita49/VITA49Stream.java index 78ea454a7..f03e94868 100644 --- a/bulkioInterfaces/libsrc/java/src/bulkio/vita49/VITA49Stream.java +++ b/bulkioInterfaces/libsrc/java/src/bulkio/vita49/VITA49Stream.java @@ -261,7 +261,7 @@ public void updateAttachments(VITA49StreamAttachment[] expectedAttachments) thro String existingConnectionId = nextAttachment.getConnectionId(); boolean detachConnection = true; - Iterator expectedConnIdIter = expectedConnectionIds.iterator(); + Iterator expectedConnIdIter = expectedConnectionIds.iterator(); while (expectedConnIdIter.hasNext()){ if (existingConnectionId.equals(expectedConnIdIter.next())){ detachConnection = false; From 4998b1a3dc89b4e60552e09a01952212593efa77 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 31 Dec 2015 11:42:28 -0500 Subject: [PATCH 0012/1644] Move filter table and helper methods to Java base output port class --- .../libsrc/java/src/bulkio/OutDataPort.java | 44 ----------------- .../libsrc/java/src/bulkio/OutFilePort.java | 4 -- .../libsrc/java/src/bulkio/OutPortBase.java | 47 +++++++++++++++++++ .../libsrc/java/src/bulkio/OutSDDSPort.java | 5 +- .../libsrc/java/src/bulkio/OutVITA49Port.java | 4 +- .../libsrc/java/src/bulkio/OutXMLPort.java | 8 ---- 6 files changed, 49 insertions(+), 63 deletions(-) diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/OutDataPort.java b/bulkioInterfaces/libsrc/java/src/bulkio/OutDataPort.java index 54cdd48d9..3eef48658 100644 --- a/bulkioInterfaces/libsrc/java/src/bulkio/OutDataPort.java +++ b/bulkioInterfaces/libsrc/java/src/bulkio/OutDataPort.java @@ -46,8 +46,6 @@ public abstract class OutDataPort extend */ protected int maxSamplesPerPush; - protected List filterTable = null; - protected OutDataPort(String portName, Logger logger, ConnectionEventListener connectionListener, SizeOf< ? > size) { super(portName, logger, connectionListener); this.sizeof = size; @@ -248,48 +246,6 @@ public void pushSRI(StreamSRI header) } } - public void updateConnectionFilter(List _filterTable) { - this.filterTable = _filterTable; - } - - protected boolean isStreamRoutedToConnection(final String streamID, final String connectionID) - { - // Is this port listed in the filter table? - boolean portListed = false; - - // Check the filter table for this stream/connection pair. - for (connection_descriptor_struct filter : bulkio.utils.emptyIfNull(this.filterTable)) { - // Ignore filters for other ports - if (!this.name.equals(filter.port_name.getValue())) { - continue; - } - // Filtering is in effect for this port - portListed = true; - - if (connectionID.equals(filter.connection_id.getValue()) && - streamID.equals(filter.stream_id.getValue())) { - if (logger != null) { - logger.trace("OutPort FilterMatch port:" + this.name + " connection:" + connectionID + - " streamID:" + streamID); - } - return true; - } - } - - // If the port was not listed and we made it to here, there is no - // filter in effect, so send the packet or SRI; otherwise, it was - // listed and there is no route. - if (!portListed) { - if (logger != null) { - logger.trace("OutPort NO Filter port:" + this.name + " connection:" + connectionID + - " streamID:" + streamID); - } - return true; - } else { - return false; - } - } - private void pushOversizedPacket(A data, PrecisionUTCTime time, boolean endOfStream, String streamID) { final int length = arraySize(data); diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/OutFilePort.java b/bulkioInterfaces/libsrc/java/src/bulkio/OutFilePort.java index 8612581c8..5c13e22d1 100644 --- a/bulkioInterfaces/libsrc/java/src/bulkio/OutFilePort.java +++ b/bulkioInterfaces/libsrc/java/src/bulkio/OutFilePort.java @@ -44,9 +44,6 @@ */ public class OutFilePort extends OutPortBase { - protected List filterTable = null; - - public OutFilePort(String portName ){ this( portName, null, null ); } @@ -63,7 +60,6 @@ public OutFilePort(String portName, Logger logger, ConnectionEventListener eventCB ) { super(portName, logger, eventCB); - filterTable = null; if ( this.logger != null ) { this.logger.debug( "bulkio.OutPort CTOR port: " + portName ); } diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/OutPortBase.java b/bulkioInterfaces/libsrc/java/src/bulkio/OutPortBase.java index ff896a3c7..10e7f209c 100644 --- a/bulkioInterfaces/libsrc/java/src/bulkio/OutPortBase.java +++ b/bulkioInterfaces/libsrc/java/src/bulkio/OutPortBase.java @@ -75,6 +75,11 @@ public abstract class OutPortBase extends BULKIO.UsesPortStatisticsProviderPO */ protected final Map currentSRIs = new HashMap(); + /** + * Table of port names, connection IDs and stream IDs for connection-based routing + */ + protected List filterTable = null; + protected OutPortBase(String portName) { this(portName, null, null); } @@ -210,4 +215,46 @@ public String getDirection() { return CF.PortSet.DIRECTION_USES; } + + public void updateConnectionFilter(List filterTable) { + this.filterTable = filterTable; + } + + protected boolean isStreamRoutedToConnection(final String streamID, final String connectionID) + { + // Is this port listed in the filter table? + boolean portListed = false; + + // Check the filter table for this stream/connection pair. + for (connection_descriptor_struct filter : bulkio.utils.emptyIfNull(this.filterTable)) { + // Ignore filters for other ports + if (!this.name.equals(filter.port_name.getValue())) { + continue; + } + // Filtering is in effect for this port + portListed = true; + + if (connectionID.equals(filter.connection_id.getValue()) && + streamID.equals(filter.stream_id.getValue())) { + if (logger != null) { + logger.trace("OutPort FilterMatch port:" + this.name + " connection:" + connectionID + + " streamID:" + streamID); + } + return true; + } + } + + // If the port was not listed and we made it to here, there is no + // filter in effect, so send the packet or SRI; otherwise, it was + // listed and there is no route. + if (!portListed) { + if (logger != null) { + logger.trace("OutPort NO Filter port:" + this.name + " connection:" + connectionID + + " streamID:" + streamID); + } + return true; + } else { + return false; + } + } } diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/OutSDDSPort.java b/bulkioInterfaces/libsrc/java/src/bulkio/OutSDDSPort.java index b51219b00..aa42877ab 100644 --- a/bulkioInterfaces/libsrc/java/src/bulkio/OutSDDSPort.java +++ b/bulkioInterfaces/libsrc/java/src/bulkio/OutSDDSPort.java @@ -66,8 +66,6 @@ public class OutSDDSPort extends OutPortBase { */ protected SDDSStreamContainer streamContainer; - protected List filterTable = null; - public OutSDDSPort(String portName ){ this( portName, null, null ); } @@ -84,7 +82,6 @@ public OutSDDSPort(String portName, Logger logger, ConnectionEventListener eventCB ) { super(portName, logger, eventCB); - this.filterTable = null; this.streamContainer = new SDDSStreamContainer(); this.userId = new String("defaultUserId"); if ( this.logger != null ) { @@ -218,7 +215,7 @@ public void pushSRI(StreamSRI header, PrecisionUTCTime time) } public void updateConnectionFilter(List _filterTable) { - this.filterTable = _filterTable; + super.updateConnectionFilter(_filterTable); //1. loop over fitlerTable // A. ignore other port names diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/OutVITA49Port.java b/bulkioInterfaces/libsrc/java/src/bulkio/OutVITA49Port.java index 004e8805b..56b6790e7 100644 --- a/bulkioInterfaces/libsrc/java/src/bulkio/OutVITA49Port.java +++ b/bulkioInterfaces/libsrc/java/src/bulkio/OutVITA49Port.java @@ -66,8 +66,6 @@ public class OutVITA49Port extends OutPortBase { */ protected VITA49StreamContainer streamContainer; - protected List filterTable = null; - public OutVITA49Port(String portName ){ this( portName, null, null ); } @@ -218,7 +216,7 @@ public void pushSRI(StreamSRI header, PrecisionUTCTime time) } public void updateConnectionFilter(List _filterTable) { - this.filterTable = _filterTable; + super.updateConnectionFilter(_filterTable); //1. loop over fitlerTable // A. ignore other port names diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/OutXMLPort.java b/bulkioInterfaces/libsrc/java/src/bulkio/OutXMLPort.java index e4d191691..569f77c27 100644 --- a/bulkioInterfaces/libsrc/java/src/bulkio/OutXMLPort.java +++ b/bulkioInterfaces/libsrc/java/src/bulkio/OutXMLPort.java @@ -44,9 +44,6 @@ */ public class OutXMLPort extends OutPortBase { - protected List filterTable = null; - - public OutXMLPort(String portName ){ this( portName, null, null ); } @@ -63,7 +60,6 @@ public OutXMLPort(String portName, Logger logger, ConnectionEventListener eventCB ) { super(portName, logger, eventCB); - filterTable = null; if ( this.logger != null ) { this.logger.debug( "bulkio.OutPort CTOR port: " + portName ); } @@ -181,10 +177,6 @@ public void pushSRI(StreamSRI header) return; } - public void updateConnectionFilter(List _filterTable) { - this.filterTable = _filterTable; - }; - public void pushPacket(String data, PrecisionUTCTime time, boolean endOfStream, String streamID) { pushPacket( data, endOfStream, streamID ); } From e04bb45e1fbc279fd896f2a8db43d1903db9a110 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 31 Dec 2015 12:17:04 -0500 Subject: [PATCH 0013/1644] Refactor Java output port class hierarchy to allow XML and File to use the same base implementation as the data types --- bulkioInterfaces/libsrc/Makefile.am | 1 + .../libsrc/java/src/bulkio/OutDataPort.java | 17 +- .../libsrc/java/src/bulkio/OutFilePort.java | 360 +----------------- .../java/src/bulkio/OutPort.java.template | 2 +- .../libsrc/java/src/bulkio/OutStreamPort.java | 80 ++++ .../libsrc/java/src/bulkio/OutXMLPort.java | 355 +---------------- 6 files changed, 130 insertions(+), 685 deletions(-) create mode 100644 bulkioInterfaces/libsrc/java/src/bulkio/OutStreamPort.java diff --git a/bulkioInterfaces/libsrc/Makefile.am b/bulkioInterfaces/libsrc/Makefile.am index cf7222aad..cfbb6fb17 100644 --- a/bulkioInterfaces/libsrc/Makefile.am +++ b/bulkioInterfaces/libsrc/Makefile.am @@ -132,6 +132,7 @@ OutLongPort.java \ OutOctetPort.java \ OutPortBase.java \ OutSDDSPort.java \ +OutStreamPort.java \ OutVITA49Port.java \ OutShortPort.java \ OutULongLongPort.java \ diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/OutDataPort.java b/bulkioInterfaces/libsrc/java/src/bulkio/OutDataPort.java index 3eef48658..52ca342b2 100644 --- a/bulkioInterfaces/libsrc/java/src/bulkio/OutDataPort.java +++ b/bulkioInterfaces/libsrc/java/src/bulkio/OutDataPort.java @@ -30,12 +30,6 @@ import BULKIO.StreamSRI; public abstract class OutDataPort extends OutPortBase { - /** - * CORBA transfer limit in bytes - */ - // Multiply by some number < 1 to leave some margin for the CORBA header - protected static final int MAX_PAYLOAD_SIZE = (int)(Const.MAX_TRANSFER_BYTES * 0.9); - /** * Size of a single element */ @@ -49,9 +43,6 @@ public abstract class OutDataPort extend protected OutDataPort(String portName, Logger logger, ConnectionEventListener connectionListener, SizeOf< ? > size) { super(portName, logger, connectionListener); this.sizeof = size; - // Make sure max samples per push is even so that complex data case is - // handled properly - this.maxSamplesPerPush = (MAX_PAYLOAD_SIZE/this.sizeof.sizeof()) & 0xFFFFFFFE; } /** @@ -167,7 +158,7 @@ public void pushPacket(A data, PrecisionUTCTime time, boolean endOfStream, Strin this.pushSRI(header); } - pushOversizedPacket(data, time, endOfStream, streamID); + doPushPacket(data, time, endOfStream, streamID); } if (logger != null) { @@ -175,6 +166,11 @@ public void pushPacket(A data, PrecisionUTCTime time, boolean endOfStream, Strin } } + protected void doPushPacket(A data, PrecisionUTCTime time, boolean endOfStream, String streamID) + { + pushSinglePacket(data, time, endOfStream, streamID); + } + /** * Sends out SRI describing the data payload. * @@ -347,7 +343,6 @@ private void pushSinglePacket(A data, PrecisionUTCTime time, boolean endOfStream protected abstract E narrow(org.omg.CORBA.Object obj); protected abstract void sendPacket(E port, A data, PrecisionUTCTime time, boolean endOfStream, String streamID); - protected abstract A copyOfRange(A array, int start, int end); protected abstract int arraySize(A array); protected abstract A emptyArray(); } diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/OutFilePort.java b/bulkioInterfaces/libsrc/java/src/bulkio/OutFilePort.java index 5c13e22d1..31d0350b1 100644 --- a/bulkioInterfaces/libsrc/java/src/bulkio/OutFilePort.java +++ b/bulkioInterfaces/libsrc/java/src/bulkio/OutFilePort.java @@ -19,367 +19,49 @@ */ package bulkio; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Set; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; import org.apache.log4j.Logger; -import CF.DataType; + import BULKIO.PrecisionUTCTime; import BULKIO.StreamSRI; import BULKIO.dataFileOperations; -import bulkio.linkStatistics; -import bulkio.Int8Size; -import bulkio.ConnectionEventListener; -import bulkio.connection_descriptor_struct; -import bulkio.SriMapStruct; -import org.ossie.properties.*; - /** - * + * BulkIO output port implementation for dataFile. */ -public class OutFilePort extends OutPortBase { +public class OutFilePort extends OutDataPort { - public OutFilePort(String portName ){ - this( portName, null, null ); + public OutFilePort(String portName) { + this(portName, null, null); } - public OutFilePort(String portName, - Logger logger ) { - this( portName, logger, null ); + public OutFilePort(String portName, Logger logger) { + this(portName, logger, null); } - /** - * @generated - */ - public OutFilePort(String portName, - Logger logger, - ConnectionEventListener eventCB ) { - super(portName, logger, eventCB); - if ( this.logger != null ) { - this.logger.debug( "bulkio.OutPort CTOR port: " + portName ); + public OutFilePort(String portName, Logger logger, ConnectionEventListener eventCB) { + super(portName, logger, eventCB, new Int8Size()); + if (this.logger != null) { + this.logger.debug("bulkio.OutPort CTOR port: " + portName); } } - /** - * pushSRI - * description: send out SRI describing the data payload - * - * H: structure of type BULKIO.StreamSRI with the SRI for this stream - * hversion - * xstart: start time of the stream - * xdelta: delta between two samples - * xunits: unit types from Platinum specification - * subsize: 0 if the data is one-dimensional - * ystart - * ydelta - * yunits: unit types from Platinum specification - * mode: 0-scalar, 1-complex - * streamID: stream identifier - * sequence keywords: unconstrained sequence of key-value pairs for additional description - * @generated - */ - public void pushSRI(StreamSRI header) - { - if ( logger != null ) { - logger.trace("bulkio.OutPort pushSRI ENTER (port=" + name +")" ); - } - - // Header cannot be null - if (header == null) { - if ( logger != null ) { - logger.trace("bulkio.OutPort pushSRI EXIT (port=" + name +")" ); - } - return; - } - - if (header.streamID == null) { - throw new NullPointerException("SRI streamID cannot be null"); - } - - // Header cannot have null keywords - if (header.keywords == null) header.keywords = new DataType[0]; - - synchronized(this.updatingPortsLock) { // don't want to process while command information is coming in - this.currentSRIs.put(header.streamID, new SriMapStruct(header)); - if (this.active) { - // state if this port is not listed in the filter table... then pushSRI down stream - boolean portListed = false; - - // for each connection - for (Entry p : this.outConnections.entrySet()) { - - // if connection is in the filter table - for (connection_descriptor_struct ftPtr : bulkio.utils.emptyIfNull(this.filterTable) ) { - - // if there is an entry for this port in the filter table....so save that state - if (ftPtr.port_name.getValue().equals(this.name)) { - portListed = true; - } - - if ( logger != null ) { - logger.trace( "pushSRI - FilterMatch port:" + this.name + " connection:" + p.getKey() + - " streamID:" + header.streamID ); - } - - if ( (ftPtr.port_name.getValue().equals(this.name)) && - (ftPtr.connection_id.getValue().equals(p.getKey())) && - (ftPtr.stream_id.getValue().equals(header.streamID))) { - try { - if ( logger != null ) { - logger.trace( "pushSRI - FilterMatch port:" + this.name + " connection:" + p.getKey() + - " streamID:" + header.streamID ); - } - p.getValue().pushSRI(header); - //Update entry in currentSRIs - this.currentSRIs.get(header.streamID).connections.add(p.getKey()); - - } catch(Exception e) { - if ( logger != null ) { - logger.error("Call to pushSRI failed on port " + name + " connection " + p.getKey() ); - } - } - } - } - } - - // no entry exists for this port in the filter table so all connections get SRI data - if (!portListed ) { - for (Entry p : this.outConnections.entrySet()) { - try { - if ( logger != null ) { - logger.trace( "pushSRI - NO Filter port:" + this.name + " connection:" + p.getKey() + - " streamID:" + header.streamID ); - } - p.getValue().pushSRI(header); - //Update entry in currentSRIs - this.currentSRIs.get(header.streamID).connections.add(p.getKey()); - } catch(Exception e) { - if ( logger != null ) { - logger.error("Call to pushSRI failed on port " + name + " connection " + p.getKey() ); - } - } - } - } - - - } - - - } // don't want to process while command information is coming in - - - if ( logger != null ) { - logger.trace("bulkio.OutPort pushSRI EXIT (port=" + name +")" ); - } - return; + public String getRepid() { + return BULKIO.dataFileHelper.id(); } - public void updateConnectionFilter(List _filterTable) { - this.filterTable = _filterTable; - }; - - /** - * @generated - */ - public void pushPacket(String data, PrecisionUTCTime time, boolean endOfStream, String streamID) - { - if ( logger != null ) { - logger.trace("bulkio.OutPort pushPacket ENTER (port=" + name +")" ); - } - - if (!this.currentSRIs.containsKey(streamID)) { - StreamSRI header = bulkio.sri.utils.create(); - header.streamID = streamID; - this.pushSRI(header); - } - SriMapStruct sriStruct = this.currentSRIs.get(streamID); - - synchronized(this.updatingPortsLock) { // don't want to process while command information is coming in - String odata = data; - if (this.active) { - boolean portListed = false; - for (Entry p : this.outConnections.entrySet()) { - - for (connection_descriptor_struct ftPtr : bulkio.utils.emptyIfNull(this.filterTable) ) { - - if (ftPtr.port_name.getValue().equals(this.name)) { - portListed = true; - } - if ( (ftPtr.port_name.getValue().equals(this.name)) && - (ftPtr.connection_id.getValue().equals(p.getKey())) && - (ftPtr.stream_id.getValue().equals(streamID)) ) { - try { - //If SRI for given streamID has not been pushed to this connection, push it - if (!sriStruct.connections.contains(p.getKey())){ - p.getValue().pushSRI(sriStruct.sri); - sriStruct.connections.add(p.getKey()); - } - p.getValue().pushPacket( odata, time, endOfStream, streamID); - this.stats.get(p.getKey()).update( odata.length(), (float)0.0, endOfStream, streamID, false); - } catch(Exception e) { - if ( logger != null ) { - logger.error("Call to pushPacket failed on port " + name + " connection " + p.getKey() ); - } - } - } - } - } - - if (!portListed ){ - for (Entry p : this.outConnections.entrySet()) { - try { - //If SRI for given streamID has not been pushed to this connection, push it - if (!sriStruct.connections.contains(p.getKey())){ - p.getValue().pushSRI(sriStruct.sri); - sriStruct.connections.add(p.getKey()); - } - p.getValue().pushPacket( odata, time, endOfStream, streamID); - this.stats.get(p.getKey()).update( odata.length(), (float)0.0, endOfStream, streamID, false); - } catch(Exception e) { - if ( logger != null ) { - logger.error("Call to pushPacket failed on port " + name + " connection " + p.getKey() ); - } - } - } - } - } - - if ( endOfStream ) { - if ( this.currentSRIs.containsKey(streamID) ) { - this.currentSRIs.remove(streamID); - } - } - - } // don't want to process while command information is coming in - - if ( logger != null ) { - logger.trace("bulkio.OutPort pushPacket EXIT (port=" + name +")" ); - } - return; - + protected dataFileOperations narrow(org.omg.CORBA.Object obj) { + return BULKIO.dataFileHelper.narrow(obj); } - - /** - * @generated - */ - public void connectPort(final org.omg.CORBA.Object connection, final String connectionId) throws CF.PortPackage.InvalidPort, CF.PortPackage.OccupiedPort - { - - if ( logger != null ) { - logger.trace("bulkio.OutPort connectPort ENTER (port=" + name +")" ); - } - - synchronized (this.updatingPortsLock) { - final dataFileOperations port; - try { - port = BULKIO.jni.dataFileHelper.narrow(connection); - } catch (final Exception ex) { - if ( logger != null ) { - logger.error("bulkio.OutPort CONNECT PORT: " + name + " PORT NARROW FAILED"); - } - throw new CF.PortPackage.InvalidPort((short)1, "Invalid port for connection '" + connectionId + "'"); - } - this.outConnections.put(connectionId, port); - this.active = true; - this.stats.put(connectionId, new linkStatistics( this.name, new Int8Size() ) ); - - if ( logger != null ) { - logger.debug("bulkio.OutPort CONNECT PORT: " + name + " CONNECTION '" + connectionId + "'"); - } - } - - if ( logger != null ) { - logger.trace("bulkio.OutPort connectPort EXIT (port=" + name +")" ); - } - - if ( callback != null ) { - callback.connect(connectionId); - } + protected String emptyArray() { + return ""; } - /** - * @generated - */ - public void disconnectPort(String connectionId) { - if ( logger != null ) { - logger.trace("bulkio.OutPort disconnectPort ENTER (port=" + name +")" ); - } - synchronized (this.updatingPortsLock) { - boolean portListed = false; - for (connection_descriptor_struct ftPtr : bulkio.utils.emptyIfNull(this.filterTable) ) { - if (ftPtr.port_name.getValue().equals(this.name)) { - portListed = true; - break; - } - } - dataFileOperations port = this.outConnections.remove(connectionId); - if (port != null) - { - String odata = ""; - BULKIO.PrecisionUTCTime tstamp = bulkio.time.utils.notSet(); - for (Map.Entry entry: this.currentSRIs.entrySet()) { - String streamID = entry.getKey(); - if (entry.getValue().connections.contains(connectionId)) { - if (portListed) { - for (connection_descriptor_struct ftPtr : bulkio.utils.emptyIfNull(this.filterTable)) { - if ( (ftPtr.port_name.getValue().equals(this.name)) && - (ftPtr.connection_id.getValue().equals(connectionId)) && - (ftPtr.stream_id.getValue().equals(streamID))) { - try { - port.pushPacket(odata,tstamp,true,streamID); - } catch(Exception e) { - if ( logger != null ) { - logger.error("Call to pushPacket failed on port " + name + " connection " + connectionId ); - } - } - } - } - } else { - try { - port.pushPacket(odata,tstamp,true,streamID); - } catch(Exception e) { - if ( logger != null ) { - logger.error("Call to pushPacket failed on port " + name + " connection " + connectionId ); - } - } - } - } - } - } - this.stats.remove(connectionId); - this.active = (this.outConnections.size() != 0); - - // Remove connectionId from any sets in the currentSRIs.connections values - for(Map.Entry entry : this.currentSRIs.entrySet()) { - entry.getValue().connections.remove(connectionId); - } - - if ( logger != null ) { - logger.trace("bulkio.OutPort DISCONNECT PORT:" + name + " CONNECTION '" + connectionId + "'"); - for(Map.Entry entry: this.currentSRIs.entrySet()) { - logger.trace("bulkio.OutPort updated currentSRIs key=" + entry.getKey() + ", value.sri=" + entry.getValue().sri + ", value.connections=" + entry.getValue().connections); - } - } - } - - if ( callback != null ) { - callback.disconnect(connectionId); - } - - if ( logger != null ) { - logger.trace("bulkio.OutPort disconnectPort EXIT (port=" + name +")" ); - } + protected int arraySize(String data) { + return data.length(); } - public String getRepid() { - return BULKIO.dataFileHelper.id(); + protected void sendPacket(dataFileOperations port, String data, PrecisionUTCTime time, boolean endOfStream, String streamID) { + port.pushPacket(data, time, endOfStream, streamID); } - } - diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/OutPort.java.template b/bulkioInterfaces/libsrc/java/src/bulkio/OutPort.java.template index 4c5fecceb..1ae47fec1 100644 --- a/bulkioInterfaces/libsrc/java/src/bulkio/OutPort.java.template +++ b/bulkioInterfaces/libsrc/java/src/bulkio/OutPort.java.template @@ -33,7 +33,7 @@ import BULKIO.@idl@Operations; /** * BulkIO output port implementation for @idl@. */ -public class Out@name@Port extends OutDataPort<@idl@Operations,@type@[]> { +public class Out@name@Port extends OutStreamPort<@idl@Operations,@type@[]> { public Out@name@Port(String portName) { this(portName, null, null); diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/OutStreamPort.java b/bulkioInterfaces/libsrc/java/src/bulkio/OutStreamPort.java new file mode 100644 index 000000000..487eb76a0 --- /dev/null +++ b/bulkioInterfaces/libsrc/java/src/bulkio/OutStreamPort.java @@ -0,0 +1,80 @@ +package bulkio; + +import org.apache.log4j.Logger; + +import BULKIO.PrecisionUTCTime; + +public abstract class OutStreamPort extends OutDataPort { + /** + * CORBA transfer limit in bytes + */ + // Multiply by some number < 1 to leave some margin for the CORBA header + protected static final int MAX_PAYLOAD_SIZE = (int)(Const.MAX_TRANSFER_BYTES * 0.9); + + /** + * CORBA transfer limit in samples + */ + protected final int maxSamplesPerPush; + + protected OutStreamPort(String portName, Logger logger, ConnectionEventListener connectionListener, SizeOf< ? > size) { + super(portName, logger, connectionListener, size); + // Make sure max samples per push is even so that complex data case is + // handled properly + this.maxSamplesPerPush = (MAX_PAYLOAD_SIZE/this.sizeof.sizeof()) & 0xFFFFFFFE; + } + + protected void doPushPacket(A data, PrecisionUTCTime time, boolean endOfStream, String streamID) { + pushOversizedPacket(data, time, endOfStream, streamID); + } + + private void pushOversizedPacket(A data, PrecisionUTCTime time, boolean endOfStream, String streamID) { + final int length = arraySize(data); + + // If there is no need to break data into smaller packets, skip + // straight to the pushPacket call and return. + if (length <= this.maxSamplesPerPush) { + this.pushSinglePacket(data, time, endOfStream, streamID); + return; + } + + // Determine xdelta for this streamID to be used for time increment for subpackets + SriMapStruct sriMap = this.currentSRIs.get(streamID); + double xdelta = 0.0; + if (sriMap != null){ + xdelta = sriMap.sri.xdelta; + } + + // Initialize time of first subpacket + PrecisionUTCTime packetTime = time; + for (int offset = 0; offset < length;) { + // Don't send more samples than are remaining + final int pushSize = java.lang.Math.min(length-offset, this.maxSamplesPerPush); + + // Copy the range for this sub-packet and advance the offset + A subPacket = copyOfRange(data, offset, offset+pushSize); + offset += pushSize; + + // Send end-of-stream as false for all sub-packets except for the + // last one (when there are no samples remaining after this push), + // which gets the input EOS. + boolean packetEOS = false; + if (offset == length) { + packetEOS = endOfStream; + } + + if (logger != null) { + logger.trace("bulkio.OutPort pushOversizedPacket() calling pushPacket with pushSize " + pushSize + " and packetTime twsec: " + packetTime.twsec + " tfsec: " + packetTime.tfsec); + } + this.pushSinglePacket(subPacket, packetTime, packetEOS, streamID); + int data_xfer_len = pushSize; + if (sriMap != null){ + if (sriMap.sri.mode == 1) { + data_xfer_len = data_xfer_len / 2; + } + } + packetTime = bulkio.time.utils.addSampleOffset(packetTime, data_xfer_len, xdelta); + } + } + + protected abstract A copyOfRange(A array, int start, int end); +} diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/OutXMLPort.java b/bulkioInterfaces/libsrc/java/src/bulkio/OutXMLPort.java index 569f77c27..daf4625a6 100644 --- a/bulkioInterfaces/libsrc/java/src/bulkio/OutXMLPort.java +++ b/bulkioInterfaces/libsrc/java/src/bulkio/OutXMLPort.java @@ -19,363 +19,50 @@ */ package bulkio; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Set; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; import org.apache.log4j.Logger; -import CF.DataType; + import BULKIO.PrecisionUTCTime; import BULKIO.StreamSRI; import BULKIO.dataXMLOperations; -import bulkio.linkStatistics; -import bulkio.Int8Size; -import bulkio.ConnectionEventListener; -import bulkio.connection_descriptor_struct; -import bulkio.SriMapStruct; -import org.ossie.properties.*; - /** - * + * BulkIO output port implementation for dataXML. */ -public class OutXMLPort extends OutPortBase { - - public OutXMLPort(String portName ){ - this( portName, null, null ); - } +public class OutXMLPort extends OutDataPort { - public OutXMLPort(String portName, - Logger logger ) { - this( portName, logger, null ); + public OutXMLPort(String portName) { + this(portName, null, null); } - /** - * @generated - */ - public OutXMLPort(String portName, - Logger logger, - ConnectionEventListener eventCB ) { - super(portName, logger, eventCB); - if ( this.logger != null ) { - this.logger.debug( "bulkio.OutPort CTOR port: " + portName ); - } + public OutXMLPort(String portName, Logger logger) { + this(portName, logger, null); } - /** - * pushSRI - * description: send out SRI describing the data payload - * - * H: structure of type BULKIO.StreamSRI with the SRI for this stream - * hversion - * xstart: start time of the stream - * xdelta: delta between two samples - * xunits: unit types from Platinum specification - * subsize: 0 if the data is one-dimensional - * ystart - * ydelta - * yunits: unit types from Platinum specification - * mode: 0-scalar, 1-complex - * streamID: stream identifier - * sequence keywords: unconstrained sequence of key-value pairs for additional description - * @generated - */ - public void pushSRI(StreamSRI header) - { - if ( logger != null ) { - logger.trace("bulkio.OutPort pushSRI ENTER (port=" + name +")" ); - } - - // Header cannot be null - if (header == null) { - if ( logger != null ) { - logger.trace("bulkio.OutPort pushSRI EXIT (port=" + name +")" ); - } - return; - } - - if (header.streamID == null) { - throw new NullPointerException("SRI streamID cannot be null"); + public OutXMLPort(String portName, Logger logger, ConnectionEventListener eventCB) { + super(portName, logger, eventCB, new Int8Size()); + if (this.logger != null) { + this.logger.debug("bulkio.OutPort CTOR port: " + portName); } - - // Header cannot have null keywords - if (header.keywords == null) header.keywords = new DataType[0]; - - synchronized(this.updatingPortsLock) { // don't want to process while command information is coming in - this.currentSRIs.put(header.streamID, new SriMapStruct(header)); - if (this.active) { - // state if this port is not listed in the filter table... then pushSRI down stream - boolean portListed = false; - - // for each connection - for (Entry p : this.outConnections.entrySet()) { - - // if connection is in the filter table - for (connection_descriptor_struct ftPtr : bulkio.utils.emptyIfNull(this.filterTable) ) { - - // if there is an entry for this port in the filter table....so save that state - if (ftPtr.port_name.getValue().equals(this.name)) { - portListed = true; - } - if ( logger != null ) { - logger.trace( "pushSRI - FilterMatch port:" + this.name + " connection:" + p.getKey() + - " streamID:" + header.streamID ); - } - if ( (ftPtr.port_name.getValue().equals(this.name)) && - (ftPtr.connection_id.getValue().equals(p.getKey())) && - (ftPtr.stream_id.getValue().equals(header.streamID))) { - try { - if ( logger != null ) { - logger.trace( "pushSRI - FilterMatch port:" + this.name + " connection:" + p.getKey() + - " streamID:" + header.streamID ); - } - p.getValue().pushSRI(header); - //Update entry in currentSRIs - this.currentSRIs.get(header.streamID).connections.add(p.getKey()); - - } catch(Exception e) { - if ( logger != null ) { - logger.error("Call to pushSRI failed on port " + name + " connection " + p.getKey() ); - } - } - } - } - } - - // no entry exists for this port in the filter table so all connections get SRI data - if (!portListed ) { - for (Entry p : this.outConnections.entrySet()) { - try { - if ( logger != null ) { - logger.trace( "pushSRI - NO Filter port:" + this.name + " connection:" + p.getKey() + - " streamID:" + header.streamID ); - } - p.getValue().pushSRI(header); - //Update entry in currentSRIs - this.currentSRIs.get(header.streamID).connections.add(p.getKey()); - } catch(Exception e) { - if ( logger != null ) { - logger.error("Call to pushSRI failed on port " + name + " connection " + p.getKey() ); - } - } - } - } - - - } - - - } // don't want to process while command information is coming in - - - if ( logger != null ) { - logger.trace("bulkio.OutPort pushSRI EXIT (port=" + name +")" ); - } - return; } - public void pushPacket(String data, PrecisionUTCTime time, boolean endOfStream, String streamID) { - pushPacket( data, endOfStream, streamID ); + public String getRepid() { + return BULKIO.dataXMLHelper.id(); } - /** - * @generated - */ - public void pushPacket(String data, boolean endOfStream, String streamID) - { - if ( logger != null ) { - logger.trace("bulkio.OutPort pushPacket ENTER (port=" + name +")" ); - } - - if (!this.currentSRIs.containsKey(streamID)) { - StreamSRI header = bulkio.sri.utils.create(); - header.streamID = streamID; - this.pushSRI(header); - } - SriMapStruct sriStruct = this.currentSRIs.get(streamID); - - synchronized(this.updatingPortsLock) { // don't want to process while command information is coming in - String odata = data; - if (this.active) { - boolean portListed = false; - for (Entry p : this.outConnections.entrySet()) { - - for (connection_descriptor_struct ftPtr : bulkio.utils.emptyIfNull(this.filterTable) ) { - - if (ftPtr.port_name.getValue().equals(this.name)) { - portListed = true; - } - if ( (ftPtr.port_name.getValue().equals(this.name)) && - (ftPtr.connection_id.getValue().equals(p.getKey())) && - (ftPtr.stream_id.getValue().equals(streamID)) ) { - try { - //If SRI for given streamID has not been pushed to this connection, push it - if (!sriStruct.connections.contains(p.getKey())){ - p.getValue().pushSRI(sriStruct.sri); - sriStruct.connections.add(p.getKey()); - } - p.getValue().pushPacket( odata, endOfStream, streamID); - this.stats.get(p.getKey()).update( odata.length(), (float)0.0, endOfStream, streamID, false); - } catch(Exception e) { - if ( logger != null ) { - logger.error("Call to pushPacket failed on port " + name + " connection " + p.getKey() ); - } - } - } - } - } - - if (!portListed ){ - for (Entry p : this.outConnections.entrySet()) { - try { - //If SRI for given streamID has not been pushed to this connection, push it - if (!sriStruct.connections.contains(p.getKey())){ - p.getValue().pushSRI(sriStruct.sri); - sriStruct.connections.add(p.getKey()); - } - p.getValue().pushPacket( odata, endOfStream, streamID); - this.stats.get(p.getKey()).update( odata.length(), (float)0.0, endOfStream, streamID, false); - } catch(Exception e) { - if ( logger != null ) { - logger.error("Call to pushPacket failed on port " + name + " connection " + p.getKey() ); - } - } - } - } - } - if ( endOfStream ) { - if ( this.currentSRIs.containsKey(streamID) ) { - this.currentSRIs.remove(streamID); - } - } - - } // don't want to process while command information is coming in - - if ( logger != null ) { - logger.trace("bulkio.OutPort pushPacket EXIT (port=" + name +")" ); - } - return; - + protected dataXMLOperations narrow(org.omg.CORBA.Object obj) { + return BULKIO.dataXMLHelper.narrow(obj); } - - /** - * @generated - */ - public void connectPort(final org.omg.CORBA.Object connection, final String connectionId) throws CF.PortPackage.InvalidPort, CF.PortPackage.OccupiedPort - { - - if ( logger != null ) { - logger.trace("bulkio.OutPort connectPort ENTER (port=" + name +")" ); - } - - synchronized (this.updatingPortsLock) { - final dataXMLOperations port; - try { - port = BULKIO.jni.dataXMLHelper.narrow(connection); - } catch (final Exception ex) { - if ( logger != null ) { - logger.error("bulkio.OutPort CONNECT PORT: " + name + " PORT NARROW FAILED"); - } - throw new CF.PortPackage.InvalidPort((short)1, "Invalid port for connection '" + connectionId + "'"); - } - this.outConnections.put(connectionId, port); - this.active = true; - this.stats.put(connectionId, new linkStatistics( this.name, new Int8Size() ) ); - - if ( logger != null ) { - logger.debug("bulkio.OutPort CONNECT PORT: " + name + " CONNECTION '" + connectionId + "'"); - } - } - - if ( logger != null ) { - logger.trace("bulkio.OutPort connectPort EXIT (port=" + name +")" ); - } - - if ( callback != null ) { - callback.connect(connectionId); - } + protected String emptyArray() { + return ""; } - /** - * @generated - */ - public void disconnectPort(String connectionId) { - if ( logger != null ) { - logger.trace("bulkio.OutPort disconnectPort ENTER (port=" + name +")" ); - } - synchronized (this.updatingPortsLock) { - boolean portListed = false; - for (connection_descriptor_struct ftPtr : bulkio.utils.emptyIfNull(this.filterTable)) { - if (ftPtr.port_name.getValue().equals(this.name)) { - portListed = true; - break; - } - } - dataXMLOperations port = this.outConnections.remove(connectionId); - if (port != null) - { - String odata = ""; - BULKIO.PrecisionUTCTime tstamp = bulkio.time.utils.notSet(); - for (Map.Entry entry: this.currentSRIs.entrySet()) { - String streamID = entry.getKey(); - if (entry.getValue().connections.contains(connectionId)) { - if (portListed) { - for (connection_descriptor_struct ftPtr : bulkio.utils.emptyIfNull(this.filterTable) ) { - if ( (ftPtr.port_name.getValue().equals(this.name)) && - (ftPtr.connection_id.getValue().equals(connectionId)) && - (ftPtr.stream_id.getValue().equals(streamID))) { - try { - port.pushPacket(odata,true,streamID); - } catch(Exception e) { - if ( logger != null ) { - logger.error("Call to pushPacket failed on port " + name + " connection " + connectionId ); - } - } - } - } - } else { - try { - port.pushPacket(odata,true,streamID); - } catch(Exception e) { - if ( logger != null ) { - logger.error("Call to pushPacket failed on port " + name + " connection " + connectionId ); - } - } - } - } - } - } - this.stats.remove(connectionId); - this.active = (this.outConnections.size() != 0); - - // Remove connectionId from any sets in the currentSRIs.connections values - for(Map.Entry entry : this.currentSRIs.entrySet()) { - entry.getValue().connections.remove(connectionId); - } - - if ( logger != null ) { - logger.trace("bulkio.OutPort DISCONNECT PORT:" + name + " CONNECTION '" + connectionId + "'"); - for(Map.Entry entry: this.currentSRIs.entrySet()) { - logger.trace("bulkio.OutPort updated currentSRIs key=" + entry.getKey() + ", value.sri=" + entry.getValue().sri + ", value.connections=" + entry.getValue().connections); - } - } - } - - if ( callback != null ) { - callback.disconnect(connectionId); - } - - if ( logger != null ) { - logger.trace("bulkio.OutPort disconnectPort EXIT (port=" + name +")" ); - } + protected int arraySize(String data) { + return data.length(); } - public String getRepid() { - return BULKIO.dataXMLHelper.id(); + protected void sendPacket(dataXMLOperations port, String data, PrecisionUTCTime time, boolean endOfStream, String streamID) { + port.pushPacket(data, endOfStream, streamID); } } From 23e46b2a33d26209e6d678c3a32763ab0f5a54d1 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 31 Dec 2015 13:05:33 -0500 Subject: [PATCH 0014/1644] Resolve remaining warnings by using int constants for Java element sizes --- bulkioInterfaces/libsrc/java/sed/Double.sed | 1 + bulkioInterfaces/libsrc/java/sed/Float.sed | 1 + bulkioInterfaces/libsrc/java/sed/Int16.sed | 1 + bulkioInterfaces/libsrc/java/sed/Int32.sed | 1 + bulkioInterfaces/libsrc/java/sed/Int64.sed | 1 + bulkioInterfaces/libsrc/java/sed/Int8.sed | 1 + bulkioInterfaces/libsrc/java/sed/UInt16.sed | 1 + bulkioInterfaces/libsrc/java/sed/UInt32.sed | 1 + bulkioInterfaces/libsrc/java/sed/UInt64.sed | 1 + bulkioInterfaces/libsrc/java/sed/UInt8.sed | 1 + .../libsrc/java/src/bulkio/InFilePort.java | 2 +- .../libsrc/java/src/bulkio/InPort.java.template | 2 +- .../libsrc/java/src/bulkio/InSDDSPort.java | 2 +- .../libsrc/java/src/bulkio/InVITA49Port.java | 2 +- .../libsrc/java/src/bulkio/InXMLPort.java | 2 +- .../libsrc/java/src/bulkio/OutDataPort.java | 2 +- .../libsrc/java/src/bulkio/OutFilePort.java | 2 +- .../libsrc/java/src/bulkio/OutPort.java.template | 2 +- .../libsrc/java/src/bulkio/OutSDDSPort.java | 2 +- .../libsrc/java/src/bulkio/OutStreamPort.java | 4 ++-- .../libsrc/java/src/bulkio/OutVITA49Port.java | 2 +- .../libsrc/java/src/bulkio/OutXMLPort.java | 2 +- .../libsrc/java/src/bulkio/linkStatistics.java | 14 ++++++++------ 23 files changed, 31 insertions(+), 19 deletions(-) diff --git a/bulkioInterfaces/libsrc/java/sed/Double.sed b/bulkioInterfaces/libsrc/java/sed/Double.sed index 07d55f6b0..866df7725 100644 --- a/bulkioInterfaces/libsrc/java/sed/Double.sed +++ b/bulkioInterfaces/libsrc/java/sed/Double.sed @@ -1,3 +1,4 @@ s/@name@/Double/g s/@type@/double/g s/@idl@/dataDouble/g +s/@size@/8/g diff --git a/bulkioInterfaces/libsrc/java/sed/Float.sed b/bulkioInterfaces/libsrc/java/sed/Float.sed index f5c59c51c..a03285f0d 100644 --- a/bulkioInterfaces/libsrc/java/sed/Float.sed +++ b/bulkioInterfaces/libsrc/java/sed/Float.sed @@ -1,3 +1,4 @@ s/@name@/Float/g s/@type@/float/g s/@idl@/dataFloat/g +s/@size@/4/g diff --git a/bulkioInterfaces/libsrc/java/sed/Int16.sed b/bulkioInterfaces/libsrc/java/sed/Int16.sed index 64612fec2..4233ef439 100644 --- a/bulkioInterfaces/libsrc/java/sed/Int16.sed +++ b/bulkioInterfaces/libsrc/java/sed/Int16.sed @@ -1,3 +1,4 @@ s/@name@/Int16/g s/@type@/short/g s/@idl@/dataShort/g +s/@size@/2/g diff --git a/bulkioInterfaces/libsrc/java/sed/Int32.sed b/bulkioInterfaces/libsrc/java/sed/Int32.sed index e2473aa1b..ff96e0ed5 100644 --- a/bulkioInterfaces/libsrc/java/sed/Int32.sed +++ b/bulkioInterfaces/libsrc/java/sed/Int32.sed @@ -1,3 +1,4 @@ s/@name@/Int32/g s/@type@/int/g s/@idl@/dataLong/g +s/@size@/4/g diff --git a/bulkioInterfaces/libsrc/java/sed/Int64.sed b/bulkioInterfaces/libsrc/java/sed/Int64.sed index d04501e0b..9bd0a1962 100644 --- a/bulkioInterfaces/libsrc/java/sed/Int64.sed +++ b/bulkioInterfaces/libsrc/java/sed/Int64.sed @@ -1,3 +1,4 @@ s/@name@/Int64/g s/@type@/long/g s/@idl@/dataLongLong/g +s/@size@/8/g diff --git a/bulkioInterfaces/libsrc/java/sed/Int8.sed b/bulkioInterfaces/libsrc/java/sed/Int8.sed index 446b19c29..722198539 100644 --- a/bulkioInterfaces/libsrc/java/sed/Int8.sed +++ b/bulkioInterfaces/libsrc/java/sed/Int8.sed @@ -1,3 +1,4 @@ s/@name@/Int8/g s/@type@/char/g s/@idl@/dataChar/g +s/@size@/1/g diff --git a/bulkioInterfaces/libsrc/java/sed/UInt16.sed b/bulkioInterfaces/libsrc/java/sed/UInt16.sed index 4ba66acd9..e9c25693b 100644 --- a/bulkioInterfaces/libsrc/java/sed/UInt16.sed +++ b/bulkioInterfaces/libsrc/java/sed/UInt16.sed @@ -1,3 +1,4 @@ s/@name@/UInt16/g s/@type@/short/g s/@idl@/dataUshort/g +s/@size@/2/g diff --git a/bulkioInterfaces/libsrc/java/sed/UInt32.sed b/bulkioInterfaces/libsrc/java/sed/UInt32.sed index 6bb5cd070..65404dfc3 100644 --- a/bulkioInterfaces/libsrc/java/sed/UInt32.sed +++ b/bulkioInterfaces/libsrc/java/sed/UInt32.sed @@ -1,3 +1,4 @@ s/@name@/UInt32/g s/@type@/int/g s/@idl@/dataUlong/g +s/@size@/4/g diff --git a/bulkioInterfaces/libsrc/java/sed/UInt64.sed b/bulkioInterfaces/libsrc/java/sed/UInt64.sed index da2d78671..5b5f2ce82 100644 --- a/bulkioInterfaces/libsrc/java/sed/UInt64.sed +++ b/bulkioInterfaces/libsrc/java/sed/UInt64.sed @@ -1,3 +1,4 @@ s/@name@/UInt64/g s/@type@/long/g s/@idl@/dataUlongLong/g +s/@size@/8/g diff --git a/bulkioInterfaces/libsrc/java/sed/UInt8.sed b/bulkioInterfaces/libsrc/java/sed/UInt8.sed index 244f86243..3f839ed22 100644 --- a/bulkioInterfaces/libsrc/java/sed/UInt8.sed +++ b/bulkioInterfaces/libsrc/java/sed/UInt8.sed @@ -1,3 +1,4 @@ s/@name@/UInt8/g s/@type@/byte/g s/@idl@/dataOctet/g +s/@size@/1/g diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/InFilePort.java b/bulkioInterfaces/libsrc/java/src/bulkio/InFilePort.java index ea30be8f5..588fa496f 100644 --- a/bulkioInterfaces/libsrc/java/src/bulkio/InFilePort.java +++ b/bulkioInterfaces/libsrc/java/src/bulkio/InFilePort.java @@ -160,7 +160,7 @@ public InFilePort( String portName, this.name = portName; this.logger = logger; - this.stats = new linkStatistics(this.name, new Int8Size() ); + this.stats = new linkStatistics(this.name, 1); this.sriUpdateLock = new Object(); this.statUpdateLock = new Object(); this.currentHs = new HashMap(); diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/InPort.java.template b/bulkioInterfaces/libsrc/java/src/bulkio/InPort.java.template index 15889ccb1..c45eaff82 100644 --- a/bulkioInterfaces/libsrc/java/src/bulkio/InPort.java.template +++ b/bulkioInterfaces/libsrc/java/src/bulkio/InPort.java.template @@ -155,7 +155,7 @@ public class In@name@Port extends BULKIO.jni.@idl@POA implements org.ossie.compo this.name = portName; this.logger = logger; - this.stats = new linkStatistics(this.name, new @name@Size() ); + this.stats = new linkStatistics(this.name, @size@); this.sriUpdateLock = new Object(); this.statUpdateLock = new Object(); this.currentHs = new HashMap(); diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/InSDDSPort.java b/bulkioInterfaces/libsrc/java/src/bulkio/InSDDSPort.java index e3be266fd..ed97a1ae4 100644 --- a/bulkioInterfaces/libsrc/java/src/bulkio/InSDDSPort.java +++ b/bulkioInterfaces/libsrc/java/src/bulkio/InSDDSPort.java @@ -142,7 +142,7 @@ public InSDDSPort( String portName, bulkio.time.Comparator timeCmp ) { this.name = portName; - this.stats = new linkStatistics(this.name, new Int8Size() ); + this.stats = new linkStatistics(this.name, 1); this.sriUpdateLock = new Object(); this.statUpdateLock = new Object(); this.attachedStreamMap = new HashMap(); diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/InVITA49Port.java b/bulkioInterfaces/libsrc/java/src/bulkio/InVITA49Port.java index 0dce296e8..00a2893cd 100644 --- a/bulkioInterfaces/libsrc/java/src/bulkio/InVITA49Port.java +++ b/bulkioInterfaces/libsrc/java/src/bulkio/InVITA49Port.java @@ -142,7 +142,7 @@ public InVITA49Port( String portName, bulkio.time.Comparator timeCmp ) { this.name = portName; - this.stats = new linkStatistics(this.name, new Int8Size() ); + this.stats = new linkStatistics(this.name, 1); this.sriUpdateLock = new Object(); this.statUpdateLock = new Object(); this.attachedStreamMap = new HashMap(); diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/InXMLPort.java b/bulkioInterfaces/libsrc/java/src/bulkio/InXMLPort.java index e0d30df30..375af46f0 100644 --- a/bulkioInterfaces/libsrc/java/src/bulkio/InXMLPort.java +++ b/bulkioInterfaces/libsrc/java/src/bulkio/InXMLPort.java @@ -155,7 +155,7 @@ public InXMLPort( String portName, bulkio.SriListener sriCallback ){ this.name = portName; this.logger = logger; - this.stats = new linkStatistics(this.name, new Int8Size() ); + this.stats = new linkStatistics(this.name, 1); this.sriUpdateLock = new Object(); this.statUpdateLock = new Object(); this.currentHs = new HashMap(); diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/OutDataPort.java b/bulkioInterfaces/libsrc/java/src/bulkio/OutDataPort.java index 52ca342b2..ed08acdeb 100644 --- a/bulkioInterfaces/libsrc/java/src/bulkio/OutDataPort.java +++ b/bulkioInterfaces/libsrc/java/src/bulkio/OutDataPort.java @@ -33,7 +33,7 @@ public abstract class OutDataPort extend /** * Size of a single element */ - protected final SizeOf< ? > sizeof; + protected final int sizeof; /** * CORBA transfer limit in samples diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/OutFilePort.java b/bulkioInterfaces/libsrc/java/src/bulkio/OutFilePort.java index 31d0350b1..4badebc83 100644 --- a/bulkioInterfaces/libsrc/java/src/bulkio/OutFilePort.java +++ b/bulkioInterfaces/libsrc/java/src/bulkio/OutFilePort.java @@ -39,7 +39,7 @@ public OutFilePort(String portName, Logger logger) { } public OutFilePort(String portName, Logger logger, ConnectionEventListener eventCB) { - super(portName, logger, eventCB, new Int8Size()); + super(portName, logger, eventCB, 1); if (this.logger != null) { this.logger.debug("bulkio.OutPort CTOR port: " + portName); } diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/OutPort.java.template b/bulkioInterfaces/libsrc/java/src/bulkio/OutPort.java.template index 1ae47fec1..1d5856cb2 100644 --- a/bulkioInterfaces/libsrc/java/src/bulkio/OutPort.java.template +++ b/bulkioInterfaces/libsrc/java/src/bulkio/OutPort.java.template @@ -44,7 +44,7 @@ public class Out@name@Port extends OutStreamPort<@idl@Operations,@type@[]> { } public Out@name@Port(String portName, Logger logger, ConnectionEventListener eventCB) { - super(portName, logger, eventCB, new @name@Size()); + super(portName, logger, eventCB, @size@); if (this.logger != null) { this.logger.debug("bulkio.OutPort CTOR port: " + portName); } diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/OutSDDSPort.java b/bulkioInterfaces/libsrc/java/src/bulkio/OutSDDSPort.java index aa42877ab..21c129d75 100644 --- a/bulkioInterfaces/libsrc/java/src/bulkio/OutSDDSPort.java +++ b/bulkioInterfaces/libsrc/java/src/bulkio/OutSDDSPort.java @@ -404,7 +404,7 @@ public void connectPort(final org.omg.CORBA.Object connection, final String conn } this.outConnections.put(connectionId, port); this.active = true; - this.stats.put(connectionId, new linkStatistics( this.name, new Int8Size() ) ); + this.stats.put(connectionId, new linkStatistics(this.name, 1)); boolean portListed = false; diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/OutStreamPort.java b/bulkioInterfaces/libsrc/java/src/bulkio/OutStreamPort.java index 487eb76a0..580667c17 100644 --- a/bulkioInterfaces/libsrc/java/src/bulkio/OutStreamPort.java +++ b/bulkioInterfaces/libsrc/java/src/bulkio/OutStreamPort.java @@ -16,11 +16,11 @@ public abstract class OutStreamPort exte */ protected final int maxSamplesPerPush; - protected OutStreamPort(String portName, Logger logger, ConnectionEventListener connectionListener, SizeOf< ? > size) { + protected OutStreamPort(String portName, Logger logger, ConnectionEventListener connectionListener, int size) { super(portName, logger, connectionListener, size); // Make sure max samples per push is even so that complex data case is // handled properly - this.maxSamplesPerPush = (MAX_PAYLOAD_SIZE/this.sizeof.sizeof()) & 0xFFFFFFFE; + this.maxSamplesPerPush = (MAX_PAYLOAD_SIZE/this.sizeof) & 0xFFFFFFFE; } protected void doPushPacket(A data, PrecisionUTCTime time, boolean endOfStream, String streamID) { diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/OutVITA49Port.java b/bulkioInterfaces/libsrc/java/src/bulkio/OutVITA49Port.java index 56b6790e7..3699ae4f3 100644 --- a/bulkioInterfaces/libsrc/java/src/bulkio/OutVITA49Port.java +++ b/bulkioInterfaces/libsrc/java/src/bulkio/OutVITA49Port.java @@ -405,7 +405,7 @@ public void connectPort(final org.omg.CORBA.Object connection, final String conn } this.outConnections.put(connectionId, port); this.active = true; - this.stats.put(connectionId, new linkStatistics( this.name, new Int8Size() ) ); + this.stats.put(connectionId, new linkStatistics(this.name, 1)); boolean portListed = false; diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/OutXMLPort.java b/bulkioInterfaces/libsrc/java/src/bulkio/OutXMLPort.java index daf4625a6..1e6db2803 100644 --- a/bulkioInterfaces/libsrc/java/src/bulkio/OutXMLPort.java +++ b/bulkioInterfaces/libsrc/java/src/bulkio/OutXMLPort.java @@ -39,7 +39,7 @@ public OutXMLPort(String portName, Logger logger) { } public OutXMLPort(String portName, Logger logger, ConnectionEventListener eventCB) { - super(portName, logger, eventCB, new Int8Size()); + super(portName, logger, eventCB, 1); if (this.logger != null) { this.logger.debug("bulkio.OutPort CTOR port: " + portName); } diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/linkStatistics.java b/bulkioInterfaces/libsrc/java/src/bulkio/linkStatistics.java index 378c543be..aa383e3fa 100644 --- a/bulkioInterfaces/libsrc/java/src/bulkio/linkStatistics.java +++ b/bulkioInterfaces/libsrc/java/src/bulkio/linkStatistics.java @@ -61,12 +61,9 @@ class statPoint { protected double flushTime; /** @generated */ protected String portName; - - /** - * @generated - */ - public linkStatistics(String portName, SizeOf dataum ) { - this.sizeof = dataum.sizeof(); + + public linkStatistics(String portName, int sizeof) { + this.sizeof = sizeof; this.enabled = true; this.bitSize = this.sizeof * 8.0; this.historyWindow = 10; @@ -89,6 +86,11 @@ public linkStatistics(String portName, SizeOf dataum ) { } } + @Deprecated + public linkStatistics(String portName, SizeOf dataum) { + this(portName, dataum.sizeof()); + } + public List< String > getActiveStreamIDs() { return this.activeStreamIDs; } From 14cfd9232b1dc4fe063885e5eb6e539073b7716d Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 4 Jan 2016 10:40:23 -0500 Subject: [PATCH 0015/1644] Fix change in interface to Java OutXMLPort.pushPacket(); rename inner method for clarity --- .../libsrc/java/src/bulkio/OutDataPort.java | 6 +++--- .../libsrc/java/src/bulkio/OutFilePort.java | 5 +++++ .../libsrc/java/src/bulkio/OutStreamPort.java | 10 +++++++++- .../libsrc/java/src/bulkio/OutXMLPort.java | 7 +++++++ 4 files changed, 24 insertions(+), 4 deletions(-) diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/OutDataPort.java b/bulkioInterfaces/libsrc/java/src/bulkio/OutDataPort.java index ed08acdeb..e1c13bf7c 100644 --- a/bulkioInterfaces/libsrc/java/src/bulkio/OutDataPort.java +++ b/bulkioInterfaces/libsrc/java/src/bulkio/OutDataPort.java @@ -145,7 +145,7 @@ public void disconnectPort(String connectionId) { /** * Sends an array of samples. */ - public void pushPacket(A data, PrecisionUTCTime time, boolean endOfStream, String streamID) + protected void pushPacket(A data, PrecisionUTCTime time, boolean endOfStream, String streamID) { if (logger != null) { logger.trace("bulkio.OutPort pushPacket ENTER (port=" + this.name +")"); @@ -158,7 +158,7 @@ public void pushPacket(A data, PrecisionUTCTime time, boolean endOfStream, Strin this.pushSRI(header); } - doPushPacket(data, time, endOfStream, streamID); + pushPacketData(data, time, endOfStream, streamID); } if (logger != null) { @@ -166,7 +166,7 @@ public void pushPacket(A data, PrecisionUTCTime time, boolean endOfStream, Strin } } - protected void doPushPacket(A data, PrecisionUTCTime time, boolean endOfStream, String streamID) + protected void pushPacketData(A data, PrecisionUTCTime time, boolean endOfStream, String streamID) { pushSinglePacket(data, time, endOfStream, streamID); } diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/OutFilePort.java b/bulkioInterfaces/libsrc/java/src/bulkio/OutFilePort.java index 4badebc83..0cf71bead 100644 --- a/bulkioInterfaces/libsrc/java/src/bulkio/OutFilePort.java +++ b/bulkioInterfaces/libsrc/java/src/bulkio/OutFilePort.java @@ -49,6 +49,11 @@ public String getRepid() { return BULKIO.dataFileHelper.id(); } + public void pushPacket(String data, PrecisionUTCTime time, boolean endOfStream, String streamID) + { + super.pushPacket(data, time, endOfStream, streamID); + } + protected dataFileOperations narrow(org.omg.CORBA.Object obj) { return BULKIO.dataFileHelper.narrow(obj); } diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/OutStreamPort.java b/bulkioInterfaces/libsrc/java/src/bulkio/OutStreamPort.java index 580667c17..0e507585d 100644 --- a/bulkioInterfaces/libsrc/java/src/bulkio/OutStreamPort.java +++ b/bulkioInterfaces/libsrc/java/src/bulkio/OutStreamPort.java @@ -23,7 +23,15 @@ protected OutStreamPort(String portName, Logger logger, ConnectionEventListener this.maxSamplesPerPush = (MAX_PAYLOAD_SIZE/this.sizeof) & 0xFFFFFFFE; } - protected void doPushPacket(A data, PrecisionUTCTime time, boolean endOfStream, String streamID) { + /** + * Sends an array of samples. + */ + public void pushPacket(A data, PrecisionUTCTime time, boolean endOfStream, String streamID) + { + super.pushPacket(data, time, endOfStream, streamID); + } + + protected void pushPacketData(A data, PrecisionUTCTime time, boolean endOfStream, String streamID) { pushOversizedPacket(data, time, endOfStream, streamID); } diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/OutXMLPort.java b/bulkioInterfaces/libsrc/java/src/bulkio/OutXMLPort.java index 1e6db2803..4988b3401 100644 --- a/bulkioInterfaces/libsrc/java/src/bulkio/OutXMLPort.java +++ b/bulkioInterfaces/libsrc/java/src/bulkio/OutXMLPort.java @@ -49,6 +49,13 @@ public String getRepid() { return BULKIO.dataXMLHelper.id(); } + public void pushPacket(String data, boolean endOfStream, String streamID) + { + // Pass a null timestamp; it will never be referenced in the base class + // and can be safely dropped in sendPacket(). + super.pushPacket(data, null, endOfStream, streamID); + } + protected dataXMLOperations narrow(org.omg.CORBA.Object obj) { return BULKIO.dataXMLHelper.narrow(obj); } From 5e884558fac1a741a78ca23855f8b8ea1a500ace Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 4 Jan 2016 14:30:03 -0500 Subject: [PATCH 0016/1644] CF-945 Add time stamp helpers in Java, with unit tests --- .../libsrc/testing/tests/java/BulkioHelpers_Test.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bulkioInterfaces/libsrc/testing/tests/java/BulkioHelpers_Test.java b/bulkioInterfaces/libsrc/testing/tests/java/BulkioHelpers_Test.java index 14b3c6a72..bf824767a 100644 --- a/bulkioInterfaces/libsrc/testing/tests/java/BulkioHelpers_Test.java +++ b/bulkioInterfaces/libsrc/testing/tests/java/BulkioHelpers_Test.java @@ -333,7 +333,7 @@ public void test_timestamp_normalize() { // Negative fractional seconds have whole portion, but seconds whole seconds have // fractional portion with larger magnitude than remaining fractional seconds time.twsec = 100.75; - time.tfsec = -2.5; +time.tfsec = -2.5; bulkio.time.utils.normalize(time); assertTimeEquals("Normalizing both with negative fractional > 1", bulkio.time.utils.create(98.0, 0.25), time); } From 5209d195faa82e682c63b0df91fe7dbecae44819 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 5 Jan 2016 13:50:37 -0500 Subject: [PATCH 0017/1644] Fix indentation --- .../libsrc/testing/tests/java/BulkioHelpers_Test.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bulkioInterfaces/libsrc/testing/tests/java/BulkioHelpers_Test.java b/bulkioInterfaces/libsrc/testing/tests/java/BulkioHelpers_Test.java index bf824767a..14b3c6a72 100644 --- a/bulkioInterfaces/libsrc/testing/tests/java/BulkioHelpers_Test.java +++ b/bulkioInterfaces/libsrc/testing/tests/java/BulkioHelpers_Test.java @@ -333,7 +333,7 @@ public void test_timestamp_normalize() { // Negative fractional seconds have whole portion, but seconds whole seconds have // fractional portion with larger magnitude than remaining fractional seconds time.twsec = 100.75; -time.tfsec = -2.5; + time.tfsec = -2.5; bulkio.time.utils.normalize(time); assertTimeEquals("Normalizing both with negative fractional > 1", bulkio.time.utils.create(98.0, 0.25), time); } From bf379de2fba72cd6fb18398e25d656d4dd1b0db6 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 4 Feb 2016 11:21:57 -0500 Subject: [PATCH 0018/1644] Modify build to support 'subdir-objects' option and to treat C++ files generated from IDL source as built sources --- bulkioInterfaces/Makefile.am | 98 ++++++++++++++++++++++++----------- bulkioInterfaces/configure.ac | 3 +- 2 files changed, 70 insertions(+), 31 deletions(-) diff --git a/bulkioInterfaces/Makefile.am b/bulkioInterfaces/Makefile.am index 700eb4473..9f220728c 100644 --- a/bulkioInterfaces/Makefile.am +++ b/bulkioInterfaces/Makefile.am @@ -95,25 +95,64 @@ lib_LTLIBRARIES = libbulkioInterfaces.la libbulkioInterfaces_la_LDFLAGS = -version-info $(LIBBULKIOINTERFACES_VERSION_INFO) libbulkioInterfaces_la_LIBADD = $(OSSIE_LIBS) -# Again, we don't use the auto variable because order is important to us libbulkioInterfaces_la_SOURCES = \ - src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bulkioDataTypesSK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bulkioDataTypesDynSK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bulkioDataTypes.h \ - src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_runtimeStatsSK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_runtimeStatsDynSK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_runtimeStats.h \ - src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_updateSRISK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_updateSRIDynSK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_updateSRI.h \ - src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataFloatSK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataFloatDynSK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataFloat.h \ - src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataFileSK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataFileDynSK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataFile.h \ - src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataXMLSK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataXMLDynSK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataXML.h \ - src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataShortSK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataShortDynSK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataShort.h \ - src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataDoubleSK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataDoubleDynSK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataDouble.h \ - src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataCharSK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataCharDynSK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataChar.h \ - src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataOctetSK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataOctetDynSK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataOctet.h \ - src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataUlongSK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataUlongDynSK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataUlong.h \ - src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataUshortSK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataUshortDynSK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataUshort.h \ - src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataLongSK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataLongDynSK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataLong.h \ - src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataLongLongSK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataLongLongDynSK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataLongLong.h \ - src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataUlongLongSK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataUlongLongDynSK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataUlongLong.h \ - src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataSDDSSK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataSDDSDynSK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataSDDS.h \ - src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataVITA49SK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataVITA49DynSK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataVITA49.h + src/cpp/ossie/BULKIO/bulkioDataTypesSK.cpp \ + src/cpp/ossie/BULKIO/bulkioDataTypesDynSK.cpp \ + src/cpp/ossie/BULKIO/bio_runtimeStatsSK.cpp \ + src/cpp/ossie/BULKIO/bio_runtimeStatsDynSK.cpp \ + src/cpp/ossie/BULKIO/bio_updateSRISK.cpp \ + src/cpp/ossie/BULKIO/bio_updateSRIDynSK.cpp \ + src/cpp/ossie/BULKIO/bio_dataFloatSK.cpp \ + src/cpp/ossie/BULKIO/bio_dataFloatDynSK.cpp \ + src/cpp/ossie/BULKIO/bio_dataFileSK.cpp \ + src/cpp/ossie/BULKIO/bio_dataFileDynSK.cpp \ + src/cpp/ossie/BULKIO/bio_dataXMLSK.cpp \ + src/cpp/ossie/BULKIO/bio_dataXMLDynSK.cpp \ + src/cpp/ossie/BULKIO/bio_dataShortSK.cpp \ + src/cpp/ossie/BULKIO/bio_dataShortDynSK.cpp \ + src/cpp/ossie/BULKIO/bio_dataDoubleSK.cpp \ + src/cpp/ossie/BULKIO/bio_dataDoubleDynSK.cpp \ + src/cpp/ossie/BULKIO/bio_dataCharSK.cpp \ + src/cpp/ossie/BULKIO/bio_dataCharDynSK.cpp \ + src/cpp/ossie/BULKIO/bio_dataOctetSK.cpp \ + src/cpp/ossie/BULKIO/bio_dataOctetDynSK.cpp \ + src/cpp/ossie/BULKIO/bio_dataUlongSK.cpp \ + src/cpp/ossie/BULKIO/bio_dataUlongDynSK.cpp \ + src/cpp/ossie/BULKIO/bio_dataUshortSK.cpp \ + src/cpp/ossie/BULKIO/bio_dataUshortDynSK.cpp \ + src/cpp/ossie/BULKIO/bio_dataLongSK.cpp \ + src/cpp/ossie/BULKIO/bio_dataLongDynSK.cpp \ + src/cpp/ossie/BULKIO/bio_dataLongLongSK.cpp \ + src/cpp/ossie/BULKIO/bio_dataLongLongDynSK.cpp \ + src/cpp/ossie/BULKIO/bio_dataUlongLongSK.cpp \ + src/cpp/ossie/BULKIO/bio_dataUlongLongDynSK.cpp \ + src/cpp/ossie/BULKIO/bio_dataSDDSSK.cpp \ + src/cpp/ossie/BULKIO/bio_dataSDDSDynSK.cpp \ + src/cpp/ossie/BULKIO/bio_dataVITA49SK.cpp \ + src/cpp/ossie/BULKIO/bio_dataVITA49DynSK.cpp + +pkgincludedir = $(includedir)/$(LIBRARY_NAME)/$(IDL_MODULE) +pkginclude_HEADERS = \ + src/cpp/ossie/BULKIO/bulkioDataTypes.h \ + src/cpp/ossie/BULKIO/bio_runtimeStats.h \ + src/cpp/ossie/BULKIO/bio_updateSRI.h \ + src/cpp/ossie/BULKIO/bio_dataFloat.h \ + src/cpp/ossie/BULKIO/bio_dataFile.h \ + src/cpp/ossie/BULKIO/bio_dataXML.h \ + src/cpp/ossie/BULKIO/bio_dataShort.h \ + src/cpp/ossie/BULKIO/bio_dataDouble.h \ + src/cpp/ossie/BULKIO/bio_dataChar.h \ + src/cpp/ossie/BULKIO/bio_dataOctet.h \ + src/cpp/ossie/BULKIO/bio_dataUlong.h \ + src/cpp/ossie/BULKIO/bio_dataUshort.h \ + src/cpp/ossie/BULKIO/bio_dataLong.h \ + src/cpp/ossie/BULKIO/bio_dataLongLong.h \ + src/cpp/ossie/BULKIO/bio_dataUlongLong.h \ + src/cpp/ossie/BULKIO/bio_dataSDDS.h \ + src/cpp/ossie/BULKIO/bio_dataVITA49.h + +BUILT_SOURCES = $(libbulkioInterfaces_la_SOURCES) $(pkginclude_HEADERS) +CLEANFILES = $(BUILT_SOURCES) ############################################################################### # DO NOT MODIFY ANY LINES BELOW HERE @@ -128,9 +167,12 @@ all-local: all-python install-exec-hook: install-python -clean-local: clean-python clean-java clean-cpp +clean-local: clean-python clean-java rm -rf build +distclean-local: + rm -rf src + # Always build the current directory first (this is hack-ish, but the # alternative is to combine the Makefile.am's) SUBDIRS = . @@ -144,18 +186,16 @@ endif pkgconfigdir = $(libdir)/pkgconfig dist_pkgconfig_DATA = $(PACKAGE_NAME).pc -pkgincludedir = $(includedir)/$(LIBRARY_NAME)/$(IDL_MODULE) -pkginclude_HEADERS = $(filter %.h, $(lib$(LOWER_CASE_IDL_MODULE)Interfaces_la_SOURCES)) +bulkio_builddir = src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE) -AM_CXXFLAGS = -Wall -I src/cpp -g $(OMNIORB_CFLAGS) $(OSSIE_CFLAGS) -AM_LIBS = $(OSSIE_LIBS) +libbulkioInterfaces_la_CXXFLAGS = -Wall -I src/cpp -g $(OMNIORB_CFLAGS) $(OSSIE_CFLAGS) +libbulkioInterfaces_la_LIBS = $(OSSIE_LIBS) -src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/%DynSK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/%SK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/%.h: idl/$(LIBRARY_NAME)/$(IDL_MODULE)/%.idl - $(AM_V_at)mkdir -p "src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)" - $(AM_V_GEN)$(IDL) -I idl $(OSSIE_CFLAGS) $(OSSIE_IDLFLAGS) -I$(OMNICOS_IDLDIR) -I$(OMNIORB_IDLDIR) -C src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE) -bcxx -Wba -Wbd=DynSK.cpp -Wbh=.h -Wbs=SK.cpp -Wbkeep_inc_path $< +$(bulkio_builddir): + $(AM_V_at)mkdir -p $@ -clean-cpp: - rm -rf src/cpp +$(bulkio_builddir)/%DynSK.cpp $(bulkio_builddir)/%SK.cpp $(bulkio_builddir)/%.h: idl/ossie/BULKIO/%.idl | $(bulkio_builddir) + $(AM_V_GEN)$(IDL) -I idl $(OSSIE_CFLAGS) $(OSSIE_IDLFLAGS) -I$(OMNICOS_IDLDIR) -I$(OMNIORB_IDLDIR) -C $(bulkio_builddir) -bcxx -Wba -Wbd=DynSK.cpp -Wbh=.h -Wbs=SK.cpp -Wbkeep_inc_path $< ############################################################################### # Python @@ -258,7 +298,7 @@ BULKIOInterfaces_jar_MANIFEST = build/java/META-INF/MANIFEST.MF BULKIOInterfaces_jar_JAVACFLAGS = -g BULKIOInterfaces_jar_JARADD = -C $(IDLJ_SRC_DEST) . -CLEANFILES = $(BULKIOInterfaces_jar_MANIFEST) +CLEANFILES += $(BULKIOInterfaces_jar_MANIFEST) # JNI library must be built after the current directory (see SUBDIRS above) SUBDIRS += jni diff --git a/bulkioInterfaces/configure.ac b/bulkioInterfaces/configure.ac index bdc3a2f16..5d910ecee 100644 --- a/bulkioInterfaces/configure.ac +++ b/bulkioInterfaces/configure.ac @@ -21,8 +21,7 @@ AC_INIT(bulkioInterfaces, 2.0.4) AC_SUBST([LIBBULKIOINTERFACES_VERSION_INFO], [3:0:1]) -#AM_INIT_AUTOMAKE([nostdinc subdir-objects]) -AM_INIT_AUTOMAKE([nostdinc]) +AM_INIT_AUTOMAKE([nostdinc subdir-objects]) AC_PROG_CC AC_PROG_CXX AC_PROG_INSTALL From 323b2809c2c68d8a991a9fcd8159611e844ad934 Mon Sep 17 00:00:00 2001 From: Ryan Bauman Date: Fri, 18 Mar 2016 14:16:32 -0400 Subject: [PATCH 0019/1644] CF-1443 RELENG-401 - adjust release field for 2.0.1-rc1 --- bulkioInterfaces/bulkioInterfaces.spec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bulkioInterfaces/bulkioInterfaces.spec b/bulkioInterfaces/bulkioInterfaces.spec index ce3230c0e..931d0ece8 100644 --- a/bulkioInterfaces/bulkioInterfaces.spec +++ b/bulkioInterfaces/bulkioInterfaces.spec @@ -28,8 +28,8 @@ Prefix: %{_prefix} %bcond_without java Name: bulkioInterfaces -Version: 2.0.0 -Release: 5%{?dist} +Version: 2.0.1 +Release: 2%{?dist} Summary: The bulkio library for REDHAWK Group: Applications/Engineering From c91410e7dc9dcc79650805308d399333106cbaf5 Mon Sep 17 00:00:00 2001 From: Ryan Bauman Date: Tue, 16 Aug 2016 11:01:27 -0400 Subject: [PATCH 0020/1644] RELENG-433 - update development versions --- bulkioInterfaces/build.sh | 6 +++--- bulkioInterfaces/bulkioInterfaces.spec | 4 ++-- bulkioInterfaces/configure.ac | 4 ++-- bulkioInterfaces/libsrc/setup.py | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/bulkioInterfaces/build.sh b/bulkioInterfaces/build.sh index 263fa6750..262c304a2 100755 --- a/bulkioInterfaces/build.sh +++ b/bulkioInterfaces/build.sh @@ -25,9 +25,9 @@ elif [ "$1" = "rpm" ]; then # A very simplistic RPM build scenario mydir=`dirname $0` tmpdir=`mktemp -d` - cp -r ${mydir} ${tmpdir}/bulkioInterfaces-2.0.4 - tar czf ${tmpdir}/bulkioInterfaces-2.0.4.tar.gz --exclude=".git" -C ${tmpdir} bulkioInterfaces-2.0.4 - rpmbuild -ta ${tmpdir}/bulkioInterfaces-2.0.4.tar.gz + cp -r ${mydir} ${tmpdir}/bulkioInterfaces-2.1.0 + tar czf ${tmpdir}/bulkioInterfaces-2.1.0.tar.gz --exclude=".git" -C ${tmpdir} bulkioInterfaces-2.1.0 + rpmbuild -ta ${tmpdir}/bulkioInterfaces-2.1.0.tar.gz rm -rf $tmpdir else # Checks if build is newer than makefile (based on modification time) diff --git a/bulkioInterfaces/bulkioInterfaces.spec b/bulkioInterfaces/bulkioInterfaces.spec index 931d0ece8..fa6244418 100644 --- a/bulkioInterfaces/bulkioInterfaces.spec +++ b/bulkioInterfaces/bulkioInterfaces.spec @@ -28,8 +28,8 @@ Prefix: %{_prefix} %bcond_without java Name: bulkioInterfaces -Version: 2.0.1 -Release: 2%{?dist} +Version: 2.1.0 +Release: 1%{?dist} Summary: The bulkio library for REDHAWK Group: Applications/Engineering diff --git a/bulkioInterfaces/configure.ac b/bulkioInterfaces/configure.ac index 5d910ecee..10b7b100f 100644 --- a/bulkioInterfaces/configure.ac +++ b/bulkioInterfaces/configure.ac @@ -18,7 +18,7 @@ # along with this program. If not, see http://www.gnu.org/licenses/. # -AC_INIT(bulkioInterfaces, 2.0.4) +AC_INIT(bulkioInterfaces, 2.1.0) AC_SUBST([LIBBULKIOINTERFACES_VERSION_INFO], [3:0:1]) AM_INIT_AUTOMAKE([nostdinc subdir-objects]) @@ -43,7 +43,7 @@ fi PKG_CHECK_MODULES([OMNIORB], [omniORB4 >= 4.1.0]) RH_PKG_IDLDIR([OMNIORB], [omniORB4]) -PKG_CHECK_MODULES([OSSIE], [ossie >= 2.0.4]) +PKG_CHECK_MODULES([OSSIE], [ossie >= 2.1.0]) RH_PKG_IDLDIR([OSSIE], [ossie]) PKG_CHECK_MODULES([OMNICOS], [omniCOS4 >= 4.0.0]) RH_PKG_IDLDIR([OMNICOS], [omniCOS4]) diff --git a/bulkioInterfaces/libsrc/setup.py b/bulkioInterfaces/libsrc/setup.py index c95a98078..e25f0a2a8 100644 --- a/bulkioInterfaces/libsrc/setup.py +++ b/bulkioInterfaces/libsrc/setup.py @@ -29,7 +29,7 @@ # replaces it (i.e. a developer does a command-line build), use 1.X.X version='__VERSION__' if version.find('__') == 0: - version = '2.0.4' + version = '2.1.0' setup( name='bulkio', From be856e6711a3a5e29a7a3ab4e9b590cca3c70334 Mon Sep 17 00:00:00 2001 From: Ryan Bauman Date: Fri, 16 Sep 2016 10:36:20 -0400 Subject: [PATCH 0021/1644] CF-1566 - Allow acceptance of Java 8 source code --- bulkioInterfaces/configure.ac | 2 +- .../libsrc/testing/devices/dev_snk/java/configure.ac | 2 +- .../libsrc/testing/devices/dev_src/java/configure.ac | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bulkioInterfaces/configure.ac b/bulkioInterfaces/configure.ac index 10b7b100f..f328ca504 100644 --- a/bulkioInterfaces/configure.ac +++ b/bulkioInterfaces/configure.ac @@ -74,7 +74,7 @@ HAVE_JAVASUPPORT=no if test "x$enable_java" != "xno"; then # configure was run with java enabled - java_source_version=1.6 + java_source_version=1.8 RH_JAVA_HOME RH_PROG_JAVAC([$java_source_version]) diff --git a/bulkioInterfaces/libsrc/testing/devices/dev_snk/java/configure.ac b/bulkioInterfaces/libsrc/testing/devices/dev_snk/java/configure.ac index 9c74c1fa0..5d1409de4 100644 --- a/bulkioInterfaces/libsrc/testing/devices/dev_snk/java/configure.ac +++ b/bulkioInterfaces/libsrc/testing/devices/dev_snk/java/configure.ac @@ -8,7 +8,7 @@ OSSIE_SDRROOT_AS_PREFIX PKG_CHECK_MODULES([OSSIE], [ossie >= 2.0]) RH_JAVA_HOME -RH_PROG_JAVAC([1.6]) +RH_PROG_JAVAC([1.8]) RH_PROG_JAR RH_PKG_CLASSPATH([REDHAWK], [ossie]) diff --git a/bulkioInterfaces/libsrc/testing/devices/dev_src/java/configure.ac b/bulkioInterfaces/libsrc/testing/devices/dev_src/java/configure.ac index 1148e7426..f87443aff 100644 --- a/bulkioInterfaces/libsrc/testing/devices/dev_src/java/configure.ac +++ b/bulkioInterfaces/libsrc/testing/devices/dev_src/java/configure.ac @@ -8,7 +8,7 @@ OSSIE_SDRROOT_AS_PREFIX PKG_CHECK_MODULES([OSSIE], [ossie >= 2.0]) RH_JAVA_HOME -RH_PROG_JAVAC([1.6]) +RH_PROG_JAVAC([1.8]) RH_PROG_JAR RH_PKG_CLASSPATH([REDHAWK], [ossie]) From 7eac6f5ffb53e2a0704c7b9a48c2579149bad15a Mon Sep 17 00:00:00 2001 From: Ryan Bauman Date: Wed, 12 Oct 2016 14:12:22 -0400 Subject: [PATCH 0022/1644] RELENG-459 - reconcile bulkio differences --- .../libsrc/java/src/bulkio/OutDataPort.java | 70 +------------------ .../libsrc/java/src/bulkio/OutStreamPort.java | 14 +++- .../tests/test_Oversized_framedata.py | 6 +- 3 files changed, 17 insertions(+), 73 deletions(-) diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/OutDataPort.java b/bulkioInterfaces/libsrc/java/src/bulkio/OutDataPort.java index e1c13bf7c..9f50e8ea8 100644 --- a/bulkioInterfaces/libsrc/java/src/bulkio/OutDataPort.java +++ b/bulkioInterfaces/libsrc/java/src/bulkio/OutDataPort.java @@ -35,12 +35,7 @@ public abstract class OutDataPort extend */ protected final int sizeof; - /** - * CORBA transfer limit in samples - */ - protected int maxSamplesPerPush; - - protected OutDataPort(String portName, Logger logger, ConnectionEventListener connectionListener, SizeOf< ? > size) { + protected OutDataPort(String portName, Logger logger, ConnectionEventListener connectionListener, int size) { super(portName, logger, connectionListener); this.sizeof = size; } @@ -242,68 +237,7 @@ public void pushSRI(StreamSRI header) } } - private void pushOversizedPacket(A data, PrecisionUTCTime time, boolean endOfStream, String streamID) { - final int length = arraySize(data); - - // If there is no need to break data into smaller packets, skip - // straight to the pushPacket call and return. - SriMapStruct sriStruct = this.currentSRIs.get(streamID); - if (sriStruct.sri.subsize != 0) { - if (this.maxSamplesPerPush%sriStruct.sri.subsize != 0) { - this.maxSamplesPerPush = (MAX_PAYLOAD_SIZE/this.sizeof.sizeof()) & 0xFFFFFFFE; - while (this.maxSamplesPerPush%sriStruct.sri.subsize != 0) { - this.maxSamplesPerPush -= this.maxSamplesPerPush%sriStruct.sri.subsize; - if (this.maxSamplesPerPush%2 != 0){ - this.maxSamplesPerPush--; - } - } - } - } - if (length <= this.maxSamplesPerPush) { - this.pushSinglePacket(data, time, endOfStream, streamID); - return; - } - - // Determine xdelta for this streamID to be used for time increment for subpackets - SriMapStruct sriMap = this.currentSRIs.get(streamID); - double xdelta = 0.0; - if (sriMap != null){ - xdelta = sriMap.sri.xdelta; - } - - // Initialize time of first subpacket - PrecisionUTCTime packetTime = time; - for (int offset = 0; offset < length;) { - // Don't send more samples than are remaining - final int pushSize = java.lang.Math.min(length-offset, this.maxSamplesPerPush); - - // Copy the range for this sub-packet and advance the offset - A subPacket = copyOfRange(data, offset, offset+pushSize); - offset += pushSize; - - // Send end-of-stream as false for all sub-packets except for the - // last one (when there are no samples remaining after this push), - // which gets the input EOS. - boolean packetEOS = false; - if (offset == length) { - packetEOS = endOfStream; - } - - if (logger != null) { - logger.trace("bulkio.OutPort pushOversizedPacket() calling pushPacket with pushSize " + pushSize + " and packetTime twsec: " + packetTime.twsec + " tfsec: " + packetTime.tfsec); - } - this.pushSinglePacket(subPacket, packetTime, packetEOS, streamID); - int data_xfer_len = pushSize; - if (sriMap != null){ - if (sriMap.sri.mode == 1) { - data_xfer_len = data_xfer_len / 2; - } - } - packetTime = bulkio.time.utils.addSampleOffset(packetTime, data_xfer_len, xdelta); - } - } - - private void pushSinglePacket(A data, PrecisionUTCTime time, boolean endOfStream, String streamID) + protected void pushSinglePacket(A data, PrecisionUTCTime time, boolean endOfStream, String streamID) { final int length = arraySize(data); SriMapStruct sriStruct = this.currentSRIs.get(streamID); diff --git a/bulkioInterfaces/libsrc/java/src/bulkio/OutStreamPort.java b/bulkioInterfaces/libsrc/java/src/bulkio/OutStreamPort.java index 0e507585d..f7c4848c1 100644 --- a/bulkioInterfaces/libsrc/java/src/bulkio/OutStreamPort.java +++ b/bulkioInterfaces/libsrc/java/src/bulkio/OutStreamPort.java @@ -14,7 +14,7 @@ public abstract class OutStreamPort exte /** * CORBA transfer limit in samples */ - protected final int maxSamplesPerPush; + protected int maxSamplesPerPush; protected OutStreamPort(String portName, Logger logger, ConnectionEventListener connectionListener, int size) { super(portName, logger, connectionListener, size); @@ -38,6 +38,18 @@ protected void pushPacketData(A data, PrecisionUTCTime time, boolean endOfStream private void pushOversizedPacket(A data, PrecisionUTCTime time, boolean endOfStream, String streamID) { final int length = arraySize(data); + SriMapStruct sriStruct = this.currentSRIs.get(streamID); + if (sriStruct.sri.subsize != 0) { + if (this.maxSamplesPerPush%sriStruct.sri.subsize != 0) { + this.maxSamplesPerPush = (MAX_PAYLOAD_SIZE/this.sizeof) & 0xFFFFFFFE; + while (this.maxSamplesPerPush%sriStruct.sri.subsize != 0) { + this.maxSamplesPerPush -= this.maxSamplesPerPush%sriStruct.sri.subsize; + if (this.maxSamplesPerPush%2 != 0){ + this.maxSamplesPerPush--; + } + } + } + } // If there is no need to break data into smaller packets, skip // straight to the pushPacket call and return. if (length <= this.maxSamplesPerPush) { diff --git a/bulkioInterfaces/libsrc/testing/components/Oversized_framedata/tests/test_Oversized_framedata.py b/bulkioInterfaces/libsrc/testing/components/Oversized_framedata/tests/test_Oversized_framedata.py index 69a56463e..ca3150e7f 100755 --- a/bulkioInterfaces/libsrc/testing/components/Oversized_framedata/tests/test_Oversized_framedata.py +++ b/bulkioInterfaces/libsrc/testing/components/Oversized_framedata/tests/test_Oversized_framedata.py @@ -11,9 +11,7 @@ class ResourceTests(ossie.utils.testing.ScaComponentTestCase): def testConsistentSize(self): ####################################################################### # Launch the resource with the default execparams - execparams = self.getPropertySet(kinds=("execparam",), modes=("readwrite", "writeonly"), includeNil=False) - execparams = dict([(x.id, any.from_any(x.value)) for x in execparams]) - self.launch(execparams) + self.launch() snk=sb.DataSink() snk.start() @@ -23,7 +21,7 @@ def testConsistentSize(self): # Make sure start and stop can be called without throwing exceptions self.comp.start() - (retval, timestamps) = snk._sink.retrieveData(20000000) + (retval, timestamps) = snk._sink.retrieveData(19999744) self.assertEquals(timestamps[1][0]%1024,0) ####################################################################### From 1186fa0171c2bebe48b773eff947004b9ab741ed Mon Sep 17 00:00:00 2001 From: Ryan Bauman Date: Fri, 12 Aug 2016 19:05:33 +0000 Subject: [PATCH 0023/1644] Update version for 2.1.0 development --- GPP/GPP.spd.xml | 2 +- GPP/GPP.spec | 2 +- GPP/build.sh | 6 +++--- GPP/cpp/configure.ac | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/GPP/GPP.spd.xml b/GPP/GPP.spd.xml index 3c9c42bda..12d3007ee 100644 --- a/GPP/GPP.spd.xml +++ b/GPP/GPP.spd.xml @@ -19,7 +19,7 @@ details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see http://www.gnu.org/licenses/. --> - + Redhawk GPP null diff --git a/GPP/GPP.spec b/GPP/GPP.spec index 403be9d5e..1b6d54c09 100644 --- a/GPP/GPP.spec +++ b/GPP/GPP.spec @@ -31,7 +31,7 @@ Prefix: %{_prefix} %define _infodir %{_prefix}/info Name: GPP -Version: 2.0.4 +Version: 2.1.0 Release: 1%{?dist} Summary: REDHAWK GPP diff --git a/GPP/build.sh b/GPP/build.sh index 4d0e8a295..97ddf098c 100755 --- a/GPP/build.sh +++ b/GPP/build.sh @@ -24,9 +24,9 @@ if [ "$1" = "rpm" ]; then if [ -e GPP.spec ]; then mydir=`dirname $0` tmpdir=`mktemp -d` - cp -r ${mydir} ${tmpdir}/GPP-2.0.4 - tar czf ${tmpdir}/GPP-2.0.4.tar.gz --exclude=".svn" --exclude=".git" -C ${tmpdir} GPP-2.0.4 - rpmbuild -ta ${tmpdir}/GPP-2.0.4.tar.gz + cp -r ${mydir} ${tmpdir}/GPP-2.1.0 + tar czf ${tmpdir}/GPP-2.1.0.tar.gz --exclude=".svn" -C ${tmpdir} GPP-2.1.0 + rpmbuild -ta ${tmpdir}/GPP-2.1.0.tar.gz rm -rf $tmpdir else echo "Missing RPM spec file in" `pwd` diff --git a/GPP/cpp/configure.ac b/GPP/cpp/configure.ac index 674665d13..578c9be46 100644 --- a/GPP/cpp/configure.ac +++ b/GPP/cpp/configure.ac @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see http://www.gnu.org/licenses/. */ -AC_INIT(GPP, 2.0.4) +AC_INIT(GPP, 2.1.0) AM_INIT_AUTOMAKE([foreign nostdinc subdir-objects]) AC_CONFIG_MACRO_DIR([m4]) @@ -33,7 +33,7 @@ m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) # Dependencies export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig" -PKG_CHECK_MODULES([PROJECTDEPS], [ossie >= 1.10 omniORB4 >= 4.1.0 ]) +PKG_CHECK_MODULES([PROJECTDEPS], [ossie >= 2.1 omniORB4 >= 4.1.0 ]) OSSIE_ENABLE_LOG4CXX AX_BOOST_BASE([1.41]) AX_BOOST_SYSTEM From 54f3ca84b25c3627b47b876bf9202e4c319d9d6a Mon Sep 17 00:00:00 2001 From: Ryan Bauman Date: Mon, 16 Nov 2015 17:37:51 -0500 Subject: [PATCH 0024/1644] Don't pass --old-and-unmanageable to build --- redhawk-codegen/setup.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/redhawk-codegen/setup.py b/redhawk-codegen/setup.py index 271d5d6b1..0a2b7d75b 100644 --- a/redhawk-codegen/setup.py +++ b/redhawk-codegen/setup.py @@ -43,10 +43,12 @@ def byte_compile(self, files): for arg in sys.argv: if '--home' in arg: homeSys = True - + if '--old-and-unmanageable' in arg: + useEgg = True + if not homeSys and ossiehome != None and not buildArg: sys.argv.append('--home='+ossiehome) -if not ('--old-and-unmanageable' in sys.argv) and not buildArg: +if not useEgg and not buildArg: sys.argv.append('--old-and-unmanageable') setup(name='redhawk-codegen', From f7e19739d982a0a49bc52c218e587c2bed3e80b8 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 23 Dec 2015 13:33:22 -0500 Subject: [PATCH 0025/1644] CF-960 No longer need to generate start/stop calls for ports in Java --- .../component/pull/templates/resource_base.java | 15 --------------- .../redhawk/codegen/jinja/java/ports/burstio.py | 6 ------ .../redhawk/codegen/jinja/java/ports/generator.py | 6 ------ .../redhawk/codegen/jinja/java/ports/mapping.py | 2 -- 4 files changed, 29 deletions(-) diff --git a/redhawk-codegen/redhawk/codegen/jinja/java/component/pull/templates/resource_base.java b/redhawk-codegen/redhawk/codegen/jinja/java/component/pull/templates/resource_base.java index 0d90fdbc4..be372c806 100644 --- a/redhawk-codegen/redhawk/codegen/jinja/java/component/pull/templates/resource_base.java +++ b/redhawk-codegen/redhawk/codegen/jinja/java/component/pull/templates/resource_base.java @@ -222,21 +222,6 @@ public CF.Resource setup(final String compId, final String compName, final ORB o } /*{% endif %}*/ - public void start() throws CF.ResourcePackage.StartError - { -/*{% for port in component.ports if port.start %}*/ - this.${port.javaname}.${port.start}; -/*{% endfor %}*/ - super.start(); - } - - public void stop() throws CF.ResourcePackage.StopError - { -/*{% for port in component.ports if port.stop %}*/ - this.${port.javaname}.${port.stop}; -/*{% endfor %}*/ - super.stop(); - } /*{% if component.hasmultioutport %}*/ protected void connectionTableChanged (List oldValue, List newValue) diff --git a/redhawk-codegen/redhawk/codegen/jinja/java/ports/burstio.py b/redhawk-codegen/redhawk/codegen/jinja/java/ports/burstio.py index 32be05597..f68fb09ab 100644 --- a/redhawk-codegen/redhawk/codegen/jinja/java/ports/burstio.py +++ b/redhawk-codegen/redhawk/codegen/jinja/java/ports/burstio.py @@ -47,11 +47,5 @@ def className(self): classname += 'Out' return classname - def start(self): - return 'start()' - - def stop(self): - return 'stop()' - def supportsMultiOut(self): return (self.direction == 'uses') diff --git a/redhawk-codegen/redhawk/codegen/jinja/java/ports/generator.py b/redhawk-codegen/redhawk/codegen/jinja/java/ports/generator.py index 0caf49d8d..62befcda3 100644 --- a/redhawk-codegen/redhawk/codegen/jinja/java/ports/generator.py +++ b/redhawk-codegen/redhawk/codegen/jinja/java/ports/generator.py @@ -53,12 +53,6 @@ def poaClass(self): def _ctorArgs(self, name): return tuple() - def start(self): - return None - - def stop(self): - return None - def constructor(self, name): return '%s(%s)' % (self.className(), ', '.join(self._ctorArgs(name))) diff --git a/redhawk-codegen/redhawk/codegen/jinja/java/ports/mapping.py b/redhawk-codegen/redhawk/codegen/jinja/java/ports/mapping.py index ef23ea640..f4ad5a8aa 100644 --- a/redhawk-codegen/redhawk/codegen/jinja/java/ports/mapping.py +++ b/redhawk-codegen/redhawk/codegen/jinja/java/ports/mapping.py @@ -28,7 +28,5 @@ def _mapPort(self, port, generator): javaport['javaname'] = java.identifier('port_'+port.name()) javaport['javatype'] = generator.className() javaport['constructor'] = generator.constructor(port.name()) - javaport['start'] = generator.start() - javaport['stop'] = generator.stop() javaport['multiout'] = generator.supportsMultiOut() return javaport From b00e1c04a8fe64eb0ab7744c707064119d153de3 Mon Sep 17 00:00:00 2001 From: Ryan Bauman Date: Fri, 18 Mar 2016 14:26:06 -0400 Subject: [PATCH 0026/1644] CF-1443 RELENG-401 - adjust release field for 2.0.1-rc1 --- redhawk-codegen/redhawk-codegen.spec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/redhawk-codegen/redhawk-codegen.spec b/redhawk-codegen/redhawk-codegen.spec index b2ccfab79..6a71b9926 100644 --- a/redhawk-codegen/redhawk-codegen.spec +++ b/redhawk-codegen/redhawk-codegen.spec @@ -23,8 +23,8 @@ Prefix: %{_prefix} Name: redhawk-codegen -Version: 2.0.4 -Release: 1%{?dist} +Version: 2.0.1 +Release: 2%{?dist} Summary: Redhawk Code Generators Group: Applications/Engineering From f385c436c274cf40907e3532a47fbd8702df4ef9 Mon Sep 17 00:00:00 2001 From: Ryan Bauman Date: Tue, 16 Aug 2016 11:03:52 -0400 Subject: [PATCH 0027/1644] RELENG-433 - update development versions --- redhawk-codegen/redhawk-codegen.spec | 4 ++-- redhawk-codegen/redhawk/codegen/versions.py | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/redhawk-codegen/redhawk-codegen.spec b/redhawk-codegen/redhawk-codegen.spec index 6a71b9926..519387ae4 100644 --- a/redhawk-codegen/redhawk-codegen.spec +++ b/redhawk-codegen/redhawk-codegen.spec @@ -23,8 +23,8 @@ Prefix: %{_prefix} Name: redhawk-codegen -Version: 2.0.1 -Release: 2%{?dist} +Version: 2.1.0 +Release: 1%{?dist} Summary: Redhawk Code Generators Group: Applications/Engineering diff --git a/redhawk-codegen/redhawk/codegen/versions.py b/redhawk-codegen/redhawk/codegen/versions.py index 8efefa048..04d5baf27 100644 --- a/redhawk-codegen/redhawk/codegen/versions.py +++ b/redhawk-codegen/redhawk/codegen/versions.py @@ -17,8 +17,8 @@ # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see http://www.gnu.org/licenses/. # -codegen = '2.0.4' -redhawk = '2.0' +codegen = '2.1.0' +redhawk = '2.1' jinja2 = '2.6' boost = '1.41' omniORB4 = '4.1.0' @@ -29,4 +29,4 @@ bulkio = redhawk burstio = redhawk -frontend = '2.2' +frontend = '2.4' From 7be4973e34606bfb0d721aec42081358a9ca016b Mon Sep 17 00:00:00 2001 From: Ryan Bauman Date: Wed, 12 Oct 2016 14:19:43 -0400 Subject: [PATCH 0028/1644] RELENG-459 - reconcile codegen differences --- .../sdr/dom/components/get_ports/tests/test_get_ports.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/codegenTesting/sdr/dom/components/get_ports/tests/test_get_ports.py b/codegenTesting/sdr/dom/components/get_ports/tests/test_get_ports.py index c44c7c336..95b79b717 100644 --- a/codegenTesting/sdr/dom/components/get_ports/tests/test_get_ports.py +++ b/codegenTesting/sdr/dom/components/get_ports/tests/test_get_ports.py @@ -48,20 +48,20 @@ def getPortDefinition(self, name, scd): if port.get_usesname() == name: port_def = { 'repid': port.get_repid(), 'description': port.get_description(), - 'direction': 'Uses' } + 'direction': CF.PortSet.DIRECTION_USES } break for port in scd.get_componentfeatures().get_ports().get_provides(): if port.get_providesname() == name: if port_def is not None: # Port was already found in uses ports, so it must be bi-directional - port_def['direction'] = 'Bidir' + port_def['direction'] = CF.PortSet.DIRECTION_BIDIR if not port_def['description']: port_def['description'] = port.get_description() else: port_def = { 'repid': port.get_repid(), 'description': port.get_description(), - 'direction': 'Provides' } + 'direction': CF.PortSet.DIRECTION_PROVIDES } break return port_def From ac7064721eb9d6a113a32bc56a74f538214fa779 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 30 Dec 2015 16:56:27 -0500 Subject: [PATCH 0029/1644] Use the IDL constant for port directions in testing --- .../sdr/dom/components/get_ports/tests/test_get_ports.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/codegenTesting/sdr/dom/components/get_ports/tests/test_get_ports.py b/codegenTesting/sdr/dom/components/get_ports/tests/test_get_ports.py index 95b79b717..0f0ab1427 100644 --- a/codegenTesting/sdr/dom/components/get_ports/tests/test_get_ports.py +++ b/codegenTesting/sdr/dom/components/get_ports/tests/test_get_ports.py @@ -1,7 +1,9 @@ #!/usr/bin/env python import ossie.utils.testing -from ossie.utils import sb +from ossie.cf import CF +import os +from omniORB import any class ComponentTests(ossie.utils.testing.RHTestCase): # Path to the SPD file, relative to this file. This must be set in order to From 7aefb4f5daec75586341b15055ba6ee3dd08c72c Mon Sep 17 00:00:00 2001 From: Ryan Bauman Date: Wed, 12 Oct 2016 14:23:46 -0400 Subject: [PATCH 0030/1644] RELENG-459 - reconcile codegenTesting differences --- .../sdr/dom/components/get_ports/tests/test_get_ports.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/codegenTesting/sdr/dom/components/get_ports/tests/test_get_ports.py b/codegenTesting/sdr/dom/components/get_ports/tests/test_get_ports.py index 0f0ab1427..95b79b717 100644 --- a/codegenTesting/sdr/dom/components/get_ports/tests/test_get_ports.py +++ b/codegenTesting/sdr/dom/components/get_ports/tests/test_get_ports.py @@ -1,9 +1,7 @@ #!/usr/bin/env python import ossie.utils.testing -from ossie.cf import CF -import os -from omniORB import any +from ossie.utils import sb class ComponentTests(ossie.utils.testing.RHTestCase): # Path to the SPD file, relative to this file. This must be set in order to From fbaed35ec8523ddf2e6eff1ca36053ec39f785c9 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Tue, 22 Dec 2015 12:42:32 -0500 Subject: [PATCH 0031/1644] Feature updates --- redhawk/Updates.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/redhawk/Updates.txt b/redhawk/Updates.txt index 25119d73b..60faf5217 100644 --- a/redhawk/Updates.txt +++ b/redhawk/Updates.txt @@ -1,4 +1,13 @@ New Feature list +May-December 2015 +- DeviceManager/DomainManager properties available through Python interface +- Added affinity support to the framework libraries to assist with the deployment of resources by application factories and nodes. +- Python property change listeners are passed complex values rather than dictionaries +- Property change listener triggered only when the value changes +- SIGUSR1 can be used for the Domain Manager to close all open file handles +- When a component dies in the sandbox, it is reported +- getPortSet supported by the Application +- Busy FEI devices are skipped if a listener is being allocated January/February/March/April 2015 - Connection Manager - createApplication call on DomainManager object (do not have to install application and call create on ApplicationFactory object) From 17044b2fa2161cc3dc980e81b9e6576803f0e7e4 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 23 Dec 2015 13:29:54 -0500 Subject: [PATCH 0032/1644] CF-960 Add a StartablePort interface to allow Resource to start and stop ports, if required --- .../src/base/framework/java/ossie/Makefile.am | 3 +- .../src/org/ossie/component/Resource.java | 41 +++++++++++++++++++ .../org/ossie/component/StartablePort.java | 26 ++++++++++++ 3 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 redhawk/src/base/framework/java/ossie/src/org/ossie/component/StartablePort.java diff --git a/redhawk/src/base/framework/java/ossie/Makefile.am b/redhawk/src/base/framework/java/ossie/Makefile.am index 29446e916..10e3d487b 100644 --- a/redhawk/src/base/framework/java/ossie/Makefile.am +++ b/redhawk/src/base/framework/java/ossie/Makefile.am @@ -108,7 +108,8 @@ ossie_jar_SOURCE = src/org/ossie/component/AllocCapacity.java \ src/org/ossie/component/ThreadedResource.java \ src/org/ossie/component/Service.java \ src/org/ossie/component/UsesPort.java \ - src/org/ossie/component/PortBase.java \ + src/org/ossie/component/PortBase.java \ + src/org/ossie/component/StartablePort.java \ src/org/ossie/logging/logging.java \ src/org/ossie/logging/RH_LogEventAppender.java \ src/org/ossie/events/Consumer_i.java \ diff --git a/redhawk/src/base/framework/java/ossie/src/org/ossie/component/Resource.java b/redhawk/src/base/framework/java/ossie/src/org/ossie/component/Resource.java index 7f9ac19b1..62d646943 100644 --- a/redhawk/src/base/framework/java/ossie/src/org/ossie/component/Resource.java +++ b/redhawk/src/base/framework/java/ossie/src/org/ossie/component/Resource.java @@ -29,6 +29,7 @@ import java.util.Arrays; import java.util.HashMap; import java.util.Hashtable; +import java.util.List; import java.util.Map; import java.util.Properties; import java.io.FileOutputStream; @@ -257,6 +258,44 @@ protected void addPort(String name, String description, omnijni.Servant servant) addPort(name, servant); } + /** + * Start processing for any ports that support it. + */ + protected void startPorts() { + for (StartablePort port : getStartablePorts()) { + port.startPort(); + } + } + + /** + * Stop processing for any ports that support it. If there are any calls on + * the port that are blocking, this should cause them to return immediately. + */ + protected void stopPorts() { + for (StartablePort port : getStartablePorts()) { + port.stopPort(); + } + } + + /** + * Returns a list of the registered ports that support the StartablePort + * interface. + */ + private List getStartablePorts() { + List startablePorts = new ArrayList(); + for (Servant servant : this.portServants.values()) { + if (servant instanceof StartablePort) { + startablePorts.add((StartablePort) servant); + } + } + for (omnijni.Servant servant : this.nativePorts.values()) { + if (servant instanceof StartablePort) { + startablePorts.add((StartablePort) servant); + } + } + return startablePorts; + } + /** * Default Constructor that automatically sets parameters for the Sun ORB * and the JacORB ORB. @@ -335,6 +374,7 @@ public void start() throws StartError { // While we are starting or stopping don't let anything else occur logger.trace("start()"); synchronized (this) { + startPorts(); this._started = true; if (processingThread == null) { processingThread = new Thread(this); @@ -351,6 +391,7 @@ public void stop() throws StopError { logger.trace("stop()"); synchronized (this) { if (processingThread != null) { + stopPorts(); this._started = false; try { processingThread.interrupt(); diff --git a/redhawk/src/base/framework/java/ossie/src/org/ossie/component/StartablePort.java b/redhawk/src/base/framework/java/ossie/src/org/ossie/component/StartablePort.java new file mode 100644 index 000000000..5c5096e45 --- /dev/null +++ b/redhawk/src/base/framework/java/ossie/src/org/ossie/component/StartablePort.java @@ -0,0 +1,26 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK core. + * + * REDHAWK core is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +package org.ossie.component; + +public interface StartablePort extends PortBase { + public void startPort(); + public void stopPort(); +} From d87d50fea4820acce0bb09e10dd3c9b670e02b32 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 30 Dec 2015 16:50:30 -0500 Subject: [PATCH 0033/1644] Use public constants in the IDL file for the possible values of PortInfoType's direction field instead of the literal strings at all points-of-use --- .../src/base/framework/MessageInterface.cpp | 6 +++--- .../org/ossie/events/MessageConsumerPort.java | 18 +++++++++--------- .../org/ossie/events/MessageSupplierPort.java | 18 +++++++++--------- .../base/framework/python/ossie/resource.py | 6 +++--- redhawk/src/base/include/ossie/Port_impl.h | 4 ++-- redhawk/src/idl/ossie/CF/cf.idl | 6 ++++++ 6 files changed, 32 insertions(+), 26 deletions(-) diff --git a/redhawk/src/base/framework/MessageInterface.cpp b/redhawk/src/base/framework/MessageInterface.cpp index 244f8154a..b1ac13fe0 100644 --- a/redhawk/src/base/framework/MessageInterface.cpp +++ b/redhawk/src/base/framework/MessageInterface.cpp @@ -171,12 +171,12 @@ void MessageConsumerPort::fireCallback (const std::string& id, const CORBA::Any& std::string MessageConsumerPort::getRepid() const { - return "IDL:ExtendedEvent/MessageEvent:1.0"; + return ExtendedEvent::MessageEvent::_PD_repoId; } std::string MessageConsumerPort::getDirection() const { - return "Bidir"; + return CF::PortSet::DIRECTION_BIDIR; } MessageSupplierPort::MessageSupplierPort (std::string port_name) : @@ -246,5 +246,5 @@ void MessageSupplierPort::extendConsumers(std::string consumer_id, CosEventChann std::string MessageSupplierPort::getRepid() const { - return "IDL:ExtendedEvent/MessageEvent:1.0"; + return ExtendedEvent::MessageEvent::_PD_repoId; } diff --git a/redhawk/src/base/framework/java/ossie/src/org/ossie/events/MessageConsumerPort.java b/redhawk/src/base/framework/java/ossie/src/org/ossie/events/MessageConsumerPort.java index f82a0a8be..4ddaeb81c 100644 --- a/redhawk/src/base/framework/java/ossie/src/org/ossie/events/MessageConsumerPort.java +++ b/redhawk/src/base/framework/java/ossie/src/org/ossie/events/MessageConsumerPort.java @@ -148,15 +148,15 @@ public void setLogger(Logger logger) this.logger = logger; } - public String getRepid() - { - return "IDL:ExtendedEvent/MessageEvent:1.0"; - } - - public String getDirection() - { - return "Bidir"; - } + public String getRepid() + { + return ExtendedEvent.MessageEventHelper.id(); + } + + public String getDirection() + { + return CF.PortSet.DIRECTION_BIDIR; + } /** * Register a listener for a message. diff --git a/redhawk/src/base/framework/java/ossie/src/org/ossie/events/MessageSupplierPort.java b/redhawk/src/base/framework/java/ossie/src/org/ossie/events/MessageSupplierPort.java index d4e733d1e..7719bc714 100644 --- a/redhawk/src/base/framework/java/ossie/src/org/ossie/events/MessageSupplierPort.java +++ b/redhawk/src/base/framework/java/ossie/src/org/ossie/events/MessageSupplierPort.java @@ -242,13 +242,13 @@ public org.omg.CosEventChannelAdmin.SupplierAdmin for_suppliers() return null; } - public String getRepid() - { - return "IDL:ExtendedEvent/MessageEvent:1.0"; - } - - public String getDirection() - { - return "Uses"; - } + public String getRepid() + { + return ExtendedEvent.MessageEventHelper.id(); + } + + public String getDirection() + { + return CF.PortSet.DIRECTION_USES; + } } diff --git a/redhawk/src/base/framework/python/ossie/resource.py b/redhawk/src/base/framework/python/ossie/resource.py index 0d64fbbf3..bb69461f0 100644 --- a/redhawk/src/base/framework/python/ossie/resource.py +++ b/redhawk/src/base/framework/python/ossie/resource.py @@ -466,12 +466,12 @@ def getPortSet(self): description = portdef.__doc__ direction = '' if isinstance(portdef, usesport): - direction = 'Uses' + direction = CF.PortSet.DIRECTION_USES elif isinstance(portdef, providesport): if repid == 'IDL:ExtendedEvent/MessageEvent:1.0': - direction = 'Bidir' + direction = CF.PortSet.DIRECTION_BIDIR else: - direction = 'Provides' + direction = CF.PortSet.DIRECTION_PROVIDES info = CF.PortSet.PortInfoType(obj_ptr, name, repid, description, direction) portList.append(info) diff --git a/redhawk/src/base/include/ossie/Port_impl.h b/redhawk/src/base/include/ossie/Port_impl.h index 2b6c85b9f..692711f2a 100644 --- a/redhawk/src/base/include/ossie/Port_impl.h +++ b/redhawk/src/base/include/ossie/Port_impl.h @@ -352,7 +352,7 @@ class Port_Uses_base_impl : public PortBase // Return the direction (uses/provides) for this Port virtual std::string getDirection () const { - return "Uses"; + return CF::PortSet::DIRECTION_USES; } protected: @@ -376,7 +376,7 @@ class Port_Provides_base_impl : public PortBase // Return the direction (uses/provides) for this Port virtual std::string getDirection () const { - return "Provides"; + return CF::PortSet::DIRECTION_PROVIDES; } }; diff --git a/redhawk/src/idl/ossie/CF/cf.idl b/redhawk/src/idl/ossie/CF/cf.idl index cf680ad2a..9b10b154d 100644 --- a/redhawk/src/idl/ossie/CF/cf.idl +++ b/redhawk/src/idl/ossie/CF/cf.idl @@ -888,6 +888,12 @@ module CF { string description; string direction; }; + /* Constant for PortInfoType direction field for provides ports */ + const string DIRECTION_PROVIDES = "Provides"; + /* Constant for PortInfoType direction field for uses ports */ + const string DIRECTION_USES = "Uses"; + /* Constant for PortInfoType direction field for bi-directional ports */ + const string DIRECTION_BIDIR = "Bidir"; /* The PortInfoSequence type defines an unbounded sequence of ports' information for getPortSet function. */ typedef sequence PortInfoSequence; /* The getPortSet operation provides a mechanism to obtain information about all ports in the resource. */ From 6d0a7d666310326259dd9f9293ac3847b7f9ebdc Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 7 Jan 2016 14:27:36 -0500 Subject: [PATCH 0034/1644] Remove unused imports and avoid "import *" --- .../ossie/utils/bluefile/bluefile_helpers.py | 28 ++++++++----------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/bluefile/bluefile_helpers.py b/redhawk/src/base/framework/python/ossie/utils/bluefile/bluefile_helpers.py index 3838f400e..a7788c8dc 100644 --- a/redhawk/src/base/framework/python/ossie/utils/bluefile/bluefile_helpers.py +++ b/redhawk/src/base/framework/python/ossie/utils/bluefile/bluefile_helpers.py @@ -18,22 +18,18 @@ # along with this program. If not, see http://www.gnu.org/licenses/. # - -import numpy -from numpy import * -import platform -import bluefile - -from ossie.cf import CF -import ossie.properties -from ossie.cf import CF, CF__POA -from new import classobj -import array -import ossie.utils.bulkio.bulkio_helpers as bulkio_helpers import os import threading import time -import logging +import numpy +from new import classobj + +from ossie.cf import CF, CF__POA +import ossie.properties +from ossie.utils.bulkio import bulkio_helpers +from ossie.utils.log4py import logging + +import bluefile try: from bulkio.bulkioInterfaces import BULKIO, BULKIO__POA except: @@ -42,8 +38,6 @@ logging.basicConfig() log = logging.getLogger(__name__) -arch = platform.machine() - def hdr_to_sri(hdr, stream_id): """ Generates a StreamSRI object based on the information contained in the @@ -315,9 +309,9 @@ def run(self, infile, pktsize=1024, streamID=None): if hdr['format'].startswith('C'): data = data.flatten() if hdr['format'].endswith('F'): - data = data.view(float32) + data = data.view(numpy.float32) elif hdr['format'].endswith('D'): - data = data.view(float64) + data = data.view(numpy.float64) sz = len(data) self.done = False From d1e638e5094386e0a4990a7839fac9cd394fcbe2 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 8 Jan 2016 13:40:38 -0500 Subject: [PATCH 0035/1644] Remove dead code --- redhawk/src/control/sdr/devmgr/main.cpp | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/redhawk/src/control/sdr/devmgr/main.cpp b/redhawk/src/control/sdr/devmgr/main.cpp index af32ebfe4..1175d833f 100644 --- a/redhawk/src/control/sdr/devmgr/main.cpp +++ b/redhawk/src/control/sdr/devmgr/main.cpp @@ -78,17 +78,6 @@ static void shutdown (void) } -// System Signal Interrupt Handler will allow proper ORB shutdown -void signal_catcher( int sig ) -{ - // IMPORTANT Don't call exit(...) in this function - // issue all CORBA calls that you need for cleanup here before calling ORB shutdown - if ((( sig == SIGINT ) || (sig == SIGQUIT) || (sig == SIGTERM))) { - shutdown(); - } -} - - static void child_exit (int sig) { pid_t pid; From 92e9133362527412d2eeb4cb65b882c85332c1db Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 12 Jan 2016 15:30:58 -0500 Subject: [PATCH 0036/1644] Separate sandbox proxy creation from launch --- .../python/ossie/utils/sandbox/base.py | 17 ++++++- .../python/ossie/utils/sandbox/ide.py | 34 +++++-------- .../python/ossie/utils/sandbox/local.py | 49 +++++++------------ 3 files changed, 46 insertions(+), 54 deletions(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/base.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/base.py index 8c94670b0..d6bc68ab3 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/base.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/base.py @@ -253,8 +253,12 @@ def launch(self, descriptor, instanceName=None, refid=None, impl=None, execparams, initProps, configure = self._sortOverrides(prf, execparams, configure) # Determine the class for the component type and create a new instance. - return self._launch(profile, spd, scd, prf, instanceName, refid, impl, execparams, - initProps, initialize, configure, debugger, window, timeout) + comp = self._create(profile, spd, scd, prf, instanceName, refid, impl) + + # Launch the entry point (handled by subclass). + self._launch(comp, execparams, initProps, initialize, configure, debugger, window, timeout) + + return comp def shutdown(self): # Clean up any event channels created by this sandbox instance. @@ -366,7 +370,16 @@ def __init__(self, sandbox, profile, spd, scd, prf, instanceName, refid, impl): self._propRef[str(prop.id)] = prop.defValue self.__ports = None + + self._parseComponentXMLFiles() + self._buildAPI() + def _getExecparams(self): + execparams = dict((str(ep.id), ep.defValue) for ep in self._getPropertySet(kinds=('execparam',), includeNil=False)) + for prop in self._getPropertySet(kinds=('property',), includeNil=False, commandline=True): + execparams[str(prop.id)] = prop.defValue + return execparams + def _readProfile(self): sdrRoot = self._sandbox.getSdrRoot() self._spd, self._scd, self._prf = sdrRoot.readProfile(self._profile) diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/ide.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/ide.py index d740b4d97..b840e9ba2 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/ide.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/ide.py @@ -81,10 +81,8 @@ def getLocation(self): class IDEMixin(object): - def __init__(self, execparams, initProps, configProps): - self._execparams = execparams - self._initProps = initProps - self._configProps = configProps + def __init__(self): + self._execparams = {} def _launch(self): # Pack the execparams into an array of string-valued properties @@ -105,23 +103,15 @@ def _launch(self): return ref - def _getExecparams(self): - return {} - def _terminate(self): pass class IDESandboxComponent(SandboxComponent, IDEMixin): - def __init__(self, sandbox, profile, spd, scd, prf, instanceName, refid, impl, execparams, - initProps, configProps): - SandboxComponent.__init__(self, sandbox, profile, spd, scd, prf, instanceName, refid, impl) - IDEMixin.__init__(self, execparams, initProps, configProps) - self._parseComponentXMLFiles() - self._buildAPI() - def _getExecparams(self): - return dict((str(ep.id), ep.defValue) for ep in self._getPropertySet(kinds=('execparam',), includeNil=False)) + def __init__(self, sandbox, profile, spd, scd, prf, instanceName, refid, impl): + SandboxComponent.__init__(self, sandbox, profile, spd, scd, prf, instanceName, refid, impl) + IDEMixin.__init__(self) class IDEComponent(IDESandboxComponent, Resource): @@ -189,13 +179,14 @@ def _checkInstanceId(self, refid, componentType='resource'): # "valid" return True - def _launch(self, profile, spd, scd, prf, instanceName, refid, impl, execparams, - initProps, initialize, configProps, debugger, window, timeout): + def _create(self, profile, spd, scd, prf, instanceName, refid, impl): # Determine the class for the component type and create a new instance. clazz = self.__comptypes__[scd.get_componenttype()] - comp = clazz(self, profile, spd, scd, prf, instanceName, refid, impl, execparams, initProps, configProps) + return clazz(self, profile, spd, scd, prf, instanceName, refid, impl) + + def _launch(self, comp, execparams, initProps, initialize, configProps, debugger, window, timeout): + comp._execparams = execparams comp._kick() - return comp def _createResource(self, profile, name, qualifiers=[]): log.debug("Creating resource '%s' with profile '%s'", name, profile) @@ -257,10 +248,9 @@ def _scanChalkboard(self): # ask the resource itself. profile = resource._get_softwareProfile() - # Create the component/device sandbox wrapper, disabling the - # automatic launch since it is already running + # Create the component/device sandbox wrapper spd, scd, prf = self.getSdrRoot().readProfile(profile) - comp = clazz(self, profile, spd, scd, prf, instanceName, refid, impl, {}, {}, {}) + comp = clazz(self, profile, spd, scd, prf, instanceName, refid, impl) comp.ref = resource self.__components[instanceName] = comp except Exception, e: diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py index 2d60cc647..093106b38 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py @@ -95,12 +95,8 @@ def findProfile(self, descriptor, objType=None): class LocalMixin(object): - def __init__(self, execparams, debugger, window, timeout): + def __init__(self): self._process = None - self._execparams = execparams - self._debugger = debugger - self._window = window - self._timeout = timeout def _launch(self): launchFactory = self.__launcher__(self._profile, self._refid, self._instanceName, self._sandbox) @@ -130,21 +126,9 @@ def _processAlive(self): return False class LocalSandboxComponent(SandboxComponent, LocalMixin): - def __init__(self, sdrroot, profile, spd, scd, prf, instanceName, refid, impl, - execparams, debugger, window, timeout): + def __init__(self, sdrroot, profile, spd, scd, prf, instanceName, refid, impl): SandboxComponent.__init__(self, sdrroot, profile, spd, scd, prf, instanceName, refid, impl) - LocalMixin.__init__(self, execparams, debugger, window, timeout) - - self._kick() - - self._parseComponentXMLFiles() - self._buildAPI() - - def _getExecparams(self): - execparams = dict((str(ep.id), ep.defValue) for ep in self._getPropertySet(kinds=('execparam',), includeNil=False)) - commandline_property = dict((str(ep.id), ep.defValue) for ep in self._getPropertySet(kinds=('property',), includeNil=False,commandline=True)) - execparams.update(commandline_property) - return execparams + LocalMixin.__init__(self) def releaseObject(self): try: @@ -196,14 +180,14 @@ def api(self): class LocalService(Service, LocalMixin): __launcher__ = launcher.ServiceLauncher - def __init__(self, sdrroot, profile, spd, scd, prf, instanceName, refid, impl, - execparams, debugger, window, timeout): + def __init__(self, sdrroot, profile, spd, scd, prf, instanceName, refid, impl): self._sandbox = sdrroot Service.__init__(self, None, profile, spd, scd, prf, instanceName, refid, impl) - LocalMixin.__init__(self, execparams, debugger, window, timeout) + LocalMixin.__init__(self) + + def _kick(self): self.ref = self._launch() self.populateMemberFunctions() - self._sandbox._addService(self) def _getExecparams(self): @@ -272,12 +256,19 @@ def _checkInstanceId(self, refid, componentType): return False return True - def _launch(self, profile, spd, scd, prf, instanceName, refid, impl, execparams, - initProps, initialize, configProps, debugger, window, timeout): + def _create(self, profile, spd, scd, prf, instanceName, refid, impl): # Determine the class for the component type and create a new instance. comptype = scd.get_componenttype() clazz = self.__comptypes__[comptype] - comp = clazz(self, profile, spd, scd, prf, instanceName, refid, impl, execparams, debugger, window, timeout) + return clazz(self, profile, spd, scd, prf, instanceName, refid, impl) + + def _launch(self, comp, execparams, initProps, initialize, configProps, debugger, window, timeout): + # Store the launch configuration in the component and kick it + comp._execparams = execparams + comp._debugger = debugger + comp._window = window + comp._timeout = timeout + comp._kick() try: # Occasionally, when a lot of components are launched from the @@ -294,8 +285,8 @@ def _launch(self, profile, spd, scd, prf, instanceName, refid, impl, execparams, pass # Services don't get initialized or configured - if comptype == 'service': - return comp + if not hasattr(comp, 'initialize'): + return # Initialize the component unless asked not to. if initialize: @@ -322,8 +313,6 @@ def _launch(self, profile, spd, scd, prf, instanceName, refid, impl, execparams, except: log.exception('Failure in component configuration') - return comp - def getComponents(self): return self.__components.values() From d2d6d6a3bf0034e3d76878bf8f2f88093d67dc67 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 13 Jan 2016 09:55:26 -0500 Subject: [PATCH 0037/1644] Partial redesign of sandbox to only create the launcher in the specific sandbox implementations, simplifying the class hierarchy and giving better control of launch to the specific classes --- .../python/ossie/utils/sandbox/base.py | 68 ++++++- .../python/ossie/utils/sandbox/ide.py | 82 +++----- .../python/ossie/utils/sandbox/local.py | 177 +++++++----------- 3 files changed, 150 insertions(+), 177 deletions(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/base.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/base.py index d6bc68ab3..4bbb0e005 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/base.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/base.py @@ -29,6 +29,7 @@ from ossie.utils import log4py from ossie.utils import weakobj from ossie.utils.model import PortSupplier, PropertySet, ComponentBase, CorbaObject +from ossie.utils.model import Service, Resource, Device from ossie.utils.model.connect import ConnectionManager from ossie.utils.uuid import uuid4 from ossie.utils.sandbox.events import EventChannel @@ -234,8 +235,12 @@ def launch(self, descriptor, instanceName=None, refid=None, impl=None, # Check that we can launch the component. comptype = scd.get_componenttype() - if comptype not in self.__comptypes__: - raise NotImplementedError, "No support for component type '%s'" % comptype + if comptype == 'resource': + clazz = SandboxComponent + elif comptype in ('device', 'loadabledevice', 'executabledevice'): + clazz = SandboxDevice + else: + raise NotImplementedError("No support for component type '%s'" % comptype) # Generate/check instance name. if not instanceName: @@ -253,10 +258,10 @@ def launch(self, descriptor, instanceName=None, refid=None, impl=None, execparams, initProps, configure = self._sortOverrides(prf, execparams, configure) # Determine the class for the component type and create a new instance. - comp = self._create(profile, spd, scd, prf, instanceName, refid, impl) - - # Launch the entry point (handled by subclass). - self._launch(comp, execparams, initProps, initialize, configure, debugger, window, timeout) + comp = clazz(self, profile, spd, scd, prf, instanceName, refid, impl) + comp._factory = self._createFactory(comptype, execparams, initProps, initialize, configure, debugger, window, timeout) + # Launch the component + comp._kick() return comp @@ -351,9 +356,20 @@ def _getInitializationStages(self, prf): yield prop, self._getInitializationStage(prop, prop.get_configurationkind()) -class SandboxComponent(ComponentBase): +class SandboxFactory(object): + def launch(self, comp): + raise NotImplementedError('launch') + + def setup(self, comp): + raise NotImplementedError('setup') + + def terminate(self, comp): + raise NotImplementedError('terminate') + + +class SandboxResource(ComponentBase): def __init__(self, sandbox, profile, spd, scd, prf, instanceName, refid, impl): - super(SandboxComponent,self).__init__(spd, scd, prf, instanceName, refid, impl) + super(SandboxResource,self).__init__(spd, scd, prf, instanceName, refid, impl) self._sandbox = sandbox self._profile = profile self._componentName = spd.get_name() @@ -385,7 +401,8 @@ def _readProfile(self): self._spd, self._scd, self._prf = sdrRoot.readProfile(self._profile) def _kick(self): - self.ref = self._launch() + self.ref = self._factory.launch(self) + self._factory.setup(self) self._sandbox._registerComponent(self) @property @@ -418,7 +435,13 @@ def releaseObject(self): manager.breakConnection(identifier, uses) manager.unregisterConnection(identifier, uses) self._sandbox._unregisterComponent(self) - super(SandboxComponent,self).releaseObject() + + # Call superclass release, which calls the CORBA method. + super(SandboxResource,self).releaseObject() + + # Allow the launch factory to peform any follow-up cleanup. + if self._factory: + self._factory.terminate(self) def api(self): ''' @@ -446,6 +469,31 @@ def sendMessage(self, msg, msgId=None, msgPort=None, restrict=True ): return self._msgSupplierHelper.sendMessage( msg, msgId, msgPort, restrict ) return False +class SandboxComponent(SandboxResource, Resource): + def __init__(self, *args, **kwargs): + Resource.__init__(self) + SandboxResource.__init__(self, *args, **kwargs) + + def __repr__(self): + return "<%s component '%s' at 0x%x>" % (self._sandbox.getType(), self._instanceName, id(self)) + + +class SandboxDevice(SandboxResource, Device): + def __init__(self, *args, **kwargs): + Device.__init__(self) + SandboxResource.__init__(self, *args, **kwargs) + + Device._buildAPI(self) + + def __repr__(self): + return "<%s device '%s' at 0x%x>" % (self._sandbox.getType(), self._instanceName, id(self)) + + def api(self): + SandboxResource.api(self) + print + Device.api(self) + + class SandboxEventChannel(EventChannel, CorbaObject): def __init__(self, name, sandbox): EventChannel.__init__(self, name) diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/ide.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/ide.py index b840e9ba2..e97387440 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/ide.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/ide.py @@ -32,9 +32,9 @@ from ossie.cf import ExtendedCF from ossie.cf import CF -from ossie.utils.model import Resource, Device, CorbaObject +from ossie.utils.model import CorbaObject -from base import SdrRoot, Sandbox, SandboxComponent +from base import SdrRoot, Sandbox, SandboxComponent, SandboxDevice, SandboxFactory log = logging.getLogger(__name__) @@ -80,62 +80,26 @@ def getLocation(self): return 'REDHAWK IDE virtual SDR' -class IDEMixin(object): - def __init__(self): - self._execparams = {} +class IDEFactory(SandboxFactory): + def __init__(self, execparams): + self._execparams = execparams - def _launch(self): - # Pack the execparams into an array of string-valued properties - properties = [CF.DataType(k, to_any(str(v))) for k, v in self._execparams.iteritems()] - # Pack the remaining props by having the component do the conversion - properties.extend(self._itemToDataType(k,v) for k,v in self._initProps.iteritems()) - properties.extend(self._itemToDataType(k,v) for k,v in self._configProps.iteritems()) - - # Tell the IDE to launch a specific implementation, if given - if self._impl is not None: - properties.append(CF.DataType('__implementationID', to_any(self._impl))) - - ref = self._sandbox._createResource(self._profile, self._instanceName, properties) + def launch(self, comp): + execparams = comp._getExecparams() + execparams.update(self._execparams) + ref = comp._sandbox._createResource(comp._profile, comp._instanceName, execparams, comp._impl) # The IDE sandbox API only allows us to specify the instance name, not # the identifier, so update by querying the component itself - self._refid = ref._get_identifier() + comp._refid = ref._get_identifier() return ref - def _terminate(self): + def setup(self, comp): pass - -class IDESandboxComponent(SandboxComponent, IDEMixin): - - def __init__(self, sandbox, profile, spd, scd, prf, instanceName, refid, impl): - SandboxComponent.__init__(self, sandbox, profile, spd, scd, prf, instanceName, refid, impl) - IDEMixin.__init__(self) - - -class IDEComponent(IDESandboxComponent, Resource): - def __init__(self, *args, **kwargs): - Resource.__init__(self) - IDESandboxComponent.__init__(self, *args, **kwargs) - - def __repr__(self): - return "" % (self._instanceName, id(self)) - - -class IDEDevice(IDESandboxComponent, Device): - def __init__(self, *args, **kwargs): - Device.__init__(self) - IDESandboxComponent.__init__(self, *args, **kwargs) - Device._buildAPI(self) - - def __repr__(self): - return "" % (self._instanceName, id(self)) - - def api(self): - IDESandboxComponent.api(self) - print - Device.api(self) + def terminate(self, comp): + pass class IDEService(CorbaObject): @@ -148,11 +112,6 @@ def __repr__(self): class IDESandbox(Sandbox): - __comptypes__ = { - 'resource': IDEComponent, - 'device': IDEDevice, - } - def __init__(self, ideRef): super(IDESandbox, self).__init__() self.__ide = ideRef @@ -179,10 +138,10 @@ def _checkInstanceId(self, refid, componentType='resource'): # "valid" return True - def _create(self, profile, spd, scd, prf, instanceName, refid, impl): - # Determine the class for the component type and create a new instance. - clazz = self.__comptypes__[scd.get_componenttype()] - return clazz(self, profile, spd, scd, prf, instanceName, refid, impl) + def _createFactory(self, comptype, execparams, initProps, initialize, configProps, debugger, window, timeout): + if comptype in ('resource', 'device', 'loadabledevice', 'executabledevice'): + return IDEFactory(execparams, debugger, window, timeout) + return None def _launch(self, comp, execparams, initProps, initialize, configProps, debugger, window, timeout): comp._execparams = execparams @@ -221,12 +180,12 @@ def _scanChalkboard(self): try: resource = desc.resource if resource._is_a('IDL:CF/Device:1.0'): - clazz = IDEDevice + clazz = SandboxDevice refid = resource._get_identifier() instanceName = resource._get_label() impl = self.__ide._get_deviceManager().getComponentImplementationId(refid) else: - clazz = IDEComponent + clazz = SandboxComponent refid = resource._get_identifier() if ':DCE:' in refid: # Components launched from the Python console have the @@ -372,3 +331,6 @@ def getService(self, name): def getServices(self): self._scanServices() return self.__services.values() + + def getType(self): + return 'IDE' diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py index 093106b38..61273233e 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py @@ -26,10 +26,10 @@ import warnings from ossie import parsers -from ossie.utils.model import Service, Resource, Device +from ossie.utils.model import Service from ossie.utils.model.connect import ConnectionManager -from base import SdrRoot, Sandbox, SandboxComponent +from base import SdrRoot, Sandbox, SandboxFactory import launcher import pydoc @@ -94,96 +94,82 @@ def findProfile(self, descriptor, objType=None): return super(LocalSdrRoot,self).findProfile(descriptor, objType=objType) -class LocalMixin(object): - def __init__(self): - self._process = None +class LocalFactory(SandboxFactory): + def __init__(self, execparams, initProps, initialize, configProps, debugger, window, timeout): + self._execparams = execparams + self._debugger = debugger + self._window = window + self._timeout = timeout + self._initProps = initProps + self._initialize = initialize + self._configProps = configProps - def _launch(self): - launchFactory = self.__launcher__(self._profile, self._refid, self._instanceName, self._sandbox) - execparams = self._getExecparams() + def launch(self, comp): + launchFactory = self.__launcher__(comp._profile, comp._refid, comp._instanceName, comp._sandbox) + execparams = comp._getExecparams() execparams.update(self._execparams) - proc, ref = launchFactory.execute(self._spd, self._impl, execparams, self._debugger, self._window, self._timeout) - self._process = proc - self._pid = self._process.pid() + proc, ref = launchFactory.execute(comp._spd, comp._impl, execparams, self._debugger, self._window, self._timeout) + # Store the process on the component proxy + comp._process = proc return ref - - def _requestTermination(self): - self._process.requestTermination() - - def _getExecparams(self): - return {} - def _terminate(self): - if self._process: - # Kill child process (may be multiple processes in the case of a debugger) - self._process.terminate() - self._process = None + def setup(self, comp): + # Services don't get initialized or configured + if not hasattr(comp, 'initialize'): + return - def _processAlive(self): - if self._process: - return self._process.isAlive() - else: - return False + # Initialize the component unless asked not to. + if self._initialize: + # Set initial property values for 'property' kind properties + initvals = copy.deepcopy(comp._propRef) + initvals.update(self._initProps) + try: + comp.initializeProperties(initvals) + except: + log.exception('Failure in component property initialization') -class LocalSandboxComponent(SandboxComponent, LocalMixin): - def __init__(self, sdrroot, profile, spd, scd, prf, instanceName, refid, impl): - SandboxComponent.__init__(self, sdrroot, profile, spd, scd, prf, instanceName, refid, impl) - LocalMixin.__init__(self) + # Actually initialize the component + comp.initialize() - def releaseObject(self): - try: - self._requestTermination() - super(LocalSandboxComponent,self).releaseObject() - except: - # Tolerate exceptions (e.g., the object has already been released) - # and continue on to ensure that the process still gets terminated. - pass + # Configure component with default values unless requested not to (e.g., + # when launched from a SAD file). + if self._configProps is not None: + # Make a copy of the default properties, and update with any passed-in + # properties that were not already passed to initializeProperties() + initvals = copy.deepcopy(comp._configRef) + initvals.update(self._configProps) + try: + comp.configure(initvals) + except: + log.exception('Failure in component configuration') - # Give the process a little time (50ms) to exit after releaseObject() - # returns before sending termination signals - timeout = 50e-3 - end = time.time() + timeout - while self._processAlive() and time.time() < end: - time.sleep(1e-3) + def terminate(self, comp): + if comp._process: + # Give the process a little time (50ms) to exit after releaseObject() + # returns before sending termination signals + timeout = 50e-3 + end = time.time() + timeout + while comp._process.isAlive() and time.time() < end: + time.sleep(1e-3) - self._terminate() + # Kill child process (may be multiple processes in the case of a debugger) + comp._process.terminate() + comp._process = None -class LocalComponent(LocalSandboxComponent, Resource): +class LocalComponentFactory(LocalFactory): __launcher__ = launcher.ResourceLauncher - def __init__(self, *args, **kwargs): - Resource.__init__(self) - LocalSandboxComponent.__init__(self, *args, **kwargs) - def __repr__(self): - return "" % (self._instanceName, id(self)) - - -class LocalDevice(LocalSandboxComponent, Device): +class LocalDeviceFactory(LocalFactory): __launcher__ = launcher.DeviceLauncher - def __init__(self, *args, **kwargs): - Device.__init__(self) - LocalSandboxComponent.__init__(self, *args, **kwargs) - - Device._buildAPI(self) - - def __repr__(self): - return "" % (self._instanceName, id(self)) - - def api(self): - LocalSandboxComponent.api(self) - print - Device.api(self) - - -class LocalService(Service, LocalMixin): +class LocalServiceFactory(LocalFactory): __launcher__ = launcher.ServiceLauncher - + +class LocalService(Service): def __init__(self, sdrroot, profile, spd, scd, prf, instanceName, refid, impl): self._sandbox = sdrroot Service.__init__(self, None, profile, spd, scd, prf, instanceName, refid, impl) - LocalMixin.__init__(self) def _kick(self): self.ref = self._launch() @@ -213,14 +199,6 @@ def __repr__(self): class LocalSandbox(Sandbox): - __comptypes__ = { - 'resource': LocalComponent, - 'device': LocalDevice, - 'loadabledevice': LocalDevice, - 'executabledevice': LocalDevice, - 'service': LocalService - } - def __init__(self, sdrroot): super(LocalSandbox, self).__init__() self.__components = {} @@ -256,34 +234,16 @@ def _checkInstanceId(self, refid, componentType): return False return True - def _create(self, profile, spd, scd, prf, instanceName, refid, impl): - # Determine the class for the component type and create a new instance. - comptype = scd.get_componenttype() - clazz = self.__comptypes__[comptype] - return clazz(self, profile, spd, scd, prf, instanceName, refid, impl) + def _createFactory(self, comptype, execparams, initProps, initialize, configProps, debugger, window, timeout): + if comptype == 'resource': + clazz = LocalComponentFactory + elif comptype in ('device', 'loadabledevice', 'executabledevice'): + clazz = LocalDeviceFactory + else: + raise NotImplementedError("No support for component type '%s'" % comptype) + return clazz(execparams, initProps, initialize, configProps, debugger, window, timeout) def _launch(self, comp, execparams, initProps, initialize, configProps, debugger, window, timeout): - # Store the launch configuration in the component and kick it - comp._execparams = execparams - comp._debugger = debugger - comp._window = window - comp._timeout = timeout - comp._kick() - - try: - # Occasionally, when a lot of components are launched from the - # sandbox, omniORB may have a cached connection where the other end - # has terminated (this is particularly a problem with Java, because - # the Sun ORB never closes connections on shutdown). If the new - # component just happens to have the same TCP/IP address and port, - # the first time we try to reach the component, it will get a - # CORBA.COMM_FAILURE exception even though the reference is valid. - # In this case, a call to _non_existent() should cause omniORB to - # clean up the stale socket, and subsequent calls behave normally. - comp.ref._non_existent() - except: - pass - # Services don't get initialized or configured if not hasattr(comp, 'initialize'): return @@ -468,3 +428,6 @@ def browse(self, searchPath=None, objType=None,withDescription=False): output_text += '%-30s%-30s%-30s%-30s\n' % (v1,v2,v3,v4) output_text += "\n" pydoc.pager(output_text) + + def getType(self): + return "local" From 73af5c48510d219068fd44ce94395a8b8508b950 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 13 Jan 2016 10:15:40 -0500 Subject: [PATCH 0038/1644] Move sandbox component classes to their own "model" sub-package --- .../python/ossie/utils/sandbox/base.py | 152 +---------------- .../python/ossie/utils/sandbox/model.py | 154 ++++++++++++++++++ 2 files changed, 156 insertions(+), 150 deletions(-) create mode 100644 redhawk/src/base/framework/python/ossie/utils/sandbox/model.py diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/base.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/base.py index 4bbb0e005..fe29983bc 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/base.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/base.py @@ -20,7 +20,6 @@ import os import logging -import warnings as _warnings import time from ossie import parsers @@ -28,11 +27,9 @@ from ossie import properties as _properties from ossie.utils import log4py from ossie.utils import weakobj -from ossie.utils.model import PortSupplier, PropertySet, ComponentBase, CorbaObject -from ossie.utils.model import Service, Resource, Device -from ossie.utils.model.connect import ConnectionManager from ossie.utils.uuid import uuid4 -from ossie.utils.sandbox.events import EventChannel + +from model import SandboxComponent, SandboxDevice, SandboxEventChannel log = logging.getLogger(__name__) @@ -365,148 +362,3 @@ def setup(self, comp): def terminate(self, comp): raise NotImplementedError('terminate') - - -class SandboxResource(ComponentBase): - def __init__(self, sandbox, profile, spd, scd, prf, instanceName, refid, impl): - super(SandboxResource,self).__init__(spd, scd, prf, instanceName, refid, impl) - self._sandbox = sandbox - self._profile = profile - self._componentName = spd.get_name() - self._propRef = {} - self._configRef = {} - self._msgSupplierHelper = None - for prop in self._getPropertySet(kinds=('configure',), modes=('readwrite', 'writeonly'), includeNil=False): - if prop.defValue is None: - continue - self._configRef[str(prop.id)] = prop.defValue - for prop in self._getPropertySet(kinds=('property',), includeNil=False, commandline=False): - if prop.defValue is None: - continue - self._propRef[str(prop.id)] = prop.defValue - - self.__ports = None - - self._parseComponentXMLFiles() - self._buildAPI() - - def _getExecparams(self): - execparams = dict((str(ep.id), ep.defValue) for ep in self._getPropertySet(kinds=('execparam',), includeNil=False)) - for prop in self._getPropertySet(kinds=('property',), includeNil=False, commandline=True): - execparams[str(prop.id)] = prop.defValue - return execparams - - def _readProfile(self): - sdrRoot = self._sandbox.getSdrRoot() - self._spd, self._scd, self._prf = sdrRoot.readProfile(self._profile) - - def _kick(self): - self.ref = self._factory.launch(self) - self._factory.setup(self) - self._sandbox._registerComponent(self) - - @property - def _ports(self): - #DEPRECATED: replaced with ports - _warnings.warn("'_ports' is deprecated", DeprecationWarning) - return self.ports - - @property - def ports(self): - if self.__ports == None: - self.__ports = self._populatePorts() - return self.__ports - - def reset(self): - self.releaseObject() - self._readProfile() - self._kick() - self.initialize() - self._parseComponentXMLFiles() - self._buildAPI() - # Clear cached ports list - self.__ports = None - - def releaseObject(self): - # Break any connections involving this component. - manager = ConnectionManager.instance() - for _identifier, (identifier, uses, provides) in manager.getConnections().items(): - if uses.hasComponent(self) or provides.hasComponent(self): - manager.breakConnection(identifier, uses) - manager.unregisterConnection(identifier, uses) - self._sandbox._unregisterComponent(self) - - # Call superclass release, which calls the CORBA method. - super(SandboxResource,self).releaseObject() - - # Allow the launch factory to peform any follow-up cleanup. - if self._factory: - self._factory.terminate(self) - - def api(self): - ''' - Inspect interfaces and properties for the component - ''' - print "Component [" + str(self._componentName) + "]:" - PortSupplier.api(self) - PropertySet.api(self) - - def sendMessage(self, msg, msgId=None, msgPort=None, restrict=True ): - """ - send a message out a component's message event port - - msg : dictionary of information to send or an any object - msgId : select a specific message structure property from the component, if None will - choose first available message property structure for the component - msgPort : select a specified message event port to use, if None will try to autoselect - restrict : if True, will restrict msgId to only those message ids defined by the component - if False, will allow for ad-hoc message to be sent - """ - if self._msgSupplierHelper == None: - import ossie.utils - self._msgSupplierHelper = ossie.utils.sb.io_helpers.MsgSupplierHelper(self) - if self.ref and self.ref._get_started() == True and self._msgSupplierHelper: - return self._msgSupplierHelper.sendMessage( msg, msgId, msgPort, restrict ) - return False - -class SandboxComponent(SandboxResource, Resource): - def __init__(self, *args, **kwargs): - Resource.__init__(self) - SandboxResource.__init__(self, *args, **kwargs) - - def __repr__(self): - return "<%s component '%s' at 0x%x>" % (self._sandbox.getType(), self._instanceName, id(self)) - - -class SandboxDevice(SandboxResource, Device): - def __init__(self, *args, **kwargs): - Device.__init__(self) - SandboxResource.__init__(self, *args, **kwargs) - - Device._buildAPI(self) - - def __repr__(self): - return "<%s device '%s' at 0x%x>" % (self._sandbox.getType(), self._instanceName, id(self)) - - def api(self): - SandboxResource.api(self) - print - Device.api(self) - - -class SandboxEventChannel(EventChannel, CorbaObject): - def __init__(self, name, sandbox): - EventChannel.__init__(self, name) - CorbaObject.__init__(self) - self._sandbox = sandbox - self._instanceName = name - - def destroy(self): - # Break any connections involving this event channel. - manager = ConnectionManager.instance() - for _identifier, (identifier, uses, provides) in manager.getConnections().items(): - if provides.hasComponent(self): - manager.breakConnection(identifier, uses) - manager.unregisterConnection(identifier, uses) - self._sandbox._removeEventChannel(self._instanceName) - EventChannel.destroy(self) diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/model.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/model.py new file mode 100644 index 000000000..b162dc74d --- /dev/null +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/model.py @@ -0,0 +1,154 @@ +# +# This file is protected by Copyright. Please refer to the COPYRIGHT file +# distributed with this source distribution. +# +# This file is part of REDHAWK core. +# +# REDHAWK core is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation, either version 3 of the License, or (at your option) any +# later version. +# +# REDHAWK core is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +# details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/. +# + +import warnings + +from ossie.utils.model import CorbaObject +from ossie.utils.model import PortSupplier, PropertySet, ComponentBase +from ossie.utils.model import Resource, Device +from ossie.utils.model.connect import ConnectionManager + +from ossie.utils.sandbox.events import EventChannel + +class SandboxResource(ComponentBase): + def __init__(self, sandbox, profile, spd, scd, prf, instanceName, refid, impl): + super(SandboxResource,self).__init__(spd, scd, prf, instanceName, refid, impl) + self._sandbox = sandbox + self._profile = profile + self._componentName = spd.get_name() + self._propRef = {} + self._configRef = {} + for prop in self._getPropertySet(kinds=('configure',), modes=('readwrite', 'writeonly'), includeNil=False): + if prop.defValue is None: + continue + self._configRef[str(prop.id)] = prop.defValue + for prop in self._getPropertySet(kinds=('property',), includeNil=False, commandline=False): + if prop.defValue is None: + continue + self._propRef[str(prop.id)] = prop.defValue + + self.__ports = None + + self._parseComponentXMLFiles() + self._buildAPI() + + def _getExecparams(self): + execparams = dict((str(ep.id), ep.defValue) for ep in self._getPropertySet(kinds=('execparam',), includeNil=False)) + for prop in self._getPropertySet(kinds=('property',), includeNil=False, commandline=True): + execparams[str(prop.id)] = prop.defValue + return execparams + + def _readProfile(self): + sdrRoot = self._sandbox.getSdrRoot() + self._spd, self._scd, self._prf = sdrRoot.readProfile(self._profile) + + def _kick(self): + self.ref = self._factory.launch(self) + self._factory.setup(self) + self._sandbox._registerComponent(self) + + @property + def _ports(self): + #DEPRECATED: replaced with ports + warnings.warn("'_ports' is deprecated", DeprecationWarning) + return self.ports + + @property + def ports(self): + if self.__ports == None: + self.__ports = self._populatePorts() + return self.__ports + + def reset(self): + self.releaseObject() + self._readProfile() + self._kick() + self.initialize() + self._parseComponentXMLFiles() + self._buildAPI() + # Clear cached ports list + self.__ports = None + + def releaseObject(self): + # Break any connections involving this component. + manager = ConnectionManager.instance() + for identifier, (uses, provides) in manager.getConnections().items(): + if uses.hasComponent(self) or provides.hasComponent(self): + manager.breakConnection(identifier) + manager.unregisterConnection(identifier) + self._sandbox._unregisterComponent(self) + + # Call superclass release, which calls the CORBA method. + super(SandboxResource,self).releaseObject() + + # Allow the launch factory to peform any follow-up cleanup. + if self._factory: + self._factory.terminate(self) + + def api(self): + ''' + Inspect interfaces and properties for the component + ''' + print "Component [" + str(self._componentName) + "]:" + PortSupplier.api(self) + PropertySet.api(self) + + +class SandboxComponent(SandboxResource, Resource): + def __init__(self, *args, **kwargs): + Resource.__init__(self) + SandboxResource.__init__(self, *args, **kwargs) + + def __repr__(self): + return "<%s component '%s' at 0x%x>" % (self._sandbox.getType(), self._instanceName, id(self)) + + +class SandboxDevice(SandboxResource, Device): + def __init__(self, *args, **kwargs): + Device.__init__(self) + SandboxResource.__init__(self, *args, **kwargs) + + Device._buildAPI(self) + + def __repr__(self): + return "<%s device '%s' at 0x%x>" % (self._sandbox.getType(), self._instanceName, id(self)) + + def api(self): + SandboxResource.api(self) + print + Device.api(self) + + +class SandboxEventChannel(EventChannel, CorbaObject): + def __init__(self, name, sandbox): + EventChannel.__init__(self, name) + CorbaObject.__init__(self) + self._sandbox = sandbox + self._instanceName = name + + def destroy(self): + # Break any connections involving this event channel. + manager = ConnectionManager.instance() + for identifier, (uses, provides) in manager.getConnections().items(): + if provides.hasComponent(self): + manager.breakConnection(identifier) + manager.unregisterConnection(identifier) + self._sandbox._removeEventChannel(self._instanceName) + EventChannel.destroy(self) From d10eb4183716ef868139833e480e5069f0b371f4 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 13 Jan 2016 10:17:50 -0500 Subject: [PATCH 0039/1644] Remove dead functions --- .../python/ossie/utils/sandbox/ide.py | 6 +--- .../python/ossie/utils/sandbox/local.py | 30 ------------------- 2 files changed, 1 insertion(+), 35 deletions(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/ide.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/ide.py index e97387440..f592e69d0 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/ide.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/ide.py @@ -143,11 +143,7 @@ def _createFactory(self, comptype, execparams, initProps, initialize, configProp return IDEFactory(execparams, debugger, window, timeout) return None - def _launch(self, comp, execparams, initProps, initialize, configProps, debugger, window, timeout): - comp._execparams = execparams - comp._kick() - - def _createResource(self, profile, name, qualifiers=[]): + def _createResource(self, profile, name, execparams={}, impl=None): log.debug("Creating resource '%s' with profile '%s'", name, profile) rescFactory = self.__ide.getResourceFactoryByProfile(profile) diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py index 61273233e..c8a52ce81 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py @@ -243,36 +243,6 @@ def _createFactory(self, comptype, execparams, initProps, initialize, configProp raise NotImplementedError("No support for component type '%s'" % comptype) return clazz(execparams, initProps, initialize, configProps, debugger, window, timeout) - def _launch(self, comp, execparams, initProps, initialize, configProps, debugger, window, timeout): - # Services don't get initialized or configured - if not hasattr(comp, 'initialize'): - return - - # Initialize the component unless asked not to. - if initialize: - # Set initial property values for 'property' kind properties - initvals = copy.deepcopy(comp._propRef) - initvals.update(initProps) - try: - comp.initializeProperties(initvals) - except: - log.exception('Failure in component property initialization') - - # Actually initialize the component - comp.initialize() - - # Configure component with default values unless requested not to (e.g., - # when launched from a SAD file). - if configProps is not None: - # Make a copy of the default properties, and update with any passed-in - # properties that were not already passed to initializeProperties() - initvals = copy.deepcopy(comp._configRef) - initvals.update(configProps) - try: - comp.configure(initvals) - except: - log.exception('Failure in component configuration') - def getComponents(self): return self.__components.values() From 0a948c0ab70a50cc3b9f0b6a03a59dc2d8da7298 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 13 Jan 2016 10:51:09 -0500 Subject: [PATCH 0040/1644] Fix accidental IDE sandbox breakage --- redhawk/src/base/framework/python/ossie/utils/sandbox/ide.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/ide.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/ide.py index f592e69d0..6671f44fb 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/ide.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/ide.py @@ -140,7 +140,7 @@ def _checkInstanceId(self, refid, componentType='resource'): def _createFactory(self, comptype, execparams, initProps, initialize, configProps, debugger, window, timeout): if comptype in ('resource', 'device', 'loadabledevice', 'executabledevice'): - return IDEFactory(execparams, debugger, window, timeout) + return IDEFactory(execparams) return None def _createResource(self, profile, name, execparams={}, impl=None): From e0c6530b3402af34dd9340e6d274698a1a311dda Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 13 Jan 2016 10:52:46 -0500 Subject: [PATCH 0041/1644] Move local service proxy to base sandbox model, following pattern established with components and devices --- .../python/ossie/utils/sandbox/base.py | 10 ++++- .../python/ossie/utils/sandbox/local.py | 36 ++--------------- .../python/ossie/utils/sandbox/model.py | 39 ++++++++++++++++++- 3 files changed, 49 insertions(+), 36 deletions(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/base.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/base.py index fe29983bc..fccb92850 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/base.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/base.py @@ -29,7 +29,7 @@ from ossie.utils import weakobj from ossie.utils.uuid import uuid4 -from model import SandboxComponent, SandboxDevice, SandboxEventChannel +from model import SandboxComponent, SandboxDevice, SandboxService, SandboxEventChannel log = logging.getLogger(__name__) @@ -236,6 +236,8 @@ def launch(self, descriptor, instanceName=None, refid=None, impl=None, clazz = SandboxComponent elif comptype in ('device', 'loadabledevice', 'executabledevice'): clazz = SandboxDevice + elif comptype == 'service': + clazz = SandboxService else: raise NotImplementedError("No support for component type '%s'" % comptype) @@ -256,7 +258,11 @@ def launch(self, descriptor, instanceName=None, refid=None, impl=None, # Determine the class for the component type and create a new instance. comp = clazz(self, profile, spd, scd, prf, instanceName, refid, impl) - comp._factory = self._createFactory(comptype, execparams, initProps, initialize, configure, debugger, window, timeout) + factory = self._createFactory(comptype, execparams, initProps, initialize, configure, debugger, window, timeout) + if not factory: + raise NotImplementedError("No support for component type '%s'" % comptype) + comp._factory = factory + # Launch the component comp._kick() diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py index c8a52ce81..b1a75e0a5 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py @@ -26,7 +26,6 @@ import warnings from ossie import parsers -from ossie.utils.model import Service from ossie.utils.model.connect import ConnectionManager from base import SdrRoot, Sandbox, SandboxFactory @@ -166,37 +165,6 @@ class LocalDeviceFactory(LocalFactory): class LocalServiceFactory(LocalFactory): __launcher__ = launcher.ServiceLauncher -class LocalService(Service): - def __init__(self, sdrroot, profile, spd, scd, prf, instanceName, refid, impl): - self._sandbox = sdrroot - Service.__init__(self, None, profile, spd, scd, prf, instanceName, refid, impl) - - def _kick(self): - self.ref = self._launch() - self.populateMemberFunctions() - self._sandbox._addService(self) - - def _getExecparams(self): - if not self._prf: - return {} - execparams = {} - for prop in self._prf.get_simple(): - # Skip non-execparam properties - kinds = set(k.get_kindtype() for k in prop.get_kind()) - if ('execparam' not in kinds) and ('property' not in kinds): - continue - if 'property' in kinds: - if prop.get_commandline() == 'false': - continue - # Only include properties with values - value = prop.get_value() - if value is not None: - execparams[prop.get_id()] = value - return execparams - - def __repr__(self): - return "" % (self._instanceName, id(self)) - class LocalSandbox(Sandbox): def __init__(self, sdrroot): @@ -239,8 +207,10 @@ def _createFactory(self, comptype, execparams, initProps, initialize, configProp clazz = LocalComponentFactory elif comptype in ('device', 'loadabledevice', 'executabledevice'): clazz = LocalDeviceFactory + elif comptype == 'service': + clazz = LocalServiceFactory else: - raise NotImplementedError("No support for component type '%s'" % comptype) + return None return clazz(execparams, initProps, initialize, configProps, debugger, window, timeout) def getComponents(self): diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/model.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/model.py index b162dc74d..8a827197c 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/model.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/model.py @@ -22,7 +22,7 @@ from ossie.utils.model import CorbaObject from ossie.utils.model import PortSupplier, PropertySet, ComponentBase -from ossie.utils.model import Resource, Device +from ossie.utils.model import Resource, Device, Service from ossie.utils.model.connect import ConnectionManager from ossie.utils.sandbox.events import EventChannel @@ -136,6 +136,43 @@ def api(self): Device.api(self) +class SandboxService(Service): + def __init__(self, sandbox, profile, spd, scd, prf, instanceName, refid, impl): + self._sandbox = sandbox + Service.__init__(self, None, profile, spd, scd, prf, instanceName, refid, impl) + + def _kick(self): + self.ref = self._factory.launch(self) + self._factory.setup(self) + self.populateMemberFunctions() + self._sandbox._addService(self) + + def _terminate(self): + if self._factory: + self._factory.terminate(self) + + def _getExecparams(self): + if not self._prf: + return {} + execparams = {} + for prop in self._prf.get_simple(): + # Skip non-execparam properties + kinds = set(k.get_kindtype() for k in prop.get_kind()) + if ('execparam' not in kinds) and ('property' not in kinds): + continue + if 'property' in kinds: + if prop.get_commandline() != 'true': + continue + # Only include properties with values + value = prop.get_value() + if value is not None: + execparams[prop.get_id()] = value + return execparams + + def __repr__(self): + return "<%s service '%s' at 0x%x>" % (self._instanceName, self._sandbox.getType(), id(self)) + + class SandboxEventChannel(EventChannel, CorbaObject): def __init__(self, name, sandbox): EventChannel.__init__(self, name) From 0659218740c15e410eae01bf37b3cbe3df8e6817 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 13 Jan 2016 11:30:45 -0500 Subject: [PATCH 0042/1644] Clean up imports --- .../src/base/framework/python/ossie/utils/sandbox/base.py | 6 +----- .../src/base/framework/python/ossie/utils/sandbox/ide.py | 3 ++- .../src/base/framework/python/ossie/utils/sandbox/local.py | 3 +-- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/base.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/base.py index fccb92850..0427b3a0f 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/base.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/base.py @@ -19,13 +19,9 @@ # import os -import logging -import time from ossie import parsers -from ossie.cf import CF -from ossie import properties as _properties -from ossie.utils import log4py +from ossie.utils.log4py import logging from ossie.utils import weakobj from ossie.utils.uuid import uuid4 diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/ide.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/ide.py index 6671f44fb..d5bfc711f 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/ide.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/ide.py @@ -34,7 +34,8 @@ from ossie.utils.model import CorbaObject -from base import SdrRoot, Sandbox, SandboxComponent, SandboxDevice, SandboxFactory +from base import SdrRoot, Sandbox, SandboxFactory +from model import SandboxComponent, SandboxDevice log = logging.getLogger(__name__) diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py index b1a75e0a5..8201862e4 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py @@ -23,14 +23,13 @@ import fnmatch import time import copy -import warnings +import pydoc from ossie import parsers from ossie.utils.model.connect import ConnectionManager from base import SdrRoot, Sandbox, SandboxFactory import launcher -import pydoc log = logging.getLogger(__name__) From ec168fd75b241b4e75f8cc9c3cee490e88105b7c Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 13 Jan 2016 11:50:54 -0500 Subject: [PATCH 0043/1644] Remove dead code --- .../framework/python/ossie/utils/sandbox/launcher.py | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/launcher.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/launcher.py index aad09d74a..384bba900 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/launcher.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/launcher.py @@ -152,9 +152,6 @@ def _getEntryPoint(self, implementation): entry_point = os.path.join(self._xmlpath, entry_point) return entry_point - def _getDomainPath(self): - return {"DOM_PATH" : "/dom/sandbox/"} - def execute(self, spd, impl, execparams, debugger, window, timeout=None): # Find a suitable implementation. if impl: @@ -181,14 +178,6 @@ def execute(self, spd, impl, execparams, debugger, window, timeout=None): # Get required execparams based on the component type execparams.update(self._getRequiredExecparams()) - ''' - execparams.update(self._getDomainPath()) - if execparams.has_key('LOGGING_CONFIG_URI'): - if execparams['LOGGING_CONFIG_URI'].find("sca:") == 0: - execparams['LOGGING_CONFIG_URI'] += "?fs=" + orb.object_to_string(self.__namingContext._this()),DeviceManagerStub - pass - ''' - # Convert execparams into arguments. arguments = [] for name, value in execparams.iteritems(): From 5bc5573200342a0b990e3ae1634dfa388d4e5bb1 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 13 Jan 2016 12:56:24 -0500 Subject: [PATCH 0044/1644] Absorb some of the type-specific launch functionality into the local sandbox launch factories --- .../python/ossie/utils/sandbox/launcher.py | 101 ++--------------- .../python/ossie/utils/sandbox/local.py | 106 ++++++++++++++++-- 2 files changed, 104 insertions(+), 103 deletions(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/launcher.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/launcher.py index 384bba900..3aa54ebed 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/launcher.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/launcher.py @@ -27,24 +27,15 @@ import tempfile import subprocess -from omniORB import CORBA, URI - from ossie.utils import log4py from ossie import parsers from ossie.utils.popen import Popen -from devmgr import DeviceManagerStub -from naming import NamingContextStub from debugger import GDB, PDB, Valgrind from terminal import XTerm __all__ = ('ResourceLauncher', 'DeviceLauncher', 'ServiceLauncher') -# Prepare the ORB -orb = CORBA.ORB_init() -poa = orb.resolve_initial_references("RootPOA") -poa._get_the_POAManager().activate() - log = logging.getLogger(__name__) @@ -125,12 +116,15 @@ def terminate(self): self.__debugger.terminate() self.__child.terminate() + def isAlive(self): + return self.__child.isAlive() + + class LocalLauncher(object): - def __init__(self, profile, identifier, name, sandbox): + def __init__(self, profile, name, sandbox): self._sandbox = sandbox self._profile = profile self._xmlpath = os.path.dirname(self._profile) - self._identifier = identifier self._name = name def _selectImplementation(self, spd): @@ -152,7 +146,7 @@ def _getEntryPoint(self, implementation): entry_point = os.path.join(self._xmlpath, entry_point) return entry_point - def execute(self, spd, impl, execparams, debugger, window, timeout=None): + def execute(self, spd, impl, execparams, debugger, window): # Find a suitable implementation. if impl: implementation = self._getImplementation(spd, impl) @@ -175,9 +169,6 @@ def execute(self, spd, impl, execparams, debugger, window, timeout=None): for varname in ('LD_LIBRARY_PATH', 'PYTHONPATH', 'CLASSPATH'): log.trace('%s=%s', varname, environment.get(varname, '')) - # Get required execparams based on the component type - execparams.update(self._getRequiredExecparams()) - # Convert execparams into arguments. arguments = [] for name, value in execparams.iteritems(): @@ -205,7 +196,6 @@ def execute(self, spd, impl, execparams, debugger, window, timeout=None): if debugger and debugger.modifiesCommand(): # Run the command in the debugger. command, arguments = debugger.wrap(entry_point, arguments) - default_timeout = 60.0 if debugger.isInteractive() and not debugger.canAttach(): if not window: window = XTerm() @@ -213,11 +203,6 @@ def execute(self, spd, impl, execparams, debugger, window, timeout=None): else: # Run the command directly. command = entry_point - default_timeout = 10.0 - - # Provided timeout takes precedence - if timeout is None: - timeout = default_timeout stdout = None if window_mode == 'monitor': @@ -237,21 +222,6 @@ def execute(self, spd, impl, execparams, debugger, window, timeout=None): command, arguments = window.command(command, arguments) process = LocalProcess(command, arguments, environment, stdout) - # Wait for the component to register with the virtual naming service or - # DeviceManager. - sleepIncrement = 0.1 - while self.getReference() is None: - if not process.isAlive(): - raise RuntimeError, "%s '%s' terminated before registering with virtual environment" % (self._getType(), self._name) - time.sleep(sleepIncrement) - timeout -= sleepIncrement - if timeout < 0: - process.terminate() - raise RuntimeError, "%s '%s' did not register with virtual environment" % (self._getType(), self._name) - - # Store the CORBA reference. - ref = self.getReference() - # Attach a debugger to the process. if debugger and debugger.canAttach(): if not window: @@ -261,7 +231,7 @@ def execute(self, spd, impl, execparams, debugger, window, timeout=None): debug_process = LocalProcess(debug_command, debug_args) process = DebuggerProcess(debug_process, process) - return process, ref + return process # this function checks that the base dependencies match an impl exactly def _equalDeps(self, base, impl): @@ -403,60 +373,3 @@ def _extendEnvironment(self, env, keyname, value): return oldvalue.insert(0,value) env[keyname] = ':'.join(oldvalue) - -class ResourceLauncher(LocalLauncher): - def __init__(self, profile, identifier, name, sdrroot): - super(ResourceLauncher,self).__init__(profile, identifier, name, sdrroot) - self.__namingContext = NamingContextStub() - log.trace('Activating virtual NamingContext') - self.__namingContextId = poa.activate_object(self.__namingContext) - - def __del__(self): - log.trace('Deactivating virtual NamingContext') - poa.deactivate_object(self.__namingContextId) - - def getReference(self): - return self.__namingContext.getObject(self._name) - - def _getRequiredExecparams(self): - return {'COMPONENT_IDENTIFIER': self._identifier, - 'NAMING_CONTEXT_IOR': orb.object_to_string(self.__namingContext._this()), - 'PROFILE_NAME': self._profile, - 'NAME_BINDING': self._name} - - def _getType(self): - return 'resource' - -class ServiceLauncher(LocalLauncher): - def getReference(self): - return DeviceManagerStub.instance().getService(self._name) - - def _getRequiredExecparams(self): - devmgr_stub = DeviceManagerStub.instance() - devmgr_ior = orb.object_to_string(devmgr_stub._this()) - - return {'DEVICE_MGR_IOR': devmgr_ior, - 'SERVICE_NAME': self._name} - - def _getType(self): - return 'service' - -class DeviceLauncher(LocalLauncher): - def getReference(self): - return DeviceManagerStub.instance().getDevice(self._identifier) - - def _getRequiredExecparams(self): - devmgr_stub = DeviceManagerStub.instance() - devmgr_ior = orb.object_to_string(devmgr_stub._this()) - # Create (or reuse) IDM channel. - idm_channel = self._sandbox.createEventChannel('IDM_Channel') - idm_ior = orb.object_to_string(idm_channel.ref) - - return {'DEVICE_ID': self._identifier, - 'DEVICE_LABEL': self._name, - 'DEVICE_MGR_IOR': devmgr_ior, - 'IDM_CHANNEL_IOR': idm_ior, - 'PROFILE_NAME': self._profile} - - def _getType(self): - return 'device' diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py index 8201862e4..d1210d229 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py @@ -25,12 +25,21 @@ import copy import pydoc +from omniORB import CORBA + from ossie import parsers from ossie.utils.model.connect import ConnectionManager from base import SdrRoot, Sandbox, SandboxFactory +from devmgr import DeviceManagerStub +from naming import NamingContextStub import launcher +# Prepare the ORB +orb = CORBA.ORB_init() +poa = orb.resolve_initial_references("RootPOA") +poa._get_the_POAManager().activate() + log = logging.getLogger(__name__) class LocalSdrRoot(SdrRoot): @@ -97,19 +106,47 @@ def __init__(self, execparams, initProps, initialize, configProps, debugger, win self._execparams = execparams self._debugger = debugger self._window = window - self._timeout = timeout self._initProps = initProps self._initialize = initialize self._configProps = configProps + # Provided timeout takes precedence + if timeout is None: + # Default timeout depends on whether the debugger might increase + # the startup time + if debugger: # and debugger.modifiesCommand(): + timeout = 60.0 + else: + timeout = 10.0 + self._timeout = timeout + def launch(self, comp): - launchFactory = self.__launcher__(comp._profile, comp._refid, comp._instanceName, comp._sandbox) + # Build up the full set of command line arguments execparams = comp._getExecparams() execparams.update(self._execparams) - proc, ref = launchFactory.execute(comp._spd, comp._impl, execparams, self._debugger, self._window, self._timeout) - # Store the process on the component proxy - comp._process = proc - return ref + execparams.update(self._getRequiredExecparams(comp)) + + launchFactory = launcher.LocalLauncher(comp._profile, comp._instanceName, comp._sandbox) + process = launchFactory.execute(comp._spd, comp._impl, execparams, self._debugger, self._window) + + # Wait for the component to register with the virtual naming service or + # DeviceManager. + timeout = self._timeout + sleepIncrement = 0.1 + while self.getReference(comp) is None: + if not process.isAlive(): + raise RuntimeError, "%s '%s' terminated before registering with virtual environment" % (self._getType(), comp._instanceName) + time.sleep(sleepIncrement) + timeout -= sleepIncrement + if timeout < 0: + process.terminate() + raise RuntimeError, "%s '%s' did not register with virtual environment" % (self._getType(), comp._instanceName) + + # Store the process on the component proxy. + comp._process = process + + # Return the now-resolved CORBA reference. + return self.getReference(comp) def setup(self, comp): # Services don't get initialized or configured @@ -156,13 +193,64 @@ def terminate(self, comp): class LocalComponentFactory(LocalFactory): - __launcher__ = launcher.ResourceLauncher + def launch(self, *args, **kwargs): + self.__namingContext = NamingContextStub() + log.trace('Activating virtual NamingContext') + namingContextId = poa.activate_object(self.__namingContext) + try: + return LocalFactory.launch(self, *args, **kwargs) + finally: + log.trace('Deactivating virtual NamingContext') + poa.deactivate_object(namingContextId) + del self.__namingContext + + def getReference(self, component): + return self.__namingContext.getObject(component._instanceName) + + def _getRequiredExecparams(self, component): + return {'COMPONENT_IDENTIFIER': component._refid, + 'NAMING_CONTEXT_IOR': orb.object_to_string(self.__namingContext._this()), + 'PROFILE_NAME': component._profile, + 'NAME_BINDING': component._instanceName} + + def _getType(self): + return 'resource' + class LocalDeviceFactory(LocalFactory): - __launcher__ = launcher.DeviceLauncher + def getReference(self, device): + return DeviceManagerStub.instance().getDevice(device._refid) + + def _getRequiredExecparams(self, device): + devmgr_stub = DeviceManagerStub.instance() + devmgr_ior = orb.object_to_string(devmgr_stub._this()) + # Create (or reuse) IDM channel. + idm_channel = device._sandbox.createEventChannel('IDM_Channel') + idm_ior = orb.object_to_string(idm_channel.ref) + + return {'DEVICE_ID': device._refid, + 'DEVICE_LABEL': device._instanceName, + 'DEVICE_MGR_IOR': devmgr_ior, + 'IDM_CHANNEL_IOR': idm_ior, + 'PROFILE_NAME': device._profile} + + def _getType(self): + return 'device' + class LocalServiceFactory(LocalFactory): - __launcher__ = launcher.ServiceLauncher + def getReference(self, service): + return DeviceManagerStub.instance().getService(service._instanceName) + + def _getRequiredExecparams(self, service): + devmgr_stub = DeviceManagerStub.instance() + devmgr_ior = orb.object_to_string(devmgr_stub._this()) + + return {'DEVICE_MGR_IOR': devmgr_ior, + 'SERVICE_NAME': service._instanceName} + + def _getType(self): + return 'service' class LocalSandbox(Sandbox): From 19170e291b67de28f2c030a1db67e9df63661230 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 13 Jan 2016 13:26:47 -0500 Subject: [PATCH 0045/1644] Move debugger responsibility to the local sandbox launcher; create a single method that launches a softpkg --- .../python/ossie/utils/sandbox/launcher.py | 19 ++------- .../python/ossie/utils/sandbox/local.py | 40 +++++++++++++------ 2 files changed, 32 insertions(+), 27 deletions(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/launcher.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/launcher.py index 3aa54ebed..03398bf24 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/launcher.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/launcher.py @@ -31,7 +31,6 @@ from ossie import parsers from ossie.utils.popen import Popen -from debugger import GDB, PDB, Valgrind from terminal import XTerm __all__ = ('ResourceLauncher', 'DeviceLauncher', 'ServiceLauncher') @@ -174,20 +173,6 @@ def execute(self, spd, impl, execparams, debugger, window): for name, value in execparams.iteritems(): arguments += [name, str(value)] - if isinstance(debugger,basestring): - try: - if debugger == 'pdb': - debugger = PDB() - elif debugger == 'gdb': - debugger = GDB() - elif debugger == 'valgrind': - debugger = Valgrind() - else: - raise RuntimeError, 'not supported' - except Exception, e: - log.warning('Cannot run debugger %s (%s)', debugger, e) - debugger = None - if window: window_mode = 'monitor' else: @@ -373,3 +358,7 @@ def _extendEnvironment(self, env, keyname, value): return oldvalue.insert(0,value) env[keyname] = ':'.join(oldvalue) + +def launchSoftpkg(profile, name, sandbox, spd, impl, execparams, debugger, window): + launcher = LocalLauncher(profile, name, sandbox) + return launcher.execute(spd, impl, execparams, debugger, window) diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py index d1210d229..cf58ffa6f 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py @@ -34,6 +34,7 @@ from devmgr import DeviceManagerStub from naming import NamingContextStub import launcher +from debugger import GDB, PDB, Valgrind # Prepare the ORB orb = CORBA.ORB_init() @@ -109,15 +110,6 @@ def __init__(self, execparams, initProps, initialize, configProps, debugger, win self._initProps = initProps self._initialize = initialize self._configProps = configProps - - # Provided timeout takes precedence - if timeout is None: - # Default timeout depends on whether the debugger might increase - # the startup time - if debugger: # and debugger.modifiesCommand(): - timeout = 60.0 - else: - timeout = 10.0 self._timeout = timeout def launch(self, comp): @@ -126,12 +118,36 @@ def launch(self, comp): execparams.update(self._execparams) execparams.update(self._getRequiredExecparams(comp)) - launchFactory = launcher.LocalLauncher(comp._profile, comp._instanceName, comp._sandbox) - process = launchFactory.execute(comp._spd, comp._impl, execparams, self._debugger, self._window) + # Set up the debugger if requested + debugger = self._debugger + if isinstance(debugger, basestring): + try: + if debugger == 'pdb': + debugger = PDB() + elif debugger == 'gdb': + debugger = GDB() + elif debugger == 'valgrind': + debugger = Valgrind() + else: + raise RuntimeError, 'not supported' + except Exception, e: + log.warning('Cannot run debugger %s (%s)', debugger, e) + debugger = None + + process = launcher.launchSoftpkg(comp._profile, comp._instanceName, comp._sandbox, comp._spd, + comp._impl, execparams, debugger, self._window) # Wait for the component to register with the virtual naming service or # DeviceManager. - timeout = self._timeout + if self._timeout is None: + # Default timeout depends on whether the debugger might increase + # the startup time + if debugger and debugger.modifiesCommand(): + timeout = 60.0 + else: + timeout = 10.0 + else: + timeout = self._timeout sleepIncrement = 0.1 while self.getReference(comp) is None: if not process.isAlive(): From 8b0492d98133daaeafdc88a392b1383b5c74b5cc Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 13 Jan 2016 14:32:23 -0500 Subject: [PATCH 0046/1644] Move window creation and debugger attach responsibility to local sandbox launcher --- .../python/ossie/utils/sandbox/debugger.py | 7 ++++ .../python/ossie/utils/sandbox/launcher.py | 24 +++---------- .../python/ossie/utils/sandbox/local.py | 35 +++++++++++++++++-- .../python/ossie/utils/sandbox/terminal.py | 13 ++++--- 4 files changed, 53 insertions(+), 26 deletions(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/debugger.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/debugger.py index 6dd88b392..e129ee1e8 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/debugger.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/debugger.py @@ -55,6 +55,9 @@ def attach(self, process): def wrap(self, command, arguments): return self.command, ['--args', command] + arguments + def name(self): + return 'gdb' + class PDB(Debugger): def __init__(self): super(PDB,self).__init__(PDB.findPDB()) @@ -73,6 +76,8 @@ def findPDB(): return filename raise RuntimeError, 'pdb cannot be found' + def name(self): + return 'pdb' class Valgrind(Debugger): def __init__(self, quiet=False, verbose=False, **opts): @@ -102,3 +107,5 @@ def isInteractive(self): def wrap(self, command, arguments): return self.command, self.arguments + [command] + arguments + def name(self): + return 'valgrind' diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/launcher.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/launcher.py index 03398bf24..aa5ebc647 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/launcher.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/launcher.py @@ -31,9 +31,7 @@ from ossie import parsers from ossie.utils.popen import Popen -from terminal import XTerm - -__all__ = ('ResourceLauncher', 'DeviceLauncher', 'ServiceLauncher') +__all__ = ('LocalProcess', 'launchSoftpkg') log = logging.getLogger(__name__) @@ -120,11 +118,10 @@ def isAlive(self): class LocalLauncher(object): - def __init__(self, profile, name, sandbox): + def __init__(self, profile, sandbox): self._sandbox = sandbox self._profile = profile self._xmlpath = os.path.dirname(self._profile) - self._name = name def _selectImplementation(self, spd): for implementation in spd.get_implementation(): @@ -182,8 +179,6 @@ def execute(self, spd, impl, execparams, debugger, window): # Run the command in the debugger. command, arguments = debugger.wrap(entry_point, arguments) if debugger.isInteractive() and not debugger.canAttach(): - if not window: - window = XTerm() window_mode = 'direct' else: # Run the command directly. @@ -196,7 +191,7 @@ def execute(self, spd, impl, execparams, debugger, window): tempdir = tempfile.mkdtemp() fifoname = os.path.join(tempdir, 'fifo') os.mkfifo(fifoname) - window_command, window_args = window.command('/usr/bin/tail', ['-n', '+0', '-f', fifoname], self._name) + window_command, window_args = window.command('/usr/bin/tail', ['-n', '+0', '-f', fifoname]) window_proc = LocalProcess(window_command, window_args) stdout = open(fifoname, 'w') os.unlink(fifoname) @@ -207,15 +202,6 @@ def execute(self, spd, impl, execparams, debugger, window): command, arguments = window.command(command, arguments) process = LocalProcess(command, arguments, environment, stdout) - # Attach a debugger to the process. - if debugger and debugger.canAttach(): - if not window: - window = XTerm() - debug_command, debug_args = debugger.attach(process) - debug_command, debug_args = window.command(debug_command, debug_args) - debug_process = LocalProcess(debug_command, debug_args) - process = DebuggerProcess(debug_process, process) - return process # this function checks that the base dependencies match an impl exactly @@ -359,6 +345,6 @@ def _extendEnvironment(self, env, keyname, value): oldvalue.insert(0,value) env[keyname] = ':'.join(oldvalue) -def launchSoftpkg(profile, name, sandbox, spd, impl, execparams, debugger, window): - launcher = LocalLauncher(profile, name, sandbox) +def launchSoftpkg(profile, sandbox, spd, impl, execparams, debugger, window): + launcher = LocalLauncher(profile, sandbox) return launcher.execute(spd, impl, execparams, debugger, window) diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py index cf58ffa6f..dd1d3c8c1 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py @@ -35,6 +35,7 @@ from naming import NamingContextStub import launcher from debugger import GDB, PDB, Valgrind +import terminal # Prepare the ORB orb = CORBA.ORB_init() @@ -134,8 +135,29 @@ def launch(self, comp): log.warning('Cannot run debugger %s (%s)', debugger, e) debugger = None - process = launcher.launchSoftpkg(comp._profile, comp._instanceName, comp._sandbox, comp._spd, - comp._impl, execparams, debugger, self._window) + # If using an interactive debugger that directly runs the command, put + # it in a window so it doesn't compete for the terminal. + window = self._window + if debugger and debugger.modifiesCommand(): + if debugger.isInteractive() and not debugger.canAttach(): + if not window: + window = 'xterm' + + # Allow symbolic names for windows + if isinstance(window, basestring): + try: + if window == 'xterm': + window = terminal.XTerm(comp._instanceName) + elif window == 'gnome-terminal': + window = terminal.GnomeTerm(comp._instanceName) + else: + raise RuntimeError, 'not supported' + except Exception, e: + log.warning('Cannot run terminal %s (%s)', window, e) + debugger = None + + process = launcher.launchSoftpkg(comp._profile, comp._sandbox, comp._spd, + comp._impl, execparams, debugger, window) # Wait for the component to register with the virtual naming service or # DeviceManager. @@ -158,6 +180,15 @@ def launch(self, comp): process.terminate() raise RuntimeError, "%s '%s' did not register with virtual environment" % (self._getType(), comp._instanceName) + # Attach a debugger to the process. + if debugger and debugger.canAttach(): + if not window: + window = XTerm('%s (%s)' % (debugger.name(), comp._instanceName)) + debug_command, debug_args = debugger.attach(process) + debug_command, debug_args = window.command(debug_command, debug_args) + debug_process = launcher.LocalProcess(debug_command, debug_args) + process = launcher.DebuggerProcess(debug_process, process) + # Store the process on the component proxy. comp._process = process diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/terminal.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/terminal.py index 344438282..a938f5064 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/terminal.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/terminal.py @@ -21,23 +21,26 @@ import commands class Terminal(object): - def __init__(self, command): + def __init__(self, command, title): status, self.__command = commands.getstatusoutput('which '+command) if status: raise RuntimeError, command + ' cannot be found' + self._title = title def _termOpts(self): return [] def command(self, command, arguments, title=None): options = self._termOpts() + if not title: + title = self._title if title: options += self._titleArgs(title) return self.__command, options + self._execArgs(command, arguments) class XTerm(Terminal): - def __init__(self): - super(XTerm,self).__init__('xterm') + def __init__(self, title=None): + super(XTerm,self).__init__('xterm', title) def _titleArgs(self, title): return ['-T', title] @@ -46,8 +49,8 @@ def _execArgs(self, command, arguments): return ['-e', command] + arguments class GnomeTerm(Terminal): - def __init__(self): - super(GnomeTerm,self).__init__('gnome-terminal') + def __init__(self, title=None): + super(GnomeTerm,self).__init__('gnome-terminal', title) def _titleArgs(self, title): return ['-t', title] From c1a804106d0dfd351ed08c554efeec6b5e26b4f2 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 13 Jan 2016 14:47:21 -0500 Subject: [PATCH 0047/1644] Disable initialize/configure of sandbox service in the service launcher --- .../base/framework/python/ossie/utils/sandbox/local.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py index dd1d3c8c1..4a0a4879a 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py @@ -196,10 +196,6 @@ def launch(self, comp): return self.getReference(comp) def setup(self, comp): - # Services don't get initialized or configured - if not hasattr(comp, 'initialize'): - return - # Initialize the component unless asked not to. if self._initialize: # Set initial property values for 'property' kind properties @@ -286,6 +282,10 @@ def _getType(self): class LocalServiceFactory(LocalFactory): + def setup(self, service): + # Services don't get initialized or configured + return + def getReference(self, service): return DeviceManagerStub.instance().getService(service._instanceName) From 4872229da58f52eac986626a1d18134b6646abfe Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 13 Jan 2016 15:43:57 -0500 Subject: [PATCH 0048/1644] Simplify sandbox component exit notification using a callback and only starting thread if a callback is registered --- .../python/ossie/utils/sandbox/launcher.py | 30 +++++++++---------- .../python/ossie/utils/sandbox/local.py | 9 ++++++ 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/launcher.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/launcher.py index aa5ebc647..62e76d46e 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/launcher.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/launcher.py @@ -50,26 +50,24 @@ def __init__(self, command, arguments, environment=None, stdout=None): cwd=os.getcwd(), env=environment, stdout=stdout, stderr=subprocess.STDOUT, preexec_fn=os.setpgrp) - self.__tracker = threading.Thread(target=self.monitorChild) - self.__tracker.daemon = True - self.__tracker.start() + self.__callback = None + def setTerminationCallback(self, callback): + if not self.__callback: + # Nothing is currently waiting for notification, start monitor. + tracker = threading.Thread(target=self.monitorChild) + tracker.daemon = True + tracker.start() + self.__callback = callback + def monitorChild(self): - pid = self.__process.pid try: - self.__process.communicate()[0] - if self.__terminateRequested or self.__process.returncode == 0: - return - for idx in range(len(self.__arguments)): - if self.__arguments[idx] == 'NAME_BINDING': - if len(self.__arguments)>=idx+1: - print 'Component '+self.__arguments[idx+1]+' (pid='+str(pid)+') has died' - else: - print 'Component with process id '+str(pid)+'has died' + status = self.__process.wait() except: - if self.__terminateRequested or self.__process.returncode == 0: - return - print 'Component with process id '+str(pid)+'has died' + # If wait fails, don't bother with notification. + return + if self.__callback: + self.__callback(self.pid(), status) def terminate(self): for sig, timeout in self.STOP_SIGNALS: diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py index 4a0a4879a..1ee59b3cb 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py @@ -159,6 +159,15 @@ def launch(self, comp): process = launcher.launchSoftpkg(comp._profile, comp._sandbox, comp._spd, comp._impl, execparams, debugger, window) + # Set up a callback to notify when the component exits abnormally. + name = comp._instanceName + def terminate_callback(pid, status): + if status > 0: + print 'Component %s (pid=%d) exited with status %d' % (name, pid, status) + elif status < 0: + print 'Component %s (pid=%d) terminated with signal %d' % (name, pid, -status) + process.setTerminationCallback(terminate_callback) + # Wait for the component to register with the virtual naming service or # DeviceManager. if self._timeout is None: From db71b336ef56bc7a7ab004fb30221a3ff63227d6 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 13 Jan 2016 16:11:02 -0500 Subject: [PATCH 0049/1644] Use qualified name to restore gdb in sandbox --- redhawk/src/base/framework/python/ossie/utils/sandbox/local.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py index 1ee59b3cb..825b7cc56 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py @@ -192,7 +192,7 @@ def terminate_callback(pid, status): # Attach a debugger to the process. if debugger and debugger.canAttach(): if not window: - window = XTerm('%s (%s)' % (debugger.name(), comp._instanceName)) + window = terminal.XTerm('%s (%s)' % (debugger.name(), comp._instanceName)) debug_command, debug_args = debugger.attach(process) debug_command, debug_args = window.command(debug_command, debug_args) debug_process = launcher.LocalProcess(debug_command, debug_args) From c93c086d654a38bcf638fdabcccfa61cb696946b Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 13 Jan 2016 16:27:47 -0500 Subject: [PATCH 0050/1644] Use the '-p' option to GDB for a shorter command line --- .../src/base/framework/python/ossie/utils/sandbox/debugger.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/debugger.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/debugger.py index e129ee1e8..23bf308ec 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/debugger.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/debugger.py @@ -50,7 +50,7 @@ def canAttach(self): return self._attach def attach(self, process): - return self.command, [process.command(), str(process.pid())] + return self.command, ['-p', str(process.pid())] def wrap(self, command, arguments): return self.command, ['--args', command] + arguments From 323fab8315049ab39ac835aef6c13905a4726730 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 13 Jan 2016 16:28:14 -0500 Subject: [PATCH 0051/1644] Keep track of the process tracking thread again, and give it a helpful name --- .../framework/python/ossie/utils/sandbox/launcher.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/launcher.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/launcher.py index 62e76d46e..750f244cf 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/launcher.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/launcher.py @@ -50,14 +50,16 @@ def __init__(self, command, arguments, environment=None, stdout=None): cwd=os.getcwd(), env=environment, stdout=stdout, stderr=subprocess.STDOUT, preexec_fn=os.setpgrp) + self.__tracker = None self.__callback = None def setTerminationCallback(self, callback): - if not self.__callback: + if not self.__tracker: # Nothing is currently waiting for notification, start monitor. - tracker = threading.Thread(target=self.monitorChild) - tracker.daemon = True - tracker.start() + name = 'process-%d-tracker' % self.pid() + self.__tracker = threading.Thread(name=name, target=self.monitorChild) + self.__tracker.daemon = True + self.__tracker.start() self.__callback = callback def monitorChild(self): From 9cfcafc1fcf2a80a6c025f6a38e181adc47519ae Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 13 Jan 2016 16:36:36 -0500 Subject: [PATCH 0052/1644] Get rid of DebuggerProcess and just allow tacking children onto an existing LocalProcess; rename monitor function accordingly to avoid confusion --- .../python/ossie/utils/sandbox/launcher.py | 23 ++++++++----------- .../python/ossie/utils/sandbox/local.py | 2 +- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/launcher.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/launcher.py index 750f244cf..d3249dbd3 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/launcher.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/launcher.py @@ -52,17 +52,18 @@ def __init__(self, command, arguments, environment=None, stdout=None): preexec_fn=os.setpgrp) self.__tracker = None self.__callback = None + self.__children = [] def setTerminationCallback(self, callback): if not self.__tracker: # Nothing is currently waiting for notification, start monitor. name = 'process-%d-tracker' % self.pid() - self.__tracker = threading.Thread(name=name, target=self.monitorChild) + self.__tracker = threading.Thread(name=name, target=self._monitorProcess) self.__tracker.daemon = True self.__tracker.start() self.__callback = callback - def monitorChild(self): + def _monitorProcess(self): try: status = self.__process.wait() except: @@ -72,6 +73,10 @@ def monitorChild(self): self.__callback(self.pid(), status) def terminate(self): + for child in self.__children: + child.terminate() + self.__children = [] + for sig, timeout in self.STOP_SIGNALS: try: log.debug('Killing process group %s with signal %s', self.__process.pid, sig) @@ -103,18 +108,8 @@ def pid(self): def isAlive(self): return self.__process and self.__process.poll() is None - -class DebuggerProcess(object): - def __init__(self, debugger, child): - self.__debugger = debugger - self.__child = child - - def terminate(self): - self.__debugger.terminate() - self.__child.terminate() - - def isAlive(self): - return self.__child.isAlive() + def addChild(self, process): + self.__children.append(process) class LocalLauncher(object): diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py index 825b7cc56..7ea0732bd 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py @@ -196,7 +196,7 @@ def terminate_callback(pid, status): debug_command, debug_args = debugger.attach(process) debug_command, debug_args = window.command(debug_command, debug_args) debug_process = launcher.LocalProcess(debug_command, debug_args) - process = launcher.DebuggerProcess(debug_process, process) + process.addChild(debug_process) # Store the process on the component proxy. comp._process = process From c3c2b3a941d507fe5fbbb207dd137d73e4b0e2a3 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 13 Jan 2016 17:30:22 -0500 Subject: [PATCH 0053/1644] Move common sandbox model behavior into mix-in class --- .../python/ossie/utils/sandbox/model.py | 45 ++++++++++++------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/model.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/model.py index 8a827197c..b05f2369d 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/model.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/model.py @@ -27,10 +27,30 @@ from ossie.utils.sandbox.events import EventChannel -class SandboxResource(ComponentBase): - def __init__(self, sandbox, profile, spd, scd, prf, instanceName, refid, impl): - super(SandboxResource,self).__init__(spd, scd, prf, instanceName, refid, impl) +class SandboxMixin(object): + def __init__(self, sandbox): self._sandbox = sandbox + + def _kick(self): + self.ref = self._factory.launch(self) + self._factory.setup(self) + self._register() + + def _terminate(self): + if self._factory: + self._factory.terminate(self) + + def _register(self): + raise NotImplemented('_register') + + def _getExecparams(self): + raise NotImplemented('_getExecparams') + + +class SandboxResource(ComponentBase, SandboxMixin): + def __init__(self, sandbox, profile, spd, scd, prf, instanceName, refid, impl): + ComponentBase.__init__(self, spd, scd, prf, instanceName, refid, impl) + SandboxMixin.__init__(self, sandbox) self._profile = profile self._componentName = spd.get_name() self._propRef = {} @@ -59,9 +79,7 @@ def _readProfile(self): sdrRoot = self._sandbox.getSdrRoot() self._spd, self._scd, self._prf = sdrRoot.readProfile(self._profile) - def _kick(self): - self.ref = self._factory.launch(self) - self._factory.setup(self) + def _register(self): self._sandbox._registerComponent(self) @property @@ -99,8 +117,7 @@ def releaseObject(self): super(SandboxResource,self).releaseObject() # Allow the launch factory to peform any follow-up cleanup. - if self._factory: - self._factory.terminate(self) + SandboxMixin._terminate(self) def api(self): ''' @@ -136,21 +153,15 @@ def api(self): Device.api(self) -class SandboxService(Service): +class SandboxService(Service, SandboxMixin): def __init__(self, sandbox, profile, spd, scd, prf, instanceName, refid, impl): - self._sandbox = sandbox Service.__init__(self, None, profile, spd, scd, prf, instanceName, refid, impl) + SandboxMixin.__init__(self, sandbox) - def _kick(self): - self.ref = self._factory.launch(self) - self._factory.setup(self) + def _register(self): self.populateMemberFunctions() self._sandbox._addService(self) - def _terminate(self): - if self._factory: - self._factory.terminate(self) - def _getExecparams(self): if not self._prf: return {} From d7ca422142f9a336c20b02ffcf335451f177177c Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 13 Jan 2016 17:42:23 -0500 Subject: [PATCH 0054/1644] Add methods to get the properties for initializeProperties() and the initial configure() call, instead of keeping a dictionary around --- .../python/ossie/utils/sandbox/local.py | 7 ++--- .../python/ossie/utils/sandbox/model.py | 30 +++++++++++-------- .../python/ossie/utils/sb/domainless.py | 2 +- 3 files changed, 22 insertions(+), 17 deletions(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py index 7ea0732bd..a442c442b 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py @@ -208,7 +208,7 @@ def setup(self, comp): # Initialize the component unless asked not to. if self._initialize: # Set initial property values for 'property' kind properties - initvals = copy.deepcopy(comp._propRef) + initvals = comp._getInitializeProperties() initvals.update(self._initProps) try: comp.initializeProperties(initvals) @@ -221,9 +221,8 @@ def setup(self, comp): # Configure component with default values unless requested not to (e.g., # when launched from a SAD file). if self._configProps is not None: - # Make a copy of the default properties, and update with any passed-in - # properties that were not already passed to initializeProperties() - initvals = copy.deepcopy(comp._configRef) + # Set initial configuration properties (pre-2.0 components) + initvals = comp._getInitialConfigureProperties() initvals.update(self._configProps) try: comp.configure(initvals) diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/model.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/model.py index b05f2369d..7b425f680 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/model.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/model.py @@ -53,26 +53,32 @@ def __init__(self, sandbox, profile, spd, scd, prf, instanceName, refid, impl): SandboxMixin.__init__(self, sandbox) self._profile = profile self._componentName = spd.get_name() - self._propRef = {} - self._configRef = {} - for prop in self._getPropertySet(kinds=('configure',), modes=('readwrite', 'writeonly'), includeNil=False): - if prop.defValue is None: - continue - self._configRef[str(prop.id)] = prop.defValue - for prop in self._getPropertySet(kinds=('property',), includeNil=False, commandline=False): - if prop.defValue is None: - continue - self._propRef[str(prop.id)] = prop.defValue self.__ports = None self._parseComponentXMLFiles() self._buildAPI() - + + def _getInitializeProperties(self): + properties = {} + for prop in self._getPropertySet(kinds=('property',), includeNil=False, commandline=False): + if prop.defValue is None: + continue + properties[prop.id] = prop.defValue + return properties + + def _getInitialConfigureProperties(self): + properties = {} + for prop in self._getPropertySet(kinds=('configure',), modes=('readwrite', 'writeonly'), includeNil=False): + if prop.defValue is None: + continue + properties[prop.id] = prop.defValue + return properties + def _getExecparams(self): execparams = dict((str(ep.id), ep.defValue) for ep in self._getPropertySet(kinds=('execparam',), includeNil=False)) for prop in self._getPropertySet(kinds=('property',), includeNil=False, commandline=True): - execparams[str(prop.id)] = prop.defValue + execparams[prop.id] = prop.defValue return execparams def _readProfile(self): diff --git a/redhawk/src/base/framework/python/ossie/utils/sb/domainless.py b/redhawk/src/base/framework/python/ossie/utils/sb/domainless.py index 689d7d8dd..4cefbc7ee 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sb/domainless.py +++ b/redhawk/src/base/framework/python/ossie/utils/sb/domainless.py @@ -813,7 +813,7 @@ def loadSADFile(filename, props={}): if len(launchedComponents) > 0: for comp in launchedComponents: if instanceID == comp._refid: - componentProps = comp._configRef + componentProps = comp._getInitialConfigureProperties() if instanceID == assemblyControllerRefid: assemblyController = True sandboxComponent = comp From 82fa1afaf86989b01fa8afb338ed8aaf963f7a62 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 14 Jan 2016 09:44:19 -0500 Subject: [PATCH 0055/1644] Rename sandbox factory classes and members to "launcher" for clarity --- .../python/ossie/utils/sandbox/base.py | 8 ++++---- .../python/ossie/utils/sandbox/ide.py | 8 ++++---- .../python/ossie/utils/sandbox/local.py | 20 +++++++++---------- .../python/ossie/utils/sandbox/model.py | 10 +++++----- 4 files changed, 23 insertions(+), 23 deletions(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/base.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/base.py index 0427b3a0f..dfba1596c 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/base.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/base.py @@ -254,10 +254,10 @@ def launch(self, descriptor, instanceName=None, refid=None, impl=None, # Determine the class for the component type and create a new instance. comp = clazz(self, profile, spd, scd, prf, instanceName, refid, impl) - factory = self._createFactory(comptype, execparams, initProps, initialize, configure, debugger, window, timeout) - if not factory: + launcher = self._createLauncher(comptype, execparams, initProps, initialize, configure, debugger, window, timeout) + if not launcher: raise NotImplementedError("No support for component type '%s'" % comptype) - comp._factory = factory + comp._launcher = launcher # Launch the component comp._kick() @@ -355,7 +355,7 @@ def _getInitializationStages(self, prf): yield prop, self._getInitializationStage(prop, prop.get_configurationkind()) -class SandboxFactory(object): +class SandboxLauncher(object): def launch(self, comp): raise NotImplementedError('launch') diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/ide.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/ide.py index d5bfc711f..1d562f2a8 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/ide.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/ide.py @@ -34,7 +34,7 @@ from ossie.utils.model import CorbaObject -from base import SdrRoot, Sandbox, SandboxFactory +from base import SdrRoot, Sandbox, SandboxLauncher from model import SandboxComponent, SandboxDevice log = logging.getLogger(__name__) @@ -81,7 +81,7 @@ def getLocation(self): return 'REDHAWK IDE virtual SDR' -class IDEFactory(SandboxFactory): +class IDELauncher(SandboxLauncher): def __init__(self, execparams): self._execparams = execparams @@ -139,9 +139,9 @@ def _checkInstanceId(self, refid, componentType='resource'): # "valid" return True - def _createFactory(self, comptype, execparams, initProps, initialize, configProps, debugger, window, timeout): + def _createLauncher(self, comptype, execparams, initProps, initialize, configProps, debugger, window, timeout): if comptype in ('resource', 'device', 'loadabledevice', 'executabledevice'): - return IDEFactory(execparams) + return IDELauncher(execparams) return None def _createResource(self, profile, name, execparams={}, impl=None): diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py index a442c442b..b16631f9e 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py @@ -30,7 +30,7 @@ from ossie import parsers from ossie.utils.model.connect import ConnectionManager -from base import SdrRoot, Sandbox, SandboxFactory +from base import SdrRoot, Sandbox, SandboxLauncher from devmgr import DeviceManagerStub from naming import NamingContextStub import launcher @@ -103,7 +103,7 @@ def findProfile(self, descriptor, objType=None): return super(LocalSdrRoot,self).findProfile(descriptor, objType=objType) -class LocalFactory(SandboxFactory): +class LocalLauncher(SandboxLauncher): def __init__(self, execparams, initProps, initialize, configProps, debugger, window, timeout): self._execparams = execparams self._debugger = debugger @@ -243,13 +243,13 @@ def terminate(self, comp): comp._process = None -class LocalComponentFactory(LocalFactory): +class LocalComponentLauncher(LocalLauncher): def launch(self, *args, **kwargs): self.__namingContext = NamingContextStub() log.trace('Activating virtual NamingContext') namingContextId = poa.activate_object(self.__namingContext) try: - return LocalFactory.launch(self, *args, **kwargs) + return LocalLauncher.launch(self, *args, **kwargs) finally: log.trace('Deactivating virtual NamingContext') poa.deactivate_object(namingContextId) @@ -268,7 +268,7 @@ def _getType(self): return 'resource' -class LocalDeviceFactory(LocalFactory): +class LocalDeviceLauncher(LocalLauncher): def getReference(self, device): return DeviceManagerStub.instance().getDevice(device._refid) @@ -289,7 +289,7 @@ def _getType(self): return 'device' -class LocalServiceFactory(LocalFactory): +class LocalServiceLauncher(LocalLauncher): def setup(self, service): # Services don't get initialized or configured return @@ -344,13 +344,13 @@ def _checkInstanceId(self, refid, componentType): return False return True - def _createFactory(self, comptype, execparams, initProps, initialize, configProps, debugger, window, timeout): + def _createLauncher(self, comptype, execparams, initProps, initialize, configProps, debugger, window, timeout): if comptype == 'resource': - clazz = LocalComponentFactory + clazz = LocalComponentLauncher elif comptype in ('device', 'loadabledevice', 'executabledevice'): - clazz = LocalDeviceFactory + clazz = LocalDeviceLauncher elif comptype == 'service': - clazz = LocalServiceFactory + clazz = LocalServiceLauncher else: return None return clazz(execparams, initProps, initialize, configProps, debugger, window, timeout) diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/model.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/model.py index 7b425f680..e78b3e9f2 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/model.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/model.py @@ -32,13 +32,13 @@ def __init__(self, sandbox): self._sandbox = sandbox def _kick(self): - self.ref = self._factory.launch(self) - self._factory.setup(self) + self.ref = self._launcher.launch(self) + self._launcher.setup(self) self._register() def _terminate(self): - if self._factory: - self._factory.terminate(self) + if self._launcher: + self._launcher.terminate(self) def _register(self): raise NotImplemented('_register') @@ -122,7 +122,7 @@ def releaseObject(self): # Call superclass release, which calls the CORBA method. super(SandboxResource,self).releaseObject() - # Allow the launch factory to peform any follow-up cleanup. + # Allow the launcher to peform any follow-up cleanup. SandboxMixin._terminate(self) def api(self): From 2188d043721714572e34668c80efee98e9e18454 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 14 Jan 2016 10:23:52 -0500 Subject: [PATCH 0056/1644] Refactor connection breaking into a method on the sandbox --- .../framework/python/ossie/utils/model/connect.py | 12 ++++++++++-- .../framework/python/ossie/utils/sandbox/base.py | 9 +++++++++ .../framework/python/ossie/utils/sandbox/model.py | 13 ++----------- 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/model/connect.py b/redhawk/src/base/framework/python/ossie/utils/model/connect.py index 90b4fdb45..8b62082b0 100644 --- a/redhawk/src/base/framework/python/ossie/utils/model/connect.py +++ b/redhawk/src/base/framework/python/ossie/utils/model/connect.py @@ -41,7 +41,11 @@ def getInterface(self): return self.port['Port Interface'] def hasComponent(self, component): - return self.supplier._refid == component._refid + try: + return self.supplier._refid == component._refid + except AttributeError: + # Other object is not a port supplier + return False def getRefid(self): return self.supplier._refid @@ -67,7 +71,11 @@ def getInterface(self): return 'IDL:CF/Resource:1.0' def hasComponent(self, component): - return self.component._refid == component._refid + try: + return self.component._refid == component._refid + except AttributeError: + # Other object is not a component + return False def getRefid(self): return self.component._refid diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/base.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/base.py index dfba1596c..7eee49480 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/base.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/base.py @@ -23,6 +23,7 @@ from ossie import parsers from ossie.utils.log4py import logging from ossie.utils import weakobj +from ossie.utils.model.connect import ConnectionManager from ossie.utils.uuid import uuid4 from model import SandboxComponent, SandboxDevice, SandboxService, SandboxEventChannel @@ -354,6 +355,14 @@ def _getInitializationStages(self, prf): for prop in prf.get_structsequence(): yield prop, self._getInitializationStage(prop, prop.get_configurationkind()) + def _breakConnections(self, target): + # Break any connections involving this object. + manager = ConnectionManager.instance() + for identifier, (uses, provides) in manager.getConnections().items(): + if uses.hasComponent(target) or provides.hasComponent(target): + manager.breakConnection(identifier) + manager.unregisterConnection(identifier) + class SandboxLauncher(object): def launch(self, comp): diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/model.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/model.py index e78b3e9f2..5b9d5d750 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/model.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/model.py @@ -23,7 +23,6 @@ from ossie.utils.model import CorbaObject from ossie.utils.model import PortSupplier, PropertySet, ComponentBase from ossie.utils.model import Resource, Device, Service -from ossie.utils.model.connect import ConnectionManager from ossie.utils.sandbox.events import EventChannel @@ -112,11 +111,7 @@ def reset(self): def releaseObject(self): # Break any connections involving this component. - manager = ConnectionManager.instance() - for identifier, (uses, provides) in manager.getConnections().items(): - if uses.hasComponent(self) or provides.hasComponent(self): - manager.breakConnection(identifier) - manager.unregisterConnection(identifier) + self._sandbox._breakConnections(self) self._sandbox._unregisterComponent(self) # Call superclass release, which calls the CORBA method. @@ -199,10 +194,6 @@ def __init__(self, name, sandbox): def destroy(self): # Break any connections involving this event channel. - manager = ConnectionManager.instance() - for identifier, (uses, provides) in manager.getConnections().items(): - if provides.hasComponent(self): - manager.breakConnection(identifier) - manager.unregisterConnection(identifier) + self._sandbox._breakConnections(self) self._sandbox._removeEventChannel(self._instanceName) EventChannel.destroy(self) From a43e586da53a1681d6dbbd7093aca81200ce9eaf Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 14 Jan 2016 13:17:45 -0500 Subject: [PATCH 0057/1644] CF-1294 Add a 'properties' argument to sb.launch() that handles all property overrides. The existing 'execparams' argument has been deprecated, and the usage of 'configure' to provide overrides has also been deprecated; however, 'configure' can be used with a boolean value to disable the initial call to configure(). The legacy usage of None to disable configure() is still supported (None evaluates to false). --- .../python/ossie/utils/sandbox/base.py | 65 ++++++++----------- .../python/ossie/utils/sb/domainless.py | 52 +++++++++++---- redhawk/src/testing/tests/test_13_TestSB.py | 17 +++-- 3 files changed, 79 insertions(+), 55 deletions(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/base.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/base.py index 7eee49480..f4c70b0fb 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/base.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/base.py @@ -214,7 +214,7 @@ def reset(self): component.reset() def launch(self, descriptor, instanceName=None, refid=None, impl=None, - debugger=None, window=None, execparams={}, configure={}, + debugger=None, window=None, properties={}, configure=True, initialize=True, timeout=None, objType=None): sdrRoot = self.getSdrRoot() @@ -251,11 +251,13 @@ def launch(self, descriptor, instanceName=None, refid=None, impl=None, raise ValueError, "User-specified identifier '%s' already in use" % (refid,) # If possible, determine the correct placement of properties - execparams, initProps, configure = self._sortOverrides(prf, execparams, configure) + execparams, initProps, configProps = self._sortOverrides(prf, properties) + if not configure: + configProps = None # Determine the class for the component type and create a new instance. comp = clazz(self, profile, spd, scd, prf, instanceName, refid, impl) - launcher = self._createLauncher(comptype, execparams, initProps, initialize, configure, debugger, window, timeout) + launcher = self._createLauncher(comptype, execparams, initProps, initialize, configProps, debugger, window, timeout) if not launcher: raise NotImplementedError("No support for component type '%s'" % comptype) comp._launcher = launcher @@ -271,16 +273,10 @@ def shutdown(self): channel.destroy() self._eventChannels = {} - def catalog(self, searchPath=None, objType="components"): - files = {} - for profile in self.getSdrRoot().readProfiles(objType, searchPath): - files[profile['name']] = profile['profile'] - return files - - def _sortOverrides(self, prf, execparams, configure): + def _sortOverrides(self, prf, properties): if not prf: - # No PRF file, assume the properties are correct as-is - return execparams, {}, configure + # No PRF file, assume all properties are execparams. + return properties, {}, {} # Classify the PRF properties by which stage of initialization they get # set: 'commandline', 'initialize', 'configure' or None (not settable). @@ -293,34 +289,29 @@ def _sortOverrides(self, prf, execparams, configure): if not name in stages: stages[name] = stage - # Check properties that do not belong in execparams - arguments = {} - for key, value in execparams.iteritems(): - if key in stages and stages[key] != 'commandline': - raise ValueError("Non-command line property '%s' given in execparams" % key) - arguments[key] = value + # Add in system-defined execparams that users are allowed to override + stages['DEBUG_LEVEL'] = 'commandline' + stages['LOGGING_CONFIG_URI'] = 'commandline' - # Sort configure properties into the appropriate stage of initialization + # Sort properties into the appropriate stage of initialization + execparams = {} initProps = {} - if configure is not None: - configProps = {} - for key, value in configure.iteritems(): - if not key in stages: - log.warning("Unknown property '%s'" , key) - continue - stage = stages[key] - if stage == 'commandline': - arguments[key] = value - elif stage == 'initialize': - initProps[key] = value - elif stage == 'configure': - configProps[key] = value - else: - log.warning("Property '%s' cannot be set at launch", key) - else: - configProps = None + configProps = {} + for key, value in properties.iteritems(): + if not key in stages: + log.warning("Unknown property '%s'" , key) + continue + stage = stages[key] + if stage == 'commandline': + execparams[key] = value + elif stage == 'initialize': + initProps[key] = value + elif stage == 'configure': + configProps[key] = value + else: + log.warning("Property '%s' cannot be set at launch", key) - return arguments, initProps, configProps + return execparams, initProps, configProps def _getInitializationStage(self, prop, kinds, commandline=False): # Helper method to classify the initialization stage for a particular diff --git a/redhawk/src/base/framework/python/ossie/utils/sb/domainless.py b/redhawk/src/base/framework/python/ossie/utils/sb/domainless.py index 4cefbc7ee..8d9cffea5 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sb/domainless.py +++ b/redhawk/src/base/framework/python/ossie/utils/sb/domainless.py @@ -722,7 +722,8 @@ def loadSADFile(filename, props={}): simple_exec_vals[container.id] = container.value try: # NB: Explicitly request no configure call is made on the component - newComponent = launch(componentName, instanceName,instanceID,configure=None,execparams=simple_exec_vals, objType="components") + newComponent = launch(componentName, instanceName, instanceID, configure=False, + properties=simple_exec_vals, objType="component") launchedComponents.append(newComponent) except Exception as e: msg = "Failed to launch component '%s', REASON: %s" % (instanceName, str(e)) @@ -1135,8 +1136,8 @@ def release(): _getSandbox().shutdown() def launch(descriptor, instanceName=None, refid=None, impl=None, - debugger=None, window=None, execparams={}, configure={}, - initialize=True, timeout=None, objType=None): + debugger=None, window=None, execparams={}, configure=True, + initialize=True, timeout=None, objType=None, properties={}): """ Execute a softpkg, returning a proxy object. This is a factory function that may return a component, device or service depending on the SPD. @@ -1160,22 +1161,49 @@ def launch(descriptor, instanceName=None, refid=None, impl=None, window - Terminal to receive command input/output. If not given, output will be directed to stdout, and component will not receive input. - execparams - Execparams to override on component execution. - configure - If a dictionary, a set of key/value pairs to override the - initial configuration values of the component. - If None, defer configuration of the component to the - caller (generally used by loadSADFile). + properties - Dictionary of key/value pairs to override the initial + property values of the component. + configure - If true, call configure() with the default values for + properties of kind 'configure' after launching the + component. + If false, defer configuration to the caller (generally + used by loadSADFile). + DEPRECATED: If a dictionary, a set of key/value pairs + to override the initial configuration values of the + component. All property kinds should be included in the + 'properties' argument. initialize - If true, call initialize() after launching the component. - If false, defer initialization to ther caller. + If false, defer initialization to the caller. timeout - Time, in seconds, to wait for launch to complete. If not given, the default is 10 seconds, except when running with a debugger, in which case the default is 60 seconds. objType - The type that you would like to launch. Options are component, device, or service. If not given, all types will be searched for with the descriptor given. - """ - return _getSandbox().launch(descriptor, instanceName, refid, impl, debugger, - window, execparams, configure, initialize, timeout, objType) + + Deprecated arguments: + execparams - Execparams to override on component execution. All property + kinds should included in the 'properties' argument. + """ + # Check for deprecation conditions + if isinstance(configure, dict) or execparams: + if properties: + raise ValueError("'properties' argument cannot be mixed with 'configure' overrides or 'execparams'") + # Combine the overrides from configure and execparams into a single + # properties dictionary, with the latter having precedence + properties = {} + if isinstance(configure, dict): + warnings.warn("'configure' argument is deprecated for property overrides; use 'properties'.", DeprecationWarning) + properties.update(configure) + configure = True + if execparams: + warnings.warn("'execparams' argument is deprecated; use 'properties'.", DeprecationWarning) + properties.update(execparams) + + return _getSandbox().launch(descriptor=descriptor, instanceName=instanceName, refid=refid, + impl=impl, debugger=debugger, window=window, properties=properties, + initialize=initialize, configure=configure, timeout=timeout, + objType=objType) def createEventChannel(name, exclusive=False): """ diff --git a/redhawk/src/testing/tests/test_13_TestSB.py b/redhawk/src/testing/tests/test_13_TestSB.py index cb21ce83e..6e4eade71 100644 --- a/redhawk/src/testing/tests/test_13_TestSB.py +++ b/redhawk/src/testing/tests/test_13_TestSB.py @@ -218,7 +218,16 @@ def test_propertyInitialization(self): self.assertFalse('cmdline' in comp.initialize_props) comp.releaseObject() - # Test with (correct) overrides + # Test with overrides + comp = sb.launch('sdr/dom/components/property_init/property_init.spd.xml', + properties={'cmdline':'override', 'initial':'override'}) + self.assertFalse('initial' in comp.cmdline_args) + self.assertFalse('cmdline' in comp.initialize_props) + self.assertEquals('override', comp.cmdline) + self.assertEquals('override', comp.initial) + comp.releaseObject() + + # Test with overrides in deprecated 'execparams' and 'configure' arguments comp = sb.launch('sdr/dom/components/property_init/property_init.spd.xml', execparams={'cmdline':'override'}, configure={'initial':'override'}) self.assertFalse('initial' in comp.cmdline_args) @@ -227,7 +236,7 @@ def test_propertyInitialization(self): self.assertEquals('override', comp.initial) comp.releaseObject() - # Test with misplaced command line property + # Test with misplaced command line property in deprecated 'configure' argument comp = sb.launch('sdr/dom/components/property_init/property_init.spd.xml', configure={'cmdline':'override'}) self.assertFalse('initial' in comp.cmdline_args) @@ -235,10 +244,6 @@ def test_propertyInitialization(self): self.assertEquals('override', comp.cmdline) comp.releaseObject() - # A non-command line property in the wrong override should throw an exception - self.assertRaises(ValueError, sb.launch, 'sdr/dom/components/property_init/property_init.spd.xml', - execparams={'initial':'override'}) - def test_nestedSoftPkgDeps(self): cwd = os.getcwd() depLibraryPath = cwd + "/sdr/dom/components/softpkgNestedDep/spdNestedDepLibrary" From ab87a1dd94390f082d18f9cb45c24671d736e304 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 14 Jan 2016 13:37:41 -0500 Subject: [PATCH 0058/1644] Streamline implementation of local sandbox getProfiles() --- .../python/ossie/utils/sandbox/local.py | 29 ++++++++++--------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py index b16631f9e..fd4ef8740 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py @@ -62,21 +62,22 @@ def _readFile(self, filename): path = open(self._sdrPath(filename), 'r') return path.read() - def _getSearchPaths(self, objTypes): - paths = [] - if 'components' in objTypes: - paths.append('dom/components') - if 'devices' in objTypes: - paths.append('dev/devices') - if 'services' in objTypes: - paths.append('dev/services') - return [self._sdrPath(p) for p in paths] - - def _getAvailableProfiles(self, path): + def getProfiles(self, objType=None): files = [] - for root, dirs, fnames in os.walk(path): - for filename in fnmatch.filter(fnames, '*.spd.xml'): - files.append(os.path.join(root, filename)) + searchPath = [] + if objType == "component" or objType is None: + searchPath.append('dom/components') + if objType == "device" or objType is None: + searchPath.append('dev/devices') + if objType == "service" or objType is None: + searchPath.append('dev/services') + if not searchPath: + raise ValueError, "'%s' is not a valid object Type" % objType + for path in searchPath: + path = self._sdrPath(path) + for root, dirs, fnames in os.walk(path): + for filename in fnmatch.filter(fnames, '*.spd.xml'): + files.append(os.path.join(root, filename)) return files def _getObjectTypes(self, objType): From dc45ce0c1b71386e62c05adf181951a2e55f6420 Mon Sep 17 00:00:00 2001 From: Ryan Bauman Date: Fri, 18 Mar 2016 14:07:57 -0400 Subject: [PATCH 0059/1644] CF-1443 RELENG-401 - adjust release field for 2.0.1-rc1 --- redhawk/src/releng/redhawk.spec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/redhawk/src/releng/redhawk.spec b/redhawk/src/releng/redhawk.spec index afd56f690..69c3a362e 100644 --- a/redhawk/src/releng/redhawk.spec +++ b/redhawk/src/releng/redhawk.spec @@ -26,8 +26,8 @@ Prefix: %{_sdrroot} Prefix: %{_sysconfdir} Name: redhawk -Version: 2.0.4 -Release: 1%{?dist} +Version: 2.0.1 +Release: 2%{?dist} Summary: REDHAWK is a Software Defined Radio framework Group: Applications/Engineering From 47d192670b80af71a24329976c55e085398c9706 Mon Sep 17 00:00:00 2001 From: 8530 <8530@vm-131.vsi-corp.com> Date: Thu, 24 Mar 2016 13:02:03 -0400 Subject: [PATCH 0060/1644] wip --- .../logging/RH_SyncRollingAppender.cpp | 392 ++++++++++++++++++ .../logging/RH_SyncRollingAppender.h | 115 +++++ .../testing/loggers/syncappender/Makefile.am | 55 +++ .../loggers/syncappender/appender_test.cpp | 49 +++ .../testing/loggers/syncappender/cleanmem.cpp | 20 + .../testing/loggers/syncappender/configure.ac | 26 ++ .../loggers/syncappender/log4j.appender | 35 ++ .../testing/loggers/syncappender/log4j.stdout | 9 + .../loggers/syncappender/logtestdebug.h | 28 ++ .../testing/loggers/syncappender/proc_log.cpp | 52 +++ .../src/testing/loggers/syncappender/reconf | 2 + .../src/testing/loggers/syncappender/runtests | 13 + .../loggers/syncappender/test_suites.cpp | 153 +++++++ .../loggers/syncappender/test_suites.h | 41 ++ 14 files changed, 990 insertions(+) create mode 100644 redhawk/src/base/framework/logging/RH_SyncRollingAppender.cpp create mode 100644 redhawk/src/base/framework/logging/RH_SyncRollingAppender.h create mode 100644 redhawk/src/testing/loggers/syncappender/Makefile.am create mode 100644 redhawk/src/testing/loggers/syncappender/appender_test.cpp create mode 100644 redhawk/src/testing/loggers/syncappender/cleanmem.cpp create mode 100644 redhawk/src/testing/loggers/syncappender/configure.ac create mode 100644 redhawk/src/testing/loggers/syncappender/log4j.appender create mode 100644 redhawk/src/testing/loggers/syncappender/log4j.stdout create mode 100644 redhawk/src/testing/loggers/syncappender/logtestdebug.h create mode 100644 redhawk/src/testing/loggers/syncappender/proc_log.cpp create mode 100755 redhawk/src/testing/loggers/syncappender/reconf create mode 100755 redhawk/src/testing/loggers/syncappender/runtests create mode 100644 redhawk/src/testing/loggers/syncappender/test_suites.cpp create mode 100644 redhawk/src/testing/loggers/syncappender/test_suites.h diff --git a/redhawk/src/base/framework/logging/RH_SyncRollingAppender.cpp b/redhawk/src/base/framework/logging/RH_SyncRollingAppender.cpp new file mode 100644 index 000000000..0f2572d7e --- /dev/null +++ b/redhawk/src/base/framework/logging/RH_SyncRollingAppender.cpp @@ -0,0 +1,392 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK core. + * + * REDHAWK core is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ +#ifdef HAVE_LOG4CXX +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if !defined(LOG4CXX) +#define LOG4CXX 1 +#endif +#include + +#include +#include +#include + +#include "RH_SyncRollingAppender.h" + +typedef ipc::scoped_lock< _IPC_Mutex > _IPC_ScopedMLock; +typedef ipc::scoped_lock< ipc::file_lock > _IPC_ScopedFLock; + +using namespace log4cxx; +using namespace log4cxx::helpers; + +#define _LL_DEBUG( msg ) \ + { std::ostringstream __os; __os << msg; LogLog::debug(__os.str()); __os.str(""); } + +#define _LL_WARN( msg ) \ + { std::ostringstream __os; __os << msg; LogLog::warn(__os.str()); __os.str(""); } + +#define _LL_ERROR( msg ) \ + { std::ostringstream __os; __os << msg; LogLog::error(__os.str()); __os.str(""); } + +#define _LLS_DEBUG( os, msg ) \ + os << msg; LogLog::debug(os.str()); os.str(""); + + +namespace log4cxx { + // + // Allows for same naming reference to LogEvent Appender class + // + class ClassRH_SyncRollingAppender : public Class + { + public: + ClassRH_SyncRollingAppender() : helpers::Class() {} + virtual LogString getName() const { + return LOG4CXX_STR("org.ossie.logging.RH_SyncRollingAppender"); + } + virtual ObjectPtr newInstance() const { + return new RH_SyncRollingAppender(); + } + }; + +}; + +// Register factory class with log4cxx for the appender +IMPLEMENT_LOG4CXX_OBJECT_WITH_CUSTOM_CLASS(RH_SyncRollingAppender, ClassRH_SyncRollingAppender) + +RH_SyncRollingAppender::RH_SyncRollingAppender(): +rolling::RollingFileAppenderSkeleton(), + wait_on_lock(50), + retries(0), + max_file_size(10*1024*1024), + max_bkup_index(1), + roll_count(0), + cleanup(false), + created(false), + sync_ctx(NULL) +{ + +} + + +RH_SyncRollingAppender::~RH_SyncRollingAppender() { + + int pid=getpid(); + _LL_DEBUG( "RH_SyncRollingAppender::DTOR START " << pid ); + + try { + _LL_DEBUG( "UNLOCK FILE LOCK " << pid ); + flock.unlock(); + } + catch(...){} + + if ( sync_ctx ) { + _LL_DEBUG( "RH_SyncRollingAppender::DTOR unlock shared memory <" << sync_ctx->fname << "> " << pid << "\n" ); + try { + sync_ctx->mutex.unlock(); + } + catch(...){} + + if ( cleanup ) { + _LL_DEBUG( "RH_SyncRollingAppender::DTPR clean up sharedg memory for: <" << sync_ctx->fname << "> " << pid << "\n" ); + // clean up shared memory opbject + ipc::shared_memory_object::remove(sync_ctx->fname); + } + else { + _LL_WARN( "RH_SyncRollingAppender: LEAVING SHARED MEMORY KEY <" << sync_ctx->fname << "> " << pid << "\n" ); + } + } + + _LL_DEBUG( "RH_SyncRollingAppender::DTOR END " << pid ); +} + +int RH_SyncRollingAppender::_get_mem( const std::string &fname) { + + int retval=0; + created = false; + + // use the file name as the key for the shared memory segment... + try { + ipc::shared_memory_object shm_obj + (ipc::create_only, //only create + fname.c_str(), //name + ipc::read_write //read-write mode + ); + + shm_obj.truncate(sizeof(sync_log_file)); + shm.swap(shm_obj); + _LL_DEBUG( "RH_SyncRollingAppender::get_mem Creating Named memory space <" << fname << ">" ); + created = true; + } + catch(...) { + } + + if ( !created ) { + _LL_DEBUG( "RH_SyncRollingAppender::get_mem Attach to Existing <" << fname << ">" ); + ipc::shared_memory_object shm_obj + (ipc::open_only, //only create + fname.c_str(), //name + ipc::read_write //read-write mode + ); + + shm.swap(shm_obj); + } + + //Map the whole shared memory in this process + ipc::mapped_region tregion(shm, ipc::read_write); + + void *addr = tregion.get_address(); + sync_ctx = new(addr) sync_log_file; + + if ( created ) { + _IPC_ScopedMLock lock(sync_ctx->mutex); + strcpy( sync_ctx->fname, fname.c_str() ); + sync_ctx->n_msgs = 0; + sync_ctx->max_size = 10*1024*1024; + sync_ctx->max_index = 10; + sync_ctx->roll_count = 0; + } + + _LL_DEBUG( "RH_SyncRollingAppender::get_mem key: <" << sync_ctx->fname << ">" ); + _LL_DEBUG( " n_msgs : " << sync_ctx->n_msgs ); + _LL_DEBUG( " max_size : " << sync_ctx->max_size ); + _LL_DEBUG( " max_index : " << sync_ctx->max_index ); + _LL_DEBUG( " roll_count : " << sync_ctx->roll_count ); + _LL_DEBUG( " fname : " << sync_ctx->fname << std::endl ); + + region.swap(tregion); + + return 0; +} + + +void RH_SyncRollingAppender::resync_rollover(log4cxx::helpers::Pool &p){ + + try { + _LL_DEBUG( "RH_SyncRollingAppender::resync_rollover... RESYNC START "); + synchronized sync(mutex); + setImmediateFlush(true); + closeWriter(); + helpers::OutputStreamPtr os(new helpers::FileOutputStream(getFile(), getAppend() )); + helpers::WriterPtr newWriter(createWriter(os)); + setFile(getFile()); + setWriter(newWriter); + if (getAppend()) { + fileLength = File().setPath(getFile()).length(p); + } else { + fileLength = 0; + } + _LL_DEBUG( "RH_SyncRollingAppender::resync_rollover... RESYNC COMPLETED "); + } catch (std::exception& ex) { + LogLog::warn(LOG4CXX_STR("Exception during resync-rollover")); + } +} + +void RH_SyncRollingAppender::subAppend(const spi::LoggingEventPtr& event, log4cxx::helpers::Pool& p){ + + int cretries = retries; + do { + _LL_DEBUG( "RH_SyncRollingAppender::subAppend Waiting to lock mutex."); + boost::posix_time::ptime::ptime abs_time = boost::posix_time::microsec_clock::universal_time()+boost::posix_time::millisec(wait_on_lock); + try { + _IPC_ScopedFLock lock(flock,abs_time); + + if ( lock ) { + + /// we are behind... need to reopen the base file... + if ( roll_count < sync_ctx->roll_count ) { + resync_rollover(p); + roll_count = sync_ctx->roll_count; + } + else { + + // get the current file status to test the trigger with + { + synchronized sync(mutex); + fileLength = File().setPath(getFile()).length(p); + } + + _LL_DEBUG( "RH_SyncRollingAppender::subAppend roll_count: " << roll_count << " length:" << fileLength); + // The rollover check must precede actual writing. This is the + // only correct behavior for time driven triggers. + if ( + triggeringPolicy->isTriggeringEvent(this, event, getFile(), getFileLength())) { + // + // wrap rollover request in try block since + // rollover may fail in case read access to directory + // is not provided. However appender should still be in good + // condition and the append should still happen. + try { + _LL_DEBUG( "Rolling......for: " << getFile() << " PRE:" << sync_ctx->roll_count); + rollover(p); + sync_ctx->roll_count++; + roll_count = sync_ctx->roll_count; + _LL_DEBUG( "Rolling......for: " << getFile() << " POST:" << sync_ctx->roll_count); + } catch (std::exception& ex) { + LogLog::warn(LOG4CXX_STR("Exception during rollover attempt.")); + } + } + } + + FileAppender::subAppend(event, p); + } + else if ( cretries ) { + _LL_DEBUG( "RH_SyncRollingAppender::subAppend --- UNABLE TO LOCK...RETRY " << cretries); + } + } + catch(...){ + _LL_DEBUG( "RH_SyncRollingAppender::subAppend : exception during subAPPEND " << cretries); + } + } + while ( cretries && --cretries ); +} + +void RH_SyncRollingAppender::activateOptions(Pool& p) { + + if ( !sync_ctx) { + std::string fname; + log4cxx::helpers::Transcoder::encode( fileName, fname ); + _LL_DEBUG( "ACTIVATE OPTIONS FOR: " << fname ); + _get_mem( fname ); + if ( !sync_ctx ) { + throw MissingResourceException(LOG4CXX_STR("No Shared Memory Access")); + } + + if ( !created ) { + _LL_WARN( "IGNORING LOG4 OPTIONS.. USING OPTIONS FROM MEMORY KEY: " << fname << " max_size:" << sync_ctx->max_size << " max index:" << sync_ctx->max_index << "\n"); + setMaximumFileSize(sync_ctx->max_size); + setMaxBackupIndex(sync_ctx->max_index); + } + } + + log4cxx::rolling::SizeBasedTriggeringPolicyPtr trigger( + new log4cxx::rolling::SizeBasedTriggeringPolicy()); + trigger->setMaxFileSize(max_file_size); + trigger->activateOptions(pool); + setTriggeringPolicy(trigger); + + log4cxx::rolling::FixedWindowRollingPolicyPtr rolling( + new log4cxx::rolling::FixedWindowRollingPolicy()); + rolling->setMinIndex(1); + rolling->setMaxIndex(max_bkup_index); + rolling->setFileNamePattern(getFile() + LOG4CXX_STR(".%i")); + rolling->activateOptions(pool); + setRollingPolicy(rolling); + + if ( sync_ctx ) { + + // if we created then apply settings back to shared memory object + if ( created ) { + _IPC_ScopedMLock lock(sync_ctx->mutex); + sync_ctx->max_index = rolling->getMaxIndex(); + sync_ctx->max_size = trigger->getMaxFileSize(); + } + + _LL_DEBUG( "RH_SyncRollingAppender::memory access KEY:" << sync_ctx->fname ); + _LL_DEBUG( " created : " << created ); + _LL_DEBUG( " n_msgs : " << sync_ctx->n_msgs ); + _LL_DEBUG( " max_size : " << sync_ctx->max_size ); + _LL_DEBUG( " max_index : " << sync_ctx->max_index ); + _LL_DEBUG( " roll_count : " << sync_ctx->roll_count ); + _LL_DEBUG( " fname : " << sync_ctx->fname << std::endl ); + } + + rolling::RollingFileAppenderSkeleton::activateOptions(p); + + // enforce no buffered IO + setImmediateFlush(false); + + std::string fname; + log4cxx::helpers::Transcoder::encode( fileName, fname ); + flock = ipc::file_lock(fname.c_str()); + +} + +int RH_SyncRollingAppender::getMaxBackupIndex() const { + return max_bkup_index; +} + +size_t RH_SyncRollingAppender::getMaximumFileSize() const { + return max_file_size; +} + +void RH_SyncRollingAppender::setMaxBackupIndex(int maxBackups) { + max_bkup_index = maxBackups; +} + +void RH_SyncRollingAppender::setMaximumFileSize(size_t maxFileSize1) { + max_file_size = maxFileSize1; +} + +void RH_SyncRollingAppender::setMaxFileSize(const LogString& value) { + long maxFileSize=100; + max_file_size = OptionConverter::toFileSize(value, maxFileSize + 1); +} + +void RH_SyncRollingAppender::setOption(const LogString& option, const LogString& value) { + + RollingFileAppenderSkeleton::setOption( option, value ); + + + if(StringHelper::equalsIgnoreCase(option, LOG4CXX_STR("CLEANUP"), LOG4CXX_STR("cleanup"))) { + synchronized sync(mutex); + cleanup=false; + cleanup = OptionConverter::toBoolean(value,false); + _LL_DEBUG( " RH_SyncRollingLogAppender: option: cleanup shared memory : " << cleanup ); + } + + if (StringHelper::equalsIgnoreCase(option, LOG4CXX_STR("WAITONLOCK"), LOG4CXX_STR("waitonlock")) ) { + synchronized sync(mutex); + wait_on_lock = StringHelper::toInt(value); + _LL_DEBUG( " RH_SyncRollingAppender: option: wait_on_lock : " << wait_on_lock ); + } + + if (StringHelper::equalsIgnoreCase(option, LOG4CXX_STR("RETRIES"), LOG4CXX_STR("retries")) ) { + synchronized sync(mutex); + retries = StringHelper::toInt(value); + _LL_DEBUG( " RH_SyncRollingAppender: option: retries : " << retries ); + } + + if (StringHelper::equalsIgnoreCase(option, LOG4CXX_STR("MAXFILESIZE"), LOG4CXX_STR("maxfilesize")) + || StringHelper::equalsIgnoreCase(option, LOG4CXX_STR("MAXIMUMFILESIZE"), LOG4CXX_STR("maximumfilesize"))) { + synchronized sync(mutex); + setMaxFileSize(value); + } + + if (StringHelper::equalsIgnoreCase(option,LOG4CXX_STR("MAXBACKUPINDEX"), LOG4CXX_STR("maxbackupindex")) + || StringHelper::equalsIgnoreCase(option, LOG4CXX_STR("MAXIMUMBACKUPINDEX"), LOG4CXX_STR("maximumbackupindex"))) { + synchronized sync(mutex); + setMaxBackupIndex(StringHelper::toInt(value)); + } + +} +#endif // HAVE_LOG4CXX diff --git a/redhawk/src/base/framework/logging/RH_SyncRollingAppender.h b/redhawk/src/base/framework/logging/RH_SyncRollingAppender.h new file mode 100644 index 000000000..e56dc04dd --- /dev/null +++ b/redhawk/src/base/framework/logging/RH_SyncRollingAppender.h @@ -0,0 +1,115 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK core. + * + * REDHAWK core is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ +#ifdef HAVE_LOG4CXX + +#ifndef RH_SyncRollingAppender_H +#define RH_SyncRollingAppender_H +#include +#include + +#include +#include +#include +#include + +namespace ipc=boost::interprocess; + +typedef ipc::interprocess_mutex _IPC_Mutex; + + +namespace log4cxx +{ + + class RH_SyncRollingAppender : public rolling::RollingFileAppenderSkeleton { + + // shared memory object for synchronous file appender + struct sync_log_file { + uint64_t n_msgs; + uint64_t max_size; + uint64_t max_index; + uint64_t roll_count; + char fname[PATH_MAX]; + _IPC_Mutex mutex; + }; + + + public: + + DECLARE_LOG4CXX_OBJECT_WITH_CUSTOM_CLASS(RH_SyncRollingAppender, ClassRH_SyncRollingAppender ) + + BEGIN_LOG4CXX_CAST_MAP() + LOG4CXX_CAST_ENTRY(RH_SyncRollingAppender) + LOG4CXX_CAST_ENTRY_CHAIN(rolling::RollingFileAppenderSkeleton) + END_LOG4CXX_CAST_MAP() + + + RH_SyncRollingAppender(); + + RH_SyncRollingAppender( const LayoutPtr &layout, + const LogString &filename ); + + virtual ~RH_SyncRollingAppender(); + + // + // Called by log4cxx internals to process options + // + void setOption(const LogString& option, const LogString& value); + + void activateOptions( log4cxx::helpers::Pool& p); + + int getMaxBackupIndex() const; + size_t getMaximumFileSize() const; + void setMaxBackupIndex( int maxBackupIndex ); + void setMaxFileSize( const LogString & value ); + void setMaximumFileSize(size_t value ); + + protected: + + void subAppend (const spi::LoggingEventPtr &event, log4cxx::helpers::Pool &p); + void resync_rollover (log4cxx::helpers::Pool &p); + + private: + + int _get_mem( const std::string &fname ); + + // prevent copy and assignment statements + RH_SyncRollingAppender(const RH_SyncRollingAppender&); + RH_SyncRollingAppender& operator=(const RH_SyncRollingAppender&); + + int wait_on_lock; + int retries; + size_t max_file_size; + int max_bkup_index; + uint64_t roll_count; + bool cleanup; + bool created; + sync_log_file *sync_ctx; + ipc::file_lock flock; + ipc::shared_memory_object shm; + ipc::mapped_region region; + + + }; + +}; // end of namespace +#endif + + +#endif // HAVE_LOG4CXX diff --git a/redhawk/src/testing/loggers/syncappender/Makefile.am b/redhawk/src/testing/loggers/syncappender/Makefile.am new file mode 100644 index 000000000..86a4df0a2 --- /dev/null +++ b/redhawk/src/testing/loggers/syncappender/Makefile.am @@ -0,0 +1,55 @@ +# Rules for the test code (use `make check` to execute) +ACLOCAL_AMFLAGS = -I m4 -I ${OSSIEHOME}/share/aclocal/ossie +TESTS = appender_test proc_log cleanmem +check_PROGRAMS = $(TESTS) +logger_top=../../../base/framework/logging +logger_libsrc=$(logger_top) +logger_lib_SRC=$(logger_libsrc)/RH_SyncRollingAppender.cpp +logger_lib_INC=-I$(logger_libsrc) + +appender_test_SOURCES = appender_test.cpp test_suites.cpp $(logger_lib_SRC) + +appender_test_boost_ldadd=$(BOOST_LDFLAGS) $(BOOST_SYSTEM_LIB) -lboost_filesystem +appender_test_log4cxx_ldadd=-llog4cxx +appender_test_LIB = +appender_test_CXXFLAGS = $(CPPUNIT_CFLAGS) -I$(logger_top)/include $(logger_lib_INC) $(logger_idl_INC) -I/usr/include/apr-1 $(BOOST_CPPFLAGS) -DDEBUG_ON -DHAVE_LOG4CXX +appender_test_LDADD = $(appender_test_LIB) $(logger_idl_LIB) $(appender_test_boost_ldadd) $(appender_test_log4cxx_ldadd) +appender_test_LDFLAGS = $(CPPUNIT_LIBS) +appender_test_LDFLAGS += -ldl + + +proc_log_SOURCES = proc_log.cpp $(logger_lib_SRC) +proc_log_boost_ldadd=$(BOOST_LDFLAGS) $(BOOST_SYSTEM_LIB) -lboost_filesystem +proc_log_log4cxx_ldadd=-llog4cxx +proc_log_LIB = +proc_log_CXXFLAGS = $(CPPUNIT_CFLAGS) -I$(logger_top)/include $(logger_lib_INC) $(logger_idl_INC) -I/usr/include/apr-1 $(BOOST_CPPFLAGS) -DDEBUG_ON -DHAVE_LOG4CXX +proc_log_LDADD = $(proc_log_LIB) $(logger_idl_LIB) $(proc_log_boost_ldadd) $(proc_log_log4cxx_ldadd) +proc_log_LDFLAGS = $(CPPUNIT_LIBS) +proc_log_LDFLAGS += -ldl + + +cleanmem_SOURCES = cleanmem.cpp +cleanmem_boost_ldadd=$(BOOST_LDFLAGS) $(BOOST_SYSTEM_LIB) -lboost_filesystem +cleanmem_log4cxx_ldadd=-llog4cxx +cleanmem_LIB = +cleanmem_CXXFLAGS = $(CPPUNIT_CFLAGS) -I$(logger_top)/include $(logger_lib_INC) $(logger_idl_INC) -I/usr/include/apr-1 $(BOOST_CPPFLAGS) -DDEBUG_ON -DHAVE_LOG4CXX +cleanmem_LDADD = $(cleanmem_LIB) $(logger_idl_LIB) $(cleanmem_boost_ldadd) $(cleanmem_log4cxx_ldadd) +cleanmem_LDFLAGS = $(CPPUNIT_LIBS) +cleanmem_LDFLAGS += -ldl + +distclean-local: + rm -rf m4 + rm -f config.* + rm -rf autom4te.cache + rm -f acinclude.m4 + rm -f aclocal.m4 + rm -f configure + rm -f depcomp + rm -f install-sh + rm -f ltmain.sh + rm -f Makefile.in + rm -f missing + rm -rf .deps + rm -f COPYING INSTALL *~ MP_RedhawkTest + + diff --git a/redhawk/src/testing/loggers/syncappender/appender_test.cpp b/redhawk/src/testing/loggers/syncappender/appender_test.cpp new file mode 100644 index 000000000..836a16473 --- /dev/null +++ b/redhawk/src/testing/loggers/syncappender/appender_test.cpp @@ -0,0 +1,49 @@ +#include +#include +#include +#include "log4cxx/logger.h" +#include "log4cxx/propertyconfigurator.h" +#include "log4cxx/helpers/exception.h" +#include "logtestdebug.h" + + +LOGGER_CFG("LOGGER-CFG-TEST"); + +int main(int argc, char* argv[]) +{ + + std::string cfgname("log4j.stdout"); + std::string testname(""); + if ( argc > 1 ) { + testname = argv[1]; + } + + // Set up a simple configuration that logs on the console. + log4cxx::PropertyConfigurator::configure(cfgname.c_str()); + + // Get the top level suite from the registry + CppUnit::Test *suite; + if ( testname != "" ) { + CppUnit::TestFactoryRegistry ®istry = CppUnit::TestFactoryRegistry::getRegistry(testname); + suite = registry.makeTest(); + } + else { + CppUnit::TestFactoryRegistry ®istry = CppUnit::TestFactoryRegistry::getRegistry(); + suite = registry.makeTest(); + } + + // Adds the test to the list of test to run + CppUnit::TextUi::TestRunner runner; + runner.addTest( suite ); + + // Change the default outputter to a compiler error format outputter + runner.setOutputter( new CppUnit::CompilerOutputter( &runner.result(), + std::cerr ) ); + // Run the tests. + bool wasSucessful = runner.run(); + + LOGGER_END("LOGGER-CFG-TEST"); + + // Return error code 1 if the one of test failed. + return wasSucessful ? 0 : 1; +} diff --git a/redhawk/src/testing/loggers/syncappender/cleanmem.cpp b/redhawk/src/testing/loggers/syncappender/cleanmem.cpp new file mode 100644 index 000000000..a2e96b727 --- /dev/null +++ b/redhawk/src/testing/loggers/syncappender/cleanmem.cpp @@ -0,0 +1,20 @@ +#include +#include +#include +#include + +int main (int argc, char **argv ) +{ + using namespace boost::interprocess; + try{ + //Erase previous shared memory + shared_memory_object::remove(argv[1]); + + } + catch(interprocess_exception &ex){ + shared_memory_object::remove("shared_memory-a"); + std::cout << ex.what() << std::endl; + return 1; + } + return 0; +} diff --git a/redhawk/src/testing/loggers/syncappender/configure.ac b/redhawk/src/testing/loggers/syncappender/configure.ac new file mode 100644 index 000000000..057b06037 --- /dev/null +++ b/redhawk/src/testing/loggers/syncappender/configure.ac @@ -0,0 +1,26 @@ + + +dnl Process this file with autoconf to produce a configure script. +dnl AC_INIT(Makefile.am) +dnl AC_CONFIG_MACRO_DIR([m4]) +dnl AM_INIT_AUTOMAKE(Logging_Test,0.1) + +AC_INIT(Logging_Test,0.1) +AC_CONFIG_MACRO_DIR([m4]) +AM_INIT_AUTOMAKE([foreign]) + +AM_PATH_CPPUNIT(1.9.6) +AC_PROG_CXX +AC_PROG_CC +AC_PROG_INSTALL +AC_PREFIX_DEFAULT(${OSSIEHOME}) + +OSSIE_CHECK_OSSIE +OSSIE_OSSIEHOME_AS_PREFIX +PKG_CHECK_MODULES([OMNI_DEPS], [ omniORB4 >= 4.0 omniEvents >= 2.0 omniDynamic4 >= 4.0.0 ]) +PKG_CHECK_MODULES([OSSIE_DEPS], [ossie >= 1.8 ] ) + +AX_BOOST_BASE([1.41]) +AX_BOOST_SYSTEM +AC_CORBA_ORB +AC_OUTPUT(Makefile) diff --git a/redhawk/src/testing/loggers/syncappender/log4j.appender b/redhawk/src/testing/loggers/syncappender/log4j.appender new file mode 100644 index 000000000..b055cad6f --- /dev/null +++ b/redhawk/src/testing/loggers/syncappender/log4j.appender @@ -0,0 +1,35 @@ + + + +#log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n + +log4j.rootLogger=ALL,stdout, mp + +# Direct log messages to stdout +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.Target=System.out +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c:%L - %m%n + +# Direct log messages to stdout +log4j.appender.pse=org.ossie.logging.RH_LogEventAppender +log4j.appender.pse.name_context=TEST_APPENDER +log4j.appender.pse.event_channel=TEST_EVT_CH1 +log4j.appender.pse.producer_id=PRODUCER1 +log4j.appender.pse.producer_name=THE BIG CHEESE +log4j.appender.pse.layout=org.apache.log4j.PatternLayout +log4j.appender.pse.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c:%L - %m%n + +# Direct log messages to stdout +log4j.appender.mp=org.ossie.logging.RH_SyncRollingAppender +log4j.appender.mp.Retries=2 +log4j.appender.mp.WaitOnLock=30 +log4j.appender.mp.MaxFileSize=5MB +log4j.appender.mp.MaxBackupIndex=10 +log4j.appender.mp.File=MP_RedhawkTest +log4j.appender.mp.Cleanup=False +log4j.appender.mp.layout=org.apache.log4j.PatternLayout +log4j.appender.mp.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c:%L - %m%n + + + diff --git a/redhawk/src/testing/loggers/syncappender/log4j.stdout b/redhawk/src/testing/loggers/syncappender/log4j.stdout new file mode 100644 index 000000000..a632ff660 --- /dev/null +++ b/redhawk/src/testing/loggers/syncappender/log4j.stdout @@ -0,0 +1,9 @@ + + +log4j.rootLogger=INFO,stdout + +# Direct log messages to stdout +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.Target=System.out +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n diff --git a/redhawk/src/testing/loggers/syncappender/logtestdebug.h b/redhawk/src/testing/loggers/syncappender/logtestdebug.h new file mode 100644 index 000000000..925f928dd --- /dev/null +++ b/redhawk/src/testing/loggers/syncappender/logtestdebug.h @@ -0,0 +1,28 @@ +#ifndef _LOGTESTDEBUG_H +#define _LOGTESTDEBUG_H + +// set when compiling library for test mode... OK to use log4 logging.... +#include +#include +extern log4cxx::LoggerPtr _logger_; +#define LTRACE( expression ) LOG4CXX_TRACE( _logger_, expression ) +#define LDEBUG( expression ) LOG4CXX_DEBUG( _logger_ , expression ) +#define LINFO( expression ) LOG4CXX_INFO( _logger_, expression ) +#define LWARN( expression ) LOG4CXX_WARN( _logger_, expression ) +#define LERROR( expression ) LOG4CXX_ERROR( _logger_, expression ) +#define LFATAL( expression ) LOG4CXX_FATAL( _logger_, expression ) + +#define LNTRACE( lname, expression ) LOG4CXX_TRACE( log4cxx::Logger::getLogger(lname), expression ) +#define LNDEBUG( lname, expression ) LOG4CXX_DEBUG( log4cxx::Logger::getLogger(lname), expression ) +#define LNINFO( lname, expression ) LOG4CXX_INFO( log4cxx::Logger::getLogger(lname), expression ) +#define LNWARN( lname, expression ) LOG4CXX_WARN( log4cxx::Logger::getLogger(lname), expression ) +#define LNERROR( lname, expression ) LOG4CXX_ERROR( log4cxx::Logger::getLogger(lname), expression ) +#define LNFATAL( lname, expression ) LOG4CXX_FATAL( log4cxx::Logger::getLogger(lname), expression ) + +#define LOGGER_CFG( name ) \ + log4cxx::LoggerPtr _logger_ = log4cxx::Logger::getLogger(name); + +#define LOGGER_END( name ) \ + log4cxx::LogManager::shutdown(); + +#endif diff --git a/redhawk/src/testing/loggers/syncappender/proc_log.cpp b/redhawk/src/testing/loggers/syncappender/proc_log.cpp new file mode 100644 index 000000000..1cce6d0f4 --- /dev/null +++ b/redhawk/src/testing/loggers/syncappender/proc_log.cpp @@ -0,0 +1,52 @@ +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +int main( int argc, char ** argv ) { + + // Set up a simple configuration that logs on the console. + log4cxx::PropertyConfigurator::configure("log4j.appender" ); + + log4cxx::helpers::LogLog::setInternalDebugging(true); + + log4cxx::LoggerPtr logger = log4cxx::Logger::getRootLogger(); + + int32_t interval=1000; + int64_t cnt=10; + int pid = getpid(); + + if ( argc > 1 ) cnt=strtoll( argv[1], NULL, 0); + if ( argc > 2 ) interval=strtol( argv[2], NULL, 0); + + + while ( cnt-- ) { + LOG4CXX_INFO(logger, "test_log4j_props_appender MSG 1 - root logger (" << pid << ")" ); + LOG4CXX_INFO(logger, "test_log4j_props_appender MSG 2 - root logger (" << pid << ")" ); + LOG4CXX_INFO(logger, "test_log4j_props_appender MSG 3 - root logger (" << pid << ")" ); + + std::ostringstream os; + os << "LOG-MultiProcRollingFileAppender.Sub" << getpid(); + log4cxx::LoggerPtr lp = log4cxx::Logger::getLogger(os.str()); + LOG4CXX_INFO(lp, "test_log4j_props_appender MSG 1 - SUB logger (" << pid << ")" ); + LOG4CXX_INFO(lp, "test_log4j_props_appender MSG 2 - SUB logger (" << pid << ")" ); + LOG4CXX_INFO(lp, "test_log4j_props_appender MSG 3 - SUB logger (" << pid << ")" ); + + LOG4CXX_INFO(logger, "proc_log -END (" << pid << ")" ); + usleep(interval); + } + + // closes appenders correctly... + log4cxx::LogManager::shutdown(); + + return(0); + +} + diff --git a/redhawk/src/testing/loggers/syncappender/reconf b/redhawk/src/testing/loggers/syncappender/reconf new file mode 100755 index 000000000..db88259ab --- /dev/null +++ b/redhawk/src/testing/loggers/syncappender/reconf @@ -0,0 +1,2 @@ +[ -d m4 ] || mkdir m4 +autoreconf -i diff --git a/redhawk/src/testing/loggers/syncappender/runtests b/redhawk/src/testing/loggers/syncappender/runtests new file mode 100755 index 000000000..af87478d3 --- /dev/null +++ b/redhawk/src/testing/loggers/syncappender/runtests @@ -0,0 +1,13 @@ +# +# +logging_top=../.. +logging_libsrc_top=$logging_top/libsrc +export LD_LIBRARY_PATH=$logging_top/idl/.libs:$logging_libsrc_top/.libs:${LD_LIBRARY_PATH} +make appender_test +make proc_log +make cleanmem + +./appender_test test_one + +./cleanmem MP_RedhawkTest + diff --git a/redhawk/src/testing/loggers/syncappender/test_suites.cpp b/redhawk/src/testing/loggers/syncappender/test_suites.cpp new file mode 100644 index 000000000..4a7a8f11a --- /dev/null +++ b/redhawk/src/testing/loggers/syncappender/test_suites.cpp @@ -0,0 +1,153 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "test_suites.h" + +// Registers the fixture into the 'registry' +CPPUNIT_TEST_SUITE_REGISTRATION( test_suite_one ); +CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( test_suite_one, "test_one" ); +CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( test_suite_two, "test_two" ); + + +void +test_suite_one::setUp() +{ + + // Set up a simple configuration that logs on the console. + log4cxx::PropertyConfigurator::configure("log4j.stdout" ); + + log4cxx::helpers::LogLog::setInternalDebugging(true); + + logger = log4cxx::Logger::getLogger("LOG-MultiProcRollingFileAppender"); + + LOG4CXX_INFO(logger, "Setup cache directory for saved configuration files"); + boost::filesystem::path dir("./logs"); + boost::filesystem::create_directory(dir); +} + +void +test_suite_one::tearDown() +{ + // Set up a simple configuration that logs on the console. + log4cxx::PropertyConfigurator::configure("log4j.stdout" ); + + boost::filesystem::path dir("./logs"); + boost::filesystem::remove_all(dir); + +} + +void +test_suite_one::test_one() +{ + LOG4CXX_INFO(logger, "RH_SyncRollingAppender - BEGIN "); + + // Set up a simple configuration that logs on the console. + log4cxx::PropertyConfigurator::configure("log4j.appender" ); + int cnt=10; + int pid = getpid(); + + while ( cnt-- ) { + LOG4CXX_INFO(logger, "test_log4j_props_appender MSG 1 - root logger (" << pid << ")" ); + LOG4CXX_INFO(logger, "test_log4j_props_appender MSG 2 - root logger (" << pid << ")" ); + LOG4CXX_INFO(logger, "test_log4j_props_appender MSG 3 - root logger (" << pid << ")" ); + + std::ostringstream os; + os << "LOG-MultiProcRollingFileAppender.Sub" << getpid(); + log4cxx::LoggerPtr lp = log4cxx::Logger::getLogger(os.str()); + LOG4CXX_INFO(lp, "test_log4j_props_appender MSG 1 - SUB logger (" << pid << ")" ); + LOG4CXX_INFO(lp, "test_log4j_props_appender MSG 2 - SUB logger (" << pid << ")" ); + LOG4CXX_INFO(lp, "test_log4j_props_appender MSG 3 - SUB logger (" << pid << ")" ); + + LOG4CXX_INFO(logger, "RH_SyncRollingAppender -END "); + usleep(1000); + } + +} + + +void +test_suite_one::test_two() +{ + LOG4CXX_INFO(logger, "MultiProcess Test - BEGIN "); + + typedef std::vector< int > Chillens; + + Chillens chillens; + int cnt=10; + for( int i=0; i +#include + +class test_suite_one : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE( test_suite_one ); + CPPUNIT_TEST( test_one ); + CPPUNIT_TEST( test_two ); + CPPUNIT_TEST_SUITE_END(); + +public: + void setUp(); + void tearDown(); + + void test_one(); + void test_two(); + + log4cxx::LoggerPtr logger; + +}; + + +class test_suite_two : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE( test_suite_two ); + CPPUNIT_TEST( test_loop ); + CPPUNIT_TEST_SUITE_END(); + +public: + void setUp(); + void tearDown(); + + void test_loop(); + + log4cxx::LoggerPtr logger; + +}; + +#endif // TEST_ONE From 1e6ec24f31c302b80cb314507fef23364ab241e5 Mon Sep 17 00:00:00 2001 From: 8530 <8530@vm-131.vsi-corp.com> Date: Thu, 24 Mar 2016 15:12:39 -0400 Subject: [PATCH 0061/1644] wip --- redhawk/src/base/framework/Makefile.am | 1 + .../src/base/framework/logging/RH_SyncRollingAppender.cpp | 8 ++------ redhawk/src/testing/loggers/syncappender/Makefile.am | 5 +++-- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/redhawk/src/base/framework/Makefile.am b/redhawk/src/base/framework/Makefile.am index 1d0f8d3f2..10dbfa9fc 100644 --- a/redhawk/src/base/framework/Makefile.am +++ b/redhawk/src/base/framework/Makefile.am @@ -49,6 +49,7 @@ libossiecf_la_SOURCES = AggregateDevice_impl.cpp \ logging/rh_logger.cpp \ logging/StringInputStream.cpp \ logging/RH_LogEventAppender.cpp \ + logging/RH_SyncRollingAppender.cpp \ EventChannelSupport.cpp \ Events.cpp \ Component.cpp \ diff --git a/redhawk/src/base/framework/logging/RH_SyncRollingAppender.cpp b/redhawk/src/base/framework/logging/RH_SyncRollingAppender.cpp index 0f2572d7e..f6ab8c25f 100644 --- a/redhawk/src/base/framework/logging/RH_SyncRollingAppender.cpp +++ b/redhawk/src/base/framework/logging/RH_SyncRollingAppender.cpp @@ -19,7 +19,6 @@ */ #ifdef HAVE_LOG4CXX #include -#include #include #include #include @@ -32,10 +31,7 @@ #include #include #include -#if !defined(LOG4CXX) -#define LOG4CXX 1 -#endif -#include + #include #include @@ -185,7 +181,7 @@ int RH_SyncRollingAppender::_get_mem( const std::string &fname) { region.swap(tregion); - return 0; + return retval; } diff --git a/redhawk/src/testing/loggers/syncappender/Makefile.am b/redhawk/src/testing/loggers/syncappender/Makefile.am index 86a4df0a2..9561452f1 100644 --- a/redhawk/src/testing/loggers/syncappender/Makefile.am +++ b/redhawk/src/testing/loggers/syncappender/Makefile.am @@ -4,8 +4,9 @@ TESTS = appender_test proc_log cleanmem check_PROGRAMS = $(TESTS) logger_top=../../../base/framework/logging logger_libsrc=$(logger_top) -logger_lib_SRC=$(logger_libsrc)/RH_SyncRollingAppender.cpp -logger_lib_INC=-I$(logger_libsrc) +#logger_lib_INC=-I$(logger_libsrc) +logger_lib_SRC=../../../base/framework/logging/RH_SyncRollingAppender.cpp +logger_lib_INC=-I../../../base/framework/logging appender_test_SOURCES = appender_test.cpp test_suites.cpp $(logger_lib_SRC) From e76f85082df8efa12124eb8d654d25b4c92e4480 Mon Sep 17 00:00:00 2001 From: 8530 <8530@vm-131.vsi-corp.com> Date: Fri, 29 Apr 2016 15:38:39 -0400 Subject: [PATCH 0062/1644] fixed property change listeners when an event channel is used for notifications, #resolves CF-1467 --- .../tests/test_08_PropertyChangeListener.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/redhawk/src/testing/tests/test_08_PropertyChangeListener.py b/redhawk/src/testing/tests/test_08_PropertyChangeListener.py index a135b457a..f932be7e9 100644 --- a/redhawk/src/testing/tests/test_08_PropertyChangeListener.py +++ b/redhawk/src/testing/tests/test_08_PropertyChangeListener.py @@ -33,6 +33,7 @@ from ossie.utils import redhawk from ossie.events import Subscriber +java_support = scatest.hasJavaSupport() execDeviceNode = "/nodes/test_GPP_node/DeviceManager.dcd.xml" class Consumer_i(CosEventComm__POA.PushConsumer): @@ -216,7 +217,6 @@ def test_PropertyChangeListener_PYTHON(self): app.releaseObject() self._app=None - @scatest.requireJava def test_PropertyChangeListener_JAVA(self): self.localEvent = threading.Event() @@ -407,7 +407,10 @@ def test_PropertyChangeListener_EC_CPP(self): self._devBooter, self._devMgr = self.launchDeviceManager(execDeviceNode, self._domMgr) self.assertNotEqual(self._devBooter, None) - self._domMgr.installApplication("/waveforms/PropertyChangeListenerNoJava/PropertyChangeListenerNoJava.sad.xml") + if java_support: + self._domMgr.installApplication("/waveforms/PropertyChangeListener/PropertyChangeListener.sad.xml") + else: + self._domMgr.installApplication("/waveforms/PropertyChangeListenerNoJava/PropertyChangeListenerNoJava.sad.xml") appFact = self._domMgr._get_applicationFactories()[0] self.assertNotEqual(appFact, None) app = appFact.create(appFact._get_name(), [], []) @@ -461,7 +464,10 @@ def test_PropertyChangeListener_EC_PYTHON(self): self._devBooter, self._devMgr = self.launchDeviceManager(execDeviceNode, self._domMgr) self.assertNotEqual(self._devBooter, None) - self._domMgr.installApplication("/waveforms/PropertyChangeListenerNoJava/PropertyChangeListenerNoJava.sad.xml") + if java_support: + self._domMgr.installApplication("/waveforms/PropertyChangeListener/PropertyChangeListener.sad.xml") + else: + self._domMgr.installApplication("/waveforms/PropertyChangeListenerNoJava/PropertyChangeListenerNoJava.sad.xml") appFact = self._domMgr._get_applicationFactories()[0] self.assertNotEqual(appFact, None) app = appFact.create(appFact._get_name(), [], []) @@ -509,8 +515,9 @@ def test_PropertyChangeListener_EC_PYTHON(self): app.releaseObject() self._app=None - @scatest.requireJava def test_PropertyChangeListener_EC_JAVA(self): + if not java_support: + return self.localEvent = threading.Event() self.eventFlag = False @@ -570,7 +577,7 @@ def test_PropertyChangeListener_EC_APP(self): self._devBooter, self._devMgr = self.launchDeviceManager(execDeviceNode, self._domMgr) self.assertNotEqual(self._devBooter, None) - self._domMgr.installApplication("/waveforms/PropertyChangeListenerNoJava/PropertyChangeListenerNoJava.sad.xml") + self._domMgr.installApplication("/waveforms/PropertyChangeListener/PropertyChangeListener.sad.xml") appFact = self._domMgr._get_applicationFactories()[0] self.assertNotEqual(appFact, None) app = appFact.create(appFact._get_name(), [], []) From 035741fc0931c4629f32d806be244efa029ce8e1 Mon Sep 17 00:00:00 2001 From: 8530 <8530@vm-131.vsi-corp.com> Date: Tue, 10 May 2016 08:53:45 -0400 Subject: [PATCH 0063/1644] added test suite for additional appender and a framework unit test --- .../testing/loggers/syncappender/.gitignore | 5 ++ .../testing/loggers/syncappender/Makefile.am | 6 +- .../loggers/syncappender/appender_test.cpp | 1 + .../testing/loggers/syncappender/cleanmem.cpp | 9 ++- .../src/testing/loggers/syncappender/runtests | 9 +-- .../loggers/syncappender/test_suites.cpp | 69 +++++++++++++++++++ .../loggers/syncappender/test_suites.h | 21 ++++++ .../testing/sdr/logcfg/log4j.event_appender | 21 ++++++ redhawk/src/testing/sdr/logcfg/log4j.stdout | 9 +++ .../testing/sdr/logcfg/log4j.sync_appender | 26 +++++++ .../testing/sdr/logcfg/log4j.sync_appender2 | 26 +++++++ .../testing/tests/test_15_LoggingConfig.py | 2 + 12 files changed, 194 insertions(+), 10 deletions(-) create mode 100644 redhawk/src/testing/loggers/syncappender/.gitignore create mode 100644 redhawk/src/testing/sdr/logcfg/log4j.event_appender create mode 100644 redhawk/src/testing/sdr/logcfg/log4j.stdout create mode 100644 redhawk/src/testing/sdr/logcfg/log4j.sync_appender create mode 100644 redhawk/src/testing/sdr/logcfg/log4j.sync_appender2 diff --git a/redhawk/src/testing/loggers/syncappender/.gitignore b/redhawk/src/testing/loggers/syncappender/.gitignore new file mode 100644 index 000000000..017c963c3 --- /dev/null +++ b/redhawk/src/testing/loggers/syncappender/.gitignore @@ -0,0 +1,5 @@ + +Makefile.in +Makefile +configure +config.* diff --git a/redhawk/src/testing/loggers/syncappender/Makefile.am b/redhawk/src/testing/loggers/syncappender/Makefile.am index 9561452f1..f030f1d6f 100644 --- a/redhawk/src/testing/loggers/syncappender/Makefile.am +++ b/redhawk/src/testing/loggers/syncappender/Makefile.am @@ -1,6 +1,7 @@ # Rules for the test code (use `make check` to execute) ACLOCAL_AMFLAGS = -I m4 -I ${OSSIEHOME}/share/aclocal/ossie -TESTS = appender_test proc_log cleanmem +TESTS = appender_test +noinst_PROGRAMS = cleanmem proc_log check_PROGRAMS = $(TESTS) logger_top=../../../base/framework/logging logger_libsrc=$(logger_top) @@ -51,6 +52,7 @@ distclean-local: rm -f Makefile.in rm -f missing rm -rf .deps - rm -f COPYING INSTALL *~ MP_RedhawkTest + rm -f COPYING INSTALL *~ + rm -rf MP_RedhawkTest* diff --git a/redhawk/src/testing/loggers/syncappender/appender_test.cpp b/redhawk/src/testing/loggers/syncappender/appender_test.cpp index 836a16473..6a6284c8e 100644 --- a/redhawk/src/testing/loggers/syncappender/appender_test.cpp +++ b/redhawk/src/testing/loggers/syncappender/appender_test.cpp @@ -29,6 +29,7 @@ int main(int argc, char* argv[]) } else { CppUnit::TestFactoryRegistry ®istry = CppUnit::TestFactoryRegistry::getRegistry(); + registry.registerFactory( &CppUnit::TestFactoryRegistry::getRegistry("test_three") ); suite = registry.makeTest(); } diff --git a/redhawk/src/testing/loggers/syncappender/cleanmem.cpp b/redhawk/src/testing/loggers/syncappender/cleanmem.cpp index a2e96b727..eaa3bcba7 100644 --- a/redhawk/src/testing/loggers/syncappender/cleanmem.cpp +++ b/redhawk/src/testing/loggers/syncappender/cleanmem.cpp @@ -5,6 +5,12 @@ int main (int argc, char **argv ) { + + if ( argc < 2 ) { + printf("usage cleanmem \n"); + return -1; + } + using namespace boost::interprocess; try{ //Erase previous shared memory @@ -12,9 +18,8 @@ int main (int argc, char **argv ) } catch(interprocess_exception &ex){ - shared_memory_object::remove("shared_memory-a"); std::cout << ex.what() << std::endl; - return 1; + return -1; } return 0; } diff --git a/redhawk/src/testing/loggers/syncappender/runtests b/redhawk/src/testing/loggers/syncappender/runtests index af87478d3..e88e7e977 100755 --- a/redhawk/src/testing/loggers/syncappender/runtests +++ b/redhawk/src/testing/loggers/syncappender/runtests @@ -3,11 +3,8 @@ logging_top=../.. logging_libsrc_top=$logging_top/libsrc export LD_LIBRARY_PATH=$logging_top/idl/.libs:$logging_libsrc_top/.libs:${LD_LIBRARY_PATH} -make appender_test -make proc_log -make cleanmem +./reconf +./configure +make check -./appender_test test_one - -./cleanmem MP_RedhawkTest diff --git a/redhawk/src/testing/loggers/syncappender/test_suites.cpp b/redhawk/src/testing/loggers/syncappender/test_suites.cpp index 4a7a8f11a..02fac2a8b 100644 --- a/redhawk/src/testing/loggers/syncappender/test_suites.cpp +++ b/redhawk/src/testing/loggers/syncappender/test_suites.cpp @@ -17,6 +17,8 @@ CPPUNIT_TEST_SUITE_REGISTRATION( test_suite_one ); CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( test_suite_one, "test_one" ); CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( test_suite_two, "test_two" ); +CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( test_suite_three, "test_three" ); + void @@ -151,3 +153,70 @@ test_suite_two::test_loop() } + + +#include +#include + + +void +test_suite_three::setUp() +{ + + // Set up a simple configuration that logs on the console. + log4cxx::PropertyConfigurator::configure("log4j.stdout" ); + + log4cxx::helpers::LogLog::setInternalDebugging(true); + + logger = log4cxx::Logger::getLogger("LOG-SyncRollingAppender"); + + LOG4CXX_INFO(logger, "Setup cache directory for saved configuration files"); + boost::filesystem::path dir("./logs"); + boost::filesystem::create_directory(dir); +} + +void +test_suite_three::tearDown() +{ + // Set up a simple configuration that logs on the console. + log4cxx::PropertyConfigurator::configure("log4j.stdout" ); + + boost::filesystem::path dir("./logs"); + boost::filesystem::remove_all(dir); + +} + + +void +test_suite_three::test_cleanmem() +{ + LOG4CXX_INFO(logger, "RH_SyncRollingAppender - BEGIN "); + + // Set up a simple configuration that logs on the console. + log4cxx::PropertyConfigurator::configure("log4j.appender" ); + + int ret=system("./cleanmem MP_RedhawkTest"); + + CPPUNIT_ASSERT_EQUAL( ret, 0); + + +} + + +void +test_suite_three::test_cleanmem_missing() +{ + LOG4CXX_INFO(logger, "RH_SyncRollingAppender - BEGIN "); + + // Set up a simple configuration that logs on the console. + log4cxx::PropertyConfigurator::configure("log4j.appender" ); + + int ret=system("./cleanmem MP_RedhawkTest"); + + using namespace boost::interprocess; + + // validate memory is no long there + shared_memory_object obj( open_only, "MP_RedhawkTest", read_only ); + +} + diff --git a/redhawk/src/testing/loggers/syncappender/test_suites.h b/redhawk/src/testing/loggers/syncappender/test_suites.h index 121fc53c8..c586c05ef 100644 --- a/redhawk/src/testing/loggers/syncappender/test_suites.h +++ b/redhawk/src/testing/loggers/syncappender/test_suites.h @@ -1,6 +1,7 @@ #ifndef TEST_SUITES_H #define TEST_SUITES_H #include +#include #include class test_suite_one : public CppUnit::TestFixture @@ -38,4 +39,24 @@ class test_suite_two : public CppUnit::TestFixture }; + +class test_suite_three : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE( test_suite_three ); + CPPUNIT_TEST( test_cleanmem ); + CPPUNIT_TEST_EXCEPTION( test_cleanmem_missing, boost::interprocess::interprocess_exception ); + CPPUNIT_TEST_SUITE_END(); + +public: + void setUp(); + void tearDown(); + + void test_cleanmem(); + void test_cleanmem_missing(); + + log4cxx::LoggerPtr logger; + +}; + + #endif // TEST_ONE diff --git a/redhawk/src/testing/sdr/logcfg/log4j.event_appender b/redhawk/src/testing/sdr/logcfg/log4j.event_appender new file mode 100644 index 000000000..a82308165 --- /dev/null +++ b/redhawk/src/testing/sdr/logcfg/log4j.event_appender @@ -0,0 +1,21 @@ + + + +#log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n + +log4j.rootLogger=ALL,stdout, pse + +# Direct log messages to stdout +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.Target=System.out +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c:%L - %m%n + +# Direct log messages to stdout +log4j.appender.pse=org.ossie.logging.RH_LogEventAppender +log4j.appender.pse.name_context=TEST_APPENDER +log4j.appender.pse.event_channel=TEST_EVT_CH1 +log4j.appender.pse.producer_id=PRODUCER1 +log4j.appender.pse.producer_name=THE BIG CHEESE +log4j.appender.pse.layout=org.apache.log4j.PatternLayout +log4j.appender.pse.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c:%L - %m%n diff --git a/redhawk/src/testing/sdr/logcfg/log4j.stdout b/redhawk/src/testing/sdr/logcfg/log4j.stdout new file mode 100644 index 000000000..a632ff660 --- /dev/null +++ b/redhawk/src/testing/sdr/logcfg/log4j.stdout @@ -0,0 +1,9 @@ + + +log4j.rootLogger=INFO,stdout + +# Direct log messages to stdout +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.Target=System.out +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n diff --git a/redhawk/src/testing/sdr/logcfg/log4j.sync_appender b/redhawk/src/testing/sdr/logcfg/log4j.sync_appender new file mode 100644 index 000000000..352a629b1 --- /dev/null +++ b/redhawk/src/testing/sdr/logcfg/log4j.sync_appender @@ -0,0 +1,26 @@ + + + +#log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n + +log4j.rootLogger=ALL,stdout, mp + +# Direct log messages to stdout +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.Target=System.out +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c:%L - %m%n + +# Direct log messages to stdout +log4j.appender.mp=org.ossie.logging.RH_SyncRollingAppender +log4j.appender.mp.Retries=2 +log4j.appender.mp.WaitOnLock=30 +log4j.appender.mp.MaxFileSize=5MB +log4j.appender.mp.MaxBackupIndex=10 +log4j.appender.mp.File=/tmp/MP_RedhawkTest +log4j.appender.mp.Cleanup=False +log4j.appender.mp.layout=org.apache.log4j.PatternLayout +log4j.appender.mp.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c:%L - %m%n + + + diff --git a/redhawk/src/testing/sdr/logcfg/log4j.sync_appender2 b/redhawk/src/testing/sdr/logcfg/log4j.sync_appender2 new file mode 100644 index 000000000..d98c5acc5 --- /dev/null +++ b/redhawk/src/testing/sdr/logcfg/log4j.sync_appender2 @@ -0,0 +1,26 @@ + + + +#log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n + +log4j.rootLogger=ALL,stdout, mp + +# Direct log messages to stdout +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.Target=System.out +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c:%L - %m%n + +# Direct log messages to stdout +log4j.appender.mp=org.ossie.logging.RH_SyncRollingAppender +log4j.appender.mp.Retries=2 +log4j.appender.mp.WaitOnLock=30 +log4j.appender.mp.MaxFileSize=5MB +log4j.appender.mp.MaxBackupIndex=10 +log4j.appender.mp.File=MP_RedhawkTest +log4j.appender.mp.Cleanup=False +log4j.appender.mp.layout=org.apache.log4j.PatternLayout +log4j.appender.mp.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} COMP2 %-5p %c:%L - %m%n + + + diff --git a/redhawk/src/testing/tests/test_15_LoggingConfig.py b/redhawk/src/testing/tests/test_15_LoggingConfig.py index f1b269d8c..4ece4832a 100644 --- a/redhawk/src/testing/tests/test_15_LoggingConfig.py +++ b/redhawk/src/testing/tests/test_15_LoggingConfig.py @@ -18,6 +18,8 @@ # along with this program. If not, see http://www.gnu.org/licenses/. # +import time +import os import unittest from _unitTestHelpers import scatest from ossie.cf import CF From 72b25ad4b80e247b01b2b558529c80e187f08f07 Mon Sep 17 00:00:00 2001 From: 8530 <8530@vm-131.vsi-corp.com> Date: Tue, 10 May 2016 13:35:19 -0400 Subject: [PATCH 0064/1644] fix issue with / for shared memory key lookup CF-1251 --- .../logging/RH_SyncRollingAppender.cpp | 14 ++++++++++---- .../framework/logging/RH_SyncRollingAppender.h | 3 +++ .../testing/loggers/syncappender/.gitignore | 3 +++ .../testing/loggers/syncappender/cleanmem.cpp | 9 ++++++++- .../loggers/syncappender/log4j.appender | 1 - .../loggers/syncappender/test_suites.cpp | 18 ++++++++++++++++++ .../testing/loggers/syncappender/test_suites.h | 2 ++ .../src/testing/sdr/logcfg/log4j.sync_appender | 2 +- 8 files changed, 45 insertions(+), 7 deletions(-) diff --git a/redhawk/src/base/framework/logging/RH_SyncRollingAppender.cpp b/redhawk/src/base/framework/logging/RH_SyncRollingAppender.cpp index f6ab8c25f..2bc955049 100644 --- a/redhawk/src/base/framework/logging/RH_SyncRollingAppender.cpp +++ b/redhawk/src/base/framework/logging/RH_SyncRollingAppender.cpp @@ -32,7 +32,7 @@ #include #include - +#include #include #include #include @@ -115,7 +115,8 @@ RH_SyncRollingAppender::~RH_SyncRollingAppender() { if ( cleanup ) { _LL_DEBUG( "RH_SyncRollingAppender::DTPR clean up sharedg memory for: <" << sync_ctx->fname << "> " << pid << "\n" ); // clean up shared memory opbject - ipc::shared_memory_object::remove(sync_ctx->fname); + std::string fname=_clean_fname(sync_ctx->fname); + ipc::shared_memory_object::remove(fname.c_str()); } else { _LL_WARN( "RH_SyncRollingAppender: LEAVING SHARED MEMORY KEY <" << sync_ctx->fname << "> " << pid << "\n" ); @@ -125,16 +126,21 @@ RH_SyncRollingAppender::~RH_SyncRollingAppender() { _LL_DEBUG( "RH_SyncRollingAppender::DTOR END " << pid ); } +std::string RH_SyncRollingAppender::_clean_fname( const std::string &fname ) { + return boost::replace_all_copy( fname, "/", "-" ); +} + int RH_SyncRollingAppender::_get_mem( const std::string &fname) { int retval=0; created = false; + std::string clean_fname =_clean_fname(fname); // use the file name as the key for the shared memory segment... try { ipc::shared_memory_object shm_obj (ipc::create_only, //only create - fname.c_str(), //name + clean_fname.c_str(), //name ipc::read_write //read-write mode ); @@ -150,7 +156,7 @@ int RH_SyncRollingAppender::_get_mem( const std::string &fname) { _LL_DEBUG( "RH_SyncRollingAppender::get_mem Attach to Existing <" << fname << ">" ); ipc::shared_memory_object shm_obj (ipc::open_only, //only create - fname.c_str(), //name + clean_fname.c_str(), //name ipc::read_write //read-write mode ); diff --git a/redhawk/src/base/framework/logging/RH_SyncRollingAppender.h b/redhawk/src/base/framework/logging/RH_SyncRollingAppender.h index e56dc04dd..546bd4284 100644 --- a/redhawk/src/base/framework/logging/RH_SyncRollingAppender.h +++ b/redhawk/src/base/framework/logging/RH_SyncRollingAppender.h @@ -89,6 +89,9 @@ namespace log4cxx int _get_mem( const std::string &fname ); + // remove special characters from filename for shared memory context + std::string _clean_fname( const std::string &fname ); + // prevent copy and assignment statements RH_SyncRollingAppender(const RH_SyncRollingAppender&); RH_SyncRollingAppender& operator=(const RH_SyncRollingAppender&); diff --git a/redhawk/src/testing/loggers/syncappender/.gitignore b/redhawk/src/testing/loggers/syncappender/.gitignore index 017c963c3..c2b1cdd8d 100644 --- a/redhawk/src/testing/loggers/syncappender/.gitignore +++ b/redhawk/src/testing/loggers/syncappender/.gitignore @@ -3,3 +3,6 @@ Makefile.in Makefile configure config.* +appender_test +proc_log +cleanmem diff --git a/redhawk/src/testing/loggers/syncappender/cleanmem.cpp b/redhawk/src/testing/loggers/syncappender/cleanmem.cpp index eaa3bcba7..65080136e 100644 --- a/redhawk/src/testing/loggers/syncappender/cleanmem.cpp +++ b/redhawk/src/testing/loggers/syncappender/cleanmem.cpp @@ -2,6 +2,12 @@ #include #include #include +#include + + +std::string clean_fname( const std::string &fname ) { + return boost::replace_all_copy( fname, "/", "-" ); +} int main (int argc, char **argv ) { @@ -14,7 +20,8 @@ int main (int argc, char **argv ) using namespace boost::interprocess; try{ //Erase previous shared memory - shared_memory_object::remove(argv[1]); + std::string fname = clean_fname(argv[1]); + shared_memory_object::remove(fname.c_str()); } catch(interprocess_exception &ex){ diff --git a/redhawk/src/testing/loggers/syncappender/log4j.appender b/redhawk/src/testing/loggers/syncappender/log4j.appender index b055cad6f..a27ec5183 100644 --- a/redhawk/src/testing/loggers/syncappender/log4j.appender +++ b/redhawk/src/testing/loggers/syncappender/log4j.appender @@ -30,6 +30,5 @@ log4j.appender.mp.File=MP_RedhawkTest log4j.appender.mp.Cleanup=False log4j.appender.mp.layout=org.apache.log4j.PatternLayout log4j.appender.mp.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c:%L - %m%n - diff --git a/redhawk/src/testing/loggers/syncappender/test_suites.cpp b/redhawk/src/testing/loggers/syncappender/test_suites.cpp index 02fac2a8b..ad5fb6a6e 100644 --- a/redhawk/src/testing/loggers/syncappender/test_suites.cpp +++ b/redhawk/src/testing/loggers/syncappender/test_suites.cpp @@ -183,6 +183,8 @@ test_suite_three::tearDown() boost::filesystem::path dir("./logs"); boost::filesystem::remove_all(dir); + boost::filesystem::path d2("./tmp"); + boost::filesystem::remove_all(d2); } @@ -220,3 +222,19 @@ test_suite_three::test_cleanmem_missing() } + + +void +test_suite_three::test_cleanmem_path() +{ + LOG4CXX_INFO(logger, "RH_SyncRollingAppender - BEGIN "); + + // Set up a simple configuration that logs on the console. + log4cxx::PropertyConfigurator::configure("log4j.appender2" ); + + int ret=system("./cleanmem tmp/MP_RedhawkTest"); + + CPPUNIT_ASSERT_EQUAL( ret, 0); + + +} diff --git a/redhawk/src/testing/loggers/syncappender/test_suites.h b/redhawk/src/testing/loggers/syncappender/test_suites.h index c586c05ef..8cf31ff81 100644 --- a/redhawk/src/testing/loggers/syncappender/test_suites.h +++ b/redhawk/src/testing/loggers/syncappender/test_suites.h @@ -45,6 +45,7 @@ class test_suite_three : public CppUnit::TestFixture CPPUNIT_TEST_SUITE( test_suite_three ); CPPUNIT_TEST( test_cleanmem ); CPPUNIT_TEST_EXCEPTION( test_cleanmem_missing, boost::interprocess::interprocess_exception ); + CPPUNIT_TEST( test_cleanmem_path ); CPPUNIT_TEST_SUITE_END(); public: @@ -52,6 +53,7 @@ class test_suite_three : public CppUnit::TestFixture void tearDown(); void test_cleanmem(); + void test_cleanmem_path(); void test_cleanmem_missing(); log4cxx::LoggerPtr logger; diff --git a/redhawk/src/testing/sdr/logcfg/log4j.sync_appender b/redhawk/src/testing/sdr/logcfg/log4j.sync_appender index 352a629b1..9067aaca4 100644 --- a/redhawk/src/testing/sdr/logcfg/log4j.sync_appender +++ b/redhawk/src/testing/sdr/logcfg/log4j.sync_appender @@ -17,7 +17,7 @@ log4j.appender.mp.Retries=2 log4j.appender.mp.WaitOnLock=30 log4j.appender.mp.MaxFileSize=5MB log4j.appender.mp.MaxBackupIndex=10 -log4j.appender.mp.File=/tmp/MP_RedhawkTest +log4j.appender.mp.File=MP_RedhawkTest log4j.appender.mp.Cleanup=False log4j.appender.mp.layout=org.apache.log4j.PatternLayout log4j.appender.mp.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c:%L - %m%n From 7bd08ffc741af28baeca9c2e22c86c44dbc000f9 Mon Sep 17 00:00:00 2001 From: 8530 <8530@vm-131.vsi-corp.com> Date: Tue, 10 May 2016 13:35:38 -0400 Subject: [PATCH 0065/1644] fix issue with / for shared memory key lookup CF-1251 --- .../loggers/syncappender/log4j.appender2 | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 redhawk/src/testing/loggers/syncappender/log4j.appender2 diff --git a/redhawk/src/testing/loggers/syncappender/log4j.appender2 b/redhawk/src/testing/loggers/syncappender/log4j.appender2 new file mode 100644 index 000000000..9c78bb669 --- /dev/null +++ b/redhawk/src/testing/loggers/syncappender/log4j.appender2 @@ -0,0 +1,34 @@ + + + +#log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n + +log4j.rootLogger=ALL,stdout, mp + +# Direct log messages to stdout +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.Target=System.out +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c:%L - %m%n + +# Direct log messages to stdout +log4j.appender.pse=org.ossie.logging.RH_LogEventAppender +log4j.appender.pse.name_context=TEST_APPENDER +log4j.appender.pse.event_channel=TEST_EVT_CH1 +log4j.appender.pse.producer_id=PRODUCER1 +log4j.appender.pse.producer_name=THE BIG CHEESE +log4j.appender.pse.layout=org.apache.log4j.PatternLayout +log4j.appender.pse.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c:%L - %m%n + +# Direct log messages to stdout +log4j.appender.mp=org.ossie.logging.RH_SyncRollingAppender +log4j.appender.mp.Retries=2 +log4j.appender.mp.WaitOnLock=30 +log4j.appender.mp.MaxFileSize=5MB +log4j.appender.mp.MaxBackupIndex=10 +log4j.appender.mp.File=tmp/MP_RedhawkTest +log4j.appender.mp.Cleanup=False +log4j.appender.mp.layout=org.apache.log4j.PatternLayout +log4j.appender.mp.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c:%L - %m%n + + From 14771ad1be9d83f2b69b8f252a64d33022237f42 Mon Sep 17 00:00:00 2001 From: 8530 <8530@vm-131.vsi-corp.com> Date: Tue, 10 May 2016 15:09:58 -0400 Subject: [PATCH 0066/1644] fix el7 compilation issue --- redhawk/src/base/framework/logging/RH_SyncRollingAppender.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/redhawk/src/base/framework/logging/RH_SyncRollingAppender.cpp b/redhawk/src/base/framework/logging/RH_SyncRollingAppender.cpp index 2bc955049..ddaee1b1f 100644 --- a/redhawk/src/base/framework/logging/RH_SyncRollingAppender.cpp +++ b/redhawk/src/base/framework/logging/RH_SyncRollingAppender.cpp @@ -218,7 +218,7 @@ void RH_SyncRollingAppender::subAppend(const spi::LoggingEventPtr& event, log4cx int cretries = retries; do { _LL_DEBUG( "RH_SyncRollingAppender::subAppend Waiting to lock mutex."); - boost::posix_time::ptime::ptime abs_time = boost::posix_time::microsec_clock::universal_time()+boost::posix_time::millisec(wait_on_lock); + boost::posix_time::ptime abs_time = boost::posix_time::microsec_clock::universal_time()+boost::posix_time::millisec(wait_on_lock); try { _IPC_ScopedFLock lock(flock,abs_time); From 9a1462035e2e72146d9d87c8baa68ca845f27a96 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Thu, 12 May 2016 16:54:39 -0400 Subject: [PATCH 0067/1644] Ref CF-1493. Fixes related to bulkio data management when it is chunked and is also frame data --- .../python/ossie/utils/bulkio/bulkio_data_helpers.py | 6 +++--- .../src/base/framework/python/ossie/utils/sandbox/base.py | 4 ++-- .../src/base/framework/python/ossie/utils/sb/domainless.py | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/bulkio/bulkio_data_helpers.py b/redhawk/src/base/framework/python/ossie/utils/bulkio/bulkio_data_helpers.py index 5dbf6cd64..63e67b898 100644 --- a/redhawk/src/base/framework/python/ossie/utils/bulkio/bulkio_data_helpers.py +++ b/redhawk/src/base/framework/python/ossie/utils/bulkio/bulkio_data_helpers.py @@ -291,11 +291,11 @@ def retrieveData(self, length=None): # No length specified; get all of the data. length = len(self.data) - # have not received any data yet (and I need a minimum amount) - if self.sri == None and len(self.data) == 0 and length != 0: + # have not received any data yet + if self.sri == None: self.port_cond.wait() - if self.sri != None and self.sri.subsize != 0: + if self.sri.subsize != 0: frameLength = self.sri.subsize if not self.sri.mode else 2*self.sri.subsize if float(length)/frameLength != length/frameLength: print 'The requested length divided by the subsize ('+str(length)+'/'+str(self.sri.subsize)+') is not a whole number. Cannot return framed data' diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/base.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/base.py index f4c70b0fb..a08ebedd2 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/base.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/base.py @@ -351,8 +351,8 @@ def _breakConnections(self, target): manager = ConnectionManager.instance() for identifier, (uses, provides) in manager.getConnections().items(): if uses.hasComponent(target) or provides.hasComponent(target): - manager.breakConnection(identifier) - manager.unregisterConnection(identifier) + manager.breakConnection(identifier, uses) + manager.unregisterConnection(identifier, uses) class SandboxLauncher(object): diff --git a/redhawk/src/base/framework/python/ossie/utils/sb/domainless.py b/redhawk/src/base/framework/python/ossie/utils/sb/domainless.py index 8d9cffea5..30e22b3d8 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sb/domainless.py +++ b/redhawk/src/base/framework/python/ossie/utils/sb/domainless.py @@ -1192,11 +1192,11 @@ def launch(descriptor, instanceName=None, refid=None, impl=None, # Combine the overrides from configure and execparams into a single # properties dictionary, with the latter having precedence properties = {} - if isinstance(configure, dict): + if isinstance(configure, dict) and len(configure) != 0: warnings.warn("'configure' argument is deprecated for property overrides; use 'properties'.", DeprecationWarning) properties.update(configure) configure = True - if execparams: + if execparams and len(execparams) != 0: warnings.warn("'execparams' argument is deprecated; use 'properties'.", DeprecationWarning) properties.update(execparams) From ea49b1d07e7f27ad78b6a0b2bed1654985260250 Mon Sep 17 00:00:00 2001 From: Ryan Bauman Date: Tue, 16 Aug 2016 14:48:32 +0000 Subject: [PATCH 0068/1644] RELENG-433 - update version on development branch --- redhawk/src/base/framework/python/ossie/version.py | 2 +- redhawk/src/configure.ac | 2 +- redhawk/src/releng/redhawk.spec | 4 ++-- redhawk/src/testing/setup.py | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/redhawk/src/base/framework/python/ossie/version.py b/redhawk/src/base/framework/python/ossie/version.py index cd3c4f247..93b931f11 100644 --- a/redhawk/src/base/framework/python/ossie/version.py +++ b/redhawk/src/base/framework/python/ossie/version.py @@ -18,4 +18,4 @@ # along with this program. If not, see http://www.gnu.org/licenses/. # -__version__='2.0.4' +__version__='2.1.0' diff --git a/redhawk/src/configure.ac b/redhawk/src/configure.ac index 1df7b17a4..be6e712f6 100644 --- a/redhawk/src/configure.ac +++ b/redhawk/src/configure.ac @@ -19,7 +19,7 @@ # dnl Update this version number immedately after a release -AC_INIT([ossie],[2.0.4]) +AC_INIT([ossie],[2.1.0]) #AM_INIT_AUTOMAKE(nostdinc) # allows filenames over 99 characters long during dist AM_INIT_AUTOMAKE([1.9 tar-pax subdir-objects]) diff --git a/redhawk/src/releng/redhawk.spec b/redhawk/src/releng/redhawk.spec index 69c3a362e..0eb90bcb3 100644 --- a/redhawk/src/releng/redhawk.spec +++ b/redhawk/src/releng/redhawk.spec @@ -26,8 +26,8 @@ Prefix: %{_sdrroot} Prefix: %{_sysconfdir} Name: redhawk -Version: 2.0.1 -Release: 2%{?dist} +Version: 2.1.0 +Release: 1%{?dist} Summary: REDHAWK is a Software Defined Radio framework Group: Applications/Engineering diff --git a/redhawk/src/testing/setup.py b/redhawk/src/testing/setup.py index 5aaa0f622..b0ca90547 100644 --- a/redhawk/src/testing/setup.py +++ b/redhawk/src/testing/setup.py @@ -47,7 +47,7 @@ '_unitTestHelpers.runtestHelpers', '_unitTestHelpers.buildconfig'] -version='2.0.4' +version='2.1.0' setup( name='unitTestHelper', From 7b61b97babf5e7435542c9ec886963a302ca7930 Mon Sep 17 00:00:00 2001 From: 8530 <8530@vm-131.vsi-corp.com> Date: Thu, 8 Sep 2016 11:41:26 -0400 Subject: [PATCH 0069/1644] fix merge issues with develop-2.0 --- redhawk/src/base/framework/python/ossie/utils/sandbox/model.py | 1 + redhawk/src/testing/tests/test_13_TestSB.py | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/model.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/model.py index 5b9d5d750..95bd4227b 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/model.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/model.py @@ -32,6 +32,7 @@ def __init__(self, sandbox): def _kick(self): self.ref = self._launcher.launch(self) + self._pid = self._process.pid() self._launcher.setup(self) self._register() diff --git a/redhawk/src/testing/tests/test_13_TestSB.py b/redhawk/src/testing/tests/test_13_TestSB.py index 6e4eade71..ca9015638 100644 --- a/redhawk/src/testing/tests/test_13_TestSB.py +++ b/redhawk/src/testing/tests/test_13_TestSB.py @@ -118,7 +118,8 @@ def test_softpkgDepDouble(self): def test_pid(self): a = sb.launch('comp_src') - status,output = commands.getstatusoutput('ps -ww -f | grep comp_src') + #status,output = commands.getstatusoutput('ps -ef | grep comp_src | grep -v grep ') + status,output = commands.getstatusoutput('ps -ww -f | grep comp_src ') lines = output.split('\n') for line in lines: if 'IOR' in line: From f6d195d7653907e80eae5a67bf9b1b6d53f97569 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 8 Sep 2016 17:53:45 -0400 Subject: [PATCH 0070/1644] Only set a pid on the component for local components --- redhawk/src/base/framework/python/ossie/utils/sandbox/local.py | 1 + redhawk/src/base/framework/python/ossie/utils/sandbox/model.py | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py index fd4ef8740..7ab3581f6 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py @@ -201,6 +201,7 @@ def terminate_callback(pid, status): # Store the process on the component proxy. comp._process = process + comp._pid = process.pid() # Return the now-resolved CORBA reference. return self.getReference(comp) diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/model.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/model.py index 95bd4227b..5b9d5d750 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/model.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/model.py @@ -32,7 +32,6 @@ def __init__(self, sandbox): def _kick(self): self.ref = self._launcher.launch(self) - self._pid = self._process.pid() self._launcher.setup(self) self._register() From 8bcb01ff46aed66c882184c55df03dbda97bc8bb Mon Sep 17 00:00:00 2001 From: Ryan Bauman Date: Wed, 12 Oct 2016 14:32:26 -0400 Subject: [PATCH 0071/1644] RELENG-459 - reconcile redhawk differences --- .../ossie/utils/bulkio/bulkio_data_helpers.py | 6 +-- .../python/ossie/utils/sandbox/base.py | 8 +++- .../python/ossie/utils/sandbox/ide.py | 22 ++++++--- .../python/ossie/utils/sandbox/local.py | 46 ++++++++++++------- .../python/ossie/utils/sandbox/model.py | 19 +++++++- .../python/ossie/utils/sb/domainless.py | 3 +- redhawk/src/configure.ac | 2 +- redhawk/src/releng/redhawk.spec | 27 +++-------- .../tests/test_08_PropertyChangeListener.py | 17 ++----- 9 files changed, 88 insertions(+), 62 deletions(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/bulkio/bulkio_data_helpers.py b/redhawk/src/base/framework/python/ossie/utils/bulkio/bulkio_data_helpers.py index 63e67b898..5dbf6cd64 100644 --- a/redhawk/src/base/framework/python/ossie/utils/bulkio/bulkio_data_helpers.py +++ b/redhawk/src/base/framework/python/ossie/utils/bulkio/bulkio_data_helpers.py @@ -291,11 +291,11 @@ def retrieveData(self, length=None): # No length specified; get all of the data. length = len(self.data) - # have not received any data yet - if self.sri == None: + # have not received any data yet (and I need a minimum amount) + if self.sri == None and len(self.data) == 0 and length != 0: self.port_cond.wait() - if self.sri.subsize != 0: + if self.sri != None and self.sri.subsize != 0: frameLength = self.sri.subsize if not self.sri.mode else 2*self.sri.subsize if float(length)/frameLength != length/frameLength: print 'The requested length divided by the subsize ('+str(length)+'/'+str(self.sri.subsize)+') is not a whole number. Cannot return framed data' diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/base.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/base.py index a08ebedd2..a300b1829 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/base.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/base.py @@ -273,6 +273,12 @@ def shutdown(self): channel.destroy() self._eventChannels = {} + def catalog(self, searchPath=None, objType="components"): + files = {} + for profile in self.getSdrRoot().readProfiles(objType, searchPath): + files[profile['name']] = profile['profile'] + return files + def _sortOverrides(self, prf, properties): if not prf: # No PRF file, assume all properties are execparams. @@ -349,7 +355,7 @@ def _getInitializationStages(self, prf): def _breakConnections(self, target): # Break any connections involving this object. manager = ConnectionManager.instance() - for identifier, (uses, provides) in manager.getConnections().items(): + for _identifier, (identifier, uses, provides) in manager.getConnections().items(): if uses.hasComponent(target) or provides.hasComponent(target): manager.breakConnection(identifier, uses) manager.unregisterConnection(identifier, uses) diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/ide.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/ide.py index 1d562f2a8..5fe474af2 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/ide.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/ide.py @@ -82,14 +82,24 @@ def getLocation(self): class IDELauncher(SandboxLauncher): - def __init__(self, execparams): + def __init__(self, execparams, initProps, configProps): self._execparams = execparams + self._initProps = initProps + self._configProps = configProps def launch(self, comp): - execparams = comp._getExecparams() - execparams.update(self._execparams) + # Pack the execparams into an array of string-valued properties + properties = [CF.DataType(k, to_any(str(v))) for k, v in self._execparams.iteritems()] + # Pack the remaining props by having the component do the conversion + properties.extend(comp._itemToDataType(k,v) for k,v in self._initProps.iteritems()) + properties.extend(comp._itemToDataType(k,v) for k,v in self._configProps.iteritems()) + + # Tell the IDE to launch a specific implementation, if given + if comp._impl is not None: + properties.append(CF.DataType('__implementationID', to_any(comp._impl))) + + ref = comp._sandbox._createResource(comp._profile, comp._instanceName, properties) - ref = comp._sandbox._createResource(comp._profile, comp._instanceName, execparams, comp._impl) # The IDE sandbox API only allows us to specify the instance name, not # the identifier, so update by querying the component itself comp._refid = ref._get_identifier() @@ -141,10 +151,10 @@ def _checkInstanceId(self, refid, componentType='resource'): def _createLauncher(self, comptype, execparams, initProps, initialize, configProps, debugger, window, timeout): if comptype in ('resource', 'device', 'loadabledevice', 'executabledevice'): - return IDELauncher(execparams) + return IDELauncher(execparams, initProps, configProps) return None - def _createResource(self, profile, name, execparams={}, impl=None): + def _createResource(self, profile, name, qualifiers=[]): log.debug("Creating resource '%s' with profile '%s'", name, profile) rescFactory = self.__ide.getResourceFactoryByProfile(profile) diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py index 7ab3581f6..1dfe9e5e2 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py @@ -24,6 +24,7 @@ import time import copy import pydoc +import warnings from omniORB import CORBA @@ -62,22 +63,21 @@ def _readFile(self, filename): path = open(self._sdrPath(filename), 'r') return path.read() - def getProfiles(self, objType=None): + def _getSearchPaths(self, objTypes): + paths = [] + if 'components' in objTypes: + paths.append('dom/components') + if 'devices' in objTypes: + paths.append('dev/devices') + if 'services' in objTypes: + paths.append('dev/services') + return [self._sdrPath(p) for p in paths] + + def _getAvailableProfiles(self, path): files = [] - searchPath = [] - if objType == "component" or objType is None: - searchPath.append('dom/components') - if objType == "device" or objType is None: - searchPath.append('dev/devices') - if objType == "service" or objType is None: - searchPath.append('dev/services') - if not searchPath: - raise ValueError, "'%s' is not a valid object Type" % objType - for path in searchPath: - path = self._sdrPath(path) - for root, dirs, fnames in os.walk(path): - for filename in fnmatch.filter(fnames, '*.spd.xml'): - files.append(os.path.join(root, filename)) + for root, dirs, fnames in os.walk(path): + for filename in fnmatch.filter(fnames, '*.spd.xml'): + files.append(os.path.join(root, filename)) return files def _getObjectTypes(self, objType): @@ -204,7 +204,21 @@ def terminate_callback(pid, status): comp._pid = process.pid() # Return the now-resolved CORBA reference. - return self.getReference(comp) + ref = self.getReference(comp) + try: + # Occasionally, when a lot of components are launched from the + # sandbox, omniORB may have a cached connection where the other end + # has terminated (this is particularly a problem with Java, because + # the Sun ORB never closes connections on shutdown). If the new + # component just happens to have the same TCP/IP address and port, + # the first time we try to reach the component, it will get a + # CORBA.COMM_FAILURE exception even though the reference is valid. + # In this case, a call to _non_existent() should cause omniORB to + # clean up the stale socket, and subsequent calls behave normally. + comp.ref._non_existent() + except: + pass + return ref def setup(self, comp): # Initialize the component unless asked not to. diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/model.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/model.py index 5b9d5d750..6346b0208 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/model.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/model.py @@ -54,7 +54,7 @@ def __init__(self, sandbox, profile, spd, scd, prf, instanceName, refid, impl): self._componentName = spd.get_name() self.__ports = None - + self._msgSupplierHelper = None self._parseComponentXMLFiles() self._buildAPI() @@ -128,6 +128,23 @@ def api(self): PortSupplier.api(self) PropertySet.api(self) + def sendMessage(self, msg, msgId=None, msgPort=None, restrict=True ): + """ + send a message out a component's message event port + + msg : dictionary of information to send or an any object + msgId : select a specific message structure property from the component, if None will + choose first available message property structure for the component + msgPort : select a specified message event port to use, if None will try to autoselect + restrict : if True, will restrict msgId to only those message ids defined by the component + if False, will allow for ad-hoc message to be sent + """ + if self._msgSupplierHelper == None: + import ossie.utils + self._msgSupplierHelper = ossie.utils.sb.io_helpers.MsgSupplierHelper(self) + if self.ref and self.ref._get_started() == True and self._msgSupplierHelper: + return self._msgSupplierHelper.sendMessage( msg, msgId, msgPort, restrict ) + return False class SandboxComponent(SandboxResource, Resource): def __init__(self, *args, **kwargs): diff --git a/redhawk/src/base/framework/python/ossie/utils/sb/domainless.py b/redhawk/src/base/framework/python/ossie/utils/sb/domainless.py index 30e22b3d8..0628024f3 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sb/domainless.py +++ b/redhawk/src/base/framework/python/ossie/utils/sb/domainless.py @@ -722,8 +722,7 @@ def loadSADFile(filename, props={}): simple_exec_vals[container.id] = container.value try: # NB: Explicitly request no configure call is made on the component - newComponent = launch(componentName, instanceName, instanceID, configure=False, - properties=simple_exec_vals, objType="component") + newComponent = launch(componentName, instanceName, instanceID, configure=False, properties=simple_exec_vals, objType="components") launchedComponents.append(newComponent) except Exception as e: msg = "Failed to launch component '%s', REASON: %s" % (instanceName, str(e)) diff --git a/redhawk/src/configure.ac b/redhawk/src/configure.ac index be6e712f6..712bd16ce 100644 --- a/redhawk/src/configure.ac +++ b/redhawk/src/configure.ac @@ -168,7 +168,7 @@ if test "x$enable_java" != "xno"; then RH_JAVA_HOME # Minimum Java version - java_source_version=1.6 + java_source_version=1.8 # Locate tools we need based on JAVA_HOME RH_PROG_JAVAC([$java_source_version]) diff --git a/redhawk/src/releng/redhawk.spec b/redhawk/src/releng/redhawk.spec index 0eb90bcb3..1b7824d6d 100644 --- a/redhawk/src/releng/redhawk.spec +++ b/redhawk/src/releng/redhawk.spec @@ -39,29 +39,18 @@ Vendor: REDHAWK %define __arch_install_post %{nil} Requires: util-linux-ng - -%if 0%{?rhel} >= 7 || 0%{?fedora} >= 17 -Requires: java >= 1.7 -%else -Requires: java7 >= 1.7 -%endif - +Requires: java >= 1:1.8.0 Requires: python Requires: numpy Requires: python-omniORB >= 3.0 Requires: omniORB-devel >= 4.1.0 Requires: binutils + BuildRequires: libuuid-devel BuildRequires: boost-devel >= 1.41 BuildRequires: autoconf automake libtool BuildRequires: expat-devel - -%if 0%{?rhel} >= 7 || 0%{?fedora} >= 17 -BuildRequires: java-devel >= 1.7 -%else -BuildRequires: java7-devel >= 1.7 -%endif - +BuildRequires: java-1.8.0-openjdk-devel BuildRequires: python-devel >= 2.4 BuildRequires: log4cxx-devel >= 0.10 BuildRequires: omniORB-devel >= 4.1.0 @@ -129,12 +118,7 @@ Requires: omniORBpy-devel >= 3.0 # Languages Requires: gcc-c++ Requires: python-devel >= 2.4 - -%if 0%{?rhel} >= 7 || 0%{?fedora} >= 17 -Requires: java-devel >= 1.7 -%else -Requires: java7-devel >= 1.7 -%endif +Requires: java-1.8.0-openjdk-devel %description devel This package ensures that all requirements for REDHAWK development are installed. It also provides a useful development utilities. @@ -273,6 +257,9 @@ fi %changelog +* Fri Sep 16 2016 - 2.0.3-1 +- Update for dependency on Java 8 + * Wed Sep 9 2015 - 2.0.0-2 - Add qt-tools package - Remove el5 support diff --git a/redhawk/src/testing/tests/test_08_PropertyChangeListener.py b/redhawk/src/testing/tests/test_08_PropertyChangeListener.py index f932be7e9..a135b457a 100644 --- a/redhawk/src/testing/tests/test_08_PropertyChangeListener.py +++ b/redhawk/src/testing/tests/test_08_PropertyChangeListener.py @@ -33,7 +33,6 @@ from ossie.utils import redhawk from ossie.events import Subscriber -java_support = scatest.hasJavaSupport() execDeviceNode = "/nodes/test_GPP_node/DeviceManager.dcd.xml" class Consumer_i(CosEventComm__POA.PushConsumer): @@ -217,6 +216,7 @@ def test_PropertyChangeListener_PYTHON(self): app.releaseObject() self._app=None + @scatest.requireJava def test_PropertyChangeListener_JAVA(self): self.localEvent = threading.Event() @@ -407,10 +407,7 @@ def test_PropertyChangeListener_EC_CPP(self): self._devBooter, self._devMgr = self.launchDeviceManager(execDeviceNode, self._domMgr) self.assertNotEqual(self._devBooter, None) - if java_support: - self._domMgr.installApplication("/waveforms/PropertyChangeListener/PropertyChangeListener.sad.xml") - else: - self._domMgr.installApplication("/waveforms/PropertyChangeListenerNoJava/PropertyChangeListenerNoJava.sad.xml") + self._domMgr.installApplication("/waveforms/PropertyChangeListenerNoJava/PropertyChangeListenerNoJava.sad.xml") appFact = self._domMgr._get_applicationFactories()[0] self.assertNotEqual(appFact, None) app = appFact.create(appFact._get_name(), [], []) @@ -464,10 +461,7 @@ def test_PropertyChangeListener_EC_PYTHON(self): self._devBooter, self._devMgr = self.launchDeviceManager(execDeviceNode, self._domMgr) self.assertNotEqual(self._devBooter, None) - if java_support: - self._domMgr.installApplication("/waveforms/PropertyChangeListener/PropertyChangeListener.sad.xml") - else: - self._domMgr.installApplication("/waveforms/PropertyChangeListenerNoJava/PropertyChangeListenerNoJava.sad.xml") + self._domMgr.installApplication("/waveforms/PropertyChangeListenerNoJava/PropertyChangeListenerNoJava.sad.xml") appFact = self._domMgr._get_applicationFactories()[0] self.assertNotEqual(appFact, None) app = appFact.create(appFact._get_name(), [], []) @@ -515,9 +509,8 @@ def test_PropertyChangeListener_EC_PYTHON(self): app.releaseObject() self._app=None + @scatest.requireJava def test_PropertyChangeListener_EC_JAVA(self): - if not java_support: - return self.localEvent = threading.Event() self.eventFlag = False @@ -577,7 +570,7 @@ def test_PropertyChangeListener_EC_APP(self): self._devBooter, self._devMgr = self.launchDeviceManager(execDeviceNode, self._domMgr) self.assertNotEqual(self._devBooter, None) - self._domMgr.installApplication("/waveforms/PropertyChangeListener/PropertyChangeListener.sad.xml") + self._domMgr.installApplication("/waveforms/PropertyChangeListenerNoJava/PropertyChangeListenerNoJava.sad.xml") appFact = self._domMgr._get_applicationFactories()[0] self.assertNotEqual(appFact, None) app = appFact.create(appFact._get_name(), [], []) From 66a970cda3d7aa48d110370328ca397d3e2d44ac Mon Sep 17 00:00:00 2001 From: Ryan Bauman Date: Wed, 12 Oct 2016 14:34:20 -0400 Subject: [PATCH 0072/1644] RELENG-459 - reconcile codgen differences --- redhawk-codegen/setup.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/redhawk-codegen/setup.py b/redhawk-codegen/setup.py index 0a2b7d75b..271d5d6b1 100644 --- a/redhawk-codegen/setup.py +++ b/redhawk-codegen/setup.py @@ -43,12 +43,10 @@ def byte_compile(self, files): for arg in sys.argv: if '--home' in arg: homeSys = True - if '--old-and-unmanageable' in arg: - useEgg = True - + if not homeSys and ossiehome != None and not buildArg: sys.argv.append('--home='+ossiehome) -if not useEgg and not buildArg: +if not ('--old-and-unmanageable' in sys.argv) and not buildArg: sys.argv.append('--old-and-unmanageable') setup(name='redhawk-codegen', From 940c4320f51bad86aa22b6d9b7173ced30117a54 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 24 Jun 2016 09:28:45 -0400 Subject: [PATCH 0073/1644] Use the core's ExecutorService, but also bring it into the burstio namespace to avoid API breakage (though it's highly unlikely anyone is using it as such) --- .../src/cpp/include/burstio/ExecutorService.h | 133 +----------------- .../src/cpp/include/burstio/OutPortDecl.h | 5 +- 2 files changed, 6 insertions(+), 132 deletions(-) diff --git a/burstioInterfaces/src/cpp/include/burstio/ExecutorService.h b/burstioInterfaces/src/cpp/include/burstio/ExecutorService.h index fbe87f0e5..abcc3aeb5 100644 --- a/burstioInterfaces/src/cpp/include/burstio/ExecutorService.h +++ b/burstioInterfaces/src/cpp/include/burstio/ExecutorService.h @@ -20,138 +20,11 @@ #ifndef BURSTIO_EXECUTORSERVICE_H #define BURSTIO_EXECUTORSERVICE_H -#include - -#include -#include -#include +#include namespace burstio { - - class ExecutorService { - public: - ExecutorService() : - thread_(0), - running_(false) - { - } - - void start () - { - boost::mutex::scoped_lock lock(mutex_); - if (running_) { - return; - } - - running_ = true; - thread_ = new boost::thread(&ExecutorService::run, this); - } - - void stop () - { - boost::thread* old_thread = 0; - { - boost::mutex::scoped_lock lock(mutex_); - running_ = false; - old_thread = thread_; - thread_ = 0; - cond_.notify_all(); - } - if (old_thread) { - old_thread->join(); - delete old_thread; - } - } - - template - void execute (F func) - { - insert_sorted(func); - } - - template - void execute (F func, A1 arg1) - { - insert_sorted(boost::bind(func, arg1)); - } - - template - void schedule (boost::system_time when, F func) - { - insert_sorted(func, when); - } - - template - void schedule (boost::system_time when, F func, A1 arg1) - { - insert_sorted(boost::bind(func, arg1), when); - } - - void clear () - { - boost::mutex::scoped_lock lock(mutex_); - queue_.clear(); - cond_.notify_all(); - } - - private: - typedef boost::function func_type; - typedef std::pair task_type; - typedef std::list task_queue; - - void run () - { - boost::mutex::scoped_lock lock(mutex_); - while (running_) { - while (!queue_.empty()) { - // Start at the front of the queue every time--a task may - // have been added while the lock was released to service - // the last task - task_queue::iterator task = queue_.begin(); - if (task->first > boost::get_system_time()) { - // Head of queue is scheduled in the future - break; - } - - // Copy the task's function and remove it from the queue - func_type func = task->second; - queue_.erase(task); - - // Run task with the lock released - lock.unlock(); - func(); - lock.lock(); - } - - if (queue_.empty()) { - cond_.wait(lock); - } else { - boost::system_time when = queue_.front().first; - cond_.timed_wait(lock, when); - } - } - } - - void insert_sorted (func_type func, boost::system_time when=boost::get_system_time()) - { - boost::mutex::scoped_lock lock(mutex_); - task_queue::iterator pos = queue_.begin(); - while ((pos != queue_.end()) && (when > pos->first)) { - ++pos; - } - queue_.insert(pos, std::make_pair(when, func)); - cond_.notify_all(); - } - - - boost::mutex mutex_; - boost::condition_variable cond_; - - boost::thread* thread_; - task_queue queue_; - bool running_; - }; - + // Bring the core's ExecutorService into the burstio namespace + typedef redhawk::ExecutorService ExecutorService; } #endif // BURSTIO_EXECUTORSERVICE_H diff --git a/burstioInterfaces/src/cpp/include/burstio/OutPortDecl.h b/burstioInterfaces/src/cpp/include/burstio/OutPortDecl.h index 6b9d8edce..80662a66d 100644 --- a/burstioInterfaces/src/cpp/include/burstio/OutPortDecl.h +++ b/burstioInterfaces/src/cpp/include/burstio/OutPortDecl.h @@ -29,10 +29,11 @@ #include +#include + #include "UsesPort.h" #include "BurstStatistics.h" #include "PortTraits.h" -#include "ExecutorService.h" #include "utils.h" #include "debug.h" @@ -274,7 +275,7 @@ namespace burstio { RoutingModeType routingMode_; RouteTable routes_; - ExecutorService monitor_; + redhawk::ExecutorService monitor_; using super::updatingPortsLock; using super::connections_; From 1afdc8a5546a956f67e045a2d61e0fb1ccca8b70 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 24 Jun 2016 09:40:44 -0400 Subject: [PATCH 0074/1644] Minor cleanup; leverage time operators from BulkIO --- .../src/cpp/include/burstio/OutPortDecl.h | 2 +- .../src/cpp/include/burstio/utils.h | 4 +- burstioInterfaces/src/cpp/lib/OutPortImpl.h | 4 +- burstioInterfaces/src/cpp/lib/utils.cpp | 64 +++++++++---------- 4 files changed, 35 insertions(+), 39 deletions(-) diff --git a/burstioInterfaces/src/cpp/include/burstio/OutPortDecl.h b/burstioInterfaces/src/cpp/include/burstio/OutPortDecl.h index 80662a66d..7bd9c6e62 100644 --- a/burstioInterfaces/src/cpp/include/burstio/OutPortDecl.h +++ b/burstioInterfaces/src/cpp/include/burstio/OutPortDecl.h @@ -188,7 +188,7 @@ namespace burstio { // Support function for automatic component-managed stop. virtual void stopPort (); - std::string getRepid() const; + std::string getRepid() const; protected: class Queue : public OutputPolicy diff --git a/burstioInterfaces/src/cpp/include/burstio/utils.h b/burstioInterfaces/src/cpp/include/burstio/utils.h index 4a1a3e44a..cd505bd97 100644 --- a/burstioInterfaces/src/cpp/include/burstio/utils.h +++ b/burstioInterfaces/src/cpp/include/burstio/utils.h @@ -144,9 +144,7 @@ namespace burstio { double elapsed (const BULKIO::PrecisionUTCTime& begin, const BULKIO::PrecisionUTCTime& end=now()); - BURSTIO::BurstSRI createSRI ( const std::string &streamID, double xdelta); - - BURSTIO::BurstSRI createSRI ( const std::string &streamID); + BURSTIO::BurstSRI createSRI (const std::string& streamID, double xdelta=1.0); } } diff --git a/burstioInterfaces/src/cpp/lib/OutPortImpl.h b/burstioInterfaces/src/cpp/lib/OutPortImpl.h index a5126e628..aba8db5ee 100644 --- a/burstioInterfaces/src/cpp/lib/OutPortImpl.h +++ b/burstioInterfaces/src/cpp/lib/OutPortImpl.h @@ -310,10 +310,10 @@ namespace burstio { stop(); } - template + template std::string OutPort::getRepid () const { - return PortType::_PD_repoId;; + return PortType::_PD_repoId; } template diff --git a/burstioInterfaces/src/cpp/lib/utils.cpp b/burstioInterfaces/src/cpp/lib/utils.cpp index 91f14cc10..3e4b4f505 100644 --- a/burstioInterfaces/src/cpp/lib/utils.cpp +++ b/burstioInterfaces/src/cpp/lib/utils.cpp @@ -19,6 +19,8 @@ */ #include +#include + #include namespace burstio { @@ -38,42 +40,38 @@ namespace burstio { double elapsed (const BULKIO::PrecisionUTCTime& begin, const BULKIO::PrecisionUTCTime& end) { - return (end.twsec - begin.twsec) + (end.tfsec - begin.tfsec); + return end - begin; } - - BURSTIO::BurstSRI createSRI ( const std::string &streamID, double xdelta) { - BURSTIO::BurstSRI sri; - sri.hversion = 1; - sri.streamID = streamID.c_str(); - sri.id = ""; - sri.xdelta = xdelta; - sri.mode = (short)0; - sri.flags = (short)0; - sri.tau = 0.0; - sri.theta = 0.0f; - sri.gain = 0.0f; - sri.uwlength = (short)0; - sri.bursttype = (short)0; - sri.burstLength = 0; - sri.CHAN_RF = 0.0; - sri.baudestimate = 0.0f; - sri.carrieroffset = 0.0; - sri.SNR = 0.0; - sri.modulation = ""; - sri.baudrate = 0.0; - sri.fec = ""; - sri.fecrate = ""; - sri.randomizer = ""; - sri.overhead = ""; - sri.expectedStartOfBurstTime = burstio::utils::now(); - sri.keywords.length(0); - return sri; + BURSTIO::BurstSRI createSRI (const std::string& streamID, double xdelta) + { + BURSTIO::BurstSRI sri; + sri.hversion = 1; + sri.streamID = streamID.c_str(); + sri.id = ""; + sri.xdelta = xdelta; + sri.mode = (short)0; + sri.flags = (short)0; + sri.tau = 0.0; + sri.theta = 0.0f; + sri.gain = 0.0f; + sri.uwlength = (short)0; + sri.bursttype = (short)0; + sri.burstLength = 0; + sri.CHAN_RF = 0.0; + sri.baudestimate = 0.0f; + sri.carrieroffset = 0.0; + sri.SNR = 0.0; + sri.modulation = ""; + sri.baudrate = 0.0; + sri.fec = ""; + sri.fecrate = ""; + sri.randomizer = ""; + sri.overhead = ""; + sri.expectedStartOfBurstTime = burstio::utils::now(); + sri.keywords.length(0); + return sri; } - BURSTIO::BurstSRI createSRI ( const std::string &streamID ) { - return createSRI( streamID, 1.0 ); - } - } } From fdab690b33647869a89175fe25187b5daf43bea9 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 12 Jul 2016 08:39:19 -0400 Subject: [PATCH 0075/1644] Refactor C++ output port to separate per-connection transport from general bookkeeping, in preparation for adding direct transfer for connections to the same address space --- .../src/cpp/include/burstio/OutPortDecl.h | 54 ++++-- .../src/cpp/include/burstio/UsesPort.h | 90 ++++----- burstioInterfaces/src/cpp/lib/OutPortImpl.h | 180 ++++++++---------- 3 files changed, 158 insertions(+), 166 deletions(-) diff --git a/burstioInterfaces/src/cpp/include/burstio/OutPortDecl.h b/burstioInterfaces/src/cpp/include/burstio/OutPortDecl.h index 7bd9c6e62..005a51710 100644 --- a/burstioInterfaces/src/cpp/include/burstio/OutPortDecl.h +++ b/burstioInterfaces/src/cpp/include/burstio/OutPortDecl.h @@ -39,18 +39,6 @@ namespace burstio { - struct PortStatus - { - PortStatus(const std::string& name, size_t bitsPerElement): - stats(name, bitsPerElement), - alive(true) - { - } - - SenderStatistics stats; - bool alive; - }; - enum RoutingModeType { ROUTE_ALL_INTERLEAVED, ROUTE_ALL_STREAMS, @@ -68,15 +56,41 @@ namespace burstio { virtual void flush () = 0; }; + template + class BurstTransport : public BasicTransport + { + public: + typedef BasicTransport super; + typedef typename Traits::PortType PortType; + typedef typename Traits::BurstSequenceType BurstSequenceType; + typedef typename Traits::ElementType ElementType; + + BurstTransport(typename PortType::_ptr_type port, const std::string& connectionId, const std::string& name) : + super(port, connectionId), + stats_(name, sizeof(ElementType) * 8) + { + } + + virtual void pushBursts(const BurstSequenceType& bursts, boost::system_time startTime, float queueDepth) = 0; + + BULKIO::PortStatistics* getStatistics() const + { + return stats_.retrieve(); + } + + protected: + SenderStatistics stats_; + }; + template - class OutPort : public UsesPort, + class OutPort : public UsesPort >, public virtual POA_BULKIO::UsesPortStatisticsProvider { ENABLE_INSTANCE_LOGGING; public: - typedef UsesPort super; - typedef typename Traits::PortType PortType; + typedef UsesPort > super; + typedef typename Traits::PortType PortType; typedef typename Traits::BurstType BurstType; typedef typename Traits::BurstSequenceType BurstSequenceType; typedef typename Traits::ElementType ElementType; @@ -242,17 +256,20 @@ namespace burstio { std::string streamID_; }; + class RemoteTransport; + friend class RemoteTransport; + friend class Queue; typedef typename super::ConnectionMap ConnectionMap; - typedef typename super::Connection Connection; + typedef typename super::transport_type TransportType; typedef std::map QueueMap; typedef std::map > RouteTable; void sendBursts (const BurstSequenceType& bursts, boost::system_time startTime, float queueDepth, const std::string& streamID); - void partitionBursts (const BurstSequenceType& bursts, boost::system_time startTime, float queueDepth, const std::string& streamID, const Connection& connection); + // void partitionBursts (const BurstSequenceType& bursts, boost::system_time startTime, float queueDepth, const std::string& streamID, const Connection& connection); void scheduleCheck (boost::system_time when); void checkQueues (); @@ -260,8 +277,7 @@ namespace burstio { void queueBurst (SequenceType& data, const BURSTIO::BurstSRI& sri, const BULKIO::PrecisionUTCTime& timestamp, bool eos, bool isComplex); - virtual void connectionAdded (const std::string& connectionId, Connection& connection); - virtual void connectionModified (const std::string& connectionId, Connection& connection); + virtual TransportType* _createConnection(typename PortType::_ptr_type port, const std::string& connectionId); const Queue& getQueueForStream (const std::string& streamID) const; Queue& getQueueForStream (const std::string& streamID); diff --git a/burstioInterfaces/src/cpp/include/burstio/UsesPort.h b/burstioInterfaces/src/cpp/include/burstio/UsesPort.h index 6371181cc..5b77c8312 100644 --- a/burstioInterfaces/src/cpp/include/burstio/UsesPort.h +++ b/burstioInterfaces/src/cpp/include/burstio/UsesPort.h @@ -33,14 +33,44 @@ namespace burstio { - template + template + class BasicTransport { + public: + typedef PortType port_type; + typedef typename port_type::_ptr_type ptr_type; + typedef typename port_type::_var_type var_type; + + BasicTransport(var_type port, const std::string& connectionId) : + port_(port_type::_duplicate(port)), + connectionId_(connectionId) + { + } + + virtual ~BasicTransport() { } + + const std::string& getConnectionId() const + { + return connectionId_; + } + + ptr_type objref() const + { + return port_; + } + + protected: + var_type port_; + const std::string connectionId_; + }; + + template > class UsesPort : public Port_Uses_base_impl, public virtual POA_ExtendedCF::QueryablePort { public: typedef PortType port_type; typedef typename port_type::_ptr_type ptr_type; typedef typename port_type::_var_type var_type; - typedef InfoType info_type; + typedef TransportType transport_type; typedef std::pair connection_type; typedef std::vector connection_list; @@ -121,16 +151,10 @@ namespace burstio { if (entry == connections_.end()) { // Store the new connection and pass the new entry along to // connectionAdded - entry = insertPort_(connectionId, port._retn()); - - // Allow subclasses to do additional bookkeeping - connectionAdded(entry->first, entry->second); + connections_[connectionId] = _createConnection(port, connectionId); } else { - // Replace the object reference - entry->second.port = port._retn(); - - // Allow subclasses to do additional bookkeeping - connectionModified(entry->first, entry->second); + // TODO: Replace the object reference + //entry->second.port = port._retn(); } } @@ -147,10 +171,7 @@ namespace burstio { throw CF::Port::InvalidPort(2, message.c_str()); } - // Allow subclasses to do additional cleanup - connectionRemoved(existing->first, existing->second); - delete existing->second.info; - + delete existing->second; connections_.erase(existing); } @@ -165,7 +186,7 @@ namespace burstio { CORBA::ULong index = 0; for (typename ConnectionMap::iterator ii = connections_.begin(); ii != connections_.end(); ++ii, ++index) { retval[index].connectionId = ii->first.c_str(); - retval[index].port = CORBA::Object::_duplicate(ii->second.port); + retval[index].port = CORBA::Object::_duplicate(ii->second->objref()); } return retval._retn(); } @@ -177,7 +198,7 @@ namespace burstio { if (existing == connections_.end()) { throw std::invalid_argument("No connection " + connectionId); } - return port_type::_duplicate(existing->second.port); + return port_type::_duplicate(existing->second->objref()); } connection_list getConnections() @@ -185,52 +206,23 @@ namespace burstio { boost::mutex::scoped_lock lock(updatingPortsLock); connection_list result; for (typename ConnectionMap::iterator ii = connections_.begin(); ii != connections_.end(); ++ii) { - result.push_back(std::make_pair(ii->first, port_type::_duplicate(ii->second.port))); + result.push_back(std::make_pair(ii->first, port_type::_duplicate(ii->second->objref()))); } return result; } protected: - struct Connection { - Connection(ptr_type _port) : - port(_port), - info(0) - { } - - var_type port; - info_type* info; - }; - UsesPort (std::string port_name) : Port_Uses_base_impl(port_name) { } - virtual void connectionAdded (const std::string&, Connection&) - { - } + virtual transport_type* _createConnection(ptr_type port, const std::string& connectionId) = 0; - virtual void connectionRemoved (const std::string&, Connection&) - { - } - - virtual void connectionModified (const std::string&, Connection&) - { - } - - typedef std::map ConnectionMap; + typedef std::map ConnectionMap; ConnectionMap connections_; private: - inline typename ConnectionMap::iterator - insertPort_ (const std::string& connectionId, ptr_type port) - { - // Store the new connection (constructing in-place because there is - // no default constructor for Connection), returning an iterator to - // the new entry - return connections_.insert(std::make_pair(connectionId, Connection(port))).first; - } - ossie::notification connectListeners_; ossie::notification disconnectListeners_; }; diff --git a/burstioInterfaces/src/cpp/lib/OutPortImpl.h b/burstioInterfaces/src/cpp/lib/OutPortImpl.h index aba8db5ee..730637c7c 100644 --- a/burstioInterfaces/src/cpp/lib/OutPortImpl.h +++ b/burstioInterfaces/src/cpp/lib/OutPortImpl.h @@ -26,6 +26,81 @@ namespace burstio { + template + class OutPort::RemoteTransport : public BurstTransport + { + public: + typedef BurstTransport super; + typedef typename Traits::PortType PortType; + typedef typename Traits::BurstType BurstType; + typedef typename Traits::BurstSequenceType BurstSequenceType; + + RemoteTransport(OutPort* parent, typename PortType::_ptr_type port, const std::string& connectionId) : + super(port, connectionId, parent->name), + parent_(parent), + alive_(true) + { + } + + void pushBursts(const BurstSequenceType& bursts, boost::system_time startTime, float queueDepth) + { + try { + sendBursts(bursts, startTime, queueDepth); + } catch (const CORBA::MARSHAL& ex) { + if (bursts.length() > 1) { + partitionBursts(bursts, startTime, queueDepth); + } else { + RH_ERROR(parent_->__logger, "pushBursts to " << this->connectionId_ << " failed because the burst size is too long"); + } + } catch (const CORBA::Exception& ex) { + if (alive_) { + RH_ERROR(parent_->__logger, "pushBursts to " << this->connectionId_ << " failed: CORBA::" << ex._name()); + } + alive_ = false; + } catch (...) { + if (alive_) { + RH_ERROR(parent_->__logger, "pushBursts to " << this->connectionId_ << " failed"); + } + alive_ = false; + } + } + + private: + void sendBursts(const BurstSequenceType& bursts, boost::system_time startTime, float queueDepth) + { + // Record delay from queueing of first burst to now + boost::posix_time::time_duration delay = boost::get_system_time() - startTime; + + this->port_->pushBursts(bursts); + alive_ = true; + + // Count up total elements + size_t total_elements = 0; + for (CORBA::ULong index = 0; index < bursts.length(); ++index) { + total_elements += bursts[index].data.length(); + } + this->stats_.record(bursts.length(), total_elements, queueDepth, delay.total_microseconds() * 1e-6); + } + + void partitionBursts(const BurstSequenceType& bursts, boost::system_time startTime, float queueDepth) + { + // Split the input bursts in the middle, sending each half in a + // separate call (which may end up recursively partitioning); no + // copies are made, just non-owning sequences + CORBA::ULong middle = bursts.length() / 2; + BurstType* buffer = const_cast(bursts.get_buffer()); + BurstSequenceType left(middle, middle, buffer, false); + pushBursts(left, startTime, queueDepth); + + CORBA::ULong remain = bursts.length() - middle; + BurstSequenceType right(remain, remain, buffer + middle, false); + pushBursts(right, startTime, queueDepth); + } + + OutPort* parent_; + bool alive_; + }; + template OutPort::Queue::Queue(OutPort* port, const std::string& streamID, size_t maxBursts, size_t thresholdBytes, long thresholdLatency) : port_(port), @@ -357,101 +432,16 @@ namespace burstio { { //LOG_INSTANCE_DEBUG("Sending " << bursts.length() << " bursts"); - // Count up total elements - size_t total_elements = 0; - for (CORBA::ULong index = 0; index < bursts.length(); ++index) { - total_elements += bursts[index].data.length(); - } - - boost::mutex::scoped_lock lock(updatingPortsLock); // don't want to process while command information is coming in + boost::mutex::scoped_lock lock(updatingPortsLock); for (typename ConnectionMap::iterator ii = connections_.begin(); ii != connections_.end(); ++ii) { const std::string& connectionId = ii->first; - Connection& connection = ii->second; + TransportType* connection = ii->second; if (!isStreamRoutedToConnection(streamID, connectionId)) { continue; } - // Record statistics - boost::posix_time::time_duration delay = boost::get_system_time() - startTime; - - try { - connection.port->pushBursts(bursts); - connection.info->alive = true; - connection.info->stats.record(bursts.length(), total_elements, queueDepth, delay.total_microseconds() * 1e-6); - } catch (const std::exception& ex) { - if (connection.info->alive) { - LOG_INSTANCE_ERROR("pushBursts to " << ii->first << " failed: " << ex.what()); - } - connection.info->alive = false; - } catch (const CORBA::MARSHAL& ex) { - if (bursts.length() == 1) { - // the burst length is 1. There's nothing we can do - if (connection.info->alive) { - LOG_INSTANCE_ERROR("pushBursts to " << ii->first << " failed because the burst size is too long"); - } - connection.info->alive = false; - } else { - try { - partitionBursts(bursts, startTime, queueDepth, streamID, connection); - } catch (...) { - if (connection.info->alive) { - LOG_INSTANCE_ERROR("Paritioned pushBursts to " << ii->first << " failed"); - } - connection.info->alive = false; - } - } - } catch (const CORBA::Exception& ex) { - if (connection.info->alive) { - LOG_INSTANCE_ERROR("pushBursts to " << ii->first << " failed: CORBA::" << ex._name()); - } - connection.info->alive = false; - } catch (...) { - if (connection.info->alive) { - LOG_INSTANCE_ERROR("pushBursts to " << ii->first << " failed"); - } - connection.info->alive = false; - } - } - } - - template - void OutPort::partitionBursts(const BurstSequenceType& bursts, boost::system_time startTime, float queueDepth, const std::string& streamID, const Connection& connection) - { - // cut the burst length in half and try again.... - BurstSequenceType first_burst; - BurstSequenceType second_burst; - first_burst.length(bursts.length()/2); - second_burst.length(bursts.length()-first_burst.length()); - boost::posix_time::time_duration delay = boost::get_system_time() - startTime; - for (int i=0; ipushBursts(first_burst); - connection.info->alive = true; - connection.info->stats.record(first_burst.length(), total_elements, queueDepth, delay.total_microseconds() * 1e-6); - } catch (const CORBA::MARSHAL& ex) { - partitionBursts(first_burst, startTime, queueDepth, streamID, connection); - } - try { - size_t total_elements = 0; - for (CORBA::ULong index = 0; index < first_burst.length(); ++index) { - total_elements += first_burst[index].data.length(); - } - connection.port->pushBursts(second_burst); - connection.info->alive = true; - connection.info->stats.record(second_burst.length(), total_elements, queueDepth, delay.total_microseconds() * 1e-6); - } catch (const CORBA::MARSHAL& ex) { - partitionBursts(second_burst, startTime, queueDepth, streamID, connection); + connection->pushBursts(bursts, startTime, queueDepth); } } @@ -482,7 +472,7 @@ namespace burstio { CORBA::ULong index = 0; for (typename ConnectionMap::iterator ii = connections_.begin(); ii != connections_.end(); ++ii, ++index) { retval[index].connectionId = ii->first.c_str(); - BULKIO::PortStatistics_var stats = ii->second.info->stats.retrieve(); + BULKIO::PortStatistics_var stats = ii->second->getStatistics(); for (typename QueueMap::iterator jj = streamQueues_.begin(); jj != streamQueues_.end(); ++jj) { const std::string& streamID = jj->first; if (isStreamRoutedToConnection(streamID, ii->first)) { @@ -510,16 +500,10 @@ namespace burstio { } template - void OutPort::connectionAdded (const std::string& connectionId, Connection& connection) - { - connection.info = new PortStatus(this->name, sizeof(ElementType)*8); - } - - template - void OutPort::connectionModified (const std::string& connectionId, Connection& connection) + typename OutPort::TransportType* OutPort::_createConnection (typename PortType::_ptr_type port, + const std::string& connectionId) { - // Assume that the updated connection is alive - connection.info->alive = true; + return new RemoteTransport(this, port, connectionId); } template From 528c81907c6f74eb138f5be5cec211d011721150 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 12 Jul 2016 12:12:04 -0400 Subject: [PATCH 0076/1644] Integrate C++ unit testing into main build --- burstioInterfaces/Makefile.am | 3 + burstioInterfaces/configure.ac | 12 +- .../testing/tests/cpp/Burstio_InPort.cpp | 5 +- .../testing/tests/cpp/Burstio_OutPort.cpp | 4 +- .../testing/tests/cpp/Burstio_PushTest.cpp | 5 +- .../testing/tests/cpp/Burstio_PushTest.h | 6 +- .../testing/tests/cpp/Makefile.am | 17 +- .../testing/tests/cpp/configure.ac | 46 - .../testing/tests/cpp/m4/libtool.m4 | 7360 ----------------- .../testing/tests/cpp/m4/ltoptions.m4 | 368 - .../testing/tests/cpp/m4/ltsugar.m4 | 123 - .../testing/tests/cpp/m4/ltversion.m4 | 23 - .../testing/tests/cpp/m4/lt~obsolete.m4 | 92 - burstioInterfaces/testing/tests/cpp/reconf | 27 - burstioInterfaces/testing/tests/cpp/runtests | 8 - 15 files changed, 30 insertions(+), 8069 deletions(-) delete mode 100644 burstioInterfaces/testing/tests/cpp/configure.ac delete mode 100644 burstioInterfaces/testing/tests/cpp/m4/libtool.m4 delete mode 100644 burstioInterfaces/testing/tests/cpp/m4/ltoptions.m4 delete mode 100644 burstioInterfaces/testing/tests/cpp/m4/ltsugar.m4 delete mode 100644 burstioInterfaces/testing/tests/cpp/m4/ltversion.m4 delete mode 100644 burstioInterfaces/testing/tests/cpp/m4/lt~obsolete.m4 delete mode 100755 burstioInterfaces/testing/tests/cpp/reconf delete mode 100755 burstioInterfaces/testing/tests/cpp/runtests diff --git a/burstioInterfaces/Makefile.am b/burstioInterfaces/Makefile.am index c61b1cb8f..5cf4bc8c2 100644 --- a/burstioInterfaces/Makefile.am +++ b/burstioInterfaces/Makefile.am @@ -24,6 +24,9 @@ SUBDIRS = src/idl src/cpp src/python if HAVE_JAVASUPPORT SUBDIRS += src/java endif +if ENABLE_TESTING + SUBDIRS += testing/tests/cpp +endif pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = burstioInterfaces.pc burstio.pc diff --git a/burstioInterfaces/configure.ac b/burstioInterfaces/configure.ac index f65f11b35..c06473f23 100644 --- a/burstioInterfaces/configure.ac +++ b/burstioInterfaces/configure.ac @@ -45,7 +45,7 @@ PKG_CHECK_MODULES([OMNIORB], [omniORB4 >= 4.1.0]) PKG_CHECK_MODULES(OSSIE, ossie >= 2.1.0,,exit) RH_PKG_IDLDIR([OSSIE], [ossie]) -PKG_CHECK_MODULES([BULKIO], [bulkioInterfaces >= 2.0]) +PKG_CHECK_MODULES([BULKIO], [bulkio >= 2.0]) RH_PKG_IDLDIR([BULKIO], [bulkioInterfaces]) AX_BOOST_BASE([1.41]) @@ -132,6 +132,13 @@ AC_MSG_RESULT($HAVE_JAVASUPPORT) AM_CONDITIONAL(HAVE_JAVASUPPORT, test $HAVE_JAVASUPPORT = yes) # End optional java support +# Optionally enable unit tests +AC_ARG_ENABLE([testing], AS_HELP_STRING([--enable-testing], [enable build of unit tests])) +AS_IF([test "x$enable_testing" == "xyes"], [ + AM_PATH_CPPUNIT(1.9.6) +]) +AM_CONDITIONAL(ENABLE_TESTING, test "x$enable_testing" == "xyes") + AC_SUBST(idldir, '${prefix}/share/idl') AC_CONFIG_FILES([Makefile \ @@ -141,6 +148,7 @@ AC_CONFIG_FILES([Makefile \ src/java/Makefile \ src/python/Makefile \ src/python/setup.py \ - src/idl/Makefile]) + src/idl/Makefile \ + testing/tests/cpp/Makefile]) AC_OUTPUT diff --git a/burstioInterfaces/testing/tests/cpp/Burstio_InPort.cpp b/burstioInterfaces/testing/tests/cpp/Burstio_InPort.cpp index 4a534d543..f9aa2832d 100644 --- a/burstioInterfaces/testing/tests/cpp/Burstio_InPort.cpp +++ b/burstioInterfaces/testing/tests/cpp/Burstio_InPort.cpp @@ -18,8 +18,9 @@ * along with this program. If not, see http://www.gnu.org/licenses/. */ #include "Burstio_InPort.h" -#include "burstio.h" -#include "bulkio.h" + +#include +#include // Registers the fixture into the 'registry' CPPUNIT_TEST_SUITE_REGISTRATION( Burstio_InPort ); diff --git a/burstioInterfaces/testing/tests/cpp/Burstio_OutPort.cpp b/burstioInterfaces/testing/tests/cpp/Burstio_OutPort.cpp index be442028a..4078205a1 100644 --- a/burstioInterfaces/testing/tests/cpp/Burstio_OutPort.cpp +++ b/burstioInterfaces/testing/tests/cpp/Burstio_OutPort.cpp @@ -18,9 +18,9 @@ * along with this program. If not, see http://www.gnu.org/licenses/. */ #include "Burstio_OutPort.h" -#include "bulkio.h" -#include "burstio.h" +#include +#include // Registers the fixture into the 'registry' CPPUNIT_TEST_SUITE_REGISTRATION( Burstio_OutPort ); diff --git a/burstioInterfaces/testing/tests/cpp/Burstio_PushTest.cpp b/burstioInterfaces/testing/tests/cpp/Burstio_PushTest.cpp index c67e7c1ea..93da388e2 100644 --- a/burstioInterfaces/testing/tests/cpp/Burstio_PushTest.cpp +++ b/burstioInterfaces/testing/tests/cpp/Burstio_PushTest.cpp @@ -18,8 +18,9 @@ * along with this program. If not, see http://www.gnu.org/licenses/. */ #include "Burstio_PushTest.h" -#include "bulkio.h" -#include "burstio.h" + +#include +#include template < typename OUT_PORT, typename IN_PORT > diff --git a/burstioInterfaces/testing/tests/cpp/Burstio_PushTest.h b/burstioInterfaces/testing/tests/cpp/Burstio_PushTest.h index 9cb9b6c85..2e125c4a0 100644 --- a/burstioInterfaces/testing/tests/cpp/Burstio_PushTest.h +++ b/burstioInterfaces/testing/tests/cpp/Burstio_PushTest.h @@ -21,9 +21,9 @@ #define BURSTIO_PUSHTEST_FIXTURE_H #include -#include -#include -#include +#include +#include +#include template< typename OUT_PORT, typename IN_PORT > class Burstio_PushBursts: public CppUnit::TestFixture diff --git a/burstioInterfaces/testing/tests/cpp/Makefile.am b/burstioInterfaces/testing/tests/cpp/Makefile.am index 36d6b405b..5d1ca219f 100644 --- a/burstioInterfaces/testing/tests/cpp/Makefile.am +++ b/burstioInterfaces/testing/tests/cpp/Makefile.am @@ -18,17 +18,12 @@ # along with this program. If not, see http://www.gnu.org/licenses/. # -ACLOCAL_AMFLAGS = -I m4 -I ${OSSIEHOME}/share/aclocal/ossie -I acinclude - -burstio_top=../../.. -burstio_cpplib_top=$(burstio_top)/src/cpp -Burstio_SOURCES = Burstio.cpp Burstio_InPort.cpp Burstio_OutPort.cpp Burstio_PushTest.cpp Burstio_Utils_Test.cpp -Burstio_INCLUDES = -I$(burstio_cpplib_top)/include -I$(burstio_cpplib_top)/include/burstio -I$(burstio_cpplib_top)/redhawk -I$(burstio_cpplib_top)/ -Burstio_CXXFLAGS = $(CPPUNIT_CFLAGS) $(Burstio_INCLUDES) $(BOOST_CPPFLAGS) $(BULKIO_CFLAGS) $(RH_DEPS_CFLAGS) -Burstio_LDADD = -L$(burstio_cpplib_top)/.libs -lburstio -lburstioInterfaces $(BULKIO_LIBS) $(RH_DEPS_LIBS) $(BOOST_LDFLAGS) $(BOOST_SYSTEM_LIB) $(CPPUNIT_LIBS) -llog4cxx -ldl - +burstio_include=$(top_srcdir)/src/cpp/include +Burstio_SOURCES = Burstio.cpp Burstio_InPort.cpp Burstio_OutPort.cpp Burstio_PushTest.cpp Burstio_Utils_Test.cpp +Burstio_INCLUDES = -I$(burstio_include) -I$(burstio_include)/burstio -I$(top_builddir)/src/cpp/redhawk +Burstio_CXXFLAGS = $(CPPUNIT_CFLAGS) $(Burstio_INCLUDES) $(BOOST_CPPFLAGS) $(BULKIO_CFLAGS) +Burstio_LDADD = $(BULKIO_LIBS) $(BOOST_LDFLAGS) $(BOOST_SYSTEM_LIB) $(CPPUNIT_LIBS) -llog4cxx -ldl +Burstio_LDADD += $(top_builddir)/src/cpp/libburstio.la $(top_builddir)/src/cpp/libburstioInterfaces.la TESTS = Burstio -noinst_PROGRAMS=$(TESTS) check_PROGRAMS=$(TESTS) - diff --git a/burstioInterfaces/testing/tests/cpp/configure.ac b/burstioInterfaces/testing/tests/cpp/configure.ac deleted file mode 100644 index 7bef998de..000000000 --- a/burstioInterfaces/testing/tests/cpp/configure.ac +++ /dev/null @@ -1,46 +0,0 @@ -/* - * This file is protected by Copyright. Please refer to the COPYRIGHT file - * distributed with this source distribution. - * - * This file is part of REDHAWK burstioInterfaces. - * - * REDHAWK burstioInterfaces is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * REDHAWK burstioInterfaces is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see http://www.gnu.org/licenses/. - */ - -dnl Process this file with autoconf to produce a configure script. -AC_INIT(Burstio_Test,0.1) -AC_CONFIG_SRCDIR([Burstio.cpp]) -AM_INIT_AUTOMAKE -AM_PATH_CPPUNIT(1.9.6) -AC_CONFIG_MACRO_DIR([m4]) -AC_PROG_CXX -AC_PROG_CC -AC_PROG_INSTALL -AC_PREFIX_DEFAULT(${OSSIEHOME}) -AC_CORBA_ORB - -OSSIE_CHECK_OSSIE -OSSIE_OSSIEHOME_AS_PREFIX -PKG_CHECK_MODULES([RH_DEPS], [ossie >= 1.7 omniORB4 >= 4.0.0]) -PKG_CHECK_MODULES([BULKIO], [ bulkio >= 1.0 bulkioInterfaces >= 1.9 ]) - -AX_BOOST_BASE([1.41]) -AX_BOOST_THREAD -AX_BOOST_SYSTEM - -# set PKG_CONFIG_PATH to look at local xxx.pc files -export PKG_CONFIG_PATH="../../../..:../../..":${PKG_CONFIG_PATH} -PKG_CHECK_MODULES([BIO], [ burstio >= 1.0 burstioInterfaces >= 1.8 ]) - -AC_OUTPUT(Makefile) diff --git a/burstioInterfaces/testing/tests/cpp/m4/libtool.m4 b/burstioInterfaces/testing/tests/cpp/m4/libtool.m4 deleted file mode 100644 index 671cde117..000000000 --- a/burstioInterfaces/testing/tests/cpp/m4/libtool.m4 +++ /dev/null @@ -1,7360 +0,0 @@ -# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- -# -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, -# 2006, 2007, 2008 Free Software Foundation, Inc. -# Written by Gordon Matzigkeit, 1996 -# -# This file is free software; the Free Software Foundation gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. - -m4_define([_LT_COPYING], [dnl -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, -# 2006, 2007, 2008 Free Software Foundation, Inc. -# Written by Gordon Matzigkeit, 1996 -# -# This file is part of GNU Libtool. -# -# GNU Libtool is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# As a special exception to the GNU General Public License, -# if you distribute this file as part of a program or library that -# is built using GNU Libtool, you may include this file under the -# same distribution terms that you use for the rest of that program. -# -# GNU Libtool is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GNU Libtool; see the file COPYING. If not, a copy -# can be downloaded from http://www.gnu.org/licenses/gpl.html, or -# obtained by writing to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -]) - -# serial 56 LT_INIT - - -# LT_PREREQ(VERSION) -# ------------------ -# Complain and exit if this libtool version is less that VERSION. -m4_defun([LT_PREREQ], -[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, - [m4_default([$3], - [m4_fatal([Libtool version $1 or higher is required], - 63)])], - [$2])]) - - -# _LT_CHECK_BUILDDIR -# ------------------ -# Complain if the absolute build directory name contains unusual characters -m4_defun([_LT_CHECK_BUILDDIR], -[case `pwd` in - *\ * | *\ *) - AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; -esac -]) - - -# LT_INIT([OPTIONS]) -# ------------------ -AC_DEFUN([LT_INIT], -[AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT -AC_BEFORE([$0], [LT_LANG])dnl -AC_BEFORE([$0], [LT_OUTPUT])dnl -AC_BEFORE([$0], [LTDL_INIT])dnl -m4_require([_LT_CHECK_BUILDDIR])dnl - -dnl Autoconf doesn't catch unexpanded LT_ macros by default: -m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl -m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl -dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 -dnl unless we require an AC_DEFUNed macro: -AC_REQUIRE([LTOPTIONS_VERSION])dnl -AC_REQUIRE([LTSUGAR_VERSION])dnl -AC_REQUIRE([LTVERSION_VERSION])dnl -AC_REQUIRE([LTOBSOLETE_VERSION])dnl -m4_require([_LT_PROG_LTMAIN])dnl - -dnl Parse OPTIONS -_LT_SET_OPTIONS([$0], [$1]) - -# This can be used to rebuild libtool when needed -LIBTOOL_DEPS="$ltmain" - -# Always use our own libtool. -LIBTOOL='$(SHELL) $(top_builddir)/libtool' -AC_SUBST(LIBTOOL)dnl - -_LT_SETUP - -# Only expand once: -m4_define([LT_INIT]) -])# LT_INIT - -# Old names: -AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) -AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_PROG_LIBTOOL], []) -dnl AC_DEFUN([AM_PROG_LIBTOOL], []) - - -# _LT_CC_BASENAME(CC) -# ------------------- -# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. -m4_defun([_LT_CC_BASENAME], -[for cc_temp in $1""; do - case $cc_temp in - compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; - distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; - \-*) ;; - *) break;; - esac -done -cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` -]) - - -# _LT_FILEUTILS_DEFAULTS -# ---------------------- -# It is okay to use these file commands and assume they have been set -# sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'. -m4_defun([_LT_FILEUTILS_DEFAULTS], -[: ${CP="cp -f"} -: ${MV="mv -f"} -: ${RM="rm -f"} -])# _LT_FILEUTILS_DEFAULTS - - -# _LT_SETUP -# --------- -m4_defun([_LT_SETUP], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -AC_REQUIRE([AC_CANONICAL_BUILD])dnl -_LT_DECL([], [host_alias], [0], [The host system])dnl -_LT_DECL([], [host], [0])dnl -_LT_DECL([], [host_os], [0])dnl -dnl -_LT_DECL([], [build_alias], [0], [The build system])dnl -_LT_DECL([], [build], [0])dnl -_LT_DECL([], [build_os], [0])dnl -dnl -AC_REQUIRE([AC_PROG_CC])dnl -AC_REQUIRE([LT_PATH_LD])dnl -AC_REQUIRE([LT_PATH_NM])dnl -dnl -AC_REQUIRE([AC_PROG_LN_S])dnl -test -z "$LN_S" && LN_S="ln -s" -_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl -dnl -AC_REQUIRE([LT_CMD_MAX_LEN])dnl -_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl -_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl -dnl -m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_CHECK_SHELL_FEATURES])dnl -m4_require([_LT_CMD_RELOAD])dnl -m4_require([_LT_CHECK_MAGIC_METHOD])dnl -m4_require([_LT_CMD_OLD_ARCHIVE])dnl -m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl - -_LT_CONFIG_LIBTOOL_INIT([ -# See if we are running on zsh, and set the options which allow our -# commands through without removal of \ escapes INIT. -if test -n "\${ZSH_VERSION+set}" ; then - setopt NO_GLOB_SUBST -fi -]) -if test -n "${ZSH_VERSION+set}" ; then - setopt NO_GLOB_SUBST -fi - -_LT_CHECK_OBJDIR - -m4_require([_LT_TAG_COMPILER])dnl -_LT_PROG_ECHO_BACKSLASH - -case $host_os in -aix3*) - # AIX sometimes has problems with the GCC collect2 program. For some - # reason, if we set the COLLECT_NAMES environment variable, the problems - # vanish in a puff of smoke. - if test "X${COLLECT_NAMES+set}" != Xset; then - COLLECT_NAMES= - export COLLECT_NAMES - fi - ;; -esac - -# Sed substitution that helps us do robust quoting. It backslashifies -# metacharacters that are still active within double-quoted strings. -sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' - -# Same as above, but do not quote variable references. -double_quote_subst='s/\([["`\\]]\)/\\\1/g' - -# Sed substitution to delay expansion of an escaped shell variable in a -# double_quote_subst'ed string. -delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' - -# Sed substitution to delay expansion of an escaped single quote. -delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' - -# Sed substitution to avoid accidental globbing in evaled expressions -no_glob_subst='s/\*/\\\*/g' - -# Global variables: -ofile=libtool -can_build_shared=yes - -# All known linkers require a `.a' archive for static linking (except MSVC, -# which needs '.lib'). -libext=a - -with_gnu_ld="$lt_cv_prog_gnu_ld" - -old_CC="$CC" -old_CFLAGS="$CFLAGS" - -# Set sane defaults for various variables -test -z "$CC" && CC=cc -test -z "$LTCC" && LTCC=$CC -test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS -test -z "$LD" && LD=ld -test -z "$ac_objext" && ac_objext=o - -_LT_CC_BASENAME([$compiler]) - -# Only perform the check for file, if the check method requires it -test -z "$MAGIC_CMD" && MAGIC_CMD=file -case $deplibs_check_method in -file_magic*) - if test "$file_magic_cmd" = '$MAGIC_CMD'; then - _LT_PATH_MAGIC - fi - ;; -esac - -# Use C for the default configuration in the libtool script -LT_SUPPORTED_TAG([CC]) -_LT_LANG_C_CONFIG -_LT_LANG_DEFAULT_CONFIG -_LT_CONFIG_COMMANDS -])# _LT_SETUP - - -# _LT_PROG_LTMAIN -# --------------- -# Note that this code is called both from `configure', and `config.status' -# now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, -# `config.status' has no value for ac_aux_dir unless we are using Automake, -# so we pass a copy along to make sure it has a sensible value anyway. -m4_defun([_LT_PROG_LTMAIN], -[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl -_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) -ltmain="$ac_aux_dir/ltmain.sh" -])# _LT_PROG_LTMAIN - - -## ------------------------------------- ## -## Accumulate code for creating libtool. ## -## ------------------------------------- ## - -# So that we can recreate a full libtool script including additional -# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS -# in macros and then make a single call at the end using the `libtool' -# label. - - -# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) -# ---------------------------------------- -# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. -m4_define([_LT_CONFIG_LIBTOOL_INIT], -[m4_ifval([$1], - [m4_append([_LT_OUTPUT_LIBTOOL_INIT], - [$1 -])])]) - -# Initialize. -m4_define([_LT_OUTPUT_LIBTOOL_INIT]) - - -# _LT_CONFIG_LIBTOOL([COMMANDS]) -# ------------------------------ -# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. -m4_define([_LT_CONFIG_LIBTOOL], -[m4_ifval([$1], - [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], - [$1 -])])]) - -# Initialize. -m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) - - -# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) -# ----------------------------------------------------- -m4_defun([_LT_CONFIG_SAVE_COMMANDS], -[_LT_CONFIG_LIBTOOL([$1]) -_LT_CONFIG_LIBTOOL_INIT([$2]) -]) - - -# _LT_FORMAT_COMMENT([COMMENT]) -# ----------------------------- -# Add leading comment marks to the start of each line, and a trailing -# full-stop to the whole comment if one is not present already. -m4_define([_LT_FORMAT_COMMENT], -[m4_ifval([$1], [ -m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], - [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) -)]) - - - -## ------------------------ ## -## FIXME: Eliminate VARNAME ## -## ------------------------ ## - - -# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) -# ------------------------------------------------------------------- -# CONFIGNAME is the name given to the value in the libtool script. -# VARNAME is the (base) name used in the configure script. -# VALUE may be 0, 1 or 2 for a computed quote escaped value based on -# VARNAME. Any other value will be used directly. -m4_define([_LT_DECL], -[lt_if_append_uniq([lt_decl_varnames], [$2], [, ], - [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], - [m4_ifval([$1], [$1], [$2])]) - lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) - m4_ifval([$4], - [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) - lt_dict_add_subkey([lt_decl_dict], [$2], - [tagged?], [m4_ifval([$5], [yes], [no])])]) -]) - - -# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) -# -------------------------------------------------------- -m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) - - -# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) -# ------------------------------------------------ -m4_define([lt_decl_tag_varnames], -[_lt_decl_filter([tagged?], [yes], $@)]) - - -# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) -# --------------------------------------------------------- -m4_define([_lt_decl_filter], -[m4_case([$#], - [0], [m4_fatal([$0: too few arguments: $#])], - [1], [m4_fatal([$0: too few arguments: $#: $1])], - [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], - [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], - [lt_dict_filter([lt_decl_dict], $@)])[]dnl -]) - - -# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) -# -------------------------------------------------- -m4_define([lt_decl_quote_varnames], -[_lt_decl_filter([value], [1], $@)]) - - -# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) -# --------------------------------------------------- -m4_define([lt_decl_dquote_varnames], -[_lt_decl_filter([value], [2], $@)]) - - -# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) -# --------------------------------------------------- -m4_define([lt_decl_varnames_tagged], -[m4_assert([$# <= 2])dnl -_$0(m4_quote(m4_default([$1], [[, ]])), - m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), - m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) -m4_define([_lt_decl_varnames_tagged], -[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) - - -# lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) -# ------------------------------------------------ -m4_define([lt_decl_all_varnames], -[_$0(m4_quote(m4_default([$1], [[, ]])), - m4_if([$2], [], - m4_quote(lt_decl_varnames), - m4_quote(m4_shift($@))))[]dnl -]) -m4_define([_lt_decl_all_varnames], -[lt_join($@, lt_decl_varnames_tagged([$1], - lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl -]) - - -# _LT_CONFIG_STATUS_DECLARE([VARNAME]) -# ------------------------------------ -# Quote a variable value, and forward it to `config.status' so that its -# declaration there will have the same value as in `configure'. VARNAME -# must have a single quote delimited value for this to work. -m4_define([_LT_CONFIG_STATUS_DECLARE], -[$1='`$ECHO "X$][$1" | $Xsed -e "$delay_single_quote_subst"`']) - - -# _LT_CONFIG_STATUS_DECLARATIONS -# ------------------------------ -# We delimit libtool config variables with single quotes, so when -# we write them to config.status, we have to be sure to quote all -# embedded single quotes properly. In configure, this macro expands -# each variable declared with _LT_DECL (and _LT_TAGDECL) into: -# -# ='`$ECHO "X$" | $Xsed -e "$delay_single_quote_subst"`' -m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], -[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), - [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) - - -# _LT_LIBTOOL_TAGS -# ---------------- -# Output comment and list of tags supported by the script -m4_defun([_LT_LIBTOOL_TAGS], -[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl -available_tags="_LT_TAGS"dnl -]) - - -# _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) -# ----------------------------------- -# Extract the dictionary values for VARNAME (optionally with TAG) and -# expand to a commented shell variable setting: -# -# # Some comment about what VAR is for. -# visible_name=$lt_internal_name -m4_define([_LT_LIBTOOL_DECLARE], -[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], - [description])))[]dnl -m4_pushdef([_libtool_name], - m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl -m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), - [0], [_libtool_name=[$]$1], - [1], [_libtool_name=$lt_[]$1], - [2], [_libtool_name=$lt_[]$1], - [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl -m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl -]) - - -# _LT_LIBTOOL_CONFIG_VARS -# ----------------------- -# Produce commented declarations of non-tagged libtool config variables -# suitable for insertion in the LIBTOOL CONFIG section of the `libtool' -# script. Tagged libtool config variables (even for the LIBTOOL CONFIG -# section) are produced by _LT_LIBTOOL_TAG_VARS. -m4_defun([_LT_LIBTOOL_CONFIG_VARS], -[m4_foreach([_lt_var], - m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), - [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) - - -# _LT_LIBTOOL_TAG_VARS(TAG) -# ------------------------- -m4_define([_LT_LIBTOOL_TAG_VARS], -[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), - [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) - - -# _LT_TAGVAR(VARNAME, [TAGNAME]) -# ------------------------------ -m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) - - -# _LT_CONFIG_COMMANDS -# ------------------- -# Send accumulated output to $CONFIG_STATUS. Thanks to the lists of -# variables for single and double quote escaping we saved from calls -# to _LT_DECL, we can put quote escaped variables declarations -# into `config.status', and then the shell code to quote escape them in -# for loops in `config.status'. Finally, any additional code accumulated -# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. -m4_defun([_LT_CONFIG_COMMANDS], -[AC_PROVIDE_IFELSE([LT_OUTPUT], - dnl If the libtool generation code has been placed in $CONFIG_LT, - dnl instead of duplicating it all over again into config.status, - dnl then we will have config.status run $CONFIG_LT later, so it - dnl needs to know what name is stored there: - [AC_CONFIG_COMMANDS([libtool], - [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], - dnl If the libtool generation code is destined for config.status, - dnl expand the accumulated commands and init code now: - [AC_CONFIG_COMMANDS([libtool], - [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) -])#_LT_CONFIG_COMMANDS - - -# Initialize. -m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], -[ - -# The HP-UX ksh and POSIX shell print the target directory to stdout -# if CDPATH is set. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - -sed_quote_subst='$sed_quote_subst' -double_quote_subst='$double_quote_subst' -delay_variable_subst='$delay_variable_subst' -_LT_CONFIG_STATUS_DECLARATIONS -LTCC='$LTCC' -LTCFLAGS='$LTCFLAGS' -compiler='$compiler_DEFAULT' - -# Quote evaled strings. -for var in lt_decl_all_varnames([[ \ -]], lt_decl_quote_varnames); do - case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in - *[[\\\\\\\`\\"\\\$]]*) - eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" - ;; - *) - eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" - ;; - esac -done - -# Double-quote double-evaled strings. -for var in lt_decl_all_varnames([[ \ -]], lt_decl_dquote_varnames); do - case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in - *[[\\\\\\\`\\"\\\$]]*) - eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" - ;; - *) - eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" - ;; - esac -done - -# Fix-up fallback echo if it was mangled by the above quoting rules. -case \$lt_ECHO in -*'\\\[$]0 --fallback-echo"')dnl " - lt_ECHO=\`\$ECHO "X\$lt_ECHO" | \$Xsed -e 's/\\\\\\\\\\\\\\\[$]0 --fallback-echo"\[$]/\[$]0 --fallback-echo"/'\` - ;; -esac - -_LT_OUTPUT_LIBTOOL_INIT -]) - - -# LT_OUTPUT -# --------- -# This macro allows early generation of the libtool script (before -# AC_OUTPUT is called), incase it is used in configure for compilation -# tests. -AC_DEFUN([LT_OUTPUT], -[: ${CONFIG_LT=./config.lt} -AC_MSG_NOTICE([creating $CONFIG_LT]) -cat >"$CONFIG_LT" <<_LTEOF -#! $SHELL -# Generated by $as_me. -# Run this file to recreate a libtool stub with the current configuration. - -lt_cl_silent=false -SHELL=\${CONFIG_SHELL-$SHELL} -_LTEOF - -cat >>"$CONFIG_LT" <<\_LTEOF -AS_SHELL_SANITIZE -_AS_PREPARE - -exec AS_MESSAGE_FD>&1 -exec AS_MESSAGE_LOG_FD>>config.log -{ - echo - AS_BOX([Running $as_me.]) -} >&AS_MESSAGE_LOG_FD - -lt_cl_help="\ -\`$as_me' creates a local libtool stub from the current configuration, -for use in further configure time tests before the real libtool is -generated. - -Usage: $[0] [[OPTIONS]] - - -h, --help print this help, then exit - -V, --version print version number, then exit - -q, --quiet do not print progress messages - -d, --debug don't remove temporary files - -Report bugs to ." - -lt_cl_version="\ -m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl -m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) -configured by $[0], generated by m4_PACKAGE_STRING. - -Copyright (C) 2008 Free Software Foundation, Inc. -This config.lt script is free software; the Free Software Foundation -gives unlimited permision to copy, distribute and modify it." - -while test $[#] != 0 -do - case $[1] in - --version | --v* | -V ) - echo "$lt_cl_version"; exit 0 ;; - --help | --h* | -h ) - echo "$lt_cl_help"; exit 0 ;; - --debug | --d* | -d ) - debug=: ;; - --quiet | --q* | --silent | --s* | -q ) - lt_cl_silent=: ;; - - -*) AC_MSG_ERROR([unrecognized option: $[1] -Try \`$[0] --help' for more information.]) ;; - - *) AC_MSG_ERROR([unrecognized argument: $[1] -Try \`$[0] --help' for more information.]) ;; - esac - shift -done - -if $lt_cl_silent; then - exec AS_MESSAGE_FD>/dev/null -fi -_LTEOF - -cat >>"$CONFIG_LT" <<_LTEOF -_LT_OUTPUT_LIBTOOL_COMMANDS_INIT -_LTEOF - -cat >>"$CONFIG_LT" <<\_LTEOF -AC_MSG_NOTICE([creating $ofile]) -_LT_OUTPUT_LIBTOOL_COMMANDS -AS_EXIT(0) -_LTEOF -chmod +x "$CONFIG_LT" - -# configure is writing to config.log, but config.lt does its own redirection, -# appending to config.log, which fails on DOS, as config.log is still kept -# open by configure. Here we exec the FD to /dev/null, effectively closing -# config.log, so it can be properly (re)opened and appended to by config.lt. -if test "$no_create" != yes; then - lt_cl_success=: - test "$silent" = yes && - lt_config_lt_args="$lt_config_lt_args --quiet" - exec AS_MESSAGE_LOG_FD>/dev/null - $SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false - exec AS_MESSAGE_LOG_FD>>config.log - $lt_cl_success || AS_EXIT(1) -fi -])# LT_OUTPUT - - -# _LT_CONFIG(TAG) -# --------------- -# If TAG is the built-in tag, create an initial libtool script with a -# default configuration from the untagged config vars. Otherwise add code -# to config.status for appending the configuration named by TAG from the -# matching tagged config vars. -m4_defun([_LT_CONFIG], -[m4_require([_LT_FILEUTILS_DEFAULTS])dnl -_LT_CONFIG_SAVE_COMMANDS([ - m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl - m4_if(_LT_TAG, [C], [ - # See if we are running on zsh, and set the options which allow our - # commands through without removal of \ escapes. - if test -n "${ZSH_VERSION+set}" ; then - setopt NO_GLOB_SUBST - fi - - cfgfile="${ofile}T" - trap "$RM \"$cfgfile\"; exit 1" 1 2 15 - $RM "$cfgfile" - - cat <<_LT_EOF >> "$cfgfile" -#! $SHELL - -# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. -# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION -# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: -# NOTE: Changes made to this file will be lost: look at ltmain.sh. -# -_LT_COPYING -_LT_LIBTOOL_TAGS - -# ### BEGIN LIBTOOL CONFIG -_LT_LIBTOOL_CONFIG_VARS -_LT_LIBTOOL_TAG_VARS -# ### END LIBTOOL CONFIG - -_LT_EOF - - case $host_os in - aix3*) - cat <<\_LT_EOF >> "$cfgfile" -# AIX sometimes has problems with the GCC collect2 program. For some -# reason, if we set the COLLECT_NAMES environment variable, the problems -# vanish in a puff of smoke. -if test "X${COLLECT_NAMES+set}" != Xset; then - COLLECT_NAMES= - export COLLECT_NAMES -fi -_LT_EOF - ;; - esac - - _LT_PROG_LTMAIN - - # We use sed instead of cat because bash on DJGPP gets confused if - # if finds mixed CR/LF and LF-only lines. Since sed operates in - # text mode, it properly converts lines to CR/LF. This bash problem - # is reportedly fixed, but why not run on old versions too? - sed '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \ - || (rm -f "$cfgfile"; exit 1) - - _LT_PROG_XSI_SHELLFNS - - sed -n '/^# Generated shell functions inserted here/,$p' "$ltmain" >> "$cfgfile" \ - || (rm -f "$cfgfile"; exit 1) - - mv -f "$cfgfile" "$ofile" || - (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") - chmod +x "$ofile" -], -[cat <<_LT_EOF >> "$ofile" - -dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded -dnl in a comment (ie after a #). -# ### BEGIN LIBTOOL TAG CONFIG: $1 -_LT_LIBTOOL_TAG_VARS(_LT_TAG) -# ### END LIBTOOL TAG CONFIG: $1 -_LT_EOF -])dnl /m4_if -], -[m4_if([$1], [], [ - PACKAGE='$PACKAGE' - VERSION='$VERSION' - TIMESTAMP='$TIMESTAMP' - RM='$RM' - ofile='$ofile'], []) -])dnl /_LT_CONFIG_SAVE_COMMANDS -])# _LT_CONFIG - - -# LT_SUPPORTED_TAG(TAG) -# --------------------- -# Trace this macro to discover what tags are supported by the libtool -# --tag option, using: -# autoconf --trace 'LT_SUPPORTED_TAG:$1' -AC_DEFUN([LT_SUPPORTED_TAG], []) - - -# C support is built-in for now -m4_define([_LT_LANG_C_enabled], []) -m4_define([_LT_TAGS], []) - - -# LT_LANG(LANG) -# ------------- -# Enable libtool support for the given language if not already enabled. -AC_DEFUN([LT_LANG], -[AC_BEFORE([$0], [LT_OUTPUT])dnl -m4_case([$1], - [C], [_LT_LANG(C)], - [C++], [_LT_LANG(CXX)], - [Java], [_LT_LANG(GCJ)], - [Fortran 77], [_LT_LANG(F77)], - [Fortran], [_LT_LANG(FC)], - [Windows Resource], [_LT_LANG(RC)], - [m4_ifdef([_LT_LANG_]$1[_CONFIG], - [_LT_LANG($1)], - [m4_fatal([$0: unsupported language: "$1"])])])dnl -])# LT_LANG - - -# _LT_LANG(LANGNAME) -# ------------------ -m4_defun([_LT_LANG], -[m4_ifdef([_LT_LANG_]$1[_enabled], [], - [LT_SUPPORTED_TAG([$1])dnl - m4_append([_LT_TAGS], [$1 ])dnl - m4_define([_LT_LANG_]$1[_enabled], [])dnl - _LT_LANG_$1_CONFIG($1)])dnl -])# _LT_LANG - - -# _LT_LANG_DEFAULT_CONFIG -# ----------------------- -m4_defun([_LT_LANG_DEFAULT_CONFIG], -[AC_PROVIDE_IFELSE([AC_PROG_CXX], - [LT_LANG(CXX)], - [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) - -AC_PROVIDE_IFELSE([AC_PROG_F77], - [LT_LANG(F77)], - [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) - -AC_PROVIDE_IFELSE([AC_PROG_FC], - [LT_LANG(FC)], - [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) - -dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal -dnl pulling things in needlessly. -AC_PROVIDE_IFELSE([AC_PROG_GCJ], - [LT_LANG(GCJ)], - [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], - [LT_LANG(GCJ)], - [AC_PROVIDE_IFELSE([LT_PROG_GCJ], - [LT_LANG(GCJ)], - [m4_ifdef([AC_PROG_GCJ], - [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) - m4_ifdef([A][M_PROG_GCJ], - [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) - m4_ifdef([LT_PROG_GCJ], - [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) - -AC_PROVIDE_IFELSE([LT_PROG_RC], - [LT_LANG(RC)], - [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) -])# _LT_LANG_DEFAULT_CONFIG - -# Obsolete macros: -AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) -AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) -AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) -AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_CXX], []) -dnl AC_DEFUN([AC_LIBTOOL_F77], []) -dnl AC_DEFUN([AC_LIBTOOL_FC], []) -dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) - - -# _LT_TAG_COMPILER -# ---------------- -m4_defun([_LT_TAG_COMPILER], -[AC_REQUIRE([AC_PROG_CC])dnl - -_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl -_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl -_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl -_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl - -# If no C compiler was specified, use CC. -LTCC=${LTCC-"$CC"} - -# If no C compiler flags were specified, use CFLAGS. -LTCFLAGS=${LTCFLAGS-"$CFLAGS"} - -# Allow CC to be a program name with arguments. -compiler=$CC -])# _LT_TAG_COMPILER - - -# _LT_COMPILER_BOILERPLATE -# ------------------------ -# Check for compiler boilerplate output or warnings with -# the simple compiler test code. -m4_defun([_LT_COMPILER_BOILERPLATE], -[m4_require([_LT_DECL_SED])dnl -ac_outfile=conftest.$ac_objext -echo "$lt_simple_compile_test_code" >conftest.$ac_ext -eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err -_lt_compiler_boilerplate=`cat conftest.err` -$RM conftest* -])# _LT_COMPILER_BOILERPLATE - - -# _LT_LINKER_BOILERPLATE -# ---------------------- -# Check for linker boilerplate output or warnings with -# the simple link test code. -m4_defun([_LT_LINKER_BOILERPLATE], -[m4_require([_LT_DECL_SED])dnl -ac_outfile=conftest.$ac_objext -echo "$lt_simple_link_test_code" >conftest.$ac_ext -eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err -_lt_linker_boilerplate=`cat conftest.err` -$RM -r conftest* -])# _LT_LINKER_BOILERPLATE - -# _LT_REQUIRED_DARWIN_CHECKS -# ------------------------- -m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ - case $host_os in - rhapsody* | darwin*) - AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) - AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) - AC_CHECK_TOOL([LIPO], [lipo], [:]) - AC_CHECK_TOOL([OTOOL], [otool], [:]) - AC_CHECK_TOOL([OTOOL64], [otool64], [:]) - _LT_DECL([], [DSYMUTIL], [1], - [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) - _LT_DECL([], [NMEDIT], [1], - [Tool to change global to local symbols on Mac OS X]) - _LT_DECL([], [LIPO], [1], - [Tool to manipulate fat objects and archives on Mac OS X]) - _LT_DECL([], [OTOOL], [1], - [ldd/readelf like tool for Mach-O binaries on Mac OS X]) - _LT_DECL([], [OTOOL64], [1], - [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) - - AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], - [lt_cv_apple_cc_single_mod=no - if test -z "${LT_MULTI_MODULE}"; then - # By default we will add the -single_module flag. You can override - # by either setting the environment variable LT_MULTI_MODULE - # non-empty at configure time, or by adding -multi_module to the - # link flags. - rm -rf libconftest.dylib* - echo "int foo(void){return 1;}" > conftest.c - echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ --dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD - $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ - -dynamiclib -Wl,-single_module conftest.c 2>conftest.err - _lt_result=$? - if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then - lt_cv_apple_cc_single_mod=yes - else - cat conftest.err >&AS_MESSAGE_LOG_FD - fi - rm -rf libconftest.dylib* - rm -f conftest.* - fi]) - AC_CACHE_CHECK([for -exported_symbols_list linker flag], - [lt_cv_ld_exported_symbols_list], - [lt_cv_ld_exported_symbols_list=no - save_LDFLAGS=$LDFLAGS - echo "_main" > conftest.sym - LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" - AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], - [lt_cv_ld_exported_symbols_list=yes], - [lt_cv_ld_exported_symbols_list=no]) - LDFLAGS="$save_LDFLAGS" - ]) - case $host_os in - rhapsody* | darwin1.[[012]]) - _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; - darwin1.*) - _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; - darwin*) # darwin 5.x on - # if running on 10.5 or later, the deployment target defaults - # to the OS version, if on x86, and 10.4, the deployment - # target defaults to 10.4. Don't you love it? - case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in - 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) - _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; - 10.[[012]]*) - _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; - 10.*) - _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; - esac - ;; - esac - if test "$lt_cv_apple_cc_single_mod" = "yes"; then - _lt_dar_single_mod='$single_module' - fi - if test "$lt_cv_ld_exported_symbols_list" = "yes"; then - _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' - else - _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' - fi - if test "$DSYMUTIL" != ":"; then - _lt_dsymutil='~$DSYMUTIL $lib || :' - else - _lt_dsymutil= - fi - ;; - esac -]) - - -# _LT_DARWIN_LINKER_FEATURES -# -------------------------- -# Checks for linker and compiler features on darwin -m4_defun([_LT_DARWIN_LINKER_FEATURES], -[ - m4_require([_LT_REQUIRED_DARWIN_CHECKS]) - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_automatic, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported - _LT_TAGVAR(whole_archive_flag_spec, $1)='' - _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined" - case $cc_basename in - ifort*) _lt_dar_can_shared=yes ;; - *) _lt_dar_can_shared=$GCC ;; - esac - if test "$_lt_dar_can_shared" = "yes"; then - output_verbose_link_cmd=echo - _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" - _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" - _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" - _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" - m4_if([$1], [CXX], -[ if test "$lt_cv_apple_cc_single_mod" != "yes"; then - _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" - _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" - fi -],[]) - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi -]) - -# _LT_SYS_MODULE_PATH_AIX -# ----------------------- -# Links a minimal program and checks the executable -# for the system default hardcoded library path. In most cases, -# this is /usr/lib:/lib, but when the MPI compilers are used -# the location of the communication and MPI libs are included too. -# If we don't find anything, use the default library path according -# to the aix ld manual. -m4_defun([_LT_SYS_MODULE_PATH_AIX], -[m4_require([_LT_DECL_SED])dnl -AC_LINK_IFELSE(AC_LANG_PROGRAM,[ -lt_aix_libpath_sed=' - /Import File Strings/,/^$/ { - /^0/ { - s/^0 *\(.*\)$/\1/ - p - } - }' -aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` -# Check for a 64-bit object if we didn't find anything. -if test -z "$aix_libpath"; then - aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` -fi],[]) -if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi -])# _LT_SYS_MODULE_PATH_AIX - - -# _LT_SHELL_INIT(ARG) -# ------------------- -m4_define([_LT_SHELL_INIT], -[ifdef([AC_DIVERSION_NOTICE], - [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)], - [AC_DIVERT_PUSH(NOTICE)]) -$1 -AC_DIVERT_POP -])# _LT_SHELL_INIT - - -# _LT_PROG_ECHO_BACKSLASH -# ----------------------- -# Add some code to the start of the generated configure script which -# will find an echo command which doesn't interpret backslashes. -m4_defun([_LT_PROG_ECHO_BACKSLASH], -[_LT_SHELL_INIT([ -# Check that we are running under the correct shell. -SHELL=${CONFIG_SHELL-/bin/sh} - -case X$lt_ECHO in -X*--fallback-echo) - # Remove one level of quotation (which was required for Make). - ECHO=`echo "$lt_ECHO" | sed 's,\\\\\[$]\\[$]0,'[$]0','` - ;; -esac - -ECHO=${lt_ECHO-echo} -if test "X[$]1" = X--no-reexec; then - # Discard the --no-reexec flag, and continue. - shift -elif test "X[$]1" = X--fallback-echo; then - # Avoid inline document here, it may be left over - : -elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' ; then - # Yippee, $ECHO works! - : -else - # Restart under the correct shell. - exec $SHELL "[$]0" --no-reexec ${1+"[$]@"} -fi - -if test "X[$]1" = X--fallback-echo; then - # used as fallback echo - shift - cat <<_LT_EOF -[$]* -_LT_EOF - exit 0 -fi - -# The HP-UX ksh and POSIX shell print the target directory to stdout -# if CDPATH is set. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - -if test -z "$lt_ECHO"; then - if test "X${echo_test_string+set}" != Xset; then - # find a string as large as possible, as long as the shell can cope with it - for cmd in 'sed 50q "[$]0"' 'sed 20q "[$]0"' 'sed 10q "[$]0"' 'sed 2q "[$]0"' 'echo test'; do - # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... - if { echo_test_string=`eval $cmd`; } 2>/dev/null && - { test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null - then - break - fi - done - fi - - if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && - echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - : - else - # The Solaris, AIX, and Digital Unix default echo programs unquote - # backslashes. This makes it impossible to quote backslashes using - # echo "$something" | sed 's/\\/\\\\/g' - # - # So, first we look for a working echo in the user's PATH. - - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - for dir in $PATH /usr/ucb; do - IFS="$lt_save_ifs" - if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && - test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && - echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - ECHO="$dir/echo" - break - fi - done - IFS="$lt_save_ifs" - - if test "X$ECHO" = Xecho; then - # We didn't find a better echo, so look for alternatives. - if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' && - echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - # This shell has a builtin print -r that does the trick. - ECHO='print -r' - elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } && - test "X$CONFIG_SHELL" != X/bin/ksh; then - # If we have ksh, try running configure again with it. - ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} - export ORIGINAL_CONFIG_SHELL - CONFIG_SHELL=/bin/ksh - export CONFIG_SHELL - exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"} - else - # Try using printf. - ECHO='printf %s\n' - if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && - echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - # Cool, printf works - : - elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && - test "X$echo_testing_string" = 'X\t' && - echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL - export CONFIG_SHELL - SHELL="$CONFIG_SHELL" - export SHELL - ECHO="$CONFIG_SHELL [$]0 --fallback-echo" - elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && - test "X$echo_testing_string" = 'X\t' && - echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - ECHO="$CONFIG_SHELL [$]0 --fallback-echo" - else - # maybe with a smaller string... - prev=: - - for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do - if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null - then - break - fi - prev="$cmd" - done - - if test "$prev" != 'sed 50q "[$]0"'; then - echo_test_string=`eval $prev` - export echo_test_string - exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"} - else - # Oops. We lost completely, so just stick with echo. - ECHO=echo - fi - fi - fi - fi - fi -fi - -# Copy echo and quote the copy suitably for passing to libtool from -# the Makefile, instead of quoting the original, which is used later. -lt_ECHO=$ECHO -if test "X$lt_ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then - lt_ECHO="$CONFIG_SHELL \\\$\[$]0 --fallback-echo" -fi - -AC_SUBST(lt_ECHO) -]) -_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) -_LT_DECL([], [ECHO], [1], - [An echo program that does not interpret backslashes]) -])# _LT_PROG_ECHO_BACKSLASH - - -# _LT_ENABLE_LOCK -# --------------- -m4_defun([_LT_ENABLE_LOCK], -[AC_ARG_ENABLE([libtool-lock], - [AS_HELP_STRING([--disable-libtool-lock], - [avoid locking (might break parallel builds)])]) -test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes - -# Some flags need to be propagated to the compiler or linker for good -# libtool support. -case $host in -ia64-*-hpux*) - # Find out which ABI we are using. - echo 'int i;' > conftest.$ac_ext - if AC_TRY_EVAL(ac_compile); then - case `/usr/bin/file conftest.$ac_objext` in - *ELF-32*) - HPUX_IA64_MODE="32" - ;; - *ELF-64*) - HPUX_IA64_MODE="64" - ;; - esac - fi - rm -rf conftest* - ;; -*-*-irix6*) - # Find out which ABI we are using. - echo '[#]line __oline__ "configure"' > conftest.$ac_ext - if AC_TRY_EVAL(ac_compile); then - if test "$lt_cv_prog_gnu_ld" = yes; then - case `/usr/bin/file conftest.$ac_objext` in - *32-bit*) - LD="${LD-ld} -melf32bsmip" - ;; - *N32*) - LD="${LD-ld} -melf32bmipn32" - ;; - *64-bit*) - LD="${LD-ld} -melf64bmip" - ;; - esac - else - case `/usr/bin/file conftest.$ac_objext` in - *32-bit*) - LD="${LD-ld} -32" - ;; - *N32*) - LD="${LD-ld} -n32" - ;; - *64-bit*) - LD="${LD-ld} -64" - ;; - esac - fi - fi - rm -rf conftest* - ;; - -x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ -s390*-*linux*|s390*-*tpf*|sparc*-*linux*) - # Find out which ABI we are using. - echo 'int i;' > conftest.$ac_ext - if AC_TRY_EVAL(ac_compile); then - case `/usr/bin/file conftest.o` in - *32-bit*) - case $host in - x86_64-*kfreebsd*-gnu) - LD="${LD-ld} -m elf_i386_fbsd" - ;; - x86_64-*linux*) - LD="${LD-ld} -m elf_i386" - ;; - ppc64-*linux*|powerpc64-*linux*) - LD="${LD-ld} -m elf32ppclinux" - ;; - s390x-*linux*) - LD="${LD-ld} -m elf_s390" - ;; - sparc64-*linux*) - LD="${LD-ld} -m elf32_sparc" - ;; - esac - ;; - *64-bit*) - case $host in - x86_64-*kfreebsd*-gnu) - LD="${LD-ld} -m elf_x86_64_fbsd" - ;; - x86_64-*linux*) - LD="${LD-ld} -m elf_x86_64" - ;; - ppc*-*linux*|powerpc*-*linux*) - LD="${LD-ld} -m elf64ppc" - ;; - s390*-*linux*|s390*-*tpf*) - LD="${LD-ld} -m elf64_s390" - ;; - sparc*-*linux*) - LD="${LD-ld} -m elf64_sparc" - ;; - esac - ;; - esac - fi - rm -rf conftest* - ;; - -*-*-sco3.2v5*) - # On SCO OpenServer 5, we need -belf to get full-featured binaries. - SAVE_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -belf" - AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, - [AC_LANG_PUSH(C) - AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) - AC_LANG_POP]) - if test x"$lt_cv_cc_needs_belf" != x"yes"; then - # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf - CFLAGS="$SAVE_CFLAGS" - fi - ;; -sparc*-*solaris*) - # Find out which ABI we are using. - echo 'int i;' > conftest.$ac_ext - if AC_TRY_EVAL(ac_compile); then - case `/usr/bin/file conftest.o` in - *64-bit*) - case $lt_cv_prog_gnu_ld in - yes*) LD="${LD-ld} -m elf64_sparc" ;; - *) - if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then - LD="${LD-ld} -64" - fi - ;; - esac - ;; - esac - fi - rm -rf conftest* - ;; -esac - -need_locks="$enable_libtool_lock" -])# _LT_ENABLE_LOCK - - -# _LT_CMD_OLD_ARCHIVE -# ------------------- -m4_defun([_LT_CMD_OLD_ARCHIVE], -[AC_CHECK_TOOL(AR, ar, false) -test -z "$AR" && AR=ar -test -z "$AR_FLAGS" && AR_FLAGS=cru -_LT_DECL([], [AR], [1], [The archiver]) -_LT_DECL([], [AR_FLAGS], [1]) - -AC_CHECK_TOOL(STRIP, strip, :) -test -z "$STRIP" && STRIP=: -_LT_DECL([], [STRIP], [1], [A symbol stripping program]) - -AC_CHECK_TOOL(RANLIB, ranlib, :) -test -z "$RANLIB" && RANLIB=: -_LT_DECL([], [RANLIB], [1], - [Commands used to install an old-style archive]) - -# Determine commands to create old-style static archives. -old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' -old_postinstall_cmds='chmod 644 $oldlib' -old_postuninstall_cmds= - -if test -n "$RANLIB"; then - case $host_os in - openbsd*) - old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" - ;; - *) - old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" - ;; - esac - old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" -fi -_LT_DECL([], [old_postinstall_cmds], [2]) -_LT_DECL([], [old_postuninstall_cmds], [2]) -_LT_TAGDECL([], [old_archive_cmds], [2], - [Commands used to build an old-style archive]) -])# _LT_CMD_OLD_ARCHIVE - - -# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, -# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) -# ---------------------------------------------------------------- -# Check whether the given compiler option works -AC_DEFUN([_LT_COMPILER_OPTION], -[m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_DECL_SED])dnl -AC_CACHE_CHECK([$1], [$2], - [$2=no - m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - lt_compiler_flag="$3" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - # The option is referenced via a variable to avoid confusing sed. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD) - (eval "$lt_compile" 2>conftest.err) - ac_status=$? - cat conftest.err >&AS_MESSAGE_LOG_FD - echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD - if (exit $ac_status) && test -s "$ac_outfile"; then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings other than the usual output. - $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp - $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 - if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then - $2=yes - fi - fi - $RM conftest* -]) - -if test x"[$]$2" = xyes; then - m4_if([$5], , :, [$5]) -else - m4_if([$6], , :, [$6]) -fi -])# _LT_COMPILER_OPTION - -# Old name: -AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) - - -# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, -# [ACTION-SUCCESS], [ACTION-FAILURE]) -# ---------------------------------------------------- -# Check whether the given linker option works -AC_DEFUN([_LT_LINKER_OPTION], -[m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_DECL_SED])dnl -AC_CACHE_CHECK([$1], [$2], - [$2=no - save_LDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS $3" - echo "$lt_simple_link_test_code" > conftest.$ac_ext - if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then - # The linker can only warn and ignore the option if not recognized - # So say no if there are warnings - if test -s conftest.err; then - # Append any errors to the config.log. - cat conftest.err 1>&AS_MESSAGE_LOG_FD - $ECHO "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp - $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 - if diff conftest.exp conftest.er2 >/dev/null; then - $2=yes - fi - else - $2=yes - fi - fi - $RM -r conftest* - LDFLAGS="$save_LDFLAGS" -]) - -if test x"[$]$2" = xyes; then - m4_if([$4], , :, [$4]) -else - m4_if([$5], , :, [$5]) -fi -])# _LT_LINKER_OPTION - -# Old name: -AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) - - -# LT_CMD_MAX_LEN -#--------------- -AC_DEFUN([LT_CMD_MAX_LEN], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -# find the maximum length of command line arguments -AC_MSG_CHECKING([the maximum length of command line arguments]) -AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl - i=0 - teststring="ABCD" - - case $build_os in - msdosdjgpp*) - # On DJGPP, this test can blow up pretty badly due to problems in libc - # (any single argument exceeding 2000 bytes causes a buffer overrun - # during glob expansion). Even if it were fixed, the result of this - # check would be larger than it should be. - lt_cv_sys_max_cmd_len=12288; # 12K is about right - ;; - - gnu*) - # Under GNU Hurd, this test is not required because there is - # no limit to the length of command line arguments. - # Libtool will interpret -1 as no limit whatsoever - lt_cv_sys_max_cmd_len=-1; - ;; - - cygwin* | mingw* | cegcc*) - # On Win9x/ME, this test blows up -- it succeeds, but takes - # about 5 minutes as the teststring grows exponentially. - # Worse, since 9x/ME are not pre-emptively multitasking, - # you end up with a "frozen" computer, even though with patience - # the test eventually succeeds (with a max line length of 256k). - # Instead, let's just punt: use the minimum linelength reported by - # all of the supported platforms: 8192 (on NT/2K/XP). - lt_cv_sys_max_cmd_len=8192; - ;; - - amigaos*) - # On AmigaOS with pdksh, this test takes hours, literally. - # So we just punt and use a minimum line length of 8192. - lt_cv_sys_max_cmd_len=8192; - ;; - - netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) - # This has been around since 386BSD, at least. Likely further. - if test -x /sbin/sysctl; then - lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` - elif test -x /usr/sbin/sysctl; then - lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` - else - lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs - fi - # And add a safety zone - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` - ;; - - interix*) - # We know the value 262144 and hardcode it with a safety zone (like BSD) - lt_cv_sys_max_cmd_len=196608 - ;; - - osf*) - # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure - # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not - # nice to cause kernel panics so lets avoid the loop below. - # First set a reasonable default. - lt_cv_sys_max_cmd_len=16384 - # - if test -x /sbin/sysconfig; then - case `/sbin/sysconfig -q proc exec_disable_arg_limit` in - *1*) lt_cv_sys_max_cmd_len=-1 ;; - esac - fi - ;; - sco3.2v5*) - lt_cv_sys_max_cmd_len=102400 - ;; - sysv5* | sco5v6* | sysv4.2uw2*) - kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` - if test -n "$kargmax"; then - lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` - else - lt_cv_sys_max_cmd_len=32768 - fi - ;; - *) - lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` - if test -n "$lt_cv_sys_max_cmd_len"; then - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` - else - # Make teststring a little bigger before we do anything with it. - # a 1K string should be a reasonable start. - for i in 1 2 3 4 5 6 7 8 ; do - teststring=$teststring$teststring - done - SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} - # If test is not a shell built-in, we'll probably end up computing a - # maximum length that is only half of the actual maximum length, but - # we can't tell. - while { test "X"`$SHELL [$]0 --fallback-echo "X$teststring$teststring" 2>/dev/null` \ - = "XX$teststring$teststring"; } >/dev/null 2>&1 && - test $i != 17 # 1/2 MB should be enough - do - i=`expr $i + 1` - teststring=$teststring$teststring - done - # Only check the string length outside the loop. - lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` - teststring= - # Add a significant safety factor because C++ compilers can tack on - # massive amounts of additional arguments before passing them to the - # linker. It appears as though 1/2 is a usable value. - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` - fi - ;; - esac -]) -if test -n $lt_cv_sys_max_cmd_len ; then - AC_MSG_RESULT($lt_cv_sys_max_cmd_len) -else - AC_MSG_RESULT(none) -fi -max_cmd_len=$lt_cv_sys_max_cmd_len -_LT_DECL([], [max_cmd_len], [0], - [What is the maximum length of a command?]) -])# LT_CMD_MAX_LEN - -# Old name: -AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) - - -# _LT_HEADER_DLFCN -# ---------------- -m4_defun([_LT_HEADER_DLFCN], -[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl -])# _LT_HEADER_DLFCN - - -# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, -# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) -# ---------------------------------------------------------------- -m4_defun([_LT_TRY_DLOPEN_SELF], -[m4_require([_LT_HEADER_DLFCN])dnl -if test "$cross_compiling" = yes; then : - [$4] -else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF -[#line __oline__ "configure" -#include "confdefs.h" - -#if HAVE_DLFCN_H -#include -#endif - -#include - -#ifdef RTLD_GLOBAL -# define LT_DLGLOBAL RTLD_GLOBAL -#else -# ifdef DL_GLOBAL -# define LT_DLGLOBAL DL_GLOBAL -# else -# define LT_DLGLOBAL 0 -# endif -#endif - -/* We may have to define LT_DLLAZY_OR_NOW in the command line if we - find out it does not work in some platform. */ -#ifndef LT_DLLAZY_OR_NOW -# ifdef RTLD_LAZY -# define LT_DLLAZY_OR_NOW RTLD_LAZY -# else -# ifdef DL_LAZY -# define LT_DLLAZY_OR_NOW DL_LAZY -# else -# ifdef RTLD_NOW -# define LT_DLLAZY_OR_NOW RTLD_NOW -# else -# ifdef DL_NOW -# define LT_DLLAZY_OR_NOW DL_NOW -# else -# define LT_DLLAZY_OR_NOW 0 -# endif -# endif -# endif -# endif -#endif - -void fnord() { int i=42;} -int main () -{ - void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); - int status = $lt_dlunknown; - - if (self) - { - if (dlsym (self,"fnord")) status = $lt_dlno_uscore; - else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; - /* dlclose (self); */ - } - else - puts (dlerror ()); - - return status; -}] -_LT_EOF - if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then - (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null - lt_status=$? - case x$lt_status in - x$lt_dlno_uscore) $1 ;; - x$lt_dlneed_uscore) $2 ;; - x$lt_dlunknown|x*) $3 ;; - esac - else : - # compilation failed - $3 - fi -fi -rm -fr conftest* -])# _LT_TRY_DLOPEN_SELF - - -# LT_SYS_DLOPEN_SELF -# ------------------ -AC_DEFUN([LT_SYS_DLOPEN_SELF], -[m4_require([_LT_HEADER_DLFCN])dnl -if test "x$enable_dlopen" != xyes; then - enable_dlopen=unknown - enable_dlopen_self=unknown - enable_dlopen_self_static=unknown -else - lt_cv_dlopen=no - lt_cv_dlopen_libs= - - case $host_os in - beos*) - lt_cv_dlopen="load_add_on" - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - ;; - - mingw* | pw32* | cegcc*) - lt_cv_dlopen="LoadLibrary" - lt_cv_dlopen_libs= - ;; - - cygwin*) - lt_cv_dlopen="dlopen" - lt_cv_dlopen_libs= - ;; - - darwin*) - # if libdl is installed we need to link against it - AC_CHECK_LIB([dl], [dlopen], - [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ - lt_cv_dlopen="dyld" - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - ]) - ;; - - *) - AC_CHECK_FUNC([shl_load], - [lt_cv_dlopen="shl_load"], - [AC_CHECK_LIB([dld], [shl_load], - [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"], - [AC_CHECK_FUNC([dlopen], - [lt_cv_dlopen="dlopen"], - [AC_CHECK_LIB([dl], [dlopen], - [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], - [AC_CHECK_LIB([svld], [dlopen], - [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], - [AC_CHECK_LIB([dld], [dld_link], - [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"]) - ]) - ]) - ]) - ]) - ]) - ;; - esac - - if test "x$lt_cv_dlopen" != xno; then - enable_dlopen=yes - else - enable_dlopen=no - fi - - case $lt_cv_dlopen in - dlopen) - save_CPPFLAGS="$CPPFLAGS" - test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" - - save_LDFLAGS="$LDFLAGS" - wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" - - save_LIBS="$LIBS" - LIBS="$lt_cv_dlopen_libs $LIBS" - - AC_CACHE_CHECK([whether a program can dlopen itself], - lt_cv_dlopen_self, [dnl - _LT_TRY_DLOPEN_SELF( - lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, - lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) - ]) - - if test "x$lt_cv_dlopen_self" = xyes; then - wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" - AC_CACHE_CHECK([whether a statically linked program can dlopen itself], - lt_cv_dlopen_self_static, [dnl - _LT_TRY_DLOPEN_SELF( - lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, - lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) - ]) - fi - - CPPFLAGS="$save_CPPFLAGS" - LDFLAGS="$save_LDFLAGS" - LIBS="$save_LIBS" - ;; - esac - - case $lt_cv_dlopen_self in - yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; - *) enable_dlopen_self=unknown ;; - esac - - case $lt_cv_dlopen_self_static in - yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; - *) enable_dlopen_self_static=unknown ;; - esac -fi -_LT_DECL([dlopen_support], [enable_dlopen], [0], - [Whether dlopen is supported]) -_LT_DECL([dlopen_self], [enable_dlopen_self], [0], - [Whether dlopen of programs is supported]) -_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], - [Whether dlopen of statically linked programs is supported]) -])# LT_SYS_DLOPEN_SELF - -# Old name: -AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) - - -# _LT_COMPILER_C_O([TAGNAME]) -# --------------------------- -# Check to see if options -c and -o are simultaneously supported by compiler. -# This macro does not hard code the compiler like AC_PROG_CC_C_O. -m4_defun([_LT_COMPILER_C_O], -[m4_require([_LT_DECL_SED])dnl -m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_TAG_COMPILER])dnl -AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], - [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], - [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no - $RM -r conftest 2>/dev/null - mkdir conftest - cd conftest - mkdir out - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - - lt_compiler_flag="-o out/conftest2.$ac_objext" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD) - (eval "$lt_compile" 2>out/conftest.err) - ac_status=$? - cat out/conftest.err >&AS_MESSAGE_LOG_FD - echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD - if (exit $ac_status) && test -s out/conftest2.$ac_objext - then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp - $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 - if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then - _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes - fi - fi - chmod u+w . 2>&AS_MESSAGE_LOG_FD - $RM conftest* - # SGI C++ compiler will create directory out/ii_files/ for - # template instantiation - test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files - $RM out/* && rmdir out - cd .. - $RM -r conftest - $RM conftest* -]) -_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], - [Does compiler simultaneously support -c and -o options?]) -])# _LT_COMPILER_C_O - - -# _LT_COMPILER_FILE_LOCKS([TAGNAME]) -# ---------------------------------- -# Check to see if we can do hard links to lock some files if needed -m4_defun([_LT_COMPILER_FILE_LOCKS], -[m4_require([_LT_ENABLE_LOCK])dnl -m4_require([_LT_FILEUTILS_DEFAULTS])dnl -_LT_COMPILER_C_O([$1]) - -hard_links="nottested" -if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then - # do not overwrite the value of need_locks provided by the user - AC_MSG_CHECKING([if we can lock with hard links]) - hard_links=yes - $RM conftest* - ln conftest.a conftest.b 2>/dev/null && hard_links=no - touch conftest.a - ln conftest.a conftest.b 2>&5 || hard_links=no - ln conftest.a conftest.b 2>/dev/null && hard_links=no - AC_MSG_RESULT([$hard_links]) - if test "$hard_links" = no; then - AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) - need_locks=warn - fi -else - need_locks=no -fi -_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) -])# _LT_COMPILER_FILE_LOCKS - - -# _LT_CHECK_OBJDIR -# ---------------- -m4_defun([_LT_CHECK_OBJDIR], -[AC_CACHE_CHECK([for objdir], [lt_cv_objdir], -[rm -f .libs 2>/dev/null -mkdir .libs 2>/dev/null -if test -d .libs; then - lt_cv_objdir=.libs -else - # MS-DOS does not allow filenames that begin with a dot. - lt_cv_objdir=_libs -fi -rmdir .libs 2>/dev/null]) -objdir=$lt_cv_objdir -_LT_DECL([], [objdir], [0], - [The name of the directory that contains temporary libtool files])dnl -m4_pattern_allow([LT_OBJDIR])dnl -AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/", - [Define to the sub-directory in which libtool stores uninstalled libraries.]) -])# _LT_CHECK_OBJDIR - - -# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) -# -------------------------------------- -# Check hardcoding attributes. -m4_defun([_LT_LINKER_HARDCODE_LIBPATH], -[AC_MSG_CHECKING([how to hardcode library paths into programs]) -_LT_TAGVAR(hardcode_action, $1)= -if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || - test -n "$_LT_TAGVAR(runpath_var, $1)" || - test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then - - # We can hardcode non-existent directories. - if test "$_LT_TAGVAR(hardcode_direct, $1)" != no && - # If the only mechanism to avoid hardcoding is shlibpath_var, we - # have to relink, otherwise we might link with an installed library - # when we should be linking with a yet-to-be-installed one - ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no && - test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then - # Linking always hardcodes the temporary library directory. - _LT_TAGVAR(hardcode_action, $1)=relink - else - # We can link without hardcoding, and we can hardcode nonexisting dirs. - _LT_TAGVAR(hardcode_action, $1)=immediate - fi -else - # We cannot hardcode anything, or else we can only hardcode existing - # directories. - _LT_TAGVAR(hardcode_action, $1)=unsupported -fi -AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) - -if test "$_LT_TAGVAR(hardcode_action, $1)" = relink || - test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then - # Fast installation is not supported - enable_fast_install=no -elif test "$shlibpath_overrides_runpath" = yes || - test "$enable_shared" = no; then - # Fast installation is not necessary - enable_fast_install=needless -fi -_LT_TAGDECL([], [hardcode_action], [0], - [How to hardcode a shared library path into an executable]) -])# _LT_LINKER_HARDCODE_LIBPATH - - -# _LT_CMD_STRIPLIB -# ---------------- -m4_defun([_LT_CMD_STRIPLIB], -[m4_require([_LT_DECL_EGREP]) -striplib= -old_striplib= -AC_MSG_CHECKING([whether stripping libraries is possible]) -if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then - test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" - test -z "$striplib" && striplib="$STRIP --strip-unneeded" - AC_MSG_RESULT([yes]) -else -# FIXME - insert some real tests, host_os isn't really good enough - case $host_os in - darwin*) - if test -n "$STRIP" ; then - striplib="$STRIP -x" - old_striplib="$STRIP -S" - AC_MSG_RESULT([yes]) - else - AC_MSG_RESULT([no]) - fi - ;; - *) - AC_MSG_RESULT([no]) - ;; - esac -fi -_LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) -_LT_DECL([], [striplib], [1]) -])# _LT_CMD_STRIPLIB - - -# _LT_SYS_DYNAMIC_LINKER([TAG]) -# ----------------------------- -# PORTME Fill in your ld.so characteristics -m4_defun([_LT_SYS_DYNAMIC_LINKER], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -m4_require([_LT_DECL_EGREP])dnl -m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_DECL_OBJDUMP])dnl -m4_require([_LT_DECL_SED])dnl -AC_MSG_CHECKING([dynamic linker characteristics]) -m4_if([$1], - [], [ -if test "$GCC" = yes; then - case $host_os in - darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; - *) lt_awk_arg="/^libraries:/" ;; - esac - lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e "s,=/,/,g"` - if $ECHO "$lt_search_path_spec" | $GREP ';' >/dev/null ; then - # if the path contains ";" then we assume it to be the separator - # otherwise default to the standard path separator (i.e. ":") - it is - # assumed that no part of a normal pathname contains ";" but that should - # okay in the real world where ";" in dirpaths is itself problematic. - lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e 's/;/ /g'` - else - lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` - fi - # Ok, now we have the path, separated by spaces, we can step through it - # and add multilib dir if necessary. - lt_tmp_lt_search_path_spec= - lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` - for lt_sys_path in $lt_search_path_spec; do - if test -d "$lt_sys_path/$lt_multi_os_dir"; then - lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" - else - test -d "$lt_sys_path" && \ - lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" - fi - done - lt_search_path_spec=`$ECHO $lt_tmp_lt_search_path_spec | awk ' -BEGIN {RS=" "; FS="/|\n";} { - lt_foo=""; - lt_count=0; - for (lt_i = NF; lt_i > 0; lt_i--) { - if ($lt_i != "" && $lt_i != ".") { - if ($lt_i == "..") { - lt_count++; - } else { - if (lt_count == 0) { - lt_foo="/" $lt_i lt_foo; - } else { - lt_count--; - } - } - } - } - if (lt_foo != "") { lt_freq[[lt_foo]]++; } - if (lt_freq[[lt_foo]] == 1) { print lt_foo; } -}'` - sys_lib_search_path_spec=`$ECHO $lt_search_path_spec` -else - sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" -fi]) -library_names_spec= -libname_spec='lib$name' -soname_spec= -shrext_cmds=".so" -postinstall_cmds= -postuninstall_cmds= -finish_cmds= -finish_eval= -shlibpath_var= -shlibpath_overrides_runpath=unknown -version_type=none -dynamic_linker="$host_os ld.so" -sys_lib_dlsearch_path_spec="/lib /usr/lib" -need_lib_prefix=unknown -hardcode_into_libs=no - -# when you set need_version to no, make sure it does not cause -set_version -# flags to be left without arguments -need_version=unknown - -case $host_os in -aix3*) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' - shlibpath_var=LIBPATH - - # AIX 3 has no versioning support, so we append a major version to the name. - soname_spec='${libname}${release}${shared_ext}$major' - ;; - -aix[[4-9]]*) - version_type=linux - need_lib_prefix=no - need_version=no - hardcode_into_libs=yes - if test "$host_cpu" = ia64; then - # AIX 5 supports IA64 - library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - else - # With GCC up to 2.95.x, collect2 would create an import file - # for dependence libraries. The import file would start with - # the line `#! .'. This would cause the generated library to - # depend on `.', always an invalid library. This was fixed in - # development snapshots of GCC prior to 3.0. - case $host_os in - aix4 | aix4.[[01]] | aix4.[[01]].*) - if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' - echo ' yes ' - echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then - : - else - can_build_shared=no - fi - ;; - esac - # AIX (on Power*) has no versioning support, so currently we can not hardcode correct - # soname into executable. Probably we can add versioning support to - # collect2, so additional links can be useful in future. - if test "$aix_use_runtimelinking" = yes; then - # If using run time linking (on AIX 4.2 or later) use lib.so - # instead of lib.a to let people know that these are not - # typical AIX shared libraries. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - else - # We preserve .a as extension for shared libraries through AIX4.2 - # and later when we are not doing run time linking. - library_names_spec='${libname}${release}.a $libname.a' - soname_spec='${libname}${release}${shared_ext}$major' - fi - shlibpath_var=LIBPATH - fi - ;; - -amigaos*) - case $host_cpu in - powerpc) - # Since July 2007 AmigaOS4 officially supports .so libraries. - # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - ;; - m68k) - library_names_spec='$libname.ixlibrary $libname.a' - # Create ${libname}_ixlibrary.a entries in /sys/libs. - finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' - ;; - esac - ;; - -beos*) - library_names_spec='${libname}${shared_ext}' - dynamic_linker="$host_os ld.so" - shlibpath_var=LIBRARY_PATH - ;; - -bsdi[[45]]*) - version_type=linux - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" - sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" - # the default ld.so.conf also contains /usr/contrib/lib and - # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow - # libtool to hard-code these into programs - ;; - -cygwin* | mingw* | pw32* | cegcc*) - version_type=windows - shrext_cmds=".dll" - need_version=no - need_lib_prefix=no - - case $GCC,$host_os in - yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*) - library_names_spec='$libname.dll.a' - # DLL is installed to $(libdir)/../bin by postinstall_cmds - postinstall_cmds='base_file=`basename \${file}`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ - dldir=$destdir/`dirname \$dlpath`~ - test -d \$dldir || mkdir -p \$dldir~ - $install_prog $dir/$dlname \$dldir/$dlname~ - chmod a+x \$dldir/$dlname~ - if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then - eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; - fi' - postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ - dlpath=$dir/\$dldll~ - $RM \$dlpath' - shlibpath_overrides_runpath=yes - - case $host_os in - cygwin*) - # Cygwin DLLs use 'cyg' prefix rather than 'lib' - soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' - sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" - ;; - mingw* | cegcc*) - # MinGW DLLs use traditional 'lib' prefix - soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' - sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` - if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then - # It is most probably a Windows format PATH printed by - # mingw gcc, but we are running on Cygwin. Gcc prints its search - # path with ; separators, and with drive letters. We can handle the - # drive letters (cygwin fileutils understands them), so leave them, - # especially as we might pass files found there to a mingw objdump, - # which wouldn't understand a cygwinified path. Ahh. - sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` - else - sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` - fi - ;; - pw32*) - # pw32 DLLs use 'pw' prefix rather than 'lib' - library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' - ;; - esac - ;; - - *) - library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' - ;; - esac - dynamic_linker='Win32 ld.exe' - # FIXME: first we should search . and the directory the executable is in - shlibpath_var=PATH - ;; - -darwin* | rhapsody*) - dynamic_linker="$host_os dyld" - version_type=darwin - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' - soname_spec='${libname}${release}${major}$shared_ext' - shlibpath_overrides_runpath=yes - shlibpath_var=DYLD_LIBRARY_PATH - shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' -m4_if([$1], [],[ - sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) - sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' - ;; - -dgux*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -freebsd1*) - dynamic_linker=no - ;; - -freebsd* | dragonfly*) - # DragonFly does not have aout. When/if they implement a new - # versioning mechanism, adjust this. - if test -x /usr/bin/objformat; then - objformat=`/usr/bin/objformat` - else - case $host_os in - freebsd[[123]]*) objformat=aout ;; - *) objformat=elf ;; - esac - fi - version_type=freebsd-$objformat - case $version_type in - freebsd-elf*) - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' - need_version=no - need_lib_prefix=no - ;; - freebsd-*) - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' - need_version=yes - ;; - esac - shlibpath_var=LD_LIBRARY_PATH - case $host_os in - freebsd2*) - shlibpath_overrides_runpath=yes - ;; - freebsd3.[[01]]* | freebsdelf3.[[01]]*) - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ - freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - *) # from 4.6 on, and DragonFly - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - esac - ;; - -gnu*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - hardcode_into_libs=yes - ;; - -hpux9* | hpux10* | hpux11*) - # Give a soname corresponding to the major version so that dld.sl refuses to - # link against other versions. - version_type=sunos - need_lib_prefix=no - need_version=no - case $host_cpu in - ia64*) - shrext_cmds='.so' - hardcode_into_libs=yes - dynamic_linker="$host_os dld.so" - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - if test "X$HPUX_IA64_MODE" = X32; then - sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" - else - sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" - fi - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec - ;; - hppa*64*) - shrext_cmds='.sl' - hardcode_into_libs=yes - dynamic_linker="$host_os dld.sl" - shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH - shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec - ;; - *) - shrext_cmds='.sl' - dynamic_linker="$host_os dld.sl" - shlibpath_var=SHLIB_PATH - shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - ;; - esac - # HP-UX runs *really* slowly unless shared libraries are mode 555. - postinstall_cmds='chmod 555 $lib' - ;; - -interix[[3-9]]*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - -irix5* | irix6* | nonstopux*) - case $host_os in - nonstopux*) version_type=nonstopux ;; - *) - if test "$lt_cv_prog_gnu_ld" = yes; then - version_type=linux - else - version_type=irix - fi ;; - esac - need_lib_prefix=no - need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' - case $host_os in - irix5* | nonstopux*) - libsuff= shlibsuff= - ;; - *) - case $LD in # libtool.m4 will add one of these switches to LD - *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") - libsuff= shlibsuff= libmagic=32-bit;; - *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") - libsuff=32 shlibsuff=N32 libmagic=N32;; - *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") - libsuff=64 shlibsuff=64 libmagic=64-bit;; - *) libsuff= shlibsuff= libmagic=never-match;; - esac - ;; - esac - shlibpath_var=LD_LIBRARY${shlibsuff}_PATH - shlibpath_overrides_runpath=no - sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" - sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" - hardcode_into_libs=yes - ;; - -# No shared lib support for Linux oldld, aout, or coff. -linux*oldld* | linux*aout* | linux*coff*) - dynamic_linker=no - ;; - -# This must be Linux ELF. -linux* | k*bsd*-gnu) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - # Some binutils ld are patched to set DT_RUNPATH - save_LDFLAGS=$LDFLAGS - save_libdir=$libdir - eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ - LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" - AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], - [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], - [shlibpath_overrides_runpath=yes])]) - LDFLAGS=$save_LDFLAGS - libdir=$save_libdir - - # This implies no fast_install, which is unacceptable. - # Some rework will be needed to allow for fast_install - # before this can be enabled. - hardcode_into_libs=yes - - # Add ABI-specific directories to the system library path. - sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib" - - # Append ld.so.conf contents to the search path - if test -f /etc/ld.so.conf; then - lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` - sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra" - fi - - # We used to test for /lib/ld.so.1 and disable shared libraries on - # powerpc, because MkLinux only supported shared libraries with the - # GNU dynamic linker. Since this was broken with cross compilers, - # most powerpc-linux boxes support dynamic linking these days and - # people can always --disable-shared, the test was removed, and we - # assume the GNU/Linux dynamic linker is in use. - dynamic_linker='GNU/Linux ld.so' - ;; - -netbsd*) - version_type=sunos - need_lib_prefix=no - need_version=no - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - dynamic_linker='NetBSD (a.out) ld.so' - else - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - dynamic_linker='NetBSD ld.elf_so' - fi - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - -newsos6) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - ;; - -*nto* | *qnx*) - version_type=qnx - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='ldqnx.so' - ;; - -openbsd*) - version_type=sunos - sys_lib_dlsearch_path_spec="/usr/lib" - need_lib_prefix=no - # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. - case $host_os in - openbsd3.3 | openbsd3.3.*) need_version=yes ;; - *) need_version=no ;; - esac - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - shlibpath_var=LD_LIBRARY_PATH - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - case $host_os in - openbsd2.[[89]] | openbsd2.[[89]].*) - shlibpath_overrides_runpath=no - ;; - *) - shlibpath_overrides_runpath=yes - ;; - esac - else - shlibpath_overrides_runpath=yes - fi - ;; - -os2*) - libname_spec='$name' - shrext_cmds=".dll" - need_lib_prefix=no - library_names_spec='$libname${shared_ext} $libname.a' - dynamic_linker='OS/2 ld.exe' - shlibpath_var=LIBPATH - ;; - -osf3* | osf4* | osf5*) - version_type=osf - need_lib_prefix=no - need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" - sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" - ;; - -rdos*) - dynamic_linker=no - ;; - -solaris*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - # ldd complains unless libraries are executable - postinstall_cmds='chmod +x $lib' - ;; - -sunos4*) - version_type=sunos - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - if test "$with_gnu_ld" = yes; then - need_lib_prefix=no - fi - need_version=yes - ;; - -sysv4 | sysv4.3*) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - case $host_vendor in - sni) - shlibpath_overrides_runpath=no - need_lib_prefix=no - runpath_var=LD_RUN_PATH - ;; - siemens) - need_lib_prefix=no - ;; - motorola) - need_lib_prefix=no - need_version=no - shlibpath_overrides_runpath=no - sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' - ;; - esac - ;; - -sysv4*MP*) - if test -d /usr/nec ;then - version_type=linux - library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' - soname_spec='$libname${shared_ext}.$major' - shlibpath_var=LD_LIBRARY_PATH - fi - ;; - -sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) - version_type=freebsd-elf - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - if test "$with_gnu_ld" = yes; then - sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' - else - sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' - case $host_os in - sco3.2v5*) - sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" - ;; - esac - fi - sys_lib_dlsearch_path_spec='/usr/lib' - ;; - -tpf*) - # TPF is a cross-target only. Preferred cross-host = GNU/Linux. - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - -uts4*) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -*) - dynamic_linker=no - ;; -esac -AC_MSG_RESULT([$dynamic_linker]) -test "$dynamic_linker" = no && can_build_shared=no - -variables_saved_for_relink="PATH $shlibpath_var $runpath_var" -if test "$GCC" = yes; then - variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" -fi - -if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then - sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" -fi -if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then - sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" -fi - -_LT_DECL([], [variables_saved_for_relink], [1], - [Variables whose values should be saved in libtool wrapper scripts and - restored at link time]) -_LT_DECL([], [need_lib_prefix], [0], - [Do we need the "lib" prefix for modules?]) -_LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) -_LT_DECL([], [version_type], [0], [Library versioning type]) -_LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) -_LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) -_LT_DECL([], [shlibpath_overrides_runpath], [0], - [Is shlibpath searched before the hard-coded library search path?]) -_LT_DECL([], [libname_spec], [1], [Format of library name prefix]) -_LT_DECL([], [library_names_spec], [1], - [[List of archive names. First name is the real one, the rest are links. - The last name is the one that the linker finds with -lNAME]]) -_LT_DECL([], [soname_spec], [1], - [[The coded name of the library, if different from the real name]]) -_LT_DECL([], [postinstall_cmds], [2], - [Command to use after installation of a shared archive]) -_LT_DECL([], [postuninstall_cmds], [2], - [Command to use after uninstallation of a shared archive]) -_LT_DECL([], [finish_cmds], [2], - [Commands used to finish a libtool library installation in a directory]) -_LT_DECL([], [finish_eval], [1], - [[As "finish_cmds", except a single script fragment to be evaled but - not shown]]) -_LT_DECL([], [hardcode_into_libs], [0], - [Whether we should hardcode library paths into libraries]) -_LT_DECL([], [sys_lib_search_path_spec], [2], - [Compile-time system search path for libraries]) -_LT_DECL([], [sys_lib_dlsearch_path_spec], [2], - [Run-time system search path for libraries]) -])# _LT_SYS_DYNAMIC_LINKER - - -# _LT_PATH_TOOL_PREFIX(TOOL) -# -------------------------- -# find a file program which can recognize shared library -AC_DEFUN([_LT_PATH_TOOL_PREFIX], -[m4_require([_LT_DECL_EGREP])dnl -AC_MSG_CHECKING([for $1]) -AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, -[case $MAGIC_CMD in -[[\\/*] | ?:[\\/]*]) - lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. - ;; -*) - lt_save_MAGIC_CMD="$MAGIC_CMD" - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR -dnl $ac_dummy forces splitting on constant user-supplied paths. -dnl POSIX.2 word splitting is done only on the output of word expansions, -dnl not every word. This closes a longstanding sh security hole. - ac_dummy="m4_if([$2], , $PATH, [$2])" - for ac_dir in $ac_dummy; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$1; then - lt_cv_path_MAGIC_CMD="$ac_dir/$1" - if test -n "$file_magic_test_file"; then - case $deplibs_check_method in - "file_magic "*) - file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` - MAGIC_CMD="$lt_cv_path_MAGIC_CMD" - if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | - $EGREP "$file_magic_regex" > /dev/null; then - : - else - cat <<_LT_EOF 1>&2 - -*** Warning: the command libtool uses to detect shared libraries, -*** $file_magic_cmd, produces output that libtool cannot recognize. -*** The result is that libtool may fail to recognize shared libraries -*** as such. This will affect the creation of libtool libraries that -*** depend on shared libraries, but programs linked with such libtool -*** libraries will work regardless of this problem. Nevertheless, you -*** may want to report the problem to your system manager and/or to -*** bug-libtool@gnu.org - -_LT_EOF - fi ;; - esac - fi - break - fi - done - IFS="$lt_save_ifs" - MAGIC_CMD="$lt_save_MAGIC_CMD" - ;; -esac]) -MAGIC_CMD="$lt_cv_path_MAGIC_CMD" -if test -n "$MAGIC_CMD"; then - AC_MSG_RESULT($MAGIC_CMD) -else - AC_MSG_RESULT(no) -fi -_LT_DECL([], [MAGIC_CMD], [0], - [Used to examine libraries when file_magic_cmd begins with "file"])dnl -])# _LT_PATH_TOOL_PREFIX - -# Old name: -AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) - - -# _LT_PATH_MAGIC -# -------------- -# find a file program which can recognize a shared library -m4_defun([_LT_PATH_MAGIC], -[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) -if test -z "$lt_cv_path_MAGIC_CMD"; then - if test -n "$ac_tool_prefix"; then - _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) - else - MAGIC_CMD=: - fi -fi -])# _LT_PATH_MAGIC - - -# LT_PATH_LD -# ---------- -# find the pathname to the GNU or non-GNU linker -AC_DEFUN([LT_PATH_LD], -[AC_REQUIRE([AC_PROG_CC])dnl -AC_REQUIRE([AC_CANONICAL_HOST])dnl -AC_REQUIRE([AC_CANONICAL_BUILD])dnl -m4_require([_LT_DECL_SED])dnl -m4_require([_LT_DECL_EGREP])dnl - -AC_ARG_WITH([gnu-ld], - [AS_HELP_STRING([--with-gnu-ld], - [assume the C compiler uses GNU ld @<:@default=no@:>@])], - [test "$withval" = no || with_gnu_ld=yes], - [with_gnu_ld=no])dnl - -ac_prog=ld -if test "$GCC" = yes; then - # Check if gcc -print-prog-name=ld gives a path. - AC_MSG_CHECKING([for ld used by $CC]) - case $host in - *-*-mingw*) - # gcc leaves a trailing carriage return which upsets mingw - ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; - *) - ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; - esac - case $ac_prog in - # Accept absolute paths. - [[\\/]]* | ?:[[\\/]]*) - re_direlt='/[[^/]][[^/]]*/\.\./' - # Canonicalize the pathname of ld - ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` - while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do - ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` - done - test -z "$LD" && LD="$ac_prog" - ;; - "") - # If it fails, then pretend we aren't using GCC. - ac_prog=ld - ;; - *) - # If it is relative, then search for the first ld in PATH. - with_gnu_ld=unknown - ;; - esac -elif test "$with_gnu_ld" = yes; then - AC_MSG_CHECKING([for GNU ld]) -else - AC_MSG_CHECKING([for non-GNU ld]) -fi -AC_CACHE_VAL(lt_cv_path_LD, -[if test -z "$LD"; then - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - for ac_dir in $PATH; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then - lt_cv_path_LD="$ac_dir/$ac_prog" - # Check to see if the program is GNU ld. I'd rather use --version, - # but apparently some variants of GNU ld only accept -v. - # Break only if it was the GNU/non-GNU ld that we prefer. - case `"$lt_cv_path_LD" -v 2>&1 &1 /dev/null 2>&1; then - lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' - lt_cv_file_magic_cmd='func_win32_libid' - else - lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' - lt_cv_file_magic_cmd='$OBJDUMP -f' - fi - ;; - -cegcc) - # use the weaker test based on 'objdump'. See mingw*. - lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' - lt_cv_file_magic_cmd='$OBJDUMP -f' - ;; - -darwin* | rhapsody*) - lt_cv_deplibs_check_method=pass_all - ;; - -freebsd* | dragonfly*) - if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then - case $host_cpu in - i*86 ) - # Not sure whether the presence of OpenBSD here was a mistake. - # Let's accept both of them until this is cleared up. - lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' - lt_cv_file_magic_cmd=/usr/bin/file - lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` - ;; - esac - else - lt_cv_deplibs_check_method=pass_all - fi - ;; - -gnu*) - lt_cv_deplibs_check_method=pass_all - ;; - -hpux10.20* | hpux11*) - lt_cv_file_magic_cmd=/usr/bin/file - case $host_cpu in - ia64*) - lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' - lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so - ;; - hppa*64*) - [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]'] - lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl - ;; - *) - lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]].[[0-9]]) shared library' - lt_cv_file_magic_test_file=/usr/lib/libc.sl - ;; - esac - ;; - -interix[[3-9]]*) - # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here - lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' - ;; - -irix5* | irix6* | nonstopux*) - case $LD in - *-32|*"-32 ") libmagic=32-bit;; - *-n32|*"-n32 ") libmagic=N32;; - *-64|*"-64 ") libmagic=64-bit;; - *) libmagic=never-match;; - esac - lt_cv_deplibs_check_method=pass_all - ;; - -# This must be Linux ELF. -linux* | k*bsd*-gnu) - lt_cv_deplibs_check_method=pass_all - ;; - -netbsd*) - if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then - lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' - else - lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' - fi - ;; - -newos6*) - lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' - lt_cv_file_magic_cmd=/usr/bin/file - lt_cv_file_magic_test_file=/usr/lib/libnls.so - ;; - -*nto* | *qnx*) - lt_cv_deplibs_check_method=pass_all - ;; - -openbsd*) - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' - else - lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' - fi - ;; - -osf3* | osf4* | osf5*) - lt_cv_deplibs_check_method=pass_all - ;; - -rdos*) - lt_cv_deplibs_check_method=pass_all - ;; - -solaris*) - lt_cv_deplibs_check_method=pass_all - ;; - -sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) - lt_cv_deplibs_check_method=pass_all - ;; - -sysv4 | sysv4.3*) - case $host_vendor in - motorola) - lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' - lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` - ;; - ncr) - lt_cv_deplibs_check_method=pass_all - ;; - sequent) - lt_cv_file_magic_cmd='/bin/file' - lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' - ;; - sni) - lt_cv_file_magic_cmd='/bin/file' - lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" - lt_cv_file_magic_test_file=/lib/libc.so - ;; - siemens) - lt_cv_deplibs_check_method=pass_all - ;; - pc) - lt_cv_deplibs_check_method=pass_all - ;; - esac - ;; - -tpf*) - lt_cv_deplibs_check_method=pass_all - ;; -esac -]) -file_magic_cmd=$lt_cv_file_magic_cmd -deplibs_check_method=$lt_cv_deplibs_check_method -test -z "$deplibs_check_method" && deplibs_check_method=unknown - -_LT_DECL([], [deplibs_check_method], [1], - [Method to check whether dependent libraries are shared objects]) -_LT_DECL([], [file_magic_cmd], [1], - [Command to use when deplibs_check_method == "file_magic"]) -])# _LT_CHECK_MAGIC_METHOD - - -# LT_PATH_NM -# ---------- -# find the pathname to a BSD- or MS-compatible name lister -AC_DEFUN([LT_PATH_NM], -[AC_REQUIRE([AC_PROG_CC])dnl -AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, -[if test -n "$NM"; then - # Let the user override the test. - lt_cv_path_NM="$NM" -else - lt_nm_to_check="${ac_tool_prefix}nm" - if test -n "$ac_tool_prefix" && test "$build" = "$host"; then - lt_nm_to_check="$lt_nm_to_check nm" - fi - for lt_tmp_nm in $lt_nm_to_check; do - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - tmp_nm="$ac_dir/$lt_tmp_nm" - if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then - # Check to see if the nm accepts a BSD-compat flag. - # Adding the `sed 1q' prevents false positives on HP-UX, which says: - # nm: unknown option "B" ignored - # Tru64's nm complains that /dev/null is an invalid object file - case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in - */dev/null* | *'Invalid file or object type'*) - lt_cv_path_NM="$tmp_nm -B" - break - ;; - *) - case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in - */dev/null*) - lt_cv_path_NM="$tmp_nm -p" - break - ;; - *) - lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but - continue # so that we can try to find one that supports BSD flags - ;; - esac - ;; - esac - fi - done - IFS="$lt_save_ifs" - done - : ${lt_cv_path_NM=no} -fi]) -if test "$lt_cv_path_NM" != "no"; then - NM="$lt_cv_path_NM" -else - # Didn't find any BSD compatible name lister, look for dumpbin. - AC_CHECK_TOOLS(DUMPBIN, ["dumpbin -symbols" "link -dump -symbols"], :) - AC_SUBST([DUMPBIN]) - if test "$DUMPBIN" != ":"; then - NM="$DUMPBIN" - fi -fi -test -z "$NM" && NM=nm -AC_SUBST([NM]) -_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl - -AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], - [lt_cv_nm_interface="BSD nm" - echo "int some_variable = 0;" > conftest.$ac_ext - (eval echo "\"\$as_me:__oline__: $ac_compile\"" >&AS_MESSAGE_LOG_FD) - (eval "$ac_compile" 2>conftest.err) - cat conftest.err >&AS_MESSAGE_LOG_FD - (eval echo "\"\$as_me:__oline__: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) - (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) - cat conftest.err >&AS_MESSAGE_LOG_FD - (eval echo "\"\$as_me:__oline__: output\"" >&AS_MESSAGE_LOG_FD) - cat conftest.out >&AS_MESSAGE_LOG_FD - if $GREP 'External.*some_variable' conftest.out > /dev/null; then - lt_cv_nm_interface="MS dumpbin" - fi - rm -f conftest*]) -])# LT_PATH_NM - -# Old names: -AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) -AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AM_PROG_NM], []) -dnl AC_DEFUN([AC_PROG_NM], []) - - -# LT_LIB_M -# -------- -# check for math library -AC_DEFUN([LT_LIB_M], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -LIBM= -case $host in -*-*-beos* | *-*-cygwin* | *-*-pw32* | *-*-darwin*) - # These system don't have libm, or don't need it - ;; -*-ncr-sysv4.3*) - AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") - AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") - ;; -*) - AC_CHECK_LIB(m, cos, LIBM="-lm") - ;; -esac -AC_SUBST([LIBM]) -])# LT_LIB_M - -# Old name: -AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_CHECK_LIBM], []) - - -# _LT_COMPILER_NO_RTTI([TAGNAME]) -# ------------------------------- -m4_defun([_LT_COMPILER_NO_RTTI], -[m4_require([_LT_TAG_COMPILER])dnl - -_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= - -if test "$GCC" = yes; then - _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' - - _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], - lt_cv_prog_compiler_rtti_exceptions, - [-fno-rtti -fno-exceptions], [], - [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) -fi -_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], - [Compiler flag to turn off builtin functions]) -])# _LT_COMPILER_NO_RTTI - - -# _LT_CMD_GLOBAL_SYMBOLS -# ---------------------- -m4_defun([_LT_CMD_GLOBAL_SYMBOLS], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -AC_REQUIRE([AC_PROG_CC])dnl -AC_REQUIRE([LT_PATH_NM])dnl -AC_REQUIRE([LT_PATH_LD])dnl -m4_require([_LT_DECL_SED])dnl -m4_require([_LT_DECL_EGREP])dnl -m4_require([_LT_TAG_COMPILER])dnl - -# Check for command to grab the raw symbol name followed by C symbol from nm. -AC_MSG_CHECKING([command to parse $NM output from $compiler object]) -AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], -[ -# These are sane defaults that work on at least a few old systems. -# [They come from Ultrix. What could be older than Ultrix?!! ;)] - -# Character class describing NM global symbol codes. -symcode='[[BCDEGRST]]' - -# Regexp to match symbols that can be accessed directly from C. -sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' - -# Define system-specific variables. -case $host_os in -aix*) - symcode='[[BCDT]]' - ;; -cygwin* | mingw* | pw32* | cegcc*) - symcode='[[ABCDGISTW]]' - ;; -hpux*) - if test "$host_cpu" = ia64; then - symcode='[[ABCDEGRST]]' - fi - ;; -irix* | nonstopux*) - symcode='[[BCDEGRST]]' - ;; -osf*) - symcode='[[BCDEGQRST]]' - ;; -solaris*) - symcode='[[BDRT]]' - ;; -sco3.2v5*) - symcode='[[DT]]' - ;; -sysv4.2uw2*) - symcode='[[DT]]' - ;; -sysv5* | sco5v6* | unixware* | OpenUNIX*) - symcode='[[ABDT]]' - ;; -sysv4) - symcode='[[DFNSTU]]' - ;; -esac - -# If we're using GNU nm, then use its standard symbol codes. -case `$NM -V 2>&1` in -*GNU* | *'with BFD'*) - symcode='[[ABCDGIRSTW]]' ;; -esac - -# Transform an extracted symbol line into a proper C declaration. -# Some systems (esp. on ia64) link data and code symbols differently, -# so use this general approach. -lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" - -# Transform an extracted symbol line into symbol name and symbol address -lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'" -lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'" - -# Handle CRLF in mingw tool chain -opt_cr= -case $build_os in -mingw*) - opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp - ;; -esac - -# Try without a prefix underscore, then with it. -for ac_symprfx in "" "_"; do - - # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. - symxfrm="\\1 $ac_symprfx\\2 \\2" - - # Write the raw and C identifiers. - if test "$lt_cv_nm_interface" = "MS dumpbin"; then - # Fake it for dumpbin and say T for any non-static function - # and D for any global variable. - # Also find C++ and __fastcall symbols from MSVC++, - # which start with @ or ?. - lt_cv_sys_global_symbol_pipe="$AWK ['"\ -" {last_section=section; section=\$ 3};"\ -" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ -" \$ 0!~/External *\|/{next};"\ -" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ -" {if(hide[section]) next};"\ -" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ -" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ -" s[1]~/^[@?]/{print s[1], s[1]; next};"\ -" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ -" ' prfx=^$ac_symprfx]" - else - lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" - fi - - # Check to see that the pipe works correctly. - pipe_works=no - - rm -f conftest* - cat > conftest.$ac_ext <<_LT_EOF -#ifdef __cplusplus -extern "C" { -#endif -char nm_test_var; -void nm_test_func(void); -void nm_test_func(void){} -#ifdef __cplusplus -} -#endif -int main(){nm_test_var='a';nm_test_func();return(0);} -_LT_EOF - - if AC_TRY_EVAL(ac_compile); then - # Now try to grab the symbols. - nlist=conftest.nm - if AC_TRY_EVAL(NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) && test -s "$nlist"; then - # Try sorting and uniquifying the output. - if sort "$nlist" | uniq > "$nlist"T; then - mv -f "$nlist"T "$nlist" - else - rm -f "$nlist"T - fi - - # Make sure that we snagged all the symbols we need. - if $GREP ' nm_test_var$' "$nlist" >/dev/null; then - if $GREP ' nm_test_func$' "$nlist" >/dev/null; then - cat <<_LT_EOF > conftest.$ac_ext -#ifdef __cplusplus -extern "C" { -#endif - -_LT_EOF - # Now generate the symbol file. - eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' - - cat <<_LT_EOF >> conftest.$ac_ext - -/* The mapping between symbol names and symbols. */ -const struct { - const char *name; - void *address; -} -lt__PROGRAM__LTX_preloaded_symbols[[]] = -{ - { "@PROGRAM@", (void *) 0 }, -_LT_EOF - $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext - cat <<\_LT_EOF >> conftest.$ac_ext - {0, (void *) 0} -}; - -/* This works around a problem in FreeBSD linker */ -#ifdef FREEBSD_WORKAROUND -static const void *lt_preloaded_setup() { - return lt__PROGRAM__LTX_preloaded_symbols; -} -#endif - -#ifdef __cplusplus -} -#endif -_LT_EOF - # Now try linking the two files. - mv conftest.$ac_objext conftstm.$ac_objext - lt_save_LIBS="$LIBS" - lt_save_CFLAGS="$CFLAGS" - LIBS="conftstm.$ac_objext" - CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" - if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then - pipe_works=yes - fi - LIBS="$lt_save_LIBS" - CFLAGS="$lt_save_CFLAGS" - else - echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD - fi - else - echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD - fi - else - echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD - fi - else - echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD - cat conftest.$ac_ext >&5 - fi - rm -rf conftest* conftst* - - # Do not use the global_symbol_pipe unless it works. - if test "$pipe_works" = yes; then - break - else - lt_cv_sys_global_symbol_pipe= - fi -done -]) -if test -z "$lt_cv_sys_global_symbol_pipe"; then - lt_cv_sys_global_symbol_to_cdecl= -fi -if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then - AC_MSG_RESULT(failed) -else - AC_MSG_RESULT(ok) -fi - -_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], - [Take the output of nm and produce a listing of raw symbols and C names]) -_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], - [Transform the output of nm in a proper C declaration]) -_LT_DECL([global_symbol_to_c_name_address], - [lt_cv_sys_global_symbol_to_c_name_address], [1], - [Transform the output of nm in a C name address pair]) -_LT_DECL([global_symbol_to_c_name_address_lib_prefix], - [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], - [Transform the output of nm in a C name address pair when lib prefix is needed]) -]) # _LT_CMD_GLOBAL_SYMBOLS - - -# _LT_COMPILER_PIC([TAGNAME]) -# --------------------------- -m4_defun([_LT_COMPILER_PIC], -[m4_require([_LT_TAG_COMPILER])dnl -_LT_TAGVAR(lt_prog_compiler_wl, $1)= -_LT_TAGVAR(lt_prog_compiler_pic, $1)= -_LT_TAGVAR(lt_prog_compiler_static, $1)= - -AC_MSG_CHECKING([for $compiler option to produce PIC]) -m4_if([$1], [CXX], [ - # C++ specific cases for pic, static, wl, etc. - if test "$GXX" = yes; then - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - - case $host_os in - aix*) - # All AIX code is PIC. - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - fi - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - m68k) - # FIXME: we need at least 68020 code to build shared libraries, but - # adding the `-m68020' flag to GCC prevents building anything better, - # like `-m68040'. - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' - ;; - esac - ;; - - beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) - # PIC is the default for these OSes. - ;; - mingw* | cygwin* | os2* | pw32* | cegcc*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - # Although the cygwin gcc ignores -fPIC, still need this for old-style - # (--disable-auto-import) libraries - m4_if([$1], [GCJ], [], - [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) - ;; - darwin* | rhapsody*) - # PIC is the default on this platform - # Common symbols not allowed in MH_DYLIB files - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' - ;; - *djgpp*) - # DJGPP does not support shared libraries at all - _LT_TAGVAR(lt_prog_compiler_pic, $1)= - ;; - interix[[3-9]]*) - # Interix 3.x gcc -fpic/-fPIC options generate broken code. - # Instead, we relocate shared libraries at runtime. - ;; - sysv4*MP*) - if test -d /usr/nec; then - _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic - fi - ;; - hpux*) - # PIC is the default for 64-bit PA HP-UX, but not for 32-bit - # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag - # sets the default TLS model and affects inlining. - case $host_cpu in - hppa*64*) - ;; - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - esac - ;; - *qnx* | *nto*) - # QNX uses GNU C++, but need to define -shared option too, otherwise - # it will coredump. - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' - ;; - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - esac - else - case $host_os in - aix[[4-9]]*) - # All AIX code is PIC. - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - else - _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' - fi - ;; - chorus*) - case $cc_basename in - cxch68*) - # Green Hills C++ Compiler - # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" - ;; - esac - ;; - dgux*) - case $cc_basename in - ec++*) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - ;; - ghcx*) - # Green Hills C++ Compiler - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - ;; - *) - ;; - esac - ;; - freebsd* | dragonfly*) - # FreeBSD uses GNU C++ - ;; - hpux9* | hpux10* | hpux11*) - case $cc_basename in - CC*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' - if test "$host_cpu" != ia64; then - _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' - fi - ;; - aCC*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' - case $host_cpu in - hppa*64*|ia64*) - # +Z the default - ;; - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' - ;; - esac - ;; - *) - ;; - esac - ;; - interix*) - # This is c89, which is MS Visual C++ (no shared libs) - # Anyone wants to do a port? - ;; - irix5* | irix6* | nonstopux*) - case $cc_basename in - CC*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - # CC pic flag -KPIC is the default. - ;; - *) - ;; - esac - ;; - linux* | k*bsd*-gnu) - case $cc_basename in - KCC*) - # KAI C++ Compiler - _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - ecpc* ) - # old Intel C++ for x86_64 which still supported -KPIC. - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - ;; - icpc* ) - # Intel C++, used to be incompatible with GCC. - # ICC 10 doesn't accept -KPIC any more. - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - ;; - pgCC* | pgcpp*) - # Portland Group C++ compiler - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - cxx*) - # Compaq C++ - # Make sure the PIC flag is empty. It appears that all Alpha - # Linux and Compaq Tru64 Unix objects are PIC. - _LT_TAGVAR(lt_prog_compiler_pic, $1)= - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - xlc* | xlC*) - # IBM XL 8.0 on PPC - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' - ;; - *) - case `$CC -V 2>&1 | sed 5q` in - *Sun\ C*) - # Sun C++ 5.9 - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' - ;; - esac - ;; - esac - ;; - lynxos*) - ;; - m88k*) - ;; - mvs*) - case $cc_basename in - cxx*) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' - ;; - *) - ;; - esac - ;; - netbsd*) - ;; - *qnx* | *nto*) - # QNX uses GNU C++, but need to define -shared option too, otherwise - # it will coredump. - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' - ;; - osf3* | osf4* | osf5*) - case $cc_basename in - KCC*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' - ;; - RCC*) - # Rational C++ 2.4.1 - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - ;; - cxx*) - # Digital/Compaq C++ - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # Make sure the PIC flag is empty. It appears that all Alpha - # Linux and Compaq Tru64 Unix objects are PIC. - _LT_TAGVAR(lt_prog_compiler_pic, $1)= - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - *) - ;; - esac - ;; - psos*) - ;; - solaris*) - case $cc_basename in - CC*) - # Sun C++ 4.2, 5.x and Centerline C++ - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' - ;; - gcx*) - # Green Hills C++ Compiler - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' - ;; - *) - ;; - esac - ;; - sunos4*) - case $cc_basename in - CC*) - # Sun C++ 4.x - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - lcc*) - # Lucid - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - ;; - *) - ;; - esac - ;; - sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) - case $cc_basename in - CC*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - esac - ;; - tandem*) - case $cc_basename in - NCC*) - # NonStop-UX NCC 3.20 - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - ;; - *) - ;; - esac - ;; - vxworks*) - ;; - *) - _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no - ;; - esac - fi -], -[ - if test "$GCC" = yes; then - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - - case $host_os in - aix*) - # All AIX code is PIC. - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - fi - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - m68k) - # FIXME: we need at least 68020 code to build shared libraries, but - # adding the `-m68020' flag to GCC prevents building anything better, - # like `-m68040'. - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' - ;; - esac - ;; - - beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) - # PIC is the default for these OSes. - ;; - - mingw* | cygwin* | pw32* | os2* | cegcc*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - # Although the cygwin gcc ignores -fPIC, still need this for old-style - # (--disable-auto-import) libraries - m4_if([$1], [GCJ], [], - [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) - ;; - - darwin* | rhapsody*) - # PIC is the default on this platform - # Common symbols not allowed in MH_DYLIB files - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' - ;; - - hpux*) - # PIC is the default for 64-bit PA HP-UX, but not for 32-bit - # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag - # sets the default TLS model and affects inlining. - case $host_cpu in - hppa*64*) - # +Z the default - ;; - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - esac - ;; - - interix[[3-9]]*) - # Interix 3.x gcc -fpic/-fPIC options generate broken code. - # Instead, we relocate shared libraries at runtime. - ;; - - msdosdjgpp*) - # Just because we use GCC doesn't mean we suddenly get shared libraries - # on systems that don't support them. - _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no - enable_shared=no - ;; - - *nto* | *qnx*) - # QNX uses GNU C++, but need to define -shared option too, otherwise - # it will coredump. - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' - ;; - - sysv4*MP*) - if test -d /usr/nec; then - _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic - fi - ;; - - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - esac - else - # PORTME Check for flag to pass linker flags through the system compiler. - case $host_os in - aix*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - else - _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' - fi - ;; - - mingw* | cygwin* | pw32* | os2* | cegcc*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - m4_if([$1], [GCJ], [], - [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) - ;; - - hpux9* | hpux10* | hpux11*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but - # not for PA HP-UX. - case $host_cpu in - hppa*64*|ia64*) - # +Z the default - ;; - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' - ;; - esac - # Is there a better lt_prog_compiler_static that works with the bundled CC? - _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' - ;; - - irix5* | irix6* | nonstopux*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # PIC (with -KPIC) is the default. - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - - linux* | k*bsd*-gnu) - case $cc_basename in - # old Intel for x86_64 which still supported -KPIC. - ecc*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - ;; - # icc used to be incompatible with GCC. - # ICC 10 doesn't accept -KPIC any more. - icc* | ifort*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - ;; - # Lahey Fortran 8.1. - lf95*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' - _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' - ;; - pgcc* | pgf77* | pgf90* | pgf95*) - # Portland Group compilers (*not* the Pentium gcc compiler, - # which looks to be a dead project) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - ccc*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # All Alpha code is PIC. - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - xl*) - # IBM XL C 8.0/Fortran 10.1 on PPC - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' - ;; - *) - case `$CC -V 2>&1 | sed 5q` in - *Sun\ C*) - # Sun C 5.9 - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - ;; - *Sun\ F*) - # Sun Fortran 8.3 passes all unrecognized flags to the linker - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - _LT_TAGVAR(lt_prog_compiler_wl, $1)='' - ;; - esac - ;; - esac - ;; - - newsos6) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - - *nto* | *qnx*) - # QNX uses GNU C++, but need to define -shared option too, otherwise - # it will coredump. - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' - ;; - - osf3* | osf4* | osf5*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # All OSF/1 code is PIC. - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - - rdos*) - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - - solaris*) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - case $cc_basename in - f77* | f90* | f95*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; - *) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; - esac - ;; - - sunos4*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - - sysv4 | sysv4.2uw2* | sysv4.3*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - - sysv4*MP*) - if test -d /usr/nec ;then - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - fi - ;; - - sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - - unicos*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no - ;; - - uts4*) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - - *) - _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no - ;; - esac - fi -]) -case $host_os in - # For platforms which do not support PIC, -DPIC is meaningless: - *djgpp*) - _LT_TAGVAR(lt_prog_compiler_pic, $1)= - ;; - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" - ;; -esac -AC_MSG_RESULT([$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) -_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], - [How to pass a linker flag through the compiler]) - -# -# Check to make sure the PIC flag actually works. -# -if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then - _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], - [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], - [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], - [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in - "" | " "*) ;; - *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; - esac], - [_LT_TAGVAR(lt_prog_compiler_pic, $1)= - _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) -fi -_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], - [Additional compiler flags for building library objects]) - -# -# Check to make sure the static flag actually works. -# -wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" -_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], - _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), - $lt_tmp_static_flag, - [], - [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) -_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], - [Compiler flag to prevent dynamic linking]) -])# _LT_COMPILER_PIC - - -# _LT_LINKER_SHLIBS([TAGNAME]) -# ---------------------------- -# See if the linker supports building shared libraries. -m4_defun([_LT_LINKER_SHLIBS], -[AC_REQUIRE([LT_PATH_LD])dnl -AC_REQUIRE([LT_PATH_NM])dnl -m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_DECL_EGREP])dnl -m4_require([_LT_DECL_SED])dnl -m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl -m4_require([_LT_TAG_COMPILER])dnl -AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) -m4_if([$1], [CXX], [ - _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' - case $host_os in - aix[[4-9]]*) - # If we're using GNU nm, then we don't want the "-C" option. - # -C means demangle to AIX nm, but means don't demangle with GNU nm - if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then - _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' - else - _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' - fi - ;; - pw32*) - _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" - ;; - cygwin* | mingw* | cegcc*) - _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;/^.*[[ ]]__nm__/s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' - ;; - *) - _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' - ;; - esac - _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] -], [ - runpath_var= - _LT_TAGVAR(allow_undefined_flag, $1)= - _LT_TAGVAR(always_export_symbols, $1)=no - _LT_TAGVAR(archive_cmds, $1)= - _LT_TAGVAR(archive_expsym_cmds, $1)= - _LT_TAGVAR(compiler_needs_object, $1)=no - _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no - _LT_TAGVAR(export_dynamic_flag_spec, $1)= - _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' - _LT_TAGVAR(hardcode_automatic, $1)=no - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_direct_absolute, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= - _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= - _LT_TAGVAR(hardcode_libdir_separator, $1)= - _LT_TAGVAR(hardcode_minus_L, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported - _LT_TAGVAR(inherit_rpath, $1)=no - _LT_TAGVAR(link_all_deplibs, $1)=unknown - _LT_TAGVAR(module_cmds, $1)= - _LT_TAGVAR(module_expsym_cmds, $1)= - _LT_TAGVAR(old_archive_from_new_cmds, $1)= - _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= - _LT_TAGVAR(thread_safe_flag_spec, $1)= - _LT_TAGVAR(whole_archive_flag_spec, $1)= - # include_expsyms should be a list of space-separated symbols to be *always* - # included in the symbol list - _LT_TAGVAR(include_expsyms, $1)= - # exclude_expsyms can be an extended regexp of symbols to exclude - # it will be wrapped by ` (' and `)$', so one must not match beginning or - # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', - # as well as any symbol that contains `d'. - _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] - # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out - # platforms (ab)use it in PIC code, but their linkers get confused if - # the symbol is explicitly referenced. Since portable code cannot - # rely on this symbol name, it's probably fine to never include it in - # preloaded symbol tables. - # Exclude shared library initialization/finalization symbols. -dnl Note also adjust exclude_expsyms for C++ above. - extract_expsyms_cmds= - - case $host_os in - cygwin* | mingw* | pw32* | cegcc*) - # FIXME: the MSVC++ port hasn't been tested in a loooong time - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - if test "$GCC" != yes; then - with_gnu_ld=no - fi - ;; - interix*) - # we just hope/assume this is gcc and not c89 (= MSVC++) - with_gnu_ld=yes - ;; - openbsd*) - with_gnu_ld=no - ;; - esac - - _LT_TAGVAR(ld_shlibs, $1)=yes - if test "$with_gnu_ld" = yes; then - # If archive_cmds runs LD, not CC, wlarc should be empty - wlarc='${wl}' - - # Set some defaults for GNU ld with shared library support. These - # are reset later if shared libraries are not supported. Putting them - # here allows them to be overridden if necessary. - runpath_var=LD_RUN_PATH - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - # ancient GNU ld didn't support --whole-archive et. al. - if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then - _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' - else - _LT_TAGVAR(whole_archive_flag_spec, $1)= - fi - supports_anon_versioning=no - case `$LD -v 2>&1` in - *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 - *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... - *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... - *\ 2.11.*) ;; # other 2.11 versions - *) supports_anon_versioning=yes ;; - esac - - # See if GNU ld supports shared libraries. - case $host_os in - aix[[3-9]]*) - # On AIX/PPC, the GNU linker is very broken - if test "$host_cpu" != ia64; then - _LT_TAGVAR(ld_shlibs, $1)=no - cat <<_LT_EOF 1>&2 - -*** Warning: the GNU linker, at least up to release 2.9.1, is reported -*** to be unable to reliably create shared libraries on AIX. -*** Therefore, libtool is disabling shared libraries support. If you -*** really care for shared libraries, you may want to modify your PATH -*** so that a non-GNU linker is found, and then restart. - -_LT_EOF - fi - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='' - ;; - m68k) - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_minus_L, $1)=yes - ;; - esac - ;; - - beos*) - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - # Joseph Beckenbach says some releases of gcc - # support --undefined. This deserves some investigation. FIXME - _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - cygwin* | mingw* | pw32* | cegcc*) - # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, - # as there is no search path for DLLs. - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_TAGVAR(always_export_symbols, $1)=no - _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes - _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' - - if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - # If the export-symbols file already is a .def file (1st line - # is EXPORTS), use it as is; otherwise, prepend... - _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - cp $export_symbols $output_objdir/$soname.def; - else - echo EXPORTS > $output_objdir/$soname.def; - cat $export_symbols >> $output_objdir/$soname.def; - fi~ - $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - interix[[3-9]]*) - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. - # Instead, shared libraries are loaded at an image base (0x10000000 by - # default) and relocated if they conflict, which is a slow very memory - # consuming and fragmenting process. To avoid this, we pick a random, - # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link - # time. Moving up from 0x10000000 also allows more sbrk(2) space. - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - ;; - - gnu* | linux* | tpf* | k*bsd*-gnu) - tmp_diet=no - if test "$host_os" = linux-dietlibc; then - case $cc_basename in - diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) - esac - fi - if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ - && test "$tmp_diet" = no - then - tmp_addflag= - tmp_sharedflag='-shared' - case $cc_basename,$host_cpu in - pgcc*) # Portland Group C compiler - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' - tmp_addflag=' $pic_flag' - ;; - pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' - tmp_addflag=' $pic_flag -Mnomain' ;; - ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 - tmp_addflag=' -i_dynamic' ;; - efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 - tmp_addflag=' -i_dynamic -nofor_main' ;; - ifc* | ifort*) # Intel Fortran compiler - tmp_addflag=' -nofor_main' ;; - lf95*) # Lahey Fortran 8.1 - _LT_TAGVAR(whole_archive_flag_spec, $1)= - tmp_sharedflag='--shared' ;; - xl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) - tmp_sharedflag='-qmkshrobj' - tmp_addflag= ;; - esac - case `$CC -V 2>&1 | sed 5q` in - *Sun\ C*) # Sun C 5.9 - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' - _LT_TAGVAR(compiler_needs_object, $1)=yes - tmp_sharedflag='-G' ;; - *Sun\ F*) # Sun Fortran 8.3 - tmp_sharedflag='-G' ;; - esac - _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - - if test "x$supports_anon_versioning" = xyes; then - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' - fi - - case $cc_basename in - xlf*) - # IBM XL Fortran 10.1 on PPC cannot create shared libs itself - _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= - _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir' - _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $compiler_flags -soname $soname -o $lib' - if test "x$supports_anon_versioning" = xyes; then - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $LD -shared $libobjs $deplibs $compiler_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' - fi - ;; - esac - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - netbsd*) - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' - wlarc= - else - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - fi - ;; - - solaris*) - if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then - _LT_TAGVAR(ld_shlibs, $1)=no - cat <<_LT_EOF 1>&2 - -*** Warning: The releases 2.8.* of the GNU linker cannot reliably -*** create shared libraries on Solaris systems. Therefore, libtool -*** is disabling shared libraries support. We urge you to upgrade GNU -*** binutils to release 2.9.1 or newer. Another option is to modify -*** your PATH or compiler configuration so that the native linker is -*** used, and then restart. - -_LT_EOF - elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) - case `$LD -v 2>&1` in - *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) - _LT_TAGVAR(ld_shlibs, $1)=no - cat <<_LT_EOF 1>&2 - -*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not -*** reliably create shared libraries on SCO systems. Therefore, libtool -*** is disabling shared libraries support. We urge you to upgrade GNU -*** binutils to release 2.16.91.0.3 or newer. Another option is to modify -*** your PATH or compiler configuration so that the native linker is -*** used, and then restart. - -_LT_EOF - ;; - *) - # For security reasons, it is highly recommended that you always - # use absolute paths for naming shared libraries, and exclude the - # DT_RUNPATH tag from executables and libraries. But doing so - # requires that you compile everything twice, which is a pain. - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - ;; - - sunos4*) - _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' - wlarc= - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - *) - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - - if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then - runpath_var= - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= - _LT_TAGVAR(export_dynamic_flag_spec, $1)= - _LT_TAGVAR(whole_archive_flag_spec, $1)= - fi - else - # PORTME fill in a description of your system's linker (not GNU ld) - case $host_os in - aix3*) - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_TAGVAR(always_export_symbols, $1)=yes - _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' - # Note: this linker hardcodes the directories in LIBPATH if there - # are no directories specified by -L. - _LT_TAGVAR(hardcode_minus_L, $1)=yes - if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then - # Neither direct hardcoding nor static linking is supported with a - # broken collect2. - _LT_TAGVAR(hardcode_direct, $1)=unsupported - fi - ;; - - aix[[4-9]]*) - if test "$host_cpu" = ia64; then - # On IA64, the linker does run time linking by default, so we don't - # have to do anything special. - aix_use_runtimelinking=no - exp_sym_flag='-Bexport' - no_entry_flag="" - else - # If we're using GNU nm, then we don't want the "-C" option. - # -C means demangle to AIX nm, but means don't demangle with GNU nm - if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then - _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' - else - _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' - fi - aix_use_runtimelinking=no - - # Test if we are trying to use run time linking or normal - # AIX style linking. If -brtl is somewhere in LDFLAGS, we - # need to do runtime linking. - case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) - for ld_flag in $LDFLAGS; do - if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then - aix_use_runtimelinking=yes - break - fi - done - ;; - esac - - exp_sym_flag='-bexport' - no_entry_flag='-bnoentry' - fi - - # When large executables or shared objects are built, AIX ld can - # have problems creating the table of contents. If linking a library - # or program results in "error TOC overflow" add -mminimal-toc to - # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not - # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. - - _LT_TAGVAR(archive_cmds, $1)='' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(hardcode_libdir_separator, $1)=':' - _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' - - if test "$GCC" = yes; then - case $host_os in aix4.[[012]]|aix4.[[012]].*) - # We only want to do this on AIX 4.2 and lower, the check - # below for broken collect2 doesn't work under 4.3+ - collect2name=`${CC} -print-prog-name=collect2` - if test -f "$collect2name" && - strings "$collect2name" | $GREP resolve_lib_name >/dev/null - then - # We have reworked collect2 - : - else - # We have old collect2 - _LT_TAGVAR(hardcode_direct, $1)=unsupported - # It fails to find uninstalled libraries when the uninstalled - # path is not listed in the libpath. Setting hardcode_minus_L - # to unsupported forces relinking - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)= - fi - ;; - esac - shared_flag='-shared' - if test "$aix_use_runtimelinking" = yes; then - shared_flag="$shared_flag "'${wl}-G' - fi - else - # not using gcc - if test "$host_cpu" = ia64; then - # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release - # chokes on -Wl,-G. The following line is correct: - shared_flag='-G' - else - if test "$aix_use_runtimelinking" = yes; then - shared_flag='${wl}-G' - else - shared_flag='${wl}-bM:SRE' - fi - fi - fi - - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' - # It seems that -bexpall does not export symbols beginning with - # underscore (_), so it is better to generate a list of symbols to export. - _LT_TAGVAR(always_export_symbols, $1)=yes - if test "$aix_use_runtimelinking" = yes; then - # Warning - without using the other runtime loading flags (-brtl), - # -berok will link without error, but may produce a broken library. - _LT_TAGVAR(allow_undefined_flag, $1)='-berok' - # Determine the default libpath from the value encoded in an - # empty executable. - _LT_SYS_MODULE_PATH_AIX - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" - else - if test "$host_cpu" = ia64; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' - _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" - _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" - else - # Determine the default libpath from the value encoded in an - # empty executable. - _LT_SYS_MODULE_PATH_AIX - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" - # Warning - without using the other run time loading flags, - # -berok will link without error, but may produce a broken library. - _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' - # Exported symbols can be pulled into shared objects from archives - _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' - _LT_TAGVAR(archive_cmds_need_lc, $1)=yes - # This is similar to how AIX traditionally builds its shared libraries. - _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' - fi - fi - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='' - ;; - m68k) - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_minus_L, $1)=yes - ;; - esac - ;; - - bsdi[[45]]*) - _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic - ;; - - cygwin* | mingw* | pw32* | cegcc*) - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - # hardcode_libdir_flag_spec is actually meaningless, as there is - # no search path for DLLs. - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - # Tell ltmain to make .lib files, not .a files. - libext=lib - # Tell ltmain to make .dll files, not .so files. - shrext_cmds=".dll" - # FIXME: Setting linknames here is a bad hack. - _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `$ECHO "X$deplibs" | $Xsed -e '\''s/ -lc$//'\''` -link -dll~linknames=' - # The linker will automatically build a .lib file if we build a DLL. - _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' - # FIXME: Should let the user specify the lib program. - _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' - _LT_TAGVAR(fix_srcfile_path, $1)='`cygpath -w "$srcfile"`' - _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes - ;; - - darwin* | rhapsody*) - _LT_DARWIN_LINKER_FEATURES($1) - ;; - - dgux*) - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - freebsd1*) - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor - # support. Future versions do this automatically, but an explicit c++rt0.o - # does not break anything, and helps significantly (at the cost of a little - # extra space). - freebsd2.2*) - _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - # Unfortunately, older versions of FreeBSD 2 do not have this feature. - freebsd2*) - _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - # FreeBSD 3 and greater uses gcc -shared to do shared libraries. - freebsd* | dragonfly*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - hpux9*) - if test "$GCC" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - else - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - fi - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(hardcode_direct, $1)=yes - - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - ;; - - hpux10*) - if test "$GCC" = yes -a "$with_gnu_ld" = no; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' - else - _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' - fi - if test "$with_gnu_ld" = no; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - _LT_TAGVAR(hardcode_minus_L, $1)=yes - fi - ;; - - hpux11*) - if test "$GCC" = yes -a "$with_gnu_ld" = no; then - case $host_cpu in - hppa*64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - ia64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' - ;; - esac - else - case $host_cpu in - hppa*64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - ia64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' - ;; - esac - fi - if test "$with_gnu_ld" = no; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - - case $host_cpu in - hppa*64*|ia64*) - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - *) - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - _LT_TAGVAR(hardcode_minus_L, $1)=yes - ;; - esac - fi - ;; - - irix5* | irix6* | nonstopux*) - if test "$GCC" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - # Try to use the -exported_symbol ld option, if it does not - # work, assume that -exports_file does not work either and - # implicitly export all symbols. - save_LDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" - AC_LINK_IFELSE(int foo(void) {}, - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' - ) - LDFLAGS="$save_LDFLAGS" - else - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' - fi - _LT_TAGVAR(archive_cmds_need_lc, $1)='no' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(inherit_rpath, $1)=yes - _LT_TAGVAR(link_all_deplibs, $1)=yes - ;; - - netbsd*) - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out - else - _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF - fi - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - newsos6) - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - *nto* | *qnx*) - ;; - - openbsd*) - if test -f /usr/libexec/ld.so; then - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - else - case $host_os in - openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) - _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - ;; - esac - fi - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - os2*) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$ECHO DATA >> $output_objdir/$libname.def~$ECHO " SINGLE NONSHARED" >> $output_objdir/$libname.def~$ECHO EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' - _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' - ;; - - osf3*) - if test "$GCC" = yes; then - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - else - _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' - fi - _LT_TAGVAR(archive_cmds_need_lc, $1)='no' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - ;; - - osf4* | osf5*) # as osf3* with the addition of -msym flag - if test "$GCC" = yes; then - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - else - _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ - $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' - - # Both c and cxx compiler support -rpath directly - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' - fi - _LT_TAGVAR(archive_cmds_need_lc, $1)='no' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - ;; - - solaris*) - _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' - if test "$GCC" = yes; then - wlarc='${wl}' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -shared ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' - else - case `$CC -V 2>&1` in - *"Compilers 5.0"*) - wlarc='' - _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' - ;; - *) - wlarc='${wl}' - _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' - ;; - esac - fi - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - case $host_os in - solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; - *) - # The compiler driver will combine and reorder linker options, - # but understands `-z linker_flag'. GCC discards it without `$wl', - # but is careful enough not to reorder. - # Supported since Solaris 2.6 (maybe 2.5.1?) - if test "$GCC" = yes; then - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' - else - _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' - fi - ;; - esac - _LT_TAGVAR(link_all_deplibs, $1)=yes - ;; - - sunos4*) - if test "x$host_vendor" = xsequent; then - # Use $CC to link under sequent, because it throws in some extra .o - # files that make .init and .fini sections work. - _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' - else - _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' - fi - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - sysv4) - case $host_vendor in - sni) - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? - ;; - siemens) - ## LD is ld it makes a PLAMLIB - ## CC just makes a GrossModule. - _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' - _LT_TAGVAR(hardcode_direct, $1)=no - ;; - motorola) - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie - ;; - esac - runpath_var='LD_RUN_PATH' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - sysv4.3*) - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' - ;; - - sysv4*MP*) - if test -d /usr/nec; then - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - runpath_var=LD_RUN_PATH - hardcode_runpath_var=yes - _LT_TAGVAR(ld_shlibs, $1)=yes - fi - ;; - - sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) - _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - runpath_var='LD_RUN_PATH' - - if test "$GCC" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - else - _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - fi - ;; - - sysv5* | sco3.2v5* | sco5v6*) - # Note: We can NOT use -z defs as we might desire, because we do not - # link with -lc, and that would cause any symbols used from libc to - # always be unresolved, which means just about no library would - # ever link correctly. If we're not using GNU ld we use -z text - # though, which does catch some bad symbols but isn't as heavy-handed - # as -z defs. - _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' - _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=':' - _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' - runpath_var='LD_RUN_PATH' - - if test "$GCC" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - else - _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - fi - ;; - - uts4*) - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - *) - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - - if test x$host_vendor = xsni; then - case $host in - sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym' - ;; - esac - fi - fi -]) -AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) -test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no - -_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld - -_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl -_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl -_LT_DECL([], [extract_expsyms_cmds], [2], - [The commands to extract the exported symbol list from a shared archive]) - -# -# Do we need to explicitly link libc? -# -case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in -x|xyes) - # Assume -lc should be added - _LT_TAGVAR(archive_cmds_need_lc, $1)=yes - - if test "$enable_shared" = yes && test "$GCC" = yes; then - case $_LT_TAGVAR(archive_cmds, $1) in - *'~'*) - # FIXME: we may have to deal with multi-command sequences. - ;; - '$CC '*) - # Test whether the compiler implicitly links with -lc since on some - # systems, -lgcc has to come before -lc. If gcc already passes -lc - # to ld, don't add -lc before -lgcc. - AC_MSG_CHECKING([whether -lc should be explicitly linked in]) - $RM conftest* - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - - if AC_TRY_EVAL(ac_compile) 2>conftest.err; then - soname=conftest - lib=conftest - libobjs=conftest.$ac_objext - deplibs= - wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) - pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) - compiler_flags=-v - linker_flags=-v - verstring= - output_objdir=. - libname=conftest - lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) - _LT_TAGVAR(allow_undefined_flag, $1)= - if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) - then - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - else - _LT_TAGVAR(archive_cmds_need_lc, $1)=yes - fi - _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag - else - cat conftest.err 1>&5 - fi - $RM conftest* - AC_MSG_RESULT([$_LT_TAGVAR(archive_cmds_need_lc, $1)]) - ;; - esac - fi - ;; -esac - -_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], - [Whether or not to add -lc for building shared libraries]) -_LT_TAGDECL([allow_libtool_libs_with_static_runtimes], - [enable_shared_with_static_runtimes], [0], - [Whether or not to disallow shared libs when runtime libs are static]) -_LT_TAGDECL([], [export_dynamic_flag_spec], [1], - [Compiler flag to allow reflexive dlopens]) -_LT_TAGDECL([], [whole_archive_flag_spec], [1], - [Compiler flag to generate shared objects directly from archives]) -_LT_TAGDECL([], [compiler_needs_object], [1], - [Whether the compiler copes with passing no objects directly]) -_LT_TAGDECL([], [old_archive_from_new_cmds], [2], - [Create an old-style archive from a shared archive]) -_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], - [Create a temporary old-style archive to link instead of a shared archive]) -_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) -_LT_TAGDECL([], [archive_expsym_cmds], [2]) -_LT_TAGDECL([], [module_cmds], [2], - [Commands used to build a loadable module if different from building - a shared archive.]) -_LT_TAGDECL([], [module_expsym_cmds], [2]) -_LT_TAGDECL([], [with_gnu_ld], [1], - [Whether we are building with GNU ld or not]) -_LT_TAGDECL([], [allow_undefined_flag], [1], - [Flag that allows shared libraries with undefined symbols to be built]) -_LT_TAGDECL([], [no_undefined_flag], [1], - [Flag that enforces no undefined symbols]) -_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], - [Flag to hardcode $libdir into a binary during linking. - This must work even if $libdir does not exist]) -_LT_TAGDECL([], [hardcode_libdir_flag_spec_ld], [1], - [[If ld is used when linking, flag to hardcode $libdir into a binary - during linking. This must work even if $libdir does not exist]]) -_LT_TAGDECL([], [hardcode_libdir_separator], [1], - [Whether we need a single "-rpath" flag with a separated argument]) -_LT_TAGDECL([], [hardcode_direct], [0], - [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes - DIR into the resulting binary]) -_LT_TAGDECL([], [hardcode_direct_absolute], [0], - [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes - DIR into the resulting binary and the resulting library dependency is - "absolute", i.e impossible to change by setting ${shlibpath_var} if the - library is relocated]) -_LT_TAGDECL([], [hardcode_minus_L], [0], - [Set to "yes" if using the -LDIR flag during linking hardcodes DIR - into the resulting binary]) -_LT_TAGDECL([], [hardcode_shlibpath_var], [0], - [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR - into the resulting binary]) -_LT_TAGDECL([], [hardcode_automatic], [0], - [Set to "yes" if building a shared library automatically hardcodes DIR - into the library and all subsequent libraries and executables linked - against it]) -_LT_TAGDECL([], [inherit_rpath], [0], - [Set to yes if linker adds runtime paths of dependent libraries - to runtime path list]) -_LT_TAGDECL([], [link_all_deplibs], [0], - [Whether libtool must link a program against all its dependency libraries]) -_LT_TAGDECL([], [fix_srcfile_path], [1], - [Fix the shell variable $srcfile for the compiler]) -_LT_TAGDECL([], [always_export_symbols], [0], - [Set to "yes" if exported symbols are required]) -_LT_TAGDECL([], [export_symbols_cmds], [2], - [The commands to list exported symbols]) -_LT_TAGDECL([], [exclude_expsyms], [1], - [Symbols that should not be listed in the preloaded symbols]) -_LT_TAGDECL([], [include_expsyms], [1], - [Symbols that must always be exported]) -_LT_TAGDECL([], [prelink_cmds], [2], - [Commands necessary for linking programs (against libraries) with templates]) -_LT_TAGDECL([], [file_list_spec], [1], - [Specify filename containing input files]) -dnl FIXME: Not yet implemented -dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], -dnl [Compiler flag to generate thread safe objects]) -])# _LT_LINKER_SHLIBS - - -# _LT_LANG_C_CONFIG([TAG]) -# ------------------------ -# Ensure that the configuration variables for a C compiler are suitably -# defined. These variables are subsequently used by _LT_CONFIG to write -# the compiler configuration to `libtool'. -m4_defun([_LT_LANG_C_CONFIG], -[m4_require([_LT_DECL_EGREP])dnl -lt_save_CC="$CC" -AC_LANG_PUSH(C) - -# Source file extension for C test sources. -ac_ext=c - -# Object file extension for compiled C test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# Code to be used in simple compile tests -lt_simple_compile_test_code="int some_variable = 0;" - -# Code to be used in simple link tests -lt_simple_link_test_code='int main(){return(0);}' - -_LT_TAG_COMPILER -# Save the default compiler, since it gets overwritten when the other -# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. -compiler_DEFAULT=$CC - -# save warnings/boilerplate of simple test code -_LT_COMPILER_BOILERPLATE -_LT_LINKER_BOILERPLATE - -## CAVEAT EMPTOR: -## There is no encapsulation within the following macros, do not change -## the running order or otherwise move them around unless you know exactly -## what you are doing... -if test -n "$compiler"; then - _LT_COMPILER_NO_RTTI($1) - _LT_COMPILER_PIC($1) - _LT_COMPILER_C_O($1) - _LT_COMPILER_FILE_LOCKS($1) - _LT_LINKER_SHLIBS($1) - _LT_SYS_DYNAMIC_LINKER($1) - _LT_LINKER_HARDCODE_LIBPATH($1) - LT_SYS_DLOPEN_SELF - _LT_CMD_STRIPLIB - - # Report which library types will actually be built - AC_MSG_CHECKING([if libtool supports shared libraries]) - AC_MSG_RESULT([$can_build_shared]) - - AC_MSG_CHECKING([whether to build shared libraries]) - test "$can_build_shared" = "no" && enable_shared=no - - # On AIX, shared libraries and static libraries use the same namespace, and - # are all built from PIC. - case $host_os in - aix3*) - test "$enable_shared" = yes && enable_static=no - if test -n "$RANLIB"; then - archive_cmds="$archive_cmds~\$RANLIB \$lib" - postinstall_cmds='$RANLIB $lib' - fi - ;; - - aix[[4-9]]*) - if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then - test "$enable_shared" = yes && enable_static=no - fi - ;; - esac - AC_MSG_RESULT([$enable_shared]) - - AC_MSG_CHECKING([whether to build static libraries]) - # Make sure either enable_shared or enable_static is yes. - test "$enable_shared" = yes || enable_static=yes - AC_MSG_RESULT([$enable_static]) - - _LT_CONFIG($1) -fi -AC_LANG_POP -CC="$lt_save_CC" -])# _LT_LANG_C_CONFIG - - -# _LT_PROG_CXX -# ------------ -# Since AC_PROG_CXX is broken, in that it returns g++ if there is no c++ -# compiler, we have our own version here. -m4_defun([_LT_PROG_CXX], -[ -pushdef([AC_MSG_ERROR], [_lt_caught_CXX_error=yes]) -AC_PROG_CXX -if test -n "$CXX" && ( test "X$CXX" != "Xno" && - ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || - (test "X$CXX" != "Xg++"))) ; then - AC_PROG_CXXCPP -else - _lt_caught_CXX_error=yes -fi -popdef([AC_MSG_ERROR]) -])# _LT_PROG_CXX - -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([_LT_PROG_CXX], []) - - -# _LT_LANG_CXX_CONFIG([TAG]) -# -------------------------- -# Ensure that the configuration variables for a C++ compiler are suitably -# defined. These variables are subsequently used by _LT_CONFIG to write -# the compiler configuration to `libtool'. -m4_defun([_LT_LANG_CXX_CONFIG], -[AC_REQUIRE([_LT_PROG_CXX])dnl -m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_DECL_EGREP])dnl - -AC_LANG_PUSH(C++) -_LT_TAGVAR(archive_cmds_need_lc, $1)=no -_LT_TAGVAR(allow_undefined_flag, $1)= -_LT_TAGVAR(always_export_symbols, $1)=no -_LT_TAGVAR(archive_expsym_cmds, $1)= -_LT_TAGVAR(compiler_needs_object, $1)=no -_LT_TAGVAR(export_dynamic_flag_spec, $1)= -_LT_TAGVAR(hardcode_direct, $1)=no -_LT_TAGVAR(hardcode_direct_absolute, $1)=no -_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= -_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= -_LT_TAGVAR(hardcode_libdir_separator, $1)= -_LT_TAGVAR(hardcode_minus_L, $1)=no -_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported -_LT_TAGVAR(hardcode_automatic, $1)=no -_LT_TAGVAR(inherit_rpath, $1)=no -_LT_TAGVAR(module_cmds, $1)= -_LT_TAGVAR(module_expsym_cmds, $1)= -_LT_TAGVAR(link_all_deplibs, $1)=unknown -_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds -_LT_TAGVAR(no_undefined_flag, $1)= -_LT_TAGVAR(whole_archive_flag_spec, $1)= -_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no - -# Source file extension for C++ test sources. -ac_ext=cpp - -# Object file extension for compiled C++ test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# No sense in running all these tests if we already determined that -# the CXX compiler isn't working. Some variables (like enable_shared) -# are currently assumed to apply to all compilers on this platform, -# and will be corrupted by setting them based on a non-working compiler. -if test "$_lt_caught_CXX_error" != yes; then - # Code to be used in simple compile tests - lt_simple_compile_test_code="int some_variable = 0;" - - # Code to be used in simple link tests - lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' - - # ltmain only uses $CC for tagged configurations so make sure $CC is set. - _LT_TAG_COMPILER - - # save warnings/boilerplate of simple test code - _LT_COMPILER_BOILERPLATE - _LT_LINKER_BOILERPLATE - - # Allow CC to be a program name with arguments. - lt_save_CC=$CC - lt_save_LD=$LD - lt_save_GCC=$GCC - GCC=$GXX - lt_save_with_gnu_ld=$with_gnu_ld - lt_save_path_LD=$lt_cv_path_LD - if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then - lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx - else - $as_unset lt_cv_prog_gnu_ld - fi - if test -n "${lt_cv_path_LDCXX+set}"; then - lt_cv_path_LD=$lt_cv_path_LDCXX - else - $as_unset lt_cv_path_LD - fi - test -z "${LDCXX+set}" || LD=$LDCXX - CC=${CXX-"c++"} - compiler=$CC - _LT_TAGVAR(compiler, $1)=$CC - _LT_CC_BASENAME([$compiler]) - - if test -n "$compiler"; then - # We don't want -fno-exception when compiling C++ code, so set the - # no_builtin_flag separately - if test "$GXX" = yes; then - _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' - else - _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= - fi - - if test "$GXX" = yes; then - # Set up default GNU C++ configuration - - LT_PATH_LD - - # Check if GNU C++ uses GNU ld as the underlying linker, since the - # archiving commands below assume that GNU ld is being used. - if test "$with_gnu_ld" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - - # If archive_cmds runs LD, not CC, wlarc should be empty - # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to - # investigate it a little bit more. (MM) - wlarc='${wl}' - - # ancient GNU ld didn't support --whole-archive et. al. - if eval "`$CC -print-prog-name=ld` --help 2>&1" | - $GREP 'no-whole-archive' > /dev/null; then - _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' - else - _LT_TAGVAR(whole_archive_flag_spec, $1)= - fi - else - with_gnu_ld=no - wlarc= - - # A generic and very simple default shared library creation - # command for GNU C++ for the case where it uses the native - # linker, instead of GNU ld. If possible, this setting should - # overridden to take advantage of the native linker features on - # the platform it is being used on. - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' - fi - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' - - else - GXX=no - with_gnu_ld=no - wlarc= - fi - - # PORTME: fill in a description of your system's C++ link characteristics - AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) - _LT_TAGVAR(ld_shlibs, $1)=yes - case $host_os in - aix3*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - aix[[4-9]]*) - if test "$host_cpu" = ia64; then - # On IA64, the linker does run time linking by default, so we don't - # have to do anything special. - aix_use_runtimelinking=no - exp_sym_flag='-Bexport' - no_entry_flag="" - else - aix_use_runtimelinking=no - - # Test if we are trying to use run time linking or normal - # AIX style linking. If -brtl is somewhere in LDFLAGS, we - # need to do runtime linking. - case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) - for ld_flag in $LDFLAGS; do - case $ld_flag in - *-brtl*) - aix_use_runtimelinking=yes - break - ;; - esac - done - ;; - esac - - exp_sym_flag='-bexport' - no_entry_flag='-bnoentry' - fi - - # When large executables or shared objects are built, AIX ld can - # have problems creating the table of contents. If linking a library - # or program results in "error TOC overflow" add -mminimal-toc to - # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not - # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. - - _LT_TAGVAR(archive_cmds, $1)='' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(hardcode_libdir_separator, $1)=':' - _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' - - if test "$GXX" = yes; then - case $host_os in aix4.[[012]]|aix4.[[012]].*) - # We only want to do this on AIX 4.2 and lower, the check - # below for broken collect2 doesn't work under 4.3+ - collect2name=`${CC} -print-prog-name=collect2` - if test -f "$collect2name" && - strings "$collect2name" | $GREP resolve_lib_name >/dev/null - then - # We have reworked collect2 - : - else - # We have old collect2 - _LT_TAGVAR(hardcode_direct, $1)=unsupported - # It fails to find uninstalled libraries when the uninstalled - # path is not listed in the libpath. Setting hardcode_minus_L - # to unsupported forces relinking - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)= - fi - esac - shared_flag='-shared' - if test "$aix_use_runtimelinking" = yes; then - shared_flag="$shared_flag "'${wl}-G' - fi - else - # not using gcc - if test "$host_cpu" = ia64; then - # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release - # chokes on -Wl,-G. The following line is correct: - shared_flag='-G' - else - if test "$aix_use_runtimelinking" = yes; then - shared_flag='${wl}-G' - else - shared_flag='${wl}-bM:SRE' - fi - fi - fi - - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' - # It seems that -bexpall does not export symbols beginning with - # underscore (_), so it is better to generate a list of symbols to - # export. - _LT_TAGVAR(always_export_symbols, $1)=yes - if test "$aix_use_runtimelinking" = yes; then - # Warning - without using the other runtime loading flags (-brtl), - # -berok will link without error, but may produce a broken library. - _LT_TAGVAR(allow_undefined_flag, $1)='-berok' - # Determine the default libpath from the value encoded in an empty - # executable. - _LT_SYS_MODULE_PATH_AIX - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" - - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" - else - if test "$host_cpu" = ia64; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' - _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" - _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" - else - # Determine the default libpath from the value encoded in an - # empty executable. - _LT_SYS_MODULE_PATH_AIX - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" - # Warning - without using the other run time loading flags, - # -berok will link without error, but may produce a broken library. - _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' - # Exported symbols can be pulled into shared objects from archives - _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' - _LT_TAGVAR(archive_cmds_need_lc, $1)=yes - # This is similar to how AIX traditionally builds its shared - # libraries. - _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' - fi - fi - ;; - - beos*) - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - # Joseph Beckenbach says some releases of gcc - # support --undefined. This deserves some investigation. FIXME - _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - chorus*) - case $cc_basename in - *) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - - cygwin* | mingw* | pw32* | cegcc*) - # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, - # as there is no search path for DLLs. - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_TAGVAR(always_export_symbols, $1)=no - _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes - - if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - # If the export-symbols file already is a .def file (1st line - # is EXPORTS), use it as is; otherwise, prepend... - _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - cp $export_symbols $output_objdir/$soname.def; - else - echo EXPORTS > $output_objdir/$soname.def; - cat $export_symbols >> $output_objdir/$soname.def; - fi~ - $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - darwin* | rhapsody*) - _LT_DARWIN_LINKER_FEATURES($1) - ;; - - dgux*) - case $cc_basename in - ec++*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - ghcx*) - # Green Hills C++ Compiler - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - *) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - - freebsd[[12]]*) - # C++ shared libraries reported to be fairly broken before - # switch to ELF - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - freebsd-elf*) - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - ;; - - freebsd* | dragonfly*) - # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF - # conventions - _LT_TAGVAR(ld_shlibs, $1)=yes - ;; - - gnu*) - ;; - - hpux9*) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, - # but as the default - # location of the library. - - case $cc_basename in - CC*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - aCC*) - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' - ;; - *) - if test "$GXX" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - else - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - ;; - - hpux10*|hpux11*) - if test $with_gnu_ld = no; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - - case $host_cpu in - hppa*64*|ia64*) - ;; - *) - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - ;; - esac - fi - case $host_cpu in - hppa*64*|ia64*) - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - *) - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, - # but as the default - # location of the library. - ;; - esac - - case $cc_basename in - CC*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - aCC*) - case $host_cpu in - hppa*64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - ia64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - esac - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' - ;; - *) - if test "$GXX" = yes; then - if test $with_gnu_ld = no; then - case $host_cpu in - hppa*64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - ia64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - esac - fi - else - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - ;; - - interix[[3-9]]*) - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. - # Instead, shared libraries are loaded at an image base (0x10000000 by - # default) and relocated if they conflict, which is a slow very memory - # consuming and fragmenting process. To avoid this, we pick a random, - # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link - # time. Moving up from 0x10000000 also allows more sbrk(2) space. - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - ;; - irix5* | irix6*) - case $cc_basename in - CC*) - # SGI C++ - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' - - # Archives containing C++ object files must be created using - # "CC -ar", where "CC" is the IRIX C++ compiler. This is - # necessary to make sure instantiated templates are included - # in the archive. - _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' - ;; - *) - if test "$GXX" = yes; then - if test "$with_gnu_ld" = no; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - else - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` -o $lib' - fi - fi - _LT_TAGVAR(link_all_deplibs, $1)=yes - ;; - esac - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(inherit_rpath, $1)=yes - ;; - - linux* | k*bsd*-gnu) - case $cc_basename in - KCC*) - # Kuck and Associates, Inc. (KAI) C++ Compiler - - # KCC will only create a shared library if the output file - # ends with ".so" (or ".sl" for HP-UX), so rename the library - # to its proper name (with version) after linking. - _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - - # Archives containing C++ object files must be created using - # "CC -Bstatic", where "CC" is the KAI C++ compiler. - _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' - ;; - icpc* | ecpc* ) - # Intel C++ - with_gnu_ld=yes - # version 8.0 and above of icpc choke on multiply defined symbols - # if we add $predep_objects and $postdep_objects, however 7.1 and - # earlier do not add the objects themselves. - case `$CC -V 2>&1` in - *"Version 7."*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - ;; - *) # Version 8.0 or newer - tmp_idyn= - case $host_cpu in - ia64*) tmp_idyn=' -i_dynamic';; - esac - _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - ;; - esac - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' - ;; - pgCC* | pgcpp*) - # Portland Group C++ compiler - case `$CC -V` in - *pgCC\ [[1-5]]* | *pgcpp\ [[1-5]]*) - _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ - compile_command="$compile_command `find $tpldir -name \*.o | $NL2SP`"' - _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ - $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | $NL2SP`~ - $RANLIB $oldlib' - _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ - $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ - $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' - ;; - *) # Version 6 will use weak symbols - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' - ;; - esac - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' - ;; - cxx*) - # Compaq C++ - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' - - runpath_var=LD_RUN_PATH - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' - ;; - xl*) - # IBM XL 8.0 on PPC, with GNU ld - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - if test "x$supports_anon_versioning" = xyes; then - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' - fi - ;; - *) - case `$CC -V 2>&1 | sed 5q` in - *Sun\ C*) - # Sun C++ 5.9 - _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' - _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' - _LT_TAGVAR(compiler_needs_object, $1)=yes - - # Not sure whether something based on - # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 - # would be better. - output_verbose_link_cmd='echo' - - # Archives containing C++ object files must be created using - # "CC -xar", where "CC" is the Sun C++ compiler. This is - # necessary to make sure instantiated templates are included - # in the archive. - _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' - ;; - esac - ;; - esac - ;; - - lynxos*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - m88k*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - mvs*) - case $cc_basename in - cxx*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - *) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - - netbsd*) - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' - wlarc= - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - fi - # Workaround some broken pre-1.5 toolchains - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' - ;; - - *nto* | *qnx*) - _LT_TAGVAR(ld_shlibs, $1)=yes - ;; - - openbsd2*) - # C++ shared libraries are fairly broken - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - openbsd*) - if test -f /usr/libexec/ld.so; then - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' - fi - output_verbose_link_cmd=echo - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - osf3* | osf4* | osf5*) - case $cc_basename in - KCC*) - # Kuck and Associates, Inc. (KAI) C++ Compiler - - # KCC will only create a shared library if the output file - # ends with ".so" (or ".sl" for HP-UX), so rename the library - # to its proper name (with version) after linking. - _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - - # Archives containing C++ object files must be created using - # the KAI C++ compiler. - case $host in - osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; - *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; - esac - ;; - RCC*) - # Rational C++ 2.4.1 - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - cxx*) - case $host in - osf3*) - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && $ECHO "X${wl}-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - ;; - *) - _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ - echo "-hidden">> $lib.exp~ - $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~ - $RM $lib.exp' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' - ;; - esac - - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' - ;; - *) - if test "$GXX" = yes && test "$with_gnu_ld" = no; then - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' - case $host in - osf3*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - ;; - esac - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' - - else - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - ;; - - psos*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - sunos4*) - case $cc_basename in - CC*) - # Sun C++ 4.x - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - lcc*) - # Lucid - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - *) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - - solaris*) - case $cc_basename in - CC*) - # Sun C++ 4.2, 5.x and Centerline C++ - _LT_TAGVAR(archive_cmds_need_lc,$1)=yes - _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' - _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - case $host_os in - solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; - *) - # The compiler driver will combine and reorder linker options, - # but understands `-z linker_flag'. - # Supported since Solaris 2.6 (maybe 2.5.1?) - _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' - ;; - esac - _LT_TAGVAR(link_all_deplibs, $1)=yes - - output_verbose_link_cmd='echo' - - # Archives containing C++ object files must be created using - # "CC -xar", where "CC" is the Sun C++ compiler. This is - # necessary to make sure instantiated templates are included - # in the archive. - _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' - ;; - gcx*) - # Green Hills C++ Compiler - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' - - # The C++ compiler must be used to create the archive. - _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' - ;; - *) - # GNU C++ compiler with Solaris linker - if test "$GXX" = yes && test "$with_gnu_ld" = no; then - _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' - if $CC --version | $GREP -v '^2\.7' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' - else - # g++ 2.7 appears to require `-G' NOT `-shared' on this - # platform. - _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' - fi - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' - case $host_os in - solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; - *) - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' - ;; - esac - fi - ;; - esac - ;; - - sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) - _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - runpath_var='LD_RUN_PATH' - - case $cc_basename in - CC*) - _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - esac - ;; - - sysv5* | sco3.2v5* | sco5v6*) - # Note: We can NOT use -z defs as we might desire, because we do not - # link with -lc, and that would cause any symbols used from libc to - # always be unresolved, which means just about no library would - # ever link correctly. If we're not using GNU ld we use -z text - # though, which does catch some bad symbols but isn't as heavy-handed - # as -z defs. - _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' - _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=':' - _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' - runpath_var='LD_RUN_PATH' - - case $cc_basename in - CC*) - _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - esac - ;; - - tandem*) - case $cc_basename in - NCC*) - # NonStop-UX NCC 3.20 - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - *) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - - vxworks*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - *) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - - AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) - test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no - - _LT_TAGVAR(GCC, $1)="$GXX" - _LT_TAGVAR(LD, $1)="$LD" - - ## CAVEAT EMPTOR: - ## There is no encapsulation within the following macros, do not change - ## the running order or otherwise move them around unless you know exactly - ## what you are doing... - _LT_SYS_HIDDEN_LIBDEPS($1) - _LT_COMPILER_PIC($1) - _LT_COMPILER_C_O($1) - _LT_COMPILER_FILE_LOCKS($1) - _LT_LINKER_SHLIBS($1) - _LT_SYS_DYNAMIC_LINKER($1) - _LT_LINKER_HARDCODE_LIBPATH($1) - - _LT_CONFIG($1) - fi # test -n "$compiler" - - CC=$lt_save_CC - LDCXX=$LD - LD=$lt_save_LD - GCC=$lt_save_GCC - with_gnu_ld=$lt_save_with_gnu_ld - lt_cv_path_LDCXX=$lt_cv_path_LD - lt_cv_path_LD=$lt_save_path_LD - lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld - lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld -fi # test "$_lt_caught_CXX_error" != yes - -AC_LANG_POP -])# _LT_LANG_CXX_CONFIG - - -# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) -# --------------------------------- -# Figure out "hidden" library dependencies from verbose -# compiler output when linking a shared library. -# Parse the compiler output and extract the necessary -# objects, libraries and library flags. -m4_defun([_LT_SYS_HIDDEN_LIBDEPS], -[m4_require([_LT_FILEUTILS_DEFAULTS])dnl -# Dependencies to place before and after the object being linked: -_LT_TAGVAR(predep_objects, $1)= -_LT_TAGVAR(postdep_objects, $1)= -_LT_TAGVAR(predeps, $1)= -_LT_TAGVAR(postdeps, $1)= -_LT_TAGVAR(compiler_lib_search_path, $1)= - -dnl we can't use the lt_simple_compile_test_code here, -dnl because it contains code intended for an executable, -dnl not a library. It's possible we should let each -dnl tag define a new lt_????_link_test_code variable, -dnl but it's only used here... -m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF -int a; -void foo (void) { a = 0; } -_LT_EOF -], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF -class Foo -{ -public: - Foo (void) { a = 0; } -private: - int a; -}; -_LT_EOF -], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF - subroutine foo - implicit none - integer*4 a - a=0 - return - end -_LT_EOF -], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF - subroutine foo - implicit none - integer a - a=0 - return - end -_LT_EOF -], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF -public class foo { - private int a; - public void bar (void) { - a = 0; - } -}; -_LT_EOF -]) -dnl Parse the compiler output and extract the necessary -dnl objects, libraries and library flags. -if AC_TRY_EVAL(ac_compile); then - # Parse the compiler output and extract the necessary - # objects, libraries and library flags. - - # Sentinel used to keep track of whether or not we are before - # the conftest object file. - pre_test_object_deps_done=no - - for p in `eval "$output_verbose_link_cmd"`; do - case $p in - - -L* | -R* | -l*) - # Some compilers place space between "-{L,R}" and the path. - # Remove the space. - if test $p = "-L" || - test $p = "-R"; then - prev=$p - continue - else - prev= - fi - - if test "$pre_test_object_deps_done" = no; then - case $p in - -L* | -R*) - # Internal compiler library paths should come after those - # provided the user. The postdeps already come after the - # user supplied libs so there is no need to process them. - if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then - _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}" - else - _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}" - fi - ;; - # The "-l" case would never come before the object being - # linked, so don't bother handling this case. - esac - else - if test -z "$_LT_TAGVAR(postdeps, $1)"; then - _LT_TAGVAR(postdeps, $1)="${prev}${p}" - else - _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}" - fi - fi - ;; - - *.$objext) - # This assumes that the test object file only shows up - # once in the compiler output. - if test "$p" = "conftest.$objext"; then - pre_test_object_deps_done=yes - continue - fi - - if test "$pre_test_object_deps_done" = no; then - if test -z "$_LT_TAGVAR(predep_objects, $1)"; then - _LT_TAGVAR(predep_objects, $1)="$p" - else - _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" - fi - else - if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then - _LT_TAGVAR(postdep_objects, $1)="$p" - else - _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" - fi - fi - ;; - - *) ;; # Ignore the rest. - - esac - done - - # Clean up. - rm -f a.out a.exe -else - echo "libtool.m4: error: problem compiling $1 test program" -fi - -$RM -f confest.$objext - -# PORTME: override above test on systems where it is broken -m4_if([$1], [CXX], -[case $host_os in -interix[[3-9]]*) - # Interix 3.5 installs completely hosed .la files for C++, so rather than - # hack all around it, let's just trust "g++" to DTRT. - _LT_TAGVAR(predep_objects,$1)= - _LT_TAGVAR(postdep_objects,$1)= - _LT_TAGVAR(postdeps,$1)= - ;; - -linux*) - case `$CC -V 2>&1 | sed 5q` in - *Sun\ C*) - # Sun C++ 5.9 - - # The more standards-conforming stlport4 library is - # incompatible with the Cstd library. Avoid specifying - # it if it's in CXXFLAGS. Ignore libCrun as - # -library=stlport4 depends on it. - case " $CXX $CXXFLAGS " in - *" -library=stlport4 "*) - solaris_use_stlport4=yes - ;; - esac - - if test "$solaris_use_stlport4" != yes; then - _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' - fi - ;; - esac - ;; - -solaris*) - case $cc_basename in - CC*) - # The more standards-conforming stlport4 library is - # incompatible with the Cstd library. Avoid specifying - # it if it's in CXXFLAGS. Ignore libCrun as - # -library=stlport4 depends on it. - case " $CXX $CXXFLAGS " in - *" -library=stlport4 "*) - solaris_use_stlport4=yes - ;; - esac - - # Adding this requires a known-good setup of shared libraries for - # Sun compiler versions before 5.6, else PIC objects from an old - # archive will be linked into the output, leading to subtle bugs. - if test "$solaris_use_stlport4" != yes; then - _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' - fi - ;; - esac - ;; -esac -]) - -case " $_LT_TAGVAR(postdeps, $1) " in -*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; -esac - _LT_TAGVAR(compiler_lib_search_dirs, $1)= -if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then - _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` -fi -_LT_TAGDECL([], [compiler_lib_search_dirs], [1], - [The directories searched by this compiler when creating a shared library]) -_LT_TAGDECL([], [predep_objects], [1], - [Dependencies to place before and after the objects being linked to - create a shared library]) -_LT_TAGDECL([], [postdep_objects], [1]) -_LT_TAGDECL([], [predeps], [1]) -_LT_TAGDECL([], [postdeps], [1]) -_LT_TAGDECL([], [compiler_lib_search_path], [1], - [The library search path used internally by the compiler when linking - a shared library]) -])# _LT_SYS_HIDDEN_LIBDEPS - - -# _LT_PROG_F77 -# ------------ -# Since AC_PROG_F77 is broken, in that it returns the empty string -# if there is no fortran compiler, we have our own version here. -m4_defun([_LT_PROG_F77], -[ -pushdef([AC_MSG_ERROR], [_lt_disable_F77=yes]) -AC_PROG_F77 -if test -z "$F77" || test "X$F77" = "Xno"; then - _lt_disable_F77=yes -fi -popdef([AC_MSG_ERROR]) -])# _LT_PROG_F77 - -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([_LT_PROG_F77], []) - - -# _LT_LANG_F77_CONFIG([TAG]) -# -------------------------- -# Ensure that the configuration variables for a Fortran 77 compiler are -# suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to `libtool'. -m4_defun([_LT_LANG_F77_CONFIG], -[AC_REQUIRE([_LT_PROG_F77])dnl -AC_LANG_PUSH(Fortran 77) - -_LT_TAGVAR(archive_cmds_need_lc, $1)=no -_LT_TAGVAR(allow_undefined_flag, $1)= -_LT_TAGVAR(always_export_symbols, $1)=no -_LT_TAGVAR(archive_expsym_cmds, $1)= -_LT_TAGVAR(export_dynamic_flag_spec, $1)= -_LT_TAGVAR(hardcode_direct, $1)=no -_LT_TAGVAR(hardcode_direct_absolute, $1)=no -_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= -_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= -_LT_TAGVAR(hardcode_libdir_separator, $1)= -_LT_TAGVAR(hardcode_minus_L, $1)=no -_LT_TAGVAR(hardcode_automatic, $1)=no -_LT_TAGVAR(inherit_rpath, $1)=no -_LT_TAGVAR(module_cmds, $1)= -_LT_TAGVAR(module_expsym_cmds, $1)= -_LT_TAGVAR(link_all_deplibs, $1)=unknown -_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds -_LT_TAGVAR(no_undefined_flag, $1)= -_LT_TAGVAR(whole_archive_flag_spec, $1)= -_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no - -# Source file extension for f77 test sources. -ac_ext=f - -# Object file extension for compiled f77 test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# No sense in running all these tests if we already determined that -# the F77 compiler isn't working. Some variables (like enable_shared) -# are currently assumed to apply to all compilers on this platform, -# and will be corrupted by setting them based on a non-working compiler. -if test "$_lt_disable_F77" != yes; then - # Code to be used in simple compile tests - lt_simple_compile_test_code="\ - subroutine t - return - end -" - - # Code to be used in simple link tests - lt_simple_link_test_code="\ - program t - end -" - - # ltmain only uses $CC for tagged configurations so make sure $CC is set. - _LT_TAG_COMPILER - - # save warnings/boilerplate of simple test code - _LT_COMPILER_BOILERPLATE - _LT_LINKER_BOILERPLATE - - # Allow CC to be a program name with arguments. - lt_save_CC="$CC" - lt_save_GCC=$GCC - CC=${F77-"f77"} - compiler=$CC - _LT_TAGVAR(compiler, $1)=$CC - _LT_CC_BASENAME([$compiler]) - GCC=$G77 - if test -n "$compiler"; then - AC_MSG_CHECKING([if libtool supports shared libraries]) - AC_MSG_RESULT([$can_build_shared]) - - AC_MSG_CHECKING([whether to build shared libraries]) - test "$can_build_shared" = "no" && enable_shared=no - - # On AIX, shared libraries and static libraries use the same namespace, and - # are all built from PIC. - case $host_os in - aix3*) - test "$enable_shared" = yes && enable_static=no - if test -n "$RANLIB"; then - archive_cmds="$archive_cmds~\$RANLIB \$lib" - postinstall_cmds='$RANLIB $lib' - fi - ;; - aix[[4-9]]*) - if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then - test "$enable_shared" = yes && enable_static=no - fi - ;; - esac - AC_MSG_RESULT([$enable_shared]) - - AC_MSG_CHECKING([whether to build static libraries]) - # Make sure either enable_shared or enable_static is yes. - test "$enable_shared" = yes || enable_static=yes - AC_MSG_RESULT([$enable_static]) - - _LT_TAGVAR(GCC, $1)="$G77" - _LT_TAGVAR(LD, $1)="$LD" - - ## CAVEAT EMPTOR: - ## There is no encapsulation within the following macros, do not change - ## the running order or otherwise move them around unless you know exactly - ## what you are doing... - _LT_COMPILER_PIC($1) - _LT_COMPILER_C_O($1) - _LT_COMPILER_FILE_LOCKS($1) - _LT_LINKER_SHLIBS($1) - _LT_SYS_DYNAMIC_LINKER($1) - _LT_LINKER_HARDCODE_LIBPATH($1) - - _LT_CONFIG($1) - fi # test -n "$compiler" - - GCC=$lt_save_GCC - CC="$lt_save_CC" -fi # test "$_lt_disable_F77" != yes - -AC_LANG_POP -])# _LT_LANG_F77_CONFIG - - -# _LT_PROG_FC -# ----------- -# Since AC_PROG_FC is broken, in that it returns the empty string -# if there is no fortran compiler, we have our own version here. -m4_defun([_LT_PROG_FC], -[ -pushdef([AC_MSG_ERROR], [_lt_disable_FC=yes]) -AC_PROG_FC -if test -z "$FC" || test "X$FC" = "Xno"; then - _lt_disable_FC=yes -fi -popdef([AC_MSG_ERROR]) -])# _LT_PROG_FC - -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([_LT_PROG_FC], []) - - -# _LT_LANG_FC_CONFIG([TAG]) -# ------------------------- -# Ensure that the configuration variables for a Fortran compiler are -# suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to `libtool'. -m4_defun([_LT_LANG_FC_CONFIG], -[AC_REQUIRE([_LT_PROG_FC])dnl -AC_LANG_PUSH(Fortran) - -_LT_TAGVAR(archive_cmds_need_lc, $1)=no -_LT_TAGVAR(allow_undefined_flag, $1)= -_LT_TAGVAR(always_export_symbols, $1)=no -_LT_TAGVAR(archive_expsym_cmds, $1)= -_LT_TAGVAR(export_dynamic_flag_spec, $1)= -_LT_TAGVAR(hardcode_direct, $1)=no -_LT_TAGVAR(hardcode_direct_absolute, $1)=no -_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= -_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= -_LT_TAGVAR(hardcode_libdir_separator, $1)= -_LT_TAGVAR(hardcode_minus_L, $1)=no -_LT_TAGVAR(hardcode_automatic, $1)=no -_LT_TAGVAR(inherit_rpath, $1)=no -_LT_TAGVAR(module_cmds, $1)= -_LT_TAGVAR(module_expsym_cmds, $1)= -_LT_TAGVAR(link_all_deplibs, $1)=unknown -_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds -_LT_TAGVAR(no_undefined_flag, $1)= -_LT_TAGVAR(whole_archive_flag_spec, $1)= -_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no - -# Source file extension for fc test sources. -ac_ext=${ac_fc_srcext-f} - -# Object file extension for compiled fc test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# No sense in running all these tests if we already determined that -# the FC compiler isn't working. Some variables (like enable_shared) -# are currently assumed to apply to all compilers on this platform, -# and will be corrupted by setting them based on a non-working compiler. -if test "$_lt_disable_FC" != yes; then - # Code to be used in simple compile tests - lt_simple_compile_test_code="\ - subroutine t - return - end -" - - # Code to be used in simple link tests - lt_simple_link_test_code="\ - program t - end -" - - # ltmain only uses $CC for tagged configurations so make sure $CC is set. - _LT_TAG_COMPILER - - # save warnings/boilerplate of simple test code - _LT_COMPILER_BOILERPLATE - _LT_LINKER_BOILERPLATE - - # Allow CC to be a program name with arguments. - lt_save_CC="$CC" - lt_save_GCC=$GCC - CC=${FC-"f95"} - compiler=$CC - GCC=$ac_cv_fc_compiler_gnu - - _LT_TAGVAR(compiler, $1)=$CC - _LT_CC_BASENAME([$compiler]) - - if test -n "$compiler"; then - AC_MSG_CHECKING([if libtool supports shared libraries]) - AC_MSG_RESULT([$can_build_shared]) - - AC_MSG_CHECKING([whether to build shared libraries]) - test "$can_build_shared" = "no" && enable_shared=no - - # On AIX, shared libraries and static libraries use the same namespace, and - # are all built from PIC. - case $host_os in - aix3*) - test "$enable_shared" = yes && enable_static=no - if test -n "$RANLIB"; then - archive_cmds="$archive_cmds~\$RANLIB \$lib" - postinstall_cmds='$RANLIB $lib' - fi - ;; - aix[[4-9]]*) - if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then - test "$enable_shared" = yes && enable_static=no - fi - ;; - esac - AC_MSG_RESULT([$enable_shared]) - - AC_MSG_CHECKING([whether to build static libraries]) - # Make sure either enable_shared or enable_static is yes. - test "$enable_shared" = yes || enable_static=yes - AC_MSG_RESULT([$enable_static]) - - _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu" - _LT_TAGVAR(LD, $1)="$LD" - - ## CAVEAT EMPTOR: - ## There is no encapsulation within the following macros, do not change - ## the running order or otherwise move them around unless you know exactly - ## what you are doing... - _LT_SYS_HIDDEN_LIBDEPS($1) - _LT_COMPILER_PIC($1) - _LT_COMPILER_C_O($1) - _LT_COMPILER_FILE_LOCKS($1) - _LT_LINKER_SHLIBS($1) - _LT_SYS_DYNAMIC_LINKER($1) - _LT_LINKER_HARDCODE_LIBPATH($1) - - _LT_CONFIG($1) - fi # test -n "$compiler" - - GCC=$lt_save_GCC - CC="$lt_save_CC" -fi # test "$_lt_disable_FC" != yes - -AC_LANG_POP -])# _LT_LANG_FC_CONFIG - - -# _LT_LANG_GCJ_CONFIG([TAG]) -# -------------------------- -# Ensure that the configuration variables for the GNU Java Compiler compiler -# are suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to `libtool'. -m4_defun([_LT_LANG_GCJ_CONFIG], -[AC_REQUIRE([LT_PROG_GCJ])dnl -AC_LANG_SAVE - -# Source file extension for Java test sources. -ac_ext=java - -# Object file extension for compiled Java test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# Code to be used in simple compile tests -lt_simple_compile_test_code="class foo {}" - -# Code to be used in simple link tests -lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' - -# ltmain only uses $CC for tagged configurations so make sure $CC is set. -_LT_TAG_COMPILER - -# save warnings/boilerplate of simple test code -_LT_COMPILER_BOILERPLATE -_LT_LINKER_BOILERPLATE - -# Allow CC to be a program name with arguments. -lt_save_CC="$CC" -lt_save_GCC=$GCC -GCC=yes -CC=${GCJ-"gcj"} -compiler=$CC -_LT_TAGVAR(compiler, $1)=$CC -_LT_TAGVAR(LD, $1)="$LD" -_LT_CC_BASENAME([$compiler]) - -# GCJ did not exist at the time GCC didn't implicitly link libc in. -_LT_TAGVAR(archive_cmds_need_lc, $1)=no - -_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds - -## CAVEAT EMPTOR: -## There is no encapsulation within the following macros, do not change -## the running order or otherwise move them around unless you know exactly -## what you are doing... -if test -n "$compiler"; then - _LT_COMPILER_NO_RTTI($1) - _LT_COMPILER_PIC($1) - _LT_COMPILER_C_O($1) - _LT_COMPILER_FILE_LOCKS($1) - _LT_LINKER_SHLIBS($1) - _LT_LINKER_HARDCODE_LIBPATH($1) - - _LT_CONFIG($1) -fi - -AC_LANG_RESTORE - -GCC=$lt_save_GCC -CC="$lt_save_CC" -])# _LT_LANG_GCJ_CONFIG - - -# _LT_LANG_RC_CONFIG([TAG]) -# ------------------------- -# Ensure that the configuration variables for the Windows resource compiler -# are suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to `libtool'. -m4_defun([_LT_LANG_RC_CONFIG], -[AC_REQUIRE([LT_PROG_RC])dnl -AC_LANG_SAVE - -# Source file extension for RC test sources. -ac_ext=rc - -# Object file extension for compiled RC test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# Code to be used in simple compile tests -lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' - -# Code to be used in simple link tests -lt_simple_link_test_code="$lt_simple_compile_test_code" - -# ltmain only uses $CC for tagged configurations so make sure $CC is set. -_LT_TAG_COMPILER - -# save warnings/boilerplate of simple test code -_LT_COMPILER_BOILERPLATE -_LT_LINKER_BOILERPLATE - -# Allow CC to be a program name with arguments. -lt_save_CC="$CC" -lt_save_GCC=$GCC -GCC= -CC=${RC-"windres"} -compiler=$CC -_LT_TAGVAR(compiler, $1)=$CC -_LT_CC_BASENAME([$compiler]) -_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes - -if test -n "$compiler"; then - : - _LT_CONFIG($1) -fi - -GCC=$lt_save_GCC -AC_LANG_RESTORE -CC="$lt_save_CC" -])# _LT_LANG_RC_CONFIG - - -# LT_PROG_GCJ -# ----------- -AC_DEFUN([LT_PROG_GCJ], -[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], - [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], - [AC_CHECK_TOOL(GCJ, gcj,) - test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" - AC_SUBST(GCJFLAGS)])])[]dnl -]) - -# Old name: -AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([LT_AC_PROG_GCJ], []) - - -# LT_PROG_RC -# ---------- -AC_DEFUN([LT_PROG_RC], -[AC_CHECK_TOOL(RC, windres,) -]) - -# Old name: -AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([LT_AC_PROG_RC], []) - - -# _LT_DECL_EGREP -# -------------- -# If we don't have a new enough Autoconf to choose the best grep -# available, choose the one first in the user's PATH. -m4_defun([_LT_DECL_EGREP], -[AC_REQUIRE([AC_PROG_EGREP])dnl -AC_REQUIRE([AC_PROG_FGREP])dnl -test -z "$GREP" && GREP=grep -_LT_DECL([], [GREP], [1], [A grep program that handles long lines]) -_LT_DECL([], [EGREP], [1], [An ERE matcher]) -_LT_DECL([], [FGREP], [1], [A literal string matcher]) -dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too -AC_SUBST([GREP]) -]) - - -# _LT_DECL_OBJDUMP -# -------------- -# If we don't have a new enough Autoconf to choose the best objdump -# available, choose the one first in the user's PATH. -m4_defun([_LT_DECL_OBJDUMP], -[AC_CHECK_TOOL(OBJDUMP, objdump, false) -test -z "$OBJDUMP" && OBJDUMP=objdump -_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) -AC_SUBST([OBJDUMP]) -]) - - -# _LT_DECL_SED -# ------------ -# Check for a fully-functional sed program, that truncates -# as few characters as possible. Prefer GNU sed if found. -m4_defun([_LT_DECL_SED], -[AC_PROG_SED -test -z "$SED" && SED=sed -Xsed="$SED -e 1s/^X//" -_LT_DECL([], [SED], [1], [A sed program that does not truncate output]) -_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], - [Sed that helps us avoid accidentally triggering echo(1) options like -n]) -])# _LT_DECL_SED - -m4_ifndef([AC_PROG_SED], [ -############################################################ -# NOTE: This macro has been submitted for inclusion into # -# GNU Autoconf as AC_PROG_SED. When it is available in # -# a released version of Autoconf we should remove this # -# macro and use it instead. # -############################################################ - -m4_defun([AC_PROG_SED], -[AC_MSG_CHECKING([for a sed that does not truncate output]) -AC_CACHE_VAL(lt_cv_path_SED, -[# Loop through the user's path and test for sed and gsed. -# Then use that list of sed's as ones to test for truncation. -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for lt_ac_prog in sed gsed; do - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then - lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" - fi - done - done -done -IFS=$as_save_IFS -lt_ac_max=0 -lt_ac_count=0 -# Add /usr/xpg4/bin/sed as it is typically found on Solaris -# along with /bin/sed that truncates output. -for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do - test ! -f $lt_ac_sed && continue - cat /dev/null > conftest.in - lt_ac_count=0 - echo $ECHO_N "0123456789$ECHO_C" >conftest.in - # Check for GNU sed and select it if it is found. - if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then - lt_cv_path_SED=$lt_ac_sed - break - fi - while true; do - cat conftest.in conftest.in >conftest.tmp - mv conftest.tmp conftest.in - cp conftest.in conftest.nl - echo >>conftest.nl - $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break - cmp -s conftest.out conftest.nl || break - # 10000 chars as input seems more than enough - test $lt_ac_count -gt 10 && break - lt_ac_count=`expr $lt_ac_count + 1` - if test $lt_ac_count -gt $lt_ac_max; then - lt_ac_max=$lt_ac_count - lt_cv_path_SED=$lt_ac_sed - fi - done -done -]) -SED=$lt_cv_path_SED -AC_SUBST([SED]) -AC_MSG_RESULT([$SED]) -])#AC_PROG_SED -])#m4_ifndef - -# Old name: -AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([LT_AC_PROG_SED], []) - - -# _LT_CHECK_SHELL_FEATURES -# ------------------------ -# Find out whether the shell is Bourne or XSI compatible, -# or has some other useful features. -m4_defun([_LT_CHECK_SHELL_FEATURES], -[AC_MSG_CHECKING([whether the shell understands some XSI constructs]) -# Try some XSI features -xsi_shell=no -( _lt_dummy="a/b/c" - test "${_lt_dummy##*/},${_lt_dummy%/*},"${_lt_dummy%"$_lt_dummy"}, \ - = c,a/b,, \ - && eval 'test $(( 1 + 1 )) -eq 2 \ - && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ - && xsi_shell=yes -AC_MSG_RESULT([$xsi_shell]) -_LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell']) - -AC_MSG_CHECKING([whether the shell understands "+="]) -lt_shell_append=no -( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \ - >/dev/null 2>&1 \ - && lt_shell_append=yes -AC_MSG_RESULT([$lt_shell_append]) -_LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append']) - -if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then - lt_unset=unset -else - lt_unset=false -fi -_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl - -# test EBCDIC or ASCII -case `echo X|tr X '\101'` in - A) # ASCII based system - # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr - lt_SP2NL='tr \040 \012' - lt_NL2SP='tr \015\012 \040\040' - ;; - *) # EBCDIC based system - lt_SP2NL='tr \100 \n' - lt_NL2SP='tr \r\n \100\100' - ;; -esac -_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl -_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl -])# _LT_CHECK_SHELL_FEATURES - - -# _LT_PROG_XSI_SHELLFNS -# --------------------- -# Bourne and XSI compatible variants of some useful shell functions. -m4_defun([_LT_PROG_XSI_SHELLFNS], -[case $xsi_shell in - yes) - cat << \_LT_EOF >> "$cfgfile" - -# func_dirname file append nondir_replacement -# Compute the dirname of FILE. If nonempty, add APPEND to the result, -# otherwise set result to NONDIR_REPLACEMENT. -func_dirname () -{ - case ${1} in - */*) func_dirname_result="${1%/*}${2}" ;; - * ) func_dirname_result="${3}" ;; - esac -} - -# func_basename file -func_basename () -{ - func_basename_result="${1##*/}" -} - -# func_dirname_and_basename file append nondir_replacement -# perform func_basename and func_dirname in a single function -# call: -# dirname: Compute the dirname of FILE. If nonempty, -# add APPEND to the result, otherwise set result -# to NONDIR_REPLACEMENT. -# value returned in "$func_dirname_result" -# basename: Compute filename of FILE. -# value retuned in "$func_basename_result" -# Implementation must be kept synchronized with func_dirname -# and func_basename. For efficiency, we do not delegate to -# those functions but instead duplicate the functionality here. -func_dirname_and_basename () -{ - case ${1} in - */*) func_dirname_result="${1%/*}${2}" ;; - * ) func_dirname_result="${3}" ;; - esac - func_basename_result="${1##*/}" -} - -# func_stripname prefix suffix name -# strip PREFIX and SUFFIX off of NAME. -# PREFIX and SUFFIX must not contain globbing or regex special -# characters, hashes, percent signs, but SUFFIX may contain a leading -# dot (in which case that matches only a dot). -func_stripname () -{ - # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are - # positional parameters, so assign one to ordinary parameter first. - func_stripname_result=${3} - func_stripname_result=${func_stripname_result#"${1}"} - func_stripname_result=${func_stripname_result%"${2}"} -} - -# func_opt_split -func_opt_split () -{ - func_opt_split_opt=${1%%=*} - func_opt_split_arg=${1#*=} -} - -# func_lo2o object -func_lo2o () -{ - case ${1} in - *.lo) func_lo2o_result=${1%.lo}.${objext} ;; - *) func_lo2o_result=${1} ;; - esac -} - -# func_xform libobj-or-source -func_xform () -{ - func_xform_result=${1%.*}.lo -} - -# func_arith arithmetic-term... -func_arith () -{ - func_arith_result=$(( $[*] )) -} - -# func_len string -# STRING may not start with a hyphen. -func_len () -{ - func_len_result=${#1} -} - -_LT_EOF - ;; - *) # Bourne compatible functions. - cat << \_LT_EOF >> "$cfgfile" - -# func_dirname file append nondir_replacement -# Compute the dirname of FILE. If nonempty, add APPEND to the result, -# otherwise set result to NONDIR_REPLACEMENT. -func_dirname () -{ - # Extract subdirectory from the argument. - func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"` - if test "X$func_dirname_result" = "X${1}"; then - func_dirname_result="${3}" - else - func_dirname_result="$func_dirname_result${2}" - fi -} - -# func_basename file -func_basename () -{ - func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"` -} - -dnl func_dirname_and_basename -dnl A portable version of this function is already defined in general.m4sh -dnl so there is no need for it here. - -# func_stripname prefix suffix name -# strip PREFIX and SUFFIX off of NAME. -# PREFIX and SUFFIX must not contain globbing or regex special -# characters, hashes, percent signs, but SUFFIX may contain a leading -# dot (in which case that matches only a dot). -# func_strip_suffix prefix name -func_stripname () -{ - case ${2} in - .*) func_stripname_result=`$ECHO "X${3}" \ - | $Xsed -e "s%^${1}%%" -e "s%\\\\${2}\$%%"`;; - *) func_stripname_result=`$ECHO "X${3}" \ - | $Xsed -e "s%^${1}%%" -e "s%${2}\$%%"`;; - esac -} - -# sed scripts: -my_sed_long_opt='1s/^\(-[[^=]]*\)=.*/\1/;q' -my_sed_long_arg='1s/^-[[^=]]*=//' - -# func_opt_split -func_opt_split () -{ - func_opt_split_opt=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_opt"` - func_opt_split_arg=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_arg"` -} - -# func_lo2o object -func_lo2o () -{ - func_lo2o_result=`$ECHO "X${1}" | $Xsed -e "$lo2o"` -} - -# func_xform libobj-or-source -func_xform () -{ - func_xform_result=`$ECHO "X${1}" | $Xsed -e 's/\.[[^.]]*$/.lo/'` -} - -# func_arith arithmetic-term... -func_arith () -{ - func_arith_result=`expr "$[@]"` -} - -# func_len string -# STRING may not start with a hyphen. -func_len () -{ - func_len_result=`expr "$[1]" : ".*" 2>/dev/null || echo $max_cmd_len` -} - -_LT_EOF -esac - -case $lt_shell_append in - yes) - cat << \_LT_EOF >> "$cfgfile" - -# func_append var value -# Append VALUE to the end of shell variable VAR. -func_append () -{ - eval "$[1]+=\$[2]" -} -_LT_EOF - ;; - *) - cat << \_LT_EOF >> "$cfgfile" - -# func_append var value -# Append VALUE to the end of shell variable VAR. -func_append () -{ - eval "$[1]=\$$[1]\$[2]" -} - -_LT_EOF - ;; - esac -]) diff --git a/burstioInterfaces/testing/tests/cpp/m4/ltoptions.m4 b/burstioInterfaces/testing/tests/cpp/m4/ltoptions.m4 deleted file mode 100644 index 34151a3ba..000000000 --- a/burstioInterfaces/testing/tests/cpp/m4/ltoptions.m4 +++ /dev/null @@ -1,368 +0,0 @@ -# Helper functions for option handling. -*- Autoconf -*- -# -# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. -# Written by Gary V. Vaughan, 2004 -# -# This file is free software; the Free Software Foundation gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. - -# serial 6 ltoptions.m4 - -# This is to help aclocal find these macros, as it can't see m4_define. -AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) - - -# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) -# ------------------------------------------ -m4_define([_LT_MANGLE_OPTION], -[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) - - -# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) -# --------------------------------------- -# Set option OPTION-NAME for macro MACRO-NAME, and if there is a -# matching handler defined, dispatch to it. Other OPTION-NAMEs are -# saved as a flag. -m4_define([_LT_SET_OPTION], -[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl -m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), - _LT_MANGLE_DEFUN([$1], [$2]), - [m4_warning([Unknown $1 option `$2'])])[]dnl -]) - - -# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) -# ------------------------------------------------------------ -# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. -m4_define([_LT_IF_OPTION], -[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) - - -# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) -# ------------------------------------------------------- -# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME -# are set. -m4_define([_LT_UNLESS_OPTIONS], -[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), - [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), - [m4_define([$0_found])])])[]dnl -m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 -])[]dnl -]) - - -# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) -# ---------------------------------------- -# OPTION-LIST is a space-separated list of Libtool options associated -# with MACRO-NAME. If any OPTION has a matching handler declared with -# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about -# the unknown option and exit. -m4_defun([_LT_SET_OPTIONS], -[# Set options -m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), - [_LT_SET_OPTION([$1], _LT_Option)]) - -m4_if([$1],[LT_INIT],[ - dnl - dnl Simply set some default values (i.e off) if boolean options were not - dnl specified: - _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no - ]) - _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no - ]) - dnl - dnl If no reference was made to various pairs of opposing options, then - dnl we run the default mode handler for the pair. For example, if neither - dnl `shared' nor `disable-shared' was passed, we enable building of shared - dnl archives by default: - _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) - _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) - _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) - _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], - [_LT_ENABLE_FAST_INSTALL]) - ]) -])# _LT_SET_OPTIONS - - -## --------------------------------- ## -## Macros to handle LT_INIT options. ## -## --------------------------------- ## - -# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) -# ----------------------------------------- -m4_define([_LT_MANGLE_DEFUN], -[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) - - -# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) -# ----------------------------------------------- -m4_define([LT_OPTION_DEFINE], -[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl -])# LT_OPTION_DEFINE - - -# dlopen -# ------ -LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes -]) - -AU_DEFUN([AC_LIBTOOL_DLOPEN], -[_LT_SET_OPTION([LT_INIT], [dlopen]) -AC_DIAGNOSE([obsolete], -[$0: Remove this warning and the call to _LT_SET_OPTION when you -put the `dlopen' option into LT_INIT's first parameter.]) -]) - -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) - - -# win32-dll -# --------- -# Declare package support for building win32 dll's. -LT_OPTION_DEFINE([LT_INIT], [win32-dll], -[enable_win32_dll=yes - -case $host in -*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-cegcc*) - AC_CHECK_TOOL(AS, as, false) - AC_CHECK_TOOL(DLLTOOL, dlltool, false) - AC_CHECK_TOOL(OBJDUMP, objdump, false) - ;; -esac - -test -z "$AS" && AS=as -_LT_DECL([], [AS], [0], [Assembler program])dnl - -test -z "$DLLTOOL" && DLLTOOL=dlltool -_LT_DECL([], [DLLTOOL], [0], [DLL creation program])dnl - -test -z "$OBJDUMP" && OBJDUMP=objdump -_LT_DECL([], [OBJDUMP], [0], [Object dumper program])dnl -])# win32-dll - -AU_DEFUN([AC_LIBTOOL_WIN32_DLL], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -_LT_SET_OPTION([LT_INIT], [win32-dll]) -AC_DIAGNOSE([obsolete], -[$0: Remove this warning and the call to _LT_SET_OPTION when you -put the `win32-dll' option into LT_INIT's first parameter.]) -]) - -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) - - -# _LT_ENABLE_SHARED([DEFAULT]) -# ---------------------------- -# implement the --enable-shared flag, and supports the `shared' and -# `disable-shared' LT_INIT options. -# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. -m4_define([_LT_ENABLE_SHARED], -[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl -AC_ARG_ENABLE([shared], - [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], - [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], - [p=${PACKAGE-default} - case $enableval in - yes) enable_shared=yes ;; - no) enable_shared=no ;; - *) - enable_shared=no - # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," - for pkg in $enableval; do - IFS="$lt_save_ifs" - if test "X$pkg" = "X$p"; then - enable_shared=yes - fi - done - IFS="$lt_save_ifs" - ;; - esac], - [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) - - _LT_DECL([build_libtool_libs], [enable_shared], [0], - [Whether or not to build shared libraries]) -])# _LT_ENABLE_SHARED - -LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) -LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) - -# Old names: -AC_DEFUN([AC_ENABLE_SHARED], -[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) -]) - -AC_DEFUN([AC_DISABLE_SHARED], -[_LT_SET_OPTION([LT_INIT], [disable-shared]) -]) - -AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) -AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) - -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AM_ENABLE_SHARED], []) -dnl AC_DEFUN([AM_DISABLE_SHARED], []) - - - -# _LT_ENABLE_STATIC([DEFAULT]) -# ---------------------------- -# implement the --enable-static flag, and support the `static' and -# `disable-static' LT_INIT options. -# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. -m4_define([_LT_ENABLE_STATIC], -[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl -AC_ARG_ENABLE([static], - [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], - [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], - [p=${PACKAGE-default} - case $enableval in - yes) enable_static=yes ;; - no) enable_static=no ;; - *) - enable_static=no - # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," - for pkg in $enableval; do - IFS="$lt_save_ifs" - if test "X$pkg" = "X$p"; then - enable_static=yes - fi - done - IFS="$lt_save_ifs" - ;; - esac], - [enable_static=]_LT_ENABLE_STATIC_DEFAULT) - - _LT_DECL([build_old_libs], [enable_static], [0], - [Whether or not to build static libraries]) -])# _LT_ENABLE_STATIC - -LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) -LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) - -# Old names: -AC_DEFUN([AC_ENABLE_STATIC], -[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) -]) - -AC_DEFUN([AC_DISABLE_STATIC], -[_LT_SET_OPTION([LT_INIT], [disable-static]) -]) - -AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) -AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) - -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AM_ENABLE_STATIC], []) -dnl AC_DEFUN([AM_DISABLE_STATIC], []) - - - -# _LT_ENABLE_FAST_INSTALL([DEFAULT]) -# ---------------------------------- -# implement the --enable-fast-install flag, and support the `fast-install' -# and `disable-fast-install' LT_INIT options. -# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. -m4_define([_LT_ENABLE_FAST_INSTALL], -[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl -AC_ARG_ENABLE([fast-install], - [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], - [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], - [p=${PACKAGE-default} - case $enableval in - yes) enable_fast_install=yes ;; - no) enable_fast_install=no ;; - *) - enable_fast_install=no - # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," - for pkg in $enableval; do - IFS="$lt_save_ifs" - if test "X$pkg" = "X$p"; then - enable_fast_install=yes - fi - done - IFS="$lt_save_ifs" - ;; - esac], - [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) - -_LT_DECL([fast_install], [enable_fast_install], [0], - [Whether or not to optimize for fast installation])dnl -])# _LT_ENABLE_FAST_INSTALL - -LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) -LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) - -# Old names: -AU_DEFUN([AC_ENABLE_FAST_INSTALL], -[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) -AC_DIAGNOSE([obsolete], -[$0: Remove this warning and the call to _LT_SET_OPTION when you put -the `fast-install' option into LT_INIT's first parameter.]) -]) - -AU_DEFUN([AC_DISABLE_FAST_INSTALL], -[_LT_SET_OPTION([LT_INIT], [disable-fast-install]) -AC_DIAGNOSE([obsolete], -[$0: Remove this warning and the call to _LT_SET_OPTION when you put -the `disable-fast-install' option into LT_INIT's first parameter.]) -]) - -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) -dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) - - -# _LT_WITH_PIC([MODE]) -# -------------------- -# implement the --with-pic flag, and support the `pic-only' and `no-pic' -# LT_INIT options. -# MODE is either `yes' or `no'. If omitted, it defaults to `both'. -m4_define([_LT_WITH_PIC], -[AC_ARG_WITH([pic], - [AS_HELP_STRING([--with-pic], - [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], - [pic_mode="$withval"], - [pic_mode=default]) - -test -z "$pic_mode" && pic_mode=m4_default([$1], [default]) - -_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl -])# _LT_WITH_PIC - -LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) -LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) - -# Old name: -AU_DEFUN([AC_LIBTOOL_PICMODE], -[_LT_SET_OPTION([LT_INIT], [pic-only]) -AC_DIAGNOSE([obsolete], -[$0: Remove this warning and the call to _LT_SET_OPTION when you -put the `pic-only' option into LT_INIT's first parameter.]) -]) - -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) - -## ----------------- ## -## LTDL_INIT Options ## -## ----------------- ## - -m4_define([_LTDL_MODE], []) -LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], - [m4_define([_LTDL_MODE], [nonrecursive])]) -LT_OPTION_DEFINE([LTDL_INIT], [recursive], - [m4_define([_LTDL_MODE], [recursive])]) -LT_OPTION_DEFINE([LTDL_INIT], [subproject], - [m4_define([_LTDL_MODE], [subproject])]) - -m4_define([_LTDL_TYPE], []) -LT_OPTION_DEFINE([LTDL_INIT], [installable], - [m4_define([_LTDL_TYPE], [installable])]) -LT_OPTION_DEFINE([LTDL_INIT], [convenience], - [m4_define([_LTDL_TYPE], [convenience])]) diff --git a/burstioInterfaces/testing/tests/cpp/m4/ltsugar.m4 b/burstioInterfaces/testing/tests/cpp/m4/ltsugar.m4 deleted file mode 100644 index 9000a057d..000000000 --- a/burstioInterfaces/testing/tests/cpp/m4/ltsugar.m4 +++ /dev/null @@ -1,123 +0,0 @@ -# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- -# -# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. -# Written by Gary V. Vaughan, 2004 -# -# This file is free software; the Free Software Foundation gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. - -# serial 6 ltsugar.m4 - -# This is to help aclocal find these macros, as it can't see m4_define. -AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) - - -# lt_join(SEP, ARG1, [ARG2...]) -# ----------------------------- -# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their -# associated separator. -# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier -# versions in m4sugar had bugs. -m4_define([lt_join], -[m4_if([$#], [1], [], - [$#], [2], [[$2]], - [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) -m4_define([_lt_join], -[m4_if([$#$2], [2], [], - [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) - - -# lt_car(LIST) -# lt_cdr(LIST) -# ------------ -# Manipulate m4 lists. -# These macros are necessary as long as will still need to support -# Autoconf-2.59 which quotes differently. -m4_define([lt_car], [[$1]]) -m4_define([lt_cdr], -[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], - [$#], 1, [], - [m4_dquote(m4_shift($@))])]) -m4_define([lt_unquote], $1) - - -# lt_append(MACRO-NAME, STRING, [SEPARATOR]) -# ------------------------------------------ -# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'. -# Note that neither SEPARATOR nor STRING are expanded; they are appended -# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). -# No SEPARATOR is output if MACRO-NAME was previously undefined (different -# than defined and empty). -# -# This macro is needed until we can rely on Autoconf 2.62, since earlier -# versions of m4sugar mistakenly expanded SEPARATOR but not STRING. -m4_define([lt_append], -[m4_define([$1], - m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) - - - -# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) -# ---------------------------------------------------------- -# Produce a SEP delimited list of all paired combinations of elements of -# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list -# has the form PREFIXmINFIXSUFFIXn. -# Needed until we can rely on m4_combine added in Autoconf 2.62. -m4_define([lt_combine], -[m4_if(m4_eval([$# > 3]), [1], - [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl -[[m4_foreach([_Lt_prefix], [$2], - [m4_foreach([_Lt_suffix], - ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, - [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) - - -# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) -# ----------------------------------------------------------------------- -# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited -# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. -m4_define([lt_if_append_uniq], -[m4_ifdef([$1], - [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], - [lt_append([$1], [$2], [$3])$4], - [$5])], - [lt_append([$1], [$2], [$3])$4])]) - - -# lt_dict_add(DICT, KEY, VALUE) -# ----------------------------- -m4_define([lt_dict_add], -[m4_define([$1($2)], [$3])]) - - -# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) -# -------------------------------------------- -m4_define([lt_dict_add_subkey], -[m4_define([$1($2:$3)], [$4])]) - - -# lt_dict_fetch(DICT, KEY, [SUBKEY]) -# ---------------------------------- -m4_define([lt_dict_fetch], -[m4_ifval([$3], - m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), - m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) - - -# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) -# ----------------------------------------------------------------- -m4_define([lt_if_dict_fetch], -[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], - [$5], - [$6])]) - - -# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) -# -------------------------------------------------------------- -m4_define([lt_dict_filter], -[m4_if([$5], [], [], - [lt_join(m4_quote(m4_default([$4], [[, ]])), - lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), - [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl -]) diff --git a/burstioInterfaces/testing/tests/cpp/m4/ltversion.m4 b/burstioInterfaces/testing/tests/cpp/m4/ltversion.m4 deleted file mode 100644 index f3c530980..000000000 --- a/burstioInterfaces/testing/tests/cpp/m4/ltversion.m4 +++ /dev/null @@ -1,23 +0,0 @@ -# ltversion.m4 -- version numbers -*- Autoconf -*- -# -# Copyright (C) 2004 Free Software Foundation, Inc. -# Written by Scott James Remnant, 2004 -# -# This file is free software; the Free Software Foundation gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. - -# Generated from ltversion.in. - -# serial 3017 ltversion.m4 -# This file is part of GNU Libtool - -m4_define([LT_PACKAGE_VERSION], [2.2.6b]) -m4_define([LT_PACKAGE_REVISION], [1.3017]) - -AC_DEFUN([LTVERSION_VERSION], -[macro_version='2.2.6b' -macro_revision='1.3017' -_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) -_LT_DECL(, macro_revision, 0) -]) diff --git a/burstioInterfaces/testing/tests/cpp/m4/lt~obsolete.m4 b/burstioInterfaces/testing/tests/cpp/m4/lt~obsolete.m4 deleted file mode 100644 index 637bb2066..000000000 --- a/burstioInterfaces/testing/tests/cpp/m4/lt~obsolete.m4 +++ /dev/null @@ -1,92 +0,0 @@ -# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- -# -# Copyright (C) 2004, 2005, 2007 Free Software Foundation, Inc. -# Written by Scott James Remnant, 2004. -# -# This file is free software; the Free Software Foundation gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. - -# serial 4 lt~obsolete.m4 - -# These exist entirely to fool aclocal when bootstrapping libtool. -# -# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN) -# which have later been changed to m4_define as they aren't part of the -# exported API, or moved to Autoconf or Automake where they belong. -# -# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN -# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us -# using a macro with the same name in our local m4/libtool.m4 it'll -# pull the old libtool.m4 in (it doesn't see our shiny new m4_define -# and doesn't know about Autoconf macros at all.) -# -# So we provide this file, which has a silly filename so it's always -# included after everything else. This provides aclocal with the -# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything -# because those macros already exist, or will be overwritten later. -# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. -# -# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. -# Yes, that means every name once taken will need to remain here until -# we give up compatibility with versions before 1.7, at which point -# we need to keep only those names which we still refer to. - -# This is to help aclocal find these macros, as it can't see m4_define. -AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) - -m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) -m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) -m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) -m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) -m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) -m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) -m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) -m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) -m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) -m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) -m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) -m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) -m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) -m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) -m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) -m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) -m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) -m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) -m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) -m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) -m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) -m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) -m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) -m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) -m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) -m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) -m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) -m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) -m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) -m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) -m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) -m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) -m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) -m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) -m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) -m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) -m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) -m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) -m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) -m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) -m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) -m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) -m4_ifndef([AC_LIBTOOL_RC], [AC_DEFUN([AC_LIBTOOL_RC])]) -m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) -m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) -m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) -m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) -m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) -m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) -m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) -m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) -m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) -m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) -m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) -m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) diff --git a/burstioInterfaces/testing/tests/cpp/reconf b/burstioInterfaces/testing/tests/cpp/reconf deleted file mode 100755 index 59ffdc071..000000000 --- a/burstioInterfaces/testing/tests/cpp/reconf +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/sh -# -# This file is protected by Copyright. Please refer to the COPYRIGHT file -# distributed with this source distribution. -# -# This file is part of REDHAWK burstioInterfaces. -# -# REDHAWK burstioInterfaces is free software: you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation, either version 3 of the License, or (at your option) any -# later version. -# -# REDHAWK burstioInterfaces is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more -# details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with this program. If not, see http://www.gnu.org/licenses/. -# -test -d m4 || mkdir m4 -test -d acinclude || mkdir acinclude -test -e NEWS || touch NEWS -test -e README || touch README -test -e AUTHORS || touch AUTHORS -test -e ChangeLog || touch ChangeLog -autoreconf -i diff --git a/burstioInterfaces/testing/tests/cpp/runtests b/burstioInterfaces/testing/tests/cpp/runtests deleted file mode 100755 index fac7b1c03..000000000 --- a/burstioInterfaces/testing/tests/cpp/runtests +++ /dev/null @@ -1,8 +0,0 @@ -# -# -burstio_top=../../.. -burstio_libsrc_top=$burstio_top/src -burstio_cpp_lib=$burstio_libsrc_top/cpp -export LD_LIBRARY_PATH=$burstio_cpp_lib/.libs:$burstio_libsrc_top/.libs:${LD_LIBRARY_PATH} -make check - From c52939f2b399511ad7244fc13482c4c372cd1c7d Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 12 Jul 2016 14:16:36 -0400 Subject: [PATCH 0077/1644] Locate the CppUnit test logging file relative to the source directory (if available) --- burstioInterfaces/testing/tests/cpp/Burstio.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/burstioInterfaces/testing/tests/cpp/Burstio.cpp b/burstioInterfaces/testing/tests/cpp/Burstio.cpp index 651cd9b4d..74d1e7d83 100644 --- a/burstioInterfaces/testing/tests/cpp/Burstio.cpp +++ b/burstioInterfaces/testing/tests/cpp/Burstio.cpp @@ -18,6 +18,7 @@ * along with this program. If not, see http://www.gnu.org/licenses/. */ #include +#include #include #include #include @@ -28,14 +29,18 @@ #include "log4cxx/basicconfigurator.h" #include "log4cxx/propertyconfigurator.h" #include "log4cxx/helpers/exception.h" -using namespace std; - int main(int argc, char* argv[]) { + // Locate the logging configuration file relative to the source directory + std::string log_config = "log4j.props"; + char* srcdir = getenv("srcdir"); + if (srcdir) { + log_config = std::string(srcdir) + "/" + log_config; + } // Set up a simple configuration that logs on the console. - log4cxx::PropertyConfigurator::configure("log4j.props"); + log4cxx::PropertyConfigurator::configure(log_config); // Get the top level suite from the registry CppUnit::Test *suite = CppUnit::TestFactoryRegistry::getRegistry().makeTest(); @@ -47,7 +52,7 @@ int main(int argc, char* argv[]) controller.addListener ( &result ); CppUnit::TextUi::TestRunner *runner = new CppUnit::TextUi::TestRunner; - ofstream xmlout ( "../cppunit-results.xml" ); + std::ofstream xmlout ( "../cppunit-results.xml" ); CppUnit::XmlOutputter xmlOutputter ( &result, xmlout ); CppUnit::CompilerOutputter compilerOutputter ( &result, std::cerr ); From fd6b1daead1a95f0671db93dc059d2a041438a02 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 12 Jul 2016 14:20:17 -0400 Subject: [PATCH 0078/1644] Integrate JUnit testing into the main build; Jenkins should still be able to use ant to generate XML output --- burstioInterfaces/Makefile.am | 3 + burstioInterfaces/configure.ac | 9 ++- .../testing/tests/java/.gitignore | 2 - ..._Test.template => Burstio_Utils_Test.java} | 0 burstioInterfaces/testing/tests/java/Makefile | 52 ----------------- .../testing/tests/java/Makefile.am | 56 +++++++++++++++++++ 6 files changed, 66 insertions(+), 56 deletions(-) delete mode 100644 burstioInterfaces/testing/tests/java/.gitignore rename burstioInterfaces/testing/tests/java/{templates/Burstio_Utils_Test.template => Burstio_Utils_Test.java} (100%) delete mode 100644 burstioInterfaces/testing/tests/java/Makefile create mode 100644 burstioInterfaces/testing/tests/java/Makefile.am diff --git a/burstioInterfaces/Makefile.am b/burstioInterfaces/Makefile.am index 5cf4bc8c2..a813fe517 100644 --- a/burstioInterfaces/Makefile.am +++ b/burstioInterfaces/Makefile.am @@ -26,6 +26,9 @@ if HAVE_JAVASUPPORT endif if ENABLE_TESTING SUBDIRS += testing/tests/cpp +if HAVE_JAVASUPPORT + SUBDIRS += testing/tests/java +endif endif pkgconfigdir = $(libdir)/pkgconfig diff --git a/burstioInterfaces/configure.ac b/burstioInterfaces/configure.ac index c06473f23..d6b1eb3df 100644 --- a/burstioInterfaces/configure.ac +++ b/burstioInterfaces/configure.ac @@ -72,7 +72,7 @@ if test "x$enable_java" != "xno"; then # Set up CLASSPATH for REDHAWK, CF and BULKIO RH_PKG_CLASSPATH([OSSIE], [ossie]) - RH_PKG_CLASSPATH([BULKIO], [bulkioInterfaces]) + RH_PKG_CLASSPATH([BULKIO], [bulkio]) if test -n "$HAVE_JNI_H"; then # The omnijni package must be available to generate JNI stubs and skeletons. @@ -136,6 +136,10 @@ AM_CONDITIONAL(HAVE_JAVASUPPORT, test $HAVE_JAVASUPPORT = yes) AC_ARG_ENABLE([testing], AS_HELP_STRING([--enable-testing], [enable build of unit tests])) AS_IF([test "x$enable_testing" == "xyes"], [ AM_PATH_CPPUNIT(1.9.6) + AS_IF([test "x$HAVE_JAVASUPPORT" == "xyes"], [ + dnl Use RPM location hard-coded for now + AC_SUBST([JUNIT_CLASSPATH], "/usr/share/java/junit4.jar") + ]) ]) AM_CONDITIONAL(ENABLE_TESTING, test "x$enable_testing" == "xyes") @@ -149,6 +153,7 @@ AC_CONFIG_FILES([Makefile \ src/python/Makefile \ src/python/setup.py \ src/idl/Makefile \ - testing/tests/cpp/Makefile]) + testing/tests/cpp/Makefile \ + testing/tests/java/Makefile]) AC_OUTPUT diff --git a/burstioInterfaces/testing/tests/java/.gitignore b/burstioInterfaces/testing/tests/java/.gitignore deleted file mode 100644 index 96966d7c4..000000000 --- a/burstioInterfaces/testing/tests/java/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -*.class -!Makefile diff --git a/burstioInterfaces/testing/tests/java/templates/Burstio_Utils_Test.template b/burstioInterfaces/testing/tests/java/Burstio_Utils_Test.java similarity index 100% rename from burstioInterfaces/testing/tests/java/templates/Burstio_Utils_Test.template rename to burstioInterfaces/testing/tests/java/Burstio_Utils_Test.java diff --git a/burstioInterfaces/testing/tests/java/Makefile b/burstioInterfaces/testing/tests/java/Makefile deleted file mode 100644 index cfc17e1dc..000000000 --- a/burstioInterfaces/testing/tests/java/Makefile +++ /dev/null @@ -1,52 +0,0 @@ - -burstio_top_dir=../../../ -burstio_idl_dir=$(burstio_top_dir) -burstio_idl_java_dir=$(burstio_top_dir) -burstio_libsrc_dir=$(burstio_top_dir)/src -burstio_libsrc_java_dir=$(burstio_libsrc_dir)/java -OSSIE_HOME=$(shell echo $(OSSIEHOME)) -BURSTIO_JARS=$(OSSIE_HOME)/lib/CFInterfaces.jar:$(OSSIE_HOME)/lib/log4j-1.2.15.jar:$(OSSIE_HOME)/lib/ossie.jar:$(OSSIE_HOME)/lib/bulkio.jar:$(OSSIE_HOME)/lib/BULKIOInterfaces.jar:$(burstio_libsrc_java_dir)/burstio.jar:$(burstio_libsrc_java_dir)/BURSTIOInterfaces.jar - -JAVA_HOME = $(shell echo $(JAVAHOME)) -JAVA = $(JAVA_HOME)/bin/java -JDB = $(JAVA_HOME)/bin/jdb -JAVAC = $(JAVA_HOME)/bin/javac -JAVA_CP=$(CLASSPATH):.:/usr/share/java/junit4.jar:$(BURSTIO_JARS) - -.SUFFIXES: .java .class -.PHONEY: all check build-all clean tcheck - -IN_PORTS=$(patsubst %.java,%.class,$(wildcard InBurst*.java)) -OUT_PORTS=$(patsubst %.java,%.class,$(wildcard OutBurst*.java)) -PUSH_TESTS=$(patsubst %.java,%.class,$(wildcard Burst*Push*.java)) -UTILS=Burstio_Utils_Test.class -#MULTIOUT_PORTS=$(patsubst %.java,%.class,$(wildcard Multi*.java)) - -JTESTS=$(IN_PORTS:.class=) $(OUT_PORTS:.class=) $(PUSH_TESTS:.class=) $(MULTIOUT_PORTS:.class=) $(UTILS:.class=) -.java.class: - $(JAVAC) -cp $(JAVA_CP) -Xlint $^ - -all: build-all check - -build-all: $(IN_PORTS) $(OUT_PORTS) $(PUSH_TESTS) $(MULTIOUT_PORTS) $(UTILS) - -tcheck: - $(JAVA) -cp $(JAVA_CP) org.junit.runner.JUnitCore OutVectorPort_Test - -check: - @for jtest in "$(JTESTS)" ; do \ - $(JAVA) -cp $(JAVA_CP) -Dlog4j.configuration=file:log4j_config.txt org.junit.runner.JUnitCore $$jtest ; \ - done - -debug: - @for jtest in "$(JTESTS)" ; do \ - $(JDB) -sourcepath $(burstio_libsrc_java_dir)/BURSTIO:$(burstio_libsrc_java_dir)/burstio -classpath $(JAVA_CP) -Dlog4j.configuration=file:log4j_config.txt org.junit.runner.JUnitCore $$jtest ; \ - done - -clean: - -rm *.class - -rm InBurst*_Test.java - -rm OutBurst*_Test.java - -rm Burst*Push_Test.java - -rm Burstio_Utils_Test.java - diff --git a/burstioInterfaces/testing/tests/java/Makefile.am b/burstioInterfaces/testing/tests/java/Makefile.am new file mode 100644 index 000000000..8b8fc9056 --- /dev/null +++ b/burstioInterfaces/testing/tests/java/Makefile.am @@ -0,0 +1,56 @@ +# +# This file is protected by Copyright. Please refer to the COPYRIGHT file +# distributed with this source distribution. +# +# This file is part of REDHAWK burstioInterfaces. +# +# REDHAWK burstioInterfaces is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation, either version 3 of the License, or (at your option) any +# later version. +# +# REDHAWK burstioInterfaces is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +# details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/. +# +burstio_libsrc_dir=$(top_srcdir)/src +burstio_libsrc_java_dir=$(burstio_libsrc_dir)/java +BURSTIO_JARS=$(top_builddir)/src/java/burstio.jar:$(top_builddir)/src/java/BURSTIOInterfaces.jar + +sed_dir = $(top_srcdir)/src/java/sed +sed_generate = $(AM_V_GEN)$(SED) -f $(sed_dir)/$*.sed $< > $@ + +InBurst%Port_Test.java : $(srcdir)/templates/InBurstPort_Test.template $(sed_dir)/%.sed + $(sed_generate) + +OutBurst%Port_Test.java : $(srcdir)/templates/OutBurstPort_Test.template $(sed_dir)/%.sed + $(sed_generate) + +Burst%Push_Test.java : $(srcdir)/templates/BurstPush_Test.template $(sed_dir)/%.sed + $(sed_generate) + +BUILT_SOURCES = $(patsubst $(sed_dir)/%.sed,InBurst%Port_Test.java,$(wildcard $(sed_dir)/*.sed)) +BUILT_SOURCES += $(patsubst $(sed_dir)/%.sed,OutBurst%Port_Test.java,$(wildcard $(sed_dir)/*.sed)) +BUILT_SOURCES += $(patsubst $(sed_dir)/%.sed,Burst%Push_Test.java,$(wildcard $(sed_dir)/*.sed)) + +Burstio_CLASSES = Burstio_Utils_Test.class $(patsubst %.java,%.class,$(BUILT_SOURCES)) +Burstio_CLASSPATH = $(BURSTIO_JARS):$(OSSIE_CLASSPATH):$(BULKIO_CLASSPATH):$(JUNIT_CLASSPATH) + +TEST_CLASSES = $(patsubst %.class,%,$(Burstio_CLASSES)) + +TESTS = Burstio +check_SCRIPTS = Burstio + +%.class : %.java + $(AM_V_at)$(JAVAC) -d $(builddir) -cp $(Burstio_CLASSPATH) -g -Xlint $< + +Burstio : $(Burstio_CLASSES) Makefile.am + @echo "#!/bin/sh" > $@ + @echo "exec java -cp $(Burstio_CLASSPATH):. -Dlog4j.configuration=file:$(srcdir)/log4j_config.txt org.junit.runner.JUnitCore $(TEST_CLASSES)" >> $@ + @chmod +x $@ + +CLEANFILES = Burstio $(BUILT_SOURCES) *.class From 831894fe79816632a2fe036f1d05b4b6cb7712ee Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 13 Jul 2016 10:16:05 -0400 Subject: [PATCH 0079/1644] BasicTransport should take a CORBA object ptr, not a var, to avoid segfaults --- burstioInterfaces/src/cpp/include/burstio/UsesPort.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/burstioInterfaces/src/cpp/include/burstio/UsesPort.h b/burstioInterfaces/src/cpp/include/burstio/UsesPort.h index 5b77c8312..0fcbd35b0 100644 --- a/burstioInterfaces/src/cpp/include/burstio/UsesPort.h +++ b/burstioInterfaces/src/cpp/include/burstio/UsesPort.h @@ -40,7 +40,7 @@ namespace burstio { typedef typename port_type::_ptr_type ptr_type; typedef typename port_type::_var_type var_type; - BasicTransport(var_type port, const std::string& connectionId) : + BasicTransport(ptr_type port, const std::string& connectionId) : port_(port_type::_duplicate(port)), connectionId_(connectionId) { From 74977b95deb6455410cf18fac6ce3b7eb9abb7cf Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 13 Jul 2016 10:16:56 -0400 Subject: [PATCH 0080/1644] Basic implementation of C++ local transport --- .../src/cpp/include/burstio/OutPortDecl.h | 2 +- burstioInterfaces/src/cpp/lib/OutPortImpl.h | 54 ++++++++++++++++++- 2 files changed, 54 insertions(+), 2 deletions(-) diff --git a/burstioInterfaces/src/cpp/include/burstio/OutPortDecl.h b/burstioInterfaces/src/cpp/include/burstio/OutPortDecl.h index 005a51710..fcc265bc7 100644 --- a/burstioInterfaces/src/cpp/include/burstio/OutPortDecl.h +++ b/burstioInterfaces/src/cpp/include/burstio/OutPortDecl.h @@ -257,7 +257,7 @@ namespace burstio { }; class RemoteTransport; - friend class RemoteTransport; + class LocalTransport; friend class Queue; diff --git a/burstioInterfaces/src/cpp/lib/OutPortImpl.h b/burstioInterfaces/src/cpp/lib/OutPortImpl.h index 730637c7c..1c346ac4b 100644 --- a/burstioInterfaces/src/cpp/lib/OutPortImpl.h +++ b/burstioInterfaces/src/cpp/lib/OutPortImpl.h @@ -20,7 +20,10 @@ #ifndef BURSTIO_OUTPORTIMPL_H #define BURSTIO_OUTPORTIMPL_H +#include + #include +#include #include "debug_impl.h" @@ -101,6 +104,48 @@ namespace burstio { bool alive_; }; + template + class OutPort::LocalTransport : public BurstTransport + { + public: + typedef BurstTransport super; + typedef typename Traits::PortType PortType; + typedef typename Traits::BurstType BurstType; + typedef typename Traits::BurstSequenceType BurstSequenceType; + + LocalTransport(OutPort* parent, InPort* localPort, typename PortType::_ptr_type port, const std::string& connectionId) : + super(port, connectionId, parent->name), + parent_(parent), + localPort_(localPort) + { + } + + void pushBursts(const BurstSequenceType& bursts, boost::system_time startTime, float queueDepth) + { + try { + // Record delay from queueing of first burst to now + boost::posix_time::time_duration delay = boost::get_system_time() - startTime; + + localPort_->pushBursts(bursts); + + // Count up total elements + size_t total_elements = 0; + for (CORBA::ULong index = 0; index < bursts.length(); ++index) { + total_elements += bursts[index].data.length(); + } + this->stats_.record(bursts.length(), total_elements, queueDepth, delay.total_microseconds() * 1e-6); + } catch (const CORBA::Exception& ex) { + RH_ERROR(parent_->__logger, "pushBursts to " << this->connectionId_ << " failed: CORBA::" << ex._name()); + } catch (...) { + RH_ERROR(parent_->__logger, "pushBursts to " << this->connectionId_ << " failed"); + } + } + + private: + OutPort* parent_; + InPort* localPort_; + }; + template OutPort::Queue::Queue(OutPort* port, const std::string& streamID, size_t maxBursts, size_t thresholdBytes, long thresholdLatency) : port_(port), @@ -503,7 +548,14 @@ namespace burstio { typename OutPort::TransportType* OutPort::_createConnection (typename PortType::_ptr_type port, const std::string& connectionId) { - return new RemoteTransport(this, port, connectionId); + InPort* local_port = ossie::corba::getLocalServant >(port); + if (local_port) { + LOG_INSTANCE_DEBUG("Using local connection to port " << local_port->getName() + << " for connection " << connectionId); + return new LocalTransport(this, local_port, port, connectionId); + } else { + return new RemoteTransport(this, port, connectionId); + } } template From ac46f964b01efda5cacc9c182cf49320a3477727 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 13 Jul 2016 10:32:35 -0400 Subject: [PATCH 0081/1644] Always return a new object reference in BasicTransport --- burstioInterfaces/src/cpp/include/burstio/UsesPort.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/burstioInterfaces/src/cpp/include/burstio/UsesPort.h b/burstioInterfaces/src/cpp/include/burstio/UsesPort.h index 0fcbd35b0..c23d23688 100644 --- a/burstioInterfaces/src/cpp/include/burstio/UsesPort.h +++ b/burstioInterfaces/src/cpp/include/burstio/UsesPort.h @@ -55,7 +55,7 @@ namespace burstio { ptr_type objref() const { - return port_; + return port_type::_duplicate(port_); } protected: @@ -198,7 +198,7 @@ namespace burstio { if (existing == connections_.end()) { throw std::invalid_argument("No connection " + connectionId); } - return port_type::_duplicate(existing->second->objref()); + return existing->second->objref(); } connection_list getConnections() @@ -206,7 +206,7 @@ namespace burstio { boost::mutex::scoped_lock lock(updatingPortsLock); connection_list result; for (typename ConnectionMap::iterator ii = connections_.begin(); ii != connections_.end(); ++ii) { - result.push_back(std::make_pair(ii->first, port_type::_duplicate(ii->second->objref()))); + result.push_back(std::make_pair(ii->first, ii->second->objref())); } return result; } From 4edb0ce243d5e985438e7f47d9572025324b95be Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 13 Jul 2016 13:09:52 -0400 Subject: [PATCH 0082/1644] Collect statistics before push in local push --- burstioInterfaces/src/cpp/lib/OutPortImpl.h | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/burstioInterfaces/src/cpp/lib/OutPortImpl.h b/burstioInterfaces/src/cpp/lib/OutPortImpl.h index 1c346ac4b..89e996dc3 100644 --- a/burstioInterfaces/src/cpp/lib/OutPortImpl.h +++ b/burstioInterfaces/src/cpp/lib/OutPortImpl.h @@ -126,14 +126,16 @@ namespace burstio { // Record delay from queueing of first burst to now boost::posix_time::time_duration delay = boost::get_system_time() - startTime; - localPort_->pushBursts(bursts); - // Count up total elements size_t total_elements = 0; - for (CORBA::ULong index = 0; index < bursts.length(); ++index) { + size_t total_bursts = bursts.length(); + for (CORBA::ULong index = 0; index < total_bursts; ++index) { total_elements += bursts[index].data.length(); } - this->stats_.record(bursts.length(), total_elements, queueDepth, delay.total_microseconds() * 1e-6); + + localPort_->pushBursts(bursts); + + this->stats_.record(total_bursts, total_elements, queueDepth, delay.total_microseconds() * 1e-6); } catch (const CORBA::Exception& ex) { RH_ERROR(parent_->__logger, "pushBursts to " << this->connectionId_ << " failed: CORBA::" << ex._name()); } catch (...) { From db942fdc11312d7753d2957765b226e8688b3f67 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 13 Jul 2016 16:16:01 -0400 Subject: [PATCH 0083/1644] Pre-allocate the CORBA sequence for queued bursts so that the local case doesn't have to do a bunch of copies --- burstioInterfaces/src/cpp/lib/OutPortImpl.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/burstioInterfaces/src/cpp/lib/OutPortImpl.h b/burstioInterfaces/src/cpp/lib/OutPortImpl.h index 89e996dc3..0651ae9f5 100644 --- a/burstioInterfaces/src/cpp/lib/OutPortImpl.h +++ b/burstioInterfaces/src/cpp/lib/OutPortImpl.h @@ -285,7 +285,12 @@ namespace burstio { { if (bursts_.length() > 0) { port_->sendBursts(bursts_, startTime_, bursts_.length()/(float)maxBursts_, streamID_); - bursts_.length(0); + // Reset the burst queue to empty, reallocating if necessary + if (bursts_.maximum() < maxBursts_) { + bursts_.replace(maxBursts_, 0, BurstSequenceType::allocbuf(maxBursts_), true); + } else { + bursts_.length(0); + } bytes_ = 0; startTime_ = boost::posix_time::ptime(); } From ff3fdccd6506530f8993cc861b4d11075a9df568 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 14 Jul 2016 11:10:01 -0400 Subject: [PATCH 0084/1644] Define port traits classes as their own classes inheriting from the traits template, instead of as typedefs, to greatly reduce the length of the symbol names --- .../src/cpp/include/burstio/PortTraits.h | 27 ++++++++++--------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/burstioInterfaces/src/cpp/include/burstio/PortTraits.h b/burstioInterfaces/src/cpp/include/burstio/PortTraits.h index 3ec1b4afb..e098cad18 100644 --- a/burstioInterfaces/src/cpp/include/burstio/PortTraits.h +++ b/burstioInterfaces/src/cpp/include/burstio/PortTraits.h @@ -43,18 +43,21 @@ namespace burstio { typedef Native NativeType; }; -#define TYPEDEF_PORTTRAITS(T, CT, ST, NT) typedef PortTraits T##Traits; - TYPEDEF_PORTTRAITS(Byte, Octet, CF::OctetSequence, signed char); - TYPEDEF_PORTTRAITS(Double, Double, PortTypes::DoubleSequence, CORBA::Double); - TYPEDEF_PORTTRAITS(Float, Float, PortTypes::FloatSequence, CORBA::Float); - TYPEDEF_PORTTRAITS(Long, Long, PortTypes::LongSequence, CORBA::Long); - TYPEDEF_PORTTRAITS(LongLong, LongLong, PortTypes::LongLongSequence, CORBA::LongLong); - TYPEDEF_PORTTRAITS(Short, Short, PortTypes::ShortSequence, CORBA::Short); - TYPEDEF_PORTTRAITS(Ubyte, Octet, CF::OctetSequence, unsigned char); - TYPEDEF_PORTTRAITS(Ulong, ULong, PortTypes::UlongSequence, CORBA::ULong); - TYPEDEF_PORTTRAITS(UlongLong, ULongLong, PortTypes::UlongLongSequence, CORBA::ULongLong); - TYPEDEF_PORTTRAITS(Ushort, UShort, PortTypes::UshortSequence, CORBA::UShort); -#undef TYPEDEF_PORTTRAITS +#define DEFINE_PORTTRAITS(T, CT, ST, NT) \ + struct T##Traits : public PortTraits { \ + }; + + DEFINE_PORTTRAITS(Byte, Octet, CF::OctetSequence, signed char); + DEFINE_PORTTRAITS(Double, Double, PortTypes::DoubleSequence, CORBA::Double); + DEFINE_PORTTRAITS(Float, Float, PortTypes::FloatSequence, CORBA::Float); + DEFINE_PORTTRAITS(Long, Long, PortTypes::LongSequence, CORBA::Long); + DEFINE_PORTTRAITS(LongLong, LongLong, PortTypes::LongLongSequence, CORBA::LongLong); + DEFINE_PORTTRAITS(Short, Short, PortTypes::ShortSequence, CORBA::Short); + DEFINE_PORTTRAITS(Ubyte, Octet, CF::OctetSequence, unsigned char); + DEFINE_PORTTRAITS(Ulong, ULong, PortTypes::UlongSequence, CORBA::ULong); + DEFINE_PORTTRAITS(UlongLong, ULongLong, PortTypes::UlongLongSequence, CORBA::ULongLong); + DEFINE_PORTTRAITS(Ushort, UShort, PortTypes::UshortSequence, CORBA::UShort); +#undef DEFINE_PORTTRAITS } #endif // BURSTIO_PORTTRAITS_H From c3ee4a181a39afd6c3a5c9fa54757c5fd5fa0584 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 14 Jul 2016 14:26:32 -0400 Subject: [PATCH 0085/1644] Handle fanout case with local transport, making copies as necessary --- .../src/cpp/include/burstio/OutPortDecl.h | 4 ++ burstioInterfaces/src/cpp/lib/OutPortImpl.h | 40 +++++++++++++++++-- 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/burstioInterfaces/src/cpp/include/burstio/OutPortDecl.h b/burstioInterfaces/src/cpp/include/burstio/OutPortDecl.h index fcc265bc7..7d166239c 100644 --- a/burstioInterfaces/src/cpp/include/burstio/OutPortDecl.h +++ b/burstioInterfaces/src/cpp/include/burstio/OutPortDecl.h @@ -78,6 +78,10 @@ namespace burstio { return stats_.retrieve(); } + // Return true if this connection may modify the burst sequence memory + // on push + virtual bool modifiesBursts () const = 0; + protected: SenderStatistics stats_; }; diff --git a/burstioInterfaces/src/cpp/lib/OutPortImpl.h b/burstioInterfaces/src/cpp/lib/OutPortImpl.h index 0651ae9f5..bb875d030 100644 --- a/burstioInterfaces/src/cpp/lib/OutPortImpl.h +++ b/burstioInterfaces/src/cpp/lib/OutPortImpl.h @@ -20,6 +20,8 @@ #ifndef BURSTIO_OUTPORTIMPL_H #define BURSTIO_OUTPORTIMPL_H +#include + #include #include @@ -45,6 +47,11 @@ namespace burstio { { } + bool modifiesBursts() const + { + return false; + } + void pushBursts(const BurstSequenceType& bursts, boost::system_time startTime, float queueDepth) { try { @@ -120,6 +127,11 @@ namespace burstio { { } + bool modifiesBursts() const + { + return true; + } + void pushBursts(const BurstSequenceType& bursts, boost::system_time startTime, float queueDepth) { try { @@ -482,8 +494,8 @@ namespace burstio { template void OutPort::sendBursts(const BurstSequenceType& bursts, boost::system_time startTime, float queueDepth, const std::string& streamID) { - //LOG_INSTANCE_DEBUG("Sending " << bursts.length() << " bursts"); - + LOG_INSTANCE_TRACE("Sending " << bursts.length() << " bursts"); + std::vector deferred_ports; boost::mutex::scoped_lock lock(updatingPortsLock); for (typename ConnectionMap::iterator ii = connections_.begin(); ii != connections_.end(); ++ii) { const std::string& connectionId = ii->first; @@ -493,7 +505,29 @@ namespace burstio { continue; } - connection->pushBursts(bursts, startTime, queueDepth); + // If this connection may modify the burst sequence, save the push + // until the second pass + if (connection->modifiesBursts()) { + deferred_ports.push_back(connection); + } else { + connection->pushBursts(bursts, startTime, queueDepth); + } + } + + // Second pass: push to connections that may modify (i.e., steal) the + // burst sequence, making copies as needed + if (!deferred_ports.empty()) { + // There are remaining ports that may require a copy + int remaining = deferred_ports.size(); + BOOST_FOREACH(TransportType* connection, deferred_ports) { + if (remaining == 1) { + // Last connection, can allow it to steal the buffer + connection->pushBursts(bursts, startTime, queueDepth); + } else { + // There are more connections, make an (unnamed) copy + connection->pushBursts(BurstSequenceType(bursts), startTime, queueDepth); + } + } } } From c025d73a5b3ab32f231be132b1594a0366d7deb1 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 13 Apr 2016 17:09:43 -0400 Subject: [PATCH 0086/1644] Allow running just a specific test or set of tests --- throughput/redhawk-benchmark | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/throughput/redhawk-benchmark b/throughput/redhawk-benchmark index dd86e3ccd..5d382988b 100755 --- a/throughput/redhawk-benchmark +++ b/throughput/redhawk-benchmark @@ -75,7 +75,7 @@ class TextDisplay(TestMonitor): class BarGraph(TestMonitor): - def __init__(self, bins): + def __init__(self, series, bins): # Quiet the warning about GTK Tooltip deprecation import warnings with warnings.catch_warnings(): @@ -89,7 +89,7 @@ class BarGraph(TestMonitor): self.bar_plot.set_xlabel('Transfer size (B)') self.bar_plot.set_ylabel('Throughput (Bps)') - self.width = 1.0/3.0 + self.width = 1.0/series self.colors = itertools.cycle('bgrcmyk') self.bins = dict((bin, index) for index, bin in enumerate(bins)) @@ -317,6 +317,7 @@ if __name__ == '__main__': window_size = 5 tolerance = 0.1 nogui = False + interfaces = ['Raw', 'CORBA', 'BulkIO'] opts, args = getopt.getopt(sys.argv[1:], 'hw:t:d:', ['help', 'transport=', 'numa-distance=', 'no-gui']) for key, value in opts: @@ -335,6 +336,9 @@ if __name__ == '__main__': elif key == '--no-gui': nogui = True + if args: + interfaces = args + # Try powers of two from 16K to 32M transfer_sizes = [2**x for x in xrange(14, 26)] test = TransferSizeTest(transfer_sizes, poll_time, window_size, tolerance) @@ -343,7 +347,7 @@ if __name__ == '__main__': display = TextDisplay() else: from matplotlib import pyplot - display = BarGraph(transfer_sizes) + display = BarGraph(len(interfaces), transfer_sizes) test.add_idle_task(display.update) test.add_monitor(display) @@ -381,7 +385,7 @@ if __name__ == '__main__': print 'No NUMA support' numa_distance = None - for interface in ('Raw', 'CORBA', 'BulkIO'): + for interface in interfaces: if interface == 'Raw': factory = raw.factory(transport) elif interface == 'CORBA': From 1a1cc91d623f6ada048af794d43c242383e501bd Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 13 Apr 2016 17:59:32 -0400 Subject: [PATCH 0087/1644] Track the time spent in send/receive, to the best of our ability --- throughput/common/timing.h | 13 +++++ throughput/redhawk-benchmark | 4 ++ throughput/streams/bulkio/__init__.py | 6 +++ throughput/streams/bulkio/reader/cpp/.md5sums | 4 +- .../streams/bulkio/reader/cpp/Makefile.am | 2 +- .../streams/bulkio/reader/cpp/reader.cpp | 54 ++++++++++++++++++- throughput/streams/bulkio/reader/cpp/reader.h | 7 +++ .../streams/bulkio/reader/cpp/reader_base.cpp | 9 ++++ .../streams/bulkio/reader/cpp/reader_base.h | 2 + .../streams/bulkio/reader/reader.prf.xml | 5 ++ throughput/streams/bulkio/writer/cpp/.md5sums | 4 +- .../streams/bulkio/writer/cpp/Makefile.am | 2 +- .../streams/bulkio/writer/cpp/writer.cpp | 15 +++++- throughput/streams/bulkio/writer/cpp/writer.h | 2 + .../streams/bulkio/writer/cpp/writer_base.cpp | 18 +++++++ .../streams/bulkio/writer/cpp/writer_base.h | 4 ++ .../streams/bulkio/writer/writer.prf.xml | 10 ++++ throughput/streams/corba/__init__.py | 6 +++ throughput/streams/corba/idl/rawdata.idl | 2 + throughput/streams/corba/reader.cpp | 33 +++++++++++- throughput/streams/corba/writer.cpp | 27 +++++++++- throughput/streams/raw/__init__.py | 14 +++-- throughput/streams/raw/control.h | 1 + throughput/streams/raw/reader.cpp | 19 +++++++ throughput/streams/raw/writer.cpp | 13 +++++ 25 files changed, 262 insertions(+), 14 deletions(-) create mode 100644 throughput/common/timing.h diff --git a/throughput/common/timing.h b/throughput/common/timing.h new file mode 100644 index 000000000..1f32ec5d0 --- /dev/null +++ b/throughput/common/timing.h @@ -0,0 +1,13 @@ +#ifndef TIMING_H +#define TIMING_H + +#include + +inline double get_time() +{ + struct timespec now; + clock_gettime(CLOCK_MONOTONIC, &now); + return now.tv_sec + now.tv_nsec*1e-9; +} + +#endif diff --git a/throughput/redhawk-benchmark b/throughput/redhawk-benchmark index 5d382988b..c0053406c 100755 --- a/throughput/redhawk-benchmark +++ b/throughput/redhawk-benchmark @@ -277,6 +277,8 @@ class TransferSizeTest(BenchmarkTest): sample = {'time': now-start, 'rate': current_rate, 'size': transfer_size, + 'send_time': stream.send_time(), + 'recv_time': stream.recv_time(), 'write_cpu': writer['cpu'] * sys_cpu, 'write_rss': writer['rss'], 'write_majflt': writer['majflt'], @@ -355,6 +357,8 @@ if __name__ == '__main__': csv.add_field('time', 'time(s)') csv.add_field('rate', 'rate(Bps)') csv.add_field('size', 'transfer size(B)') + csv.add_field('send_time', 'average send call(s)') + csv.add_field('recv_time', 'average recv call(s)') csv.add_field('write_cpu', 'writer cpu(%)') csv.add_field('write_rss', 'writer rss') csv.add_field('write_majflt', 'writer major faults') diff --git a/throughput/streams/bulkio/__init__.py b/throughput/streams/bulkio/__init__.py index cdd017fe6..090514f11 100644 --- a/throughput/streams/bulkio/__init__.py +++ b/throughput/streams/bulkio/__init__.py @@ -66,6 +66,12 @@ def transfer_size(self, size): def received(self): return int(self.reader.received) + def send_time(self): + return float(self.writer.average_time) + + def recv_time(self): + return float(self.reader.average_time) + def terminate(self): self.writer.releaseObject() self.reader.releaseObject() diff --git a/throughput/streams/bulkio/reader/cpp/.md5sums b/throughput/streams/bulkio/reader/cpp/.md5sums index 70ce0fc2f..e90d2bc8a 100644 --- a/throughput/streams/bulkio/reader/cpp/.md5sums +++ b/throughput/streams/bulkio/reader/cpp/.md5sums @@ -1,10 +1,10 @@ -ebdea83f12424c8e125a20cf9fddb60d reader_base.cpp +1a313dab45817ac1afff2bb0d33fea5a reader_base.cpp f2bb62c7e2ca437dd8e3e549cdbbd98e main.cpp 8bfcd22353c3a57fee561ad86ee2a56b reconf 7babbadc243db5a457c46cb3953f7465 configure.ac a8bc574b27dc23d05cb5632e36afa093 Makefile.am 2aefaeaafd472e72e6f06082f92b1322 Makefile.am.ide 09d75d4d9a1858282f95a52ec7e70552 reader.h -3fa8f27c69574d2ef8db1cab3b21f41a reader_base.h +24dad4cedd3684f44f41b9857dae6681 reader_base.h b87651ea3565402473fb088004430fbf build.sh bbc766fb5d35f240b41015c3e999e6ac reader.cpp diff --git a/throughput/streams/bulkio/reader/cpp/Makefile.am b/throughput/streams/bulkio/reader/cpp/Makefile.am index df8c6c8fe..43366e7db 100644 --- a/throughput/streams/bulkio/reader/cpp/Makefile.am +++ b/throughput/streams/bulkio/reader/cpp/Makefile.am @@ -49,6 +49,6 @@ distclean-local: include $(srcdir)/Makefile.am.ide reader_SOURCES = $(redhawk_SOURCES_auto) reader_LDADD = $(SOFTPKG_LIBS) $(PROJECTDEPS_LIBS) $(BOOST_LDFLAGS) $(BOOST_THREAD_LIB) $(BOOST_REGEX_LIB) $(BOOST_SYSTEM_LIB) $(INTERFACEDEPS_LIBS) $(redhawk_LDADD_auto) -reader_CXXFLAGS = -Wall $(SOFTPKG_CFLAGS) $(PROJECTDEPS_CFLAGS) $(BOOST_CPPFLAGS) $(INTERFACEDEPS_CFLAGS) $(redhawk_INCLUDES_auto) +reader_CXXFLAGS = -Wall $(SOFTPKG_CFLAGS) $(PROJECTDEPS_CFLAGS) $(BOOST_CPPFLAGS) $(INTERFACEDEPS_CFLAGS) $(redhawk_INCLUDES_auto) -I$(top_srcdir)/common reader_LDFLAGS = -Wall $(redhawk_LDFLAGS_auto) diff --git a/throughput/streams/bulkio/reader/cpp/reader.cpp b/throughput/streams/bulkio/reader/cpp/reader.cpp index 3ada042c5..093fdcb0b 100644 --- a/throughput/streams/bulkio/reader/cpp/reader.cpp +++ b/throughput/streams/bulkio/reader/cpp/reader.cpp @@ -26,19 +26,65 @@ **************************************************************************/ +#include + #include "reader.h" +class OctetPort : public bulkio::InOctetPort +{ +public: + OctetPort(const std::string& name) : + bulkio::InOctetPort(name), + lastPacketSize(0), + packetCount(0), + totalTime(0.0), + averageTime(0.0) + { + } + + virtual void pushPacket(const CF::OctetSequence& data, const BULKIO::PrecisionUTCTime& T, CORBA::Boolean EOS, const char* streamID) + { + double start = get_time(); + bulkio::InOctetPort::pushPacket(data, T, EOS, streamID); + double end = get_time(); + + if (lastPacketSize != data.length()) { + lastPacketSize = data.length(); + packetCount = 1; + totalTime = end - start; + averageTime = totalTime; + } else { + packetCount++; + totalTime += end - start; + averageTime = totalTime / packetCount; + } + } + + double getAverageTime() + { + return averageTime; + } + +private: + size_t lastPacketSize; + size_t packetCount; + double totalTime; + double averageTime; +}; + PREPARE_LOGGING(reader_i) reader_i::reader_i(const char *uuid, const char *label) : reader_base(uuid, label) { // Avoid placing constructor code here. Instead, use the "constructor" function. - + dataOctet_in = new OctetPort("dataOctet_in"); + addPort("dataOctet_in", dataOctet_in); } reader_i::~reader_i() { + delete dataOctet_in; } void reader_i::constructor() @@ -46,6 +92,12 @@ void reader_i::constructor() /*********************************************************************************** This is the RH constructor. All properties are properly initialized before this function is called ***********************************************************************************/ + setPropertyQueryImpl(average_time, this, &reader_i::get_average_time); +} + +double reader_i::get_average_time() +{ + return dataOctet_in->getAverageTime(); } /*********************************************************************************************** diff --git a/throughput/streams/bulkio/reader/cpp/reader.h b/throughput/streams/bulkio/reader/cpp/reader.h index b4018d827..959258dd6 100644 --- a/throughput/streams/bulkio/reader/cpp/reader.h +++ b/throughput/streams/bulkio/reader/cpp/reader.h @@ -22,6 +22,8 @@ #include "reader_base.h" +class OctetPort; + class reader_i : public reader_base { ENABLE_LOGGING @@ -32,6 +34,11 @@ class reader_i : public reader_base void constructor(); int serviceFunction(); + + private: + OctetPort* dataOctet_in; + + double get_average_time(); }; #endif // READER_I_IMPL_H diff --git a/throughput/streams/bulkio/reader/cpp/reader_base.cpp b/throughput/streams/bulkio/reader/cpp/reader_base.cpp index 10a207663..d2124a305 100644 --- a/throughput/streams/bulkio/reader/cpp/reader_base.cpp +++ b/throughput/streams/bulkio/reader/cpp/reader_base.cpp @@ -86,6 +86,15 @@ void reader_base::loadProperties() "external", "property"); + addProperty(average_time, + 0.0, + "average_time", + "", + "readonly", + "", + "external", + "property"); + } diff --git a/throughput/streams/bulkio/reader/cpp/reader_base.h b/throughput/streams/bulkio/reader/cpp/reader_base.h index 04a81cdbd..5ef55bdde 100644 --- a/throughput/streams/bulkio/reader/cpp/reader_base.h +++ b/throughput/streams/bulkio/reader/cpp/reader_base.h @@ -44,6 +44,8 @@ class reader_base : public Component, protected ThreadedComponent // Member variables exposed as properties /// Property: received CORBA::ULongLong received; + /// Property: average_time + double average_time; // Ports /// Port: dataOctet_in diff --git a/throughput/streams/bulkio/reader/reader.prf.xml b/throughput/streams/bulkio/reader/reader.prf.xml index 79a1c1eee..3c88458aa 100644 --- a/throughput/streams/bulkio/reader/reader.prf.xml +++ b/throughput/streams/bulkio/reader/reader.prf.xml @@ -25,4 +25,9 @@ with this program. If not, see http://www.gnu.org/licenses/. + + 0.0 + + + diff --git a/throughput/streams/bulkio/writer/cpp/.md5sums b/throughput/streams/bulkio/writer/cpp/.md5sums index 93c62aa70..fce9e35d7 100644 --- a/throughput/streams/bulkio/writer/cpp/.md5sums +++ b/throughput/streams/bulkio/writer/cpp/.md5sums @@ -1,10 +1,10 @@ 04765722f6bd272eadc240fa48f2caec main.cpp b87651ea3565402473fb088004430fbf build.sh 8bfcd22353c3a57fee561ad86ee2a56b reconf -9bed716ae031bab9a729cbd74246aefd writer_base.h +9e5d33596cdced0a9983169fbcb50fef writer_base.h 68964fc9bfc7dc13cd670a7b711b1b43 configure.ac cf250777e1af3cb1c0606423e85a800f writer.cpp a46d6351333bed1378280bc9c1331f82 Makefile.am 2697fc91ff0865583b7f248454c0c1b2 Makefile.am.ide f905c5c2f46f79a675d8f3e10d7c528a writer.h -4182ca94f290d82ff4edfcd39c59651d writer_base.cpp +c3f6d1ca4ddaa476fb914bc2dc102e63 writer_base.cpp diff --git a/throughput/streams/bulkio/writer/cpp/Makefile.am b/throughput/streams/bulkio/writer/cpp/Makefile.am index 5c829281b..0cb735291 100644 --- a/throughput/streams/bulkio/writer/cpp/Makefile.am +++ b/throughput/streams/bulkio/writer/cpp/Makefile.am @@ -49,6 +49,6 @@ distclean-local: include $(srcdir)/Makefile.am.ide writer_SOURCES = $(redhawk_SOURCES_auto) writer_LDADD = $(SOFTPKG_LIBS) $(PROJECTDEPS_LIBS) $(BOOST_LDFLAGS) $(BOOST_THREAD_LIB) $(BOOST_REGEX_LIB) $(BOOST_SYSTEM_LIB) $(INTERFACEDEPS_LIBS) $(redhawk_LDADD_auto) -writer_CXXFLAGS = -Wall $(SOFTPKG_CFLAGS) $(PROJECTDEPS_CFLAGS) $(BOOST_CPPFLAGS) $(INTERFACEDEPS_CFLAGS) $(redhawk_INCLUDES_auto) +writer_CXXFLAGS = -Wall $(SOFTPKG_CFLAGS) $(PROJECTDEPS_CFLAGS) $(BOOST_CPPFLAGS) $(INTERFACEDEPS_CFLAGS) $(redhawk_INCLUDES_auto) -I $(top_srcdir)/common writer_LDFLAGS = -Wall $(redhawk_LDFLAGS_auto) diff --git a/throughput/streams/bulkio/writer/cpp/writer.cpp b/throughput/streams/bulkio/writer/cpp/writer.cpp index a3244204b..0de8f4478 100644 --- a/throughput/streams/bulkio/writer/cpp/writer.cpp +++ b/throughput/streams/bulkio/writer/cpp/writer.cpp @@ -26,12 +26,15 @@ **************************************************************************/ +#include + #include "writer.h" -PREPARE_LOGGING(writer_i) +PREPARE_LOGGING(writer_i); writer_i::writer_i(const char *uuid, const char *label) : - writer_base(uuid, label) + writer_base(uuid, label), + totalSeconds(0.0) { // Avoid placing constructor code here. Instead, use the "constructor" function. @@ -223,9 +226,17 @@ int writer_i::serviceFunction() size_t buffer_size = transfer_length; if (buffer.size() != buffer_size) { buffer.resize(buffer_size); + total_packets = 0; + totalSeconds = 0.0; } + double start = get_time(); stream.write(buffer, bulkio::time::utils::now()); + double end = get_time(); + + total_packets++; + totalSeconds += end-start; + average_time = totalSeconds/total_packets; return NORMAL; } diff --git a/throughput/streams/bulkio/writer/cpp/writer.h b/throughput/streams/bulkio/writer/cpp/writer.h index 5e96047e5..1826553df 100644 --- a/throughput/streams/bulkio/writer/cpp/writer.h +++ b/throughput/streams/bulkio/writer/cpp/writer.h @@ -36,6 +36,8 @@ class writer_i : public writer_base private: std::vector buffer; bulkio::OutOctetStream stream; + + double totalSeconds; }; #endif // WRITER_I_IMPL_H diff --git a/throughput/streams/bulkio/writer/cpp/writer_base.cpp b/throughput/streams/bulkio/writer/cpp/writer_base.cpp index 6cafe95e5..71c0464a7 100644 --- a/throughput/streams/bulkio/writer/cpp/writer_base.cpp +++ b/throughput/streams/bulkio/writer/cpp/writer_base.cpp @@ -86,6 +86,24 @@ void writer_base::loadProperties() "external", "property"); + addProperty(total_packets, + 0, + "total_packets", + "", + "readonly", + "", + "external", + "property"); + + addProperty(average_time, + 0.0, + "average_time", + "", + "readonly", + "", + "external", + "property"); + } diff --git a/throughput/streams/bulkio/writer/cpp/writer_base.h b/throughput/streams/bulkio/writer/cpp/writer_base.h index 92a039124..a700e0e42 100644 --- a/throughput/streams/bulkio/writer/cpp/writer_base.h +++ b/throughput/streams/bulkio/writer/cpp/writer_base.h @@ -44,6 +44,10 @@ class writer_base : public Component, protected ThreadedComponent // Member variables exposed as properties /// Property: transfer_length CORBA::ULong transfer_length; + /// Property: total_packets + CORBA::ULong total_packets; + /// Property: average_time + double average_time; // Ports /// Port: dataOctet_out diff --git a/throughput/streams/bulkio/writer/writer.prf.xml b/throughput/streams/bulkio/writer/writer.prf.xml index 396a88ab4..e258d2f62 100644 --- a/throughput/streams/bulkio/writer/writer.prf.xml +++ b/throughput/streams/bulkio/writer/writer.prf.xml @@ -25,4 +25,14 @@ with this program. If not, see http://www.gnu.org/licenses/. + + 0 + + + + + 0.0 + + + diff --git a/throughput/streams/corba/__init__.py b/throughput/streams/corba/__init__.py index 2ab549d14..8c0375a95 100644 --- a/throughput/streams/corba/__init__.py +++ b/throughput/streams/corba/__init__.py @@ -56,6 +56,12 @@ def transfer_size(self, size): def received(self): return self.reader.received() + def send_time(self): + return self.writer._get_average_time() + + def recv_time(self): + return self.reader._get_average_time() + def terminate(self): self.reader_proc.terminate() self.writer_proc.terminate() diff --git a/throughput/streams/corba/idl/rawdata.idl b/throughput/streams/corba/idl/rawdata.idl index 09ef9fc74..d449f9c9b 100644 --- a/throughput/streams/corba/idl/rawdata.idl +++ b/throughput/streams/corba/idl/rawdata.idl @@ -27,6 +27,7 @@ module rawdata { void push_short(in short_sequence data); void push_float(in float_sequence data); long long received(); + readonly attribute double average_time; }; interface writer { @@ -34,5 +35,6 @@ module rawdata { void transfer_length(in long length); void start(); void stop(); + readonly attribute double average_time; }; }; diff --git a/throughput/streams/corba/reader.cpp b/throughput/streams/corba/reader.cpp index 7b6ccbe59..f3f2d331e 100644 --- a/throughput/streams/corba/reader.cpp +++ b/throughput/streams/corba/reader.cpp @@ -22,6 +22,7 @@ #include +#include #include #include "rawdata.h" @@ -29,14 +30,21 @@ class Reader : public virtual POA_rawdata::reader { public: Reader() : - _received(0) + _received(0), + _lastPacketSize(0), + _packetCount(0), + _totalTime(0.0), + _averageTime(0.0) { } void push_octet(const rawdata::octet_sequence& data) { + double start = get_time(); _received += data.length(); _deleter.deallocate_array(const_cast(data).get_buffer(1)); + double end = get_time(); + record_time(end-start, data.length()); } void push_short(const rawdata::short_sequence& data) @@ -56,9 +64,32 @@ class Reader : public virtual POA_rawdata::reader { return _received; } + double average_time() + { + return _averageTime; + } + + void record_time(double elapsed, size_t length) { + if (_lastPacketSize != length) { + _lastPacketSize = length; + _packetCount = 1; + _totalTime = elapsed; + _averageTime = _totalTime; + } else { + _packetCount++; + _totalTime += elapsed; + _averageTime = _totalTime / _packetCount; + } + } + private: threaded_deleter _deleter; size_t _received; + + size_t _lastPacketSize; + size_t _packetCount; + double _totalTime; + double _averageTime; }; int main (int argc, char* argv[]) diff --git a/throughput/streams/corba/writer.cpp b/throughput/streams/corba/writer.cpp index 3a6677972..220544287 100644 --- a/throughput/streams/corba/writer.cpp +++ b/throughput/streams/corba/writer.cpp @@ -21,6 +21,8 @@ #include +#include + #include "rawdata.h" class Writer : public virtual POA_rawdata::writer { @@ -28,7 +30,10 @@ class Writer : public virtual POA_rawdata::writer { Writer() : _thread(0), _running(true), - _length(1024) + _length(1024), + _totalPackets(0), + _totalSeconds(0.0), + _averageTime(0.0) { _thread = new omni_thread(&Writer::thread_start, this); } @@ -42,6 +47,9 @@ class Writer : public virtual POA_rawdata::writer { void transfer_length(CORBA::Long length) { _length = length; + _totalPackets = 0; + _totalSeconds = 0.0; + _averageTime = 0.0; } void start() @@ -54,6 +62,11 @@ class Writer : public virtual POA_rawdata::writer { _running = false; } + double average_time() + { + return _averageTime; + } + private: void thread_run() { @@ -82,11 +95,19 @@ class Writer : public virtual POA_rawdata::writer { if (data.length() != _length) { data.length(_length); } + + double start = get_time(); _reader->push_octet(data); + double end = get_time(); + + _totalPackets++; + _totalSeconds += end-start; + _averageTime = _totalSeconds/_totalPackets; } } } + static void* thread_start(void* arg) { Writer* writer = (Writer*)arg; @@ -99,6 +120,10 @@ class Writer : public virtual POA_rawdata::writer { volatile bool _running; std::string _format; int _length; + + size_t _totalPackets; + double _totalSeconds; + double _averageTime; }; int main (int argc, char* argv[]) diff --git a/throughput/streams/raw/__init__.py b/throughput/streams/raw/__init__.py index 8f607057e..70f356fd7 100644 --- a/throughput/streams/raw/__init__.py +++ b/throughput/streams/raw/__init__.py @@ -29,12 +29,14 @@ class control(object): def __init__(self, transfer_size): fd, self.filename = tempfile.mkstemp() - os.ftruncate(fd, 12) - self.buf = mmap.mmap(fd, 12, mmap.MAP_SHARED, mmap.PROT_WRITE) + os.ftruncate(fd, 20) + self.buf = mmap.mmap(fd, 20, mmap.MAP_SHARED, mmap.PROT_WRITE) os.close(fd) self.total_bytes = ctypes.c_uint64.from_buffer(self.buf) self.total_bytes.value = 0 - self.transfer_size = ctypes.c_uint32.from_buffer(self.buf, 8) + self.average_time = ctypes.c_double.from_buffer(self.buf, 8) + self.average_time.value = 0.0 + self.transfer_size = ctypes.c_uint32.from_buffer(self.buf, 16) self.transfer_size.value = transfer_size def __del__(self): @@ -71,6 +73,12 @@ def transfer_size(self, size): def received(self): return self.reader_control.total_bytes.value + def send_time(self): + return self.writer_control.average_time.value + + def recv_time(self): + return self.reader_control.average_time.value + def terminate(self): # Assuming stop() was already called, the reader and writer should have # already exited diff --git a/throughput/streams/raw/control.h b/throughput/streams/raw/control.h index 744b79212..b61c27c42 100644 --- a/throughput/streams/raw/control.h +++ b/throughput/streams/raw/control.h @@ -26,6 +26,7 @@ struct control { volatile uint64_t total_bytes; + volatile double average_time; volatile uint32_t transfer_size; }; diff --git a/throughput/streams/raw/reader.cpp b/throughput/streams/raw/reader.cpp index ebd5923c9..47b5952f6 100644 --- a/throughput/streams/raw/reader.cpp +++ b/throughput/streams/raw/reader.cpp @@ -33,6 +33,7 @@ #include +#include #include #include "control.h" @@ -125,19 +126,37 @@ int main(int argc, const char* argv[]) control* state = open_control(argv[3]); + size_t total_packets = 0; + double total_seconds = 0.0; + size_t last_size = 0; + ssize_t count = 0; while (true) { + double start = get_time(); + size_t buffer_size = 0; if (read(fd, &buffer_size, sizeof(buffer_size)) < sizeof(buffer_size)) { break; } + if (buffer_size != last_size) { + last_size = buffer_size; + total_packets = 0; + total_seconds = 0.0; + state->average_time = 0.0; + } + char* buffer = new char[buffer_size]; size_t pass = read_buffer(fd, buffer, buffer_size); deleter.deallocate_array(buffer); if (pass == 0) { break; } + double end = get_time(); + + total_packets++; + total_seconds += end - start; + state->average_time = total_seconds / total_packets; state->total_bytes += pass; } diff --git a/throughput/streams/raw/writer.cpp b/throughput/streams/raw/writer.cpp index 9c80f0b96..ef7fdb2a8 100644 --- a/throughput/streams/raw/writer.cpp +++ b/throughput/streams/raw/writer.cpp @@ -29,6 +29,8 @@ #include #include +#include + #include "control.h" static volatile bool running = true; @@ -109,13 +111,24 @@ int main(int argc, const char* argv[]) char temp; std::cin.get(temp); + size_t total_packets = 0; + double total_seconds = 0.0; + while (running) { size_t buffer_size = state->transfer_size; if (buffer_size != buffer.size()) { buffer.resize(buffer_size); + total_packets = 0; + total_seconds = 0.0; + state->average_time = 0.0; } + double start = get_time(); write(fd, &buffer_size, sizeof(buffer_size)); ssize_t pass = write(fd, &buffer[0], buffer.size()); + double end = get_time(); + total_packets++; + total_seconds += end - start; + state->average_time = total_seconds / total_packets; state->total_bytes += pass; } From ad36430cbd0304297b186a16aa66ef6cda3b1ec2 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 14 Apr 2016 13:11:01 -0400 Subject: [PATCH 0088/1644] Add a slider to speedometer to change the transfer size --- throughput/streams/bulkio/__init__.py | 2 +- throughput/streams/corba/__init__.py | 2 +- throughput/streams/raw/__init__.py | 4 ++-- throughput/tools/speedometer.py | 11 +++++++++++ 4 files changed, 15 insertions(+), 4 deletions(-) diff --git a/throughput/streams/bulkio/__init__.py b/throughput/streams/bulkio/__init__.py index 090514f11..9a58be13b 100644 --- a/throughput/streams/bulkio/__init__.py +++ b/throughput/streams/bulkio/__init__.py @@ -61,7 +61,7 @@ def get_writer(self): return self.writer._process.pid() def transfer_size(self, size): - self.writer.transfer_length = size + self.writer.transfer_length = int(size) def received(self): return int(self.reader.received) diff --git a/throughput/streams/corba/__init__.py b/throughput/streams/corba/__init__.py index 8c0375a95..a761578e9 100644 --- a/throughput/streams/corba/__init__.py +++ b/throughput/streams/corba/__init__.py @@ -51,7 +51,7 @@ def get_writer(self): return self.writer_proc.pid def transfer_size(self, size): - self.writer.transfer_length(size) + self.writer.transfer_length(int(size)) def received(self): return self.reader.received() diff --git a/throughput/streams/raw/__init__.py b/throughput/streams/raw/__init__.py index 70f356fd7..8a1965beb 100644 --- a/throughput/streams/raw/__init__.py +++ b/throughput/streams/raw/__init__.py @@ -67,8 +67,8 @@ def get_writer(self): return self.writer_proc.pid def transfer_size(self, size): - self.writer_control.transfer_size.value = size - self.reader_control.transfer_size.value = size + self.writer_control.transfer_size.value = int(size) + self.reader_control.transfer_size.value = int(size) def received(self): return self.reader_control.total_bytes.value diff --git a/throughput/tools/speedometer.py b/throughput/tools/speedometer.py index fd3da4bf5..513b7c100 100644 --- a/throughput/tools/speedometer.py +++ b/throughput/tools/speedometer.py @@ -51,6 +51,15 @@ def __init__(self, period): self.line, = self.axes.plot(self.x, self.y) self.axes.set_xlim(xmax=period) + self.figure.subplots_adjust(bottom=0.2) + + sliderax = self.figure.add_axes([0.2, 0.05, 0.6, 0.05]) + min_size = 1024 + max_size = 8*1024*1024 + default_size = 1*1024*1024 + self.slider = matplotlib.widgets.Slider(sliderax, 'Transfer size', min_size, max_size, + default_size, '%.0f') + self.figure.show() def sample_added(self, **stats): @@ -182,6 +191,7 @@ def run(self, name, stream): test = ThroughputTest(poll_time, run_time) + import matplotlib from matplotlib import pyplot display = Speedometer(run_time) test.add_idle_task(display.update) @@ -197,6 +207,7 @@ def run(self, name, stream): numa_policy = numa.NumaPolicy(numa_distance) stream = factory.create('octet', numa_policy.next()) + display.slider.on_changed(stream.transfer_size) try: stream.transfer_size(transfer_size) test.run(interface, stream) From 375c0aa9e3fff4a5a8f11bb9469482f8816838de Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 27 Sep 2016 14:40:39 -0400 Subject: [PATCH 0089/1644] Convert BulkIO reader and writer to shared library components --- throughput/.gitignore | 9 +++++-- throughput/Makefile.am | 2 +- throughput/configure.ac | 4 ++++ throughput/streams/bulkio/__init__.py | 10 ++++---- throughput/streams/bulkio/reader/cpp/.md5sums | 8 +++---- .../streams/bulkio/reader/cpp/Makefile.am | 24 ++++++++++++------- throughput/streams/bulkio/reader/cpp/main.cpp | 10 ++++---- .../streams/bulkio/reader/cpp/reader_base.cpp | 2 ++ .../streams/bulkio/reader/reader.spd.xml | 6 ++--- throughput/streams/bulkio/writer/cpp/.md5sums | 8 +++---- .../streams/bulkio/writer/cpp/Makefile.am | 23 ++++++++++++------ throughput/streams/bulkio/writer/cpp/main.cpp | 10 ++++---- .../streams/bulkio/writer/cpp/writer.cpp | 7 +++--- throughput/streams/bulkio/writer/cpp/writer.h | 1 + .../streams/bulkio/writer/cpp/writer_base.cpp | 2 ++ .../streams/bulkio/writer/writer.spd.xml | 6 ++--- 16 files changed, 83 insertions(+), 49 deletions(-) diff --git a/throughput/.gitignore b/throughput/.gitignore index 2a17fee6e..f0639bc0b 100644 --- a/throughput/.gitignore +++ b/throughput/.gitignore @@ -1,5 +1,11 @@ +*.csv +*.la +*.lo *.m4 +*.o +*.so .deps/ +.libs/ autom4te.cache/ Makefile Makefile.in @@ -7,6 +13,7 @@ config.* configure depcomp install-sh +libtool ltmain.sh missing streams/bulkio/reader/cpp/reader @@ -20,5 +27,3 @@ streams/corba/reader streams/corba/writer streams/raw/reader streams/raw/writer -*.o -*.csv diff --git a/throughput/Makefile.am b/throughput/Makefile.am index 40ef0173d..3fcb49e53 100644 --- a/throughput/Makefile.am +++ b/throughput/Makefile.am @@ -17,6 +17,6 @@ # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see http://www.gnu.org/licenses/. # -ACLOCAL_AMFLAGS = -I ${OSSIEHOME}/share/aclocal/ossie +ACLOCAL_AMFLAGS = -I m4 -I ${OSSIEHOME}/share/aclocal/ossie SUBDIRS = streams/raw streams/corba streams/bulkio/reader/cpp streams/bulkio/writer/cpp diff --git a/throughput/configure.ac b/throughput/configure.ac index 2b07db0cc..99e4f62da 100644 --- a/throughput/configure.ac +++ b/throughput/configure.ac @@ -19,6 +19,8 @@ # AC_INIT([throughput], 1.0.0) AM_INIT_AUTOMAKE([foreign]) +AC_CONFIG_MACRO_DIR([m4]) +LT_INIT([dlopen disable-static]) AC_PROG_CC AC_PROG_CXX @@ -41,6 +43,8 @@ AX_BOOST_SYSTEM AX_BOOST_THREAD AX_BOOST_REGEX +CPPFLAGS="$CPPFLAGS -I\$(top_srcdir)/common" + AC_CONFIG_FILES([Makefile \ streams/corba/Makefile \ streams/raw/Makefile \ diff --git a/throughput/streams/bulkio/__init__.py b/throughput/streams/bulkio/__init__.py index 9a58be13b..db00b4234 100644 --- a/throughput/streams/bulkio/__init__.py +++ b/throughput/streams/bulkio/__init__.py @@ -43,10 +43,12 @@ def wrap(self, command, arguments): class BulkioStream(object): def __init__(self, format, numa_policy): + # TODO: Use NUMA launcher when supported in sandbox for .so components launcher = NumaLauncher(numa_policy) - self.writer = sb.launch(os.path.join(PATH, 'writer/writer.spd.xml'), debugger=launcher) - self.reader = sb.launch(os.path.join(PATH, 'reader/reader.spd.xml'), debugger=launcher) + self.writer = sb.launch(os.path.join(PATH, 'writer/writer.spd.xml')) + self.reader = sb.launch(os.path.join(PATH, 'reader/reader.spd.xml')) self.writer.connect(self.reader) + self.container = sb.domainless._getSandbox()._getComponentHost() def start(self): sb.start() @@ -55,10 +57,10 @@ def stop(self): sb.stop() def get_reader(self): - return self.reader._process.pid() + return self.container._process.pid() def get_writer(self): - return self.writer._process.pid() + return self.container._process.pid() def transfer_size(self, size): self.writer.transfer_length = int(size) diff --git a/throughput/streams/bulkio/reader/cpp/.md5sums b/throughput/streams/bulkio/reader/cpp/.md5sums index e90d2bc8a..54398b64b 100644 --- a/throughput/streams/bulkio/reader/cpp/.md5sums +++ b/throughput/streams/bulkio/reader/cpp/.md5sums @@ -1,8 +1,8 @@ -1a313dab45817ac1afff2bb0d33fea5a reader_base.cpp -f2bb62c7e2ca437dd8e3e549cdbbd98e main.cpp +bb780ee6cc14bbe61373f5da8b83cdc4 reader_base.cpp +a93fd9c0203f708c0bccb34cf8b02360 main.cpp 8bfcd22353c3a57fee561ad86ee2a56b reconf -7babbadc243db5a457c46cb3953f7465 configure.ac -a8bc574b27dc23d05cb5632e36afa093 Makefile.am +994527613365ab24d8f01fa45a2c6399 configure.ac +e6c2f53ac60077a6b5bfe2d7df24b1c1 Makefile.am 2aefaeaafd472e72e6f06082f92b1322 Makefile.am.ide 09d75d4d9a1858282f95a52ec7e70552 reader.h 24dad4cedd3684f44f41b9857dae6681 reader_base.h diff --git a/throughput/streams/bulkio/reader/cpp/Makefile.am b/throughput/streams/bulkio/reader/cpp/Makefile.am index 43366e7db..4cb479698 100644 --- a/throughput/streams/bulkio/reader/cpp/Makefile.am +++ b/throughput/streams/bulkio/reader/cpp/Makefile.am @@ -18,15 +18,24 @@ # along with this program. If not, see http://www.gnu.org/licenses/. # ossieName = reader -bindir = $(prefix)/dom/components/reader/cpp/ -bin_PROGRAMS = reader +libdir = $(prefix)/dom/components/reader/cpp +lib_LTLIBRARIES = reader.la -xmldir = $(prefix)/dom/components/reader/ +xmldir = $(prefix)/dom/components/reader dist_xml_DATA = ../reader.scd.xml ../reader.prf.xml ../reader.spd.xml ACLOCAL_AMFLAGS = -I m4 -I${OSSIEHOME}/share/aclocal/ossie AUTOMAKE_OPTIONS = subdir-objects +.PHONY: convenience-link clean-convenience-link +all-local : convenience-link +clean-local : clean-convenience-link + +convenience-link : reader.la + @ln -fs .libs/reader.so + +clean-convenience-link: + @rm -f reader.so distclean-local: rm -rf m4 @@ -42,13 +51,12 @@ distclean-local: rm -f missing rm -rf .deps - # Sources, libraries and library directories are auto-included from a file # generated by the REDHAWK IDE. You can remove/modify the following lines if # you wish to manually control these options. include $(srcdir)/Makefile.am.ide -reader_SOURCES = $(redhawk_SOURCES_auto) -reader_LDADD = $(SOFTPKG_LIBS) $(PROJECTDEPS_LIBS) $(BOOST_LDFLAGS) $(BOOST_THREAD_LIB) $(BOOST_REGEX_LIB) $(BOOST_SYSTEM_LIB) $(INTERFACEDEPS_LIBS) $(redhawk_LDADD_auto) -reader_CXXFLAGS = -Wall $(SOFTPKG_CFLAGS) $(PROJECTDEPS_CFLAGS) $(BOOST_CPPFLAGS) $(INTERFACEDEPS_CFLAGS) $(redhawk_INCLUDES_auto) -I$(top_srcdir)/common -reader_LDFLAGS = -Wall $(redhawk_LDFLAGS_auto) +reader_la_SOURCES = $(redhawk_SOURCES_auto) +reader_la_LIBADD = $(SOFTPKG_LIBS) $(PROJECTDEPS_LIBS) $(BOOST_LDFLAGS) $(BOOST_THREAD_LIB) $(BOOST_REGEX_LIB) $(BOOST_SYSTEM_LIB) $(INTERFACEDEPS_LIBS) $(redhawk_LDADD_auto) +reader_la_CXXFLAGS = -Wall $(SOFTPKG_CFLAGS) $(PROJECTDEPS_CFLAGS) $(BOOST_CPPFLAGS) $(INTERFACEDEPS_CFLAGS) $(redhawk_INCLUDES_auto) +reader_la_LDFLAGS = -shared -module -export-dynamic -export-symbols-regex 'make_component' -avoid-version $(redhawk_LDFLAGS_auto) diff --git a/throughput/streams/bulkio/reader/cpp/main.cpp b/throughput/streams/bulkio/reader/cpp/main.cpp index 06fb8ab52..8564681e6 100644 --- a/throughput/streams/bulkio/reader/cpp/main.cpp +++ b/throughput/streams/bulkio/reader/cpp/main.cpp @@ -21,10 +21,10 @@ #include "ossie/ossieSupport.h" #include "reader.h" -int main(int argc, char* argv[]) -{ - reader_i* reader_servant; - Component::start_component(reader_servant, argc, argv); - return 0; +extern "C" { + Resource_impl* make_component(const std::string& uuid, const std::string& identifier) + { + return new reader_i(uuid.c_str(), identifier.c_str()); + } } diff --git a/throughput/streams/bulkio/reader/cpp/reader_base.cpp b/throughput/streams/bulkio/reader/cpp/reader_base.cpp index d2124a305..7ffebc1d0 100644 --- a/throughput/streams/bulkio/reader/cpp/reader_base.cpp +++ b/throughput/streams/bulkio/reader/cpp/reader_base.cpp @@ -33,6 +33,8 @@ reader_base::reader_base(const char *uuid, const char *label) : Component(uuid, label), ThreadedComponent() { + setThreadName(label); + loadProperties(); dataOctet_in = new bulkio::InOctetPort("dataOctet_in"); diff --git a/throughput/streams/bulkio/reader/reader.spd.xml b/throughput/streams/bulkio/reader/reader.spd.xml index c76ee4afe..5d4883692 100644 --- a/throughput/streams/bulkio/reader/reader.spd.xml +++ b/throughput/streams/bulkio/reader/reader.spd.xml @@ -32,9 +32,9 @@ with this program. If not, see http://www.gnu.org/licenses/. The implementation contains descriptive information about the template for a software component. - - - cpp/reader + + + cpp/reader.so diff --git a/throughput/streams/bulkio/writer/cpp/.md5sums b/throughput/streams/bulkio/writer/cpp/.md5sums index fce9e35d7..a7d41c697 100644 --- a/throughput/streams/bulkio/writer/cpp/.md5sums +++ b/throughput/streams/bulkio/writer/cpp/.md5sums @@ -1,10 +1,10 @@ -04765722f6bd272eadc240fa48f2caec main.cpp +dff373b5aa0cad57441e0dd60ed03b6f main.cpp b87651ea3565402473fb088004430fbf build.sh 8bfcd22353c3a57fee561ad86ee2a56b reconf 9e5d33596cdced0a9983169fbcb50fef writer_base.h -68964fc9bfc7dc13cd670a7b711b1b43 configure.ac +9957cb9059fc17084dcb83614b0c8301 configure.ac cf250777e1af3cb1c0606423e85a800f writer.cpp -a46d6351333bed1378280bc9c1331f82 Makefile.am +2eb5eac4936add3eb4c5430a5b476eb1 Makefile.am 2697fc91ff0865583b7f248454c0c1b2 Makefile.am.ide f905c5c2f46f79a675d8f3e10d7c528a writer.h -c3f6d1ca4ddaa476fb914bc2dc102e63 writer_base.cpp +f01dd717a4833099b79af1604b39d280 writer_base.cpp diff --git a/throughput/streams/bulkio/writer/cpp/Makefile.am b/throughput/streams/bulkio/writer/cpp/Makefile.am index 0cb735291..6e7c71503 100644 --- a/throughput/streams/bulkio/writer/cpp/Makefile.am +++ b/throughput/streams/bulkio/writer/cpp/Makefile.am @@ -18,15 +18,24 @@ # along with this program. If not, see http://www.gnu.org/licenses/. # ossieName = writer -bindir = $(prefix)/dom/components/writer/cpp/ -bin_PROGRAMS = writer +libdir = $(prefix)/dom/components/writer/cpp +lib_LTLIBRARIES = writer.la -xmldir = $(prefix)/dom/components/writer/ +xmldir = $(prefix)/dom/components/writer dist_xml_DATA = ../writer.scd.xml ../writer.prf.xml ../writer.spd.xml ACLOCAL_AMFLAGS = -I m4 -I${OSSIEHOME}/share/aclocal/ossie AUTOMAKE_OPTIONS = subdir-objects +.PHONY: convenience-link clean-convenience-link +all-local : convenience-link +clean-local : clean-convenience-link + +convenience-link : writer.la + @ln -fs .libs/writer.so + +clean-convenience-link: + @rm -f writer.so distclean-local: rm -rf m4 @@ -47,8 +56,8 @@ distclean-local: # generated by the REDHAWK IDE. You can remove/modify the following lines if # you wish to manually control these options. include $(srcdir)/Makefile.am.ide -writer_SOURCES = $(redhawk_SOURCES_auto) -writer_LDADD = $(SOFTPKG_LIBS) $(PROJECTDEPS_LIBS) $(BOOST_LDFLAGS) $(BOOST_THREAD_LIB) $(BOOST_REGEX_LIB) $(BOOST_SYSTEM_LIB) $(INTERFACEDEPS_LIBS) $(redhawk_LDADD_auto) -writer_CXXFLAGS = -Wall $(SOFTPKG_CFLAGS) $(PROJECTDEPS_CFLAGS) $(BOOST_CPPFLAGS) $(INTERFACEDEPS_CFLAGS) $(redhawk_INCLUDES_auto) -I $(top_srcdir)/common -writer_LDFLAGS = -Wall $(redhawk_LDFLAGS_auto) +writer_la_SOURCES = $(redhawk_SOURCES_auto) +writer_la_LIBADD = $(SOFTPKG_LIBS) $(PROJECTDEPS_LIBS) $(BOOST_LDFLAGS) $(BOOST_THREAD_LIB) $(BOOST_REGEX_LIB) $(BOOST_SYSTEM_LIB) $(INTERFACEDEPS_LIBS) $(redhawk_LDADD_auto) +writer_la_CXXFLAGS = -Wall $(SOFTPKG_CFLAGS) $(PROJECTDEPS_CFLAGS) $(BOOST_CPPFLAGS) $(INTERFACEDEPS_CFLAGS) $(redhawk_INCLUDES_auto) +writer_la_LDFLAGS = -shared -module -export-dynamic -export-symbols-regex 'make_component' -avoid-version $(redhawk_LDFLAGS_auto) diff --git a/throughput/streams/bulkio/writer/cpp/main.cpp b/throughput/streams/bulkio/writer/cpp/main.cpp index 8e28ed5a3..c2a4ba206 100644 --- a/throughput/streams/bulkio/writer/cpp/main.cpp +++ b/throughput/streams/bulkio/writer/cpp/main.cpp @@ -21,10 +21,10 @@ #include "ossie/ossieSupport.h" #include "writer.h" -int main(int argc, char* argv[]) -{ - writer_i* writer_servant; - Component::start_component(writer_servant, argc, argv); - return 0; +extern "C" { + Resource_impl* make_component(const std::string& uuid, const std::string& identifier) + { + return new writer_i(uuid.c_str(), identifier.c_str()); + } } diff --git a/throughput/streams/bulkio/writer/cpp/writer.cpp b/throughput/streams/bulkio/writer/cpp/writer.cpp index 0de8f4478..ef93179f1 100644 --- a/throughput/streams/bulkio/writer/cpp/writer.cpp +++ b/throughput/streams/bulkio/writer/cpp/writer.cpp @@ -34,6 +34,7 @@ PREPARE_LOGGING(writer_i); writer_i::writer_i(const char *uuid, const char *label) : writer_base(uuid, label), + lastSize(0), totalSeconds(0.0) { // Avoid placing constructor code here. Instead, use the "constructor" function. @@ -223,11 +224,11 @@ void writer_i::constructor() ************************************************************************************************/ int writer_i::serviceFunction() { - size_t buffer_size = transfer_length; - if (buffer.size() != buffer_size) { - buffer.resize(buffer_size); + redhawk::buffer buffer(transfer_length); + if (buffer.size() != lastSize) { total_packets = 0; totalSeconds = 0.0; + lastSize = buffer.size(); } double start = get_time(); diff --git a/throughput/streams/bulkio/writer/cpp/writer.h b/throughput/streams/bulkio/writer/cpp/writer.h index 1826553df..66202c212 100644 --- a/throughput/streams/bulkio/writer/cpp/writer.h +++ b/throughput/streams/bulkio/writer/cpp/writer.h @@ -37,6 +37,7 @@ class writer_i : public writer_base std::vector buffer; bulkio::OutOctetStream stream; + size_t lastSize; double totalSeconds; }; diff --git a/throughput/streams/bulkio/writer/cpp/writer_base.cpp b/throughput/streams/bulkio/writer/cpp/writer_base.cpp index 71c0464a7..42d0913f4 100644 --- a/throughput/streams/bulkio/writer/cpp/writer_base.cpp +++ b/throughput/streams/bulkio/writer/cpp/writer_base.cpp @@ -33,6 +33,8 @@ writer_base::writer_base(const char *uuid, const char *label) : Component(uuid, label), ThreadedComponent() { + setThreadName(label); + loadProperties(); dataOctet_out = new bulkio::OutOctetPort("dataOctet_out"); diff --git a/throughput/streams/bulkio/writer/writer.spd.xml b/throughput/streams/bulkio/writer/writer.spd.xml index a9bf69bf2..47927bb1a 100644 --- a/throughput/streams/bulkio/writer/writer.spd.xml +++ b/throughput/streams/bulkio/writer/writer.spd.xml @@ -32,9 +32,9 @@ with this program. If not, see http://www.gnu.org/licenses/. The implementation contains descriptive information about the template for a software component. - - - cpp/writer + + + cpp/writer.so From b446f219d4826ed9403ca9368bcaa833f91ffc59 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 25 Apr 2016 13:53:59 -0400 Subject: [PATCH 0090/1644] Add generation of C++ dynamically-loaded module for components, to allow running in a shared address space --- .../jinja/cpp/component/base/mapping.py | 9 ++++ .../cpp/component/base/templates/Makefile.am | 54 ++++++++++++++----- .../cpp/component/base/templates/configure.ac | 3 ++ .../cpp/component/base/templates/main.cpp | 9 ++++ .../redhawk/codegen/model/softpkg.py | 3 ++ 5 files changed, 65 insertions(+), 13 deletions(-) diff --git a/redhawk-codegen/redhawk/codegen/jinja/cpp/component/base/mapping.py b/redhawk-codegen/redhawk/codegen/jinja/cpp/component/base/mapping.py index 539a3b32b..517c32dd5 100644 --- a/redhawk-codegen/redhawk/codegen/jinja/cpp/component/base/mapping.py +++ b/redhawk-codegen/redhawk/codegen/jinja/cpp/component/base/mapping.py @@ -29,6 +29,15 @@ def _mapComponent(self, softpkg): cppcomp['interfacedeps'] = tuple(self.getInterfaceDependencies(softpkg)) return cppcomp + def _mapImplementation(self, impl): + impldict = {} + if impl.isModule(): + impldict['module'] = True + impldict['target'] = impl.entrypoint().replace('.so', '.la') + else: + impldict['target'] = impl.entrypoint() + return impldict + def getInterfaceDependencies(self, softpkg): for namespace in self.getInterfaceNamespaces(softpkg): yield libraries.getPackageRequires(namespace) diff --git a/redhawk-codegen/redhawk/codegen/jinja/cpp/component/base/templates/Makefile.am b/redhawk-codegen/redhawk/codegen/jinja/cpp/component/base/templates/Makefile.am index f02d2bfec..93e970bc4 100644 --- a/redhawk-codegen/redhawk/codegen/jinja/cpp/component/base/templates/Makefile.am +++ b/redhawk-codegen/redhawk/codegen/jinja/cpp/component/base/templates/Makefile.am @@ -19,30 +19,50 @@ #} #% set outputdir = generator.getOutputDir() #% set componentdir = component.name.replace('.','/') -#% set executable = component.impl.entrypoint|relpath(outputdir) -#% set target = automake.canonicalName(executable) +#% set target = component.impl.target|relpath(outputdir) +#% set installdir = '/'.join(['$(prefix)', component.sdrpath, componentdir]) +#% set impldir = installdir + '/' + outputdir +#% set amtarget = automake.canonicalName(target) #{% block license %} #{# Allow child templates to include license #} #{% endblock %} #{% block binInfo %} ossieName = {{component.name}} -bindir = $(prefix)/{{component.sdrpath}}/{{componentdir}}/{{outputdir}}/ -bin_PROGRAMS = {{executable}} +#{% if component.impl.module %} +libdir = {{impldir}} +lib_LTLIBRARIES = {{target}} +#{% else %} +bindir = {{impldir}} +bin_PROGRAMS = {{target}} +#{% endif %} #{% endblock %} #{% block xmlInfo %} -xmldir = $(prefix)/{{component.sdrpath}}/{{componentdir}}/ +xmldir = {{installdir}} dist_xml_DATA = {{component.profile.values()|relpath(outputdir)|join(' ')}} #{% endblock %} ACLOCAL_AMFLAGS = -I m4 -I${OSSIEHOME}/share/aclocal/ossie AUTOMAKE_OPTIONS = subdir-objects - #{% if component.mFunction != None %} -mdir = $(prefix)/{{component.sdrpath}}/{{componentdir}}/{{outputdir}}/ +mdir = {{impldir}} dist_m_DATA = *.m + #{% endif %} +#{% if component.impl.module %} +#{% set solib = component.impl.entrypoint|relpath(outputdir) %} +.PHONY: convenience-link clean-convenience-link + +all-local : convenience-link +clean-local : clean-convenience-link + +convenience-link : {{ target }} + @ln -fs .libs/{{solib}} +clean-convenience-link: + @rm -f {{solib}} + +#{% endif %} #{% block distClean %} distclean-local: rm -rf m4 @@ -68,12 +88,20 @@ distclean-local: # generated by the REDHAWK IDE. You can remove/modify the following lines if # you wish to manually control these options. include $(srcdir)/Makefile.am.ide -{{target}}_SOURCES = $(redhawk_SOURCES_auto) -{{target}}_LDADD = $(SOFTPKG_LIBS) $(PROJECTDEPS_LIBS) $(BOOST_LDFLAGS) $(BOOST_THREAD_LIB) $(BOOST_REGEX_LIB) $(BOOST_SYSTEM_LIB) $(INTERFACEDEPS_LIBS) $(redhawk_LDADD_auto) -{{target}}_CXXFLAGS = -Wall $(SOFTPKG_CFLAGS) $(PROJECTDEPS_CFLAGS) $(BOOST_CPPFLAGS) $(INTERFACEDEPS_CFLAGS) $(redhawk_INCLUDES_auto) -{{target}}_LDFLAGS = -Wall $(redhawk_LDFLAGS_auto) +{{amtarget}}_SOURCES = $(redhawk_SOURCES_auto) +#{% if component.impl.module %} +{{amtarget}}_LIBADD = $(SOFTPKG_LIBS) $(PROJECTDEPS_LIBS) $(BOOST_LDFLAGS) $(BOOST_THREAD_LIB) $(BOOST_REGEX_LIB) $(BOOST_SYSTEM_LIB) $(INTERFACEDEPS_LIBS) $(redhawk_LDADD_auto) +#{% else %} +{{amtarget}}_LDADD = $(SOFTPKG_LIBS) $(PROJECTDEPS_LIBS) $(BOOST_LDFLAGS) $(BOOST_THREAD_LIB) $(BOOST_REGEX_LIB) $(BOOST_SYSTEM_LIB) $(INTERFACEDEPS_LIBS) $(redhawk_LDADD_auto) +#{% endif %} +{{amtarget}}_CXXFLAGS = -Wall $(SOFTPKG_CFLAGS) $(PROJECTDEPS_CFLAGS) $(BOOST_CPPFLAGS) $(INTERFACEDEPS_CFLAGS) $(redhawk_INCLUDES_auto) +#{% if component.impl.module %} +{{amtarget}}_LDFLAGS = -module -export-dynamic -avoid-version $(redhawk_LDFLAGS_auto) +#{% else %} +{{amtarget}}_LDFLAGS = -Wall $(redhawk_LDFLAGS_auto) +#{% endif %} #{% if component.mFunction %} -{{target}}_CXXFLAGS += $(M_FUNCTION_INTERPRETER_INCLUDE) -{{target}}_LDFLAGS += $(M_FUNCTION_INTERPRETER_LOAD) +{{amtarget}}_CXXFLAGS += $(M_FUNCTION_INTERPRETER_INCLUDE) +{{amtarget}}_LDFLAGS += $(M_FUNCTION_INTERPRETER_LOAD) #{% endif %} #{% endblock %} diff --git a/redhawk-codegen/redhawk/codegen/jinja/cpp/component/base/templates/configure.ac b/redhawk-codegen/redhawk/codegen/jinja/cpp/component/base/templates/configure.ac index 175720981..216624239 100644 --- a/redhawk-codegen/redhawk/codegen/jinja/cpp/component/base/templates/configure.ac +++ b/redhawk-codegen/redhawk/codegen/jinja/cpp/component/base/templates/configure.ac @@ -24,6 +24,9 @@ AC_INIT({{component.name}}, {{component.version}}) AM_INIT_AUTOMAKE([nostdinc foreign]) AC_CONFIG_MACRO_DIR([m4]) +#{% if component.impl.module %} +LT_INIT([dlopen disable-static]) +#{% endif %} #{% endblock %} #{% block acChecks %} diff --git a/redhawk-codegen/redhawk/codegen/jinja/cpp/component/base/templates/main.cpp b/redhawk-codegen/redhawk/codegen/jinja/cpp/component/base/templates/main.cpp index 179e2c860..ce9658adb 100644 --- a/redhawk-codegen/redhawk/codegen/jinja/cpp/component/base/templates/main.cpp +++ b/redhawk-codegen/redhawk/codegen/jinja/cpp/component/base/templates/main.cpp @@ -40,6 +40,14 @@ void signal_catcher(int sig) } } /*{% endif %}*/ +/*{% if component.impl.module %}*/ +extern "C" { + Resource_impl* make_component(const std::string& uuid, const std::string& identifier) + { + return new ${component.userclass.name}(uuid.c_str(), identifier.c_str()); + } +} +/*{% else %}*/ int main(int argc, char* argv[]) { /*{% if component is device %}*/ @@ -56,4 +64,5 @@ int main(int argc, char* argv[]) /*{% endif %}*/ return 0; } +/*{% endif %}*/ /*{% endblock %}*/ diff --git a/redhawk-codegen/redhawk/codegen/model/softpkg.py b/redhawk-codegen/redhawk/codegen/model/softpkg.py index c7532edbc..e47685c13 100644 --- a/redhawk-codegen/redhawk/codegen/model/softpkg.py +++ b/redhawk-codegen/redhawk/codegen/model/softpkg.py @@ -59,6 +59,9 @@ def entrypoint(self): return self.__impl.code.localfile.name return self.__impl.code.entrypoint + def isModule(self): + return self.__impl.code.get_type() == 'SharedLibrary' + def localfile(self): return self.__impl.code.localfile.name From 8894c3a7c45c636bff667510c2e3e65d3c6f3a61 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 26 Apr 2016 16:35:54 -0400 Subject: [PATCH 0091/1644] Only export the 'make_component' symbol; put a '-shared' flag on the library rather than disabling static libraries in configure --- .../codegen/jinja/cpp/component/base/templates/Makefile.am | 2 +- .../codegen/jinja/cpp/component/base/templates/configure.ac | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/redhawk-codegen/redhawk/codegen/jinja/cpp/component/base/templates/Makefile.am b/redhawk-codegen/redhawk/codegen/jinja/cpp/component/base/templates/Makefile.am index 93e970bc4..69b4eea04 100644 --- a/redhawk-codegen/redhawk/codegen/jinja/cpp/component/base/templates/Makefile.am +++ b/redhawk-codegen/redhawk/codegen/jinja/cpp/component/base/templates/Makefile.am @@ -96,7 +96,7 @@ include $(srcdir)/Makefile.am.ide #{% endif %} {{amtarget}}_CXXFLAGS = -Wall $(SOFTPKG_CFLAGS) $(PROJECTDEPS_CFLAGS) $(BOOST_CPPFLAGS) $(INTERFACEDEPS_CFLAGS) $(redhawk_INCLUDES_auto) #{% if component.impl.module %} -{{amtarget}}_LDFLAGS = -module -export-dynamic -avoid-version $(redhawk_LDFLAGS_auto) +{{amtarget}}_LDFLAGS = -shared -module -export-dynamic -export-symbols-regex 'make_component' -avoid-version $(redhawk_LDFLAGS_auto) #{% else %} {{amtarget}}_LDFLAGS = -Wall $(redhawk_LDFLAGS_auto) #{% endif %} diff --git a/redhawk-codegen/redhawk/codegen/jinja/cpp/component/base/templates/configure.ac b/redhawk-codegen/redhawk/codegen/jinja/cpp/component/base/templates/configure.ac index 216624239..8db7869a1 100644 --- a/redhawk-codegen/redhawk/codegen/jinja/cpp/component/base/templates/configure.ac +++ b/redhawk-codegen/redhawk/codegen/jinja/cpp/component/base/templates/configure.ac @@ -25,7 +25,7 @@ AC_INIT({{component.name}}, {{component.version}}) AM_INIT_AUTOMAKE([nostdinc foreign]) AC_CONFIG_MACRO_DIR([m4]) #{% if component.impl.module %} -LT_INIT([dlopen disable-static]) +LT_INIT([dlopen]) #{% endif %} #{% endblock %} From d28b3dac8394874dae38670a658988114f268af0 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 14 Jul 2016 15:19:32 -0400 Subject: [PATCH 0092/1644] Set the thread name (used for the service function) based on the label in C++ components --- .../jinja/cpp/component/pull/templates/resource_base.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/redhawk-codegen/redhawk/codegen/jinja/cpp/component/pull/templates/resource_base.cpp b/redhawk-codegen/redhawk/codegen/jinja/cpp/component/pull/templates/resource_base.cpp index 99d336bc1..e6e21c140 100644 --- a/redhawk-codegen/redhawk/codegen/jinja/cpp/component/pull/templates/resource_base.cpp +++ b/redhawk-codegen/redhawk/codegen/jinja/cpp/component/pull/templates/resource_base.cpp @@ -88,6 +88,8 @@ ${baseClass}(uuid, label), ThreadedComponent() { + setThreadName(label); + /*{% block constructorBody %}*/ loadProperties(); /*{% for port in component.ports %}*/ From 0f6e3548b078a9aa86916a7d1d958102cdca8ff9 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 22 Jul 2016 14:24:58 -0400 Subject: [PATCH 0093/1644] Generate a format string for C++ struct properties, used in local messaging negotiation --- .../codegen/jinja/cpp/properties/mapping.py | 31 ++++++++++++++++++- .../cpp/properties/templates/properties.cpp | 8 +++-- 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/redhawk-codegen/redhawk/codegen/jinja/cpp/properties/mapping.py b/redhawk-codegen/redhawk/codegen/jinja/cpp/properties/mapping.py index 25b9151c3..04044b926 100644 --- a/redhawk-codegen/redhawk/codegen/jinja/cpp/properties/mapping.py +++ b/redhawk-codegen/redhawk/codegen/jinja/cpp/properties/mapping.py @@ -19,11 +19,37 @@ # from redhawk.codegen.lang import cpp -from redhawk.codegen.lang.idl import IDLInterface +from redhawk.codegen.lang.idl import IDLInterface, CorbaTypes from redhawk.codegen.jinja.mapping import PropertyMapper +_formats = { + CorbaTypes.OCTET : 'o', + CorbaTypes.BOOLEAN : 'b', + CorbaTypes.CHAR : 'c', + CorbaTypes.SHORT : 'h', + CorbaTypes.USHORT : 'H', + CorbaTypes.LONG : 'i', + CorbaTypes.ULONG : 'I', + CorbaTypes.LONGLONG : 'l', + CorbaTypes.ULONGLONG : 'L', + CorbaTypes.FLOAT : 'f', + CorbaTypes.DOUBLE : 'd', + CorbaTypes.STRING : 's', + CorbaTypes.OBJREF : 's', +} + class CppPropertyMapper(PropertyMapper): + def _getSimpleFormat(self, prop, isSequence): + format = _formats[prop.type()] + if prop.isComplex(): + format = '2' + format; + if isSequence: + format = '[' + format + ']' + if prop.isOptional(): + format += '?' + return format + def mapProperty(self, prop): cppprop = {} if prop.hasName(): @@ -42,6 +68,7 @@ def mapSimpleProperty(self, prop): cppprop['cppvalue'] = cpp.literal(prop.value(), prop.type(), prop.isComplex()) + cppprop['format'] = self._getSimpleFormat(prop, False) return cppprop def mapSimpleSequenceProperty(self, prop): @@ -53,6 +80,7 @@ def mapSimpleSequenceProperty(self, prop): prop.type(), prop.isComplex()) for v in prop.value()] + cppprop['format'] = self._getSimpleFormat(prop, True) return cppprop def mapStructProperty(self, prop, fields): @@ -60,6 +88,7 @@ def mapStructProperty(self, prop, fields): typename = self.getStructPropertyType(prop) cppprop['cpptype'] = typename cppprop['cppvalue'] = typename + '()' + cppprop['format'] = ''.join(f['format'] for f in fields) return cppprop def getStructPropertyType(self, prop): diff --git a/redhawk-codegen/redhawk/codegen/jinja/cpp/properties/templates/properties.cpp b/redhawk-codegen/redhawk/codegen/jinja/cpp/properties/templates/properties.cpp index fb66720a6..7f184b521 100644 --- a/redhawk-codegen/redhawk/codegen/jinja/cpp/properties/templates/properties.cpp +++ b/redhawk-codegen/redhawk/codegen/jinja/cpp/properties/templates/properties.cpp @@ -107,11 +107,15 @@ struct ${struct.cpptype}${' : public '+struct.baseclass if struct.baseclass} { /*{% endif %}*/ /*{% endif %}*/ /*{% endfor %}*/ - }; + } static std::string getId() { return std::string("${struct.identifier}"); - }; + } + + static const char* getFormat() { + return "${struct.format}"; + } /*{% for field in struct.fields if not field.inherited %}*/ /*{% if loop.first %}*/ From 6e183690ea4832515e3444dd4f029f5f354ee760 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 29 Feb 2016 16:05:18 -0500 Subject: [PATCH 0094/1644] Only steal incoming CORBA memory if the sequence owns it, otherwise make a copy. This happens within the same process space, because the CORBA sequence is a non-owning view of the original vector. --- bulkioInterfaces/libsrc/cpp/bulkio.cpp | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio.cpp b/bulkioInterfaces/libsrc/cpp/bulkio.cpp index 6ca4a749b..cd9be35fb 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio.cpp @@ -238,25 +238,22 @@ namespace bulkio { template < typename DataTransferTraits > DataTransfer< DataTransferTraits >::DataTransfer(const PortSequenceType & data, const BULKIO::PrecisionUTCTime &_T, bool _EOS, const char* _streamID, BULKIO::StreamSRI &_H, bool _sriChanged, bool _inputQueueFlushed) { - int dataLength = data.length(); + const size_t dataLength = data.length(); typedef typename std::_Vector_base< TransportType, typename DataTransferTraits::DataBufferType::allocator_type >::_Vector_impl *VectorPtr; VectorPtr vectorPtr = (VectorPtr)(&dataBuffer); - vectorPtr->_M_start = const_cast< PortSequenceType *>(&data)->get_buffer(1); - vectorPtr->_M_finish = vectorPtr->_M_start + dataLength; - vectorPtr->_M_end_of_storage = vectorPtr->_M_finish; - // - // removed... - // -#if 0 - dataBuffer.resize(dataLength); - if (dataLength > 0) { - memcpy(&dataBuffer[0], &data[0], dataLength * sizeof(data[0])); + if (data.release()) { + vectorPtr->_M_start = const_cast< PortSequenceType *>(&data)->get_buffer(1); + } else { + // Somebody else owns the data; make a copy + vectorPtr->_M_start = vectorPtr->allocate(dataLength); + const void* buffer = data.get_buffer(); + memcpy(vectorPtr->_M_start, buffer, dataLength*sizeof(NativeDataType)); } - -#endif + vectorPtr->_M_finish = vectorPtr->_M_start + dataLength; + vectorPtr->_M_end_of_storage = vectorPtr->_M_finish; T = _T; EOS = _EOS; From 780cd26adfaf0c718b179fe2932acd1148885443 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 8 Apr 2016 15:10:01 -0400 Subject: [PATCH 0095/1644] Add output stream write overloads for read buffers --- .../libsrc/cpp/bulkio_out_stream.cpp | 24 +++++++++++ .../libsrc/cpp/bulkio_out_stream.h | 40 +++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp index 7d7b750fc..b752795f0 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp @@ -274,6 +274,30 @@ void OutputStream::eraseKeyword(const std::string& name) _impl->eraseKeyword(name); } +template +void OutputStream::write(const scalar_buffer& data, const BULKIO::PrecisionUTCTime& time) +{ + _impl->write(data.data(), data.size(), time); +} + +template +void OutputStream::write(const scalar_buffer& data, const std::list& times) +{ + _impl->write(data.data(), data.size(), times); +} + +template +void OutputStream::write(const complex_buffer& data, const BULKIO::PrecisionUTCTime& time) +{ + _impl->write(data.data(), data.size(), time); +} + +template +void OutputStream::write(const complex_buffer& data, const std::list& times) +{ + _impl->write(data.data(), data.size(), times); +} + template void OutputStream::write(const ScalarType* data, size_t count, const BULKIO::PrecisionUTCTime& time) { diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h index 43b79146a..9d57e2e9b 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h @@ -26,6 +26,7 @@ #include #include +#include #include #include "bulkio_traits.h" @@ -41,6 +42,9 @@ namespace bulkio { public: typedef typename PortTraits::DataTransferTraits::NativeDataType ScalarType; typedef std::complex ComplexType; + + typedef redhawk::read_buffer scalar_buffer; + typedef redhawk::read_buffer complex_buffer; OutputStream(); @@ -84,6 +88,42 @@ namespace bulkio { write(&data[0], data.size(), times); } + /** + * @brief Write scalar data to the stream. + * @param data The %read_buffer to write. + * @param time The timestamp of the first sample. + */ + void write(const scalar_buffer& data, const BULKIO::PrecisionUTCTime& time); + + /** + * @brief Write scalar data to the stream. + * @param data The %read_buffer to write. + * @param times A list of sample timestamps. Sample offsets must be in + * increasing order, starting at 0. + * + * Writes a buffer of data with multiple timestamps, breaking up the data + * into chunks at the SampleTimestamp offsets. + */ + void write(const scalar_buffer& data, const std::list& times); + + /** + * @brief Write complex data to the stream. + * @param data The %read_buffer to write. + * @param time The timestamp of the first sample. + */ + void write(const complex_buffer& data, const BULKIO::PrecisionUTCTime& time); + + /** + * @brief Write complex data to the stream. + * @param data The %read_buffer to write. + * @param times A list of sample timestamps. Sample offsets must be in + * increasing order, starting at 0. + * + * Writes a buffer of data with multiple timestamps, breaking up the data + * into chunks at the SampleTimestamp offsets. + */ + void write(const complex_buffer& data, const std::list& times); + void write(const ScalarType* data, size_t count, const BULKIO::PrecisionUTCTime& time); void write(const ScalarType* data, size_t count, const std::list& times); From ae80f02ba7ee46179c8b2dad6bfd049746b4d857 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 11 Apr 2016 10:13:18 -0400 Subject: [PATCH 0096/1644] Enable direct calls to local input ports, skipping CORBA layer entirely --- .../libsrc/cpp/bulkio_out_port.cpp | 57 ++++++++++++++++++- bulkioInterfaces/libsrc/cpp/bulkio_out_port.h | 19 +++++++ 2 files changed, 75 insertions(+), 1 deletion(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp index 8cc3cd227..4d5c3aab4 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp @@ -24,6 +24,7 @@ #include "bulkio_out_port.h" #include "bulkio_p.h" #include "bulkio_time_operators.h" +#include "bulkio_in_port.h" // Suppress warnings for access to "deprecated" currentSRI member--it's the // public access that's deprecated, not the member itself @@ -170,6 +171,17 @@ namespace bulkio { port->pushPacket(data, T, EOS, streamID); } + template < typename PortTraits > + void OutPortBase< PortTraits >::_pushPacketToPort( + LocalPortType* port, + PushArgumentType data, + const BULKIO::PrecisionUTCTime& T, + bool EOS, + const char* streamID) + { + port->pushPacket(data, T, EOS, streamID); + } + template < typename PortTraits > void OutPortBase< PortTraits >::_sendEOS( PortPtrType port, @@ -231,7 +243,12 @@ namespace bulkio { } try { - _pushPacketToPort(port->first, data, T, EOS, streamID.c_str()); + typename LocalPortMap::iterator local = localPorts.find(port->second); + if (local != localPorts.end()) { + _pushPacketToPort(local->second, data, T, EOS, streamID.c_str()); + } else { + _pushPacketToPort(port->first, data, T, EOS, streamID.c_str()); + } if ( stats.count(port->second) == 0 ) { stats.insert( std::make_pair(port->second, linkStatistics( name, sizeof(NativeType) ) ) ); } @@ -321,6 +338,15 @@ namespace bulkio { LOG_ERROR( logger, "CONNECT FAILED: UNABLE TO NARROW ENDPOINT, USES PORT:" << name ); throw CF::Port::InvalidPort(1, "Unable to narrow"); } + + LocalPortType* local_port = ossie::corba::getLocalServant(port); + if (local_port) { + LOG_DEBUG(logger, "Using local connection to port " << local_port->getName() + << " for connection " << connectionId); + local_port->_add_ref(); + localPorts[connectionId] = local_port; + } + outConnections.push_back(std::make_pair(port, connectionId)); active = true; recConnectionsRefresh = true; @@ -371,6 +397,13 @@ namespace bulkio { LOG_DEBUG( logger, "DISCONNECT, PORT/CONNECTION: " << name << "/" << connectionId ); stats.erase(ii->second); outConnections.erase(ii); + + typename LocalPortMap::iterator local = localPorts.find(connectionId); + if (local != localPorts.end()) { + LocalPortType* local_port = local->second; + localPorts.erase(local); + local_port->_remove_ref(); + } break; } @@ -510,6 +543,17 @@ namespace bulkio { port->pushPacket(data, EOS, streamID); } + template <> + void OutPortBase< XMLPortTraits >::_pushPacketToPort( + InPort* port, + const char* data, + const BULKIO::PrecisionUTCTime& T, + bool EOS, + const char* streamID) + { + port->pushPacket((bulkio::Char*)data, T, EOS, streamID); + } + template <> void OutPortBase< XMLPortTraits >::_sendEOS( @@ -534,6 +578,17 @@ namespace bulkio { * Specializations of base class methods for dataFile ports */ + template <> + void OutPortBase< FilePortTraits >::_pushPacketToPort( + LocalPortType* port, + PushArgumentType data, + const BULKIO::PrecisionUTCTime& T, + bool EOS, + const char* streamID) + { + port->pushPacket((bulkio::Char*)data, T, EOS, streamID); + } + template <> void OutPortBase< FilePortTraits >::_sendEOS( BULKIO::dataFile_ptr port, diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h index 713cae3e7..31e1b4965 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h @@ -38,6 +38,8 @@ namespace bulkio { + template class InPort; + // // OutPortBase // @@ -296,6 +298,13 @@ namespace bulkio { // _StatsMap stats; + // + // Lookup table for connections to input ports in the same process space + // + typedef InPort LocalPortType; + typedef std::map LocalPortMap; + LocalPortMap localPorts; + // // _pushSRI - method to push given SRI to a specific connections // @@ -354,6 +363,16 @@ namespace bulkio { bool EOS, const char* streamID); + // + // In-process version of _pushPacketToPort, skips middleware + // + void _pushPacketToPort( + LocalPortType* port, + PushArgumentType data, + const BULKIO::PrecisionUTCTime& T, + bool EOS, + const char* streamID); + // // Returns the total number of elements of data in a pushPacket call, for // statistical tracking; enables XML and File specialization, which have From 60650cd7f07b19fb09519ec3881ae7b3b19ccf42 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 11 Apr 2016 11:11:12 -0400 Subject: [PATCH 0097/1644] Pass shared buffer down another level in output stream --- .../libsrc/cpp/bulkio_out_stream.cpp | 59 ++++++++++++++++--- .../libsrc/cpp/bulkio_out_stream.h | 12 ++-- 2 files changed, 57 insertions(+), 14 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp index b752795f0..1435e4288 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp @@ -30,6 +30,9 @@ class OutputStream::Impl { typedef std::complex ComplexType; typedef typename PortTraits::DataTransferTraits::TransportType TransportType; + typedef typename OutputStream::ScalarBuffer ScalarBuffer; + typedef typename OutputStream::ComplexBuffer ComplexBuffer; + Impl(const std::string& streamID, bulkio::OutPort* port) : _streamID(streamID), _port(port), @@ -97,6 +100,46 @@ class OutputStream::Impl { _sriUpdated = true; } + void write(const ScalarBuffer& data, const BULKIO::PrecisionUTCTime& time) + { + if (_sriUpdated) { + _port->pushSRI(_sri); + _sriUpdated = false; + } + // TODO: Enable buffer transfer + _send(reinterpret_cast(data.data()), data.size(), time, false); + } + + void write(const ComplexBuffer& data, const BULKIO::PrecisionUTCTime& time) + { + if (_sri.mode == 0) { + throw std::logic_error("stream mode is not complex"); + } + write(ScalarBuffer::recast(data), time); + } + + template + void write(const redhawk::read_buffer& data, const std::list& times) + { + std::list::const_iterator timestamp = times.begin(); + if (timestamp == times.end()) { + throw std::logic_error("no timestamps given"); + } + + size_t first = 0; + while (first < data.size()) { + size_t last = 0; + const BULKIO::PrecisionUTCTime& when = timestamp->time; + if (++timestamp == times.end()) { + last = data.size(); + } else { + last = timestamp->offset; + } + write(data.slice(first, last), when); + first = last; + } + } + template void write(const Sample* data, size_t count, const std::list& times) { @@ -275,27 +318,27 @@ void OutputStream::eraseKeyword(const std::string& name) } template -void OutputStream::write(const scalar_buffer& data, const BULKIO::PrecisionUTCTime& time) +void OutputStream::write(const ScalarBuffer& data, const BULKIO::PrecisionUTCTime& time) { - _impl->write(data.data(), data.size(), time); + _impl->write(data, time); } template -void OutputStream::write(const scalar_buffer& data, const std::list& times) +void OutputStream::write(const ScalarBuffer& data, const std::list& times) { - _impl->write(data.data(), data.size(), times); + _impl->write(data, times); } template -void OutputStream::write(const complex_buffer& data, const BULKIO::PrecisionUTCTime& time) +void OutputStream::write(const ComplexBuffer& data, const BULKIO::PrecisionUTCTime& time) { - _impl->write(data.data(), data.size(), time); + _impl->write(data, time); } template -void OutputStream::write(const complex_buffer& data, const std::list& times) +void OutputStream::write(const ComplexBuffer& data, const std::list& times) { - _impl->write(data.data(), data.size(), times); + _impl->write(data, times); } template diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h index 9d57e2e9b..e518ce303 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h @@ -43,8 +43,8 @@ namespace bulkio { typedef typename PortTraits::DataTransferTraits::NativeDataType ScalarType; typedef std::complex ComplexType; - typedef redhawk::read_buffer scalar_buffer; - typedef redhawk::read_buffer complex_buffer; + typedef redhawk::read_buffer ScalarBuffer; + typedef redhawk::read_buffer ComplexBuffer; OutputStream(); @@ -93,7 +93,7 @@ namespace bulkio { * @param data The %read_buffer to write. * @param time The timestamp of the first sample. */ - void write(const scalar_buffer& data, const BULKIO::PrecisionUTCTime& time); + void write(const ScalarBuffer& data, const BULKIO::PrecisionUTCTime& time); /** * @brief Write scalar data to the stream. @@ -104,14 +104,14 @@ namespace bulkio { * Writes a buffer of data with multiple timestamps, breaking up the data * into chunks at the SampleTimestamp offsets. */ - void write(const scalar_buffer& data, const std::list& times); + void write(const ScalarBuffer& data, const std::list& times); /** * @brief Write complex data to the stream. * @param data The %read_buffer to write. * @param time The timestamp of the first sample. */ - void write(const complex_buffer& data, const BULKIO::PrecisionUTCTime& time); + void write(const ComplexBuffer& data, const BULKIO::PrecisionUTCTime& time); /** * @brief Write complex data to the stream. @@ -122,7 +122,7 @@ namespace bulkio { * Writes a buffer of data with multiple timestamps, breaking up the data * into chunks at the SampleTimestamp offsets. */ - void write(const complex_buffer& data, const std::list& times); + void write(const ComplexBuffer& data, const std::list& times); void write(const ScalarType* data, size_t count, const BULKIO::PrecisionUTCTime& time); void write(const ScalarType* data, size_t count, const std::list& times); From dd98355ff64f0fbf36a9faa8f3c0201b146126b8 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 11 Apr 2016 11:19:06 -0400 Subject: [PATCH 0098/1644] Implement all out stream writes in terms of read_buffer --- .../libsrc/cpp/bulkio_out_stream.cpp | 71 +++++-------------- 1 file changed, 18 insertions(+), 53 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp index 1435e4288..59bb8c4b5 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp @@ -20,6 +20,7 @@ #include "bulkio_out_stream.h" #include "bulkio_out_port.h" +#include "bulkio_p.h" using bulkio::OutputStream; @@ -100,7 +101,7 @@ class OutputStream::Impl { _sriUpdated = true; } - void write(const ScalarBuffer& data, const BULKIO::PrecisionUTCTime& time) + void write(const ScalarBuffer& data, const BULKIO::PrecisionUTCTime& time, bool shared) { if (_sriUpdated) { _port->pushSRI(_sri); @@ -110,16 +111,16 @@ class OutputStream::Impl { _send(reinterpret_cast(data.data()), data.size(), time, false); } - void write(const ComplexBuffer& data, const BULKIO::PrecisionUTCTime& time) + void write(const ComplexBuffer& data, const BULKIO::PrecisionUTCTime& time, bool shared) { if (_sri.mode == 0) { throw std::logic_error("stream mode is not complex"); } - write(ScalarBuffer::recast(data), time); + write(ScalarBuffer::recast(data), time, shared); } template - void write(const redhawk::read_buffer& data, const std::list& times) + void write(const redhawk::read_buffer& data, const std::list& times, bool shared) { std::list::const_iterator timestamp = times.begin(); if (timestamp == times.end()) { @@ -135,51 +136,11 @@ class OutputStream::Impl { } else { last = timestamp->offset; } - write(data.slice(first, last), when); + write(data.slice(first, last), when, shared); first = last; } } - template - void write(const Sample* data, size_t count, const std::list& times) - { - std::list::const_iterator timestamp = times.begin(); - if (timestamp == times.end()) { - throw std::logic_error("no timestamps given"); - } - - size_t first = 0; - while (first < count) { - size_t last = 0; - const BULKIO::PrecisionUTCTime& when = timestamp->time; - if (++timestamp == times.end()) { - last = count; - } else { - last = timestamp->offset; - } - const size_t pass = last-first; - write(data+first, pass, when); - first += pass; - } - } - - void write(const ScalarType* data, size_t count, const BULKIO::PrecisionUTCTime& time) - { - if (_sriUpdated) { - _port->pushSRI(_sri); - _sriUpdated = false; - } - _send(reinterpret_cast(data), count, time, false); - } - - void write(const ComplexType* data, size_t count, const BULKIO::PrecisionUTCTime& time) - { - if (_sri.mode == 0) { - throw std::logic_error("stream mode is not complex"); - } - write(reinterpret_cast(data), count*2, time); - } - void close() { // Send an empty packet with an end-of-stream marker; since there is no @@ -320,49 +281,53 @@ void OutputStream::eraseKeyword(const std::string& name) template void OutputStream::write(const ScalarBuffer& data, const BULKIO::PrecisionUTCTime& time) { - _impl->write(data, time); + _impl->write(data, time, true); } template void OutputStream::write(const ScalarBuffer& data, const std::list& times) { - _impl->write(data, times); + _impl->write(data, times, true); } template void OutputStream::write(const ComplexBuffer& data, const BULKIO::PrecisionUTCTime& time) { - _impl->write(data, time); + _impl->write(data, time, true); } template void OutputStream::write(const ComplexBuffer& data, const std::list& times) { - _impl->write(data, times); + _impl->write(data, times, true); } template void OutputStream::write(const ScalarType* data, size_t count, const BULKIO::PrecisionUTCTime& time) { - _impl->write(data, count, time); + ScalarBuffer buffer(const_cast(data), count, null_deleter()); + _impl->write(buffer, time, false); } template void OutputStream::write(const ScalarType* data, size_t count, const std::list& times) { - _impl->write(data, count, times); + ScalarBuffer buffer(const_cast(data), count, null_deleter()); + _impl->write(buffer, times, false); } template void OutputStream::write(const ComplexType* data, size_t count, const BULKIO::PrecisionUTCTime& time) { - _impl->write(data, count, time); + ComplexBuffer buffer(const_cast(data), count, null_deleter()); + _impl->write(buffer, time, false); } template void OutputStream::write(const ComplexType* data, size_t count, const std::list& times) { - _impl->write(data, count, times); + ComplexBuffer buffer(const_cast(data), count, null_deleter()); + _impl->write(buffer, times, false); } template From ca6c120e5f6b663ea81bcb77f2d6be1f721dd5d3 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 11 Apr 2016 11:43:06 -0400 Subject: [PATCH 0099/1644] Pass shared buffer from output stream to port --- .../libsrc/cpp/bulkio_out_port.cpp | 43 +++++++++++-------- bulkioInterfaces/libsrc/cpp/bulkio_out_port.h | 15 ++++--- .../libsrc/cpp/bulkio_out_stream.cpp | 3 +- 3 files changed, 35 insertions(+), 26 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp index 4d5c3aab4..6e65fb90b 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp @@ -643,16 +643,18 @@ namespace bulkio { * the last sub-packet, who uses the input EOS argument. */ template < typename PortTraits > - void OutPort< PortTraits>::_pushOversizedPacket( - const TransportType* buffer, - size_t size, - const BULKIO::PrecisionUTCTime& T, - bool EOS, - const std::string& streamID) + void OutPort< PortTraits>::_pushOversizedPacket(const ScalarBuffer& data, + const BULKIO::PrecisionUTCTime& T, + bool EOS, + const std::string& streamID, + bool shared) { // don't want to process while command information is coming in SCOPED_LOCK lock(this->updatingPortsLock); + const TransportType* buffer = reinterpret_cast(data.data()); + size_t size = data.size(); + // Multiply by some number < 1 to leave some margin for the CORBA header const size_t maxPayloadSize = (size_t) (bulkio::Const::MaxTransferBytes() * .9); @@ -731,10 +733,8 @@ namespace bulkio { bool EOS, const std::string& streamID) { - // Use const alias to start of buffer and defer to pointer-based push - const TransportType* buffer = reinterpret_cast(&data[0]); - const size_t size = data.size(); - pushPacket(buffer, size, T, EOS, streamID); + ScalarBuffer buffer(&data[0], data.size(), null_deleter()); + _pushOversizedPacket(buffer, T, EOS, streamID, false); } template < typename PortTraits > @@ -744,10 +744,8 @@ namespace bulkio { bool EOS, const std::string& streamID) { - // Use const alias to start of buffer and defer to pointer-based push - const TransportType* buffer = reinterpret_cast(&data[0]); - const size_t size = data.size(); - pushPacket(buffer, size, T, EOS, streamID); + ScalarBuffer buffer(const_cast(&data[0]), data.size(), null_deleter()); + _pushOversizedPacket(buffer, T, EOS, streamID, false); } template < typename PortTraits > @@ -756,12 +754,21 @@ namespace bulkio { size_t size, const BULKIO::PrecisionUTCTime& T, bool EOS, - const std::string& streamID) { + const std::string& streamID) + { + ScalarBuffer buffer((NativeType*)data, size, null_deleter()); + _pushOversizedPacket(buffer, T, EOS, streamID, false); + } + template < typename PortTraits > + void OutPort< PortTraits >::pushPacket(const ScalarBuffer& data, + const BULKIO::PrecisionUTCTime& T, + bool EOS, + const std::string& streamID, + bool shared) + { TRACE_ENTER(logger, "OutPort::pushPacket" ); - - _pushOversizedPacket(data, size, T, EOS, streamID); - + _pushOversizedPacket(data, T, EOS, streamID, shared); TRACE_EXIT(logger, "OutPort::pushPacket" ); } diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h index 31e1b4965..5839a7c77 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h @@ -438,6 +438,8 @@ namespace bulkio { // typedef OutputStream StreamType; + typedef redhawk::read_buffer ScalarBuffer; + // // OutPort Creates a uses port object for publishing data to the framework // @@ -508,6 +510,8 @@ namespace bulkio { */ void pushPacket( const DataBufferType & data, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID); + void pushPacket(const ScalarBuffer& data, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID, bool shared); + // Create a new stream based on a stream ID StreamType createStream(const std::string& streamID); // Create a new stream based on an SRI instance @@ -517,12 +521,11 @@ namespace bulkio { protected: using OutPortBase::logger; - void _pushOversizedPacket( - const TransportType* buffer, - size_t size, - const BULKIO::PrecisionUTCTime& T, - bool EOS, - const std::string& streamID); + void _pushOversizedPacket(const ScalarBuffer& buffer, + const BULKIO::PrecisionUTCTime& T, + bool EOS, + const std::string& streamID, + bool shared); }; // diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp index 59bb8c4b5..31cb812dd 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp @@ -107,8 +107,7 @@ class OutputStream::Impl { _port->pushSRI(_sri); _sriUpdated = false; } - // TODO: Enable buffer transfer - _send(reinterpret_cast(data.data()), data.size(), time, false); + _port->pushPacket(data, time, false, _streamID, shared); } void write(const ComplexBuffer& data, const BULKIO::PrecisionUTCTime& time, bool shared) From 060a199a0062b9410146e8483bd476afd4716b9f Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 11 Apr 2016 14:38:05 -0400 Subject: [PATCH 0100/1644] Start moving output connection management into a class that also handles the local/remote distinction --- .../libsrc/cpp/bulkio_out_port.cpp | 174 +++++++++--------- bulkioInterfaces/libsrc/cpp/bulkio_out_port.h | 38 ++-- 2 files changed, 106 insertions(+), 106 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp index 6e65fb90b..f0b537e5f 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp @@ -32,6 +32,74 @@ namespace bulkio { + template + class OutPortBase::RemoteConnection : public OutPortBase::PortConnection + { + public: + RemoteConnection(PortPtrType port) : + _port(PortType::_duplicate(port)) + { + } + + virtual void pushPacket(PushArgumentType data, const BULKIO::PrecisionUTCTime& T, + bool EOS, const std::string& streamID) + { + _port->pushPacket(data, T, EOS, streamID.c_str()); + } + + protected: + PortVarType _port; + }; + + template <> + void OutPortBase::RemoteConnection::pushPacket(PushArgumentType data, + const BULKIO::PrecisionUTCTime& /* unused */, + bool EOS, const std::string& streamID) + { + _port->pushPacket(data, EOS, streamID.c_str()); + } + + template + class OutPortBase::LocalConnection : public OutPortBase::PortConnection + { + public: + LocalConnection(LocalPortType* port) : + _port(port) + { + _port->_add_ref(); + } + + ~LocalConnection() + { + _port->_remove_ref(); + } + + virtual void pushPacket(PushArgumentType data, const BULKIO::PrecisionUTCTime& T, + bool EOS, const std::string& streamID) + { + _port->pushPacket(data, T, EOS, streamID.c_str()); + } + + protected: + LocalPortType* _port; + }; + + template <> + void OutPortBase::LocalConnection::pushPacket(PushArgumentType data, + const BULKIO::PrecisionUTCTime& T, + bool EOS, const std::string& streamID) + { + _port->pushPacket((bulkio::Char*)data, T, EOS, streamID.c_str()); + } + + template <> + void OutPortBase::LocalConnection::pushPacket(PushArgumentType data, + const BULKIO::PrecisionUTCTime& T, + bool EOS, const std::string& streamID) + { + _port->pushPacket((bulkio::Char*)data, T, EOS, streamID.c_str()); + } + /* OutPort Constructor @@ -160,28 +228,6 @@ namespace bulkio { return !portListed; } - template < typename PortTraits > - void OutPortBase< PortTraits >::_pushPacketToPort( - PortPtrType port, - PushArgumentType data, - const BULKIO::PrecisionUTCTime& T, - bool EOS, - const char* streamID) - { - port->pushPacket(data, T, EOS, streamID); - } - - template < typename PortTraits > - void OutPortBase< PortTraits >::_pushPacketToPort( - LocalPortType* port, - PushArgumentType data, - const BULKIO::PrecisionUTCTime& T, - bool EOS, - const char* streamID) - { - port->pushPacket(data, T, EOS, streamID); - } - template < typename PortTraits > void OutPortBase< PortTraits >::_sendEOS( PortPtrType port, @@ -243,12 +289,8 @@ namespace bulkio { } try { - typename LocalPortMap::iterator local = localPorts.find(port->second); - if (local != localPorts.end()) { - _pushPacketToPort(local->second, data, T, EOS, streamID.c_str()); - } else { - _pushPacketToPort(port->first, data, T, EOS, streamID.c_str()); - } + typename TransportMap::iterator transport = _transportMap.find(port->second); + transport->second->pushPacket(data, T, EOS, streamID); if ( stats.count(port->second) == 0 ) { stats.insert( std::make_pair(port->second, linkStatistics( name, sizeof(NativeType) ) ) ); } @@ -339,13 +381,7 @@ namespace bulkio { throw CF::Port::InvalidPort(1, "Unable to narrow"); } - LocalPortType* local_port = ossie::corba::getLocalServant(port); - if (local_port) { - LOG_DEBUG(logger, "Using local connection to port " << local_port->getName() - << " for connection " << connectionId); - local_port->_add_ref(); - localPorts[connectionId] = local_port; - } + _transportMap[connectionId] = _createConnection(port, connectionId); outConnections.push_back(std::make_pair(port, connectionId)); active = true; @@ -360,6 +396,22 @@ namespace bulkio { } + template < typename PortTraits > + typename OutPortBase< PortTraits >::PortConnection* + OutPortBase< PortTraits >::_createConnection(PortPtrType port, const std::string& connectionId) + { + LocalPortType* local_port = ossie::corba::getLocalServant(port); + if (local_port) { + LOG_DEBUG(logger, "Using local connection to port " << local_port->getName() + << " for connection " << connectionId); + return new LocalConnection(local_port); + } else { + return new RemoteConnection(port); + } + } + + + template < typename PortTraits > void OutPortBase< PortTraits >::disconnectPort(const char* connectionId) { @@ -398,11 +450,10 @@ namespace bulkio { stats.erase(ii->second); outConnections.erase(ii); - typename LocalPortMap::iterator local = localPorts.find(connectionId); - if (local != localPorts.end()) { - LocalPortType* local_port = local->second; - localPorts.erase(local); - local_port->_remove_ref(); + typename TransportMap::iterator transport = _transportMap.find(connectionId); + if (transport != _transportMap.end()) { + delete transport->second; + _transportMap.erase(transport); } break; } @@ -532,29 +583,6 @@ namespace bulkio { * Specializations of base class methods for dataXML ports */ - template <> - void OutPortBase< XMLPortTraits >::_pushPacketToPort( - BULKIO::dataXML_ptr port, - const char* data, - const BULKIO::PrecisionUTCTime& /*unused*/, - bool EOS, - const char* streamID) - { - port->pushPacket(data, EOS, streamID); - } - - template <> - void OutPortBase< XMLPortTraits >::_pushPacketToPort( - InPort* port, - const char* data, - const BULKIO::PrecisionUTCTime& T, - bool EOS, - const char* streamID) - { - port->pushPacket((bulkio::Char*)data, T, EOS, streamID); - } - - template <> void OutPortBase< XMLPortTraits >::_sendEOS( BULKIO::dataXML_ptr port, @@ -578,26 +606,6 @@ namespace bulkio { * Specializations of base class methods for dataFile ports */ - template <> - void OutPortBase< FilePortTraits >::_pushPacketToPort( - LocalPortType* port, - PushArgumentType data, - const BULKIO::PrecisionUTCTime& T, - bool EOS, - const char* streamID) - { - port->pushPacket((bulkio::Char*)data, T, EOS, streamID); - } - - template <> - void OutPortBase< FilePortTraits >::_sendEOS( - BULKIO::dataFile_ptr port, - const std::string& streamID) - { - port->pushPacket("", bulkio::time::utils::notSet(), true, streamID.c_str()); - } - - template <> size_t OutPortBase< FilePortTraits >::_dataLength(const char* /*unused*/) { diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h index 5839a7c77..1f5c2cf6c 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h @@ -302,8 +302,21 @@ namespace bulkio { // Lookup table for connections to input ports in the same process space // typedef InPort LocalPortType; - typedef std::map LocalPortMap; - LocalPortMap localPorts; + + class PortConnection + { + public: + virtual ~PortConnection() { }; + virtual void pushPacket(PushArgumentType data, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID) = 0; + }; + + class RemoteConnection; + class LocalConnection; + + virtual PortConnection* _createConnection(PortPtrType port, const std::string& connectionId); + + typedef std::map TransportMap; + TransportMap _transportMap; // // _pushSRI - method to push given SRI to a specific connections @@ -352,27 +365,6 @@ namespace bulkio { void _sendEOS(PortPtrType port, const std::string& streamID); - // - // Low-level push of data and metadata to the given port; enables XML and - // File specialization for consistent high-level pushPacket behavior - // - void _pushPacketToPort( - PortPtrType port, - PushArgumentType data, - const BULKIO::PrecisionUTCTime& T, - bool EOS, - const char* streamID); - - // - // In-process version of _pushPacketToPort, skips middleware - // - void _pushPacketToPort( - LocalPortType* port, - PushArgumentType data, - const BULKIO::PrecisionUTCTime& T, - bool EOS, - const char* streamID); - // // Returns the total number of elements of data in a pushPacket call, for // statistical tracking; enables XML and File specialization, which have From 442bcbaa933d92080c5b939920520b9d8001be0f Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 11 Apr 2016 14:56:22 -0400 Subject: [PATCH 0101/1644] Use the new connection data structures for iteration in pushSRI and pushPacket --- .../libsrc/cpp/bulkio_out_port.cpp | 98 ++++++++----------- bulkioInterfaces/libsrc/cpp/bulkio_out_port.h | 4 +- 2 files changed, 43 insertions(+), 59 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp index f0b537e5f..e7ed0a468 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp @@ -41,6 +41,11 @@ namespace bulkio { { } + virtual void pushSRI(BULKIO::StreamSRI& sri) + { + _port->pushSRI(sri); + } + virtual void pushPacket(PushArgumentType data, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID) { @@ -74,6 +79,11 @@ namespace bulkio { _port->_remove_ref(); } + virtual void pushSRI(BULKIO::StreamSRI& sri) + { + _port->pushSRI(sri); + } + virtual void pushPacket(PushArgumentType data, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID) { @@ -166,8 +176,6 @@ namespace bulkio { TRACE_ENTER(logger, "OutPort::pushSRI" ); - typename ConnectionsList::iterator i; - SCOPED_LOCK lock(updatingPortsLock); // don't want to process while command information is coming in std::string sid( H.streamID ); @@ -188,22 +196,25 @@ namespace bulkio { } if (active) { - for (i = outConnections.begin(); i != outConnections.end(); ++i) { - if (!_isStreamRoutedToConnection(sid, i->second)) { + typename TransportMap::iterator port; + + for (port = _transportMap.begin(); port != _transportMap.end(); ++port) { + if (!_isStreamRoutedToConnection(sid, port->first)) { continue; } - LOG_DEBUG(logger,"pushSRI - PORT:" << name << " CONNECTION:" << i->second << " SRI streamID:" << H.streamID << " Mode:" << H.mode << " XDELTA:" << 1.0/H.xdelta ); + LOG_DEBUG(logger,"pushSRI - PORT:" << name << " CONNECTION:" << port->first << " SRI streamID:" + << H.streamID << " Mode:" << H.mode << " XDELTA:" << 1.0/H.xdelta); try { - i->first->pushSRI(H); - sri_iter->second.connections.insert( i->second ); + port->second->pushSRI(H); + sri_iter->second.connections.insert(port->first); } catch(...) { - LOG_ERROR( logger, "PUSH-SRI FAILED, PORT/CONNECTION: " << name << "/" << i->second ); + LOG_ERROR(logger, "PUSH-SRI FAILED, PORT/CONNECTION: " << name << "/" << port->first); } } } - TRACE_EXIT(logger, "OutPort::pushSRI" ); + TRACE_EXIT(logger, "OutPort::pushSRI"); return; } @@ -276,27 +287,26 @@ namespace bulkio { const size_t length = _dataLength(data); if (active) { - typename ConnectionsList::iterator port; - for (port = outConnections.begin(); port != outConnections.end(); port++) { + typename TransportMap::iterator port; + for (port = _transportMap.begin(); port != _transportMap.end(); ++port) { // Check whether filtering is enabled and if this connection should // receive the stream - if (!_isStreamRoutedToConnection(streamID, port->second)) { + if (!_isStreamRoutedToConnection(streamID, port->first)) { continue; } - if ( sri_iter != currentSRIs.end() && sri_iter->second.connections.count( port->second ) == 0 ) { - this->_pushSRI( port, sri_iter->second ); + if ((sri_iter != currentSRIs.end()) && (sri_iter->second.connections.count(port->first) == 0)) { + this->_pushSRI(port, sri_iter->second); } try { - typename TransportMap::iterator transport = _transportMap.find(port->second); - transport->second->pushPacket(data, T, EOS, streamID); - if ( stats.count(port->second) == 0 ) { - stats.insert( std::make_pair(port->second, linkStatistics( name, sizeof(NativeType) ) ) ); + port->second->pushPacket(data, T, EOS, streamID); + if (stats.count(port->first) == 0 ) { + stats.insert( std::make_pair(port->first, linkStatistics( name, sizeof(NativeType) ) ) ); } - stats[port->second].update(length, 0, EOS, streamID); + stats[port->first].update(length, 0, EOS, streamID); } catch(...) { - LOG_ERROR( logger, "PUSH-PACKET FAILED, PORT/CONNECTION: " << name << "/" << port->second ); + LOG_ERROR( logger, "PUSH-PACKET FAILED, PORT/CONNECTION: " << name << "/" << port->first ); } } } @@ -469,46 +479,20 @@ namespace bulkio { } template < typename PortTraits > - void OutPortBase< PortTraits >::_pushSRI( typename ConnectionsList::iterator connPair, SriMapStruct &sri_ctx) + void OutPortBase< PortTraits >::_pushSRI(typename TransportMap::iterator connPair, SriMapStruct &sri_ctx) { - TRACE_ENTER(logger, "OutPort::_pushSRI" ); - - // assume parent will lock us... - if ( connPair != outConnections.end() ) { - - // push SRI over port instance - try { - connPair->first->pushSRI(sri_ctx.sri); - sri_ctx.connections.insert( connPair->second ); - LOG_TRACE( logger, "_pushSRI() connection_id/streamID " << connPair->second << "/" << sri_ctx.sri.streamID ); - } catch(...) { - LOG_ERROR( logger, "_pushSRI() PUSH-SRI FAILED, PORT/CONNECTION: " << name << "/" << connPair->second ); - } - } - - TRACE_EXIT(logger, "OutPort::_pushSRI" ); - return; - } - - - template < typename PortTraits > - void OutPortBase< PortTraits >::_pushSRI( const std::string &connectionId, SriMapStruct &sri_ctx) - { - TRACE_ENTER(logger, "OutPort::_pushSRI" ); - - typename ConnectionsList::iterator i; - - for ( i=outConnections.begin(); i != outConnections.end(); i++ ) { - if ( i->second == connectionId ) { - this->_pushSRI( i, sri_ctx ); - break; - } - } - TRACE_EXIT(logger, "OutPort::_pushSRI" ); - return; + TRACE_ENTER(logger, "OutPort::_pushSRI"); + // push SRI over port instance + try { + connPair->second->pushSRI(sri_ctx.sri); + sri_ctx.connections.insert(connPair->first); + LOG_TRACE(logger, "_pushSRI() connection_id/streamID " << connPair->first << "/" << sri_ctx.sri.streamID); + } catch(...) { + LOG_ERROR(logger, "_pushSRI() PUSH-SRI FAILED, PORT/CONNECTION: " << name << "/" << connPair->first); + } + TRACE_EXIT(logger, "OutPort::_pushSRI"); } - template < typename PortTraits > bulkio::SriMap OutPortBase< PortTraits >::getCurrentSRI() { diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h index 1f5c2cf6c..cd53eb245 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h @@ -307,6 +307,7 @@ namespace bulkio { { public: virtual ~PortConnection() { }; + virtual void pushSRI(const BULKIO::StreamSRI& sri); virtual void pushPacket(PushArgumentType data, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID) = 0; }; @@ -321,8 +322,7 @@ namespace bulkio { // // _pushSRI - method to push given SRI to a specific connections // - void _pushSRI( typename ConnectionsList::iterator connPair, SriMapStruct &sri_ctx); - void _pushSRI( const std::string &connectionId, SriMapStruct &sri_ctx); + void _pushSRI(typename TransportMap::iterator connPair, SriMapStruct &sri_ctx); LOGGER_PTR logger; std::vector filterTable; From 9ab0f029e416894f56c482c4d65789755caba646 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 11 Apr 2016 15:35:03 -0400 Subject: [PATCH 0102/1644] Remove old outConnections struct entirely and just use the transport map --- .../libsrc/cpp/bulkio_out_port.cpp | 126 ++++++++++-------- bulkioInterfaces/libsrc/cpp/bulkio_out_port.h | 15 +-- 2 files changed, 71 insertions(+), 70 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp index e7ed0a468..aed3c21b2 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp @@ -52,6 +52,16 @@ namespace bulkio { _port->pushPacket(data, T, EOS, streamID.c_str()); } + virtual void sendEOS(const std::string& streamID) + { + _port->pushPacket(PortSequenceType(), bulkio::time::utils::notSet(), true, streamID.c_str()); + } + + virtual PortPtrType objref() + { + return PortType::_duplicate(_port); + } + protected: PortVarType _port; }; @@ -64,6 +74,12 @@ namespace bulkio { _port->pushPacket(data, EOS, streamID.c_str()); } + template <> + void OutPortBase::RemoteConnection::sendEOS(const std::string& streamID) + { + _port->pushPacket("", true, streamID.c_str()); + } + template class OutPortBase::LocalConnection : public OutPortBase::PortConnection { @@ -90,6 +106,16 @@ namespace bulkio { _port->pushPacket(data, T, EOS, streamID.c_str()); } + virtual void sendEOS(const std::string& streamID) + { + _port->pushPacket(PortSequenceType(), bulkio::time::utils::notSet(), true, streamID.c_str()); + } + + virtual PortPtrType objref() + { + return _port->_this(); + } + protected: LocalPortType* _port; }; @@ -133,10 +159,6 @@ namespace bulkio { _disconnectCB = boost::shared_ptr< ConnectionEventListener >( disconnectCB, null_deleter() ); } - - recConnectionsRefresh = false; - recConnections.length(0); - LOG_DEBUG( logger, "bulkio::OutPort::CTOR port:" << name ); } @@ -158,9 +180,6 @@ namespace bulkio { _disconnectCB = boost::shared_ptr< ConnectionEventListener >( disconnectCB, null_deleter() ); } - recConnectionsRefresh = false; - recConnections.length(0); - } template < typename PortTraits > @@ -322,14 +341,15 @@ namespace bulkio { template < typename PortTraits > - BULKIO::UsesPortStatisticsSequence * OutPortBase< PortTraits >::statistics() + BULKIO::UsesPortStatisticsSequence* OutPortBase< PortTraits >::statistics() { SCOPED_LOCK lock(updatingPortsLock); BULKIO::UsesPortStatisticsSequence_var recStat = new BULKIO::UsesPortStatisticsSequence(); - recStat->length(outConnections.size()); - for (unsigned int i = 0; i < outConnections.size(); i++) { - recStat[i].connectionId = CORBA::string_dup(outConnections[i].second.c_str()); - recStat[i].statistics = stats[outConnections[i].second].retrieve(); + recStat->length(_transportMap.size()); + size_t index = 0; + for (typename _StatsMap::iterator ii = stats.begin(); ii != stats.end(); ++ii, ++index) { + recStat[index].connectionId = ii->first.c_str(); + recStat[index].statistics = ii->second.retrieve(); } return recStat._retn(); } @@ -338,20 +358,18 @@ namespace bulkio { BULKIO::PortUsageType OutPortBase< PortTraits >::state() { SCOPED_LOCK lock(updatingPortsLock); - if (outConnections.size() > 0) { - return BULKIO::ACTIVE; - } else { + if (_transportMap.empty()) { return BULKIO::IDLE; + } else { + return BULKIO::ACTIVE; } - - return BULKIO::BUSY; } template < typename PortTraits > void OutPortBase< PortTraits >::enableStats(bool enable) { - for (unsigned int i = 0; i < outConnections.size(); i++) { - stats[outConnections[i].second].setEnabled(enable); + for (typename _StatsMap::iterator ii = stats.begin(); ii != stats.end(); ++ii) { + ii->second.setEnabled(enable); } } @@ -360,16 +378,13 @@ namespace bulkio { ExtendedCF::UsesConnectionSequence * OutPortBase< PortTraits >::connections() { SCOPED_LOCK lock(updatingPortsLock); // don't want to process while command information is coming in - if (recConnectionsRefresh) { - recConnections.length(outConnections.size()); - for (unsigned int i = 0; i < outConnections.size(); i++) { - recConnections[i].connectionId = CORBA::string_dup(outConnections[i].second.c_str()); - recConnections[i].port = CORBA::Object::_duplicate(outConnections[i].first); - } - recConnectionsRefresh = false; + ExtendedCF::UsesConnectionSequence_var retVal = new ExtendedCF::UsesConnectionSequence(); + for (typename TransportMap::iterator port = _transportMap.begin(); port != _transportMap.end(); ++port) { + ExtendedCF::UsesConnection conn; + conn.connectionId = port->first.c_str(); + conn.port = port->second->objref(); + ossie::corba::push_back(retVal, conn); } - ExtendedCF::UsesConnectionSequence_var retVal = new ExtendedCF::UsesConnectionSequence(recConnections); - // NOTE: You must delete the object that this function returns! return retVal._retn(); } @@ -393,9 +408,7 @@ namespace bulkio { _transportMap[connectionId] = _createConnection(port, connectionId); - outConnections.push_back(std::make_pair(port, connectionId)); active = true; - recConnectionsRefresh = true; LOG_DEBUG( logger, "CONNECTION ESTABLISHED, PORT/CONNECTION_ID:" << name << "/" << connectionId ); @@ -430,22 +443,17 @@ namespace bulkio { SCOPED_LOCK lock(updatingPortsLock); // don't want to process while command information is coming in const std::string cid(connectionId); - for (typename ConnectionsList::iterator ii = outConnections.begin(); ii != outConnections.end(); ++ii) { - if (ii->second != connectionId) { - continue; - } - - typename OutPortSriMap::iterator cSRIs = currentSRIs.begin(); - - // send an EOS for every connection that's listed for this SRI - for (; cSRIs!=currentSRIs.end(); cSRIs++) { - std::string cSriSid(cSRIs->second.sri.streamID); + typename TransportMap::iterator port = _transportMap.find(connectionId); + if (port != _transportMap.end()) { + // Send an EOS for every connection that's listed for this SRI + for (typename OutPortSriMap::iterator cSRIs = currentSRIs.begin(); cSRIs!=currentSRIs.end(); cSRIs++) { + const std::string stream_id(cSRIs->second.sri.streamID); // Check if we have sent out sri/data to the connection - if ( cSRIs->second.connections.count( cid ) != 0 ) { - if (_isStreamRoutedToConnection(cSriSid, cid)) { + if (cSRIs->second.connections.count( cid ) != 0) { + if (_isStreamRoutedToConnection(stream_id, cid)) { try { - _sendEOS(ii->first, cSriSid); + port->second->sendEOS(stream_id); } catch (...) { // Ignore all exceptions; the receiver may be dead } @@ -456,24 +464,20 @@ namespace bulkio { cSRIs->second.connections.erase( cid ); } + LOG_DEBUG( logger, "DISCONNECT, PORT/CONNECTION: " << name << "/" << connectionId ); - stats.erase(ii->second); - outConnections.erase(ii); + stats.erase(port->first); + delete port->second; + _transportMap.erase(port); - typename TransportMap::iterator transport = _transportMap.find(connectionId); - if (transport != _transportMap.end()) { - delete transport->second; - _transportMap.erase(transport); + if (_transportMap.empty()) { + active = false; } - break; } - - if (outConnections.size() == 0) { - active = false; - } - recConnectionsRefresh = true; } - if (_disconnectCB) (*_disconnectCB)(connectionId); + if (_disconnectCB) { + (*_disconnectCB)(connectionId); + } TRACE_EXIT(logger, "OutPort::disconnectPort" ); } @@ -521,8 +525,14 @@ namespace bulkio { template < typename PortTraits > typename OutPortBase< PortTraits >::ConnectionsList OutPortBase< PortTraits >::getConnections() { - SCOPED_LOCK lock(updatingPortsLock); // restrict access till method completes - return outConnections; + SCOPED_LOCK lock(updatingPortsLock); // restrict access till method completes + ConnectionsList outConnections; + + for (typename TransportMap::iterator port = _transportMap.begin(); port != _transportMap.end(); ++port) { + outConnections.push_back(std::make_pair(port->second->objref(), port->first)); + } + + return outConnections; } diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h index cd53eb245..43f345f85 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h @@ -257,7 +257,7 @@ namespace bulkio { // Allow access to the port's connection list // virtual ConnectionsList __attribute__ ((deprecated)) _getConnections() { - return outConnections; + return getConnections(); } void setLogger( LOGGER_PTR newLogger ); @@ -277,17 +277,6 @@ namespace bulkio { OutPortSriMap currentSRIs __attribute__ ((deprecated)); protected: - // - // List of Port connections and connection identifiers - // - ConnectionsList outConnections; - - // - // List of connections returned by connections() method. Used to increase efficiency when there a large amount - // of connections for a port. - // - ExtendedCF::UsesConnectionSequence recConnections; - // // // @@ -309,6 +298,8 @@ namespace bulkio { virtual ~PortConnection() { }; virtual void pushSRI(const BULKIO::StreamSRI& sri); virtual void pushPacket(PushArgumentType data, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID) = 0; + virtual void sendEOS(const std::string& streamID) = 0; + virtual PortPtrType objref() = 0; }; class RemoteConnection; From b9b6e5bfa15aec9eb6ac133f0e77d2081a6e7c75 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 11 Apr 2016 15:41:11 -0400 Subject: [PATCH 0103/1644] Fix signature of pushSRI for remote and local connections --- bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp | 4 ++-- bulkioInterfaces/libsrc/cpp/bulkio_out_port.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp index aed3c21b2..fb82620f4 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp @@ -41,7 +41,7 @@ namespace bulkio { { } - virtual void pushSRI(BULKIO::StreamSRI& sri) + virtual void pushSRI(const BULKIO::StreamSRI& sri) { _port->pushSRI(sri); } @@ -95,7 +95,7 @@ namespace bulkio { _port->_remove_ref(); } - virtual void pushSRI(BULKIO::StreamSRI& sri) + virtual void pushSRI(const BULKIO::StreamSRI& sri) { _port->pushSRI(sri); } diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h index 43f345f85..ee1032b09 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h @@ -296,7 +296,7 @@ namespace bulkio { { public: virtual ~PortConnection() { }; - virtual void pushSRI(const BULKIO::StreamSRI& sri); + virtual void pushSRI(const BULKIO::StreamSRI& sri) = 0; virtual void pushPacket(PushArgumentType data, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID) = 0; virtual void sendEOS(const std::string& streamID) = 0; virtual PortPtrType objref() = 0; From bb2a677d6c3c84bb7cabb8f168a740c2825a2aa2 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 11 Apr 2016 16:10:07 -0400 Subject: [PATCH 0104/1644] Make linkStatistics name argument const --- bulkioInterfaces/libsrc/cpp/bulkio.cpp | 2 +- bulkioInterfaces/libsrc/cpp/bulkio_base.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio.cpp b/bulkioInterfaces/libsrc/cpp/bulkio.cpp index cd9be35fb..20ae2ab66 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio.cpp @@ -99,7 +99,7 @@ namespace bulkio { } - linkStatistics::linkStatistics( std::string &portName , const int nbytes ): + linkStatistics::linkStatistics(const std::string &portName, const int nbytes): portName(portName), nbytes(nbytes) { diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_base.h b/bulkioInterfaces/libsrc/cpp/bulkio_base.h index a96bcac97..05f21e736 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_base.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_base.h @@ -162,7 +162,7 @@ namespace bulkio { { public: - linkStatistics( std::string &portName, const int nbytes=1 ); + linkStatistics(const std::string& portName, const int nbytes=1); linkStatistics(); From 8dbe88a3dc4dd68e9c4f17fd5f25bc7015326ef4 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 11 Apr 2016 16:10:24 -0400 Subject: [PATCH 0105/1644] Fold statistical tracking into PortConnection class --- .../libsrc/cpp/bulkio_out_port.cpp | 189 +++++++++--------- bulkioInterfaces/libsrc/cpp/bulkio_out_port.h | 38 +--- 2 files changed, 92 insertions(+), 135 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp index fb82620f4..30d9a8391 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp @@ -33,28 +33,80 @@ namespace bulkio { template - class OutPortBase::RemoteConnection : public OutPortBase::PortConnection + class OutPortBase::PortConnection { public: - RemoteConnection(PortPtrType port) : - _port(PortType::_duplicate(port)) + PortConnection(const std::string& name) : + stats(name, sizeof(NativeType)) { } - virtual void pushSRI(const BULKIO::StreamSRI& sri) + virtual ~PortConnection() { }; + + virtual void pushSRI(const BULKIO::StreamSRI& sri) = 0; + + virtual void pushPacket(PushArgumentType data, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID) { - _port->pushSRI(sri); + this->_pushPacket(data, T, EOS, streamID); + stats.update(this->_dataLength(data), 0, EOS, streamID); } - virtual void pushPacket(PushArgumentType data, const BULKIO::PrecisionUTCTime& T, - bool EOS, const std::string& streamID) + // + // Sends an end-of-stream packet for the given stream to a particular port, + // for use when disconnecting; enables XML and File specialization for + // consistent end-of-stream behavior + // + void sendEOS(const std::string& streamID) + { + this->_pushPacket(PortSequenceType(), bulkio::time::utils::notSet(), true, streamID); + } + + virtual PortPtrType objref() = 0; + + linkStatistics stats; + + protected: + virtual void _pushPacket(PushArgumentType data, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID) = 0; + + // + // Returns the total number of elements of data in a pushPacket call, for + // statistical tracking; enables XML and File specialization, which have + // different notions of size + // + size_t _dataLength(PushArgumentType data) + { + return data.length(); + } + }; + + template <> + size_t OutPortBase< XMLPortTraits >::PortConnection::_dataLength(const char* data) + { + if (!data) { + return 0; + } + return strlen(data); + } + + template <> + size_t OutPortBase< FilePortTraits >::PortConnection::_dataLength(const char* /*unused*/) + { + return 1; + } + + template + class OutPortBase::RemoteConnection : public OutPortBase::PortConnection + { + public: + RemoteConnection(const std::string& name, PortPtrType port) : + OutPortBase::PortConnection(name), + _port(PortType::_duplicate(port)) { - _port->pushPacket(data, T, EOS, streamID.c_str()); } - virtual void sendEOS(const std::string& streamID) + virtual void pushSRI(const BULKIO::StreamSRI& sri) { - _port->pushPacket(PortSequenceType(), bulkio::time::utils::notSet(), true, streamID.c_str()); + _port->pushSRI(sri); } virtual PortPtrType objref() @@ -63,28 +115,29 @@ namespace bulkio { } protected: + virtual void _pushPacket(PushArgumentType data, const BULKIO::PrecisionUTCTime& T, + bool EOS, const std::string& streamID) + { + _port->pushPacket(data, T, EOS, streamID.c_str()); + } + PortVarType _port; }; template <> - void OutPortBase::RemoteConnection::pushPacket(PushArgumentType data, - const BULKIO::PrecisionUTCTime& /* unused */, - bool EOS, const std::string& streamID) + void OutPortBase::RemoteConnection::_pushPacket(PushArgumentType data, + const BULKIO::PrecisionUTCTime& /* unused */, + bool EOS, const std::string& streamID) { _port->pushPacket(data, EOS, streamID.c_str()); } - template <> - void OutPortBase::RemoteConnection::sendEOS(const std::string& streamID) - { - _port->pushPacket("", true, streamID.c_str()); - } - template class OutPortBase::LocalConnection : public OutPortBase::PortConnection { public: - LocalConnection(LocalPortType* port) : + LocalConnection(const std::string& name, LocalPortType* port) : + OutPortBase::PortConnection(name), _port(port) { _port->_add_ref(); @@ -100,28 +153,23 @@ namespace bulkio { _port->pushSRI(sri); } - virtual void pushPacket(PushArgumentType data, const BULKIO::PrecisionUTCTime& T, - bool EOS, const std::string& streamID) - { - _port->pushPacket(data, T, EOS, streamID.c_str()); - } - - virtual void sendEOS(const std::string& streamID) - { - _port->pushPacket(PortSequenceType(), bulkio::time::utils::notSet(), true, streamID.c_str()); - } - virtual PortPtrType objref() { return _port->_this(); } protected: + virtual void _pushPacket(PushArgumentType data, const BULKIO::PrecisionUTCTime& T, + bool EOS, const std::string& streamID) + { + _port->pushPacket(data, T, EOS, streamID.c_str()); + } + LocalPortType* _port; }; template <> - void OutPortBase::LocalConnection::pushPacket(PushArgumentType data, + void OutPortBase::LocalConnection::_pushPacket(PushArgumentType data, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID) { @@ -129,7 +177,7 @@ namespace bulkio { } template <> - void OutPortBase::LocalConnection::pushPacket(PushArgumentType data, + void OutPortBase::LocalConnection::_pushPacket(PushArgumentType data, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID) { @@ -258,21 +306,6 @@ namespace bulkio { return !portListed; } - template < typename PortTraits > - void OutPortBase< PortTraits >::_sendEOS( - PortPtrType port, - const std::string& streamID) - { - port->pushPacket(PortSequenceType(), bulkio::time::utils::notSet(), true, streamID.c_str()); - } - - - template < typename PortTraits > - size_t OutPortBase< PortTraits >::_dataLength(PushArgumentType data) - { - return data.length(); - } - template < typename PortTraits > void OutPortBase< PortTraits >::_pushSinglePacket( @@ -303,8 +336,6 @@ namespace bulkio { sri_iter = currentSRIs.insert(std::make_pair(streamID, sri_ctx)).first; } - const size_t length = _dataLength(data); - if (active) { typename TransportMap::iterator port; for (port = _transportMap.begin(); port != _transportMap.end(); ++port) { @@ -320,10 +351,6 @@ namespace bulkio { try { port->second->pushPacket(data, T, EOS, streamID); - if (stats.count(port->first) == 0 ) { - stats.insert( std::make_pair(port->first, linkStatistics( name, sizeof(NativeType) ) ) ); - } - stats[port->first].update(length, 0, EOS, streamID); } catch(...) { LOG_ERROR( logger, "PUSH-PACKET FAILED, PORT/CONNECTION: " << name << "/" << port->first ); } @@ -345,11 +372,11 @@ namespace bulkio { { SCOPED_LOCK lock(updatingPortsLock); BULKIO::UsesPortStatisticsSequence_var recStat = new BULKIO::UsesPortStatisticsSequence(); - recStat->length(_transportMap.size()); - size_t index = 0; - for (typename _StatsMap::iterator ii = stats.begin(); ii != stats.end(); ++ii, ++index) { - recStat[index].connectionId = ii->first.c_str(); - recStat[index].statistics = ii->second.retrieve(); + for (typename TransportMap::iterator port = _transportMap.begin(); port != _transportMap.end(); ++port) { + BULKIO::UsesPortStatistics stat; + stat.connectionId = port->first.c_str(); + stat.statistics = port->second->stats.retrieve(); + ossie::corba::push_back(recStat, stat); } return recStat._retn(); } @@ -368,8 +395,9 @@ namespace bulkio { template < typename PortTraits > void OutPortBase< PortTraits >::enableStats(bool enable) { - for (typename _StatsMap::iterator ii = stats.begin(); ii != stats.end(); ++ii) { - ii->second.setEnabled(enable); + SCOPED_LOCK lock(updatingPortsLock); + for (typename TransportMap::iterator port = _transportMap.begin(); port != _transportMap.end(); ++port) { + port->second->stats.setEnabled(enable); } } @@ -427,9 +455,9 @@ namespace bulkio { if (local_port) { LOG_DEBUG(logger, "Using local connection to port " << local_port->getName() << " for connection " << connectionId); - return new LocalConnection(local_port); + return new LocalConnection(name, local_port); } else { - return new RemoteConnection(port); + return new RemoteConnection(name, port); } } @@ -466,7 +494,6 @@ namespace bulkio { } LOG_DEBUG( logger, "DISCONNECT, PORT/CONNECTION: " << name << "/" << connectionId ); - stats.erase(port->first); delete port->second; _transportMap.erase(port); @@ -573,40 +600,6 @@ namespace bulkio { } - /* - * Specializations of base class methods for dataXML ports - */ - - template <> - void OutPortBase< XMLPortTraits >::_sendEOS( - BULKIO::dataXML_ptr port, - const std::string& streamID) - { - port->pushPacket("", true, streamID.c_str()); - } - - - template <> - size_t OutPortBase< XMLPortTraits >::_dataLength(const char* data) - { - if (!data) { - return 0; - } - return strlen(data); - } - - - /* - * Specializations of base class methods for dataFile ports - */ - - template <> - size_t OutPortBase< FilePortTraits >::_dataLength(const char* /*unused*/) - { - return 1; - } - - /* OutPort Constructor diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h index ee1032b09..aa23261a7 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h @@ -264,13 +264,6 @@ namespace bulkio { std::string getRepid () const; - protected: - - - // Map of stream ids and statistic object - typedef typename std::map _StatsMap; - - public: // // List of SRIs sent out by this port // @@ -282,26 +275,12 @@ namespace bulkio { // bool recConnectionsRefresh; - // - // Set of statistical collector objects for each stream id - // - _StatsMap stats; - // // Lookup table for connections to input ports in the same process space // typedef InPort LocalPortType; - class PortConnection - { - public: - virtual ~PortConnection() { }; - virtual void pushSRI(const BULKIO::StreamSRI& sri) = 0; - virtual void pushPacket(PushArgumentType data, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID) = 0; - virtual void sendEOS(const std::string& streamID) = 0; - virtual PortPtrType objref() = 0; - }; - + class PortConnection; class RemoteConnection; class LocalConnection; @@ -347,21 +326,6 @@ namespace bulkio { const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID); - - // - // Sends an end-of-stream packet for the given stream to a particular port, - // for use when disconnecting; enables XML and File specialization for - // consistent end-of-stream behavior - // - void _sendEOS(PortPtrType port, - const std::string& streamID); - - // - // Returns the total number of elements of data in a pushPacket call, for - // statistical tracking; enables XML and File specialization, which have - // different notions of size - // - size_t _dataLength(PushArgumentType data); }; From df40c1bc28490c102277d22a3964b4ca636fa007 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 12 Apr 2016 10:36:10 -0400 Subject: [PATCH 0106/1644] Implement chunking of pushes in a RemoteConnection subclass, rather than at the output port pushPacket level. This allows local connections to skip the chunking step. --- .../libsrc/cpp/bulkio_out_port.cpp | 204 ++++++++++-------- bulkioInterfaces/libsrc/cpp/bulkio_out_port.h | 13 +- 2 files changed, 125 insertions(+), 92 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp index 30d9a8391..d2d7c6994 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp @@ -30,7 +30,7 @@ // public access that's deprecated, not the member itself #pragma GCC diagnostic ignored "-Wdeprecated-declarations" -namespace bulkio { +namespace bulkio { template class OutPortBase::PortConnection @@ -45,8 +45,12 @@ namespace bulkio { virtual void pushSRI(const BULKIO::StreamSRI& sri) = 0; - virtual void pushPacket(PushArgumentType data, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID) + virtual void pushPacket(PushArgumentType data, + const BULKIO::PrecisionUTCTime& T, + bool EOS, + const BULKIO::StreamSRI& sri) { + const std::string streamID(sri.streamID); this->_pushPacket(data, T, EOS, streamID); stats.update(this->_dataLength(data), 0, EOS, streamID); } @@ -66,7 +70,10 @@ namespace bulkio { linkStatistics stats; protected: - virtual void _pushPacket(PushArgumentType data, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID) = 0; + virtual void _pushPacket(PushArgumentType data, + const BULKIO::PrecisionUTCTime& T, + bool EOS, + const std::string& streamID) = 0; // // Returns the total number of elements of data in a pushPacket call, for @@ -115,8 +122,10 @@ namespace bulkio { } protected: - virtual void _pushPacket(PushArgumentType data, const BULKIO::PrecisionUTCTime& T, - bool EOS, const std::string& streamID) + virtual void _pushPacket(PushArgumentType data, + const BULKIO::PrecisionUTCTime& T, + bool EOS, + const std::string& streamID) { _port->pushPacket(data, T, EOS, streamID.c_str()); } @@ -127,7 +136,8 @@ namespace bulkio { template <> void OutPortBase::RemoteConnection::_pushPacket(PushArgumentType data, const BULKIO::PrecisionUTCTime& /* unused */, - bool EOS, const std::string& streamID) + bool EOS, + const std::string& streamID) { _port->pushPacket(data, EOS, streamID.c_str()); } @@ -159,8 +169,10 @@ namespace bulkio { } protected: - virtual void _pushPacket(PushArgumentType data, const BULKIO::PrecisionUTCTime& T, - bool EOS, const std::string& streamID) + virtual void _pushPacket(PushArgumentType data, + const BULKIO::PrecisionUTCTime& T, + bool EOS, + const std::string& streamID) { _port->pushPacket(data, T, EOS, streamID.c_str()); } @@ -170,16 +182,18 @@ namespace bulkio { template <> void OutPortBase::LocalConnection::_pushPacket(PushArgumentType data, - const BULKIO::PrecisionUTCTime& T, - bool EOS, const std::string& streamID) + const BULKIO::PrecisionUTCTime& T, + bool EOS, + const std::string& streamID) { _port->pushPacket((bulkio::Char*)data, T, EOS, streamID.c_str()); } template <> void OutPortBase::LocalConnection::_pushPacket(PushArgumentType data, - const BULKIO::PrecisionUTCTime& T, - bool EOS, const std::string& streamID) + const BULKIO::PrecisionUTCTime& T, + bool EOS, + const std::string& streamID) { _port->pushPacket((bulkio::Char*)data, T, EOS, streamID.c_str()); } @@ -345,12 +359,12 @@ namespace bulkio { continue; } - if ((sri_iter != currentSRIs.end()) && (sri_iter->second.connections.count(port->first) == 0)) { + if (sri_iter->second.connections.count(port->first) == 0) { this->_pushSRI(port, sri_iter->second); } try { - port->second->pushPacket(data, T, EOS, streamID); + port->second->pushPacket(data, T, EOS, sri_iter->second.sri); } catch(...) { LOG_ERROR( logger, "PUSH-PACKET FAILED, PORT/CONNECTION: " << name << "/" << port->first ); } @@ -434,7 +448,14 @@ namespace bulkio { throw CF::Port::InvalidPort(1, "Unable to narrow"); } - _transportMap[connectionId] = _createConnection(port, connectionId); + LocalPortType* local_port = ossie::corba::getLocalServant(port); + if (local_port) { + LOG_DEBUG(logger, "Using local connection to port " << local_port->getName() + << " for connection " << connectionId); + _transportMap[connectionId] = _createLocalConnection(local_port, connectionId); + } else { + _transportMap[connectionId] = _createRemoteConnection(port, connectionId); + } active = true; @@ -448,21 +469,21 @@ namespace bulkio { template < typename PortTraits > - typename OutPortBase< PortTraits >::PortConnection* - OutPortBase< PortTraits >::_createConnection(PortPtrType port, const std::string& connectionId) + typename OutPortBase< PortTraits >::RemoteConnection* + OutPortBase< PortTraits >::_createRemoteConnection(PortPtrType port, const std::string& connectionId) { - LocalPortType* local_port = ossie::corba::getLocalServant(port); - if (local_port) { - LOG_DEBUG(logger, "Using local connection to port " << local_port->getName() - << " for connection " << connectionId); - return new LocalConnection(name, local_port); - } else { - return new RemoteConnection(name, port); - } + return new RemoteConnection(name, port); } - + template < typename PortTraits > + typename OutPortBase< PortTraits >::LocalConnection* + OutPortBase< PortTraits >::_createLocalConnection(LocalPortType* port, const std::string& connectionId) + { + return new LocalConnection(name, port); + } + + template < typename PortTraits > void OutPortBase< PortTraits >::disconnectPort(const char* connectionId) { @@ -631,38 +652,36 @@ namespace bulkio { } - /* - * Push a packet whose payload cannot fit within the CORBA limit. - * The packet is broken down into sub-packets and sent via multiple pushPacket - * calls. The EOS is set to false for all of the sub-packets, except for - * the last sub-packet, who uses the input EOS argument. - */ - template < typename PortTraits > - void OutPort< PortTraits>::_pushOversizedPacket(const ScalarBuffer& data, - const BULKIO::PrecisionUTCTime& T, - bool EOS, - const std::string& streamID, - bool shared) + template + class OutPort::ChunkingConnection : public OutPortBase::RemoteConnection { - // don't want to process while command information is coming in - SCOPED_LOCK lock(this->updatingPortsLock); - - const TransportType* buffer = reinterpret_cast(data.data()); - size_t size = data.size(); - + public: + ChunkingConnection(const std::string& name, PortPtrType port) : + OutPortBase::RemoteConnection(name, port) + { // Multiply by some number < 1 to leave some margin for the CORBA header const size_t maxPayloadSize = (size_t) (bulkio::Const::MaxTransferBytes() * .9); - - size_t maxSamplesPerPush = maxPayloadSize/sizeof(TransportType); - typename OutPortSriMap::iterator sri_iter; - sri_iter = currentSRIs.find( streamID ); - // Determine xdelta for this streamID to be used for time increment for subpackets - double xdelta = 0.0; - size_t itemSize = 1; - if ( sri_iter != currentSRIs.end() ) { - xdelta = sri_iter->second.sri.xdelta; - itemSize = sri_iter->second.sri.mode?2:1; + maxSamplesPerPush = maxPayloadSize/sizeof(TransportType); + // Make sure maxSamplesPerPush is even so that complex data case is + // handled properly + if (maxSamplesPerPush%2 != 0){ + maxSamplesPerPush--; } + } + + /* + * Push a packet whose payload may not fit within the CORBA limit. The + * packet is broken down into sub-packets and sent via multiple pushPacket + * calls. The EOS is set to false for all of the sub-packets, except for + * the last sub-packet, which uses the input EOS argument. + */ + virtual void pushPacket(const PortSequenceType& data, + const BULKIO::PrecisionUTCTime& T, + bool EOS, + const BULKIO::StreamSRI& sri) + { + double xdelta = sri.xdelta; + size_t itemSize = sri.mode?2:1; if ( sri_iter != currentSRIs.end() ) { if (sri_iter->second.sri.subsize == 0) { @@ -686,38 +705,50 @@ namespace bulkio { // Always do at least one push (may be empty), ensuring that all samples // are pushed - size_t samplesRemaining = size; + const TransportType* buffer = data.get_buffer(); + size_t samplesRemaining = data.length(); // Initialize time of first subpacket BULKIO::PrecisionUTCTime packetTime = T; do { - // Don't send more samples than are remaining - const size_t pushSize = std::min(samplesRemaining, maxSamplesPerPush); - samplesRemaining -= pushSize; - - // Send end-of-stream as false for all sub-packets except for the - // last one (when there are no samples remaining after this push), - // which gets the input EOS. - bool packetEOS = false; - if (samplesRemaining == 0) { - packetEOS = EOS; - } + // Don't send more samples than are remaining + const size_t pushSize = std::min(samplesRemaining, maxSamplesPerPush); + samplesRemaining -= pushSize; + + // Send end-of-stream as false for all sub-packets except for the + // last one (when there are no samples remaining after this push), + // which gets the input EOS. + bool packetEOS = false; + if (samplesRemaining == 0) { + packetEOS = EOS; + } - // Wrap a non-owning CORBA sequence (last argument is whether to free - // the buffer on destruction) around this sub-packet's data - const PortSequenceType subPacket(pushSize, pushSize, const_cast(buffer), false); - LOG_TRACE(logger,"_pushOversizedPacket calling pushPacket with pushSize " << pushSize << " and packetTime twsec: " << packetTime.twsec << " tfsec: " << packetTime.tfsec) - this->_pushPacketLocked(subPacket, packetTime, packetEOS, streamID); + // Wrap a non-owning CORBA sequence (last argument is whether to free + // the buffer on destruction) around this sub-packet's data + const PortSequenceType subPacket(pushSize, pushSize, const_cast(buffer), false); + OutPortBase::RemoteConnection::pushPacket(subPacket, packetTime, packetEOS, sri); - // Synthesize the next packet timestamp - if (packetTime.tcstatus == BULKIO::TCS_VALID) { - packetTime += (pushSize/itemSize)* xdelta; - } + // Synthesize the next packet timestamp + if (packetTime.tcstatus == BULKIO::TCS_VALID) { + packetTime += (pushSize/itemSize)* xdelta; + } - // Advance buffer to next sub-packet boundary - buffer += pushSize; + // Advance buffer to next sub-packet boundary + buffer += pushSize; } while (samplesRemaining > 0); + } + + private: + size_t maxSamplesPerPush; + }; + + + template + typename OutPortBase::RemoteConnection* + OutPort::_createRemoteConnection(PortPtrType port, const std::string& connectionId) + { + return new ChunkingConnection(this->name, port); } @@ -728,8 +759,8 @@ namespace bulkio { bool EOS, const std::string& streamID) { - ScalarBuffer buffer(&data[0], data.size(), null_deleter()); - _pushOversizedPacket(buffer, T, EOS, streamID, false); + const PortSequenceType buffer(data.size(), data.size(), reinterpret_cast(&data[0]), false); + this->_pushPacketLocked(buffer, T, EOS, streamID); } template < typename PortTraits > @@ -739,8 +770,9 @@ namespace bulkio { bool EOS, const std::string& streamID) { - ScalarBuffer buffer(const_cast(&data[0]), data.size(), null_deleter()); - _pushOversizedPacket(buffer, T, EOS, streamID, false); + const TransportType* ptr = reinterpret_cast(&data[0]); + const PortSequenceType buffer(data.size(), data.size(), const_cast(ptr), false); + this->_pushPacketLocked(buffer, T, EOS, streamID); } template < typename PortTraits > @@ -751,8 +783,8 @@ namespace bulkio { bool EOS, const std::string& streamID) { - ScalarBuffer buffer((NativeType*)data, size, null_deleter()); - _pushOversizedPacket(buffer, T, EOS, streamID, false); + const PortSequenceType buffer(size, size, const_cast(data), false); + this->_pushPacketLocked(buffer, T, EOS, streamID); } template < typename PortTraits > @@ -762,9 +794,9 @@ namespace bulkio { const std::string& streamID, bool shared) { - TRACE_ENTER(logger, "OutPort::pushPacket" ); - _pushOversizedPacket(data, T, EOS, streamID, shared); - TRACE_EXIT(logger, "OutPort::pushPacket" ); + const TransportType* ptr = reinterpret_cast(data.data()); + const PortSequenceType buffer(data.size(), data.size(), const_cast(ptr), false); + this->_pushPacketLocked(buffer, T, EOS, streamID); } template < typename PortTraits > diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h index aa23261a7..9639e9059 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h @@ -284,7 +284,8 @@ namespace bulkio { class RemoteConnection; class LocalConnection; - virtual PortConnection* _createConnection(PortPtrType port, const std::string& connectionId); + virtual RemoteConnection* _createRemoteConnection(PortPtrType port, const std::string& connectionId); + virtual LocalConnection* _createLocalConnection(LocalPortType* port, const std::string& connectionId); typedef std::map TransportMap; TransportMap _transportMap; @@ -467,12 +468,12 @@ namespace bulkio { protected: using OutPortBase::logger; + typedef typename OutPortBase::PortPtrType PortPtrType; + typedef typename OutPortBase::RemoteConnection RemoteConnection; - void _pushOversizedPacket(const ScalarBuffer& buffer, - const BULKIO::PrecisionUTCTime& T, - bool EOS, - const std::string& streamID, - bool shared); + class ChunkingConnection; + + virtual RemoteConnection* _createRemoteConnection(PortPtrType port, const std::string& connectionId); }; // From 6729cb60aeb85e4066806c725906eac4d518dcfc Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 12 Apr 2016 12:17:07 -0400 Subject: [PATCH 0107/1644] Move connection class templates to a separate file, still included in bulkio_out_port.cpp and not installed --- bulkioInterfaces/libsrc/Makefile.am | 3 +- .../libsrc/cpp/bulkio_connection.hpp | 261 +++++++++++++++++ .../libsrc/cpp/bulkio_out_port.cpp | 273 +----------------- bulkioInterfaces/libsrc/cpp/bulkio_out_port.h | 19 +- 4 files changed, 279 insertions(+), 277 deletions(-) create mode 100644 bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp diff --git a/bulkioInterfaces/libsrc/Makefile.am b/bulkioInterfaces/libsrc/Makefile.am index cfbb6fb17..af6f1cace 100644 --- a/bulkioInterfaces/libsrc/Makefile.am +++ b/bulkioInterfaces/libsrc/Makefile.am @@ -45,7 +45,8 @@ libbulkio_@BULKIO_API_VERSION@_la_SOURCES = \ cpp/bulkio_time_helpers.cpp \ cpp/bulkio_time_operators.cpp \ cpp/bulkio_datablock.cpp \ - cpp/bulkio_p.h + cpp/bulkio_p.h \ + cpp/bulkio_connection.hpp ## Define the list of public header files and their install location. library_includedir = $(includedir)/bulkio diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp b/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp new file mode 100644 index 000000000..317b9331a --- /dev/null +++ b/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp @@ -0,0 +1,261 @@ +namespace bulkio { + + template + class PortConnection + { + public: + typedef typename PortTraits::PushType PushArgumentType; + typedef typename PortTraits::SequenceType PortSequenceType; + typedef typename PortTraits::PortType::_ptr_type PortPtrType; + typedef typename PortTraits::NativeType NativeType; + + PortConnection(const std::string& name) : + stats(name, sizeof(NativeType)) + { + } + + virtual ~PortConnection() { }; + + virtual void pushSRI(const BULKIO::StreamSRI& sri) = 0; + + virtual void pushPacket(PushArgumentType data, + const BULKIO::PrecisionUTCTime& T, + bool EOS, + const BULKIO::StreamSRI& sri) + { + const std::string streamID(sri.streamID); + this->_pushPacket(data, T, EOS, streamID); + stats.update(this->_dataLength(data), 0, EOS, streamID); + } + + // + // Sends an end-of-stream packet for the given stream to a particular port, + // for use when disconnecting; enables XML and File specialization for + // consistent end-of-stream behavior + // + void sendEOS(const std::string& streamID) + { + this->_pushPacket(PortSequenceType(), bulkio::time::utils::notSet(), true, streamID); + } + + virtual PortPtrType objref() = 0; + + linkStatistics stats; + + protected: + virtual void _pushPacket(PushArgumentType data, + const BULKIO::PrecisionUTCTime& T, + bool EOS, + const std::string& streamID) = 0; + + // + // Returns the total number of elements of data in a pushPacket call, for + // statistical tracking; enables XML and File specialization, which have + // different notions of size + // + size_t _dataLength(PushArgumentType data) + { + return data.length(); + } + }; + + template <> + size_t PortConnection::_dataLength(const char* data) + { + if (!data) { + return 0; + } + return strlen(data); + } + + template <> + size_t PortConnection::_dataLength(const char* /*unused*/) + { + return 1; + } + + template + class RemoteConnection : public PortConnection + { + public: + typedef typename PortTraits::PortVarType PortVarType; + typedef typename PortTraits::PortType PortType; + typedef typename PortType::_ptr_type PortPtrType; + typedef typename PortTraits::PushType PushArgumentType; + + RemoteConnection(const std::string& name, PortPtrType port) : + PortConnection(name), + _port(PortType::_duplicate(port)) + { + } + + virtual void pushSRI(const BULKIO::StreamSRI& sri) + { + _port->pushSRI(sri); + } + + virtual PortPtrType objref() + { + return PortType::_duplicate(_port); + } + + protected: + virtual void _pushPacket(PushArgumentType data, + const BULKIO::PrecisionUTCTime& T, + bool EOS, + const std::string& streamID) + { + _port->pushPacket(data, T, EOS, streamID.c_str()); + } + + PortVarType _port; + }; + + template <> + void RemoteConnection::_pushPacket(PushArgumentType data, + const BULKIO::PrecisionUTCTime& /* unused */, + bool EOS, + const std::string& streamID) + { + _port->pushPacket(data, EOS, streamID.c_str()); + } + + template + class ChunkingConnection : public RemoteConnection + { + public: + typedef typename PortTraits::PortType PortType; + typedef typename PortType::_ptr_type PortPtrType; + typedef typename PortTraits::TransportType TransportType; + typedef typename PortTraits::SequenceType PortSequenceType; + + ChunkingConnection(const std::string& name, PortPtrType port) : + RemoteConnection(name, port) + { + // Multiply by some number < 1 to leave some margin for the CORBA header + const size_t maxPayloadSize = (size_t) (bulkio::Const::MaxTransferBytes() * .9); + maxSamplesPerPush = maxPayloadSize/sizeof(TransportType); + // Make sure maxSamplesPerPush is even so that complex data case is + // handled properly + if (maxSamplesPerPush%2 != 0){ + maxSamplesPerPush--; + } + } + + /* + * Push a packet whose payload may not fit within the CORBA limit. The + * packet is broken down into sub-packets and sent via multiple pushPacket + * calls. The EOS is set to false for all of the sub-packets, except for + * the last sub-packet, which uses the input EOS argument. + */ + virtual void pushPacket(const PortSequenceType& data, + const BULKIO::PrecisionUTCTime& T, + bool EOS, + const BULKIO::StreamSRI& sri) + { + double xdelta = sri.xdelta; + size_t itemSize = sri.mode?2:1; + + // Always do at least one push (may be empty), ensuring that all samples + // are pushed + const TransportType* buffer = data.get_buffer(); + size_t samplesRemaining = data.length(); + + // Initialize time of first subpacket + BULKIO::PrecisionUTCTime packetTime = T; + + do { + // Don't send more samples than are remaining + const size_t pushSize = std::min(samplesRemaining, maxSamplesPerPush); + samplesRemaining -= pushSize; + + // Send end-of-stream as false for all sub-packets except for the + // last one (when there are no samples remaining after this push), + // which gets the input EOS. + bool packetEOS = false; + if (samplesRemaining == 0) { + packetEOS = EOS; + } + + // Wrap a non-owning CORBA sequence (last argument is whether to free + // the buffer on destruction) around this sub-packet's data + const PortSequenceType subPacket(pushSize, pushSize, const_cast(buffer), false); + RemoteConnection::pushPacket(subPacket, packetTime, packetEOS, sri); + + // Synthesize the next packet timestamp + if (packetTime.tcstatus == BULKIO::TCS_VALID) { + packetTime += (pushSize/itemSize)* xdelta; + } + + // Advance buffer to next sub-packet boundary + buffer += pushSize; + } while (samplesRemaining > 0); + } + + private: + size_t maxSamplesPerPush; + }; + + + template + class LocalConnection : public PortConnection + { + public: + typedef typename PortTraits::PushType PushArgumentType; + typedef typename PortTraits::PortType PortType; + typedef typename PortType::_ptr_type PortPtrType; + typedef InPort LocalPortType; + + LocalConnection(const std::string& name, LocalPortType* port) : + PortConnection(name), + _port(port) + { + _port->_add_ref(); + } + + ~LocalConnection() + { + _port->_remove_ref(); + } + + virtual void pushSRI(const BULKIO::StreamSRI& sri) + { + _port->pushSRI(sri); + } + + virtual PortPtrType objref() + { + return _port->_this(); + } + + protected: + virtual void _pushPacket(PushArgumentType data, + const BULKIO::PrecisionUTCTime& T, + bool EOS, + const std::string& streamID) + { + _port->pushPacket(data, T, EOS, streamID.c_str()); + } + + LocalPortType* _port; + }; + + template <> + void LocalConnection::_pushPacket(PushArgumentType data, + const BULKIO::PrecisionUTCTime& T, + bool EOS, + const std::string& streamID) + { + _port->pushPacket((bulkio::Char*)data, T, EOS, streamID.c_str()); + } + + template <> + void LocalConnection::_pushPacket(PushArgumentType data, + const BULKIO::PrecisionUTCTime& T, + bool EOS, + const std::string& streamID) + { + _port->pushPacket((bulkio::Char*)data, T, EOS, streamID.c_str()); + } + +} diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp index d2d7c6994..46809170d 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp @@ -26,178 +26,13 @@ #include "bulkio_time_operators.h" #include "bulkio_in_port.h" +#include "bulkio_connection.hpp" + // Suppress warnings for access to "deprecated" currentSRI member--it's the // public access that's deprecated, not the member itself #pragma GCC diagnostic ignored "-Wdeprecated-declarations" namespace bulkio { - - template - class OutPortBase::PortConnection - { - public: - PortConnection(const std::string& name) : - stats(name, sizeof(NativeType)) - { - } - - virtual ~PortConnection() { }; - - virtual void pushSRI(const BULKIO::StreamSRI& sri) = 0; - - virtual void pushPacket(PushArgumentType data, - const BULKIO::PrecisionUTCTime& T, - bool EOS, - const BULKIO::StreamSRI& sri) - { - const std::string streamID(sri.streamID); - this->_pushPacket(data, T, EOS, streamID); - stats.update(this->_dataLength(data), 0, EOS, streamID); - } - - // - // Sends an end-of-stream packet for the given stream to a particular port, - // for use when disconnecting; enables XML and File specialization for - // consistent end-of-stream behavior - // - void sendEOS(const std::string& streamID) - { - this->_pushPacket(PortSequenceType(), bulkio::time::utils::notSet(), true, streamID); - } - - virtual PortPtrType objref() = 0; - - linkStatistics stats; - - protected: - virtual void _pushPacket(PushArgumentType data, - const BULKIO::PrecisionUTCTime& T, - bool EOS, - const std::string& streamID) = 0; - - // - // Returns the total number of elements of data in a pushPacket call, for - // statistical tracking; enables XML and File specialization, which have - // different notions of size - // - size_t _dataLength(PushArgumentType data) - { - return data.length(); - } - }; - - template <> - size_t OutPortBase< XMLPortTraits >::PortConnection::_dataLength(const char* data) - { - if (!data) { - return 0; - } - return strlen(data); - } - - template <> - size_t OutPortBase< FilePortTraits >::PortConnection::_dataLength(const char* /*unused*/) - { - return 1; - } - - template - class OutPortBase::RemoteConnection : public OutPortBase::PortConnection - { - public: - RemoteConnection(const std::string& name, PortPtrType port) : - OutPortBase::PortConnection(name), - _port(PortType::_duplicate(port)) - { - } - - virtual void pushSRI(const BULKIO::StreamSRI& sri) - { - _port->pushSRI(sri); - } - - virtual PortPtrType objref() - { - return PortType::_duplicate(_port); - } - - protected: - virtual void _pushPacket(PushArgumentType data, - const BULKIO::PrecisionUTCTime& T, - bool EOS, - const std::string& streamID) - { - _port->pushPacket(data, T, EOS, streamID.c_str()); - } - - PortVarType _port; - }; - - template <> - void OutPortBase::RemoteConnection::_pushPacket(PushArgumentType data, - const BULKIO::PrecisionUTCTime& /* unused */, - bool EOS, - const std::string& streamID) - { - _port->pushPacket(data, EOS, streamID.c_str()); - } - - template - class OutPortBase::LocalConnection : public OutPortBase::PortConnection - { - public: - LocalConnection(const std::string& name, LocalPortType* port) : - OutPortBase::PortConnection(name), - _port(port) - { - _port->_add_ref(); - } - - ~LocalConnection() - { - _port->_remove_ref(); - } - - virtual void pushSRI(const BULKIO::StreamSRI& sri) - { - _port->pushSRI(sri); - } - - virtual PortPtrType objref() - { - return _port->_this(); - } - - protected: - virtual void _pushPacket(PushArgumentType data, - const BULKIO::PrecisionUTCTime& T, - bool EOS, - const std::string& streamID) - { - _port->pushPacket(data, T, EOS, streamID.c_str()); - } - - LocalPortType* _port; - }; - - template <> - void OutPortBase::LocalConnection::_pushPacket(PushArgumentType data, - const BULKIO::PrecisionUTCTime& T, - bool EOS, - const std::string& streamID) - { - _port->pushPacket((bulkio::Char*)data, T, EOS, streamID.c_str()); - } - - template <> - void OutPortBase::LocalConnection::_pushPacket(PushArgumentType data, - const BULKIO::PrecisionUTCTime& T, - bool EOS, - const std::string& streamID) - { - _port->pushPacket((bulkio::Char*)data, T, EOS, streamID.c_str()); - } - /* OutPort Constructor @@ -469,18 +304,18 @@ namespace bulkio { template < typename PortTraits > - typename OutPortBase< PortTraits >::RemoteConnection* + typename OutPortBase< PortTraits >::PortConnectionType* OutPortBase< PortTraits >::_createRemoteConnection(PortPtrType port, const std::string& connectionId) { - return new RemoteConnection(name, port); + return new RemoteConnection(name, port); } template < typename PortTraits > - typename OutPortBase< PortTraits >::LocalConnection* + typename OutPortBase< PortTraits >::PortConnectionType* OutPortBase< PortTraits >::_createLocalConnection(LocalPortType* port, const std::string& connectionId) { - return new LocalConnection(name, port); + return new LocalConnection(name, port); } @@ -653,102 +488,10 @@ namespace bulkio { template - class OutPort::ChunkingConnection : public OutPortBase::RemoteConnection - { - public: - ChunkingConnection(const std::string& name, PortPtrType port) : - OutPortBase::RemoteConnection(name, port) - { - // Multiply by some number < 1 to leave some margin for the CORBA header - const size_t maxPayloadSize = (size_t) (bulkio::Const::MaxTransferBytes() * .9); - maxSamplesPerPush = maxPayloadSize/sizeof(TransportType); - // Make sure maxSamplesPerPush is even so that complex data case is - // handled properly - if (maxSamplesPerPush%2 != 0){ - maxSamplesPerPush--; - } - } - - /* - * Push a packet whose payload may not fit within the CORBA limit. The - * packet is broken down into sub-packets and sent via multiple pushPacket - * calls. The EOS is set to false for all of the sub-packets, except for - * the last sub-packet, which uses the input EOS argument. - */ - virtual void pushPacket(const PortSequenceType& data, - const BULKIO::PrecisionUTCTime& T, - bool EOS, - const BULKIO::StreamSRI& sri) - { - double xdelta = sri.xdelta; - size_t itemSize = sri.mode?2:1; - - if ( sri_iter != currentSRIs.end() ) { - if (sri_iter->second.sri.subsize == 0) { - // make sure maxSamplesPerPush is even so that complex data case is handled properly - if (maxSamplesPerPush%2 != 0){ - maxSamplesPerPush--; - } - } else { // this is framed data, so it must be consistent with both subsize and complex - while (maxSamplesPerPush%sri_iter->second.sri.subsize != 0) { - maxSamplesPerPush -= maxSamplesPerPush%(sri_iter->second.sri.subsize); - if (maxSamplesPerPush%2 != 0){ - maxSamplesPerPush--; - } - } - } - } else { - if (maxSamplesPerPush%2 != 0){ - maxSamplesPerPush--; - } - } - - // Always do at least one push (may be empty), ensuring that all samples - // are pushed - const TransportType* buffer = data.get_buffer(); - size_t samplesRemaining = data.length(); - - // Initialize time of first subpacket - BULKIO::PrecisionUTCTime packetTime = T; - - do { - // Don't send more samples than are remaining - const size_t pushSize = std::min(samplesRemaining, maxSamplesPerPush); - samplesRemaining -= pushSize; - - // Send end-of-stream as false for all sub-packets except for the - // last one (when there are no samples remaining after this push), - // which gets the input EOS. - bool packetEOS = false; - if (samplesRemaining == 0) { - packetEOS = EOS; - } - - // Wrap a non-owning CORBA sequence (last argument is whether to free - // the buffer on destruction) around this sub-packet's data - const PortSequenceType subPacket(pushSize, pushSize, const_cast(buffer), false); - OutPortBase::RemoteConnection::pushPacket(subPacket, packetTime, packetEOS, sri); - - // Synthesize the next packet timestamp - if (packetTime.tcstatus == BULKIO::TCS_VALID) { - packetTime += (pushSize/itemSize)* xdelta; - } - - // Advance buffer to next sub-packet boundary - buffer += pushSize; - } while (samplesRemaining > 0); - } - - private: - size_t maxSamplesPerPush; - }; - - - template - typename OutPortBase::RemoteConnection* + typename OutPort::PortConnectionType* OutPort::_createRemoteConnection(PortPtrType port, const std::string& connectionId) { - return new ChunkingConnection(this->name, port); + return new ChunkingConnection(this->name, port); } diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h index 9639e9059..37ebd8bfc 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h @@ -40,6 +40,8 @@ namespace bulkio { template class InPort; + template class PortConnection; + // // OutPortBase // @@ -279,15 +281,12 @@ namespace bulkio { // Lookup table for connections to input ports in the same process space // typedef InPort LocalPortType; + typedef PortConnection PortConnectionType; - class PortConnection; - class RemoteConnection; - class LocalConnection; - - virtual RemoteConnection* _createRemoteConnection(PortPtrType port, const std::string& connectionId); - virtual LocalConnection* _createLocalConnection(LocalPortType* port, const std::string& connectionId); + virtual PortConnectionType* _createRemoteConnection(PortPtrType port, const std::string& connectionId); + virtual PortConnectionType* _createLocalConnection(LocalPortType* port, const std::string& connectionId); - typedef std::map TransportMap; + typedef std::map TransportMap; TransportMap _transportMap; // @@ -469,11 +468,9 @@ namespace bulkio { protected: using OutPortBase::logger; typedef typename OutPortBase::PortPtrType PortPtrType; - typedef typename OutPortBase::RemoteConnection RemoteConnection; - - class ChunkingConnection; + typedef typename OutPortBase::PortConnectionType PortConnectionType; - virtual RemoteConnection* _createRemoteConnection(PortPtrType port, const std::string& connectionId); + virtual PortConnectionType* _createRemoteConnection(PortPtrType port, const std::string& connectionId); }; // From 1a79926a10132caee0a63b57037b7a71f4bc7a07 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 12 Apr 2016 13:39:04 -0400 Subject: [PATCH 0108/1644] Use shared buffer type all the way down to the connection --- .../libsrc/cpp/bulkio_connection.hpp | 75 +++++------ .../libsrc/cpp/bulkio_out_port.cpp | 117 ++++++++---------- bulkioInterfaces/libsrc/cpp/bulkio_out_port.h | 30 ++--- bulkioInterfaces/libsrc/cpp/bulkio_traits.h | 8 +- 4 files changed, 108 insertions(+), 122 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp b/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp index 317b9331a..ddb9bb615 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp @@ -4,10 +4,9 @@ namespace bulkio { class PortConnection { public: - typedef typename PortTraits::PushType PushArgumentType; - typedef typename PortTraits::SequenceType PortSequenceType; typedef typename PortTraits::PortType::_ptr_type PortPtrType; typedef typename PortTraits::NativeType NativeType; + typedef typename PortTraits::SharedBufferType SharedBufferType; PortConnection(const std::string& name) : stats(name, sizeof(NativeType)) @@ -18,7 +17,7 @@ namespace bulkio { virtual void pushSRI(const BULKIO::StreamSRI& sri) = 0; - virtual void pushPacket(PushArgumentType data, + virtual void pushPacket(const SharedBufferType& data, const BULKIO::PrecisionUTCTime& T, bool EOS, const BULKIO::StreamSRI& sri) @@ -35,7 +34,7 @@ namespace bulkio { // void sendEOS(const std::string& streamID) { - this->_pushPacket(PortSequenceType(), bulkio::time::utils::notSet(), true, streamID); + this->_pushPacket(SharedBufferType(), bulkio::time::utils::notSet(), true, streamID); } virtual PortPtrType objref() = 0; @@ -43,7 +42,7 @@ namespace bulkio { linkStatistics stats; protected: - virtual void _pushPacket(PushArgumentType data, + virtual void _pushPacket(const SharedBufferType& data, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID) = 0; @@ -53,23 +52,14 @@ namespace bulkio { // statistical tracking; enables XML and File specialization, which have // different notions of size // - size_t _dataLength(PushArgumentType data) + size_t _dataLength(const SharedBufferType& data) { - return data.length(); + return data.size(); } }; template <> - size_t PortConnection::_dataLength(const char* data) - { - if (!data) { - return 0; - } - return strlen(data); - } - - template <> - size_t PortConnection::_dataLength(const char* /*unused*/) + size_t PortConnection::_dataLength(const std::string& /*unused*/) { return 1; } @@ -81,7 +71,9 @@ namespace bulkio { typedef typename PortTraits::PortVarType PortVarType; typedef typename PortTraits::PortType PortType; typedef typename PortType::_ptr_type PortPtrType; - typedef typename PortTraits::PushType PushArgumentType; + typedef typename PortTraits::SharedBufferType SharedBufferType; + typedef typename PortTraits::SequenceType PortSequenceType; + typedef typename PortTraits::TransportType TransportType; RemoteConnection(const std::string& name, PortPtrType port) : PortConnection(name), @@ -100,24 +92,35 @@ namespace bulkio { } protected: - virtual void _pushPacket(PushArgumentType data, + virtual void _pushPacket(const SharedBufferType& data, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID) { - _port->pushPacket(data, T, EOS, streamID.c_str()); + const TransportType* ptr = reinterpret_cast(data.data()); + const PortSequenceType buffer(data.size(), data.size(), const_cast(ptr), false); + _port->pushPacket(buffer, T, EOS, streamID.c_str()); } PortVarType _port; }; template <> - void RemoteConnection::_pushPacket(PushArgumentType data, + void RemoteConnection::_pushPacket(const std::string& data, + const BULKIO::PrecisionUTCTime& T, + bool EOS, + const std::string& streamID) + { + _port->pushPacket(data.c_str(), T, EOS, streamID.c_str()); + } + + template <> + void RemoteConnection::_pushPacket(const std::string& data, const BULKIO::PrecisionUTCTime& /* unused */, bool EOS, const std::string& streamID) { - _port->pushPacket(data, EOS, streamID.c_str()); + _port->pushPacket(data.c_str(), EOS, streamID.c_str()); } template @@ -128,6 +131,7 @@ namespace bulkio { typedef typename PortType::_ptr_type PortPtrType; typedef typename PortTraits::TransportType TransportType; typedef typename PortTraits::SequenceType PortSequenceType; + typedef typename PortTraits::SharedBufferType SharedBufferType; ChunkingConnection(const std::string& name, PortPtrType port) : RemoteConnection(name, port) @@ -148,7 +152,7 @@ namespace bulkio { * calls. The EOS is set to false for all of the sub-packets, except for * the last sub-packet, which uses the input EOS argument. */ - virtual void pushPacket(const PortSequenceType& data, + virtual void pushPacket(const SharedBufferType& data, const BULKIO::PrecisionUTCTime& T, bool EOS, const BULKIO::StreamSRI& sri) @@ -158,8 +162,8 @@ namespace bulkio { // Always do at least one push (may be empty), ensuring that all samples // are pushed - const TransportType* buffer = data.get_buffer(); - size_t samplesRemaining = data.length(); + size_t first = 0; + size_t samplesRemaining = data.size(); // Initialize time of first subpacket BULKIO::PrecisionUTCTime packetTime = T; @@ -177,9 +181,8 @@ namespace bulkio { packetEOS = EOS; } - // Wrap a non-owning CORBA sequence (last argument is whether to free - // the buffer on destruction) around this sub-packet's data - const PortSequenceType subPacket(pushSize, pushSize, const_cast(buffer), false); + // Take the next slice of the input buffer. + SharedBufferType subPacket = data.slice(first, first + pushSize); RemoteConnection::pushPacket(subPacket, packetTime, packetEOS, sri); // Synthesize the next packet timestamp @@ -188,7 +191,7 @@ namespace bulkio { } // Advance buffer to next sub-packet boundary - buffer += pushSize; + first += pushSize; } while (samplesRemaining > 0); } @@ -201,10 +204,10 @@ namespace bulkio { class LocalConnection : public PortConnection { public: - typedef typename PortTraits::PushType PushArgumentType; typedef typename PortTraits::PortType PortType; typedef typename PortType::_ptr_type PortPtrType; typedef InPort LocalPortType; + typedef typename PortTraits::SharedBufferType SharedBufferType; LocalConnection(const std::string& name, LocalPortType* port) : PortConnection(name), @@ -229,33 +232,33 @@ namespace bulkio { } protected: - virtual void _pushPacket(PushArgumentType data, + virtual void _pushPacket(const SharedBufferType& data, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID) { - _port->pushPacket(data, T, EOS, streamID.c_str()); + //_port->pushPacket(data, T, EOS, streamID.c_str()); } LocalPortType* _port; }; template <> - void LocalConnection::_pushPacket(PushArgumentType data, + void LocalConnection::_pushPacket(const std::string& data, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID) { - _port->pushPacket((bulkio::Char*)data, T, EOS, streamID.c_str()); + _port->pushPacket((bulkio::Char*)data.c_str(), T, EOS, streamID.c_str()); } template <> - void LocalConnection::_pushPacket(PushArgumentType data, + void LocalConnection::_pushPacket(const std::string& data, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID) { - _port->pushPacket((bulkio::Char*)data, T, EOS, streamID.c_str()); + _port->pushPacket((bulkio::Char*)data.c_str(), T, EOS, streamID.c_str()); } } diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp index 46809170d..7c0d17ed6 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp @@ -158,61 +158,52 @@ namespace bulkio { template < typename PortTraits > void OutPortBase< PortTraits >::_pushSinglePacket( - PushArgumentType data, + const SharedBufferType& data, + bool shared, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID) { // don't want to process while command information is coming in SCOPED_LOCK lock(this->updatingPortsLock); - _pushPacketLocked(data, T, EOS, streamID); - } - - template < typename PortTraits > - void OutPortBase< PortTraits >::_pushPacketLocked( - PushArgumentType data, - const BULKIO::PrecisionUTCTime& T, - bool EOS, - const std::string& streamID) - { - // grab SRI context - typename OutPortSriMap::iterator sri_iter = currentSRIs.find( streamID ); - if (sri_iter == currentSRIs.end()) { - // No SRI associated with the stream ID, create a default one and add - // it to the list; it will get pushed to downstream connections below - SriMapStruct sri_ctx(bulkio::sri::create(streamID)); - // need to use insert since we do not have default CTOR for SriMapStruct - sri_iter = currentSRIs.insert(std::make_pair(streamID, sri_ctx)).first; - } - if (active) { - typename TransportMap::iterator port; - for (port = _transportMap.begin(); port != _transportMap.end(); ++port) { - // Check whether filtering is enabled and if this connection should - // receive the stream - if (!_isStreamRoutedToConnection(streamID, port->first)) { - continue; - } + // grab SRI context + typename OutPortSriMap::iterator sri_iter = currentSRIs.find( streamID ); + if (sri_iter == currentSRIs.end()) { + // No SRI associated with the stream ID, create a default one and add + // it to the list; it will get pushed to downstream connections below + SriMapStruct sri_ctx(bulkio::sri::create(streamID)); + // need to use insert since we do not have default CTOR for SriMapStruct + sri_iter = currentSRIs.insert(std::make_pair(streamID, sri_ctx)).first; + } - if (sri_iter->second.connections.count(port->first) == 0) { - this->_pushSRI(port, sri_iter->second); - } + if (active) { + typename TransportMap::iterator port; + for (port = _transportMap.begin(); port != _transportMap.end(); ++port) { + // Check whether filtering is enabled and if this connection should + // receive the stream + if (!_isStreamRoutedToConnection(streamID, port->first)) { + continue; + } - try { - port->second->pushPacket(data, T, EOS, sri_iter->second.sri); - } catch(...) { - LOG_ERROR( logger, "PUSH-PACKET FAILED, PORT/CONNECTION: " << name << "/" << port->first ); - } + if (sri_iter->second.connections.count(port->first) == 0) { + this->_pushSRI(port, sri_iter->second); } - } - // if we have end of stream removed old sri - try { - if ( EOS ) currentSRIs.erase(streamID); - } - catch(...){ + try { + port->second->pushPacket(data, T, EOS, sri_iter->second.sri); + } catch(...) { + LOG_ERROR( logger, "PUSH-PACKET FAILED, PORT/CONNECTION: " << name << "/" << port->first ); + } } + } + // if we have end of stream removed old sri + try { + if ( EOS ) currentSRIs.erase(streamID); + } + catch(...){ + } } @@ -502,8 +493,8 @@ namespace bulkio { bool EOS, const std::string& streamID) { - const PortSequenceType buffer(data.size(), data.size(), reinterpret_cast(&data[0]), false); - this->_pushPacketLocked(buffer, T, EOS, streamID); + SharedBufferType buffer(&data[0], data.size(), null_deleter()); + this->_pushSinglePacket(buffer, false, T, EOS, streamID); } template < typename PortTraits > @@ -513,9 +504,8 @@ namespace bulkio { bool EOS, const std::string& streamID) { - const TransportType* ptr = reinterpret_cast(&data[0]); - const PortSequenceType buffer(data.size(), data.size(), const_cast(ptr), false); - this->_pushPacketLocked(buffer, T, EOS, streamID); + SharedBufferType buffer(const_cast(&data[0]), data.size(), null_deleter()); + this->_pushSinglePacket(buffer, false, T, EOS, streamID); } template < typename PortTraits > @@ -526,20 +516,19 @@ namespace bulkio { bool EOS, const std::string& streamID) { - const PortSequenceType buffer(size, size, const_cast(data), false); - this->_pushPacketLocked(buffer, T, EOS, streamID); + TransportType* ptr = const_cast(data); + SharedBufferType buffer(reinterpret_cast(ptr), size, null_deleter()); + this->_pushSinglePacket(buffer, false, T, EOS, streamID); } template < typename PortTraits > - void OutPort< PortTraits >::pushPacket(const ScalarBuffer& data, + void OutPort< PortTraits >::pushPacket(const SharedBufferType& data, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID, bool shared) { - const TransportType* ptr = reinterpret_cast(data.data()); - const PortSequenceType buffer(data.size(), data.size(), const_cast(ptr), false); - this->_pushPacketLocked(buffer, T, EOS, streamID); + this->_pushSinglePacket(data, true, T, EOS, streamID); } template < typename PortTraits > @@ -620,19 +609,19 @@ namespace bulkio { void OutFilePort::pushPacket( const char* URL, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID) { - _pushSinglePacket(URL, T, EOS, streamID); + _pushSinglePacket(URL, true, T, EOS, streamID); } void OutFilePort::pushPacket( const std::string& URL, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID) { - _pushSinglePacket(URL.c_str(), T, EOS, streamID); + _pushSinglePacket(URL, true, T, EOS, streamID); } void OutFilePort::pushPacket( const char *data, bool EOS, const std::string& streamID) { - _pushSinglePacket(data, bulkio::time::utils::now(), EOS, streamID); + _pushSinglePacket(data, true, bulkio::time::utils::now(), EOS, streamID); } @@ -655,27 +644,23 @@ namespace bulkio { } - void OutXMLPort::pushPacket( const char *data, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID) + void OutXMLPort::pushPacket(const char *data, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID) { - _pushSinglePacket(data, T, EOS, streamID); + _pushSinglePacket(data, true, T, EOS, streamID); } - void OutXMLPort::pushPacket( const char *data, bool EOS, const std::string& streamID) + void OutXMLPort::pushPacket(const char *data, bool EOS, const std::string& streamID) { - // The time argument is never dereferenced for dataXML, so it is safe to - // pass a null - BULKIO::PrecisionUTCTime* time = 0; - _pushSinglePacket(data, *time, EOS, streamID); + this->pushPacket(std::string(data), EOS, streamID); } - - void OutXMLPort::pushPacket( const std::string& data, bool EOS, const std::string& streamID) + void OutXMLPort::pushPacket(const std::string& data, bool EOS, const std::string& streamID) { // The time argument is never dereferenced for dataXML, so it is safe to // pass a null BULKIO::PrecisionUTCTime* time = 0; - _pushSinglePacket(data.c_str(), *time, EOS, streamID); + _pushSinglePacket(data, true, *time, EOS, streamID); } diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h index 37ebd8bfc..9fadba531 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h @@ -87,6 +87,11 @@ namespace bulkio { // typedef typename Traits::PushType PushArgumentType; + // + // Shared buffer type used to transfer data without copies, where possible + // + typedef typename Traits::SharedBufferType SharedBufferType; + // // Data type of items passed into the pushPacket method // @@ -310,22 +315,11 @@ namespace bulkio { // will never break a push into multiple packets (XML, File); acquires and // releases the port lock // - void _pushSinglePacket( - PushArgumentType data, - const BULKIO::PrecisionUTCTime& T, - bool EOS, - const std::string& streamID); - - // - // Sends the given data and metadata to all appropriate connections and - // updates the associated SRI if necessary (or creates one if it does not - // exist); must be called with the port lock held - // - void _pushPacketLocked( - PushArgumentType data, - const BULKIO::PrecisionUTCTime& T, - bool EOS, - const std::string& streamID); + void _pushSinglePacket(const SharedBufferType& data, + bool shared, + const BULKIO::PrecisionUTCTime& T, + bool EOS, + const std::string& streamID); }; @@ -385,7 +379,7 @@ namespace bulkio { // typedef OutputStream StreamType; - typedef redhawk::read_buffer ScalarBuffer; + typedef typename Traits::SharedBufferType SharedBufferType; // // OutPort Creates a uses port object for publishing data to the framework @@ -457,7 +451,7 @@ namespace bulkio { */ void pushPacket( const DataBufferType & data, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID); - void pushPacket(const ScalarBuffer& data, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID, bool shared); + void pushPacket(const SharedBufferType& data, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID, bool shared); // Create a new stream based on a stream ID StreamType createStream(const std::string& streamID); diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_traits.h b/bulkioInterfaces/libsrc/cpp/bulkio_traits.h index 3ce3b36f7..bce9c3b0e 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_traits.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_traits.h @@ -25,6 +25,7 @@ #include // for _seqVector #include +#include #include "BULKIO_Interfaces.h" #include "bulkio_base.h" @@ -49,13 +50,15 @@ template < typename TT, typename AT=_seqVector::seqVectorAllocator< TT > > // Traits template definition used to define input and output types used the port // classes // -template < typename PST, typename TT, typename NDT=TT, class DBT=std::vector< NDT >, class PAT=const PST& > +template < typename PST, typename TT, typename NDT=TT, class DBT=std::vector< NDT >, class PAT=const PST&, + class SBT=redhawk::read_buffer > struct DataTransferTraits { typedef PST PortSequenceType; // Port Sequence type used by middleware typedef PAT PushArgumentType; // Type of data argument to pushPacket typedef TT TransportType; // Transport Type contained in the Port Sequence container typedef NDT NativeDataType; // Native c++ mapping of Transport Type typedef DBT DataBufferType; // Container defintion to hold data from Input port + typedef SBT SharedBufferType; typedef typename DBT::allocator_type AllocatorType; }; @@ -70,7 +73,7 @@ typedef DataTransferTraits< PortTypes::LongLongSequence, CORBA::LongLong > Lo typedef DataTransferTraits< PortTypes::UlongLongSequence, CORBA::ULongLong > ULongLongDataTransferTraits; typedef DataTransferTraits< PortTypes::FloatSequence, CORBA::Float > FloatDataTransferTraits; typedef DataTransferTraits< PortTypes::DoubleSequence, CORBA::Double > DoubleDataTransferTraits; -typedef DataTransferTraits< Char *, Char, Char, std::string, const char* > StringDataTransferTraits; +typedef DataTransferTraits< Char *, Char, Char, std::string, const char*, std::string > StringDataTransferTraits; // @@ -195,6 +198,7 @@ struct PortTraits { typedef typename DTT::PortSequenceType SequenceType; typedef typename DTT::PushArgumentType PushType; typedef typename DTT::DataBufferType DataBufferType; + typedef typename DTT::SharedBufferType SharedBufferType; }; From e586d5fb49ed197afc3e03a20d1e87bcb0847359 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 12 Apr 2016 13:42:23 -0400 Subject: [PATCH 0109/1644] Drop "char*" overloads for output XML and File ports, letting the implicit conversion to std::string handle it. --- .../libsrc/cpp/bulkio_out_port.cpp | 13 +--------- bulkioInterfaces/libsrc/cpp/bulkio_out_port.h | 25 ------------------- 2 files changed, 1 insertion(+), 37 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp index 7c0d17ed6..430d7ba63 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp @@ -607,13 +607,7 @@ namespace bulkio { } - void OutFilePort::pushPacket( const char* URL, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID) - { - _pushSinglePacket(URL, true, T, EOS, streamID); - } - - - void OutFilePort::pushPacket( const std::string& URL, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID) + void OutFilePort::pushPacket(const std::string& URL, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID) { _pushSinglePacket(URL, true, T, EOS, streamID); } @@ -650,11 +644,6 @@ namespace bulkio { } - void OutXMLPort::pushPacket(const char *data, bool EOS, const std::string& streamID) - { - this->pushPacket(std::string(data), EOS, streamID); - } - void OutXMLPort::pushPacket(const std::string& data, bool EOS, const std::string& streamID) { // The time argument is never dereferenced for dataXML, so it is safe to diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h index 9fadba531..a95d856e8 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h @@ -559,21 +559,6 @@ namespace bulkio { virtual ~OutFilePort() {}; - /* - * pushPacket - * maps to dataFile BULKIO method call for passing the URL of a file - * - * data: char string containing the file URL to send out - * T: constant of type BULKIO::PrecisionUTCTime containing the timestamp for the outgoing data. - * tcmode: timecode mode - * tcstatus: timecode status - * toff: fractional sample offset - * twsec: J1970 GMT - * tfsec: fractional seconds: 0.0 to 1.0 - * EOS: end-of-stream flag - * streamID: stream identifier - */ - void pushPacket(const char *URL, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID); /* * pushPacket * maps to dataFile BULKIO method call for passing the URL of a file @@ -662,16 +647,6 @@ namespace bulkio { */ void pushPacket(const char *data, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID); - /* - * pushPacket - * maps to dataXML BULKIO method call for passing an XML-formatted string - * - * data: character string containing the XML data to send out - * EOS: end-of-stream flag - * streamID: stream identifier - */ - void pushPacket(const char *data, bool EOS, const std::string& streamID); - /* * pushPacket * maps to dataXML BULKIO method call for passing an XML-formatted string From 614e72f6ee5441a802efe90254f6301707438057 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 12 Apr 2016 14:03:35 -0400 Subject: [PATCH 0110/1644] Push the shared buffer to the input port for local transfers (which still makes a copy) --- .../libsrc/cpp/bulkio_connection.hpp | 3 +-- bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp | 18 +++++++++++++----- bulkioInterfaces/libsrc/cpp/bulkio_in_port.h | 8 +++++++- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp b/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp index ddb9bb615..b906cc7a7 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp @@ -130,7 +130,6 @@ namespace bulkio { typedef typename PortTraits::PortType PortType; typedef typename PortType::_ptr_type PortPtrType; typedef typename PortTraits::TransportType TransportType; - typedef typename PortTraits::SequenceType PortSequenceType; typedef typename PortTraits::SharedBufferType SharedBufferType; ChunkingConnection(const std::string& name, PortPtrType port) : @@ -237,7 +236,7 @@ namespace bulkio { bool EOS, const std::string& streamID) { - //_port->pushPacket(data, T, EOS, streamID.c_str()); + _port->pushPacket(data, T, EOS, streamID); } LocalPortType* _port; diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp index 122321683..a8f68b2c8 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp @@ -210,7 +210,7 @@ namespace bulkio { template < typename PortTraits > - void InPortBase< PortTraits >::queuePacket(const PushArgumentType data, const BULKIO::PrecisionUTCTime& T, CORBA::Boolean EOS, const char* streamID) + void InPortBase< PortTraits >::queuePacket(const PushArgumentType data, const BULKIO::PrecisionUTCTime& T, CORBA::Boolean EOS, const std::string& streamID) { TRACE_ENTER( logger, "InPort::pushPacket" ); @@ -223,7 +223,7 @@ namespace bulkio { return; } - BULKIO::StreamSRI tmpH = {1, 0.0, 1.0, 1, 0, 0.0, 0.0, 0, 0, streamID, false, 0}; + BULKIO::StreamSRI tmpH = {1, 0.0, 1.0, 1, 0, 0.0, 0.0, 0, 0, streamID.c_str(), false, 0}; bool sriChanged = false; bool portBlocking = false; @@ -231,7 +231,7 @@ namespace bulkio { { SCOPED_LOCK lock(sriUpdateLock); - currH = currentHs.find(std::string(streamID)); + currH = currentHs.find(streamID); if (currH != currentHs.end()) { tmpH = currH->second.first; sriChanged = currH->second.second; @@ -260,7 +260,7 @@ namespace bulkio { SCOPED_LOCK lock(dataBufferLock); LOG_TRACE( logger, "bulkio::InPort pushPacket NEW PACKET (QUEUE" << workQueue.size()+1 << ")" ); stats->update(length, (float)(workQueue.size()+1)/(float)queueSem->getMaxValue(), EOS, streamID, false); - DataTransferType *tmpIn = new DataTransferType(data, T, EOS, streamID, tmpH, sriChanged, false); + DataTransferType *tmpIn = new DataTransferType(data, T, EOS, streamID.c_str(), tmpH, sriChanged, false); workQueue.push_back(tmpIn); dataAvailable.notify_all(); } else { @@ -290,7 +290,7 @@ namespace bulkio { LOG_DEBUG( logger, "bulkio::InPort pushPacket NEW Packet (QUEUE=" << workQueue.size()+1 << ")"); stats->update(length, (float)(workQueue.size()+1)/(float)queueSem->getMaxValue(), EOS, streamID, flushToReport); - DataTransferType *tmpIn = new DataTransferType(data, T, EOS, streamID, tmpH, sriChanged, flushToReport); + DataTransferType *tmpIn = new DataTransferType(data, T, EOS, streamID.c_str(), tmpH, sriChanged, flushToReport); workQueue.push_back(tmpIn); dataAvailable.notify_all(); } @@ -659,6 +659,14 @@ namespace bulkio { this->queuePacket(data, T, EOS, streamID); } + template < typename PortTraits > + void InPort< PortTraits >::pushPacket(const SharedBufferType& data, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID) + { + const TransportType* ptr = reinterpret_cast(data.data()); + const PortSequenceType buffer(data.size(), data.size(), const_cast(ptr), false); + this->queuePacket(buffer, T, EOS, streamID.c_str()); + } + template < typename PortTraits > typename InPort< PortTraits >::StreamType InPort< PortTraits >::getCurrentStream(float timeout) { diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h index 95fcca0d5..21e43dca2 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h @@ -324,7 +324,7 @@ namespace bulkio { // Queues a packet received via pushPacket; in most cases, this method maps // exactly to pushPacket, except for dataFile // - void queuePacket(PushArgumentType data, const BULKIO::PrecisionUTCTime& T, CORBA::Boolean EOS, const char* streamID); + void queuePacket(PushArgumentType data, const BULKIO::PrecisionUTCTime& T, CORBA::Boolean EOS, const std::string& streamID); // // Returns a pointer to the first packet in the queue, blocking for up to @@ -370,6 +370,9 @@ namespace bulkio { // Transport Sequence Type use to during push packet typedef typename Traits::SequenceType PortSequenceType; + // Shared buffer type used for local transfers + typedef typename Traits::SharedBufferType SharedBufferType; + // // Transport type used by this port // @@ -425,6 +428,9 @@ namespace bulkio { // @param streamID - name of the stream the vector and stream context data are associated with virtual void pushPacket(const PortSequenceType& data, const BULKIO::PrecisionUTCTime& T, CORBA::Boolean EOS, const char* streamID); + // Local non-copying transfer + void pushPacket(const SharedBufferType& data, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID); + // // Stream-based input API // From 1a9dafc8d12bb7e512c8d332e9fea3c75ff8a11a Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 13 Apr 2016 15:58:38 -0400 Subject: [PATCH 0111/1644] Replace queue semaphore with integrated max depth and queue not full condition --- .../libsrc/cpp/bulkio_in_port.cpp | 37 ++++++++----------- bulkioInterfaces/libsrc/cpp/bulkio_in_port.h | 17 ++------- 2 files changed, 19 insertions(+), 35 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp index a8f68b2c8..a8c9d4644 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp @@ -57,9 +57,9 @@ namespace bulkio { Port_Provides_base_impl(port_name), sri_cmp(sriCmp), newStreamCallback(), + maxQueue(100), breakBlock(false), blocking(false), - queueSem(new queueSemaphore(100)), stats(new linkStatistics(port_name, sizeof(TransportType))), logger(logger) { @@ -77,7 +77,7 @@ namespace bulkio { } LOG_DEBUG( logger, "bulkio::InPort CTOR port:" << name << - " Blocking/MaxInputQueueSize " << blocking << "/" << queueSem->getMaxValue() << + " Blocking/MaxInputQueueSize " << blocking << "/" << maxQueue << " SriCompare/NewStreamCallback " << _cmpMsg << "/" << _sriMsg ); } @@ -101,8 +101,6 @@ namespace bulkio { } // clean up allocated containers - if ( queueSem ) delete queueSem; - if ( stats ) delete stats; TRACE_EXIT( logger, "InPort::DTOR" ); @@ -124,7 +122,7 @@ namespace bulkio { BULKIO::PortUsageType InPortBase< PortTraits >::state() { SCOPED_LOCK lock(dataBufferLock); - if (workQueue.size() == queueSem->getMaxValue()) { + if (workQueue.size() == maxQueue) { return BULKIO::BUSY; } else if (workQueue.size() == 0) { return BULKIO::IDLE; @@ -158,7 +156,7 @@ namespace bulkio { int InPortBase< PortTraits >::getMaxQueueDepth() { SCOPED_LOCK lock(dataBufferLock); - return queueSem->getMaxValue(); + return maxQueue; } template < typename PortTraits > @@ -172,7 +170,7 @@ namespace bulkio { void InPortBase< PortTraits >::setMaxQueueDepth(int newDepth) { SCOPED_LOCK lock(dataBufferLock); - queueSem->setMaxValue(newDepth); + maxQueue = newDepth; } template < typename PortTraits > @@ -183,7 +181,6 @@ namespace bulkio { if (H.blocking) { SCOPED_LOCK lock(dataBufferLock); blocking = true; - queueSem->setCurrValue(workQueue.size()); } const std::string streamID(H.streamID); @@ -214,7 +211,7 @@ namespace bulkio { { TRACE_ENTER( logger, "InPort::pushPacket" ); - if (queueSem->getMaxValue() == 0) { + if (maxQueue == 0) { TRACE_EXIT( logger, "InPort::pushPacket" ); return; } @@ -255,11 +252,13 @@ namespace bulkio { const size_t length = _getElementLength(data); LOG_DEBUG( logger, "bulkio::InPort port blocking:" << portBlocking ); bool flushToReport = false; - if(portBlocking) { - queueSem->incr(); + if (portBlocking) { SCOPED_LOCK lock(dataBufferLock); + while (workQueue.size() == maxQueue) { + queueAvailable.wait(lock); + } LOG_TRACE( logger, "bulkio::InPort pushPacket NEW PACKET (QUEUE" << workQueue.size()+1 << ")" ); - stats->update(length, (float)(workQueue.size()+1)/(float)queueSem->getMaxValue(), EOS, streamID, false); + stats->update(length, (float)(workQueue.size()+1)/(float)maxQueue, EOS, streamID, false); DataTransferType *tmpIn = new DataTransferType(data, T, EOS, streamID.c_str(), tmpH, sriChanged, false); workQueue.push_back(tmpIn); dataAvailable.notify_all(); @@ -267,7 +266,7 @@ namespace bulkio { SCOPED_LOCK lock(dataBufferLock); bool sriChangedHappened = false; bool flagEOS = false; - if (workQueue.size() == queueSem->getMaxValue()) { // reached maximum queue depth - flush the queue + if (workQueue.size() >= maxQueue) { // reached maximum queue depth - flush the queue LOG_DEBUG( logger, "bulkio::InPort pushPacket PURGE INPUT QUEUE (SIZE" << workQueue.size() << ")" ); flushToReport = true; DataTransferType *tmp; @@ -289,7 +288,7 @@ namespace bulkio { EOS = true; LOG_DEBUG( logger, "bulkio::InPort pushPacket NEW Packet (QUEUE=" << workQueue.size()+1 << ")"); - stats->update(length, (float)(workQueue.size()+1)/(float)queueSem->getMaxValue(), EOS, streamID, flushToReport); + stats->update(length, (float)(workQueue.size()+1)/(float)maxQueue, EOS, streamID, flushToReport); DataTransferType *tmpIn = new DataTransferType(data, T, EOS, streamID.c_str(), tmpH, sriChanged, flushToReport); workQueue.push_back(tmpIn); dataAvailable.notify_all(); @@ -362,7 +361,6 @@ namespace bulkio { { TRACE_ENTER( logger, "InPort::block" ); breakBlock = true; - queueSem->release(); dataAvailable.notify_all(); packetWaiters.interrupt(); TRACE_EXIT( logger, "InPort::block" ); @@ -442,7 +440,9 @@ namespace bulkio { } LOG_TRACE( logger, "bulkio.InPort getPacket PORT:" << name << " (QUEUE="<< workQueue.size() << ")" ); - + if (tmp) { + queueAvailable.notify_all(); + } } if (!tmp) { @@ -473,13 +473,8 @@ namespace bulkio { { SCOPED_LOCK lock(dataBufferLock); if (turnOffBlocking) { - queueSem->setCurrValue(0); blocking = false; } - - if (blocking) { - queueSem->decr(); - } } TRACE_EXIT( logger, "InPort::getPacket" ); diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h index 21e43dca2..3ba0d7a40 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h @@ -278,21 +278,15 @@ namespace bulkio { // synchronizes access to the workQueue member // MUTEX dataBufferLock; + CONDITION dataAvailable; + CONDITION queueAvailable; + size_t maxQueue; // // synchronizes access to the currentHs member // MUTEX sriUpdateLock; - // - // mutex for use with condition variable to signify when data is available for consumption - // RESOVLE: combine deque and condition into template for pushing and poping items onto the queue... - // refer to ConditionList.h example - // - MUTEX dataAvailableMutex; - - CONDITION dataAvailable; - // // used to control data flow from getPacket call // @@ -303,11 +297,6 @@ namespace bulkio { // bool blocking; - // - // An abstraction of a counting semaphore to control access to the workQueue member - // - queueSemaphore *queueSem; - // // Statistics provider object used by the port monitoring interface // From b55db597fe3cb1cac94debc79b575b74e1200fa5 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 13 Apr 2016 16:27:11 -0400 Subject: [PATCH 0112/1644] Rearrange packet queueing to reduce duplication and ensure that blocking flag is only checked when the data mutex is held --- .../libsrc/cpp/bulkio_in_port.cpp | 65 +++++++++---------- 1 file changed, 30 insertions(+), 35 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp index a8c9d4644..68b299560 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp @@ -222,7 +222,6 @@ namespace bulkio { BULKIO::StreamSRI tmpH = {1, 0.0, 1.0, 1, 0, 0.0, 0.0, 0, 0, streamID.c_str(), false, 0}; bool sriChanged = false; - bool portBlocking = false; SriMap::iterator currH; { @@ -246,49 +245,45 @@ namespace bulkio { createStream(streamID, tmpH); } - portBlocking = blocking; } const size_t length = _getElementLength(data); - LOG_DEBUG( logger, "bulkio::InPort port blocking:" << portBlocking ); - bool flushToReport = false; - if (portBlocking) { - SCOPED_LOCK lock(dataBufferLock); - while (workQueue.size() == maxQueue) { - queueAvailable.wait(lock); - } - LOG_TRACE( logger, "bulkio::InPort pushPacket NEW PACKET (QUEUE" << workQueue.size()+1 << ")" ); - stats->update(length, (float)(workQueue.size()+1)/(float)maxQueue, EOS, streamID, false); - DataTransferType *tmpIn = new DataTransferType(data, T, EOS, streamID.c_str(), tmpH, sriChanged, false); - workQueue.push_back(tmpIn); - dataAvailable.notify_all(); - } else { + { + bool flushToReport = false; SCOPED_LOCK lock(dataBufferLock); - bool sriChangedHappened = false; - bool flagEOS = false; - if (workQueue.size() >= maxQueue) { // reached maximum queue depth - flush the queue - LOG_DEBUG( logger, "bulkio::InPort pushPacket PURGE INPUT QUEUE (SIZE" << workQueue.size() << ")" ); - flushToReport = true; - DataTransferType *tmp; - while (workQueue.size() != 0) { - tmp = workQueue.front(); - if (tmp->sriChanged == true) { - sriChangedHappened = true; - } - if (tmp->EOS == true) { + LOG_DEBUG(logger, "bulkio::InPort port blocking:" << blocking); + if (blocking) { + while (workQueue.size() == maxQueue) { + queueAvailable.wait(lock); + } + } else { + bool sriChangedHappened = false; + bool flagEOS = false; + if (workQueue.size() >= maxQueue) { // reached maximum queue depth - flush the queue + LOG_DEBUG( logger, "bulkio::InPort pushPacket PURGE INPUT QUEUE (SIZE" << workQueue.size() << ")" ); + flushToReport = true; + while (workQueue.size() != 0) { + DataTransferType *tmp = workQueue.front(); + if (tmp->sriChanged == true) { + sriChangedHappened = true; + } + if (tmp->EOS == true) { flagEOS = true; + } + workQueue.pop_front(); + delete tmp; } - workQueue.pop_front(); - delete tmp; } - } - if (sriChangedHappened) - sriChanged = true; - if (flagEOS) + if (sriChangedHappened) { + sriChanged = true; + } + if (flagEOS) { EOS = true; + } + } - LOG_DEBUG( logger, "bulkio::InPort pushPacket NEW Packet (QUEUE=" << workQueue.size()+1 << ")"); - stats->update(length, (float)(workQueue.size()+1)/(float)maxQueue, EOS, streamID, flushToReport); + LOG_TRACE(logger, "bulkio::InPort pushPacket NEW PACKET (QUEUE" << workQueue.size()+1 << ")"); + stats->update(length, (float)(workQueue.size()+1)/(float)maxQueue, EOS, streamID, false); DataTransferType *tmpIn = new DataTransferType(data, T, EOS, streamID.c_str(), tmpH, sriChanged, flushToReport); workQueue.push_back(tmpIn); dataAvailable.notify_all(); From 600ac70fd9e8a190ee3cf88acdd6da2ab5ef4f9e Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 13 Apr 2016 16:34:56 -0400 Subject: [PATCH 0113/1644] Just clear the sriChanged flag instead of re-copying the SRI --- bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp index 68b299560..ed490c64f 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp @@ -231,7 +231,7 @@ namespace bulkio { if (currH != currentHs.end()) { tmpH = currH->second.first; sriChanged = currH->second.second; - currentHs[streamID] = std::make_pair(currH->second.first, false); + currentHs[streamID].second = false; } else { // Unknown stream ID, register a new default SRI following the logic in pushSRI, // and set the SRI changed flag From 6f6b368ed93598306ea39bff73d97c223c96cdbe Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 13 Apr 2016 16:45:36 -0400 Subject: [PATCH 0114/1644] Remove unused member --- bulkioInterfaces/libsrc/cpp/bulkio_in_port.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h index 3ba0d7a40..006eb3254 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h @@ -254,11 +254,6 @@ namespace bulkio { // WorkQueue workQueue; - // - // Track size of work queue between getPacket calls when using streamID for extraction - // - uint32_t lastQueueSize; - // // SRI compare method used by pushSRI method to determine how to match incoming SRI objects and streamsID // From 4e2d7f0fd82fc27237fc6ec02566ce77991062b6 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 13 Apr 2016 16:46:07 -0400 Subject: [PATCH 0115/1644] Avoid copying the SRI when queueing a packet --- bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp index ed490c64f..10520089e 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp @@ -220,7 +220,7 @@ namespace bulkio { return; } - BULKIO::StreamSRI tmpH = {1, 0.0, 1.0, 1, 0, 0.0, 0.0, 0, 0, streamID.c_str(), false, 0}; + BULKIO::StreamSRI* sri; bool sriChanged = false; SriMap::iterator currH; @@ -229,7 +229,7 @@ namespace bulkio { currH = currentHs.find(streamID); if (currH != currentHs.end()) { - tmpH = currH->second.first; + sri = &currH->second.first; sriChanged = currH->second.second; currentHs[streamID].second = false; } else { @@ -237,13 +237,15 @@ namespace bulkio { // and set the SRI changed flag LOG_WARN(logger, "InPort::pushPacket received data for stream '" << streamID << "' with no SRI"); sriChanged = true; + BULKIO::StreamSRI tmpH = {1, 0.0, 1.0, 1, 0, 0.0, 0.0, 0, 0, streamID.c_str(), false, 0}; if (newStreamCallback) { (*newStreamCallback)(tmpH); } currentHs[streamID] = std::make_pair(tmpH, false); + sri = &(currentHs[streamID].first); lock.unlock(); - createStream(streamID, tmpH); + createStream(streamID, *sri); } } @@ -284,7 +286,7 @@ namespace bulkio { LOG_TRACE(logger, "bulkio::InPort pushPacket NEW PACKET (QUEUE" << workQueue.size()+1 << ")"); stats->update(length, (float)(workQueue.size()+1)/(float)maxQueue, EOS, streamID, false); - DataTransferType *tmpIn = new DataTransferType(data, T, EOS, streamID.c_str(), tmpH, sriChanged, flushToReport); + DataTransferType *tmpIn = new DataTransferType(data, T, EOS, streamID.c_str(), *sri, sriChanged, flushToReport); workQueue.push_back(tmpIn); dataAvailable.notify_all(); } From 03c78d14b8954f8107dbeab383e3eb89bf7aa79d Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 14 Apr 2016 14:13:12 -0400 Subject: [PATCH 0116/1644] Use shared buffers in input data packet. This temporarily breaks a lot of things, but basic shared memory transfer can now work. --- bulkioInterfaces/libsrc/cpp/bulkio.cpp | 32 +++++-------------- .../libsrc/cpp/bulkio_in_port.cpp | 25 +++++---------- bulkioInterfaces/libsrc/cpp/bulkio_in_port.h | 6 ++-- bulkioInterfaces/libsrc/cpp/bulkio_traits.h | 14 ++++---- 4 files changed, 28 insertions(+), 49 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio.cpp b/bulkioInterfaces/libsrc/cpp/bulkio.cpp index 20ae2ab66..aef0d54fa 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio.cpp @@ -236,31 +236,15 @@ namespace bulkio { template < typename DataTransferTraits > - DataTransfer< DataTransferTraits >::DataTransfer(const PortSequenceType & data, const BULKIO::PrecisionUTCTime &_T, bool _EOS, const char* _streamID, BULKIO::StreamSRI &_H, bool _sriChanged, bool _inputQueueFlushed) + DataTransfer< DataTransferTraits >::DataTransfer(const SharedBufferType& data, const BULKIO::PrecisionUTCTime &_T, bool _EOS, const char* _streamID, BULKIO::StreamSRI &_H, bool _sriChanged, bool _inputQueueFlushed) : + buffer(data), + T(_T), + EOS(_EOS), + streamID(_streamID), + SRI(_H), + sriChanged(_sriChanged), + inputQueueFlushed(_inputQueueFlushed) { - const size_t dataLength = data.length(); - - typedef typename std::_Vector_base< TransportType, typename DataTransferTraits::DataBufferType::allocator_type >::_Vector_impl *VectorPtr; - - VectorPtr vectorPtr = (VectorPtr)(&dataBuffer); - - if (data.release()) { - vectorPtr->_M_start = const_cast< PortSequenceType *>(&data)->get_buffer(1); - } else { - // Somebody else owns the data; make a copy - vectorPtr->_M_start = vectorPtr->allocate(dataLength); - const void* buffer = data.get_buffer(); - memcpy(vectorPtr->_M_start, buffer, dataLength*sizeof(NativeDataType)); - } - vectorPtr->_M_finish = vectorPtr->_M_start + dataLength; - vectorPtr->_M_end_of_storage = vectorPtr->_M_finish; - - T = _T; - EOS = _EOS; - streamID = _streamID; - SRI = _H; - sriChanged = _sriChanged; - inputQueueFlushed = _inputQueueFlushed; } diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp index 10520089e..2b28a95ed 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp @@ -207,7 +207,7 @@ namespace bulkio { template < typename PortTraits > - void InPortBase< PortTraits >::queuePacket(const PushArgumentType data, const BULKIO::PrecisionUTCTime& T, CORBA::Boolean EOS, const std::string& streamID) + void InPortBase< PortTraits >::queuePacket(const SharedBufferType& data, const BULKIO::PrecisionUTCTime& T, CORBA::Boolean EOS, const std::string& streamID) { TRACE_ENTER( logger, "InPort::pushPacket" ); @@ -546,9 +546,9 @@ namespace bulkio { } template < typename PortTraits > - int InPortBase< PortTraits >::_getElementLength(const PushArgumentType data) + int InPortBase< PortTraits >::_getElementLength(const SharedBufferType& data) { - return data.length(); + return data.size(); } template < typename PortTraits > @@ -603,7 +603,7 @@ namespace bulkio { */ template <> - int InPortBase< FilePortTraits >::_getElementLength(const char* /*unused*/) + int InPortBase< FilePortTraits >::_getElementLength(const std::string& /*unused*/) { return 1; } @@ -612,15 +612,6 @@ namespace bulkio { * Specializations of base class methods for dataFile ports */ - template <> - int InPortBase< XMLPortTraits >::_getElementLength(const char* data) - { - if (!data) { - return 0; - } - return strlen(data); - } - // template < typename PortTraits > InPort< PortTraits >::InPort(std::string port_name, @@ -648,15 +639,15 @@ namespace bulkio { template < typename PortTraits > void InPort< PortTraits >::pushPacket(const PortSequenceType& data, const BULKIO::PrecisionUTCTime& T, CORBA::Boolean EOS, const char* streamID) { - this->queuePacket(data, T, EOS, streamID); + size_t size = data.length(); + TransportType* ptr = const_cast(data).get_buffer(1); + this->queuePacket(SharedBufferType(reinterpret_cast(ptr), size), T, EOS, streamID); } template < typename PortTraits > void InPort< PortTraits >::pushPacket(const SharedBufferType& data, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID) { - const TransportType* ptr = reinterpret_cast(data.data()); - const PortSequenceType buffer(data.size(), data.size(), const_cast(ptr), false); - this->queuePacket(buffer, T, EOS, streamID.c_str()); + this->queuePacket(data, T, EOS, streamID); } template < typename PortTraits > diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h index 006eb3254..ed7fa161c 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h @@ -77,6 +77,8 @@ namespace bulkio { // Queue of data transfer objects maintained by the port typedef std::deque< DataTransferType * > WorkQueue; + typedef typename Traits::SharedBufferType SharedBufferType; + // // ~InPortBase - call the virtual destructor to remove all allocated memebers // @@ -308,7 +310,7 @@ namespace bulkio { // Queues a packet received via pushPacket; in most cases, this method maps // exactly to pushPacket, except for dataFile // - void queuePacket(PushArgumentType data, const BULKIO::PrecisionUTCTime& T, CORBA::Boolean EOS, const std::string& streamID); + void queuePacket(const SharedBufferType& data, const BULKIO::PrecisionUTCTime& T, CORBA::Boolean EOS, const std::string& streamID); // // Returns a pointer to the first packet in the queue, blocking for up to @@ -333,7 +335,7 @@ namespace bulkio { // statistical tracking; enables XML and File specialization, which have // different notions of size // - int _getElementLength(PushArgumentType data); + int _getElementLength(const SharedBufferType& data); }; template < typename PortTraits > diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_traits.h b/bulkioInterfaces/libsrc/cpp/bulkio_traits.h index bce9c3b0e..0afe7d819 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_traits.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_traits.h @@ -100,13 +100,15 @@ struct DataTransfer { typedef typename Traits::TransportType TransportType; typedef typename Traits::NativeDataType NativeDataType; typedef typename Traits::DataBufferType DataBufferType; + typedef typename Traits::SharedBufferType SharedBufferType; // // Construct a DataTransfer object to be returned from an InPort's getPacket method // - DataTransfer(const PortSequenceType & data, const BULKIO::PrecisionUTCTime &_T, bool _EOS, const char* _streamID, BULKIO::StreamSRI &_H, bool _sriChanged, bool _inputQueueFlushed); + DataTransfer(const SharedBufferType& data, const BULKIO::PrecisionUTCTime &_T, bool _EOS, const char* _streamID, BULKIO::StreamSRI &_H, bool _sriChanged, bool _inputQueueFlushed); - DataBufferType dataBuffer; + SharedBufferType buffer; + DataBufferType dataBuffer; BULKIO::PrecisionUTCTime T; bool EOS; std::string streamID; @@ -133,9 +135,9 @@ struct DataTransfer< StringDataTransferTraits > typedef Traits::PortSequenceType PortSequenceType; typedef Traits::DataBufferType DataBufferType; - DataTransfer(const char *data, const BULKIO::PrecisionUTCTime &_T, bool _EOS, const char* _streamID, BULKIO::StreamSRI &_H, bool _sriChanged, bool _inputQueueFlushed) + DataTransfer(const std::string& data, const BULKIO::PrecisionUTCTime &_T, bool _EOS, const char* _streamID, BULKIO::StreamSRI &_H, bool _sriChanged, bool _inputQueueFlushed) { - if ( data != NULL ) dataBuffer = data; + dataBuffer = data; T = _T; EOS = _EOS; streamID = _streamID; @@ -143,9 +145,9 @@ struct DataTransfer< StringDataTransferTraits > sriChanged = _sriChanged; inputQueueFlushed = _inputQueueFlushed; } - DataTransfer(const char * data, bool _EOS, const char* _streamID, BULKIO::StreamSRI &_H, bool _sriChanged, bool _inputQueueFlushed) + DataTransfer(const std::string& data, bool _EOS, const char* _streamID, BULKIO::StreamSRI &_H, bool _sriChanged, bool _inputQueueFlushed) { - if ( data != NULL ) dataBuffer = data; + dataBuffer = data; EOS = _EOS; streamID = _streamID; SRI = _H; From 09e368e5b6b04403530b88863d4f6fa09d4ec2eb Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 14 Apr 2016 14:42:40 -0400 Subject: [PATCH 0117/1644] Partially update input streams to use shared buffers --- .../libsrc/cpp/bulkio_datablock.cpp | 20 +++++++++++----- .../libsrc/cpp/bulkio_datablock.h | 4 ++++ .../libsrc/cpp/bulkio_in_stream.cpp | 24 +++++++++---------- 3 files changed, 29 insertions(+), 19 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_datablock.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_datablock.cpp index 61d0a4fda..5c4043a2d 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_datablock.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_datablock.cpp @@ -33,7 +33,7 @@ using bulkio::DataBlock; template struct DataBlock::Impl { - std::vector data; + redhawk::read_buffer data; BULKIO::StreamSRI sri; std::list timestamps; int sriChangeFlags; @@ -50,7 +50,7 @@ template DataBlock::DataBlock(const BULKIO::StreamSRI& sri, size_t size) : _impl(new Impl()) { - _impl->data.resize(size); + _impl->data = redhawk::buffer(size); _impl->sri = sri; } @@ -79,13 +79,13 @@ double DataBlock::xdelta() const template T* DataBlock::data() { - return &(_impl->data[0]); + return const_cast(_impl->data.data()); } template const T* DataBlock::data() const { - return &(_impl->data[0]); + return _impl->data.data(); } template @@ -97,7 +97,8 @@ size_t DataBlock::size() const template void DataBlock::resize(size_t count) { - _impl->data.resize(count); + // TODO: Copy data + _impl->data = redhawk::buffer(count); } template @@ -222,7 +223,14 @@ void DataBlock::inputQueueFlushed(bool flushed) template void DataBlock::swap(std::vector& other) { - _impl->data.swap(other); + // TODO + //_impl->data.swap(other); +} + +template +void DataBlock::buffer(const redhawk::read_buffer& data) +{ + _impl->data = data; } // Instantiate templates for supported types diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_datablock.h b/bulkioInterfaces/libsrc/cpp/bulkio_datablock.h index 4e76bd905..7e5f5530c 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_datablock.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_datablock.h @@ -26,6 +26,8 @@ #include +#include + #include namespace bulkio { @@ -87,6 +89,8 @@ namespace bulkio { } void swap(std::vector& other); + + void buffer(const redhawk::read_buffer& other); private: struct Impl; boost::shared_ptr _impl; diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp index e2cd2547a..ac2ec1b79 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp @@ -57,7 +57,7 @@ class InputStream::Impl { typedef PortTraits TraitsType; typedef DataTransfer DataTransferType; typedef typename DataTransferType::NativeDataType NativeType; - typedef std::vector VectorType; + typedef typename PortTraits::SharedBufferType SharedBufferType; typedef DataBlock DataBlockType; Impl(const BULKIO::StreamSRI& sri, bulkio::InPort* port) : @@ -135,7 +135,7 @@ class InputStream::Impl { if (_samplesQueued == 0) { return DataBlockType(); } - const size_t samples = _queue.front()->dataBuffer.size() - _sampleOffset; + const size_t samples = _queue.front()->buffer.size() - _sampleOffset; return _readData(samples, samples); } @@ -255,7 +255,7 @@ class InputStream::Impl { void _consumeData(size_t count) { while (count > 0) { - const VectorType& data = _queue.front()->dataBuffer; + const SharedBufferType& data = _queue.front()->buffer; const size_t available = data.size() - _sampleOffset; const size_t pass = std::min(available, count); @@ -281,9 +281,6 @@ class InputStream::Impl { _port->removeStream(_streamID); } - // The packet buffer was allocated with new[] by the CORBA layer, while - // vector will use non-array delete, so explicitly delete the buffer - delete[] steal_buffer(packet->dataBuffer); delete packet; _queue.erase(_queue.begin()); @@ -314,19 +311,20 @@ class InputStream::Impl { front->inputQueueFlushed = false; } - if ((count <= consume) && (_sampleOffset == 0) && (front->dataBuffer.size() == count)) { + if ((count <= consume) && (_sampleOffset == 0) && (front->buffer.size() == count)) { // Optimization: when the read aligns perfectly with the front packet's // data buffer, and the entire packet is being consumed, swap the vector // data data.addTimestamp(bulkio::SampleTimestamp(front->T, 0)); - data.swap(front->dataBuffer); + data.buffer(front->buffer); _samplesQueued -= count; _consumePacket(); return data; } - data.resize(count); - NativeType* data_buffer = data.data(); + redhawk::buffer buffer(count); + data.buffer(buffer); + NativeType* data_buffer = buffer.data(); size_t data_offset = 0; // Assemble data that may span several input packets into the output buffer @@ -334,7 +332,7 @@ class InputStream::Impl { size_t packet_offset = _sampleOffset; while (count > 0) { DataTransferType* packet = _queue[packet_index]; - const VectorType& input_data = packet->dataBuffer; + const SharedBufferType& input_data = packet->buffer; // Determine the timestamp of this chunk of data; if this is the // first chunk, the packet offset (number of samples already read) @@ -424,7 +422,7 @@ class InputStream::Impl { void _queuePacket(DataTransferType* packet) { - if (packet->EOS && packet->dataBuffer.empty()) { + if (packet->EOS && packet->buffer.empty()) { // Handle end-of-stream packet with no data (assuming that timestamps, // SRI changes, and queue flushes are irrelevant at this point) if (_queue.empty()) { @@ -438,7 +436,7 @@ class InputStream::Impl { } delete packet; } else { - _samplesQueued += packet->dataBuffer.size(); + _samplesQueued += packet->buffer.size(); _queue.push_back(packet); } } From 6c0528dfb7f91d8a6fbac564a6d517dc7b8a57e3 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 14 Apr 2016 16:55:58 -0400 Subject: [PATCH 0118/1644] Use the slice method to return partial buffers from input stream, avoiding copies more frequently and simplifying the logic. --- .../libsrc/cpp/bulkio_in_stream.cpp | 123 +++++++++--------- 1 file changed, 62 insertions(+), 61 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp index ac2ec1b79..4ae1f5f10 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp @@ -135,6 +135,7 @@ class InputStream::Impl { if (_samplesQueued == 0) { return DataBlockType(); } + // Only read up to the end of the first packet in the queue const size_t samples = _queue.front()->buffer.size() - _sampleOffset; return _readData(samples, samples); } @@ -311,67 +312,43 @@ class InputStream::Impl { front->inputQueueFlushed = false; } - if ((count <= consume) && (_sampleOffset == 0) && (front->buffer.size() == count)) { - // Optimization: when the read aligns perfectly with the front packet's - // data buffer, and the entire packet is being consumed, swap the vector - // data - data.addTimestamp(bulkio::SampleTimestamp(front->T, 0)); - data.buffer(front->buffer); - _samplesQueued -= count; - _consumePacket(); - return data; - } - - redhawk::buffer buffer(count); - data.buffer(buffer); - NativeType* data_buffer = buffer.data(); - size_t data_offset = 0; - - // Assemble data that may span several input packets into the output buffer - size_t packet_index = 0; - size_t packet_offset = _sampleOffset; - while (count > 0) { - DataTransferType* packet = _queue[packet_index]; - const SharedBufferType& input_data = packet->buffer; - - // Determine the timestamp of this chunk of data; if this is the - // first chunk, the packet offset (number of samples already read) - // must be accounted for, so adjust the timestamp based on the SRI. - // Otherwise, the adjustment is a noop. - BULKIO::PrecisionUTCTime time = packet->T; - double time_offset = packet_offset * packet->SRI.xdelta; - size_t sample_offset = data_offset; - if (packet->SRI.mode) { - // Complex data; each sample is two values - time_offset /= 2.0; - sample_offset /= 2; - } - - // If there is a time offset, apply the adjustment and mark the timestamp - // so that the caller knows it was calculated rather than received - bool synthetic = false; - if (time_offset > 0.0) { - time += time_offset; - synthetic = true; - } - - data.addTimestamp(bulkio::SampleTimestamp(time, sample_offset, synthetic)); - - // The number of samples copied on this pass may be less than the total - // remaining - const size_t available = input_data.size() - packet_offset; - const size_t pass = std::min(available, count); - - std::copy(&input_data[packet_offset], &input_data[packet_offset+pass], &data_buffer[data_offset]); - data_offset += pass; - packet_offset += pass; - count -= pass; - - // If all the data from the current packet has been read, move on to - // the next - if (packet_offset >= input_data.size()) { - packet_offset = 0; - ++packet_index; + size_t last_offset = _sampleOffset + count; + if (last_offset <= front->buffer.size()) { + // The requsted sample count can be satisfied from the first packet + _addTimestamp(data, _sampleOffset, 0, front->T); + data.buffer(front->buffer.slice(_sampleOffset, last_offset)); + } else { + // We have to span multiple packets to get the data + redhawk::buffer buffer(count); + data.buffer(buffer); + size_t data_offset = 0; + + // Assemble data spanning several input packets into the output buffer + size_t packet_index = 0; + size_t packet_offset = _sampleOffset; + while (count > 0) { + DataTransferType* packet = _queue[packet_index]; + const SharedBufferType& input_data = packet->buffer; + + // Add the timestamp for this pass + _addTimestamp(data, packet_offset, data_offset, packet->T); + + // The number of samples copied on this pass may be less than the total + // remaining + const size_t available = input_data.size() - packet_offset; + const size_t pass = std::min(available, count); + + std::copy(&input_data[packet_offset], &input_data[packet_offset+pass], &buffer[data_offset]); + data_offset += pass; + packet_offset += pass; + count -= pass; + + // If all the data from the current packet has been read, move on to + // the next + if (packet_offset >= input_data.size()) { + packet_offset = 0; + ++packet_index; + } } } @@ -381,6 +358,30 @@ class InputStream::Impl { return data; } + void _addTimestamp(DataBlockType& data, size_t input_offset, size_t output_offset, BULKIO::PrecisionUTCTime time) + { + // Determine the timestamp of this chunk of data; if this is the + // first chunk, the packet offset (number of samples already read) + // must be accounted for, so adjust the timestamp based on the SRI. + // Otherwise, the adjustment is a noop. + double time_offset = input_offset * data.xdelta(); + if (data.complex()) { + // Complex data; each sample is two values + time_offset /= 2.0; + output_offset /= 2; + } + + // If there is a time offset, apply the adjustment and mark the timestamp + // so that the caller knows it was calculated rather than received + bool synthetic = false; + if (time_offset > 0.0) { + time += time_offset; + synthetic = true; + } + + data.addTimestamp(bulkio::SampleTimestamp(time, output_offset, synthetic)); + } + const BULKIO::StreamSRI* _nextSRI(bool blocking) { if (_queue.empty()) { From b03dd233035d33cec52aaec79f96209547474965 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 14 Apr 2016 17:13:48 -0400 Subject: [PATCH 0119/1644] Drop no longer used vector stealing routine --- .../libsrc/cpp/bulkio_in_stream.cpp | 27 ------------------- 1 file changed, 27 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp index 4ae1f5f10..5a435be05 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp @@ -22,33 +22,6 @@ #include "bulkio_time_operators.h" #include "bulkio_in_port.h" -namespace { - template - class stealable_vector : public std::vector { - public: - stealable_vector() - { - } - - T* steal() - { - T* out = this->_M_impl._M_start; - this->_M_impl._M_start = 0; - this->_M_impl._M_finish = 0; - this->_M_impl._M_end_of_storage = 0; - return out; - } - }; - - template - T* steal_buffer(std::vector& vec) - { - stealable_vector other; - std::swap(vec, other); - return other.steal(); - } -} - using bulkio::InputStream; template From 72edfa58a9de6b3a1b646d8d80a2b3cf1a028282 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 14 Apr 2016 17:14:47 -0400 Subject: [PATCH 0120/1644] Add buffer-based accessors for DataBlock; these should be the preferred way to access the data --- bulkioInterfaces/libsrc/cpp/bulkio_datablock.cpp | 12 ++++++++++++ bulkioInterfaces/libsrc/cpp/bulkio_datablock.h | 5 +++++ 2 files changed, 17 insertions(+) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_datablock.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_datablock.cpp index 5c4043a2d..684e97729 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_datablock.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_datablock.cpp @@ -227,6 +227,18 @@ void DataBlock::swap(std::vector& other) //_impl->data.swap(other); } +template +typename DataBlock::ScalarBuffer DataBlock::buffer() const +{ + return _impl->data; +} + +template +typename DataBlock::ComplexBuffer DataBlock::cxbuffer() const +{ + return ComplexBuffer::recast(_impl->data); +} + template void DataBlock::buffer(const redhawk::read_buffer& data) { diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_datablock.h b/bulkioInterfaces/libsrc/cpp/bulkio_datablock.h index 7e5f5530c..10cd81fd5 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_datablock.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_datablock.h @@ -52,6 +52,8 @@ namespace bulkio { public: typedef T ScalarType; typedef std::complex ComplexType; + typedef redhawk::read_buffer ScalarBuffer; + typedef redhawk::read_buffer ComplexBuffer; DataBlock(); DataBlock(const BULKIO::StreamSRI& sri, size_t size=0); @@ -90,6 +92,9 @@ namespace bulkio { void swap(std::vector& other); + ScalarBuffer buffer() const; + ComplexBuffer cxbuffer() const; + void buffer(const redhawk::read_buffer& other); private: struct Impl; From 90901e27644bf5d479f2dfc4bbd0de4884e201e4 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 14 Apr 2016 17:15:44 -0400 Subject: [PATCH 0121/1644] Prefer make_shared over direct construction --- bulkioInterfaces/libsrc/cpp/bulkio_datablock.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_datablock.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_datablock.cpp index 684e97729..59bdd9f1b 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_datablock.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_datablock.cpp @@ -48,7 +48,7 @@ DataBlock::DataBlock() : template DataBlock::DataBlock(const BULKIO::StreamSRI& sri, size_t size) : - _impl(new Impl()) + _impl(boost::make_shared()) { _impl->data = redhawk::buffer(size); _impl->sri = sri; From a3d3403ed150620222a5ed607e56b88f9b44aad8 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 15 Apr 2016 11:57:39 -0400 Subject: [PATCH 0122/1644] Change input port queueing to use shared buffers and restore DataTransfer to its old structure; copy into vector on getPacket(), which carries a performance hit, but is going to be deprecated anyway. --- bulkioInterfaces/libsrc/cpp/bulkio.cpp | 19 ++- .../libsrc/cpp/bulkio_in_port.cpp | 123 +++++++++--------- bulkioInterfaces/libsrc/cpp/bulkio_in_port.h | 35 ++++- .../libsrc/cpp/bulkio_in_stream.cpp | 20 +-- bulkioInterfaces/libsrc/cpp/bulkio_traits.h | 42 +++--- 5 files changed, 144 insertions(+), 95 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio.cpp b/bulkioInterfaces/libsrc/cpp/bulkio.cpp index aef0d54fa..f1b1bc1cb 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio.cpp @@ -236,8 +236,7 @@ namespace bulkio { template < typename DataTransferTraits > - DataTransfer< DataTransferTraits >::DataTransfer(const SharedBufferType& data, const BULKIO::PrecisionUTCTime &_T, bool _EOS, const char* _streamID, BULKIO::StreamSRI &_H, bool _sriChanged, bool _inputQueueFlushed) : - buffer(data), + DataTransfer< DataTransferTraits >::DataTransfer(const PortSequenceType& data, const BULKIO::PrecisionUTCTime &_T, bool _EOS, const char* _streamID, BULKIO::StreamSRI &_H, bool _sriChanged, bool _inputQueueFlushed) : T(_T), EOS(_EOS), streamID(_streamID), @@ -245,6 +244,22 @@ namespace bulkio { sriChanged(_sriChanged), inputQueueFlushed(_inputQueueFlushed) { + const size_t dataLength = data.length(); + + typedef typename std::_Vector_base::_Vector_impl *VectorPtr; + + VectorPtr vectorPtr = (VectorPtr)(&dataBuffer); + + if (data.release()) { + vectorPtr->_M_start = const_cast(&data)->get_buffer(1); + } else { + // Somebody else owns the data; make a copy + vectorPtr->_M_start = vectorPtr->allocate(dataLength); + const void* buffer = data.get_buffer(); + memcpy(vectorPtr->_M_start, buffer, dataLength*sizeof(NativeDataType)); + } + vectorPtr->_M_finish = vectorPtr->_M_start + dataLength; + vectorPtr->_M_end_of_storage = vectorPtr->_M_finish; } diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp index 2b28a95ed..6e64dff96 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp @@ -17,8 +17,9 @@ * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see http://www.gnu.org/licenses/. */ -#include +#include +#include #include namespace bulkio { @@ -91,13 +92,12 @@ namespace bulkio { // block any data coming out of getPacket.. block(); - LOG_TRACE( logger, "PORT:" << name << " DUMP PKTS:" << workQueue.size() ); + LOG_TRACE( logger, "PORT:" << name << " DUMP PKTS:" << packetQueue.size() ); // purge the queue... - while (workQueue.size() != 0) { - DataTransferType *tmp = workQueue.front(); - workQueue.pop_front(); - delete tmp; + while (packetQueue.size() != 0) { + delete packetQueue.front(); + packetQueue.pop_front(); } // clean up allocated containers @@ -122,9 +122,9 @@ namespace bulkio { BULKIO::PortUsageType InPortBase< PortTraits >::state() { SCOPED_LOCK lock(dataBufferLock); - if (workQueue.size() == maxQueue) { + if (packetQueue.size() == maxQueue) { return BULKIO::BUSY; - } else if (workQueue.size() == 0) { + } else if (packetQueue.empty()) { return BULKIO::IDLE; } else { return BULKIO::ACTIVE; @@ -163,7 +163,7 @@ namespace bulkio { int InPortBase< PortTraits >::getCurrentQueueDepth() { SCOPED_LOCK lock(dataBufferLock); - return workQueue.size(); + return packetQueue.size(); } template < typename PortTraits > @@ -255,24 +255,24 @@ namespace bulkio { SCOPED_LOCK lock(dataBufferLock); LOG_DEBUG(logger, "bulkio::InPort port blocking:" << blocking); if (blocking) { - while (workQueue.size() == maxQueue) { + while (packetQueue.size() >= maxQueue) { queueAvailable.wait(lock); } } else { bool sriChangedHappened = false; bool flagEOS = false; - if (workQueue.size() >= maxQueue) { // reached maximum queue depth - flush the queue - LOG_DEBUG( logger, "bulkio::InPort pushPacket PURGE INPUT QUEUE (SIZE" << workQueue.size() << ")" ); + if (packetQueue.size() >= maxQueue) { // reached maximum queue depth - flush the queue + LOG_DEBUG( logger, "bulkio::InPort pushPacket PURGE INPUT QUEUE (SIZE" << packetQueue.size() << ")" ); flushToReport = true; - while (workQueue.size() != 0) { - DataTransferType *tmp = workQueue.front(); + while (packetQueue.size() != 0) { + Packet *tmp = packetQueue.front(); if (tmp->sriChanged == true) { sriChangedHappened = true; } if (tmp->EOS == true) { flagEOS = true; } - workQueue.pop_front(); + packetQueue.pop_front(); delete tmp; } } @@ -284,10 +284,10 @@ namespace bulkio { } } - LOG_TRACE(logger, "bulkio::InPort pushPacket NEW PACKET (QUEUE" << workQueue.size()+1 << ")"); - stats->update(length, (float)(workQueue.size()+1)/(float)maxQueue, EOS, streamID, false); - DataTransferType *tmpIn = new DataTransferType(data, T, EOS, streamID.c_str(), *sri, sriChanged, flushToReport); - workQueue.push_back(tmpIn); + LOG_TRACE(logger, "bulkio::InPort pushPacket NEW PACKET (QUEUE" << packetQueue.size()+1 << ")"); + stats->update(length, (float)(packetQueue.size()+1)/(float)maxQueue, EOS, streamID, false); + Packet *tmpIn = new Packet(data, T, EOS, *sri, sriChanged, flushToReport); + packetQueue.push_back(tmpIn); dataAvailable.notify_all(); } @@ -298,13 +298,13 @@ namespace bulkio { template < typename PortTraits > - typename InPortBase< PortTraits >::DataTransferType* InPortBase< PortTraits >::peekPacket(float timeout) + typename InPortBase< PortTraits >::Packet* InPortBase< PortTraits >::peekPacket(float timeout) { uint64_t secs = (unsigned long)(trunc(timeout)); uint64_t msecs = (unsigned long)((timeout - secs) * 1e6); boost::system_time to_time = boost::get_system_time() + boost::posix_time::seconds(secs) + boost::posix_time::microseconds(msecs); boost::mutex::scoped_lock lock(this->dataBufferLock); - while (!breakBlock && workQueue.empty()) { + while (!breakBlock && packetQueue.empty()) { if (timeout == 0) { break; } else if (timeout > 0) { @@ -316,10 +316,10 @@ namespace bulkio { } } - if (breakBlock || workQueue.empty()) { + if (breakBlock || packetQueue.empty()) { return 0; } else { - return workQueue.front(); + return packetQueue.front(); } } @@ -404,53 +404,61 @@ namespace bulkio { template < typename PortTraits > typename InPortBase< PortTraits >::DataTransferType * InPortBase< PortTraits >::getPacket(float timeout, const std::string& streamID) { - TRACE_ENTER( logger, "InPort::getPacket" ); + boost::scoped_ptr packet(nextPacket(timeout, streamID)); + DataTransferType* transfer = new DataTransferType(PortSequenceType(), packet->T, packet->EOS, packet->streamID.c_str(), packet->SRI, packet->sriChanged, packet->inputQueueFlushed); + transfer->dataBuffer.assign(packet->buffer.begin(), packet->buffer.end()); + return transfer; + } + + + template + typename InPortBase::Packet* InPortBase::nextPacket(float timeout, const std::string& streamID) + { + TRACE_ENTER(logger, "InPort::nextPacket"); if (breakBlock) { - TRACE_EXIT( logger, "InPort::getPacket" ); + TRACE_EXIT(logger, "InPort::nextPacket"); return NULL; } - DataTransferType *tmp=NULL; + Packet* packet = 0; { SCOPED_LOCK lock(dataBufferLock); - tmp = fetchPacket(streamID); + packet = fetchPacket(streamID); uint64_t secs = (unsigned long)(trunc(timeout)); uint64_t msecs = (unsigned long)((timeout - secs) * 1e6); boost::system_time to_time = boost::get_system_time() + boost::posix_time::seconds(secs) + boost::posix_time::microseconds(msecs); - while (!tmp) { + while (!packet) { if (timeout == 0.0) { - TRACE_EXIT( logger, "InPort::getPacket" ); + TRACE_EXIT(logger, "InPort::nextPacket"); return NULL; } else if (timeout > 0){ if (!dataAvailable.timed_wait(lock, to_time)) { - TRACE_EXIT( logger, "InPort::getPacket" ); + TRACE_EXIT(logger, "InPort::nextPacket"); return NULL; } } else { dataAvailable.wait(lock); } if (breakBlock) { - TRACE_EXIT( logger, "InPort::getPacket" ); + TRACE_EXIT(logger, "InPort::nextPacket"); return NULL; } - tmp = fetchPacket(streamID); + packet = fetchPacket(streamID); } - LOG_TRACE( logger, "bulkio.InPort getPacket PORT:" << name << " (QUEUE="<< workQueue.size() << ")" ); - if (tmp) { - queueAvailable.notify_all(); + if (!packet) { + TRACE_EXIT(logger, "InPort::nextPacket"); + return NULL; } - } - if (!tmp) { - TRACE_EXIT( logger, "InPort::getPacket" ); - return NULL; + LOG_TRACE(logger, "InPort::nextPacket PORT:" << name << " (QUEUE="<< packetQueue.size() << ")"); + queueAvailable.notify_all(); } bool turnOffBlocking = false; - if (tmp->EOS) { + if (packet->EOS) { SCOPED_LOCK lock2(sriUpdateLock); - SriMap::iterator target = currentHs.find(std::string(tmp->streamID)); + SriMap::iterator target = currentHs.find(packet->streamID); if (target != currentHs.end()) { bool sriBlocking = target->second.first.blocking; currentHs.erase(target); @@ -474,27 +482,27 @@ namespace bulkio { } } - TRACE_EXIT( logger, "InPort::getPacket" ); - return tmp; + TRACE_EXIT( logger, "InPort::nextPacket" ); + return packet; } template < typename PortTraits > - typename InPortBase< PortTraits >::DataTransferType * InPortBase< PortTraits >::fetchPacket(const std::string &streamID) + typename InPortBase< PortTraits >::Packet * InPortBase< PortTraits >::fetchPacket(const std::string &streamID) { if (streamID.empty()) { - if (workQueue.empty()) { + if (packetQueue.empty()) { return 0; } - DataTransferType* packet = workQueue.front(); - workQueue.pop_front(); + Packet* packet = packetQueue.front(); + packetQueue.pop_front(); return packet; } - for (typename WorkQueue::iterator ii = workQueue.begin(); ii != workQueue.end(); ++ii) { + for (typename PacketQueue::iterator ii = packetQueue.begin(); ii != packetQueue.end(); ++ii) { if ((*ii)->streamID == streamID) { - DataTransferType* packet = *ii; - if (ii == workQueue.begin()) { + Packet* packet = *ii; + if (ii == packetQueue.begin()) { // PERFORMANCE NOTE: // In a 1-item deque, erase will end up calling pop_back(); however, // this can lead to greatly reduced performance (observed as 1/4 the @@ -504,9 +512,9 @@ namespace bulkio { // always cause allocation and deallocation. Explicitly calling // pop_front() if it's the first element prevents this worst case // scenario. - workQueue.pop_front(); + packetQueue.pop_front(); } else { - workQueue.erase(ii); + packetQueue.erase(ii); } return packet; } @@ -557,8 +565,8 @@ namespace bulkio { size_t samples = 0; size_t item_size = 1; SCOPED_LOCK lock(dataBufferLock); - for (typename WorkQueue::iterator iter = workQueue.begin(); iter != workQueue.end(); ++iter) { - DataTransferType* packet = *iter; + for (typename PacketQueue::iterator iter = packetQueue.begin(); iter != packetQueue.end(); ++iter) { + Packet* packet = *iter; if (packet->streamID != streamID) { continue; } @@ -569,7 +577,7 @@ namespace bulkio { if (packet->SRI.mode) { item_size = 2; } - samples += packet->dataBuffer.size(); + samples += packet->buffer.size(); } return samples / item_size; } @@ -665,10 +673,9 @@ namespace bulkio { // Otherwise, return the stream that owns the next packet on the queue, // potentially waiting for one to be received - DataTransferType* packet = this->peekPacket(timeout); + Packet* packet = this->peekPacket(timeout); if (packet) { - const std::string& streamID = packet->streamID; - return getStream(streamID); + return getStream(packet->streamID); } return StreamType(); diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h index ed7fa161c..77f2ac7eb 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h @@ -251,10 +251,32 @@ namespace bulkio { bulkio::sri::Compare sriCmp = bulkio::sri::DefaultComparator, SriListener *newStreamCB = NULL ); + struct Packet { + Packet(const SharedBufferType& buffer, const BULKIO::PrecisionUTCTime& T, bool EOS, const BULKIO::StreamSRI& SRI, bool sriChanged, bool inputQueueFlushed) : + buffer(buffer), + T(T), + EOS(EOS), + SRI(SRI), + sriChanged(sriChanged), + inputQueueFlushed(inputQueueFlushed), + streamID(SRI.streamID) + { + } + + SharedBufferType buffer; + BULKIO::PrecisionUTCTime T; + bool EOS; + BULKIO::StreamSRI SRI; + bool sriChanged; + bool inputQueueFlushed; + std::string streamID; + }; + // // FIFO of data vectors and time stamps waiting to be processed by a component // - WorkQueue workQueue; + typedef std::deque PacketQueue; + PacketQueue packetQueue; // // SRI compare method used by pushSRI method to determine how to match incoming SRI objects and streamsID @@ -312,11 +334,17 @@ namespace bulkio { // void queuePacket(const SharedBufferType& data, const BULKIO::PrecisionUTCTime& T, CORBA::Boolean EOS, const std::string& streamID); + // + // Fetches the next packet for the given stream ID, blocking for up to + // timeout seconds for one to be available + // + Packet* nextPacket(float timeout, const std::string& streamID); + // // Returns a pointer to the first packet in the queue, blocking for up to // timeout seconds for one to be available // - DataTransferType* peekPacket(float timeout); + Packet* peekPacket(float timeout); virtual void createStream(const std::string& streamID, const BULKIO::StreamSRI& sri); virtual void removeStream(const std::string& streamID); @@ -324,7 +352,7 @@ namespace bulkio { virtual bool isStreamActive(const std::string& streamID); virtual bool isStreamEnabled(const std::string& streamID); - DataTransferType* fetchPacket(const std::string& streamID); + Packet* fetchPacket(const std::string& streamID); void packetReceived(const std::string& streamID); friend class InputStream; @@ -449,6 +477,7 @@ namespace bulkio { typedef InPortBase super; using super::packetWaiters; using super::logger; + typedef typename super::Packet Packet; // Allow the input stream type friend access so it can call removeStream() // when it acknowledges an end-of-stream diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp index 5a435be05..2877e055e 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp @@ -28,8 +28,8 @@ template class InputStream::Impl { public: typedef PortTraits TraitsType; - typedef DataTransfer DataTransferType; - typedef typename DataTransferType::NativeDataType NativeType; + typedef typename InPort::Packet PacketType; + typedef typename PortTraits::NativeType NativeType; typedef typename PortTraits::SharedBufferType SharedBufferType; typedef DataBlock DataBlockType; @@ -249,7 +249,7 @@ class InputStream::Impl { void _consumePacket() { // Acknowledge any end-of-stream flag and delete the packet - DataTransferType* packet = _queue.front(); + PacketType* packet = _queue.front(); _eosReached = packet->EOS; if (_eosReached) { _port->removeStream(_streamID); @@ -268,7 +268,7 @@ class InputStream::Impl { DataBlockType _readData(size_t count, size_t consume) { // Acknowledge pending SRI change - DataTransferType* front = _queue.front(); + PacketType* front = _queue.front(); int sriChangeFlags = bulkio::sri::NONE; if (front->sriChanged) { sriChangeFlags = bulkio::sri::compareFields(_sri, front->SRI); @@ -300,7 +300,7 @@ class InputStream::Impl { size_t packet_index = 0; size_t packet_offset = _sampleOffset; while (count > 0) { - DataTransferType* packet = _queue[packet_index]; + PacketType* packet = _queue[packet_index]; const SharedBufferType& input_data = packet->buffer; // Add the timestamp for this pass @@ -379,7 +379,7 @@ class InputStream::Impl { } float timeout = blocking?bulkio::Const::BLOCKING:bulkio::Const::NON_BLOCKING; - DataTransferType* packet = _port->getPacket(timeout, _streamID); + PacketType* packet = _port->nextPacket(timeout, _streamID); if (!packet) { return false; } @@ -394,7 +394,7 @@ class InputStream::Impl { } } - void _queuePacket(DataTransferType* packet) + void _queuePacket(PacketType* packet) { if (packet->EOS && packet->buffer.empty()) { // Handle end-of-stream packet with no data (assuming that timestamps, @@ -415,7 +415,7 @@ class InputStream::Impl { } } - bool _canBridge(DataTransferType* packet) const + bool _canBridge(PacketType* packet) const { return !(packet->sriChanged || packet->inputQueueFlushed); } @@ -425,8 +425,8 @@ class InputStream::Impl { bool _eosReceived; bool _eosReached; InPort* _port; - std::vector _queue; - DataTransferType* _pending; + std::vector _queue; + PacketType* _pending; size_t _samplesQueued; size_t _sampleOffset; bool _enabled; diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_traits.h b/bulkioInterfaces/libsrc/cpp/bulkio_traits.h index 0afe7d819..3c1f0acc6 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_traits.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_traits.h @@ -100,31 +100,29 @@ struct DataTransfer { typedef typename Traits::TransportType TransportType; typedef typename Traits::NativeDataType NativeDataType; typedef typename Traits::DataBufferType DataBufferType; - typedef typename Traits::SharedBufferType SharedBufferType; // // Construct a DataTransfer object to be returned from an InPort's getPacket method // - DataTransfer(const SharedBufferType& data, const BULKIO::PrecisionUTCTime &_T, bool _EOS, const char* _streamID, BULKIO::StreamSRI &_H, bool _sriChanged, bool _inputQueueFlushed); + DataTransfer(const PortSequenceType& data, const BULKIO::PrecisionUTCTime &_T, bool _EOS, const char* _streamID, BULKIO::StreamSRI &_H, bool _sriChanged, bool _inputQueueFlushed); - SharedBufferType buffer; DataBufferType dataBuffer; - BULKIO::PrecisionUTCTime T; - bool EOS; - std::string streamID; - BULKIO::StreamSRI SRI; - bool sriChanged; - bool inputQueueFlushed; - - redhawk::PropertyMap& getKeywords() - { - return redhawk::PropertyMap::cast(SRI.keywords); - } + BULKIO::PrecisionUTCTime T; + bool EOS; + std::string streamID; + BULKIO::StreamSRI SRI; + bool sriChanged; + bool inputQueueFlushed; + + redhawk::PropertyMap& getKeywords() + { + return redhawk::PropertyMap::cast(SRI.keywords); + } - const redhawk::PropertyMap& getKeywords() const - { - return redhawk::PropertyMap::cast(SRI.keywords); - } + const redhawk::PropertyMap& getKeywords() const + { + return redhawk::PropertyMap::cast(SRI.keywords); + } }; @@ -135,9 +133,9 @@ struct DataTransfer< StringDataTransferTraits > typedef Traits::PortSequenceType PortSequenceType; typedef Traits::DataBufferType DataBufferType; - DataTransfer(const std::string& data, const BULKIO::PrecisionUTCTime &_T, bool _EOS, const char* _streamID, BULKIO::StreamSRI &_H, bool _sriChanged, bool _inputQueueFlushed) + DataTransfer(const char *data, const BULKIO::PrecisionUTCTime &_T, bool _EOS, const char* _streamID, BULKIO::StreamSRI &_H, bool _sriChanged, bool _inputQueueFlushed) { - dataBuffer = data; + if ( data != NULL ) dataBuffer = data; T = _T; EOS = _EOS; streamID = _streamID; @@ -145,9 +143,9 @@ struct DataTransfer< StringDataTransferTraits > sriChanged = _sriChanged; inputQueueFlushed = _inputQueueFlushed; } - DataTransfer(const std::string& data, bool _EOS, const char* _streamID, BULKIO::StreamSRI &_H, bool _sriChanged, bool _inputQueueFlushed) + DataTransfer(const char * data, bool _EOS, const char* _streamID, BULKIO::StreamSRI &_H, bool _sriChanged, bool _inputQueueFlushed) { - dataBuffer = data; + if ( data != NULL ) dataBuffer = data; EOS = _EOS; streamID = _streamID; SRI = _H; From f1e86183ce3e846ff221edaf92d039ba2639f2c4 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 15 Apr 2016 13:01:37 -0400 Subject: [PATCH 0123/1644] Use make_transient to handle converting vector and raw pointer data to shared buffers --- .../libsrc/cpp/bulkio_connection.hpp | 10 +++++- .../libsrc/cpp/bulkio_out_port.cpp | 25 ++++++--------- bulkioInterfaces/libsrc/cpp/bulkio_out_port.h | 3 +- .../libsrc/cpp/bulkio_out_stream.cpp | 32 ++++++++----------- 4 files changed, 34 insertions(+), 36 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp b/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp index b906cc7a7..5c9cdefc4 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp @@ -236,7 +236,15 @@ namespace bulkio { bool EOS, const std::string& streamID) { - _port->pushPacket(data, T, EOS, streamID); + if (data.transient()) { + // The data comes from a non-shared source (a vector or raw pointer), + // so we need to make a copy. This could be optimized for the fanout + // case by making the copy at a higher level, but only if there's at + // least one local connection. + _port->pushPacket(data.copy(), T, EOS, streamID); + } else { + _port->pushPacket(data, T, EOS, streamID); + } } LocalPortType* _port; diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp index 430d7ba63..69f711d90 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp @@ -159,7 +159,6 @@ namespace bulkio { template < typename PortTraits > void OutPortBase< PortTraits >::_pushSinglePacket( const SharedBufferType& data, - bool shared, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID) @@ -493,8 +492,7 @@ namespace bulkio { bool EOS, const std::string& streamID) { - SharedBufferType buffer(&data[0], data.size(), null_deleter()); - this->_pushSinglePacket(buffer, false, T, EOS, streamID); + this->_pushSinglePacket(SharedBufferType::make_transient(&data[0], data.size()), T, EOS, streamID); } template < typename PortTraits > @@ -504,8 +502,7 @@ namespace bulkio { bool EOS, const std::string& streamID) { - SharedBufferType buffer(const_cast(&data[0]), data.size(), null_deleter()); - this->_pushSinglePacket(buffer, false, T, EOS, streamID); + this->_pushSinglePacket(SharedBufferType::make_transient(&data[0], data.size()), T, EOS, streamID); } template < typename PortTraits > @@ -516,19 +513,17 @@ namespace bulkio { bool EOS, const std::string& streamID) { - TransportType* ptr = const_cast(data); - SharedBufferType buffer(reinterpret_cast(ptr), size, null_deleter()); - this->_pushSinglePacket(buffer, false, T, EOS, streamID); + const NativeType* ptr = reinterpret_cast(data); + this->_pushSinglePacket(SharedBufferType::make_transient(ptr, size), T, EOS, streamID); } template < typename PortTraits > void OutPort< PortTraits >::pushPacket(const SharedBufferType& data, const BULKIO::PrecisionUTCTime& T, bool EOS, - const std::string& streamID, - bool shared) + const std::string& streamID) { - this->_pushSinglePacket(data, true, T, EOS, streamID); + this->_pushSinglePacket(data, T, EOS, streamID); } template < typename PortTraits > @@ -609,13 +604,13 @@ namespace bulkio { void OutFilePort::pushPacket(const std::string& URL, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID) { - _pushSinglePacket(URL, true, T, EOS, streamID); + _pushSinglePacket(URL, T, EOS, streamID); } void OutFilePort::pushPacket( const char *data, bool EOS, const std::string& streamID) { - _pushSinglePacket(data, true, bulkio::time::utils::now(), EOS, streamID); + _pushSinglePacket(data, bulkio::time::utils::now(), EOS, streamID); } @@ -640,7 +635,7 @@ namespace bulkio { void OutXMLPort::pushPacket(const char *data, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID) { - _pushSinglePacket(data, true, T, EOS, streamID); + _pushSinglePacket(data, T, EOS, streamID); } @@ -649,7 +644,7 @@ namespace bulkio { // The time argument is never dereferenced for dataXML, so it is safe to // pass a null BULKIO::PrecisionUTCTime* time = 0; - _pushSinglePacket(data, true, *time, EOS, streamID); + _pushSinglePacket(data, *time, EOS, streamID); } diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h index a95d856e8..db93c45ac 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h @@ -316,7 +316,6 @@ namespace bulkio { // releases the port lock // void _pushSinglePacket(const SharedBufferType& data, - bool shared, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID); @@ -451,7 +450,7 @@ namespace bulkio { */ void pushPacket( const DataBufferType & data, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID); - void pushPacket(const SharedBufferType& data, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID, bool shared); + void pushPacket(const SharedBufferType& data, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID); // Create a new stream based on a stream ID StreamType createStream(const std::string& streamID); diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp index 31cb812dd..bcaa14f0c 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp @@ -101,25 +101,25 @@ class OutputStream::Impl { _sriUpdated = true; } - void write(const ScalarBuffer& data, const BULKIO::PrecisionUTCTime& time, bool shared) + void write(const ScalarBuffer& data, const BULKIO::PrecisionUTCTime& time) { if (_sriUpdated) { _port->pushSRI(_sri); _sriUpdated = false; } - _port->pushPacket(data, time, false, _streamID, shared); + _port->pushPacket(data, time, false, _streamID); } - void write(const ComplexBuffer& data, const BULKIO::PrecisionUTCTime& time, bool shared) + void write(const ComplexBuffer& data, const BULKIO::PrecisionUTCTime& time) { if (_sri.mode == 0) { throw std::logic_error("stream mode is not complex"); } - write(ScalarBuffer::recast(data), time, shared); + write(ScalarBuffer::recast(data), time); } template - void write(const redhawk::read_buffer& data, const std::list& times, bool shared) + void write(const redhawk::read_buffer& data, const std::list& times) { std::list::const_iterator timestamp = times.begin(); if (timestamp == times.end()) { @@ -135,7 +135,7 @@ class OutputStream::Impl { } else { last = timestamp->offset; } - write(data.slice(first, last), when, shared); + write(data.slice(first, last), when); first = last; } } @@ -280,53 +280,49 @@ void OutputStream::eraseKeyword(const std::string& name) template void OutputStream::write(const ScalarBuffer& data, const BULKIO::PrecisionUTCTime& time) { - _impl->write(data, time, true); + _impl->write(data, time); } template void OutputStream::write(const ScalarBuffer& data, const std::list& times) { - _impl->write(data, times, true); + _impl->write(data, times); } template void OutputStream::write(const ComplexBuffer& data, const BULKIO::PrecisionUTCTime& time) { - _impl->write(data, time, true); + _impl->write(data, time); } template void OutputStream::write(const ComplexBuffer& data, const std::list& times) { - _impl->write(data, times, true); + _impl->write(data, times); } template void OutputStream::write(const ScalarType* data, size_t count, const BULKIO::PrecisionUTCTime& time) { - ScalarBuffer buffer(const_cast(data), count, null_deleter()); - _impl->write(buffer, time, false); + _impl->write(ScalarBuffer::make_transient(data, count), time); } template void OutputStream::write(const ScalarType* data, size_t count, const std::list& times) { - ScalarBuffer buffer(const_cast(data), count, null_deleter()); - _impl->write(buffer, times, false); + _impl->write(ScalarBuffer::make_transient(data, count), times); } template void OutputStream::write(const ComplexType* data, size_t count, const BULKIO::PrecisionUTCTime& time) { - ComplexBuffer buffer(const_cast(data), count, null_deleter()); - _impl->write(buffer, time, false); + _impl->write(ComplexBuffer::make_transient(data, count), time); } template void OutputStream::write(const ComplexType* data, size_t count, const std::list& times) { - ComplexBuffer buffer(const_cast(data), count, null_deleter()); - _impl->write(buffer, times, false); + _impl->write(ComplexBuffer::make_transient(data, count), times); } template From e349db7c427617d683b6255b653872b070b5bca8 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 18 Apr 2016 14:12:48 -0400 Subject: [PATCH 0124/1644] Protect against nulls --- .../libsrc/cpp/bulkio_in_port.cpp | 15 ++++++++--- .../libsrc/cpp/bulkio_out_port.cpp | 27 ++++++++++++++++--- bulkioInterfaces/libsrc/cpp/bulkio_out_port.h | 26 ++++++++++++++++++ 3 files changed, 61 insertions(+), 7 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp index 6e64dff96..4633ecf5a 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp @@ -404,9 +404,12 @@ namespace bulkio { template < typename PortTraits > typename InPortBase< PortTraits >::DataTransferType * InPortBase< PortTraits >::getPacket(float timeout, const std::string& streamID) { + DataTransferType* transfer = 0; boost::scoped_ptr packet(nextPacket(timeout, streamID)); - DataTransferType* transfer = new DataTransferType(PortSequenceType(), packet->T, packet->EOS, packet->streamID.c_str(), packet->SRI, packet->sriChanged, packet->inputQueueFlushed); - transfer->dataBuffer.assign(packet->buffer.begin(), packet->buffer.end()); + if (packet) { + transfer = new DataTransferType(PortSequenceType(), packet->T, packet->EOS, packet->streamID.c_str(), packet->SRI, packet->sriChanged, packet->inputQueueFlushed); + transfer->dataBuffer.assign(packet->buffer.begin(), packet->buffer.end()); + } return transfer; } @@ -871,14 +874,18 @@ namespace bulkio { template < typename PortTraits > void InStringPort< PortTraits >::pushPacket(const char *data, const BULKIO::PrecisionUTCTime& T, CORBA::Boolean EOS, const char* streamID) { - this->queuePacket(data, T, EOS, streamID); + if (!data) { + this->queuePacket(std::string(), T, EOS, streamID); + } else { + this->queuePacket(data, T, EOS, streamID); + } } template < typename PortTraits > void InStringPort< PortTraits >::pushPacket(const char *data, CORBA::Boolean EOS, const char* streamID) { - this->queuePacket(data, BULKIO::PrecisionUTCTime(), EOS, streamID); + this->pushPacket(data, BULKIO::PrecisionUTCTime(), EOS, streamID); } // diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp index 69f711d90..7b18594d5 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp @@ -607,10 +607,18 @@ namespace bulkio { _pushSinglePacket(URL, T, EOS, streamID); } + void OutFilePort::pushPacket(const char* URL, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID) + { + std::string url_out; + if (URL) { + url_out = URL; + } + this->pushPacket(url_out, T, EOS, streamID); + } - void OutFilePort::pushPacket( const char *data, bool EOS, const std::string& streamID) + void OutFilePort::pushPacket(const char *data, bool EOS, const std::string& streamID) { - _pushSinglePacket(data, bulkio::time::utils::now(), EOS, streamID); + this->pushPacket(data, bulkio::time::utils::now(), EOS, streamID); } @@ -635,7 +643,11 @@ namespace bulkio { void OutXMLPort::pushPacket(const char *data, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID) { - _pushSinglePacket(data, T, EOS, streamID); + std::string data_out; + if (data) { + data_out = data; + } + _pushSinglePacket(data_out, T, EOS, streamID); } @@ -647,6 +659,15 @@ namespace bulkio { _pushSinglePacket(data, *time, EOS, streamID); } + void OutXMLPort::pushPacket(const char* data, bool EOS, const std::string& streamID) + { + std::string data_out; + if (data) { + data_out = data; + } + this->pushPacket(data_out, EOS, streamID); + } + // // Required for Template Instantion for the compilation unit. diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h index db93c45ac..b4a477235 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h @@ -574,6 +574,22 @@ namespace bulkio { */ void pushPacket(const std::string& URL, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID); + /* + * pushPacket + * maps to dataFile BULKIO method call for passing the URL of a file + * + * data: string containing the file URL to send out + * T: constant of type BULKIO::PrecisionUTCTime containing the timestamp for the outgoing data. + * tcmode: timecode mode + * tcstatus: timecode status + * toff: fractional sample offset + * twsec: J1970 GMT + * tfsec: fractional seconds: 0.0 to 1.0 + * EOS: end-of-stream flag + * streamID: stream identifier + */ + void pushPacket(const char* URL, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID); + /* * DEPRECATED: maps to dataXML BULKIO method call for passing strings of data */ @@ -656,6 +672,16 @@ namespace bulkio { */ void pushPacket(const std::string& data, bool EOS, const std::string& streamID); + /* + * pushPacket + * maps to dataXML BULKIO method call for passing an XML-formatted string + * + * data: string containing the XML data to send out + * EOS: end-of-stream flag + * streamID: stream identifier + */ + void pushPacket(const char* data, bool EOS, const std::string& streamID); + }; From 9e3ddb1705734afa5c3a7aaf12bfa6cbf14c562b Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 19 Apr 2016 10:22:26 -0400 Subject: [PATCH 0125/1644] Push strings directly in local transfers --- bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp b/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp index 5c9cdefc4..0716cf759 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp @@ -256,7 +256,7 @@ namespace bulkio { bool EOS, const std::string& streamID) { - _port->pushPacket((bulkio::Char*)data.c_str(), T, EOS, streamID.c_str()); + _port->pushPacket(data, T, EOS, streamID); } template <> @@ -265,7 +265,7 @@ namespace bulkio { bool EOS, const std::string& streamID) { - _port->pushPacket((bulkio::Char*)data.c_str(), T, EOS, streamID.c_str()); + _port->pushPacket(data, T, EOS, streamID); } } From 5c19719a8aca960d5a656927865534f5eff4daae Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 19 Apr 2016 12:08:36 -0400 Subject: [PATCH 0126/1644] Use typedefs instead of explicit template parameters for port in stream classes --- bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp | 9 ++++----- bulkioInterfaces/libsrc/cpp/bulkio_in_stream.h | 3 ++- bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp | 8 ++++---- bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h | 3 ++- 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp index 2877e055e..b326503b7 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp @@ -27,13 +27,12 @@ using bulkio::InputStream; template class InputStream::Impl { public: - typedef PortTraits TraitsType; - typedef typename InPort::Packet PacketType; + typedef typename InPortType::Packet PacketType; typedef typename PortTraits::NativeType NativeType; typedef typename PortTraits::SharedBufferType SharedBufferType; typedef DataBlock DataBlockType; - Impl(const BULKIO::StreamSRI& sri, bulkio::InPort* port) : + Impl(const BULKIO::StreamSRI& sri, InPortType* port) : _streamID(sri.streamID), _sri(sri), _eosReceived(false), @@ -424,7 +423,7 @@ class InputStream::Impl { BULKIO::StreamSRI _sri; bool _eosReceived; bool _eosReached; - InPort* _port; + InPortType* _port; std::vector _queue; PacketType* _pending; size_t _samplesQueued; @@ -440,7 +439,7 @@ InputStream::InputStream() : } template -InputStream::InputStream(const BULKIO::StreamSRI& sri, bulkio::InPort* port) : +InputStream::InputStream(const BULKIO::StreamSRI& sri, InPortType* port) : _impl(new Impl(sri, port)) { } diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.h b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.h index 2940dcfe1..4eb20caf1 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.h @@ -70,7 +70,8 @@ namespace bulkio { private: friend class InPort; - InputStream(const BULKIO::StreamSRI&, InPort*); + typedef InPort InPortType; + InputStream(const BULKIO::StreamSRI&, InPortType*); bool hasBufferedData(); diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp index bcaa14f0c..b23c439f2 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp @@ -34,7 +34,7 @@ class OutputStream::Impl { typedef typename OutputStream::ScalarBuffer ScalarBuffer; typedef typename OutputStream::ComplexBuffer ComplexBuffer; - Impl(const std::string& streamID, bulkio::OutPort* port) : + Impl(const std::string& streamID, OutPortType* port) : _streamID(streamID), _port(port), _sri(bulkio::sri::create(streamID)), @@ -42,7 +42,7 @@ class OutputStream::Impl { { } - Impl(const BULKIO::StreamSRI& sri, bulkio::OutPort* port) : + Impl(const BULKIO::StreamSRI& sri, OutPortType* port) : _streamID(sri.streamID), _port(port), _sri(sri), @@ -164,7 +164,7 @@ class OutputStream::Impl { } const std::string _streamID; - OutPort* _port; + OutPortType* _port; BULKIO::StreamSRI _sri; bool _sriUpdated; }; @@ -176,7 +176,7 @@ OutputStream::OutputStream() : } template -OutputStream::OutputStream(const BULKIO::StreamSRI& sri, bulkio::OutPort* port) : +OutputStream::OutputStream(const BULKIO::StreamSRI& sri, OutPortType* port) : _impl(new Impl(sri, port)) { } diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h index e518ce303..b361dca77 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h @@ -139,7 +139,8 @@ namespace bulkio { private: friend class OutPort; - OutputStream(const BULKIO::StreamSRI& sri, OutPort* port); + typedef OutPort OutPortType; + OutputStream(const BULKIO::StreamSRI& sri, OutPortType* port); class Impl; boost::shared_ptr _impl; From c098316363a7bdbe823aee09ea520f8ccdf224b1 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 19 Apr 2016 12:11:35 -0400 Subject: [PATCH 0127/1644] Always use shared buffer interface in output stream; drop unused typedefs in implementation --- bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp index b23c439f2..3d65802f9 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp @@ -27,10 +27,6 @@ using bulkio::OutputStream; template class OutputStream::Impl { public: - typedef typename PortTraits::DataTransferTraits::NativeDataType ScalarType; - typedef std::complex ComplexType; - typedef typename PortTraits::DataTransferTraits::TransportType TransportType; - typedef typename OutputStream::ScalarBuffer ScalarBuffer; typedef typename OutputStream::ComplexBuffer ComplexBuffer; @@ -107,7 +103,7 @@ class OutputStream::Impl { _port->pushSRI(_sri); _sriUpdated = false; } - _port->pushPacket(data, time, false, _streamID); + _send(data, time, false); } void write(const ComplexBuffer& data, const BULKIO::PrecisionUTCTime& time) @@ -144,13 +140,13 @@ class OutputStream::Impl { { // Send an empty packet with an end-of-stream marker; since there is no // sample data, the timestamp does not matter - _send(0, 0, bulkio::time::utils::notSet(), true); + _send(ScalarBuffer(), bulkio::time::utils::notSet(), true); } private: - void _send(const TransportType* data, size_t count, const BULKIO::PrecisionUTCTime& time, bool eos) + void _send(const ScalarBuffer& data, const BULKIO::PrecisionUTCTime& time, bool eos) { - _port->pushPacket(data, count, time, eos, _streamID); + _port->pushPacket(data, time, eos, _streamID); } template From e2c3d64a883b20415b918e71da5251bd3c1f8020 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 19 Apr 2016 12:32:40 -0400 Subject: [PATCH 0128/1644] Use "shared_buffer" instead of "read_buffer" --- bulkioInterfaces/libsrc/cpp/bulkio_datablock.cpp | 4 ++-- bulkioInterfaces/libsrc/cpp/bulkio_datablock.h | 6 +++--- bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp | 2 +- bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h | 4 ++-- bulkioInterfaces/libsrc/cpp/bulkio_traits.h | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_datablock.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_datablock.cpp index 59bdd9f1b..2231fb157 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_datablock.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_datablock.cpp @@ -33,7 +33,7 @@ using bulkio::DataBlock; template struct DataBlock::Impl { - redhawk::read_buffer data; + redhawk::shared_buffer data; BULKIO::StreamSRI sri; std::list timestamps; int sriChangeFlags; @@ -240,7 +240,7 @@ typename DataBlock::ComplexBuffer DataBlock::cxbuffer() const } template -void DataBlock::buffer(const redhawk::read_buffer& data) +void DataBlock::buffer(const ScalarBuffer& data) { _impl->data = data; } diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_datablock.h b/bulkioInterfaces/libsrc/cpp/bulkio_datablock.h index 10cd81fd5..92faf7239 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_datablock.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_datablock.h @@ -52,8 +52,8 @@ namespace bulkio { public: typedef T ScalarType; typedef std::complex ComplexType; - typedef redhawk::read_buffer ScalarBuffer; - typedef redhawk::read_buffer ComplexBuffer; + typedef redhawk::shared_buffer ScalarBuffer; + typedef redhawk::shared_buffer ComplexBuffer; DataBlock(); DataBlock(const BULKIO::StreamSRI& sri, size_t size=0); @@ -95,7 +95,7 @@ namespace bulkio { ScalarBuffer buffer() const; ComplexBuffer cxbuffer() const; - void buffer(const redhawk::read_buffer& other); + void buffer(const ScalarBuffer& other); private: struct Impl; boost::shared_ptr _impl; diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp index 3d65802f9..0c341e202 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp @@ -115,7 +115,7 @@ class OutputStream::Impl { } template - void write(const redhawk::read_buffer& data, const std::list& times) + void write(const redhawk::shared_buffer& data, const std::list& times) { std::list::const_iterator timestamp = times.begin(); if (timestamp == times.end()) { diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h index b361dca77..7d60ec41f 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h @@ -43,8 +43,8 @@ namespace bulkio { typedef typename PortTraits::DataTransferTraits::NativeDataType ScalarType; typedef std::complex ComplexType; - typedef redhawk::read_buffer ScalarBuffer; - typedef redhawk::read_buffer ComplexBuffer; + typedef redhawk::shared_buffer ScalarBuffer; + typedef redhawk::shared_buffer ComplexBuffer; OutputStream(); diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_traits.h b/bulkioInterfaces/libsrc/cpp/bulkio_traits.h index 3c1f0acc6..4490cdb62 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_traits.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_traits.h @@ -51,7 +51,7 @@ template < typename TT, typename AT=_seqVector::seqVectorAllocator< TT > > // classes // template < typename PST, typename TT, typename NDT=TT, class DBT=std::vector< NDT >, class PAT=const PST&, - class SBT=redhawk::read_buffer > + class SBT=redhawk::shared_buffer > struct DataTransferTraits { typedef PST PortSequenceType; // Port Sequence type used by middleware typedef PAT PushArgumentType; // Type of data argument to pushPacket From 92d6677d50ca63ad8012c59c6dd3dc232a74538e Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 19 Apr 2016 13:30:50 -0400 Subject: [PATCH 0129/1644] Track output streams in the port, instead of leaving it up to users --- .../libsrc/cpp/bulkio_out_port.cpp | 27 ++++++++++++++++--- bulkioInterfaces/libsrc/cpp/bulkio_out_port.h | 6 +++++ 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp index 7b18594d5..a25daef79 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp @@ -529,14 +529,35 @@ namespace bulkio { template < typename PortTraits > typename OutPort< PortTraits >::StreamType OutPort< PortTraits >::createStream(const std::string& streamID) { - BULKIO::StreamSRI sri = bulkio::sri::create(streamID); - return createStream(sri); + typename StreamMap::iterator existing = streams.find(streamID); + if (existing != streams.end()) { + return existing->second; + } + return createStream(bulkio::sri::create(streamID)); } template < typename PortTraits > typename OutPort< PortTraits >::StreamType OutPort< PortTraits >::createStream(const BULKIO::StreamSRI& sri) { - return StreamType(sri, this); + const std::string streamID(sri.streamID); + typename StreamMap::iterator existing = streams.find(streamID); + if (existing != streams.end()) { + return existing->second; + } + StreamType stream(sri, this); + streams[streamID] = stream; + return stream; + } + + template < typename PortTraits > + typename OutPort< PortTraits >::StreamType OutPort< PortTraits >::getStream(const std::string& streamID) + { + typename StreamMap::iterator stream = streams.find(streamID); + if (stream != streams.end()) { + return stream->second; + } else { + return StreamType(); + } } OutCharPort::OutCharPort( std::string name, diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h index b4a477235..87602416c 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h @@ -458,11 +458,17 @@ namespace bulkio { StreamType createStream(const BULKIO::StreamSRI& sri); using OutPortBase::currentSRIs; + StreamType getStream(const std::string& streamID); + protected: using OutPortBase::logger; typedef typename OutPortBase::PortPtrType PortPtrType; typedef typename OutPortBase::PortConnectionType PortConnectionType; + typedef std::map StreamMap; + StreamMap streams; + boost::mutex streamsMutex; + virtual PortConnectionType* _createRemoteConnection(PortPtrType port, const std::string& connectionId); }; From d0ee647420ece1a527320bfec605f208286b262a Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 19 Apr 2016 14:09:45 -0400 Subject: [PATCH 0130/1644] Create specific input XML and File port classes, instead of a shared template. --- .../libsrc/cpp/bulkio_in_port.cpp | 71 ++++++++++----- bulkioInterfaces/libsrc/cpp/bulkio_in_port.h | 89 +++++++------------ 2 files changed, 79 insertions(+), 81 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp index 4633ecf5a..2d7d4f256 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp @@ -847,32 +847,28 @@ namespace bulkio { // ---------------------------------------------------------------------------------------- // Source Input Port String Definitions // ---------------------------------------------------------------------------------------- - template < typename PortTraits > - InStringPort< PortTraits >::InStringPort(std::string port_name, - LOGGER_PTR logger, - bulkio::sri::Compare compareSri, - SriListener *newStreamCB ) : - InPortBase(port_name, logger, compareSri, newStreamCB) + InFilePort::InFilePort(std::string port_name, + LOGGER_PTR logger, + bulkio::sri::Compare compareSri, + SriListener *newStreamCB) : + InPortBase(port_name, logger, compareSri, newStreamCB) { } - template < typename PortTraits > - InStringPort< PortTraits >::InStringPort(std::string port_name, - bulkio::sri::Compare compareSri, - SriListener *newStreamCB ) : - InPortBase(port_name, LOGGER_PTR(), compareSri, newStreamCB) + InFilePort::InFilePort(std::string port_name, + bulkio::sri::Compare compareSri, + SriListener *newStreamCB) : + InPortBase(port_name, LOGGER_PTR(), compareSri, newStreamCB) { } - template < typename PortTraits > - InStringPort< PortTraits >::InStringPort(std::string port_name, void* /*unused*/) : - InPortBase(port_name, LOGGER_PTR()) + InFilePort::InFilePort(std::string port_name, void* /*unused*/) : + InPortBase(port_name, LOGGER_PTR()) { } - template < typename PortTraits > - void InStringPort< PortTraits >::pushPacket(const char *data, const BULKIO::PrecisionUTCTime& T, CORBA::Boolean EOS, const char* streamID) + void InFilePort::pushPacket(const char *data, const BULKIO::PrecisionUTCTime& T, CORBA::Boolean EOS, const char* streamID) { if (!data) { this->queuePacket(std::string(), T, EOS, streamID); @@ -881,11 +877,45 @@ namespace bulkio { } } + void InFilePort::pushPacket(const std::string& data, const BULKIO::PrecisionUTCTime& T, CORBA::Boolean EOS, const std::string& streamID) + { + this->queuePacket(data, T, EOS, streamID); + } - template < typename PortTraits > - void InStringPort< PortTraits >::pushPacket(const char *data, CORBA::Boolean EOS, const char* streamID) + + InXMLPort::InXMLPort(std::string name, + LOGGER_PTR logger, + bulkio::sri::Compare compareSri, + SriListener* newStreamCB) : + InPortBase(name, logger, compareSri, newStreamCB) { - this->pushPacket(data, BULKIO::PrecisionUTCTime(), EOS, streamID); + } + + + InXMLPort::InXMLPort(std::string name, + bulkio::sri::Compare compareSri, + SriListener* newStreamCB) : + InPortBase(name, LOGGER_PTR(), compareSri, newStreamCB) + { + } + + InXMLPort::InXMLPort(std::string name, void* /*unused*/) : + InPortBase(name, LOGGER_PTR()) + { + } + + void InXMLPort::pushPacket(const char* data, CORBA::Boolean EOS, const char* streamID) + { + std::string buffer; + if (data) { + buffer = data; + } + this->pushPacket(buffer, EOS, streamID); + } + + void InXMLPort::pushPacket(const std::string& data, CORBA::Boolean EOS, const std::string& streamID) + { + this->queuePacket(data, BULKIO::PrecisionUTCTime(), EOS, streamID); } // @@ -914,8 +944,5 @@ namespace bulkio { INSTANTIATE_BASE_TEMPLATE(FilePortTraits); INSTANTIATE_BASE_TEMPLATE(XMLPortTraits); - template class InStringPort< FilePortTraits >; - template class InStringPort< XMLPortTraits >; - } // end of bulkio namespace diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h index 77f2ac7eb..2054db654 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h @@ -520,50 +520,10 @@ namespace bulkio { // - template < typename PortTraits > - class InStringPort : public InPortBase + class InFilePort : public InPortBase { public: - - typedef PortTraits Traits; - - // Port Variable Type - typedef typename Traits::POAPortType PortVarType; - - // Interface Type - typedef typename Traits::PortType PortType; - - // Interface Type - typedef typename Traits::PortType ProvidesPortType; - - // Transport Sequence Type use to during push packet - typedef char * PortSequenceType; - - // - // Transport type used by this port - // - typedef typename Traits::TransportType TransportType; - - // - // Native type mapping of TransportType - // - typedef typename Traits::NativeType NativeType; - - // - // Data transfer object from ports to components - // - typedef DataTransfer< typename Traits::DataTransferTraits > DataTransferType; - - - // backwards compatible defintion - typedef DataTransfer< typename Traits::DataTransferTraits > dataTransfer; - - - // queue of dataTranfer objects maintained by the port - typedef std::deque< DataTransferType * > WorkQueue; - - // // InStringPort - creates a provides port that can accept floating point vectors from a source // @@ -572,16 +532,16 @@ namespace bulkio { // if all members match then return true, otherwise false. This is used during the pushSRI method // @param newStreamCB interface that is called when new SRI.streamID is received - InStringPort(std::string port_name, - LOGGER_PTR logger, - bulkio::sri::Compare = bulkio::sri::DefaultComparator, - SriListener *newStreamCB = NULL ); + InFilePort(std::string port_name, + LOGGER_PTR logger, + bulkio::sri::Compare=bulkio::sri::DefaultComparator, + SriListener* newStreamCB=0); - InStringPort(std::string port_name, - bulkio::sri::Compare = bulkio::sri::DefaultComparator, - SriListener *newStreamCB = NULL ); + InFilePort(std::string port_name, + bulkio::sri::Compare=bulkio::sri::DefaultComparator, + SriListener* newStreamCB=0); - InStringPort(std::string port_name, void * ); + InFilePort(std::string port_name, void*); // // pushPacket called by the source component when pushing a vector of data into a component. This method will save off the data @@ -593,7 +553,24 @@ namespace bulkio { // @param streamID - name of the stream the vector and stream context data are associated with virtual void pushPacket(const char *data, const BULKIO::PrecisionUTCTime& T, CORBA::Boolean EOS, const char* streamID); + // Local push version + void pushPacket(const std::string& data, const BULKIO::PrecisionUTCTime& T, CORBA::Boolean EOS, const std::string& streamID); + }; + + class InXMLPort : public InPortBase + { + public: + InXMLPort(std::string port_name, LOGGER_PTR logger, + bulkio::sri::Compare=bulkio::sri::DefaultComparator, + SriListener* newStreamCB=NULL); + + InXMLPort(std::string port_name, + bulkio::sri::Compare=bulkio::sri::DefaultComparator, + SriListener* newStreamCB=NULL); + + InXMLPort(std::string port_name, void*); + // // pushPacket called by the source component when pushing a vector of data into a component. This method will save off the data // vector, timestamp, EOS and streamID onto a queue for consumption by the component via the getPacket method @@ -601,7 +578,10 @@ namespace bulkio { // @param data - the vector of data to be consumed // @param EOS - indicator that the stream has ended, (stream is identified by streamID) // @param streamID - name of the stream the vector and stream context data are associated with - virtual void pushPacket( const char *data, CORBA::Boolean EOS, const char* streamID); + virtual void pushPacket(const char *data, CORBA::Boolean EOS, const char* streamID); + + // Local push version + void pushPacket(const std::string& data, CORBA::Boolean EOS, const std::string& streamID); }; @@ -645,15 +625,6 @@ namespace bulkio { typedef InPort< FloatPortTraits > InFloatPort; // Bulkio double input typedef InPort< DoublePortTraits > InDoublePort; - // Bulkio URL input - typedef InStringPort< URLPortTraits > InURLPort; - // Bulkio File (URL) input - typedef InStringPort< FilePortTraits > InFilePort; - // Bulkio XML input - typedef InStringPort< XMLPortTraits > InXMLPort; - - - } // end of bulkio namespace From 8761765b0e8ec9aca8f8e6e38a4cf2f9f966b7cd Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 19 Apr 2016 14:12:30 -0400 Subject: [PATCH 0131/1644] Use a separate traits class to handle binding the specific local port class; allows specialization to talk directly to InXMLPort and InFilePort instead of a non-existent templatized version --- .../libsrc/cpp/bulkio_connection.hpp | 6 ++--- bulkioInterfaces/libsrc/cpp/bulkio_out_port.h | 22 ++++++++++++++++++- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp b/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp index 0716cf759..ad57e6c27 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp @@ -205,7 +205,7 @@ namespace bulkio { public: typedef typename PortTraits::PortType PortType; typedef typename PortType::_ptr_type PortPtrType; - typedef InPort LocalPortType; + typedef typename LocalTraits::InPortType LocalPortType; typedef typename PortTraits::SharedBufferType SharedBufferType; LocalConnection(const std::string& name, LocalPortType* port) : @@ -261,11 +261,11 @@ namespace bulkio { template <> void LocalConnection::_pushPacket(const std::string& data, - const BULKIO::PrecisionUTCTime& T, + const BULKIO::PrecisionUTCTime& /*unused*/, bool EOS, const std::string& streamID) { - _port->pushPacket(data, T, EOS, streamID); + _port->pushPacket(data, EOS, streamID); } } diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h index 87602416c..3187f7862 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h @@ -39,6 +39,26 @@ namespace bulkio { template class InPort; + class InFilePort; + class InXMLPort; + + template + struct LocalTraits + { + typedef InPort InPortType; + }; + + template <> + struct LocalTraits + { + typedef InFilePort InPortType; + }; + + template <> + struct LocalTraits + { + typedef InXMLPort InPortType; + }; template class PortConnection; @@ -285,7 +305,7 @@ namespace bulkio { // // Lookup table for connections to input ports in the same process space // - typedef InPort LocalPortType; + typedef typename LocalTraits::InPortType LocalPortType; typedef PortConnection PortConnectionType; virtual PortConnectionType* _createRemoteConnection(PortPtrType port, const std::string& connectionId); From 9aa428420f11c7fe2a7f7cf6298a94c8a7aff779 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 19 Apr 2016 15:23:34 -0400 Subject: [PATCH 0132/1644] Use boost::function and ossie::bind instead of custom classes for new SRI listeners --- .../libsrc/cpp/bulkio_in_port.cpp | 42 ++++--------------- bulkioInterfaces/libsrc/cpp/bulkio_in_port.h | 25 +++++------ 2 files changed, 19 insertions(+), 48 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp index 2d7d4f256..6da5cf135 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp @@ -17,6 +17,8 @@ * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see http://www.gnu.org/licenses/. */ + +#include #include #include @@ -24,28 +26,6 @@ namespace bulkio { - /* - * Wrap Callback functions as SriListerer objects - */ - class StaticSriCallback : public SriListener - { - public: - virtual void operator() ( BULKIO::StreamSRI& sri) - { - (*func_)(sri); - } - - StaticSriCallback ( SriListenerCallbackFn func) : - func_(func) - { - } - - private: - - SriListenerCallbackFn func_; - }; - - // ---------------------------------------------------------------------------------------- // Source/Input Port Definitions // ---------------------------------------------------------------------------------------- @@ -68,7 +48,7 @@ namespace bulkio { std::string _sriMsg("EMPTY"); if (newStreamCB) { - newStreamCallback = boost::shared_ptr< SriListener >( newStreamCB, null_deleter()); + newStreamCallback = boost::ref(*newStreamCB); _sriMsg = "USER_DEFINED"; } @@ -191,7 +171,9 @@ namespace bulkio { SriMap::iterator currH = currentHs.find(streamID); if (currH == currentHs.end()) { LOG_DEBUG(logger,"pushSRI PORT:" << name << " NEW SRI:" << streamID << " Mode:" << H.mode ); - if ( newStreamCallback ) (*newStreamCallback)(tmpH); + if (newStreamCallback) { + newStreamCallback(tmpH); + } currentHs[streamID] = std::make_pair(tmpH, true); lock.unlock(); @@ -239,7 +221,7 @@ namespace bulkio { sriChanged = true; BULKIO::StreamSRI tmpH = {1, 0.0, 1.0, 1, 0, 0.0, 0.0, 0, 0, streamID.c_str(), false, 0}; if (newStreamCallback) { - (*newStreamCallback)(tmpH); + newStreamCallback(tmpH); } currentHs[streamID] = std::make_pair(tmpH, false); sri = &(currentHs[streamID].first); @@ -526,14 +508,8 @@ namespace bulkio { } template < typename PortTraits > - void InPortBase< PortTraits >::setNewStreamListener( SriListener *newListener ) { - newStreamCallback = boost::shared_ptr< SriListener >(newListener, null_deleter()); - } - - template < typename PortTraits > - void InPortBase< PortTraits >::setNewStreamListener( SriListenerCallbackFn newListener ) { - newStreamCallback = boost::make_shared< StaticSriCallback >( newListener ); - + void InPortBase< PortTraits >::setNewStreamListener(SriListener* newListener) { + newStreamCallback = boost::ref(*newListener); } template < typename PortTraits > diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h index 2054db654..77ddad418 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h @@ -25,8 +25,6 @@ #include #include #include -#include -#include #include #include @@ -215,23 +213,20 @@ namespace bulkio { /* * Assign a callback for notification when a new SRI StreamId is received */ - template< typename T > inline - void setNewStreamListener(T &target, void (T::*func)( BULKIO::StreamSRI &) ) { - newStreamCallback = boost::make_shared< MemberSriListener< T > >( boost::ref(target), func ); - }; + template + inline void setNewStreamListener(Target target, Func func) { + ossie::bind(newStreamCallback, target, func); + } /* * Assign a callback for notification when a new SRI StreamId is received */ - template< typename T > inline - void setNewStreamListener(T *target, void (T::*func)( BULKIO::StreamSRI &) ) { - newStreamCallback = boost::make_shared< MemberSriListener< T > >( boost::ref(*target), func ); - - }; - - void setNewStreamListener( SriListener *newListener ); + template + inline void setNewStreamListener(Func func) { + newStreamCallback = func; + } - void setNewStreamListener( SriListenerCallbackFn newListener ); + void setNewStreamListener(SriListener *newListener); void setLogger( LOGGER_PTR logger ); @@ -286,7 +281,7 @@ namespace bulkio { // // Callback for notifications when new SRI streamID's are received // - boost::shared_ptr< SriListener > newStreamCallback; + boost::function newStreamCallback; // // List of SRI objects managed by StreamID From 78e64ab7a7ff6ec25acf2c97bd0acb63bb3a545a Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 19 Apr 2016 15:25:24 -0400 Subject: [PATCH 0133/1644] Restore nested typedef for data transfer type in XML and File input ports --- bulkioInterfaces/libsrc/cpp/bulkio_in_port.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h index 77ddad418..b8a93f5d0 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h @@ -517,8 +517,10 @@ namespace bulkio { class InFilePort : public InPortBase { - public: + typedef InPortBase::DataTransferType DataTransferType; + typedef DataTransferType dataTransfer; + // // InStringPort - creates a provides port that can accept floating point vectors from a source // @@ -556,6 +558,9 @@ namespace bulkio { class InXMLPort : public InPortBase { public: + typedef InPortBase::DataTransferType DataTransferType; + typedef DataTransferType dataTransfer; + InXMLPort(std::string port_name, LOGGER_PTR logger, bulkio::sri::Compare=bulkio::sri::DefaultComparator, SriListener* newStreamCB=NULL); From 38f7eff6404a72f1f0ccc832f629c91d7643bf47 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 19 Apr 2016 15:30:32 -0400 Subject: [PATCH 0134/1644] Remove typedefs that are not used anymore, and in the case of WorkQueue, no longer meaningful --- bulkioInterfaces/libsrc/cpp/bulkio_in_port.h | 20 +------------------ bulkioInterfaces/libsrc/cpp/bulkio_out_port.h | 6 ------ bulkioInterfaces/libsrc/cpp/bulkio_traits.h | 6 ++---- 3 files changed, 3 insertions(+), 29 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h index b8a93f5d0..192a1c9b4 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h @@ -59,22 +59,13 @@ namespace bulkio { // typedef typename Traits::TransportType TransportType; - // - // True type of argument to pushPacket, typically "const PortSequenceType&" - // except for dataXML and dataFile (which use "const char*") - // - typedef typename Traits::PushType PushArgumentType; - - typedef typename Traits::PortType PortType; + typedef typename Traits::PortType PortType; // // Declaration of DataTransfer class from TransportType trait and DataBuffer type trait // typedef DataTransfer< typename Traits::DataTransferTraits > DataTransferType; - // Queue of data transfer objects maintained by the port - typedef std::deque< DataTransferType * > WorkQueue; - typedef typename Traits::SharedBufferType SharedBufferType; // @@ -367,15 +358,9 @@ namespace bulkio { public: typedef PortTraits Traits; - // Port Variable Type - typedef typename Traits::POAPortType PortVarType; - // Interface Type typedef typename Traits::PortType PortType; - // Interface Type - typedef typename Traits::PortType ProvidesPortType; - // Transport Sequence Type use to during push packet typedef typename Traits::SequenceType PortSequenceType; @@ -400,9 +385,6 @@ namespace bulkio { // backwards compatible definition typedef DataTransferType dataTransfer; - // queue of dataTranfer objects maintained by the port - typedef std::deque< DataTransferType * > WorkQueue; - // Input stream interface used by this port typedef InputStream StreamType; diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h index 3187f7862..0f3ff4c0b 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h @@ -101,12 +101,6 @@ namespace bulkio { // typedef typename Traits::SequenceType PortSequenceType; - // - // True type of argument to pushPacket, typically "const PortSequenceType&" - // except for dataXML and dataFile (which use "const char*") - // - typedef typename Traits::PushType PushArgumentType; - // // Shared buffer type used to transfer data without copies, where possible // diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_traits.h b/bulkioInterfaces/libsrc/cpp/bulkio_traits.h index 4490cdb62..1a6a434e7 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_traits.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_traits.h @@ -50,11 +50,10 @@ template < typename TT, typename AT=_seqVector::seqVectorAllocator< TT > > // Traits template definition used to define input and output types used the port // classes // -template < typename PST, typename TT, typename NDT=TT, class DBT=std::vector< NDT >, class PAT=const PST&, +template < typename PST, typename TT, typename NDT=TT, class DBT=std::vector< NDT >, class SBT=redhawk::shared_buffer > struct DataTransferTraits { typedef PST PortSequenceType; // Port Sequence type used by middleware - typedef PAT PushArgumentType; // Type of data argument to pushPacket typedef TT TransportType; // Transport Type contained in the Port Sequence container typedef NDT NativeDataType; // Native c++ mapping of Transport Type typedef DBT DataBufferType; // Container defintion to hold data from Input port @@ -73,7 +72,7 @@ typedef DataTransferTraits< PortTypes::LongLongSequence, CORBA::LongLong > Lo typedef DataTransferTraits< PortTypes::UlongLongSequence, CORBA::ULongLong > ULongLongDataTransferTraits; typedef DataTransferTraits< PortTypes::FloatSequence, CORBA::Float > FloatDataTransferTraits; typedef DataTransferTraits< PortTypes::DoubleSequence, CORBA::Double > DoubleDataTransferTraits; -typedef DataTransferTraits< Char *, Char, Char, std::string, const char*, std::string > StringDataTransferTraits; +typedef DataTransferTraits< Char *, Char, Char, std::string, std::string > StringDataTransferTraits; // @@ -196,7 +195,6 @@ struct PortTraits { typedef typename DTT::TransportType TransportType; typedef typename DTT::NativeDataType NativeType; typedef typename DTT::PortSequenceType SequenceType; - typedef typename DTT::PushArgumentType PushType; typedef typename DTT::DataBufferType DataBufferType; typedef typename DTT::SharedBufferType SharedBufferType; }; From fc758c723814712223f047d8f5aeaadd9105f93b Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 19 Apr 2016 16:00:57 -0400 Subject: [PATCH 0135/1644] Rename _pushSinglePacket to _sendPacket to reflect its real usage, and because chunking is now done at the connection level instead of the port level --- bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp | 16 ++++++++-------- bulkioInterfaces/libsrc/cpp/bulkio_out_port.h | 14 ++++++-------- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp index a25daef79..534503be2 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp @@ -157,7 +157,7 @@ namespace bulkio { template < typename PortTraits > - void OutPortBase< PortTraits >::_pushSinglePacket( + void OutPortBase< PortTraits >::_sendPacket( const SharedBufferType& data, const BULKIO::PrecisionUTCTime& T, bool EOS, @@ -492,7 +492,7 @@ namespace bulkio { bool EOS, const std::string& streamID) { - this->_pushSinglePacket(SharedBufferType::make_transient(&data[0], data.size()), T, EOS, streamID); + this->_sendPacket(SharedBufferType::make_transient(&data[0], data.size()), T, EOS, streamID); } template < typename PortTraits > @@ -502,7 +502,7 @@ namespace bulkio { bool EOS, const std::string& streamID) { - this->_pushSinglePacket(SharedBufferType::make_transient(&data[0], data.size()), T, EOS, streamID); + this->_sendPacket(SharedBufferType::make_transient(&data[0], data.size()), T, EOS, streamID); } template < typename PortTraits > @@ -514,7 +514,7 @@ namespace bulkio { const std::string& streamID) { const NativeType* ptr = reinterpret_cast(data); - this->_pushSinglePacket(SharedBufferType::make_transient(ptr, size), T, EOS, streamID); + this->_sendPacket(SharedBufferType::make_transient(ptr, size), T, EOS, streamID); } template < typename PortTraits > @@ -523,7 +523,7 @@ namespace bulkio { bool EOS, const std::string& streamID) { - this->_pushSinglePacket(data, T, EOS, streamID); + this->_sendPacket(data, T, EOS, streamID); } template < typename PortTraits > @@ -625,7 +625,7 @@ namespace bulkio { void OutFilePort::pushPacket(const std::string& URL, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID) { - _pushSinglePacket(URL, T, EOS, streamID); + _sendPacket(URL, T, EOS, streamID); } void OutFilePort::pushPacket(const char* URL, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID) @@ -668,7 +668,7 @@ namespace bulkio { if (data) { data_out = data; } - _pushSinglePacket(data_out, T, EOS, streamID); + _sendPacket(data_out, T, EOS, streamID); } @@ -677,7 +677,7 @@ namespace bulkio { // The time argument is never dereferenced for dataXML, so it is safe to // pass a null BULKIO::PrecisionUTCTime* time = 0; - _pushSinglePacket(data, *time, EOS, streamID); + _sendPacket(data, *time, EOS, streamID); } void OutXMLPort::pushPacket(const char* data, bool EOS, const std::string& streamID) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h index 0f3ff4c0b..c160016cf 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h @@ -325,14 +325,12 @@ namespace bulkio { bool _isStreamRoutedToConnection(const std::string& connectionID, const std::string& streamID); // - // Sends the given data and metadata as a single push, for subclasses that - // will never break a push into multiple packets (XML, File); acquires and - // releases the port lock - // - void _pushSinglePacket(const SharedBufferType& data, - const BULKIO::PrecisionUTCTime& T, - bool EOS, - const std::string& streamID); + // Sends data and metadata to all connections enabled for the given stream + // + void _sendPacket(const SharedBufferType& data, + const BULKIO::PrecisionUTCTime& T, + bool EOS, + const std::string& streamID); }; From 3116cdcb8222dd2b1013093155e12a6f5c13c8c4 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 19 Apr 2016 16:21:48 -0400 Subject: [PATCH 0136/1644] Protect access to the output stream map with a mutex --- bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp index 534503be2..3216d13ec 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp @@ -529,6 +529,7 @@ namespace bulkio { template < typename PortTraits > typename OutPort< PortTraits >::StreamType OutPort< PortTraits >::createStream(const std::string& streamID) { + boost::mutex::scoped_lock lock(streamsMutex); typename StreamMap::iterator existing = streams.find(streamID); if (existing != streams.end()) { return existing->second; @@ -539,9 +540,12 @@ namespace bulkio { template < typename PortTraits > typename OutPort< PortTraits >::StreamType OutPort< PortTraits >::createStream(const BULKIO::StreamSRI& sri) { + boost::mutex::scoped_lock lock(streamsMutex); const std::string streamID(sri.streamID); typename StreamMap::iterator existing = streams.find(streamID); if (existing != streams.end()) { + // Update the stream's SRI from the argument + existing->second.sri(sri); return existing->second; } StreamType stream(sri, this); @@ -552,6 +556,7 @@ namespace bulkio { template < typename PortTraits > typename OutPort< PortTraits >::StreamType OutPort< PortTraits >::getStream(const std::string& streamID) { + boost::mutex::scoped_lock lock(streamsMutex); typename StreamMap::iterator stream = streams.find(streamID); if (stream != streams.end()) { return stream->second; From 112415abb152f596cee1cb2798552abcb1409b8f Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 20 Apr 2016 10:08:53 -0400 Subject: [PATCH 0137/1644] Add a getStreams() method to output ports; automatically manage output streams based on SRI push and EOS. --- .../libsrc/cpp/bulkio_out_port.cpp | 76 ++++++++++++++----- bulkioInterfaces/libsrc/cpp/bulkio_out_port.h | 9 +++ 2 files changed, 68 insertions(+), 17 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp index 3216d13ec..1c2df2f93 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp @@ -94,16 +94,13 @@ namespace bulkio { SCOPED_LOCK lock(updatingPortsLock); // don't want to process while command information is coming in - std::string sid( H.streamID ); - typename OutPortSriMap::iterator sri_iter; - sri_iter= currentSRIs.find( sid ); - if ( sri_iter == currentSRIs.end() ) { - SriMapStruct sri_ctx( H ); + const std::string sid(H.streamID); + typename OutPortSriMap::iterator sri_iter = currentSRIs.find(sid); + if (sri_iter == currentSRIs.end()) { // need to use insert since we do not have default CTOR for SriMapStruct - currentSRIs.insert( OutPortSriMap::value_type( sid, sri_ctx ) ); - sri_iter= currentSRIs.find( sid ); - } - else { + sri_iter = currentSRIs.insert(OutPortSriMap::value_type(sid, SriMapStruct(H))).first; + addStream(sid, sri_iter->second.sri); + } else { // overwrite the SRI sri_iter->second.sri = H; @@ -163,17 +160,23 @@ namespace bulkio { bool EOS, const std::string& streamID) { + const std::string stream_id(streamID); + // don't want to process while command information is coming in SCOPED_LOCK lock(this->updatingPortsLock); // grab SRI context - typename OutPortSriMap::iterator sri_iter = currentSRIs.find( streamID ); + typename OutPortSriMap::iterator sri_iter = currentSRIs.find(stream_id); if (sri_iter == currentSRIs.end()) { + LOG_TRACE(logger, "Creating new stream '" << stream_id << "' with default SRI"); + // No SRI associated with the stream ID, create a default one and add // it to the list; it will get pushed to downstream connections below - SriMapStruct sri_ctx(bulkio::sri::create(streamID)); + SriMapStruct sri_ctx(bulkio::sri::create(stream_id)); // need to use insert since we do not have default CTOR for SriMapStruct - sri_iter = currentSRIs.insert(std::make_pair(streamID, sri_ctx)).first; + sri_iter = currentSRIs.insert(std::make_pair(stream_id, sri_ctx)).first; + + addStream(stream_id, sri_iter->second.sri); } if (active) { @@ -181,7 +184,7 @@ namespace bulkio { for (port = _transportMap.begin(); port != _transportMap.end(); ++port) { // Check whether filtering is enabled and if this connection should // receive the stream - if (!_isStreamRoutedToConnection(streamID, port->first)) { + if (!_isStreamRoutedToConnection(stream_id, port->first)) { continue; } @@ -198,10 +201,9 @@ namespace bulkio { } // if we have end of stream removed old sri - try { - if ( EOS ) currentSRIs.erase(streamID); - } - catch(...){ + if (EOS) { + currentSRIs.erase(stream_id); + removeStream(stream_id); } } @@ -445,6 +447,15 @@ namespace bulkio { //return "IDL:CORBA/Object:1.0"; } + template < typename PortTraits > + void OutPortBase< PortTraits >::addStream(const std::string& streamID, const BULKIO::StreamSRI& sri) + { + } + + template < typename PortTraits > + void OutPortBase< PortTraits >::removeStream(const std::string& streamID) + { + } /* OutPort Constructor @@ -565,6 +576,37 @@ namespace bulkio { } } + template < typename PortTraits > + typename OutPort< PortTraits >::StreamList OutPort< PortTraits >::getStreams() + { + StreamList result; + boost::mutex::scoped_lock lock(streamsMutex); + for (typename StreamMap::const_iterator stream = streams.begin(); stream != streams.end(); ++stream) { + result.push_back(stream->second); + } + return result; + } + + template < typename PortTraits > + void OutPort< PortTraits >::addStream(const std::string& streamID, const BULKIO::StreamSRI& sri) + { + boost::mutex::scoped_lock lock(streamsMutex); + if (streams.count(streamID) == 0) { + // Only create a new stream if one doesn't already exist; when a stream + // is created via createStream (the preferred method), its first call + // to pushSRI will end up calling this method + streams.insert(std::make_pair(streamID, StreamType(sri, this))); + } + } + + template < typename PortTraits > + void OutPort< PortTraits >::removeStream(const std::string& streamID) + { + boost::mutex::scoped_lock lock(streamsMutex); + streams.erase(streamID); + } + + OutCharPort::OutCharPort( std::string name, ConnectionEventListener *connectCB, ConnectionEventListener *disconnectCB ): diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h index c160016cf..047034a87 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h @@ -331,6 +331,9 @@ namespace bulkio { const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID); + + virtual void addStream(const std::string& streamID, const BULKIO::StreamSRI& sri); + virtual void removeStream(const std::string& streamID); }; @@ -472,11 +475,17 @@ namespace bulkio { StreamType getStream(const std::string& streamID); + typedef std::list StreamList; + StreamList getStreams(); + protected: using OutPortBase::logger; typedef typename OutPortBase::PortPtrType PortPtrType; typedef typename OutPortBase::PortConnectionType PortConnectionType; + virtual void addStream(const std::string& streamID, const BULKIO::StreamSRI& sri); + virtual void removeStream(const std::string& streamID); + typedef std::map StreamMap; StreamMap streams; boost::mutex streamsMutex; From e84efe41abd3bf2828eadffbb8d238b579ce3876 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 20 Apr 2016 12:48:08 -0400 Subject: [PATCH 0138/1644] Fix deadlock in output stream creation --- bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp index 1c2df2f93..e0938f5f0 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp @@ -545,7 +545,9 @@ namespace bulkio { if (existing != streams.end()) { return existing->second; } - return createStream(bulkio::sri::create(streamID)); + StreamType stream(bulkio::sri::create(streamID), this); + streams[streamID] = stream; + return stream; } template < typename PortTraits > From 2dda6cb53a43b6b356b2d10e3a4dc454354cb872 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 20 Apr 2016 12:48:29 -0400 Subject: [PATCH 0139/1644] Implement vector-to-datablock swap, which necessarily has to make a copy now --- bulkioInterfaces/libsrc/cpp/bulkio_datablock.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_datablock.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_datablock.cpp index 2231fb157..f680e6952 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_datablock.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_datablock.cpp @@ -223,8 +223,12 @@ void DataBlock::inputQueueFlushed(bool flushed) template void DataBlock::swap(std::vector& other) { - // TODO - //_impl->data.swap(other); + // Copy the vector data into a new shared buffer + ScalarBuffer data = ScalarBuffer::make_transient(&other[0], other.size()).copy(); + // Swap the block's data with the new shared buffer + _impl->data.swap(data); + // Assign the old data to the vector + other.assign(data.begin(), data.end()); } template From 492a7f2a36687434c9c93e8b8b3c410634475ee1 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 23 Jun 2016 14:01:18 -0400 Subject: [PATCH 0140/1644] Restore InURLPort (as a typedef of InFilePort) for CPP_Ports test component --- bulkioInterfaces/libsrc/cpp/bulkio_in_port.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h index 192a1c9b4..e70b89ecd 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h @@ -607,6 +607,8 @@ namespace bulkio { typedef InPort< FloatPortTraits > InFloatPort; // Bulkio double input typedef InPort< DoublePortTraits > InDoublePort; + // Maintained for backwards compatibility + typedef InFilePort InURLPort; } // end of bulkio namespace From e22474629aded82e0610feba2306337cabb09066 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 23 Jun 2016 14:03:25 -0400 Subject: [PATCH 0141/1644] Subclassing BulkIO ports isn't supported anymore, for the reason that it would restrict the ability to make major improvements (like memory sharing) --- .../tests/cpp/Bulkio_InPort_Fixture.cpp | 37 ------------ .../testing/tests/cpp/Bulkio_InPort_Fixture.h | 1 - .../tests/cpp/Bulkio_OutPort_Fixture.cpp | 57 ------------------- .../tests/cpp/Bulkio_OutPort_Fixture.h | 2 - 4 files changed, 97 deletions(-) diff --git a/bulkioInterfaces/libsrc/testing/tests/cpp/Bulkio_InPort_Fixture.cpp b/bulkioInterfaces/libsrc/testing/tests/cpp/Bulkio_InPort_Fixture.cpp index 9d96d0238..fcd253edc 100644 --- a/bulkioInterfaces/libsrc/testing/tests/cpp/Bulkio_InPort_Fixture.cpp +++ b/bulkioInterfaces/libsrc/testing/tests/cpp/Bulkio_InPort_Fixture.cpp @@ -55,29 +55,6 @@ class SriListener { }; -class MyFloatPort : public bulkio::InFloatPort { - -public: - - MyFloatPort( std::string pname, bulkio::LOGGER_PTR logger ) : - bulkio::InFloatPort( pname, logger ) {}; - - // - // over ride default behavior for pushPacket and pushSRI - // - void pushPacket(const bulkio::InFloatPort::PortSequenceType & data, const BULKIO::PrecisionUTCTime& T, CORBA::Boolean EOS, const char* streamID) { - stats->update(10, (float)workQueue.size()/(float)queueSem->getMaxValue(), EOS, streamID, false); - queueSem->setCurrValue(workQueue.size()); - bulkio::InFloatPort::pushPacket( data, T, EOS, streamID ); - } - - void pushSRI(const BULKIO::StreamSRI& H) { - queueSem->setCurrValue(workQueue.size()); - bulkio::InFloatPort::pushSRI(H); - } -}; - - void Bulkio_InPort_Fixture::setUp() { @@ -623,17 +600,3 @@ Bulkio_InPort_Fixture::test_sdds() CPPUNIT_ASSERT_NO_THROW( port ); } - - -void -Bulkio_InPort_Fixture::test_subclass() -{ - bulkio::InFloatPort *port = new MyFloatPort("test_api_subclass", logger ); - - CPPUNIT_ASSERT( port != NULL ); - - test_port_api( port ); - - CPPUNIT_ASSERT_NO_THROW( port ); -} - diff --git a/bulkioInterfaces/libsrc/testing/tests/cpp/Bulkio_InPort_Fixture.h b/bulkioInterfaces/libsrc/testing/tests/cpp/Bulkio_InPort_Fixture.h index 9048de30a..ebcffc4cd 100644 --- a/bulkioInterfaces/libsrc/testing/tests/cpp/Bulkio_InPort_Fixture.h +++ b/bulkioInterfaces/libsrc/testing/tests/cpp/Bulkio_InPort_Fixture.h @@ -50,7 +50,6 @@ class Bulkio_InPort_Fixture : public CppUnit::TestFixture CPPUNIT_TEST( test_xml ); CPPUNIT_TEST( test_create_sdds ); CPPUNIT_TEST( test_sdds ); - CPPUNIT_TEST( test_subclass ); CPPUNIT_TEST_SUITE_END(); public: diff --git a/bulkioInterfaces/libsrc/testing/tests/cpp/Bulkio_OutPort_Fixture.cpp b/bulkioInterfaces/libsrc/testing/tests/cpp/Bulkio_OutPort_Fixture.cpp index 92d23ae61..c150546a3 100644 --- a/bulkioInterfaces/libsrc/testing/tests/cpp/Bulkio_OutPort_Fixture.cpp +++ b/bulkioInterfaces/libsrc/testing/tests/cpp/Bulkio_OutPort_Fixture.cpp @@ -25,37 +25,6 @@ CPPUNIT_TEST_SUITE_REGISTRATION( Bulkio_OutPort_Fixture ); -class MyOutFloatPort : public bulkio::OutFloatPort { - -public: - - MyOutFloatPort( std::string pname, bulkio::LOGGER_PTR logger ) : - bulkio::OutFloatPort( pname, logger ) {}; - - - void pushPacket( bulkio::OutFloatPort::NativeSequenceType & data, BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID) { - - stats[streamID].update( 1, 1.0, false, "testing" ); - bulkio::OutFloatPort::pushPacket( data, T, EOS, streamID ); - } - -}; - -class NewSriCallback { - -public: - - std::vector sids; - - ~NewSriCallback() {}; - - void newSriCB( const BULKIO::StreamSRI& sri) { - std::string sid(sri.streamID); - sids.push_back( sid ); - } -}; - - // Global connection/disconnection callbacks static void port_connected( const char* connectionId ) { @@ -597,29 +566,3 @@ Bulkio_OutPort_Fixture::test_sdds() CPPUNIT_ASSERT_NO_THROW( port ); } - - -void -Bulkio_OutPort_Fixture::test_sdds_sri() -{ - bulkio::OutSDDSPort *port = new bulkio::OutSDDSPort("test_sdds_sri", logger ); - CPPUNIT_ASSERT( port != NULL ); - - test_port_sri< bulkio::OutSDDSPort, bulkio::InSDDSPort > ( port ); - - CPPUNIT_ASSERT_NO_THROW( port ); -} - - - -void -Bulkio_OutPort_Fixture::test_subclass() -{ - bulkio::OutFloatPort *port = new MyOutFloatPort("test_api_subclass", logger ); - CPPUNIT_ASSERT( port != NULL ); - - test_port_api( port ); - - CPPUNIT_ASSERT_NO_THROW( port ); -} - diff --git a/bulkioInterfaces/libsrc/testing/tests/cpp/Bulkio_OutPort_Fixture.h b/bulkioInterfaces/libsrc/testing/tests/cpp/Bulkio_OutPort_Fixture.h index 6d6e9c965..4a66421af 100644 --- a/bulkioInterfaces/libsrc/testing/tests/cpp/Bulkio_OutPort_Fixture.h +++ b/bulkioInterfaces/libsrc/testing/tests/cpp/Bulkio_OutPort_Fixture.h @@ -49,8 +49,6 @@ class Bulkio_OutPort_Fixture : public CppUnit::TestFixture CPPUNIT_TEST( test_xml ); CPPUNIT_TEST( test_create_sdds ); CPPUNIT_TEST( test_sdds ); - CPPUNIT_TEST( test_sdds_sri ); - CPPUNIT_TEST( test_subclass ); CPPUNIT_TEST_SUITE_END(); public: From f282c053b27529bbf65bde50cf317a3944136026 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 23 Jun 2016 14:41:20 -0400 Subject: [PATCH 0142/1644] Re-add the InXMLPort::pushPacket() that takes a timestamp, since strictly speaking it breaks compatibility; suppress deprecation warnings in tests --- bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp | 9 +++++++++ bulkioInterfaces/libsrc/cpp/bulkio_in_port.h | 2 ++ .../libsrc/testing/tests/cpp/Bulkio_InPort_Fixture.cpp | 5 ++++- .../libsrc/testing/tests/cpp/Bulkio_OutPort_Fixture.cpp | 3 +++ 4 files changed, 18 insertions(+), 1 deletion(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp index 6da5cf135..21376062c 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp @@ -889,6 +889,15 @@ namespace bulkio { this->pushPacket(buffer, EOS, streamID); } + void InXMLPort::pushPacket(const char* data, const BULKIO::PrecisionUTCTime& T, CORBA::Boolean EOS, const char* streamID) + { + std::string buffer; + if (data) { + buffer = data; + } + this->queuePacket(buffer, T, EOS, streamID); + } + void InXMLPort::pushPacket(const std::string& data, CORBA::Boolean EOS, const std::string& streamID) { this->queuePacket(data, BULKIO::PrecisionUTCTime(), EOS, streamID); diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h index e70b89ecd..3a4b5149c 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h @@ -562,6 +562,8 @@ namespace bulkio { // @param streamID - name of the stream the vector and stream context data are associated with virtual void pushPacket(const char *data, CORBA::Boolean EOS, const char* streamID); + void pushPacket(const char* data, const BULKIO::PrecisionUTCTime& T, CORBA::Boolean EOS, const char* streamID) __attribute__ ((deprecated)); + // Local push version void pushPacket(const std::string& data, CORBA::Boolean EOS, const std::string& streamID); }; diff --git a/bulkioInterfaces/libsrc/testing/tests/cpp/Bulkio_InPort_Fixture.cpp b/bulkioInterfaces/libsrc/testing/tests/cpp/Bulkio_InPort_Fixture.cpp index fcd253edc..f634b1e16 100644 --- a/bulkioInterfaces/libsrc/testing/tests/cpp/Bulkio_InPort_Fixture.cpp +++ b/bulkioInterfaces/libsrc/testing/tests/cpp/Bulkio_InPort_Fixture.cpp @@ -22,6 +22,9 @@ #include "Bulkio_InPort_Fixture.h" #include "bulkio.h" +// Suppress warnings for call to deprecated InXMLPort::pushPacket +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" + // Registers the fixture into the 'registry' CPPUNIT_TEST_SUITE_REGISTRATION( Bulkio_InPort_Fixture ); @@ -248,7 +251,7 @@ void Bulkio_InPort_Fixture::test_port_api( bulkio::InXMLPort *port ) { bulkio::InXMLPort::PortSequenceType v = new bulkio::InXMLPort::TransportType[1]; BULKIO::PrecisionUTCTime TS; - port->pushPacket( v, TS, false, "test_port_api" ); + port->pushPacket( v, false, "test_port_api" ); // grab off packet pkt = port->getPacket(bulkio::Const::NON_BLOCKING ); diff --git a/bulkioInterfaces/libsrc/testing/tests/cpp/Bulkio_OutPort_Fixture.cpp b/bulkioInterfaces/libsrc/testing/tests/cpp/Bulkio_OutPort_Fixture.cpp index c150546a3..e29579eb3 100644 --- a/bulkioInterfaces/libsrc/testing/tests/cpp/Bulkio_OutPort_Fixture.cpp +++ b/bulkioInterfaces/libsrc/testing/tests/cpp/Bulkio_OutPort_Fixture.cpp @@ -20,6 +20,9 @@ #include "Bulkio_OutPort_Fixture.h" #include "bulkio.h" +// Suppress warnings for access to deprecated methods +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" + // Registers the fixture into the 'registry' CPPUNIT_TEST_SUITE_REGISTRATION( Bulkio_OutPort_Fixture ); From bd328337df0bb2492e7d012fbe23c4edaaf53538 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 29 Jul 2016 10:34:44 -0400 Subject: [PATCH 0143/1644] Hold the lock for the duration of peekPacket, otherwise an input queue flush can lead to a seg fault --- bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp | 7 ++++--- bulkioInterfaces/libsrc/cpp/bulkio_in_port.h | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp index 21376062c..cbd9ab03b 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp @@ -280,12 +280,12 @@ namespace bulkio { template < typename PortTraits > - typename InPortBase< PortTraits >::Packet* InPortBase< PortTraits >::peekPacket(float timeout) + typename InPortBase< PortTraits >::Packet* InPortBase< PortTraits >::peekPacket(float timeout, + boost::unique_lock& lock) { uint64_t secs = (unsigned long)(trunc(timeout)); uint64_t msecs = (unsigned long)((timeout - secs) * 1e6); boost::system_time to_time = boost::get_system_time() + boost::posix_time::seconds(secs) + boost::posix_time::microseconds(msecs); - boost::mutex::scoped_lock lock(this->dataBufferLock); while (!breakBlock && packetQueue.empty()) { if (timeout == 0) { break; @@ -652,7 +652,8 @@ namespace bulkio { // Otherwise, return the stream that owns the next packet on the queue, // potentially waiting for one to be received - Packet* packet = this->peekPacket(timeout); + boost::mutex::scoped_lock lock(this->dataBufferLock); + Packet* packet = this->peekPacket(timeout, lock); if (packet) { return getStream(packet->streamID); } diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h index 3a4b5149c..83a2dbfb3 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h @@ -330,7 +330,7 @@ namespace bulkio { // Returns a pointer to the first packet in the queue, blocking for up to // timeout seconds for one to be available // - Packet* peekPacket(float timeout); + Packet* peekPacket(float timeout, boost::unique_lock& lock); virtual void createStream(const std::string& streamID, const BULKIO::StreamSRI& sri); virtual void removeStream(const std::string& streamID); From 9f3db9e1746dc71d040c929779bafde5348f0b03 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 29 Jul 2016 10:35:11 -0400 Subject: [PATCH 0144/1644] Add a convenience function to get the timestamp for the first sample of a block --- .../libsrc/cpp/bulkio_datablock.cpp | 33 ++++++++++++------- .../libsrc/cpp/bulkio_datablock.h | 1 + 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_datablock.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_datablock.cpp index f680e6952..39bf27a19 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_datablock.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_datablock.cpp @@ -150,18 +150,32 @@ namespace { double expected = (end.offset - begin.offset)*xdelta; return real-expected; } + + void validate_timestamps(const std::list& timestamps) + { + // Validity checks + if (timestamps.empty()) { + throw std::logic_error("block contains no timestamps"); + } else if (timestamps.front().offset != 0) { + throw std::logic_error("no timestamp at offset 0"); + } + } +} + +template +const BULKIO::PrecisionUTCTime& DataBlock::getStartTime() const +{ + const std::list& timestamps = _impl->timestamps; + validate_timestamps(timestamps); + + return _impl->timestamps.front().time; } template double DataBlock::getNetTimeDrift() const { const std::list& timestamps = _impl->timestamps; - // Validity checks - if (timestamps.empty()) { - throw std::logic_error("block contains no timestamps"); - } else if (timestamps.front().offset != 0) { - throw std::logic_error("no timestamp at offset 0"); - } + validate_timestamps(timestamps); return get_drift(timestamps.front(), timestamps.back(), _impl->sri.xdelta); } @@ -170,12 +184,7 @@ template double DataBlock::getMaxTimeDrift() const { const std::list& timestamps = _impl->timestamps; - // Validity checks - if (timestamps.empty()) { - throw std::logic_error("block contains no timestamps"); - } else if (timestamps.front().offset != 0) { - throw std::logic_error("no timestamp at offset 0"); - } + validate_timestamps(timestamps); double max = 0.0; std::list::const_iterator current = timestamps.begin(); diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_datablock.h b/bulkioInterfaces/libsrc/cpp/bulkio_datablock.h index 92faf7239..10f36779d 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_datablock.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_datablock.h @@ -81,6 +81,7 @@ namespace bulkio { void inputQueueFlushed(bool flush); void addTimestamp(const SampleTimestamp& timestamp); + const BULKIO::PrecisionUTCTime& getStartTime() const; std::list getTimestamps() const; double getNetTimeDrift() const; double getMaxTimeDrift() const; From 8b8710734269c559a0ab8e639cd0a870df551b25 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 29 Jul 2016 13:34:48 -0400 Subject: [PATCH 0145/1644] Implement output buffering for C++ ports --- .../libsrc/cpp/bulkio_out_stream.cpp | 148 +++++++++++++++--- .../libsrc/cpp/bulkio_out_stream.h | 18 +++ 2 files changed, 148 insertions(+), 18 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp index 0c341e202..9d914f8cf 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp @@ -20,6 +20,7 @@ #include "bulkio_out_stream.h" #include "bulkio_out_port.h" +#include "bulkio_time_operators.h" #include "bulkio_p.h" using bulkio::OutputStream; @@ -30,19 +31,13 @@ class OutputStream::Impl { typedef typename OutputStream::ScalarBuffer ScalarBuffer; typedef typename OutputStream::ComplexBuffer ComplexBuffer; - Impl(const std::string& streamID, OutPortType* port) : - _streamID(streamID), - _port(port), - _sri(bulkio::sri::create(streamID)), - _sriUpdated(true) - { - } - Impl(const BULKIO::StreamSRI& sri, OutPortType* port) : _streamID(sri.streamID), _port(port), _sri(sri), - _sriUpdated(true) + _sriUpdated(true), + _bufferSize(0), + _bufferOffset(0) { } @@ -58,10 +53,11 @@ class OutputStream::Impl { void setSRI(const BULKIO::StreamSRI& sri) { + _markDirtySRI(); + // Copy the new SRI, except for the stream ID, which is immutable _sri = sri; _sri.streamID = _streamID.c_str(); - _sriUpdated = true; } void setXDelta(double delta) @@ -81,20 +77,20 @@ class OutputStream::Impl { void setKeywords(const _CORBA_Unbounded_Sequence& properties) { + _markDirtySRI(); _sri.keywords = properties; - _sriUpdated = true; } void setKeyword(const std::string& name, const CORBA::Any& value) { + _markDirtySRI(); redhawk::PropertyMap::cast(_sri.keywords)[name] = value; - _sriUpdated = true; } void eraseKeyword(const std::string& name) { + _markDirtySRI(); redhawk::PropertyMap::cast(_sri.keywords).erase(name); - _sriUpdated = true; } void write(const ScalarBuffer& data, const BULKIO::PrecisionUTCTime& time) @@ -103,7 +99,14 @@ class OutputStream::Impl { _port->pushSRI(_sri); _sriUpdated = false; } - _send(data, time, false); + + // If buffering is disabled, or the buffer is empty and the input data is + // large enough for a full buffer, send it immediately + if ((_bufferSize == 0) || (_bufferOffset == 0 && (data.size() >= _bufferSize))) { + _send(data, time, false); + } else { + _doBuffer(data, time); + } } void write(const ComplexBuffer& data, const BULKIO::PrecisionUTCTime& time) @@ -136,14 +139,64 @@ class OutputStream::Impl { } } + size_t bufferSize() const + { + return _bufferSize; + } + + void setBufferSize(size_t samples) + { + // Avoid needless thrashing + if (samples == _bufferSize) { + return; + } + _bufferSize = samples; + + // If the new buffer size is less than the currently buffered data, flush + if (_bufferSize < _bufferOffset) { + flush(); + } else if (_bufferSize > _buffer.size()) { + // The buffer size is increasing beyond the existing allocation; allocate + // a new buffer of the desired size and copy existing data + redhawk::buffer new_buffer(_bufferSize); + if (_bufferOffset > 0) { + std::copy(&_buffer[0], &_buffer[_bufferOffset], &new_buffer[0]); + } + + // Replace the old buffer with the new one + _buffer.swap(new_buffer); + } + } + + void flush() + { + if (_bufferOffset == 0) { + return; + } + + _flush(false); + } + void close() { - // Send an empty packet with an end-of-stream marker; since there is no - // sample data, the timestamp does not matter - _send(ScalarBuffer(), bulkio::time::utils::notSet(), true); + if (_bufferOffset > 0) { + // Add the end-of-stream marker to the buffered data and its timestamp + _flush(true); + } else { + // Send an empty packet with an end-of-stream marker; since there is no + // sample data, the timestamp does not matter + _send(ScalarBuffer(), bulkio::time::utils::notSet(), true); + } } private: + void _markDirtySRI() + { + // Flush buffered data still using the old SRI + flush(); + _sriUpdated = true; + } + void _send(const ScalarBuffer& data, const BULKIO::PrecisionUTCTime& time, bool eos) { _port->pushPacket(data, time, eos, _streamID); @@ -152,17 +205,58 @@ class OutputStream::Impl { template void _setStreamMetadata(Field& field, Value value) { + _markDirtySRI(); if (field == value) { return; } field = value; - _sriUpdated = true; + } + + void _flush(bool eos) + { + // Push out all buffered data, which must be less than the full allocated + // size otherwise it would have already been sent + _send(_buffer.slice(0, _bufferOffset), _bufferTime, eos); + + // Allocate a new buffer and reset the offset index + _buffer = redhawk::buffer(_bufferSize); + _bufferOffset = 0; + } + + void _doBuffer(const ScalarBuffer& data, const BULKIO::PrecisionUTCTime& time) + { + // If this is the first data being queued, use its timestamp for the start + // time of the buffered data + if (_bufferOffset == 0) { + _bufferTime = time; + } + + // Only buffer up to the currently configured buffer size + size_t count = std::min(data.size(), _bufferSize - _bufferOffset); + std::copy(&data[0], &data[count], &_buffer[_bufferOffset]); + + // Advance buffer offset, flushing if the buffer is full + _bufferOffset += count; + if (_bufferOffset >= _bufferSize) { + _flush(false); + } + + // Handle remaining data + if (count < data.size()) { + BULKIO::PrecisionUTCTime next = time + (_sri.xdelta * count); + _doBuffer(data.slice(count), next); + } } const std::string _streamID; OutPortType* _port; BULKIO::StreamSRI _sri; bool _sriUpdated; + + redhawk::buffer _buffer; + BULKIO::PrecisionUTCTime _bufferTime; + size_t _bufferSize; + size_t _bufferOffset; }; template @@ -231,6 +325,24 @@ void OutputStream::blocking(bool mode) _impl->setBlocking(mode); } +template +size_t OutputStream::bufferSize() const +{ + return _impl->bufferSize(); +} + +template +void OutputStream::setBufferSize(size_t samples) +{ + _impl->setBufferSize(samples); +} + +template +void OutputStream::flush() +{ + _impl->flush(); +} + template const redhawk::PropertyMap& OutputStream::keywords() const { diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h index 7d60ec41f..29dd9f724 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h @@ -76,6 +76,24 @@ namespace bulkio { } void eraseKeyword(const std::string& name); + /** + * @brief Returns the internal buffer size. + * + * A buffer size of 0 indicates that buffering is disabled. + */ + size_t bufferSize() const; + + /** + * @brief Sets the internal buffer size. + * @param samples Number of samples to buffer (0 disables buffering). + */ + void setBufferSize(size_t samples); + + /** + * Send all currently buffered data. + */ + void flush(); + template void write(const std::vector& data, const BULKIO::PrecisionUTCTime& time) { From 40d0cb347d5eee985684f614ad8fe65732dbd1ef Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 29 Jul 2016 14:54:24 -0400 Subject: [PATCH 0146/1644] Prevent end-of-stream from getting lost when using getCurrentStream() by not dissociating the stream from the port until the end-of-stream has had a chance to be checked in the normal usage --- .../libsrc/cpp/bulkio_in_stream.cpp | 30 +++++++++++++++---- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp index b326503b7..e7447e3d5 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp @@ -37,6 +37,7 @@ class InputStream::Impl { _sri(sri), _eosReceived(false), _eosReached(false), + _eosReported(false), _port(port), _queue(), _pending(0), @@ -70,6 +71,13 @@ class InputStream::Impl { // state again _fetchPacket(false); } + if (_eosReached && !_eosReported) { + // This is the first time end-of-stream has been checked since it was + // reached; remove the stream from the port now, since the caller knows + // that the stream ended + _port->removeStream(_streamID); + _eosReported = true; + } return _eosReached; } @@ -120,6 +128,14 @@ class InputStream::Impl { if (!sri) { // No SRI retreived implies no data will be retrieved, either due to end- // of-stream or because it would block + if (_eosReached && !_eosReported) { + // If this is the first time end-of-stream could be reported, remove + // the stream from the port; since the returned data block is invalid, + // that's a cue for the caller to check end-of-stream, but they don't + // have to + _port->removeStream(_streamID); + _eosReported = true; + } return DataBlockType(); } @@ -221,7 +237,14 @@ class InputStream::Impl { bool hasBufferedData() const { - return !_queue.empty() || _pending; + if (_eosReached && !_eosReported) { + // Technically, there is no data to report; however, to nudge the caller + // to check end-of-stream, return true + return true; + } else { + // Return true if either there are queued or pending packets + return !_queue.empty() || _pending; + } } private: @@ -250,9 +273,6 @@ class InputStream::Impl { // Acknowledge any end-of-stream flag and delete the packet PacketType* packet = _queue.front(); _eosReached = packet->EOS; - if (_eosReached) { - _port->removeStream(_streamID); - } delete packet; _queue.erase(_queue.begin()); @@ -401,7 +421,6 @@ class InputStream::Impl { if (_queue.empty()) { // No queued packets, read pointer has reached end-of-stream _eosReached = true; - _port->removeStream(_streamID); } else { // Assign the end-of-stream flag to the last packet in the queue so // that it is handled on read @@ -423,6 +442,7 @@ class InputStream::Impl { BULKIO::StreamSRI _sri; bool _eosReceived; bool _eosReached; + bool _eosReported; InPortType* _port; std::vector _queue; PacketType* _pending; From 1cf25c4c38f6393836b9a4d554bd4da2797b2f8b Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 29 Jul 2016 15:05:44 -0400 Subject: [PATCH 0147/1644] Provide "unspecified bool" conversion operators on streams and data blocks, so that users don't have to use a double-negation (e.g., "!!stream") if they want to affirmatively check validity --- bulkioInterfaces/libsrc/cpp/bulkio_datablock.cpp | 6 ++++++ bulkioInterfaces/libsrc/cpp/bulkio_datablock.h | 5 +++++ bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp | 6 ++++++ bulkioInterfaces/libsrc/cpp/bulkio_in_stream.h | 5 +++++ bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp | 6 ++++++ bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h | 5 +++++ 6 files changed, 33 insertions(+) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_datablock.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_datablock.cpp index 39bf27a19..20c62f04a 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_datablock.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_datablock.cpp @@ -229,6 +229,12 @@ void DataBlock::inputQueueFlushed(bool flushed) _impl->inputQueueFlushed = flushed; } +template +DataBlock::operator unspecified_bool_type() const +{ + return _impl?&DataBlock::_impl:0; +} + template void DataBlock::swap(std::vector& other) { diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_datablock.h b/bulkioInterfaces/libsrc/cpp/bulkio_datablock.h index 10f36779d..eba0a0a4b 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_datablock.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_datablock.h @@ -100,6 +100,11 @@ namespace bulkio { private: struct Impl; boost::shared_ptr _impl; + + typedef boost::shared_ptr DataBlock::*unspecified_bool_type; + + public: + operator unspecified_bool_type() const; }; typedef DataBlock CharDataBlock; diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp index e7447e3d5..ff823f338 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp @@ -548,6 +548,12 @@ size_t InputStream::samplesAvailable() return _impl->samplesAvailable(); } +template +InputStream::operator unspecified_bool_type() const +{ + return _impl?&InputStream::_impl:0; +} + template bool InputStream::operator!() const { diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.h b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.h index 4eb20caf1..816f488fb 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.h @@ -77,6 +77,11 @@ namespace bulkio { class Impl; boost::shared_ptr _impl; + + typedef boost::shared_ptr InputStream::*unspecified_bool_type; + + public: + operator unspecified_bool_type() const; }; typedef InputStream InCharStream; diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp index 9d914f8cf..774b2bde2 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp @@ -440,6 +440,12 @@ void OutputStream::close() _impl.reset(); } +template +OutputStream::operator unspecified_bool_type() const +{ + return _impl?&OutputStream::_impl:0; +} + template class OutputStream; template class OutputStream; template class OutputStream; diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h index 29dd9f724..0c879aafe 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h @@ -162,6 +162,11 @@ namespace bulkio { class Impl; boost::shared_ptr _impl; + + typedef boost::shared_ptr OutputStream::*unspecified_bool_type; + + public: + operator unspecified_bool_type() const; }; typedef OutputStream OutCharStream; From e0725bbfa5f04b2c8c7a45f12e09720e8b8e4170 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 29 Jul 2016 15:36:51 -0400 Subject: [PATCH 0148/1644] Handle end-of-stream for disabled streams to ensure that they are at least dissociated from the port --- .../libsrc/cpp/bulkio_in_port.cpp | 48 +++++++------------ bulkioInterfaces/libsrc/cpp/bulkio_in_port.h | 14 +++--- 2 files changed, 22 insertions(+), 40 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp index cbd9ab03b..6d759ef9e 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp @@ -198,10 +198,6 @@ namespace bulkio { return; } - if (!isStreamEnabled(streamID)) { - return; - } - BULKIO::StreamSRI* sri; bool sriChanged = false; @@ -273,8 +269,6 @@ namespace bulkio { dataAvailable.notify_all(); } - packetReceived(streamID); - TRACE_EXIT( logger, "InPort::pushPacket" ); } @@ -305,27 +299,6 @@ namespace bulkio { } } - template < typename PortTraits > - bool InPortBase< PortTraits >::isStreamActive(const std::string& streamID) - { - return true; - } - - template < typename PortTraits > - bool InPortBase< PortTraits >::isStreamEnabled(const std::string& streamID) - { - return true; - } - - template < typename PortTraits > - void InPortBase< PortTraits >::packetReceived(const std::string& streamID) - { - if (isStreamActive(streamID)) { - packetWaiters.notify(streamID); - } - } - - template < typename PortTraits > void InPortBase< PortTraits >::enableStats( bool enable ) { @@ -517,11 +490,6 @@ namespace bulkio { { } - template < typename PortTraits > - void InPortBase< PortTraits >::removeStream(const std::string& streamID) - { - } - template < typename PortTraits > void InPortBase< PortTraits >::setLogger( LOGGER_PTR newLogger ) { logger = newLogger; @@ -740,6 +708,22 @@ namespace bulkio { return result; } + template < typename PortTraits > + void InPort< PortTraits >::queuePacket(const SharedBufferType& data, const BULKIO::PrecisionUTCTime& T, CORBA::Boolean EOS, const std::string& streamID) + { + if (isStreamEnabled(streamID)) { + super::queuePacket(data, T, EOS, streamID); + + if (isStreamActive(streamID)) { + packetWaiters.notify(streamID); + } + } else if (EOS) { + // Acknowledge the end-of-stream by removing the disabled stream before + // discarding the packet + removeStream(streamID); + } + } + template < typename PortTraits > void InPort< PortTraits >::createStream(const std::string& streamID, const BULKIO::StreamSRI& sri) { diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h index 83a2dbfb3..a3db4f8b3 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h @@ -333,13 +333,8 @@ namespace bulkio { Packet* peekPacket(float timeout, boost::unique_lock& lock); virtual void createStream(const std::string& streamID, const BULKIO::StreamSRI& sri); - virtual void removeStream(const std::string& streamID); - - virtual bool isStreamActive(const std::string& streamID); - virtual bool isStreamEnabled(const std::string& streamID); Packet* fetchPacket(const std::string& streamID); - void packetReceived(const std::string& streamID); friend class InputStream; size_t samplesAvailable(const std::string& streamID, bool firstPacket); @@ -476,11 +471,14 @@ namespace bulkio { // end-of-stream has been queued but not yet read std::multimap pendingStreams; + // Override of base class queuePacket to add stream-related behavior + void queuePacket(const SharedBufferType& data, const BULKIO::PrecisionUTCTime& T, CORBA::Boolean EOS, const std::string& streamID); + virtual void createStream(const std::string& streamID, const BULKIO::StreamSRI& sri); - virtual void removeStream(const std::string& streamID); + void removeStream(const std::string& streamID); - virtual bool isStreamActive(const std::string& streamID); - virtual bool isStreamEnabled(const std::string& streamID); + bool isStreamActive(const std::string& streamID); + bool isStreamEnabled(const std::string& streamID); StreamList getReadyStreams(size_t samples); }; From f584d43f5180cf6c28657763ea3a1d5880543b91 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 29 Jul 2016 15:39:50 -0400 Subject: [PATCH 0149/1644] Minor cleanup --- bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp index 6d759ef9e..8c1071390 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp @@ -497,7 +497,7 @@ namespace bulkio { template < typename PortTraits > std::string InPortBase< PortTraits >::getRepid() const { - return PortType::_PD_repoId; + return PortType::_PD_repoId; } template < typename PortTraits > @@ -554,7 +554,7 @@ namespace bulkio { } /* - * Specializations of base class methods for dataXML ports + * Specializations of base class methods for dataFile ports */ template <> @@ -563,10 +563,6 @@ namespace bulkio { return 1; } - /* - * Specializations of base class methods for dataFile ports - */ - // template < typename PortTraits > InPort< PortTraits >::InPort(std::string port_name, From 220ea8715d48ceff583d74ab36140f4314701d01 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 1 Aug 2016 10:59:53 -0400 Subject: [PATCH 0150/1644] When an input stream gets disabled, purge its internal queue --- .../libsrc/cpp/bulkio_in_stream.cpp | 67 ++++++++++++------- 1 file changed, 42 insertions(+), 25 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp index ff823f338..c48066694 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp @@ -22,6 +22,8 @@ #include "bulkio_time_operators.h" #include "bulkio_in_port.h" +#include + using bulkio::InputStream; template @@ -87,7 +89,7 @@ class InputStream::Impl { size_t queued = _samplesQueued; if (queued > 0) { // Adjust number of samples to account for complex data, if necessary - const BULKIO::StreamSRI& sri = _queue.front()->SRI; + const BULKIO::StreamSRI& sri = _queue.front().SRI; if (sri.mode) { queued /= 2; } @@ -116,7 +118,7 @@ class InputStream::Impl { return DataBlockType(); } // Only read up to the end of the first packet in the queue - const size_t samples = _queue.front()->buffer.size() - _sampleOffset; + const size_t samples = _queue.front().buffer.size() - _sampleOffset; return _readData(samples, samples); } @@ -232,7 +234,22 @@ class InputStream::Impl { void disable() { _enabled = false; - // TODO: purge queue + + // Clear queued packets, which implicitly deletes them + _queue.clear(); + + // Explicitly delete pending packet + if (_pending) { + delete _pending; + _pending = 0; + } + + // Unless end-of-stream has been received by the port (meaning any further + // packets with this stream ID are for a different instance), purge any + // packets for this stream from the port's queue + if (!_eosReceived) { + // TODO + } } bool hasBufferedData() const @@ -251,7 +268,7 @@ class InputStream::Impl { void _consumeData(size_t count) { while (count > 0) { - const SharedBufferType& data = _queue.front()->buffer; + const SharedBufferType& data = _queue.front().buffer; const size_t available = data.size() - _sampleOffset; const size_t pass = std::min(available, count); @@ -271,11 +288,8 @@ class InputStream::Impl { void _consumePacket() { // Acknowledge any end-of-stream flag and delete the packet - PacketType* packet = _queue.front(); - _eosReached = packet->EOS; - - delete packet; - _queue.erase(_queue.begin()); + _eosReached = _queue.front().EOS; + _queue.pop_front(); // If the queue is empty, move the pending packet onto the queue if (_queue.empty() && _pending) { @@ -287,28 +301,28 @@ class InputStream::Impl { DataBlockType _readData(size_t count, size_t consume) { // Acknowledge pending SRI change - PacketType* front = _queue.front(); + PacketType& front = _queue.front(); int sriChangeFlags = bulkio::sri::NONE; - if (front->sriChanged) { - sriChangeFlags = bulkio::sri::compareFields(_sri, front->SRI); - front->sriChanged = false; - _sri = front->SRI; + if (front.sriChanged) { + sriChangeFlags = bulkio::sri::compareFields(_sri, front.SRI); + front.sriChanged = false; + _sri = front.SRI; } // Allocate empty data block and propagate the SRI change and input queue // flush flags DataBlockType data(_sri); data.sriChangeFlags(sriChangeFlags); - if (front->inputQueueFlushed) { + if (front.inputQueueFlushed) { data.inputQueueFlushed(true); - front->inputQueueFlushed = false; + front.inputQueueFlushed = false; } size_t last_offset = _sampleOffset + count; - if (last_offset <= front->buffer.size()) { + if (last_offset <= front.buffer.size()) { // The requsted sample count can be satisfied from the first packet - _addTimestamp(data, _sampleOffset, 0, front->T); - data.buffer(front->buffer.slice(_sampleOffset, last_offset)); + _addTimestamp(data, _sampleOffset, 0, front.T); + data.buffer(front.buffer.slice(_sampleOffset, last_offset)); } else { // We have to span multiple packets to get the data redhawk::buffer buffer(count); @@ -319,11 +333,11 @@ class InputStream::Impl { size_t packet_index = 0; size_t packet_offset = _sampleOffset; while (count > 0) { - PacketType* packet = _queue[packet_index]; - const SharedBufferType& input_data = packet->buffer; + PacketType& packet = _queue[packet_index]; + const SharedBufferType& input_data = packet.buffer; // Add the timestamp for this pass - _addTimestamp(data, packet_offset, data_offset, packet->T); + _addTimestamp(data, packet_offset, data_offset, packet.T); // The number of samples copied on this pass may be less than the total // remaining @@ -382,7 +396,7 @@ class InputStream::Impl { } } - return &(_queue.front()->SRI); + return &(_queue.front().SRI); } bool _fetchPacket(bool blocking) @@ -424,10 +438,13 @@ class InputStream::Impl { } else { // Assign the end-of-stream flag to the last packet in the queue so // that it is handled on read - _queue.back()->EOS = true; + _queue.back().EOS = true; } + // Explicitly delete the packet, since it isn't being queued delete packet; } else { + // Add the packet to the queue, taking ownership; it will be deleted when + // it's consumed _samplesQueued += packet->buffer.size(); _queue.push_back(packet); } @@ -444,7 +461,7 @@ class InputStream::Impl { bool _eosReached; bool _eosReported; InPortType* _port; - std::vector _queue; + boost::ptr_deque _queue; PacketType* _pending; size_t _samplesQueued; size_t _sampleOffset; From cf156dea0dde0743b68e96ae7e2e6bf015426400 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 1 Aug 2016 12:18:28 -0400 Subject: [PATCH 0151/1644] Discard packets queued in the port when an input stream is set to disabled --- .../libsrc/cpp/bulkio_in_port.cpp | 63 +++++++++++-------- bulkioInterfaces/libsrc/cpp/bulkio_in_port.h | 4 ++ .../libsrc/cpp/bulkio_in_stream.cpp | 2 +- 3 files changed, 43 insertions(+), 26 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp index 8c1071390..1422be09b 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp @@ -445,6 +445,28 @@ namespace bulkio { } + namespace { + template + inline typename std::deque::iterator do_erase(std::deque& container, typename std::deque::iterator pos) + { + if (pos == container.begin()) { + // PERFORMANCE NOTE: + // In a 1-item deque, erase will end up calling pop_back(); however, + // this can lead to greatly reduced performance (observed as 1/4 the + // data rate on some systems). In the case where the deque alternates + // between 0 and 1 packets (i.e., data is consumed as fast as it is + // produced), alternating calls to push_back() and pop_back() will + // always cause allocation and deallocation. Explicitly calling + // pop_front() if it's the first element prevents this worst case + // scenario. + container.pop_front(); + return container.begin(); + } else { + return container.erase(pos); + } + } + } + template < typename PortTraits > typename InPortBase< PortTraits >::Packet * InPortBase< PortTraits >::fetchPacket(const std::string &streamID) { @@ -460,20 +482,7 @@ namespace bulkio { for (typename PacketQueue::iterator ii = packetQueue.begin(); ii != packetQueue.end(); ++ii) { if ((*ii)->streamID == streamID) { Packet* packet = *ii; - if (ii == packetQueue.begin()) { - // PERFORMANCE NOTE: - // In a 1-item deque, erase will end up calling pop_back(); however, - // this can lead to greatly reduced performance (observed as 1/4 the - // data rate on some systems). In the case where the deque alternates - // between 0 and 1 packets (i.e., data is consumed as fast as it is - // produced), alternating calls to push_back() and pop_back() will - // always cause allocation and deallocation. Explicitly calling - // pop_front() if it's the first element prevents this worst case - // scenario. - packetQueue.pop_front(); - } else { - packetQueue.erase(ii); - } + bulkio::do_erase(packetQueue, ii); return packet; } } @@ -481,18 +490,22 @@ namespace bulkio { } template < typename PortTraits > - void InPortBase< PortTraits >::setNewStreamListener(SriListener* newListener) { - newStreamCallback = boost::ref(*newListener); - } - - template < typename PortTraits > - void InPortBase< PortTraits >::createStream(const std::string& streamID, const BULKIO::StreamSRI& sri) + void InPortBase< PortTraits >::discardPacketsForStream(const std::string& streamID) { - } - - template < typename PortTraits > - void InPortBase< PortTraits >::setLogger( LOGGER_PTR newLogger ) { - logger = newLogger; + SCOPED_LOCK lock(dataBufferLock); + for (typename PacketQueue::iterator ii = packetQueue.begin(); ii != packetQueue.end();) { + if ((*ii)->streamID == streamID) { + bool eos = (*ii)->EOS; + delete *ii; + ii = bulkio::do_erase(packetQueue, ii); + queueAvailable.notify_one(); + if (eos) { + break; + } + } else { + ++ii; + } + } } template < typename PortTraits > diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h index a3db4f8b3..edf634ca9 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h @@ -336,6 +336,10 @@ namespace bulkio { Packet* fetchPacket(const std::string& streamID); + // Discard currently queued packets for the given stream ID, up to the + // first end-of-stream + void discardPacketsForStream(const std::string& streamID); + friend class InputStream; size_t samplesAvailable(const std::string& streamID, bool firstPacket); diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp index c48066694..a48dbac1c 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp @@ -248,7 +248,7 @@ class InputStream::Impl { // packets with this stream ID are for a different instance), purge any // packets for this stream from the port's queue if (!_eosReceived) { - // TODO + _port->discardPacketsForStream(_streamID); } } From c6dbf3ba599b27c48a728d5b8e2ed159c55b1aa3 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 1 Aug 2016 13:07:22 -0400 Subject: [PATCH 0152/1644] Minor code cleanup in SRI handling --- .../libsrc/cpp/bulkio_in_port.cpp | 20 +++++++------------ 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp index 1422be09b..b3f4a3716 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp @@ -118,15 +118,10 @@ namespace bulkio { BULKIO::StreamSRISequence * InPortBase< PortTraits >::activeSRIs() { SCOPED_LOCK lock(sriUpdateLock); - BULKIO::StreamSRISequence seq_rtn; - SriMap::iterator currH; - int i = 0; - for (currH = currentHs.begin(); currH != currentHs.end(); currH++) { - i++; - seq_rtn.length(i); - seq_rtn[i-1] = currH->second.first; + BULKIO::StreamSRISequence_var retSRI = new BULKIO::StreamSRISequence(); + for (SriMap::iterator currH = currentHs.begin(); currH != currentHs.end(); ++currH) { + ossie::corba::push_back(retSRI, currH->second.first); } - BULKIO::StreamSRISequence_var retSRI = new BULKIO::StreamSRISequence(seq_rtn); // NOTE: You must delete the object that this function returns! return retSRI._retn(); @@ -164,13 +159,13 @@ namespace bulkio { } const std::string streamID(H.streamID); - BULKIO::StreamSRI tmpH = H; // mutable copy for callbacks LOG_TRACE(logger,"pushSRI - FIND- PORT:" << name << " NEW SRI:" << streamID << " Mode:" << H.mode << " XDELTA:" << 1.0/H.xdelta ); SCOPED_LOCK lock(sriUpdateLock); SriMap::iterator currH = currentHs.find(streamID); if (currH == currentHs.end()) { LOG_DEBUG(logger,"pushSRI PORT:" << name << " NEW SRI:" << streamID << " Mode:" << H.mode ); + BULKIO::StreamSRI tmpH = H; // mutable copy for callbacks if (newStreamCallback) { newStreamCallback(tmpH); } @@ -179,9 +174,9 @@ namespace bulkio { createStream(streamID, tmpH); } else { - if ( sri_cmp && !sri_cmp(tmpH, currH->second.first)) { + if ( sri_cmp && !sri_cmp(H, currH->second.first)) { LOG_DEBUG(logger,"pushSRI PORT:" << name << " SAME SRI:" << streamID << " Mode:" << H.mode ); - currentHs[streamID] = std::make_pair(tmpH, true); + currentHs[streamID] = std::make_pair(H, true); } } TRACE_EXIT( logger, "InPort::pushSRI" ); @@ -201,11 +196,10 @@ namespace bulkio { BULKIO::StreamSRI* sri; bool sriChanged = false; - SriMap::iterator currH; { SCOPED_LOCK lock(sriUpdateLock); - currH = currentHs.find(streamID); + SriMap::iterator currH = currentHs.find(streamID); if (currH != currentHs.end()) { sri = &currH->second.first; sriChanged = currH->second.second; From 3a8aac8ecce6dd2555e0deada87179e830169bca Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 2 Aug 2016 08:31:23 -0400 Subject: [PATCH 0153/1644] Add back empty base class implementation of createStream --- bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp index b3f4a3716..9d02ed61d 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp @@ -461,6 +461,11 @@ namespace bulkio { } } + template < typename PortTraits > + void InPortBase< PortTraits >::createStream(const std::string& /*unused*/, const BULKIO::StreamSRI& /*unused*/) + { + } + template < typename PortTraits > typename InPortBase< PortTraits >::Packet * InPortBase< PortTraits >::fetchPacket(const std::string &streamID) { From f1d210549c74c77c2d6f679bced64160e26de444 Mon Sep 17 00:00:00 2001 From: Ryan Bauman Date: Wed, 12 Oct 2016 15:06:42 -0400 Subject: [PATCH 0154/1644] RELENG-459 - reconcile bulkio shared_address branch changes --- .../libsrc/cpp/bulkio_connection.hpp | 16 +++++++++------- .../testing/tests/cpp/Bulkio_OutPort_Fixture.cpp | 12 ++++++++++++ .../testing/tests/cpp/Bulkio_OutPort_Fixture.h | 1 + 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp b/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp index ad57e6c27..97aeab3d5 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp @@ -136,13 +136,8 @@ namespace bulkio { RemoteConnection(name, port) { // Multiply by some number < 1 to leave some margin for the CORBA header - const size_t maxPayloadSize = (size_t) (bulkio::Const::MaxTransferBytes() * .9); + const size_t maxPayloadSize = (size_t) (bulkio::Const::MaxTransferBytes() * .9); maxSamplesPerPush = maxPayloadSize/sizeof(TransportType); - // Make sure maxSamplesPerPush is even so that complex data case is - // handled properly - if (maxSamplesPerPush%2 != 0){ - maxSamplesPerPush--; - } } /* @@ -158,6 +153,13 @@ namespace bulkio { { double xdelta = sri.xdelta; size_t itemSize = sri.mode?2:1; + size_t frameSize = itemSize; + if (sri.subsize > 0) { + frameSize *= sri.subsize; + } + // Quantize the push size (in terms of scalars) to the nearest frame, + // which takes both the complex mode and subsize into account + const size_t maxPushSize = (maxSamplesPerPush/frameSize) * frameSize; // Always do at least one push (may be empty), ensuring that all samples // are pushed @@ -169,7 +171,7 @@ namespace bulkio { do { // Don't send more samples than are remaining - const size_t pushSize = std::min(samplesRemaining, maxSamplesPerPush); + const size_t pushSize = std::min(samplesRemaining, maxPushSize); samplesRemaining -= pushSize; // Send end-of-stream as false for all sub-packets except for the diff --git a/bulkioInterfaces/libsrc/testing/tests/cpp/Bulkio_OutPort_Fixture.cpp b/bulkioInterfaces/libsrc/testing/tests/cpp/Bulkio_OutPort_Fixture.cpp index e29579eb3..7d12bb4d8 100644 --- a/bulkioInterfaces/libsrc/testing/tests/cpp/Bulkio_OutPort_Fixture.cpp +++ b/bulkioInterfaces/libsrc/testing/tests/cpp/Bulkio_OutPort_Fixture.cpp @@ -569,3 +569,15 @@ Bulkio_OutPort_Fixture::test_sdds() CPPUNIT_ASSERT_NO_THROW( port ); } + + +void +Bulkio_OutPort_Fixture::test_sdds_sri() +{ + bulkio::OutSDDSPort *port = new bulkio::OutSDDSPort("test_sdds_sri", logger ); + CPPUNIT_ASSERT( port != NULL ); + + test_port_sri< bulkio::OutSDDSPort, bulkio::InSDDSPort > ( port ); + + CPPUNIT_ASSERT_NO_THROW( port ); +} diff --git a/bulkioInterfaces/libsrc/testing/tests/cpp/Bulkio_OutPort_Fixture.h b/bulkioInterfaces/libsrc/testing/tests/cpp/Bulkio_OutPort_Fixture.h index 4a66421af..c649f8b6f 100644 --- a/bulkioInterfaces/libsrc/testing/tests/cpp/Bulkio_OutPort_Fixture.h +++ b/bulkioInterfaces/libsrc/testing/tests/cpp/Bulkio_OutPort_Fixture.h @@ -49,6 +49,7 @@ class Bulkio_OutPort_Fixture : public CppUnit::TestFixture CPPUNIT_TEST( test_xml ); CPPUNIT_TEST( test_create_sdds ); CPPUNIT_TEST( test_sdds ); + CPPUNIT_TEST( test_sdds_sri ); CPPUNIT_TEST_SUITE_END(); public: From 5c8691b070089c76a635086178c7cdc8e088510a Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 16 Mar 2016 10:05:47 -0400 Subject: [PATCH 0155/1644] Provide a C++ API to get a pointer back to the servant for a given object reference, if that object reference is in the same process space --- redhawk/src/base/framework/CorbaUtils.cpp | 29 +++++++++++++++++++++ redhawk/src/base/framework/Makefile.am | 2 ++ redhawk/src/base/include/ossie/CorbaUtils.h | 16 ++++++++++++ redhawk/src/configure.ac | 2 ++ 4 files changed, 49 insertions(+) diff --git a/redhawk/src/base/framework/CorbaUtils.cpp b/redhawk/src/base/framework/CorbaUtils.cpp index f68f3690a..2b249f2a5 100644 --- a/redhawk/src/base/framework/CorbaUtils.cpp +++ b/redhawk/src/base/framework/CorbaUtils.cpp @@ -24,6 +24,8 @@ #include #include #include +#include +#include #include "ossie/CorbaUtils.h" @@ -351,6 +353,33 @@ void setObjectCommFailureRetries (CORBA::Object_ptr obj, int numRetries) omniORB::installCommFailureExceptionHandler(obj, reinterpret_cast(numRetries), handleCommFailure); } +PortableServer::ServantBase* internal::getLocalServant(CORBA::Object_ptr object) +{ + // Find the identity using internal omniORB interfaces, and then check + // whether the object is local to this address space; reading through the + // omniORB library code, it does not appear that this operation requires + // holding the internal omniORB lock + omniIdentity* identity = object->_PR_getobj()->_identity(); + if (identity->inThisAddressSpace()) { + // Given that it's in the same address space, one would assume that + // casting to omniLocalIdentity should always succeed, but since this + // is using undocumented internal omniORB interfaces, use dynamic_cast + // defensively just in case + omniLocalIdentity* local_identity = dynamic_cast(identity); + if (local_identity) { + omniServant* servant = local_identity->servant(); + // Instead of returning omniServant, which is omniORB-specific, + // use its _downcast() method to get a pointer to the servant as + // the standard PortableServer::ServantBase class; while not + // strictly necessary in this case, multiple inheritance can make + // casts between related types tricky (note that it returns a void + // pointer, so it still requires a cast, just not dynamic_cast) + return reinterpret_cast(servant->_downcast()); + } + } + return 0; +} + #define LNTRACE( lname, expression ) RH_TRACE( rh_logger::Logger::getLogger(lname), expression ) #define LNDEBUG( lname, expression ) RH_DEBUG( rh_logger::Logger::getLogger(lname), expression ) #define LNINFO( lname, expression ) RH_INFO( rh_logger::Logger::getLogger(lname), expression ) diff --git a/redhawk/src/base/framework/Makefile.am b/redhawk/src/base/framework/Makefile.am index 10dbfa9fc..9249ee6b2 100644 --- a/redhawk/src/base/framework/Makefile.am +++ b/redhawk/src/base/framework/Makefile.am @@ -59,6 +59,8 @@ libossiecf_la_SOURCES = AggregateDevice_impl.cpp \ Versions.cpp libossiecf_la_CXXFLAGS = -Wall $(BOOST_CPPFLAGS) $(OMNICOS_CFLAGS) $(OMNIORB_CFLAGS) $(LOG4CXX_FLAGS) +# Include the omniORB internal directory, otherwise CorbaUtils will not build +libossiecf_la_CXXFLAGS +=-I$(OMNIORB_INCLUDEDIR)/omniORB4/internal libossiecf_la_LIBADD = $(BOOST_LDFLAGS) $(BOOST_FILESYSTEM_LIB) $(BOOST_SERIALIZATION_LIB) $(BOOST_THREAD_LIB) $(BOOST_SYSTEM_LIB) $(OMNICOS_LIBS) $(OMNIORB_LIBS) $(LOG4CXX_LIBS) -ldl libossiecf_la_LDFLAGS = -Wall -version-info $(LIBOSSIECF_VERSION_INFO) diff --git a/redhawk/src/base/include/ossie/CorbaUtils.h b/redhawk/src/base/include/ossie/CorbaUtils.h index 5f608d268..78459564d 100644 --- a/redhawk/src/base/include/ossie/CorbaUtils.h +++ b/redhawk/src/base/include/ossie/CorbaUtils.h @@ -223,6 +223,22 @@ namespace ossie { // Set up a handler for retrying calls to the provided object on a COMM_FAILURE exception. void setObjectCommFailureRetries (CORBA::Object_ptr obj, int numRetries); + namespace internal { + // Implementation of reference-to-servant lookup for generic type + PortableServer::ServantBase* getLocalServant(CORBA::Object_ptr object); + } + + // If the object reference is to a servant in this process space, return a pointer to + // the local servant; otherwise, return a null pointer + template + T* getLocalServant(CORBA::Object_ptr object) { + PortableServer::ServantBase* servant = internal::getLocalServant(object); + if (servant) { + return dynamic_cast(servant); + } + return 0; + } + // Mapping of C++ types to type codes. template static CORBA::TypeCode_ptr TypeCode (void) diff --git a/redhawk/src/configure.ac b/redhawk/src/configure.ac index 712bd16ce..43ab53adc 100644 --- a/redhawk/src/configure.ac +++ b/redhawk/src/configure.ac @@ -75,6 +75,8 @@ if test x"$HAVE_EXPAT" = xno ; then fi PKG_CHECK_MODULES([OMNIORB], [omniORB4 >= 4.0.0]) +OMNIORB_INCLUDEDIR=`pkg-config --variable=includedir omniORB4` +AC_SUBST(OMNIORB_INCLUDEDIR) PKG_CHECK_MODULES([OMNITHREAD], [omnithread3 >= 4.0.0]) PKG_CHECK_MODULES([OMNIDYNAMIC], [omniDynamic4 >= 4.0.0]) From 09d50e19249eca35c875ac3adaaa66dc8fc372f1 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 8 Apr 2016 15:08:36 -0400 Subject: [PATCH 0156/1644] Add shared buffer classes --- redhawk/src/base/include/ossie/Makefile.am | 2 +- .../src/base/include/ossie/shared_buffer.h | 622 ++++++++++++++++++ 2 files changed, 623 insertions(+), 1 deletion(-) create mode 100644 redhawk/src/base/include/ossie/shared_buffer.h diff --git a/redhawk/src/base/include/ossie/Makefile.am b/redhawk/src/base/include/ossie/Makefile.am index 57b84ab4b..c659300ad 100644 --- a/redhawk/src/base/include/ossie/Makefile.am +++ b/redhawk/src/base/include/ossie/Makefile.am @@ -61,7 +61,7 @@ pkginclude_HEADERS = AggregateDevice_impl.h \ OptionalProperty.h \ PropertyMonitor.h \ Autocomplete.h \ - Versions.h + shared_buffer.h nobase_pkginclude_HEADERS = internal/equals.h \ logging/rh_logger.h \ diff --git a/redhawk/src/base/include/ossie/shared_buffer.h b/redhawk/src/base/include/ossie/shared_buffer.h new file mode 100644 index 000000000..db725561a --- /dev/null +++ b/redhawk/src/base/include/ossie/shared_buffer.h @@ -0,0 +1,622 @@ +#ifndef REDHAWK_SHARED_BUFFER_H +#define REDHAWK_SHARED_BUFFER_H + +#include +#include + +#include + +namespace redhawk { + + /** + * @brief Class to adapt an STL-compliant allocator to a deleter. + */ + template + class allocator_deleter : public Alloc { + public: + /// @brief The allocator type (Alloc). + typedef Alloc allocator_type; + + /** + * @brief Construct an %allocator_deleter. + * + * @internal The STL allocator concept defines deallocate as taking + * both a pointer and a size; unfortunately, Boost smart pointers + * expect deleters take just a pointer. This class extends from the + * template parameter, an allocator (which must be copy-constructible), + * and stores the size for use with deallocate. + */ + allocator_deleter(size_t size, const allocator_type& alloc=allocator_type()) : + allocator_type(alloc), + _M_size(size) + { + } + + /** + * @brief Deallocates a pointer. + */ + void operator() (typename allocator_type::pointer ptr) + { + this->deallocate(ptr, _M_size); + } + + private: + const size_t _M_size; + }; + + // Forward declaration of read/write buffer class. + template + class buffer; + + /** + * @brief An immutable container that can share its data with other + * instances. + * + * The %read_buffer class provides read-only access to a sized array of + * elements that can be shared between many buffer instances. This enables + * the transfer of ownership of data without explicit management of + * references. + * + * read_buffers have reference semantics. Assignment and copy construction + * do not copy any elements, only the data pointer. A %read_buffer never + * peforms any memory allocation of its own, but can take ownership of an + * existing array. When the last reference to the underlying data goes + * away, the data is freed. + * + * For write access and memory allocation, see buffer. + */ + template + class read_buffer { + public: + /// @brief The element type (T). + typedef T value_type; + /** + * @brief A random access iterator to const value_type. + * + * Note that all access to %read_buffer is const. This means that + * %iterator and %const_iterator are equivalent. + */ + typedef const value_type* iterator; + /** + * @brief A random access iterator to const value_type. + * + * Note that all access to %read_buffer is const. This means that + * %iterator and %const_iterator are equivalent. + */ + typedef iterator const_iterator; + + /** + * @brief Construct an empty %read_buffer. + */ + read_buffer() : + _M_array(), + _M_start(0), + _M_finish(0) + { + } + + /** + * @brief Construct a %read_buffer with an existing pointer. + * @param data Pointer to first element. + * @param size Number of elements. + * + * The newly-created %read_buffer takes ownership of @a data. When the + * last %read_buffer pointing to @a data is destroyed, @a data will be + * deleted with delete[]. + */ + read_buffer(value_type* data, size_t size) : + _M_array(data), + _M_start(data), + _M_finish(data + size) + { + } + + /** + * @brief Construct a %read_buffer with an existing pointer and a custom + * deleter. + * @param data Pointer to first element. + * @param size Number of elements. + * @param deleter Callable object. + * + * @a D must by copy-constructible. When the last %read_buffer pointing + * to @a data is destroyed, @a deleter will be called on @a data. This + * can be used to define custom release behavior. + */ + template + read_buffer(value_type* data, size_t size, D deleter) : + _M_array(data, deleter), + _M_start(data), + _M_finish(data + size) + { + } + + /** + * The dtor releases the %read_buffer's shared data pointer. If no + * other %read_buffer points to the data, the data is released. + */ + ~read_buffer() + { + } + + /** + * Returns a read-only iterator that points to the first element in the + * %read_buffer. + */ + iterator begin() const + { + return iterator(this->_M_begin()); + } + + /** + * Returns a read-only iterator that points one past the last element + * in the %read_buffer. + */ + iterator end() const + { + return iterator(this->_M_end()); + } + + /** + * @brief Subscript access to the data contained in the %read_buffer. + * @param index The index of the element to access + * @return Read-only reference to element + */ + const value_type& operator[] (size_t index) const + { + return this->_M_index(index); + } + + /** + * Returns the number of elements in the %read_buffer. + */ + size_t size() const + { + return size_t(this->_M_finish - this->_M_start); + } + + /** + * Returns true if the %read_buffer is empty. + */ + bool empty() const + { + return this->begin() == this->end(); + } + + /** + * Returns a read-only pointer to the first element. + */ + const value_type* data() const + { + return this->_M_start; + } + + /** + * @brief Returns a %read_buffer containing a subset of elements. + * @param start Index of first element. + * @param end Index of last element, exclusive (default end). + * @return The new %read_buffer. + */ + read_buffer slice(size_t start, size_t end=size_t(-1)) const + { + read_buffer result(*this); + this->_M_slice(result, start, end); + return result; + } + + /** + * @brief Returns a copy of this %read_buffer. + * + * The returned %buffer points to a newly-allocated array. + */ + buffer copy() const + { + buffer result(this->size()); + this->_M_copy(result); + return result; + } + + /** + * @brief Returns a copy of this %read_buffer. + * @param allocator An allocator object. + * + * The returned %buffer points to a new array allocated with + * @a allocator. @a allocator must be copy-constructible. + */ + template + buffer copy(const Alloc& allocator) const + { + buffer result(this->size(), allocator); + this->_M_copy(result); + return result; + } + + /** + * @brief Swap contents with another %read_buffer. + * @param other %read_buffer to swap with. + */ + void swap(read_buffer& other) + { + this->_M_swap(other); + } + + /** + * @brief Reinterpret a read_buffer as another data type. + * @param other %read_buffer to reinterpret. + * @return The new %read_buffer. + * + * Data is reinterpreted by standard C++ reinterpret_cast semantics. + * The size of the new %read_buffer is the floor of the size of + * @a other multiplied by the ratio sizeof(U)/sizeof(T). + */ + template + static read_buffer recast(const read_buffer& other) + { + return _M_recast(other); + } + + protected: + /// @cond IMPL + + // Internal implementation of operator[]; supports const and non-const + // use. + value_type& _M_index(size_t index) const + { + return this->_M_start[index]; + } + + // Internal implementation of begin; supports const and non-const use. + value_type* _M_begin() const + { + return this->_M_start; + } + + // Internal implementation of end; supports const and non-const use. + value_type* _M_end() const + { + return this->_M_finish; + } + + // Internal implementation of swap. + void _M_swap(read_buffer& other) + { + this->_M_array.swap(other._M_array); + std::swap(this->_M_start, other._M_start); + std::swap(this->_M_finish, other._M_finish); + } + + // Adjusts the start and end pointers of a read_buffer to a the given + // slice indices. + void _M_slice(read_buffer& result, size_t start, size_t end) const + { + if (end == (size_t)-1) { + end = result.size(); + } + result._M_start += start; + result._M_finish = result._M_start + end - start; + } + + // Internal implementation of copy. Copies the contents of this buffer + // into another, pre-existing buffer. + void _M_copy(read_buffer& dest) const + { + std::copy(this->begin(), this->end(), dest._M_begin()); + } + + // Implementation of recast. The output type is a template parameter so + // that buffer can use this method as well. + template + static Tout _M_recast(const U& other) + { + // Reinterpret the input class (which is some form of read_buffer + // or buffer) via a void pointer so that the compiler doesn't + // object about strict aliasing rules, which shouldn't matter here. + // The in-memory layout is always the same irrespective of the + // individual element type (including the boost::shared_array), so + // the important effects of the copy constructor like reference + // counting will still occur. + const void* ptr = &other; + Tout result(*reinterpret_cast(ptr)); + // Truncate any extra bytes from the end of the array so that the + // end pointer is at an integral offset from the start (otherwise + // iterators might not meet). This may be a concern when the output + // type is larger than the input type; e.g., 9 floats yields 4 + // complex floats, with 1 float "lost". Note that size() already + // truncates the number of elements for us. + result._M_finish = result._M_start + result.size(); + return result; + } + /// @endcond + + private: + typedef boost::shared_array array_type; + + // Disallow swap with any other type (mainly, buffer). + template + void swap(U& other); + + array_type _M_array; + value_type* _M_start; + value_type* _M_finish; + }; + + + /** + * @brief A shared container data type. + * + * The %buffer class extends read_buffer to provides write access. Multiple + * buffers and read_buffers may point to the same underlying data. + * + * buffers have reference semantics. Assignment and copy construction do + * not copy any elements, only the data pointer. + * + * Unlike %read_buffer, %buffer has allocating constructors. When the + * last reference to the underlying data goes away, the data is freed. + */ + template + class buffer : public read_buffer + { + public: + /// @brief The read-only buffer type. + typedef read_buffer read_type; + /// @brief The element type (T). + typedef T value_type; + /// @brief A random access iterator to value_type. + typedef value_type* iterator; + /// @brief A random access iterator to const value_type. + typedef const value_type* const_iterator; + /// @brief The default allocator class. + typedef std::allocator default_allocator; + + /** + * @brief Construct an empty %buffer. + */ + buffer() : + read_type() + { + } + + /** + * @brief Construct a %buffer and allocate space. + * @param size Number of elements. + * + * This constructor allocates memory for @a size elements; no + * initialization is performed. + */ + buffer(size_t size) : + read_type(this->_M_allocate(size, default_allocator())) + { + } + + /** + * @brief Construct a %buffer and allocate space. + * @param size Number of elements. + * @param allocator An allocator. + * + * This constructor allocates memory for @a size elements using + * @a allocator; no initialization is performed. @a allocator must be + * copy-constructible. + */ + template + buffer(size_t size, const Alloc& allocator) : + read_type(this->_M_allocate(size, allocator)) + { + } + + /** + * @brief Construct a %buffer with an existing pointer. + * @param data Pointer to first element. + * @param size Number of elements. + * + * The newly-created %buffer takes ownership of @a data. When the last + * %buffer pointing to @a data is destroyed, @a data will be deleted + * with delete[]. + */ + buffer(value_type* data, size_t size) : + read_type(data, size) + { + } + + /** + * @brief Construct a %buffer with an existing pointer and a custom + * deleter. + * @param data Pointer to first element. + * @param size Number of elements. + * @param deleter Callable object. + * + * @a D must by copy-constructible. When the last %buffer pointing to + * @a data is destroyed, @a deleter will be called on @a data. This can + * be used to define custom release behavior. + */ + template + buffer(value_type* data, size_t size, D deleter) : + read_type(data, size, deleter) + { + } + + /** + * The dtor releases the %buffer's shared data pointer. If no other + * buffers point to the data, the data is released. + */ + ~buffer() + { + } + + /** + * Returns a read/write iterator that points to the first element in + * the %buffer. + */ + iterator begin() + { + return iterator(this->_M_begin()); + } + + /** + * Returns a read-only iterator that points to the first element in the + * %buffer. + */ + const_iterator begin() const + { + return const_iterator(this->_M_begin()); + } + + /** + * Returns a read/write iterator that points one past the last element + * in the %buffer. + */ + iterator end() + { + return iterator(this->_M_end()); + } + + /** + * Returns a read-only iterator that points one past the last element + * in the %buffer. + */ + const_iterator end() const + { + return const_iterator(this->_M_end()); + } + + /** + * @brief Subscript access to the data contained in the %buffer. + * @param index The index of the element to access + * @return Read/write reference to element + */ + value_type& operator[] (size_t index) + { + return this->_M_index(index); + } + + /** + * @brief Subscript access to the data contained in the %buffer. + * @param index The index of the element to access + * @return Read-only reference to element + */ + const value_type& operator[] (size_t index) const + { + return this->_M_index(index); + } + + /** + * Returns the number of elements in the %buffer. + */ + size_t size() const + { + return read_type::size(); + } + + /** + * Returns true if the %buffer is empty. + */ + bool empty() const + { + return read_type::empty(); + } + + /** + * Returns a read-only pointer to the first element. + */ + const value_type* data() const + { + return this->_M_begin(); + } + + /** + * Returns a read/write pointer to the first element. + */ + value_type* data() + { + return this->_M_begin(); + } + + /** + * @brief Returns a %read_buffer containing a subset of elements. + * @param start Index of first element. + * @param end Index of last element, exclusive (default end). + * @return The new %read_buffer. + */ + read_type slice(size_t start, size_t end=size_t(-1)) const + { + return read_type::slice(start, end); + } + + /** + * @brief Returns a %buffer containing a subset of elements. + * @param start Index of first element. + * @param end Index of last element, exclusive (default end). + * @return The new %buffer. + */ + buffer slice(size_t start, size_t end=size_t(-1)) + { + buffer result(*this); + this->_M_slice(result, start, end); + return result; + } + + /** + * @brief Returns a copy of this %buffer. + * + * The returned %buffer points to a newly-allocated array. + */ + buffer copy() const + { + return read_type::copy(); + } + + /** + * @brief Returns a copy of this %buffer. + * @param allocator An allocator object. + * + * The returned %buffer points to a new array allocated with + * @a allocator. @a allocator must be copy-constructible. + */ + template + buffer copy(const Alloc& allocator) const + { + return read_type::copy(allocator); + } + + /** + * @brief Swap contents with another %buffer. + * @param other %buffer to swap with. + */ + void swap(buffer& other) + { + this->_M_swap(other); + } + + /** + * @brief Reinterpret a %buffer as another data type. + * @param other %buffer to reinterpret. + * @return The new %buffer. + * + * Data is reinterpreted by standard C++ reinterpret_cast semantics. + * The size of the new %buffer is the floor of the size of @a other + * multiplied by the ratio sizeof(U)/sizeof(T). + */ + template + static buffer recast(const buffer& other) + { + // Use the base class' template method implementation, with this + // type as the first template parameter (the second is deduced from + // the argument). + return read_type::template _M_recast(other); + } + + protected: + /// @cond IMPL + + // Implementation of allocate. + template + static read_type _M_allocate(size_t size, const Alloc& allocator) + { + allocator_deleter deleter(size, allocator); + return read_type(deleter.allocate(size), size, deleter); + } + + /// @endcond + }; + +} // namespace redhawk + +#endif // REDHAWK_SHARED_BUFFER_H From daf73a3e1f11051ed4f5c25b84fa543ddb9a82e7 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 15 Apr 2016 12:52:00 -0400 Subject: [PATCH 0157/1644] Add copyright header --- .../src/base/include/ossie/shared_buffer.h | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/redhawk/src/base/include/ossie/shared_buffer.h b/redhawk/src/base/include/ossie/shared_buffer.h index db725561a..831271765 100644 --- a/redhawk/src/base/include/ossie/shared_buffer.h +++ b/redhawk/src/base/include/ossie/shared_buffer.h @@ -1,3 +1,23 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK core. + * + * REDHAWK core is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + #ifndef REDHAWK_SHARED_BUFFER_H #define REDHAWK_SHARED_BUFFER_H From 1005adaf3449172b2e0012a57680ab0fef8c17e5 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 15 Apr 2016 12:54:35 -0400 Subject: [PATCH 0158/1644] Add "transient" concept to shared buffer that allows passthrough of externally-acquired, non-deletable data. The receiver of a transient buffer must explicitly copy the buffer if they need a copy of it past the lifetime of the call. --- .../src/base/include/ossie/shared_buffer.h | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/redhawk/src/base/include/ossie/shared_buffer.h b/redhawk/src/base/include/ossie/shared_buffer.h index 831271765..4cb32b3cb 100644 --- a/redhawk/src/base/include/ossie/shared_buffer.h +++ b/redhawk/src/base/include/ossie/shared_buffer.h @@ -274,6 +274,35 @@ namespace redhawk { return _M_recast(other); } + /** + * @brief Returns a transient %read_buffer. + * @param data Pointer to first element. + * @param size Number of elements. + * + * Adapts externally aquired memory work with the read_buffer API; + * however, additional care must be taken to ensure that the data is + * copied if it needs to be held past the lifetime of the call. + */ + static read_buffer make_transient(const value_type* data, size_t size) + { + read_buffer result; + result._M_start = const_cast(data); + result._M_finish = result._M_start + size; + return result; + } + + /** + * @brief Returns true if the array's lifetime is not managed. + * + * Transient read_buffers do not own the underlying data. If the + * receiver of a transient buffer needs to hold on to it past the + * lifetime of the call, they must make a copy. + */ + bool transient() const + { + return !(this->_M_array); + } + protected: /// @cond IMPL From f30cfd490e314aaa312852de5c3622a3452a49ff Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 19 Apr 2016 12:26:37 -0400 Subject: [PATCH 0159/1644] Rename "read_buffer" to "shared_buffer" (this was the original name prior to a refactor) --- .../src/base/include/ossie/shared_buffer.h | 119 +++++++++--------- 1 file changed, 60 insertions(+), 59 deletions(-) diff --git a/redhawk/src/base/include/ossie/shared_buffer.h b/redhawk/src/base/include/ossie/shared_buffer.h index 4cb32b3cb..c36b0f74d 100644 --- a/redhawk/src/base/include/ossie/shared_buffer.h +++ b/redhawk/src/base/include/ossie/shared_buffer.h @@ -72,13 +72,13 @@ namespace redhawk { * @brief An immutable container that can share its data with other * instances. * - * The %read_buffer class provides read-only access to a sized array of + * The %shared_buffer class provides read-only access to a sized array of * elements that can be shared between many buffer instances. This enables * the transfer of ownership of data without explicit management of * references. * - * read_buffers have reference semantics. Assignment and copy construction - * do not copy any elements, only the data pointer. A %read_buffer never + * shared_buffers have reference semantics. Assignment and copy construction + * do not copy any elements, only the data pointer. A %shared_buffer never * peforms any memory allocation of its own, but can take ownership of an * existing array. When the last reference to the underlying data goes * away, the data is freed. @@ -86,29 +86,29 @@ namespace redhawk { * For write access and memory allocation, see buffer. */ template - class read_buffer { + class shared_buffer { public: /// @brief The element type (T). typedef T value_type; /** * @brief A random access iterator to const value_type. * - * Note that all access to %read_buffer is const. This means that + * Note that all access to %shared_buffer is const. This means that * %iterator and %const_iterator are equivalent. */ typedef const value_type* iterator; /** * @brief A random access iterator to const value_type. * - * Note that all access to %read_buffer is const. This means that + * Note that all access to %shared_buffer is const. This means that * %iterator and %const_iterator are equivalent. */ typedef iterator const_iterator; /** - * @brief Construct an empty %read_buffer. + * @brief Construct an empty %shared_buffer. */ - read_buffer() : + shared_buffer() : _M_array(), _M_start(0), _M_finish(0) @@ -116,15 +116,15 @@ namespace redhawk { } /** - * @brief Construct a %read_buffer with an existing pointer. + * @brief Construct a %shared_buffer with an existing pointer. * @param data Pointer to first element. * @param size Number of elements. * - * The newly-created %read_buffer takes ownership of @a data. When the - * last %read_buffer pointing to @a data is destroyed, @a data will be - * deleted with delete[]. + * The newly-created %shared_buffer takes ownership of @a data. When + * the last %shared_buffer pointing to @a data is destroyed, @a data + * will be deleted with delete[]. */ - read_buffer(value_type* data, size_t size) : + shared_buffer(value_type* data, size_t size) : _M_array(data), _M_start(data), _M_finish(data + size) @@ -132,18 +132,18 @@ namespace redhawk { } /** - * @brief Construct a %read_buffer with an existing pointer and a custom - * deleter. + * @brief Construct a %shared_buffer with an existing pointer and a + * custom deleter. * @param data Pointer to first element. * @param size Number of elements. * @param deleter Callable object. * - * @a D must by copy-constructible. When the last %read_buffer pointing - * to @a data is destroyed, @a deleter will be called on @a data. This - * can be used to define custom release behavior. + * @a D must by copy-constructible. When the last %shared_buffer + * pointing to @a data is destroyed, @a deleter will be called on + * @a data. This can be used to define custom release behavior. */ template - read_buffer(value_type* data, size_t size, D deleter) : + shared_buffer(value_type* data, size_t size, D deleter) : _M_array(data, deleter), _M_start(data), _M_finish(data + size) @@ -151,16 +151,16 @@ namespace redhawk { } /** - * The dtor releases the %read_buffer's shared data pointer. If no - * other %read_buffer points to the data, the data is released. + * The dtor releases the %shared_buffer's shared data pointer. If no + * other %shared_buffer points to the data, the data is released. */ - ~read_buffer() + ~shared_buffer() { } /** * Returns a read-only iterator that points to the first element in the - * %read_buffer. + * %shared_buffer. */ iterator begin() const { @@ -169,7 +169,7 @@ namespace redhawk { /** * Returns a read-only iterator that points one past the last element - * in the %read_buffer. + * in the %shared_buffer. */ iterator end() const { @@ -177,7 +177,7 @@ namespace redhawk { } /** - * @brief Subscript access to the data contained in the %read_buffer. + * @brief Subscript access to the data contained in the %shared_buffer. * @param index The index of the element to access * @return Read-only reference to element */ @@ -187,7 +187,7 @@ namespace redhawk { } /** - * Returns the number of elements in the %read_buffer. + * Returns the number of elements in the %shared_buffer. */ size_t size() const { @@ -195,7 +195,7 @@ namespace redhawk { } /** - * Returns true if the %read_buffer is empty. + * Returns true if the %shared_buffer is empty. */ bool empty() const { @@ -211,20 +211,20 @@ namespace redhawk { } /** - * @brief Returns a %read_buffer containing a subset of elements. + * @brief Returns a %shared_buffer containing a subset of elements. * @param start Index of first element. * @param end Index of last element, exclusive (default end). - * @return The new %read_buffer. + * @return The new %shared_buffer. */ - read_buffer slice(size_t start, size_t end=size_t(-1)) const + shared_buffer slice(size_t start, size_t end=size_t(-1)) const { - read_buffer result(*this); + shared_buffer result(*this); this->_M_slice(result, start, end); return result; } /** - * @brief Returns a copy of this %read_buffer. + * @brief Returns a copy of this %shared_buffer. * * The returned %buffer points to a newly-allocated array. */ @@ -236,7 +236,7 @@ namespace redhawk { } /** - * @brief Returns a copy of this %read_buffer. + * @brief Returns a copy of this %shared_buffer. * @param allocator An allocator object. * * The returned %buffer points to a new array allocated with @@ -251,41 +251,41 @@ namespace redhawk { } /** - * @brief Swap contents with another %read_buffer. - * @param other %read_buffer to swap with. + * @brief Swap contents with another %shared_buffer. + * @param other %shared_buffer to swap with. */ - void swap(read_buffer& other) + void swap(shared_buffer& other) { this->_M_swap(other); } /** - * @brief Reinterpret a read_buffer as another data type. - * @param other %read_buffer to reinterpret. - * @return The new %read_buffer. + * @brief Reinterpret a shared_buffer as another data type. + * @param other %shared_buffer to reinterpret. + * @return The new %shared_buffer. * * Data is reinterpreted by standard C++ reinterpret_cast semantics. - * The size of the new %read_buffer is the floor of the size of + * The size of the new %shared_buffer is the floor of the size of * @a other multiplied by the ratio sizeof(U)/sizeof(T). */ template - static read_buffer recast(const read_buffer& other) + static shared_buffer recast(const shared_buffer& other) { - return _M_recast(other); + return _M_recast(other); } /** - * @brief Returns a transient %read_buffer. + * @brief Returns a transient %shared_buffer. * @param data Pointer to first element. * @param size Number of elements. * - * Adapts externally aquired memory work with the read_buffer API; + * Adapts externally aquired memory work with the %shared_buffer API; * however, additional care must be taken to ensure that the data is * copied if it needs to be held past the lifetime of the call. */ - static read_buffer make_transient(const value_type* data, size_t size) + static shared_buffer make_transient(const value_type* data, size_t size) { - read_buffer result; + shared_buffer result; result._M_start = const_cast(data); result._M_finish = result._M_start + size; return result; @@ -294,7 +294,7 @@ namespace redhawk { /** * @brief Returns true if the array's lifetime is not managed. * - * Transient read_buffers do not own the underlying data. If the + * Transient shared_buffers do not own the underlying data. If the * receiver of a transient buffer needs to hold on to it past the * lifetime of the call, they must make a copy. */ @@ -326,16 +326,16 @@ namespace redhawk { } // Internal implementation of swap. - void _M_swap(read_buffer& other) + void _M_swap(shared_buffer& other) { this->_M_array.swap(other._M_array); std::swap(this->_M_start, other._M_start); std::swap(this->_M_finish, other._M_finish); } - // Adjusts the start and end pointers of a read_buffer to a the given + // Adjusts the start and end pointers of a shared_buffer to a the given // slice indices. - void _M_slice(read_buffer& result, size_t start, size_t end) const + void _M_slice(shared_buffer& result, size_t start, size_t end) const { if (end == (size_t)-1) { end = result.size(); @@ -346,7 +346,7 @@ namespace redhawk { // Internal implementation of copy. Copies the contents of this buffer // into another, pre-existing buffer. - void _M_copy(read_buffer& dest) const + void _M_copy(shared_buffer& dest) const { std::copy(this->begin(), this->end(), dest._M_begin()); } @@ -356,7 +356,7 @@ namespace redhawk { template static Tout _M_recast(const U& other) { - // Reinterpret the input class (which is some form of read_buffer + // Reinterpret the input class (which is some form of shared_buffer // or buffer) via a void pointer so that the compiler doesn't // object about strict aliasing rules, which shouldn't matter here. // The in-memory layout is always the same irrespective of the @@ -392,21 +392,22 @@ namespace redhawk { /** * @brief A shared container data type. * - * The %buffer class extends read_buffer to provides write access. Multiple - * buffers and read_buffers may point to the same underlying data. + * The %buffer class extends shared_buffer to provides write access. + * Multiple buffers and shared_buffers may point to the same underlying + * data. * * buffers have reference semantics. Assignment and copy construction do * not copy any elements, only the data pointer. * - * Unlike %read_buffer, %buffer has allocating constructors. When the + * Unlike %shared_buffer, %buffer has allocating constructors. When the * last reference to the underlying data goes away, the data is freed. */ template - class buffer : public read_buffer + class buffer : public shared_buffer { public: /// @brief The read-only buffer type. - typedef read_buffer read_type; + typedef shared_buffer read_type; /// @brief The element type (T). typedef T value_type; /// @brief A random access iterator to value_type. @@ -579,10 +580,10 @@ namespace redhawk { } /** - * @brief Returns a %read_buffer containing a subset of elements. + * @brief Returns a %shared_buffer containing a subset of elements. * @param start Index of first element. * @param end Index of last element, exclusive (default end). - * @return The new %read_buffer. + * @return The new %shared_buffer. */ read_type slice(size_t start, size_t end=size_t(-1)) const { From 4167e8f3753706fe3e7003c23317e45fa1312e80 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 22 Apr 2016 11:36:22 -0400 Subject: [PATCH 0160/1644] Add a get() method to PropertyMap that allows the caller to provide a default value for when the requested property is not found; relaxed the "explicit" requirement for constructing a Value from an arbitrary type so that the caller can pass any type that is convertible to a Value as the default value --- redhawk/src/base/framework/PropertyMap.cpp | 10 ++++++++++ redhawk/src/base/include/ossie/PropertyMap.h | 2 ++ redhawk/src/base/include/ossie/Value.h | 2 +- 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/redhawk/src/base/framework/PropertyMap.cpp b/redhawk/src/base/framework/PropertyMap.cpp index 09d71a373..85876e1c6 100644 --- a/redhawk/src/base/framework/PropertyMap.cpp +++ b/redhawk/src/base/framework/PropertyMap.cpp @@ -107,6 +107,16 @@ const Value& PropertyMap::operator[] (const std::string& id) const return dt->getValue(); } +const Value& PropertyMap::get(const std::string& id, const Value& def) const +{ + const_iterator dt = find(id); + if (dt != end()) { + return dt->getValue(); + } else { + return def; + } +} + void PropertyMap::push_back(const CF::DataType& property) { ossie::corba::push_back(*this, property); diff --git a/redhawk/src/base/include/ossie/PropertyMap.h b/redhawk/src/base/include/ossie/PropertyMap.h index 384bbdd66..cefbfa9c6 100644 --- a/redhawk/src/base/include/ossie/PropertyMap.h +++ b/redhawk/src/base/include/ossie/PropertyMap.h @@ -60,6 +60,8 @@ namespace redhawk { Value& operator[] (const std::string& id); const Value& operator[] (const std::string& id) const; + const Value& get(const std::string& id, const Value& def=Value()) const; + void push_back (const CF::DataType& dt); iterator begin(); diff --git a/redhawk/src/base/include/ossie/Value.h b/redhawk/src/base/include/ossie/Value.h index 74ad28ab0..aea050b60 100644 --- a/redhawk/src/base/include/ossie/Value.h +++ b/redhawk/src/base/include/ossie/Value.h @@ -37,7 +37,7 @@ namespace redhawk { Value(const Value& any); template - explicit Value(const T& value) + Value(const T& value) { setValue(value); } From 0c0c1ab969cbfa57c40fd5e455e9a8d4b274a5a1 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 22 Apr 2016 14:38:58 -0400 Subject: [PATCH 0161/1644] Add a new method to PropertySet_impl for setting command line property values, which will allow for subclasses to implement handling for special properties (such as "NIC" in Component) --- redhawk/src/base/framework/PropertySet_impl.cpp | 15 +++++++++++++++ redhawk/src/base/include/ossie/PropertySet_impl.h | 5 +++++ 2 files changed, 20 insertions(+) diff --git a/redhawk/src/base/framework/PropertySet_impl.cpp b/redhawk/src/base/framework/PropertySet_impl.cpp index e09585629..11e760f62 100644 --- a/redhawk/src/base/framework/PropertySet_impl.cpp +++ b/redhawk/src/base/framework/PropertySet_impl.cpp @@ -28,6 +28,7 @@ #include "ossie/concurrent.h" #include "ossie/Events.h" #include "ossie/ossieSupport.h" +#include "ossie/PropertyMap.h" // @@ -143,6 +144,20 @@ void PropertySet_impl::setExecparamProperties(std::map& exec LOG_TRACE(PropertySet_impl, "Done setting exec parameters"); } +void PropertySet_impl::setCommandLineProperty(const std::string& id, const redhawk::Value& value) +{ + LOG_TRACE(PropertySet_impl, "Property: " << id << " = " << value.toString()); + PropertyInterface* property = getPropertyFromId(id); + // the property can belong to a resource, device, or Device/Domain + // Manager. If the property is not found, then it might be a resource + // property passed through the nodeBooter to the DeviceManager + if (property) { + property->setValue(value, false); + } else { + LOG_WARN(PropertySet_impl, "Property: " << id << " is not defined, ignoring it!!"); + } +} + void PropertySet_impl::initializeProperties(const CF::Properties& ctorProps) throw (CF::PropertyEmitter::AlreadyInitialized, CF::PropertySet::PartialConfiguration, diff --git a/redhawk/src/base/include/ossie/PropertySet_impl.h b/redhawk/src/base/include/ossie/PropertySet_impl.h index dc9f26754..27cee47cb 100644 --- a/redhawk/src/base/include/ossie/PropertySet_impl.h +++ b/redhawk/src/base/include/ossie/PropertySet_impl.h @@ -35,6 +35,9 @@ #include "ossie/Autocomplete.h" #include "CF/cf.h" +namespace redhawk { + class Value; +} class PropertySet_impl #ifdef BEGIN_AUTOCOMPLETE_IGNORE @@ -91,6 +94,8 @@ class PropertySet_impl protected: + virtual void setCommandLineProperty(const std::string& id, const redhawk::Value& value); + /*CF::Properties propertySet;*/ CF::DataType From 0fabe9e040601cf10fad5e5a0fa6a9fc3c2f581b Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 22 Apr 2016 14:47:21 -0400 Subject: [PATCH 0162/1644] Use scoped pointers to manage domain awareness structures --- redhawk/src/base/framework/Component.cpp | 41 +++++++++++-------- redhawk/src/base/framework/Resource_impl.cpp | 28 ++++++------- redhawk/src/base/include/ossie/Component.h | 15 +++---- .../src/base/include/ossie/Resource_impl.h | 6 +-- 4 files changed, 47 insertions(+), 43 deletions(-) diff --git a/redhawk/src/base/framework/Component.cpp b/redhawk/src/base/framework/Component.cpp index 4189e1bd8..39fcb4812 100644 --- a/redhawk/src/base/framework/Component.cpp +++ b/redhawk/src/base/framework/Component.cpp @@ -19,34 +19,43 @@ */ #include "ossie/Component.h" -Component::Component(const char* _uuid) : Resource_impl (_uuid) { - this->_app = NULL; - this->_net = NULL; +Component::Component(const char* _uuid) : + Resource_impl(_uuid), + _app(new redhawk::ApplicationContainer()), + _net(new redhawk::NetworkContainer()) +{ } -Component::Component(const char* _uuid, const char *label) : Resource_impl (_uuid, label) { - this->_app = NULL; - this->_net = NULL; +Component::Component(const char* _uuid, const char *label) : + Resource_impl(_uuid, label), + _app(new redhawk::ApplicationContainer()), + _net(new redhawk::NetworkContainer()) +{ } -Component::~Component() { - if (this->_app != NULL) - delete this->_app; - if (this->_net != NULL) - delete this->_net; +Component::~Component() +{ } void Component::setAdditionalParameters(std::string &softwareProfile, std::string &application_registrar_ior, std::string &nic) { CORBA::ORB_ptr orb = ossie::corba::Orb(); Resource_impl::setAdditionalParameters(softwareProfile, application_registrar_ior, nic); - this->_net = new redhawk::NetworkContainer(nic); + this->_net.reset(new redhawk::NetworkContainer(nic)); CORBA::Object_var applicationRegistrarObject = orb->string_to_object(application_registrar_ior.c_str()); CF::ApplicationRegistrar_var applicationRegistrar = ossie::corba::_narrowSafe(applicationRegistrarObject); if (!CORBA::is_nil(applicationRegistrar)) { - CF::Application_var app = applicationRegistrar->app(); - this->_app = new redhawk::ApplicationContainer(app); - return; + CF::Application_var app = applicationRegistrar->app(); + this->_app.reset(new redhawk::ApplicationContainer(app)); } - this->_app = new redhawk::ApplicationContainer(); +} + +redhawk::ApplicationContainer* Component::getApplication() +{ + return _app.get(); +} + +redhawk::NetworkContainer* Component::getNetwork() +{ + return _net.get(); } diff --git a/redhawk/src/base/framework/Resource_impl.cpp b/redhawk/src/base/framework/Resource_impl.cpp index 741108d9b..7df5a4b84 100644 --- a/redhawk/src/base/framework/Resource_impl.cpp +++ b/redhawk/src/base/framework/Resource_impl.cpp @@ -30,7 +30,7 @@ Resource_impl::Resource_impl (const char* _uuid) : _started(false), component_running_mutex(), component_running(&component_running_mutex), - _domMgr(NULL), + _domMgr(new redhawk::DomainManagerContainer()), _initialized(false) { } @@ -42,21 +42,17 @@ Resource_impl::Resource_impl (const char* _uuid, const char *label) : _started(false), component_running_mutex(), component_running(&component_running_mutex), - _domMgr(NULL), + _domMgr(new redhawk::DomainManagerContainer()), _initialized(false) { } -Resource_impl::~Resource_impl () { - if (this->_domMgr != NULL) - delete this->_domMgr; - - -}; - +Resource_impl::~Resource_impl () +{ +} -void Resource_impl::setAdditionalParameters(std::string &softwareProfile, std::string &application_registrar_ior, std::string &nic) +void Resource_impl::setAdditionalParameters(std::string& softwareProfile, std::string &application_registrar_ior, std::string &nic) { _softwareProfile = softwareProfile; CORBA::ORB_ptr orb = ossie::corba::Orb(); @@ -66,14 +62,14 @@ void Resource_impl::setAdditionalParameters(std::string &softwareProfile, std::s applicationRegistrarObject = orb->string_to_object(application_registrar_ior.c_str()); } catch ( ... ) { RH_NL_WARN("Resource", "No Registrar... create empty container"); - this->_domMgr = new redhawk::DomainManagerContainer(); + this->_domMgr.reset(new redhawk::DomainManagerContainer()); return; } CF::ApplicationRegistrar_ptr applicationRegistrar = ossie::corba::_narrowSafe(applicationRegistrarObject); if (!CORBA::is_nil(applicationRegistrar)) { RH_NL_TRACE("Resource", "Get DomainManager from Registrar object:" << application_registrar_ior ); CF::DomainManager_var dm=applicationRegistrar->domMgr(); - this->_domMgr = new redhawk::DomainManagerContainer(dm); + this->_domMgr.reset(new redhawk::DomainManagerContainer(dm)); return; } @@ -82,14 +78,18 @@ void Resource_impl::setAdditionalParameters(std::string &softwareProfile, std::s if (!CORBA::is_nil(devMgr)) { RH_NL_TRACE("Resource", "Resolving DomainManager from DeviceManager..."); CF::DomainManager_var dm=devMgr->domMgr(); - this->_domMgr = new redhawk::DomainManagerContainer(dm); + this->_domMgr.reset(new redhawk::DomainManagerContainer(dm)); return; } RH_NL_DEBUG("Resource", "All else failed.... use empty container"); - this->_domMgr = new redhawk::DomainManagerContainer(); + this->_domMgr.reset(new redhawk::DomainManagerContainer()); } +redhawk::DomainManagerContainer* Resource_impl::getDomainManager() +{ + return _domMgr.get(); +} void Resource_impl::constructor () { diff --git a/redhawk/src/base/include/ossie/Component.h b/redhawk/src/base/include/ossie/Component.h index 54f3f8398..da11ce707 100644 --- a/redhawk/src/base/include/ossie/Component.h +++ b/redhawk/src/base/include/ossie/Component.h @@ -34,19 +34,16 @@ class Component : public Resource_impl { /* * Return a pointer to the Application that the Resource is deployed on */ - redhawk::ApplicationContainer* getApplication() { - return this->_app; - } + redhawk::ApplicationContainer* getApplication(); + /* * Return the network information that was allocated to this Component (if applicable) */ - redhawk::NetworkContainer* getNetwork() { - return this->_net; - } -private: - redhawk::ApplicationContainer *_app; - redhawk::NetworkContainer *_net; + redhawk::NetworkContainer* getNetwork(); +private: + boost::scoped_ptr _app; + boost::scoped_ptr _net; }; #endif /* COMPONENT_H */ diff --git a/redhawk/src/base/include/ossie/Resource_impl.h b/redhawk/src/base/include/ossie/Resource_impl.h index c1d3a692d..e1be68f92 100644 --- a/redhawk/src/base/include/ossie/Resource_impl.h +++ b/redhawk/src/base/include/ossie/Resource_impl.h @@ -89,9 +89,7 @@ class Resource_impl: /* * Return a pointer to the Domain Manager that the Resource is deployed on */ - redhawk::DomainManagerContainer* getDomainManager() { - return this->_domMgr; - } + redhawk::DomainManagerContainer* getDomainManager(); /* * Globally unique identifier for this Resource @@ -135,7 +133,7 @@ class Resource_impl: typedef boost::function ctor_type; static void start_component(ctor_type ctor, int argc, char* argv[]); std::string currentWorkingDirectory; - redhawk::DomainManagerContainer *_domMgr; + boost::scoped_ptr _domMgr; bool _initialized; }; #endif From faf60eac16b790b5f0b7f8509ab2667b6091a7e8 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 22 Apr 2016 15:05:21 -0400 Subject: [PATCH 0163/1644] Refactor start_component to support creating components in the same process space as the caller; some of the special command line property handling (e.g., "NIC") is now managed by overriding setCommandLineProperty --- redhawk/src/base/framework/Component.cpp | 14 + redhawk/src/base/framework/Resource_impl.cpp | 269 ++++++++++-------- redhawk/src/base/include/ossie/Component.h | 8 + .../src/base/include/ossie/Resource_impl.h | 7 + 4 files changed, 179 insertions(+), 119 deletions(-) diff --git a/redhawk/src/base/framework/Component.cpp b/redhawk/src/base/framework/Component.cpp index 39fcb4812..140322779 100644 --- a/redhawk/src/base/framework/Component.cpp +++ b/redhawk/src/base/framework/Component.cpp @@ -59,3 +59,17 @@ redhawk::NetworkContainer* Component::getNetwork() { return _net.get(); } + +void Component::setCommandLineProperty(const std::string& id, const redhawk::Value& value) +{ + if (id == "NIC") { + _net.reset(new redhawk::NetworkContainer(value.toString())); + } else { + Resource_impl::setCommandLineProperty(id, value); + } +} + +void Component::setApplication(CF::Application_ptr application) +{ + _app.reset(new redhawk::ApplicationContainer(application)); +} diff --git a/redhawk/src/base/framework/Resource_impl.cpp b/redhawk/src/base/framework/Resource_impl.cpp index 7df5a4b84..93525b6ad 100644 --- a/redhawk/src/base/framework/Resource_impl.cpp +++ b/redhawk/src/base/framework/Resource_impl.cpp @@ -22,6 +22,7 @@ #include "ossie/Resource_impl.h" #include "ossie/Events.h" +#include "ossie/Component.h" PREPARE_CF_LOGGING(Resource_impl) @@ -62,14 +63,14 @@ void Resource_impl::setAdditionalParameters(std::string& softwareProfile, std::s applicationRegistrarObject = orb->string_to_object(application_registrar_ior.c_str()); } catch ( ... ) { RH_NL_WARN("Resource", "No Registrar... create empty container"); - this->_domMgr.reset(new redhawk::DomainManagerContainer()); + setDomainManager(CF::DomainManager::_nil()); return; } CF::ApplicationRegistrar_ptr applicationRegistrar = ossie::corba::_narrowSafe(applicationRegistrarObject); if (!CORBA::is_nil(applicationRegistrar)) { RH_NL_TRACE("Resource", "Get DomainManager from Registrar object:" << application_registrar_ior ); CF::DomainManager_var dm=applicationRegistrar->domMgr(); - this->_domMgr.reset(new redhawk::DomainManagerContainer(dm)); + setDomainManager(dm); return; } @@ -78,12 +79,12 @@ void Resource_impl::setAdditionalParameters(std::string& softwareProfile, std::s if (!CORBA::is_nil(devMgr)) { RH_NL_TRACE("Resource", "Resolving DomainManager from DeviceManager..."); CF::DomainManager_var dm=devMgr->domMgr(); - this->_domMgr.reset(new redhawk::DomainManagerContainer(dm)); + setDomainManager(dm); return; } RH_NL_DEBUG("Resource", "All else failed.... use empty container"); - this->_domMgr.reset(new redhawk::DomainManagerContainer()); + setDomainManager(CF::DomainManager::_nil()); } redhawk::DomainManagerContainer* Resource_impl::getDomainManager() @@ -91,6 +92,11 @@ redhawk::DomainManagerContainer* Resource_impl::getDomainManager() return _domMgr.get(); } +void Resource_impl::setDomainManager(CF::DomainManager_ptr domainManager) +{ + _domMgr.reset(new redhawk::DomainManagerContainer(domainManager)); +} + void Resource_impl::constructor () { } @@ -178,6 +184,81 @@ std::string& Resource_impl::getCurrentWorkingDirectory() { return this->currentWorkingDirectory; } +void Resource_impl::setCommandLineProperty(const std::string& id, const redhawk::Value& value) +{ + if (id == "PROFILE_NAME") { + _softwareProfile = value.toString(); + } else { + PropertySet_impl::setCommandLineProperty(id, value); + } +} + +Resource_impl* Resource_impl::create_component(Resource_impl::ctor_type ctor, const CF::Properties& properties) +{ + const redhawk::PropertyMap& parameters = redhawk::PropertyMap::cast(properties); + + std::string identifier; + std::string name_binding; + std::string application_registrar_ior; + redhawk::PropertyMap cmdlineProps; + for (redhawk::PropertyMap::const_iterator prop = parameters.begin(); prop != parameters.end(); ++prop) { + const std::string id = prop->getId(); + if (id == "COMPONENT_IDENTIFIER") { + identifier = prop->getValue().toString(); + } else if (id == "NAME_BINDING") { + name_binding = prop->getValue().toString(); + } else if (id == "NAMING_CONTEXT_IOR") { + application_registrar_ior = prop->getValue().toString(); + } else { + cmdlineProps.push_back(*prop); + } + } + + LOG_TRACE(Resource_impl, "Creating component with identifier '" << identifier << "'"); + Resource_impl* resource = ctor(identifier, name_binding); + + // Initialize command line properties, which can include special properties + // like PROFILE_NAME. + for (redhawk::PropertyMap::const_iterator prop = cmdlineProps.begin(); prop != cmdlineProps.end(); ++prop) { + resource->setCommandLineProperty(prop->getId(), prop->getValue()); + } + + // Activate the component servant. + LOG_TRACE(Resource_impl, "Activating component object"); + PortableServer::ObjectId_var oid = ossie::corba::RootPOA()->activate_object(resource); + CF::Resource_var resource_obj = resource->_this(); + + // Get the application naming context and bind the component into it. + if (!application_registrar_ior.empty()) { + CORBA::Object_var applicationRegistrarObject = ossie::corba::stringToObject(application_registrar_ior); + CF::ApplicationRegistrar_var applicationRegistrar = ossie::corba::_narrowSafe(applicationRegistrarObject); + if (!CORBA::is_nil(applicationRegistrar)) { + LOG_TRACE(Resource_impl, "Registering with application using name '" << name_binding << "'"); + // Register with the application + applicationRegistrar->registerComponent(name_binding.c_str(), resource_obj); + + // Set up the DomainManager container + CF::DomainManager_var domainManager = applicationRegistrar->domMgr(); + resource->setDomainManager(domainManager); + + // If it inherits from the Component class, set up the Application + // container as well + Component* component = dynamic_cast(resource); + if (component) { + CF::Application_var application = applicationRegistrar->app(); + component->setApplication(application); + } + } else { + LOG_TRACE(Resource_impl, "Binding component to naming context with name '" << name_binding << "'"); + // the registrar is not available (because the invoking infrastructure only uses the name service) + CosNaming::NamingContext_var applicationContext = ossie::corba::_narrowSafe(applicationRegistrarObject); + ossie::corba::bindObjectToContext(resource_obj, applicationContext, name_binding); + } + } + + return resource; +} + static Resource_impl* main_component = 0; static void sigint_handler(int signum) { @@ -186,74 +267,52 @@ static void sigint_handler(int signum) void Resource_impl::start_component(Resource_impl::ctor_type ctor, int argc, char* argv[]) { - std::string application_registrar_ior; - std::string component_identifier; - std::string name_binding; - std::string profile = ""; - std::string nic = ""; - const char* logging_config_uri = 0; int debug_level = -1; // use log config uri as log level context - bool standAlone = false; - std::map execparams; - std::string logcfg_uri(""); + std::string logcfg_uri; std::string dpath(""); bool skip_run = false; - // Parse execparams. - for (int i=0; i < argc; i++) { - if (strcmp("NAMING_CONTEXT_IOR", argv[i]) == 0) { - application_registrar_ior = argv[++i]; - } else if (strcmp("NIC", argv[i]) == 0) { - nic = argv[++i]; - } else if (strcmp("PROFILE_NAME", argv[i]) == 0) { - profile = argv[++i]; - } else if (strcmp("COMPONENT_IDENTIFIER", argv[i]) == 0) { - component_identifier = argv[++i]; - } else if (strcmp("NAME_BINDING", argv[i]) == 0) { - name_binding = argv[++i]; - } else if (strcmp("LOGGING_CONFIG_URI", argv[i]) == 0) { - logging_config_uri = argv[++i]; - } else if (strcmp("DEBUG_LEVEL", argv[i]) == 0) { - debug_level = atoi(argv[++i]); - } else if (strcmp("DOM_PATH", argv[i]) == 0) { - dpath = argv[++i]; - } else if (strcmp("-i", argv[i]) == 0) { - standAlone = true; - } else if (strcmp("SKIP_RUN", argv[i]) == 0) { + // The ORB must be initialized before anything that might depend on CORBA, + // such as PropertyMap and logging configuration + ossie::corba::CorbaInit(argc, argv); + + redhawk::PropertyMap cmdlineProps; + + // Parse command line arguments. + for (int i = 1; i < argc; i++) { + if (strcmp("SKIP_RUN", argv[i]) == 0) { skip_run = true; - } else if (i > 0) { // any other argument besides the first one is part of the execparams - std::string paramName = argv[i]; - execparams[paramName] = argv[++i]; + } else { + const std::string name = argv[i++]; + std::string value; + if (i < argc) { + value = argv[i]; + } else { + std::cerr << "No value given for " << name << std::endl; + } + if (name == "LOGGING_CONFIG_URI") { + logcfg_uri = value; + } else if (name == "DEBUG_LEVEL") { + debug_level = atoi(value.c_str()); + } else if (name == "DOM_PATH") { + dpath = value; + } else { // any other argument is part of the cmdlineProps + cmdlineProps[name] = value; + } } } - if (standAlone) { - if (component_identifier.empty()) { - component_identifier = ossie::generateUUID(); - } - if (name_binding.empty()) { - name_binding = ""; - } - } else { - if (application_registrar_ior.empty()) { - std::cout<setAdditionalParameters(profile, application_registrar_ior, nic); + Resource_impl* resource = create_component(ctor, cmdlineProps); if ( !skip_run ) { // assign the logging context to the resource to support logging interface resource->saveLoggingContext( logcfg_uri, debug_level, ctx ); } - // setting all the execparams passed as argument, this method resides in the Resource_impl class - resource->setExecparamProperties(execparams); - std::string pathAndFile = argv[0]; unsigned lastSlash = pathAndFile.find_last_of("/"); std::string cwd = pathAndFile.substr(0, lastSlash); resource->setCurrentWorkingDirectory(cwd); - // Activate the component servant. - LOG_TRACE(Resource_impl, "Activating component object"); - PortableServer::ObjectId_var oid = ossie::corba::RootPOA()->activate_object(resource); - CF::Resource_var resource_obj = resource->_this(); - - // Get the application naming context and bind the component into it. - if (!application_registrar_ior.empty()) { - LOG_TRACE(Resource_impl, "Binding component to application context with name '" << name_binding << "'"); - CORBA::Object_var applicationRegistrarObject = orb->string_to_object(application_registrar_ior.c_str()); - CF::ApplicationRegistrar_var applicationRegistrar = ossie::corba::_narrowSafe(applicationRegistrarObject); - if (!CORBA::is_nil(applicationRegistrar)) { - applicationRegistrar->registerComponent(name_binding.c_str(), resource_obj); - } else { - // the registrar is not available (because the invoking infrastructure only uses the name service) - CosNaming::NamingContext_var applicationContext = ossie::corba::_narrowSafe(applicationRegistrarObject); - ossie::corba::bindObjectToContext(resource_obj, applicationContext, name_binding); - } - } else { - if (standAlone) { - std::cout<object_to_string(resource_obj)<run(); - LOG_TRACE(Resource_impl, "Component run loop terminated"); - - // Ignore SIGINT from here on out to ensure that the ORB gets shut down - // properly - sa.sa_handler = SIG_IGN; - sigemptyset(&sa.sa_mask); - sigaction(SIGINT, &sa, NULL); - main_component = 0; - - LOG_TRACE(Resource_impl, "Deleting component"); - resource->_remove_ref(); - LOG_TRACE(Resource_impl, "Shutting down ORB"); - - ossie::logging::Terminate(); - - ossie::corba::OrbShutdown(true); - } + // Store away a reference to the main component and establish a handler for + // SIGINT that will break out of run() + main_component = resource; + struct sigaction sa; + sa.sa_handler = &sigint_handler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + sigaction(SIGINT, &sa, NULL); + + LOG_TRACE(Resource_impl, "Entering component run loop"); + resource->run(); + LOG_TRACE(Resource_impl, "Component run loop terminated"); + + // Ignore SIGINT from here on out to ensure that the ORB gets shut down + // properly + sa.sa_handler = SIG_IGN; + sigemptyset(&sa.sa_mask); + sigaction(SIGINT, &sa, NULL); + main_component = 0; + + LOG_TRACE(Resource_impl, "Deleting component"); + resource->_remove_ref(); + LOG_TRACE(Resource_impl, "Shutting down ORB"); + + ossie::logging::Terminate(); + + ossie::corba::OrbShutdown(true); } diff --git a/redhawk/src/base/include/ossie/Component.h b/redhawk/src/base/include/ossie/Component.h index da11ce707..955331637 100644 --- a/redhawk/src/base/include/ossie/Component.h +++ b/redhawk/src/base/include/ossie/Component.h @@ -41,6 +41,14 @@ class Component : public Resource_impl { */ redhawk::NetworkContainer* getNetwork(); +protected: + virtual void setCommandLineProperty(const std::string& id, const redhawk::Value& value); + + void setApplication(CF::Application_ptr application); + + // Give Resource_impl friend access so it can call setApplication + friend class Resource_impl; + private: boost::scoped_ptr _app; boost::scoped_ptr _net; diff --git a/redhawk/src/base/include/ossie/Resource_impl.h b/redhawk/src/base/include/ossie/Resource_impl.h index e1be68f92..4de78079d 100644 --- a/redhawk/src/base/include/ossie/Resource_impl.h +++ b/redhawk/src/base/include/ossie/Resource_impl.h @@ -102,6 +102,9 @@ class Resource_impl: std::string _parent_id; protected: + virtual void setCommandLineProperty(const std::string& id, const redhawk::Value& value); + + void setDomainManager(CF::DomainManager_ptr domainManager); /* * Boolean describing whether or not this Resource is started @@ -135,5 +138,9 @@ class Resource_impl: std::string currentWorkingDirectory; boost::scoped_ptr _domMgr; bool _initialized; + +public: + static Resource_impl* create_component(ctor_type, const CF::Properties& paramaters); + }; #endif From cd1d8e5a73e6c51287f9f5b77b527e238d3053d6 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 22 Apr 2016 15:15:05 -0400 Subject: [PATCH 0164/1644] Don't need to call Resource_impl::setAdditionalParameters from within Device version --- redhawk/src/base/framework/Device_impl.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/redhawk/src/base/framework/Device_impl.cpp b/redhawk/src/base/framework/Device_impl.cpp index b19bc15ba..3ffd3262c 100644 --- a/redhawk/src/base/framework/Device_impl.cpp +++ b/redhawk/src/base/framework/Device_impl.cpp @@ -179,10 +179,6 @@ void Device_impl::setAdditionalParameters ( std::string &profile, std::string ®istrar_ior, const std::string &nic ) { - // set parent's domain context - std::string tnic(nic); - Resource_impl::setAdditionalParameters(profile,registrar_ior, tnic); - _devMgr_ior = registrar_ior; _deviceManager = CF::DeviceManager::_nil(); CORBA::Object_var obj = ossie::corba::Orb()->string_to_object(_devMgr_ior.c_str()); @@ -197,6 +193,10 @@ void Device_impl::setAdditionalParameters ( std::string &profile, } this->_devMgr = new redhawk::DeviceManagerContainer(_deviceManager); + + // Set up domain awareness + CF::DomainManager_var domainManager = _deviceManager->domMgr(); + setDomainManager(domainManager); } From a30c39657ec281b33b18ab7ff715448f2da93e99 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 2 May 2016 14:07:40 -0400 Subject: [PATCH 0165/1644] Add C++ notification API for Resource release --- redhawk/src/base/framework/Resource_impl.cpp | 2 ++ .../src/base/include/ossie/Resource_impl.h | 22 ++++++++++++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/redhawk/src/base/framework/Resource_impl.cpp b/redhawk/src/base/framework/Resource_impl.cpp index 93525b6ad..8cd00656f 100644 --- a/redhawk/src/base/framework/Resource_impl.cpp +++ b/redhawk/src/base/framework/Resource_impl.cpp @@ -159,6 +159,8 @@ void Resource_impl::releaseObject() throw (CORBA::SystemException, CF::LifeCycle root_poa->deactivate_object(oid); component_running.signal(); + + _resourceReleased(this); } void Resource_impl::run() { diff --git a/redhawk/src/base/include/ossie/Resource_impl.h b/redhawk/src/base/include/ossie/Resource_impl.h index 4de78079d..e48c0d589 100644 --- a/redhawk/src/base/include/ossie/Resource_impl.h +++ b/redhawk/src/base/include/ossie/Resource_impl.h @@ -91,6 +91,24 @@ class Resource_impl: */ redhawk::DomainManagerContainer* getDomainManager(); + /* + * Register a function for notification when this Resource is released + */ + template + void addReleaseListener(Func func) + { + _resourceReleased.add(func); + } + + /* + * Register a member function for notification when this Resource is released + */ + template + void addReleaseListener(Target target, Func func) + { + _resourceReleased.add(target, func); + } + /* * Globally unique identifier for this Resource */ @@ -139,8 +157,10 @@ class Resource_impl: boost::scoped_ptr _domMgr; bool _initialized; + ossie::notification _resourceReleased; + public: - static Resource_impl* create_component(ctor_type, const CF::Properties& paramaters); + static Resource_impl* create_component(ctor_type, const CF::Properties& parameters); }; #endif From 83dcd7b2f87019e645c6ebb82500583392cf798f Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 3 May 2016 09:47:58 -0400 Subject: [PATCH 0166/1644] Add a getter for resource's identifer as a string --- redhawk/src/base/framework/Resource_impl.cpp | 5 +++++ redhawk/src/base/include/ossie/Resource_impl.h | 2 ++ 2 files changed, 7 insertions(+) diff --git a/redhawk/src/base/framework/Resource_impl.cpp b/redhawk/src/base/framework/Resource_impl.cpp index 8cd00656f..47d54959c 100644 --- a/redhawk/src/base/framework/Resource_impl.cpp +++ b/redhawk/src/base/framework/Resource_impl.cpp @@ -178,6 +178,11 @@ void Resource_impl::halt() { LOG_TRACE(Resource_impl, "Done sending device running signal"); } +const std::string& Resource_impl::getIdentifier() const +{ + return _identifier; +} + void Resource_impl::setCurrentWorkingDirectory(std::string& cwd) { this->currentWorkingDirectory = cwd; } diff --git a/redhawk/src/base/include/ossie/Resource_impl.h b/redhawk/src/base/include/ossie/Resource_impl.h index e48c0d589..c34af5c6d 100644 --- a/redhawk/src/base/include/ossie/Resource_impl.h +++ b/redhawk/src/base/include/ossie/Resource_impl.h @@ -109,6 +109,8 @@ class Resource_impl: _resourceReleased.add(target, func); } + const std::string& getIdentifier() const; + /* * Globally unique identifier for this Resource */ From f3bb9d905fac922b2a5e6982a44bb82457e40c59 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 3 May 2016 15:15:17 -0400 Subject: [PATCH 0167/1644] Move event manager termination to start_component() instead of releaseObject(), so that it only happens once in the case of components within a container --- redhawk/src/base/framework/Resource_impl.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/redhawk/src/base/framework/Resource_impl.cpp b/redhawk/src/base/framework/Resource_impl.cpp index 47d54959c..bf862a8be 100644 --- a/redhawk/src/base/framework/Resource_impl.cpp +++ b/redhawk/src/base/framework/Resource_impl.cpp @@ -153,7 +153,6 @@ void Resource_impl::releaseObject() throw (CORBA::SystemException, CF::LifeCycle { releasePorts(); stopPropertyChangeMonitor(); - redhawk::events::Manager::Terminate(); PortableServer::POA_ptr root_poa = ossie::corba::RootPOA(); PortableServer::ObjectId_var oid = root_poa->servant_to_id(this); root_poa->deactivate_object(oid); @@ -357,6 +356,8 @@ void Resource_impl::start_component(Resource_impl::ctor_type ctor, int argc, cha resource->run(); LOG_TRACE(Resource_impl, "Component run loop terminated"); + redhawk::events::Manager::Terminate(); + // Ignore SIGINT from here on out to ensure that the ORB gets shut down // properly sa.sa_handler = SIG_IGN; From 39d8551bf9c559930a12fc07ee30c40f0c366652 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 17 May 2016 14:00:51 -0400 Subject: [PATCH 0168/1644] Add ExecutorService, originally from BurstIO --- .../src/base/include/ossie/ExecutorService.h | 169 ++++++++++++++++++ redhawk/src/base/include/ossie/Makefile.am | 3 +- 2 files changed, 171 insertions(+), 1 deletion(-) create mode 100644 redhawk/src/base/include/ossie/ExecutorService.h diff --git a/redhawk/src/base/include/ossie/ExecutorService.h b/redhawk/src/base/include/ossie/ExecutorService.h new file mode 100644 index 000000000..cb11e81c9 --- /dev/null +++ b/redhawk/src/base/include/ossie/ExecutorService.h @@ -0,0 +1,169 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK core. + * + * REDHAWK core is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ +#ifndef REDHAWK_EXECUTORSERVICE_H +#define REDHAWK_EXECUTORSERVICE_H + +#include + +#include +#include +#include + +namespace redhawk { + + class ExecutorService { + public: + ExecutorService() : + thread_(0), + running_(false) + { + } + + void start () + { + boost::mutex::scoped_lock lock(mutex_); + if (running_) { + return; + } + + running_ = true; + thread_ = new boost::thread(&ExecutorService::run, this); + } + + void stop () + { + boost::thread* old_thread = 0; + { + boost::mutex::scoped_lock lock(mutex_); + running_ = false; + old_thread = thread_; + thread_ = 0; + cond_.notify_all(); + } + if (old_thread) { + old_thread->join(); + delete old_thread; + } + } + + template + void execute (F func) + { + insert_sorted(func); + } + + template + void execute (F func, A1 arg1) + { + insert_sorted(boost::bind(func, arg1)); + } + + template + void execute (F func, A1 arg1, A2 arg2) + { + insert_sorted(boost::bind(func, arg1, arg2)); + } + + template + void schedule (boost::system_time when, F func) + { + insert_sorted(func, when); + } + + template + void schedule (boost::system_time when, F func, A1 arg1) + { + insert_sorted(boost::bind(func, arg1), when); + } + + template + void schedule (boost::system_time when, F func, A1 arg1, A2 arg2) + { + insert_sorted(boost::bind(func, arg1, arg2), when); + } + + void clear () + { + boost::mutex::scoped_lock lock(mutex_); + queue_.clear(); + cond_.notify_all(); + } + + private: + typedef boost::function func_type; + typedef std::pair task_type; + typedef std::list task_queue; + + void run () + { + boost::mutex::scoped_lock lock(mutex_); + while (running_) { + while (!queue_.empty()) { + // Start at the front of the queue every time--a task may + // have been added while the lock was released to service + // the last task + task_queue::iterator task = queue_.begin(); + if (task->first > boost::get_system_time()) { + // Head of queue is scheduled in the future + break; + } + + // Copy the task's function and remove it from the queue + func_type func = task->second; + queue_.erase(task); + + // Run task with the lock released + lock.unlock(); + func(); + lock.lock(); + } + + if (queue_.empty()) { + cond_.wait(lock); + } else { + boost::system_time when = queue_.front().first; + cond_.timed_wait(lock, when); + } + } + } + + void insert_sorted (func_type func, boost::system_time when=boost::get_system_time()) + { + boost::mutex::scoped_lock lock(mutex_); + task_queue::iterator pos = queue_.begin(); + while ((pos != queue_.end()) && (when > pos->first)) { + ++pos; + } + queue_.insert(pos, std::make_pair(when, func)); + cond_.notify_all(); + } + + + boost::mutex mutex_; + boost::condition_variable cond_; + + boost::thread* thread_; + task_queue queue_; + bool running_; + }; + +} + +#endif // REDHAWK_EXECUTORSERVICE_H diff --git a/redhawk/src/base/include/ossie/Makefile.am b/redhawk/src/base/include/ossie/Makefile.am index c659300ad..3da135258 100644 --- a/redhawk/src/base/include/ossie/Makefile.am +++ b/redhawk/src/base/include/ossie/Makefile.am @@ -61,7 +61,8 @@ pkginclude_HEADERS = AggregateDevice_impl.h \ OptionalProperty.h \ PropertyMonitor.h \ Autocomplete.h \ - shared_buffer.h + shared_buffer.h \ + ExecutorService.h nobase_pkginclude_HEADERS = internal/equals.h \ logging/rh_logger.h \ From a4ed687e1f826145afc4ac59f1cff73088f9f940 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 6 May 2016 16:02:53 -0400 Subject: [PATCH 0169/1644] Start refactoring ApplicationFactory to work in terms of deployment objects that encapsulate the softpkg, implementation and dependencies --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 37 ++++++++++-------- .../sdr/dommgr/ApplicationFactory_impl.h | 10 +++-- .../control/sdr/dommgr/applicationSupport.cpp | 38 ++++++++++++++++--- .../control/sdr/dommgr/applicationSupport.h | 29 +++++++++++++- 4 files changed, 88 insertions(+), 26 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 6b0ecba6d..a67265254 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -694,7 +694,8 @@ void createHelper::assignRemainingComponentsToDevices(const std::string &appIden componentIter++) { if (!(*componentIter)->isAssignedToDevice()) { - allocateComponent(*componentIter, std::string(), _appUsedDevs, appIdentifier); + ossie::ComponentDeployment* deployment = allocateComponent(*componentIter, std::string(), _appUsedDevs, appIdentifier); + _deployments.push_back(deployment); } } } @@ -720,7 +721,8 @@ void createHelper::_assignComponentsUsingDAS(const DeviceAssignmentMap& deviceAs badDAS[0].assignedDeviceId = assignedDeviceId.c_str(); throw CF::ApplicationFactory::CreateApplicationRequestError(badDAS); } - allocateComponent(component, assignedDeviceId, _appUsedDevs, appIdentifier); + ossie::ComponentDeployment* deployment = allocateComponent(component, assignedDeviceId, _appUsedDevs, appIdentifier); + _deployments.push_back(deployment); } } @@ -965,14 +967,14 @@ void createHelper::_placeHostCollocation(const SoftwareAssembly::HostCollocation for (unsigned int i=0; idevice); collocAssignedDevs[i].deviceAssignment.assignedDeviceId = CORBA::string_dup(deviceId.c_str()); - (*comp)->setSelectedImplementation(*impl); if (!resolveSoftpkgDependencies(*impl, *node)) { LOG_TRACE(ApplicationFactory_impl, "Unable to resolve softpackage dependencies for component " << (*comp)->getIdentifier() << " implementation " << (*impl)->getId()); continue; } - (*comp)->setAssignedDevice(node); collocAssignedDevs[i].deviceAssignment.componentId = CORBA::string_dup((*comp)->getIdentifier()); + ossie::ComponentDeployment* deployment = new ossie::ComponentDeployment(*comp, *impl, node); + _deployments.push_back(deployment); } // Move the device to the front of the list @@ -1623,10 +1625,10 @@ CF::AllocationManager::AllocationResponseSequence* createHelper::allocateUsesDev temporary table, to assist with the allocation and clean up */ -void createHelper::allocateComponent(ossie::ComponentInfo* component, - const std::string& assignedDeviceId, - DeviceAssignmentList &appAssignedDevs, - const std::string& appIdentifier) +ossie::ComponentDeployment* createHelper::allocateComponent(ossie::ComponentInfo* component, + const std::string& assignedDeviceId, + DeviceAssignmentList &appAssignedDevs, + const std::string& appIdentifier) { // get the implementations from the component ossie::ImplementationInfo::List implementations; @@ -1705,7 +1707,6 @@ void createHelper::allocateComponent(ossie::ComponentInfo* component, // Allocation to a device succeeded LOG_DEBUG(ApplicationFactory_impl, "Assigned component " << component->getInstantiationIdentifier() << " implementation " << impl->getId() << " to device " << deviceId); - component->setAssignedDevice(response.second); // Move the device to the front of the list rotateDeviceList(_executableDevices, deviceId); @@ -1721,8 +1722,7 @@ void createHelper::allocateComponent(ossie::ComponentInfo* component, implAllocations.transfer(this->_allocations); std::copy(implAllocatedDevices.begin(), implAllocatedDevices.end(), std::back_inserter(appAssignedDevs)); - component->setSelectedImplementation(impl); - return; + return new ossie::ComponentDeployment(component, impl, response.second); } ossie::DeviceList::iterator device; @@ -2368,15 +2368,16 @@ void createHelper::loadDependencies(ossie::ComponentInfo& component, */ void createHelper::loadAndExecuteComponents(CF::ApplicationRegistrar_ptr _appReg) { - LOG_TRACE(ApplicationFactory_impl, "Loading and Executing " << _requiredComponents.size() << " components"); + LOG_TRACE(ApplicationFactory_impl, "Loading and Executing " << _deployments.size() << " components"); // apply application affinity options to required components applyApplicationAffinityOptions(); - for (unsigned int rc_idx = 0; rc_idx < _requiredComponents.size (); rc_idx++) { - ossie::ComponentInfo* component = _requiredComponents[rc_idx]; - const ossie::ImplementationInfo* implementation = component->getSelectedImplementation(); + for (unsigned int rc_idx = 0; rc_idx < _deployments.size (); rc_idx++) { + ossie::ComponentDeployment* deployment = _deployments[rc_idx]; + ossie::ComponentInfo* component = deployment->getComponent(); + const ossie::ImplementationInfo* implementation = deployment->getImplementation(); - boost::shared_ptr device = component->getAssignedDevice(); + boost::shared_ptr device = deployment->getAssignedDevice(); if (!device) { std::ostringstream message; message << "component " << component->getIdentifier() << " was not assigned to a device"; @@ -3294,6 +3295,10 @@ createHelper::~createHelper() delete (*comp); } _requiredComponents.clear(); + for (std::vector::iterator ii = _deployments.begin(); ii != _deployments.end(); ++ii) { + delete (*ii); + } + _deployments.clear(); } void createHelper::_cleanupFailedCreate() diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h index cd409e09b..908fc5d2d 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h @@ -209,6 +209,8 @@ public ossie::DeviceLookup ossie::ApplicationInfo _appInfo; + std::vector _deployments; + // createHelper helper methods ossie::ComponentInfo* getAssemblyController(); void overrideExternalProperties(const CF::Properties& initConfiguration); @@ -252,10 +254,10 @@ public ossie::DeviceLookup CF::AllocationManager::AllocationResponseSequence* allocateUsesDeviceProperties( const ossie::UsesDeviceInfo::List& component, const CF::Properties& configureProperties); - void allocateComponent(ossie::ComponentInfo* component, - const std::string& assignedDeviceId, - DeviceAssignmentList &appAssignedDevices, - const std::string& appIdentifier); + ossie::ComponentDeployment* allocateComponent(ossie::ComponentInfo* component, + const std::string& assignedDeviceId, + DeviceAssignmentList &appAssignedDevices, + const std::string& appIdentifier); ossie::AllocationResult allocateComponentToDevice(ossie::ComponentInfo* component, ossie::ImplementationInfo* implementation, diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp index 6e4442ba4..bd4b6b9c6 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp @@ -653,11 +653,6 @@ void ComponentInfo::setIdentifier(const char* _identifier, std::string instance_ instantiationId = instance_id; } -void ComponentInfo::setAssignedDevice(boost::shared_ptr device) -{ - assignedDevice = device; -} - void ComponentInfo::setNamingService(const bool _isNamingService) { isNamingService = _isNamingService; @@ -1191,3 +1186,36 @@ ComponentInfo* ApplicationInfo::findComponentByInstantiationId(const std::string } return 0; } + +Deployment::Deployment(SoftpkgInfo* softpkg, ImplementationInfo* impl) : + softpkg(softpkg), + impl(impl) +{ +} + +SoftpkgInfo* Deployment::getSoftpkg() +{ + return softpkg; +} + +ImplementationInfo* Deployment::getImplementation() +{ + return impl; +} + +ComponentDeployment::ComponentDeployment(ComponentInfo* component, ImplementationInfo* impl, + const boost::shared_ptr& device) : + Deployment(component, impl), + assignedDevice(device) +{ +} + +ComponentInfo* ComponentDeployment::getComponent() +{ + return dynamic_cast(getSoftpkg()); +} + +boost::shared_ptr ComponentDeployment::getAssignedDevice() +{ + return assignedDevice; +} diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.h b/redhawk/src/control/sdr/dommgr/applicationSupport.h index 9e2ccf11d..0f72449e0 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.h +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.h @@ -220,7 +220,6 @@ namespace ossie ~ComponentInfo (); void setIdentifier(const char* identifier, std::string instance_id); - void setAssignedDevice(boost::shared_ptr device); void setNamingService(const bool isNamingService); void setNamingServiceName(const char* NamingServiceName); void setUsageName(const char* usageName); @@ -352,5 +351,33 @@ namespace ossie CF::Properties acProps; std::vector components; }; + + class Deployment + { + public: + Deployment(SoftpkgInfo* softpkg, ImplementationInfo* impl); + + SoftpkgInfo* getSoftpkg(); + ImplementationInfo* getImplementation(); + + protected: + SoftpkgInfo* softpkg; + ImplementationInfo* impl; + std::vector dependencies; + }; + + class ComponentDeployment : public Deployment + { + public: + ComponentDeployment(ComponentInfo* component, ImplementationInfo* impl, + const boost::shared_ptr& device); + + ComponentInfo* getComponent(); + + boost::shared_ptr getAssignedDevice(); + + protected: + boost::shared_ptr assignedDevice; + }; } #endif From 2f6576e3637bd293d5c40a0ba0fd77a2a386799f Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 9 May 2016 09:59:15 -0400 Subject: [PATCH 0170/1644] Remove references to _appCapacityTable, which hasn't existed for a while (and there is no longer any need to clear _appUsedDevs) --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 23 ------------------- 1 file changed, 23 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index a67265254..88c0123be 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -1375,25 +1375,6 @@ throw (CORBA::SystemException, // Assign components to devices //////////////////////////////////////////////// - /* - * _appUsedDevs and appCapacityTable represent all the allocations - * and assigned made during applicaiton deployment. It provides the - * "context" for the deployment. This context pattern will be - * applied again when collocation requests are fullfilled. There 2 - * container are used to deploy the waveform, and also to "cleanup" - * if deployment fails - */ - - // reset list of devices that were used during component - // allocation/placement process for an application - _appUsedDevs.resize(0); - - // Start with a empty set of allocation properties, used to keep - // track of device capacity allocations. If this is not cleared - // each time, deallocation may start occuring multiple times, - // resulting in incorrect capacities. - //_appCapacityTable.clear(); - // Allocate any usesdevice capacities specified in the SAD file _handleUsesDevices(name); @@ -1619,10 +1600,6 @@ CF::AllocationManager::AllocationResponseSequence* createHelper::allocateUsesDev Current implementation takes advantage of single failure then clean up everything..... To support collocation allocation failover for mulitple devices, then we need to clean up only the allocations that we made during a failed collocation request. This requires that we know and cleanup only those allocations that we made.. - appCapacityTable holds all the applications that were made during the entire application deployment process. - - I think for each try of a collocation request... we need to swap out the current appCapacityTable for a - temporary table, to assist with the allocation and clean up */ ossie::ComponentDeployment* createHelper::allocateComponent(ossie::ComponentInfo* component, From 4091fb18a0cd689c74a227595bb13708c55aba11 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 9 May 2016 11:39:52 -0400 Subject: [PATCH 0171/1644] Move deployment classes into their own files, and always use them for managing selected implementations --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 48 ++++++------ .../sdr/dommgr/ApplicationFactory_impl.h | 7 +- redhawk/src/control/sdr/dommgr/Deployment.cpp | 74 +++++++++++++++++++ redhawk/src/control/sdr/dommgr/Deployment.h | 65 ++++++++++++++++ redhawk/src/control/sdr/dommgr/Makefile.am | 1 + .../control/sdr/dommgr/applicationSupport.cpp | 57 -------------- .../control/sdr/dommgr/applicationSupport.h | 34 +-------- 7 files changed, 173 insertions(+), 113 deletions(-) create mode 100644 redhawk/src/control/sdr/dommgr/Deployment.cpp create mode 100644 redhawk/src/control/sdr/dommgr/Deployment.h diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 88c0123be..97f345931 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -967,13 +967,14 @@ void createHelper::_placeHostCollocation(const SoftwareAssembly::HostCollocation for (unsigned int i=0; idevice); collocAssignedDevs[i].deviceAssignment.assignedDeviceId = CORBA::string_dup(deviceId.c_str()); - if (!resolveSoftpkgDependencies(*impl, *node)) { + ossie::ComponentDeployment* deployment = new ossie::ComponentDeployment(*comp, *impl, node); + if (!resolveSoftpkgDependencies(deployment, *node)) { LOG_TRACE(ApplicationFactory_impl, "Unable to resolve softpackage dependencies for component " << (*comp)->getIdentifier() << " implementation " << (*impl)->getId()); + delete deployment; continue; } collocAssignedDevs[i].deviceAssignment.componentId = CORBA::string_dup((*comp)->getIdentifier()); - ossie::ComponentDeployment* deployment = new ossie::ComponentDeployment(*comp, *impl, node); _deployments.push_back(deployment); } @@ -1674,10 +1675,11 @@ ossie::ComponentDeployment* createHelper::allocateComponent(ossie::ComponentInfo DeviceNode& node = *(response.second); const std::string& deviceId = node.identifier; - if (!resolveSoftpkgDependencies(impl, node)) { - component->clearSelectedImplementation(); + ossie::ComponentDeployment* deployment = new ossie::ComponentDeployment(component, impl, response.second); + if (!resolveSoftpkgDependencies(deployment, node)) { LOG_DEBUG(ApplicationFactory_impl, "Unable to resolve softpackage dependencies for component " << component->getIdentifier() << " implementation " << impl->getId()); + delete deployment; continue; } @@ -1699,7 +1701,7 @@ ossie::ComponentDeployment* createHelper::allocateComponent(ossie::ComponentInfo implAllocations.transfer(this->_allocations); std::copy(implAllocatedDevices.begin(), implAllocatedDevices.end(), std::back_inserter(appAssignedDevs)); - return new ossie::ComponentDeployment(component, impl, response.second); + return deployment; } ossie::DeviceList::iterator device; @@ -2031,19 +2033,19 @@ CF::DataType createHelper::castProperty(const ossie::ComponentProperty* property return dataType; } -bool createHelper::resolveSoftpkgDependencies(ossie::ImplementationInfo* implementation, ossie::DeviceNode& device) +bool createHelper::resolveSoftpkgDependencies(ossie::SoftpkgDeployment* deployment, ossie::DeviceNode& device) { + ossie::ImplementationInfo* implementation = deployment->getImplementation(); const std::vector& tmpSoftpkg = implementation->getSoftPkgDependency(); std::vector::const_iterator iterSoftpkg; for (iterSoftpkg = tmpSoftpkg.begin(); iterSoftpkg != tmpSoftpkg.end(); ++iterSoftpkg) { // Find an implementation whose dependencies match - ossie::ImplementationInfo* spdImplInfo = resolveDependencyImplementation(*iterSoftpkg, device); - if (spdImplInfo) { - (*iterSoftpkg)->setSelectedImplementation(spdImplInfo); + ossie::SoftpkgDeployment* dependency = resolveDependencyImplementation(*iterSoftpkg, device); + if (dependency) { + deployment->addDependency(dependency); } else { LOG_DEBUG(ApplicationFactory_impl, "resolveSoftpkgDependencies: implementation match not found between soft package dependency and device"); - implementation->clearSelectedDependencyImplementations(); return false; } } @@ -2051,8 +2053,8 @@ bool createHelper::resolveSoftpkgDependencies(ossie::ImplementationInfo* impleme return true; } -ossie::ImplementationInfo* createHelper::resolveDependencyImplementation(ossie::SoftpkgInfo* softpkg, - ossie::DeviceNode& device) +ossie::SoftpkgDeployment* createHelper::resolveDependencyImplementation(ossie::SoftpkgInfo* softpkg, + ossie::DeviceNode& device) { ossie::ImplementationInfo::List spd_list; softpkg->getImplementations(spd_list); @@ -2064,9 +2066,10 @@ ossie::ImplementationInfo* createHelper::resolveDependencyImplementation(ossie:: continue; } + ossie::SoftpkgDeployment* dependency = new ossie::SoftpkgDeployment(softpkg, implementation); // Recursively check any softpkg dependencies - if (resolveSoftpkgDependencies(implementation, device)) { - return implementation; + if (resolveSoftpkgDependencies(dependency, device)) { + return dependency; } } @@ -2301,25 +2304,26 @@ string ApplicationFactory_impl::getBaseWaveformContext(string waveform_context) void createHelper::loadDependencies(ossie::ComponentInfo& component, CF::LoadableDevice_ptr device, - const std::vector& dependencies) + const std::vector& dependencies) { - for (std::vector::const_iterator dep = dependencies.begin(); dep != dependencies.end(); ++dep) { - const ossie::ImplementationInfo* implementation = (*dep)->getSelectedImplementation(); + for (std::vector::const_iterator deployment = dependencies.begin(); deployment != dependencies.end(); ++deployment) { + ossie::SoftpkgInfo* dep = (*deployment)->getSoftpkg(); + const ossie::ImplementationInfo* implementation = (*deployment)->getImplementation(); if (!implementation) { - LOG_ERROR(ApplicationFactory_impl, "No implementation selected for dependency " << (*dep)->getName()); + LOG_ERROR(ApplicationFactory_impl, "No implementation selected for dependency " << dep->getName()); throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EINVAL, "Missing implementation"); } // Recursively load dependencies - LOG_TRACE(ApplicationFactory_impl, "Loading dependencies for soft package " << (*dep)->getName()); - loadDependencies(component, device, implementation->getSoftPkgDependency()); + LOG_TRACE(ApplicationFactory_impl, "Loading dependencies for soft package " << dep->getName()); + loadDependencies(component, device, (*deployment)->getDependencies()); // Determine absolute path of dependency's local file CF::LoadableDevice::LoadType codeType = implementation->getCodeType(); fs::path codeLocalFile = fs::path(implementation->getLocalFileName()); if (!codeLocalFile.has_root_directory()) { // Path is relative to SPD file location - fs::path base_dir = fs::path((*dep)->getSpdFileName()).parent_path(); + fs::path base_dir = fs::path(dep->getSpdFileName()).parent_path(); codeLocalFile = base_dir / codeLocalFile; } codeLocalFile = codeLocalFile.normalize(); @@ -2409,7 +2413,7 @@ void createHelper::loadAndExecuteComponents(CF::ApplicationRegistrar_ptr _appReg throw std::logic_error(message.str()); } - loadDependencies(*component, loadabledev, implementation->getSoftPkgDependency()); + loadDependencies(*component, loadabledev, deployment->getDependencies()); // load the file(s) ostringstream load_eout; // used for any error messages dealing with load diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h index 908fc5d2d..5a122e4dc 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h @@ -35,6 +35,7 @@ #include "PersistenceStore.h" #include "applicationSupport.h" #include "connectionSupport.h" +#include "Deployment.h" class DomainManager_impl; class Application_impl; @@ -264,13 +265,13 @@ public ossie::DeviceLookup const std::string& assignedDeviceId, const std::string& appIdentifier); - bool resolveSoftpkgDependencies(ossie::ImplementationInfo* implementation, ossie::DeviceNode& device); - ossie::ImplementationInfo* resolveDependencyImplementation(ossie::SoftpkgInfo* softpkg, ossie::DeviceNode& device); + bool resolveSoftpkgDependencies(ossie::SoftpkgDeployment* deployment, ossie::DeviceNode& device); + ossie::SoftpkgDeployment* resolveDependencyImplementation(ossie::SoftpkgInfo* softpkg, ossie::DeviceNode& device); // Supports loading, executing, initializing, configuring, & connecting void loadDependencies(ossie::ComponentInfo& component, CF::LoadableDevice_ptr device, - const std::vector& dependencies); + const std::vector& dependencies); void loadAndExecuteComponents(CF::ApplicationRegistrar_ptr _appReg); void applyApplicationAffinityOptions(); diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp new file mode 100644 index 000000000..4c66a1907 --- /dev/null +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -0,0 +1,74 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK core. + * + * REDHAWK core is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +#include "Deployment.h" + +using namespace ossie; + +SoftpkgDeployment::SoftpkgDeployment(SoftpkgInfo* softpkg, ImplementationInfo* impl) : + softpkg(softpkg), + impl(impl) +{ +} + +SoftpkgDeployment::~SoftpkgDeployment() +{ + for (std::vector::iterator dependency = dependencies.begin(); dependency != dependencies.end(); ++dependency) { + delete (*dependency); + } +} + +SoftpkgInfo* SoftpkgDeployment::getSoftpkg() +{ + return softpkg; +} + +ImplementationInfo* SoftpkgDeployment::getImplementation() +{ + return impl; +} + +void SoftpkgDeployment::addDependency(SoftpkgDeployment* dependency) +{ + dependencies.push_back(dependency); +} + +const std::vector& SoftpkgDeployment::getDependencies() +{ + return dependencies; +} + +ComponentDeployment::ComponentDeployment(ComponentInfo* component, ImplementationInfo* impl, + const boost::shared_ptr& device) : + SoftpkgDeployment(component, impl), + assignedDevice(device) +{ +} + +ComponentInfo* ComponentDeployment::getComponent() +{ + return dynamic_cast(getSoftpkg()); +} + +boost::shared_ptr ComponentDeployment::getAssignedDevice() +{ + return assignedDevice; +} + diff --git a/redhawk/src/control/sdr/dommgr/Deployment.h b/redhawk/src/control/sdr/dommgr/Deployment.h new file mode 100644 index 000000000..98b6ec5c7 --- /dev/null +++ b/redhawk/src/control/sdr/dommgr/Deployment.h @@ -0,0 +1,65 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK core. + * + * REDHAWK core is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +#ifndef DEPLOYMENT_H +#define DEPLOYMENT_H + +#include +#include + +#include + +#include "applicationSupport.h" + +namespace ossie { + class SoftpkgDeployment + { + public: + SoftpkgDeployment(SoftpkgInfo* softpkg, ImplementationInfo* impl); + ~SoftpkgDeployment(); + + SoftpkgInfo* getSoftpkg(); + ImplementationInfo* getImplementation(); + + void addDependency(SoftpkgDeployment* dependency); + const std::vector& getDependencies(); + + protected: + SoftpkgInfo* softpkg; + ImplementationInfo* impl; + std::vector dependencies; + }; + + class ComponentDeployment : public SoftpkgDeployment + { + public: + ComponentDeployment(ComponentInfo* component, ImplementationInfo* impl, + const boost::shared_ptr& device); + + ComponentInfo* getComponent(); + + boost::shared_ptr getAssignedDevice(); + + protected: + boost::shared_ptr assignedDevice; + }; +} + +#endif // DEPLOYMENT_H diff --git a/redhawk/src/control/sdr/dommgr/Makefile.am b/redhawk/src/control/sdr/dommgr/Makefile.am index 40f5face9..266099569 100644 --- a/redhawk/src/control/sdr/dommgr/Makefile.am +++ b/redhawk/src/control/sdr/dommgr/Makefile.am @@ -34,6 +34,7 @@ DomainManager_SOURCES = applicationSupport.cpp \ RH_NamingContext.cpp \ DomainManager_impl.cpp \ FakeApplication.cpp \ + Deployment.cpp \ main.cpp DomainManager_CPPFLAGS = -I../../include -I../../parser -I$(top_srcdir)/base/include -I$(top_srcdir)/base $(BOOST_CPPFLAGS) $(OMNIORB_CFLAGS) $(LOG4CXX_FLAGS) DomainManager_CXXFLAGS = -Wall diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp index bd4b6b9c6..426d8edb3 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp @@ -353,14 +353,6 @@ bool ImplementationInfo::checkProcessorAndOs(const Properties& _prf) const return matchProcessor && matchOs; } -void ImplementationInfo::clearSelectedDependencyImplementations() -{ - std::vector::const_iterator iter; - for (iter = softPkgDependencies.begin(); iter != softPkgDependencies.end(); ++iter) { - (*iter)->clearSelectedImplementation(); - } -} - PREPARE_CF_LOGGING(SoftpkgInfo); @@ -451,22 +443,6 @@ void SoftpkgInfo::getImplementations(ImplementationInfo::List& res) std::copy(_implementations.begin(), _implementations.end(), std::back_inserter(res)); } -void SoftpkgInfo::setSelectedImplementation(ImplementationInfo* implementation) -{ - if (std::find(_implementations.begin(), _implementations.end(), implementation) == _implementations.end()) { - throw std::logic_error("invalid implementation selected"); - } - _selectedImplementation = implementation; -} - -void SoftpkgInfo::clearSelectedImplementation() -{ - if (_selectedImplementation) { - _selectedImplementation->clearSelectedDependencyImplementations(); - _selectedImplementation = 0; - } -} - const ImplementationInfo* SoftpkgInfo::getSelectedImplementation() const { return _selectedImplementation; @@ -1186,36 +1162,3 @@ ComponentInfo* ApplicationInfo::findComponentByInstantiationId(const std::string } return 0; } - -Deployment::Deployment(SoftpkgInfo* softpkg, ImplementationInfo* impl) : - softpkg(softpkg), - impl(impl) -{ -} - -SoftpkgInfo* Deployment::getSoftpkg() -{ - return softpkg; -} - -ImplementationInfo* Deployment::getImplementation() -{ - return impl; -} - -ComponentDeployment::ComponentDeployment(ComponentInfo* component, ImplementationInfo* impl, - const boost::shared_ptr& device) : - Deployment(component, impl), - assignedDevice(device) -{ -} - -ComponentInfo* ComponentDeployment::getComponent() -{ - return dynamic_cast(getSoftpkg()); -} - -boost::shared_ptr ComponentDeployment::getAssignedDevice() -{ - return assignedDevice; -} diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.h b/redhawk/src/control/sdr/dommgr/applicationSupport.h index 0f72449e0..4f2687f39 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.h +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.h @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -141,8 +142,6 @@ namespace ossie bool checkProcessorAndOs(const ossie::Properties& prf) const; - void clearSelectedDependencyImplementations(); - static ImplementationInfo* buildImplementationInfo(CF::FileManager_ptr fileMgr, const SPD::Implementation& spdImpl); private: @@ -186,8 +185,8 @@ namespace ossie void getImplementations(ImplementationInfo::List& res); const ImplementationInfo* getSelectedImplementation() const; - void setSelectedImplementation(ImplementationInfo* implementation); - void clearSelectedImplementation(); + //void setSelectedImplementation(ImplementationInfo* implementation); + //void clearSelectedImplementation(); virtual const UsesDeviceInfo* getUsesDeviceById(const std::string& id) const; @@ -352,32 +351,5 @@ namespace ossie std::vector components; }; - class Deployment - { - public: - Deployment(SoftpkgInfo* softpkg, ImplementationInfo* impl); - - SoftpkgInfo* getSoftpkg(); - ImplementationInfo* getImplementation(); - - protected: - SoftpkgInfo* softpkg; - ImplementationInfo* impl; - std::vector dependencies; - }; - - class ComponentDeployment : public Deployment - { - public: - ComponentDeployment(ComponentInfo* component, ImplementationInfo* impl, - const boost::shared_ptr& device); - - ComponentInfo* getComponent(); - - boost::shared_ptr getAssignedDevice(); - - protected: - boost::shared_ptr assignedDevice; - }; } #endif From 9baf50b0660a4efa7730dc848c6ad4d57762414c Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 9 May 2016 13:05:51 -0400 Subject: [PATCH 0172/1644] Use deployment classes to determine effective local file and generate the list of dependencies' local files for execution --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 60 ++++--------------- .../sdr/dommgr/ApplicationFactory_impl.h | 3 +- redhawk/src/control/sdr/dommgr/Deployment.cpp | 33 +++++++++- redhawk/src/control/sdr/dommgr/Deployment.h | 10 +++- .../control/sdr/dommgr/applicationSupport.cpp | 9 --- .../control/sdr/dommgr/applicationSupport.h | 4 -- 6 files changed, 53 insertions(+), 66 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 97f345931..b039df996 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -2320,18 +2320,7 @@ void createHelper::loadDependencies(ossie::ComponentInfo& component, // Determine absolute path of dependency's local file CF::LoadableDevice::LoadType codeType = implementation->getCodeType(); - fs::path codeLocalFile = fs::path(implementation->getLocalFileName()); - if (!codeLocalFile.has_root_directory()) { - // Path is relative to SPD file location - fs::path base_dir = fs::path(dep->getSpdFileName()).parent_path(); - codeLocalFile = base_dir / codeLocalFile; - } - codeLocalFile = codeLocalFile.normalize(); - if (codeLocalFile.has_leaf() && codeLocalFile.leaf() == ".") { - codeLocalFile = codeLocalFile.branch_path(); - } - - const std::string fileName = codeLocalFile.string(); + const std::string fileName = (*deployment)->getLocalFile(); LOG_DEBUG(ApplicationFactory_impl, "Loading dependency local file " << fileName); try { device->load(_appFact._fileMgr, fileName.c_str(), codeType); @@ -2339,7 +2328,6 @@ void createHelper::loadDependencies(ossie::ComponentInfo& component, LOG_ERROR(ApplicationFactory_impl, "Failure loading file " << fileName); throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EINVAL, "Failed to load file"); } - component.addResolvedSoftPkgDependency(fileName); _application->addComponentLoadedFile(component.getIdentifier(), fileName); } } @@ -2380,19 +2368,12 @@ void createHelper::loadAndExecuteComponents(CF::ApplicationRegistrar_ptr _appReg _application->setComponentDevice(component->getIdentifier(), device->device); // get the code.localfile - fs::path codeLocalFile = fs::path(implementation->getLocalFileName()); LOG_TRACE(ApplicationFactory_impl, "Host is " << device->label << " Local file name is " - << codeLocalFile); - if (!codeLocalFile.has_root_directory()) { - codeLocalFile = fs::path(component->spd.getSPDPath()) / codeLocalFile; - } - codeLocalFile = codeLocalFile.normalize(); - if (codeLocalFile.has_leaf() && codeLocalFile.leaf() == ".") { - codeLocalFile = codeLocalFile.branch_path(); - } + << implementation->getLocalFileName()); // Get file name, load if it is not empty - if (codeLocalFile.string().size() <= 0) { + std::string codeLocalFile = deployment->getLocalFile(); + if (codeLocalFile.empty()) { ostringstream eout; eout << "code.localfile is empty for component: '"; eout << component->getName() << "' with component id: '" << component->getIdentifier() << "' "; @@ -2420,23 +2401,7 @@ void createHelper::loadAndExecuteComponents(CF::ApplicationRegistrar_ptr _appReg try { try { LOG_TRACE(ApplicationFactory_impl, "loading " << codeLocalFile << " on device " << ossie::corba::returnString(loadabledev->label())); - loadabledev->load(_appFact._fileMgr, codeLocalFile.string().c_str(), implementation->getCodeType()); - } catch( const CF::LoadableDevice::LoadFail &ex ) { - load_eout << "'load' failed for component: '"; - load_eout << component->getName() << "' with component id: '" << component->getIdentifier() << "' "; - load_eout << " with implementation id: '" << implementation->getId() << "';"; - load_eout << " on device id: '" << device->identifier << "'"; - load_eout << " in waveform '" << _waveformContextName<<"'"; - load_eout << "\nREASON: '" << ex.msg << "'\nError occurred near line:" <<__LINE__ << " in file:" << __FILE__ << ";"; - throw; - } catch( const CF::InvalidFileName &ex ) { - load_eout << "'load' failed for component: '"; - load_eout << component->getName() << "' with component id: '" << component->getIdentifier() << "' "; - load_eout << " with implementation id: '" << implementation->getId() << "';"; - load_eout << " on device id: '" << device->identifier << "'"; - load_eout << " in waveform '" << _waveformContextName<<"'"; - load_eout << "\nREASON: '" << ex.msg << "'\nError occurred near line:" <<__LINE__ << " in file:" << __FILE__ << ";"; - throw; + loadabledev->load(_appFact._fileMgr, codeLocalFile.c_str(), implementation->getCodeType()); } catch( ... ) { load_eout << "'load' failed for component: '"; load_eout << component->getName() << "' with component id: '" << component->getIdentifier() << "' "; @@ -2455,7 +2420,7 @@ void createHelper::loadAndExecuteComponents(CF::ApplicationRegistrar_ptr _appReg } CATCH_THROW_LOG_TRACE(ApplicationFactory_impl, "", CF::ApplicationFactory::CreateApplicationError(CF::CF_EIO, load_eout.str().c_str())); // Mark the file as loaded - _application->addComponentLoadedFile(component->getIdentifier(), codeLocalFile.string()); + _application->addComponentLoadedFile(component->getIdentifier(), codeLocalFile); // OSSIE extends section D.2.1.6.3 to support loading a directory // and execute a file in that directory using a entrypoint @@ -2611,7 +2576,7 @@ void createHelper::loadAndExecuteComponents(CF::ApplicationRegistrar_ptr _appReg executeName = executeName.normalize(); } - attemptComponentExecution(executeName, execdev, component, implementation); + attemptComponentExecution(executeName, execdev, deployment); } } } @@ -2635,15 +2600,16 @@ std::string createHelper::createVersionMismatchMessage(std::string &component_ve void createHelper::attemptComponentExecution ( const fs::path& executeName, CF::ExecutableDevice_ptr execdev, - ossie::ComponentInfo* component, - const ossie::ImplementationInfo* implementation) { - + ossie::ComponentDeployment* deployment) +{ CF::Properties execParameters; // get entrypoint CF::ExecutableDevice::ProcessID_Type tempPid = -1; - std::string component_version(component->spd.getSoftPkgType()); + ossie::ComponentInfo* component = deployment->getComponent(); + ossie::ImplementationInfo* implementation = deployment->getImplementation(); + // attempt to execute the component try { LOG_TRACE(ApplicationFactory_impl, "executing " << executeName << " on device " << ossie::corba::returnString(execdev->label())); @@ -2653,7 +2619,7 @@ void createHelper::attemptComponentExecution ( } // call 'execute' on the ExecutableDevice to execute the component CF::StringSequence dep_seq; - std::vector resolved_softpkg_deps = component->getResolvedSoftPkgDependencies(); + std::vector resolved_softpkg_deps = deployment->getDependencyLocalFiles(); dep_seq.length(resolved_softpkg_deps.size()); for (unsigned int p=0;p!=dep_seq.length();p++) { dep_seq[p]=CORBA::string_dup(resolved_softpkg_deps[p].c_str()); diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h index 5a122e4dc..25c3a9191 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h @@ -279,8 +279,7 @@ public ossie::DeviceLookup void attemptComponentExecution( const boost::filesystem::path& executeName, CF::ExecutableDevice_ptr execdev, - ossie::ComponentInfo* component, - const ossie::ImplementationInfo* implementation); + ossie::ComponentDeployment* deployment); void waitForComponentRegistration(); void initializeComponents(); diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index 4c66a1907..ab6490d4f 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -18,9 +18,12 @@ * along with this program. If not, see http://www.gnu.org/licenses/. */ +#include + #include "Deployment.h" using namespace ossie; +namespace fs = boost::filesystem; SoftpkgDeployment::SoftpkgDeployment(SoftpkgInfo* softpkg, ImplementationInfo* impl) : softpkg(softpkg), @@ -30,7 +33,7 @@ SoftpkgDeployment::SoftpkgDeployment(SoftpkgInfo* softpkg, ImplementationInfo* i SoftpkgDeployment::~SoftpkgDeployment() { - for (std::vector::iterator dependency = dependencies.begin(); dependency != dependencies.end(); ++dependency) { + for (DeploymentList::iterator dependency = dependencies.begin(); dependency != dependencies.end(); ++dependency) { delete (*dependency); } } @@ -55,6 +58,33 @@ const std::vector& SoftpkgDeployment::getDependencies() return dependencies; } +std::vector SoftpkgDeployment::getDependencyLocalFiles() +{ + std::vector files; + for (DeploymentList::iterator dependency = dependencies.begin(); dependency != dependencies.end(); ++dependency) { + std::vector depfiles = (*dependency)->getDependencyLocalFiles(); + std::copy(depfiles.begin(), depfiles.end(), std::back_inserter(files)); + files.push_back((*dependency)->getLocalFile()); + } + return files; +} + +std::string SoftpkgDeployment::getLocalFile() +{ + fs::path codeLocalFile = fs::path(impl->getLocalFileName()); + if (!codeLocalFile.has_root_directory()) { + // Path is relative to SPD file location + fs::path base_dir = fs::path(softpkg->getSpdFileName()).parent_path(); + codeLocalFile = base_dir / codeLocalFile; + } + codeLocalFile = codeLocalFile.normalize(); + if (codeLocalFile.has_leaf() && codeLocalFile.leaf() == ".") { + codeLocalFile = codeLocalFile.branch_path(); + } + + return codeLocalFile.string(); +} + ComponentDeployment::ComponentDeployment(ComponentInfo* component, ImplementationInfo* impl, const boost::shared_ptr& device) : SoftpkgDeployment(component, impl), @@ -71,4 +101,3 @@ boost::shared_ptr ComponentDeployment::getAssignedDevice() { return assignedDevice; } - diff --git a/redhawk/src/control/sdr/dommgr/Deployment.h b/redhawk/src/control/sdr/dommgr/Deployment.h index 98b6ec5c7..a24ca8a2c 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.h +++ b/redhawk/src/control/sdr/dommgr/Deployment.h @@ -32,19 +32,25 @@ namespace ossie { class SoftpkgDeployment { public: + typedef std::vector DeploymentList; + SoftpkgDeployment(SoftpkgInfo* softpkg, ImplementationInfo* impl); ~SoftpkgDeployment(); SoftpkgInfo* getSoftpkg(); ImplementationInfo* getImplementation(); + std::string getLocalFile(); + void addDependency(SoftpkgDeployment* dependency); - const std::vector& getDependencies(); + const DeploymentList& getDependencies(); + + std::vector getDependencyLocalFiles(); protected: SoftpkgInfo* softpkg; ImplementationInfo* impl; - std::vector dependencies; + DeploymentList dependencies; }; class ComponentDeployment : public SoftpkgDeployment diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp index 426d8edb3..5b2b623c1 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp @@ -598,7 +598,6 @@ ComponentInfo::ComponentInfo(const std::string& spdFileName) : assignedDevice() { nicAssignment = ""; - resolved_softpkg_dependencies.resize(0); // load common affinity property definitions try { std::stringstream os(redhawk::affinity::get_property_definitions()); @@ -614,14 +613,6 @@ ComponentInfo::~ComponentInfo () { } -void ComponentInfo::addResolvedSoftPkgDependency(const std::string &dep) { - this->resolved_softpkg_dependencies.push_back(dep); -} - -std::vector ComponentInfo::getResolvedSoftPkgDependencies() { - return this->resolved_softpkg_dependencies; -} - void ComponentInfo::setIdentifier(const char* _identifier, std::string instance_id) { identifier = _identifier; diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.h b/redhawk/src/control/sdr/dommgr/applicationSupport.h index 4f2687f39..c6bc757c6 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.h +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.h @@ -228,8 +228,6 @@ namespace ossie void setAffinity( const AffinityProperties &affinity ); void mergeAffinityOptions( const CF::Properties &new_affinity ); void setLoggingConfig( const LoggingConfig &logcfg ); - void addResolvedSoftPkgDependency(const std::string &dep); - std::vector getResolvedSoftPkgDependencies(); void addFactoryParameter(CF::DataType dt); void addExecParameter(CF::DataType dt); @@ -304,8 +302,6 @@ namespace ossie CF::Properties execParameters; CF::Properties affinityOptions; - std::vector resolved_softpkg_dependencies; - CF::Resource_var rsc; }; From 3848c7d5ffe29eaa3a27a30893dcb07e0bdee35a Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 9 May 2016 13:16:20 -0400 Subject: [PATCH 0173/1644] Clean up deployment object when dependency resolution fails --- redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index b039df996..8a184da4a 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -2071,6 +2071,7 @@ ossie::SoftpkgDeployment* createHelper::resolveDependencyImplementation(ossie::S if (resolveSoftpkgDependencies(dependency, device)) { return dependency; } + delete dependency; } return 0; From aca4d920ed73a79abbe715db54167a0547a18449 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 9 May 2016 15:07:27 -0400 Subject: [PATCH 0174/1644] Move a lot of the execution-related code into attemptComponentExecution --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 134 ++++++------------ .../sdr/dommgr/ApplicationFactory_impl.h | 5 +- redhawk/src/control/sdr/dommgr/Deployment.cpp | 15 ++ redhawk/src/control/sdr/dommgr/Deployment.h | 2 + 4 files changed, 65 insertions(+), 91 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 8a184da4a..4702154eb 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -2435,37 +2435,6 @@ void createHelper::loadAndExecuteComponents(CF::ApplicationRegistrar_ptr _appReg if (((implementation->getCodeType() == CF::LoadableDevice::EXECUTABLE) || (implementation->getCodeType() == CF::LoadableDevice::SHARED_LIBRARY)) && (implementation->getEntryPoint().size() != 0)) { - // get executable device reference - CF::ExecutableDevice_var execdev = ossie::corba::_narrowSafe(loadabledev); - if (CORBA::is_nil(execdev)){ - std::ostringstream message; - message << "component " << component->getIdentifier() << " was assigned to non-executable device " - << device->identifier; - throw std::logic_error(message.str()); - } - - // Add the required parameters specified in SR:163 - // Naming Context IOR, Name Binding, and component identifier - CF::DataType ci; - ci.id = "COMPONENT_IDENTIFIER"; - ci.value <<= component->getIdentifier(); - component->addExecParameter(ci); - - CF::DataType nb; - nb.id = "NAME_BINDING"; - nb.value <<= component->getNamingServiceName(); - component->addExecParameter(nb); - - CF::DataType dp; - dp.id = "DOM_PATH"; - dp.value <<= _baseNamingContext; - component->addExecParameter(dp); - - CF::DataType pn; - pn.id = "PROFILE_NAME"; - pn.value <<= component->getSpdFileName(); - component->addExecParameter(pn); - // See if the LOGGING_CONFIG_URI has already been set // via or initParams bool alreadyHasLoggingConfigURI = false; @@ -2543,11 +2512,6 @@ void createHelper::loadAndExecuteComponents(CF::ApplicationRegistrar_ptr _appReg LOG_TRACE(ApplicationFactory_impl, "override ....... uri " << logging_uri ); component->overrideProperty("LOGGING_CONFIG_URI", loguri); } - // Add the Naming Context IOR to make it easier to parse the command line - CF::DataType ncior; - ncior.id = "NAMING_CONTEXT_IOR"; - ncior.value <<= ossie::corba::objectToString(_appReg); - component->addExecParameter(ncior); std::string sr_key; if (this->specialized_reservations.find(std::string(component->getIdentifier())) != this->specialized_reservations.end()) { @@ -2564,66 +2528,61 @@ void createHelper::loadAndExecuteComponents(CF::ApplicationRegistrar_ptr _appReg component->addExecParameter(spec_res); } - fs::path executeName; - if ((implementation->getCodeType() == CF::LoadableDevice::EXECUTABLE) && (implementation->getEntryPoint().size() == 0)) { - LOG_WARN(ApplicationFactory_impl, "executing using code file as entry point; this is non-SCA compliant behavior; entrypoint must be set") - executeName = codeLocalFile; - } else { - executeName = fs::path(implementation->getEntryPoint()); - LOG_TRACE(ApplicationFactory_impl, "Using provided entry point " << executeName) - if (!executeName.has_root_directory()) { - executeName = fs::path(component->spd.getSPDPath()) / executeName; - } - executeName = executeName.normalize(); - } - - attemptComponentExecution(executeName, execdev, deployment); + attemptComponentExecution(_appReg, deployment); } } } -std::string createHelper::createVersionMismatchMessage(std::string &component_version) +void createHelper::attemptComponentExecution (CF::ApplicationRegistrar_ptr registrar, + ossie::ComponentDeployment* deployment) { - std::string version = this->_appFact._domainManager->getRedhawkVersion(); - std::string added_message; - try { - if (redhawk::compareVersions(component_version, version) < 0) { - added_message = "Attempting to run a component from version "; - added_message += component_version; - added_message += " on REDHAWK version "; - added_message += version; - added_message += ". "; - } - } catch ( ... ) {} - return added_message; -} - -void createHelper::attemptComponentExecution ( - const fs::path& executeName, - CF::ExecutableDevice_ptr execdev, - ossie::ComponentDeployment* deployment) -{ - CF::Properties execParameters; - - // get entrypoint - CF::ExecutableDevice::ProcessID_Type tempPid = -1; - ossie::ComponentInfo* component = deployment->getComponent(); ossie::ImplementationInfo* implementation = deployment->getImplementation(); + // Get executable device reference + boost::shared_ptr device = deployment->getAssignedDevice(); + CF::ExecutableDevice_var execdev = ossie::corba::_narrowSafe(device->device); + if (CORBA::is_nil(execdev)){ + std::ostringstream message; + message << "component " << component->getIdentifier() << " was assigned to non-executable device " + << device->identifier; + throw std::logic_error(message.str()); + } + + redhawk::PropertyMap execParameters(component->getPopulatedExecParameters()); + + // Add the required parameters specified in SR:163 + // Naming Context IOR, Name Binding, and component identifier + execParameters["COMPONENT_IDENTIFIER"] = component->getIdentifier(); + execParameters["NAME_BINDING"] = component->getNamingServiceName(); + execParameters["DOM_PATH"] = _baseNamingContext; + execParameters["PROFILE_NAME"] = component->getSpdFileName(); + + // Add the Naming Context IOR last to make it easier to parse the command line + execParameters["NAMING_CONTEXT_IOR"] = ossie::corba::objectToString(registrar); + + // Get entry point + std::string entryPoint = deployment->getEntryPoint(); + if (entryPoint.empty()) { + LOG_WARN(ApplicationFactory_impl, "executing using code file as entry point; this is non-SCA compliant behavior; entrypoint must be set"); + entryPoint = deployment->getLocalFile(); + } + + // Get the complete list of dependencies to include in executeLinked + std::vector resolved_softpkg_deps = deployment->getDependencyLocalFiles(); + CF::StringSequence dep_seq; + dep_seq.length(resolved_softpkg_deps.size()); + for (unsigned int p=0;p!=dep_seq.length();p++) { + dep_seq[p]=CORBA::string_dup(resolved_softpkg_deps[p].c_str()); + } + + CF::ExecutableDevice::ProcessID_Type tempPid = -1; + // attempt to execute the component try { - LOG_TRACE(ApplicationFactory_impl, "executing " << executeName << " on device " << ossie::corba::returnString(execdev->label())); - execParameters = component->getExecParameters(); - for (unsigned int i = 0; i < execParameters.length(); ++i) { - LOG_TRACE(ApplicationFactory_impl, " exec param " << execParameters[i].id << " " << ossie::any_to_string(execParameters[i].value)) - } - // call 'execute' on the ExecutableDevice to execute the component - CF::StringSequence dep_seq; - std::vector resolved_softpkg_deps = deployment->getDependencyLocalFiles(); - dep_seq.length(resolved_softpkg_deps.size()); - for (unsigned int p=0;p!=dep_seq.length();p++) { - dep_seq[p]=CORBA::string_dup(resolved_softpkg_deps[p].c_str()); + LOG_TRACE(ApplicationFactory_impl, "executing " << entryPoint << " on device " << device->label); + for (redhawk::PropertyMap::iterator prop = execParameters.begin(); prop != execParameters.end(); ++prop) { + LOG_TRACE(ApplicationFactory_impl, " exec param " << prop->getId() << " " << prop->getValue().toString()); } // get Options list @@ -2632,7 +2591,8 @@ void createHelper::attemptComponentExecution ( LOG_TRACE(ApplicationFactory_impl, " RESOURCE OPTION: " << cop[i].id << " " << ossie::any_to_string(cop[i].value)) } - tempPid = execdev->executeLinked(executeName.string().c_str(), cop, component->getPopulatedExecParameters(), dep_seq); + // call 'execute' on the ExecutableDevice to execute the component + tempPid = execdev->executeLinked(entryPoint.c_str(), cop, execParameters, dep_seq); } catch( CF::InvalidFileName& _ex ) { std::string added_message = this->createVersionMismatchMessage(component_version); ostringstream eout; diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h index 25c3a9191..852243aea 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h @@ -276,10 +276,7 @@ public ossie::DeviceLookup void loadAndExecuteComponents(CF::ApplicationRegistrar_ptr _appReg); void applyApplicationAffinityOptions(); - void attemptComponentExecution( - const boost::filesystem::path& executeName, - CF::ExecutableDevice_ptr execdev, - ossie::ComponentDeployment* deployment); + void attemptComponentExecution(CF::ApplicationRegistrar_ptr registrar, ossie::ComponentDeployment* deployment); void waitForComponentRegistration(); void initializeComponents(); diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index ab6490d4f..2218ccf46 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -101,3 +101,18 @@ boost::shared_ptr ComponentDeployment::getAssignedDevice() { return assignedDevice; } + +std::string ComponentDeployment::getEntryPoint() +{ + std::string entryPoint = impl->getEntryPoint(); + if (!entryPoint.empty()) { + fs::path entryPointPath = fs::path(entryPoint); + if (!entryPointPath.has_root_directory()) { + // Path is relative to SPD file location + fs::path base_dir = fs::path(softpkg->getSpdFileName()).parent_path(); + entryPointPath = base_dir / entryPointPath; + } + entryPoint = entryPointPath.normalize().string(); + } + return entryPoint; +} diff --git a/redhawk/src/control/sdr/dommgr/Deployment.h b/redhawk/src/control/sdr/dommgr/Deployment.h index a24ca8a2c..84ef45d75 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.h +++ b/redhawk/src/control/sdr/dommgr/Deployment.h @@ -61,6 +61,8 @@ namespace ossie { ComponentInfo* getComponent(); + std::string getEntryPoint(); + boost::shared_ptr getAssignedDevice(); protected: From aa1252be59b3b926470c89977414605521f3bfab Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 10 May 2016 08:20:43 -0400 Subject: [PATCH 0175/1644] Quick fix to avoid multiple deployments of collocated components --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 4702154eb..6d242b981 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -693,7 +693,14 @@ void createHelper::assignRemainingComponentsToDevices(const std::string &appIden componentIter != _requiredComponents.end(); componentIter++) { - if (!(*componentIter)->isAssignedToDevice()) { + boost::shared_ptr assignedDevice; + for (std::vector::iterator ii = _deployments.begin(); ii != _deployments.end(); ++ii) { + if ((*ii)->getComponent() == (*componentIter)) { + assignedDevice = (*ii)->getAssignedDevice(); + break; + } + } + if (!assignedDevice) { ossie::ComponentDeployment* deployment = allocateComponent(*componentIter, std::string(), _appUsedDevs, appIdentifier); _deployments.push_back(deployment); } @@ -1021,14 +1028,21 @@ void createHelper::_getComponentsToPlace( "Collocated component " << component->getInstantiationIdentifier()); - if (component->isAssignedToDevice()) { + boost::shared_ptr assignedDevice; + for (std::vector::iterator ii = _deployments.begin(); ii != _deployments.end(); ++ii) { + if ((*ii)->getComponent() == component) { + assignedDevice = (*ii)->getAssignedDevice(); + break; + } + } + if (assignedDevice) { // This component is already assigned to a device; for collocating // other components, the pre-assigned devices are used in the order // they are encountered. LOG_TRACE(ApplicationFactory_impl, "Already assigned to device " << - component->getAssignedDeviceId()); - assignedDevices.push_back( component->getAssignedDeviceId() ); + assignedDevice->identifier); + assignedDevices.push_back(assignedDevice->identifier); } else { // This component needs to be assigned to a device. placingComponents.push_back(component); From d992414b1a33558d4f791a607dadbd0cac09594f Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 10 May 2016 08:23:58 -0400 Subject: [PATCH 0176/1644] Remove unused class and member functions --- redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h | 6 ------ redhawk/src/control/sdr/dommgr/applicationSupport.cpp | 5 ----- redhawk/src/control/sdr/dommgr/applicationSupport.h | 4 ---- 3 files changed, 15 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h index 852243aea..f2924fcf3 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h @@ -144,12 +144,6 @@ public ossie::DeviceLookup { public: - struct componentReservation { - std::string id; - float reservation; - }; - std::vector componentReservations; - typedef std::map DeviceAssignmentMap; createHelper (const ApplicationFactory_impl& appFact, diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp index 5b2b623c1..e738d2966 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp @@ -443,11 +443,6 @@ void SoftpkgInfo::getImplementations(ImplementationInfo::List& res) std::copy(_implementations.begin(), _implementations.end(), std::back_inserter(res)); } -const ImplementationInfo* SoftpkgInfo::getSelectedImplementation() const -{ - return _selectedImplementation; -} - const UsesDeviceInfo* SoftpkgInfo::getUsesDeviceById(const std::string& id) const { const UsesDeviceInfo* uses = UsesDeviceContext::getUsesDeviceById(id); diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.h b/redhawk/src/control/sdr/dommgr/applicationSupport.h index c6bc757c6..f30174209 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.h +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.h @@ -184,10 +184,6 @@ namespace ossie void addImplementation(ImplementationInfo* impl); void getImplementations(ImplementationInfo::List& res); - const ImplementationInfo* getSelectedImplementation() const; - //void setSelectedImplementation(ImplementationInfo* implementation); - //void clearSelectedImplementation(); - virtual const UsesDeviceInfo* getUsesDeviceById(const std::string& id) const; static SoftpkgInfo* buildSoftpkgInfo (CF::FileManager_ptr fileMgr, const char* spdFileName); From 10cafb3a96a4edfc64d0bc63d2d35aae5cc1e192 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 10 May 2016 09:30:22 -0400 Subject: [PATCH 0177/1644] Remove last vestiges of implementation selection from ComponentInfo --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 42 ++++++++++------- .../sdr/dommgr/ApplicationFactory_impl.h | 4 +- redhawk/src/control/sdr/dommgr/Deployment.cpp | 45 ++++++++++++++++--- redhawk/src/control/sdr/dommgr/Deployment.h | 11 +++-- .../control/sdr/dommgr/applicationSupport.cpp | 29 +----------- .../control/sdr/dommgr/applicationSupport.h | 1 - 6 files changed, 78 insertions(+), 54 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 6d242b981..99f495774 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -694,7 +694,7 @@ void createHelper::assignRemainingComponentsToDevices(const std::string &appIden componentIter++) { boost::shared_ptr assignedDevice; - for (std::vector::iterator ii = _deployments.begin(); ii != _deployments.end(); ++ii) { + for (DeploymentList::iterator ii = _deployments.begin(); ii != _deployments.end(); ++ii) { if ((*ii)->getComponent() == (*componentIter)) { assignedDevice = (*ii)->getAssignedDevice(); break; @@ -1029,7 +1029,7 @@ void createHelper::_getComponentsToPlace( component->getInstantiationIdentifier()); boost::shared_ptr assignedDevice; - for (std::vector::iterator ii = _deployments.begin(); ii != _deployments.end(); ++ii) { + for (DeploymentList::iterator ii = _deployments.begin(); ii != _deployments.end(); ++ii) { if ((*ii)->getComponent() == component) { assignedDevice = (*ii)->getAssignedDevice(); break; @@ -2258,6 +2258,17 @@ ossie::ComponentInfo* createHelper::findComponentByInstantiationId(const std::st return 0; } +ossie::ComponentDeployment* createHelper::findComponentDeployment(const std::string& instantiationId) +{ + for (DeploymentList::iterator deployment = _deployments.begin(); deployment != _deployments.end(); ++deployment) { + if (instantiationId == (*deployment)->getComponent()->getInstantiationIdentifier()) { + return (*deployment); + } + } + + return 0; +} + /* Given a waveform/application name, return a unique waveform naming context * - Returns a unique waveform naming context * THIS FUNCTION IS NOT THREAD SAFE @@ -2599,14 +2610,15 @@ void createHelper::attemptComponentExecution (CF::ApplicationRegistrar_ptr regis LOG_TRACE(ApplicationFactory_impl, " exec param " << prop->getId() << " " << prop->getValue().toString()); } - // get Options list - CF::Properties cop = component->getOptions(); - for (unsigned int i = 0; i < cop.length(); ++i) { - LOG_TRACE(ApplicationFactory_impl, " RESOURCE OPTION: " << cop[i].id << " " << ossie::any_to_string(cop[i].value)) + // Get options list + redhawk::PropertyMap options = deployment->getOptions(); + for (redhawk::PropertyMap::iterator opt = options.begin(); opt != options.end(); ++opt) { + LOG_TRACE(ApplicationFactory_impl, " RESOURCE OPTION: " << opt->getId() + << " " << opt->getValue().toString()); } // call 'execute' on the ExecutableDevice to execute the component - tempPid = execdev->executeLinked(entryPoint.c_str(), cop, execParameters, dep_seq); + tempPid = execdev->executeLinked(entryPoint.c_str(), options, execParameters, dep_seq); } catch( CF::InvalidFileName& _ex ) { std::string added_message = this->createVersionMismatchMessage(component_version); ostringstream eout; @@ -3217,8 +3229,8 @@ createHelper::~createHelper() delete (*comp); } _requiredComponents.clear(); - for (std::vector::iterator ii = _deployments.begin(); ii != _deployments.end(); ++ii) { - delete (*ii); + for (DeploymentList::iterator depl = _deployments.begin(); depl != _deployments.end(); ++depl) { + delete (*depl); } _deployments.clear(); } @@ -3274,13 +3286,13 @@ CF::Device_ptr createHelper::lookupDeviceThatLoadedComponentInstantiationId(cons { LOG_TRACE(ApplicationFactory_impl, "[DeviceLookup] Lookup device that loaded component " << componentId); - ossie::ComponentInfo* component = findComponentByInstantiationId(componentId); - if (!component) { + ossie::ComponentDeployment* deployment = findComponentDeployment(componentId); + if (!deployment) { LOG_WARN(ApplicationFactory_impl, "[DeviceLookup] Component not found"); return CF::Device::_nil(); } - boost::shared_ptr device = component->getAssignedDevice(); + boost::shared_ptr device = deployment->getAssignedDevice(); if (!device) { LOG_WARN(ApplicationFactory_impl, "[DeviceLookup] Component not assigned to device"); return CF::Device::_nil(); @@ -3296,14 +3308,14 @@ CF::Device_ptr createHelper::lookupDeviceThatLoadedComponentInstantiationId(cons CF::Device_ptr createHelper::lookupDeviceUsedByComponentInstantiationId(const std::string& componentId, const std::string& usesId) { LOG_TRACE(ApplicationFactory_impl, "[DeviceLookup] Lookup device used by component " << componentId); - ossie::ComponentInfo* component = findComponentByInstantiationId(componentId.c_str()); - if (!component) { + ossie::ComponentDeployment* deployment = findComponentDeployment(componentId.c_str()); + if (!deployment) { LOG_WARN(ApplicationFactory_impl, "[DeviceLookup] Component not found"); return CF::Device::_nil(); } LOG_TRACE(ApplicationFactory_impl, "[DeviceLookup] Uses id " << usesId); - const ossie::UsesDeviceInfo* usesdevice = component->getUsesDeviceById(usesId); + const ossie::UsesDeviceInfo* usesdevice = deployment->getUsesDeviceById(usesId); if (!usesdevice) { LOG_WARN(ApplicationFactory_impl, "[DeviceLookup] UsesDevice not found"); return CF::Device::_nil(); diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h index f2924fcf3..595af3c22 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h @@ -204,7 +204,8 @@ public ossie::DeviceLookup ossie::ApplicationInfo _appInfo; - std::vector _deployments; + typedef std::vector DeploymentList; + DeploymentList _deployments; // createHelper helper methods ossie::ComponentInfo* getAssemblyController(); @@ -284,6 +285,7 @@ public ossie::DeviceLookup CF::Device_ptr find_device_from_id(const char*); const ossie::DeviceNode& find_device_node_from_id(const char*) throw(std::exception); ossie::ComponentInfo* findComponentByInstantiationId(const std::string& identifier); + ossie::ComponentDeployment* findComponentDeployment(const std::string& instantiationId); // Cleanup - used when create fails/doesn't succeed for some reason bool _isComplete; diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index 2218ccf46..c4ad5246d 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -25,9 +25,9 @@ using namespace ossie; namespace fs = boost::filesystem; -SoftpkgDeployment::SoftpkgDeployment(SoftpkgInfo* softpkg, ImplementationInfo* impl) : +SoftpkgDeployment::SoftpkgDeployment(SoftpkgInfo* softpkg, ImplementationInfo* implementation) : softpkg(softpkg), - impl(impl) + implementation(implementation) { } @@ -45,7 +45,7 @@ SoftpkgInfo* SoftpkgDeployment::getSoftpkg() ImplementationInfo* SoftpkgDeployment::getImplementation() { - return impl; + return implementation; } void SoftpkgDeployment::addDependency(SoftpkgDeployment* dependency) @@ -71,7 +71,7 @@ std::vector SoftpkgDeployment::getDependencyLocalFiles() std::string SoftpkgDeployment::getLocalFile() { - fs::path codeLocalFile = fs::path(impl->getLocalFileName()); + fs::path codeLocalFile = fs::path(implementation->getLocalFileName()); if (!codeLocalFile.has_root_directory()) { // Path is relative to SPD file location fs::path base_dir = fs::path(softpkg->getSpdFileName()).parent_path(); @@ -85,9 +85,9 @@ std::string SoftpkgDeployment::getLocalFile() return codeLocalFile.string(); } -ComponentDeployment::ComponentDeployment(ComponentInfo* component, ImplementationInfo* impl, +ComponentDeployment::ComponentDeployment(ComponentInfo* component, ImplementationInfo* implementation, const boost::shared_ptr& device) : - SoftpkgDeployment(component, impl), + SoftpkgDeployment(component, implementation), assignedDevice(device) { } @@ -104,7 +104,7 @@ boost::shared_ptr ComponentDeployment::getAssignedDevice() std::string ComponentDeployment::getEntryPoint() { - std::string entryPoint = impl->getEntryPoint(); + std::string entryPoint = implementation->getEntryPoint(); if (!entryPoint.empty()) { fs::path entryPointPath = fs::path(entryPoint); if (!entryPointPath.has_root_directory()) { @@ -116,3 +116,34 @@ std::string ComponentDeployment::getEntryPoint() } return entryPoint; } + +redhawk::PropertyMap ComponentDeployment::getOptions() +{ + // Get the options from the softpkg + redhawk::PropertyMap options(getComponent()->getOptions()); + + // Get the PRIORITY and STACK_SIZE from the SPD (if available) + if (implementation->hasStackSize()) { + // 3.1.3.3.3.3.6 + // The specification says it's supposed to be an unsigned long, but the + // parser is set to unsigned long long + options["STACK_SIZE"] = implementation->getStackSize(); + } + if (implementation->hasPriority()) { + // 3.1.3.3.3.3.7 + // The specification says it's supposed to be an unsigned long, but the + // parser is set to unsigned long long + options["PRIORITY"] = implementation->getPriority(); + } + + return options; +} + +const UsesDeviceInfo* ComponentDeployment::getUsesDeviceById(const std::string& usesId) +{ + const UsesDeviceInfo* usesDevice = getComponent()->getUsesDeviceById(usesId); + if (!usesDevice) { + usesDevice = implementation->getUsesDeviceById(usesId); + } + return usesDevice; +} diff --git a/redhawk/src/control/sdr/dommgr/Deployment.h b/redhawk/src/control/sdr/dommgr/Deployment.h index 84ef45d75..c2d689abf 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.h +++ b/redhawk/src/control/sdr/dommgr/Deployment.h @@ -26,6 +26,7 @@ #include +#include #include "applicationSupport.h" namespace ossie { @@ -34,7 +35,7 @@ namespace ossie { public: typedef std::vector DeploymentList; - SoftpkgDeployment(SoftpkgInfo* softpkg, ImplementationInfo* impl); + SoftpkgDeployment(SoftpkgInfo* softpkg, ImplementationInfo* implementation); ~SoftpkgDeployment(); SoftpkgInfo* getSoftpkg(); @@ -49,22 +50,26 @@ namespace ossie { protected: SoftpkgInfo* softpkg; - ImplementationInfo* impl; + ImplementationInfo* implementation; DeploymentList dependencies; }; class ComponentDeployment : public SoftpkgDeployment { public: - ComponentDeployment(ComponentInfo* component, ImplementationInfo* impl, + ComponentDeployment(ComponentInfo* component, ImplementationInfo* implementation, const boost::shared_ptr& device); ComponentInfo* getComponent(); std::string getEntryPoint(); + redhawk::PropertyMap getOptions(); + boost::shared_ptr getAssignedDevice(); + const ossie::UsesDeviceInfo* getUsesDeviceById(const std::string& usesId); + protected: boost::shared_ptr assignedDevice; }; diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp index e738d2966..144b0a888 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp @@ -357,8 +357,7 @@ bool ImplementationInfo::checkProcessorAndOs(const Properties& _prf) const PREPARE_CF_LOGGING(SoftpkgInfo); SoftpkgInfo::SoftpkgInfo(const std::string& spdFileName): - _spdFileName(spdFileName), - _selectedImplementation(0) + _spdFileName(spdFileName) { } @@ -445,16 +444,7 @@ void SoftpkgInfo::getImplementations(ImplementationInfo::List& res) const UsesDeviceInfo* SoftpkgInfo::getUsesDeviceById(const std::string& id) const { - const UsesDeviceInfo* uses = UsesDeviceContext::getUsesDeviceById(id); - if (uses) { - return uses; - } - - if (_selectedImplementation) { - return _selectedImplementation->getUsesDeviceById(id); - } - - return 0; + return UsesDeviceContext::getUsesDeviceById(id); } //////////////////////////////////////////////////// @@ -947,21 +937,6 @@ CF::Properties ComponentInfo::getConstructProperties() CF::Properties ComponentInfo::getOptions() { - // Get the PRIORITY and STACK_SIZE from the SPD (if available) - // unfortunately this can't happen until an implementation has been chosen - if (_selectedImplementation) { - if (_selectedImplementation->hasStackSize()) { - options.length(options.length()+1); - options[options.length()-1].id = CORBA::string_dup("STACK_SIZE"); // 3.1.3.3.3.3.6 - options[options.length()-1].value <<= _selectedImplementation->getStackSize(); // The specification says it's supposed to be an unsigned long, but the parser is set to unsigned long long - } - if (_selectedImplementation->hasPriority()) { - options.length(options.length()+1); - options[options.length()-1].id = CORBA::string_dup("PRIORITY"); // 3.1.3.3.3.3.7 - options[options.length()-1].value <<= _selectedImplementation->getPriority(); // The specification says it's supposed to be an unsigned long, but the parser is set to unsigned long long - } - } - // Add affinity settings under AFFINITY property directory CF::Properties affinity_options; for ( uint32_t i=0; i < affinityOptions.length(); i++ ) { diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.h b/redhawk/src/control/sdr/dommgr/applicationSupport.h index f30174209..958ceb415 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.h +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.h @@ -197,7 +197,6 @@ namespace ossie std::string _name; // Component name from SPD File ImplementationInfo::List _implementations; - ImplementationInfo* _selectedImplementation; // Implementation selected to run on assigned device. }; /* Base class to contain data for components From 17f9d7e262b5ce35fa9ddd7db9dd017916af17a2 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 10 May 2016 10:13:51 -0400 Subject: [PATCH 0178/1644] Make ossie::getNonNilProperties const-safe and use PropertyMap --- redhawk/src/base/framework/prop_helpers.cpp | 21 ++++++++----------- redhawk/src/base/include/ossie/prop_helpers.h | 4 ++-- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/redhawk/src/base/framework/prop_helpers.cpp b/redhawk/src/base/framework/prop_helpers.cpp index f81acb080..719958f0b 100644 --- a/redhawk/src/base/framework/prop_helpers.cpp +++ b/redhawk/src/base/framework/prop_helpers.cpp @@ -30,7 +30,7 @@ #include #include #include -#include //testing +#include using namespace ossie; @@ -1094,23 +1094,20 @@ CORBA::TypeCode_ptr ossie::getTypeCode(CORBA::TCKind kind, std::string structNam } -CF::Properties ossie::getNonNilProperties(CF::Properties& originalProperties) +CF::Properties ossie::getNonNilProperties(const CF::Properties& originalProperties) { - CF::Properties nonNilProperties; - CORBA::TypeCode_var typeProp; - - for (unsigned int i = 0; i < originalProperties.length(); i++) { - CF::DataType prop = originalProperties[i]; - typeProp = prop.value.type(); - if (typeProp->kind() != CORBA::tk_null) { - nonNilProperties.length(nonNilProperties.length() + 1); - nonNilProperties[nonNilProperties.length()-1] = prop; + redhawk::PropertyMap nonNilProperties; + const redhawk::PropertyMap& properties = redhawk::PropertyMap::cast(originalProperties); + + for (redhawk::PropertyMap::const_iterator prop = properties.begin(); prop != properties.end(); ++prop) { + if (!prop->getValue().isNil()) { + nonNilProperties.push_back(*prop); } } return nonNilProperties; } -CF::Properties ossie::getNonNilConfigureProperties(CF::Properties& originalProperties) +CF::Properties ossie::getNonNilConfigureProperties(const CF::Properties& originalProperties) { return getNonNilProperties(originalProperties); } diff --git a/redhawk/src/base/include/ossie/prop_helpers.h b/redhawk/src/base/include/ossie/prop_helpers.h index 6e60d4555..259afe319 100644 --- a/redhawk/src/base/include/ossie/prop_helpers.h +++ b/redhawk/src/base/include/ossie/prop_helpers.h @@ -117,8 +117,8 @@ namespace ossie CORBA::TCKind getTypeKind(std::string type); CORBA::TypeCode_ptr getTypeCode(std::string type); CORBA::TypeCode_ptr getTypeCode(CORBA::TCKind kind, std::string structName); - CF::Properties getNonNilProperties(CF::Properties& originalProperties); - CF::Properties getNonNilConfigureProperties(CF::Properties& originalProperties); + CF::Properties getNonNilProperties(const CF::Properties& originalProperties); + CF::Properties getNonNilConfigureProperties(const CF::Properties& originalProperties); } #endif From c7acb46d9ab6242592b0f64770dc7227fa46ad9a Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 10 May 2016 10:25:49 -0400 Subject: [PATCH 0179/1644] Add const-correctness for parser Properties::getProperty() --- redhawk/src/control/include/ossie/Properties.h | 2 +- redhawk/src/control/parser/Properties.cpp | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/redhawk/src/control/include/ossie/Properties.h b/redhawk/src/control/include/ossie/Properties.h index d50f6491c..6da7d8b5b 100644 --- a/redhawk/src/control/include/ossie/Properties.h +++ b/redhawk/src/control/include/ossie/Properties.h @@ -411,7 +411,7 @@ namespace ossie { const std::vector& getProperties() const; - const Property* getProperty(const std::string& id); + const Property* getProperty(const std::string& id) const; const std::vector& getConfigureProperties() const; diff --git a/redhawk/src/control/parser/Properties.cpp b/redhawk/src/control/parser/Properties.cpp index 98ca5eef3..175abdc0b 100644 --- a/redhawk/src/control/parser/Properties.cpp +++ b/redhawk/src/control/parser/Properties.cpp @@ -169,13 +169,13 @@ void Properties::join(ossie::Properties& props) throw (ossie::parser_error) { void Properties::override(const ossie::ComponentPropertyList & values) { - for ( ossie::ComponentPropertyList::const_iterator iter = values.begin(); iter != values.end(); ++iter) { - const ComponentProperty* new_value = &(*iter); - Property* property = const_cast(getProperty(new_value->getID())); + for (ossie::ComponentPropertyList::const_iterator iter = values.begin(); iter != values.end(); ++iter) { + const ComponentProperty* new_value = &(*iter); + const Property* property = const_cast(this)->getProperty(new_value->getID()); if (!property) { LOG_TRACE(Properties, "Skipping override of non-existent property " << new_value->getID()); } else { - property->override(new_value); + const_cast(property)->override(new_value); } } } @@ -186,7 +186,7 @@ const std::vector& Properties::getProperties() const return _prf->_allProperties; } -const Property* Properties::getProperty(const std::string& id) +const Property* Properties::getProperty(const std::string& id) const { assert(_prf.get() != 0); std::map::iterator p = _prf->_properties.find(id); From 8f40ddfe8bbd3c6dde99fc0b269aedac91b5d462 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 10 May 2016 11:07:42 -0400 Subject: [PATCH 0180/1644] Move tracking of CORBA pointer into the ComponentDeployment class; make ComponentInfo more const-safe --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 282 ++++++------------ redhawk/src/control/sdr/dommgr/Deployment.cpp | 10 + redhawk/src/control/sdr/dommgr/Deployment.h | 4 + .../control/sdr/dommgr/applicationSupport.cpp | 62 ++-- .../control/sdr/dommgr/applicationSupport.h | 40 ++- 5 files changed, 154 insertions(+), 244 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 99f495774..6ece5ef01 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -981,7 +981,7 @@ void createHelper::_placeHostCollocation(const SoftwareAssembly::HostCollocation delete deployment; continue; } - collocAssignedDevs[i].deviceAssignment.componentId = CORBA::string_dup((*comp)->getIdentifier()); + collocAssignedDevs[i].deviceAssignment.componentId = (*comp)->getIdentifier().c_str(); _deployments.push_back(deployment); } @@ -1078,7 +1078,7 @@ void createHelper::_handleUsesDevices(const std::string& appName) throw CF::ApplicationFactory::CreateApplicationError(CF::CF_ENOSPC, eout.str().c_str()); } for (DeviceAssignmentList::iterator dev=assignedDevices.begin(); dev!=assignedDevices.end(); dev++) { - dev->deviceAssignment.componentId = getAssemblyController()->getIdentifier(); + dev->deviceAssignment.componentId = getAssemblyController()->getIdentifier().c_str(); } _appUsedDevs.insert(_appUsedDevs.end(), assignedDevices.begin(), assignedDevices.end()); } @@ -1437,7 +1437,9 @@ throw (CORBA::SystemException, // Check that the assembly controller is valid CF::Resource_var assemblyController; if (assemblyControllerComponent) { - assemblyController = assemblyControllerComponent->getResourcePtr(); + const std::string& assemblyControllerId = assemblyControllerComponent->getInstantiationIdentifier(); + ossie::ComponentDeployment* deployment = findComponentDeployment(assemblyControllerId); + assemblyController = deployment->getResourcePtr(); } _checkAssemblyController(assemblyController, assemblyControllerComponent); @@ -1705,7 +1707,7 @@ ossie::ComponentDeployment* createHelper::allocateComponent(ossie::ComponentInfo rotateDeviceList(_executableDevices, deviceId); ossie::DeviceAssignmentInfo dai; - dai.deviceAssignment.componentId = CORBA::string_dup(component->getIdentifier()); + dai.deviceAssignment.componentId = component->getIdentifier().c_str(); dai.deviceAssignment.assignedDeviceId = deviceId.c_str(); dai.device = CF::Device::_duplicate(node.device); appAssignedDevs.push_back(dai); @@ -1940,7 +1942,7 @@ ossie::AllocationResult createHelper::allocateComponentToDevice( ossie::Componen " for component " << component->getIdentifier()); CF::DeviceAssignmentSequence badDAS; badDAS.length(1); - badDAS[0].componentId = CORBA::string_dup(component->getIdentifier()); + badDAS[0].componentId = component->getIdentifier().c_str(); badDAS[0].assignedDeviceId = assignedDeviceId.c_str(); throw CF::ApplicationFactory::CreateApplicationRequestError(badDAS); } @@ -2164,7 +2166,7 @@ void createHelper::getRequiredComponents() newComponent->setNamingService(instance.isNamingService()); - if (newComponent->getNamingService()) { + if (newComponent->isNamingService()) { ostringstream nameBinding; nameBinding << instance.getFindByNamingServiceName(); #if UNIQUIFY_NAME_BINDING @@ -2387,7 +2389,7 @@ void createHelper::loadAndExecuteComponents(CF::ApplicationRegistrar_ptr _appReg // Let the application know to expect the given component _application->addComponent(component->getIdentifier(), component->getSpdFileName()); _application->setComponentImplementation(component->getIdentifier(), implementation->getId()); - if (component->getNamingService()) { + if (component->isNamingService()) { std::string lookupName = _appFact._domainName + "/" + _waveformContextName + "/" + component->getNamingServiceName() ; _application->setComponentNamingContext(component->getIdentifier(), lookupName); } @@ -2797,8 +2799,9 @@ void createHelper::initializeComponents() CF::Components_var app_registeredComponents = _application->registeredComponents(); - for (unsigned int rc_idx = 0; rc_idx < _requiredComponents.size (); rc_idx++) { - ossie::ComponentInfo* component = _requiredComponents[rc_idx]; + for (unsigned int rc_idx = 0; rc_idx < _deployments.size (); rc_idx++) { + ossie::ComponentDeployment* deployment = _deployments[rc_idx]; + ossie::ComponentInfo* component = deployment->getComponent(); // If the component is non-SCA compliant then we don't expect anything beyond this if (!component->isScaCompliant()) { @@ -2832,7 +2835,7 @@ void createHelper::initializeComponents() throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EIO, eout.str().c_str()); } - component->setResourcePtr(resource); + deployment->setResourcePtr(resource); int initAttempts=3; while ( initAttempts > 0 ) { @@ -2959,28 +2962,39 @@ void createHelper::initializeComponents() void createHelper::configureComponents() { - for (unsigned int rc_idx = 0; rc_idx < _requiredComponents.size (); rc_idx++) { - ossie::ComponentInfo* component = _requiredComponents[rc_idx]; - - if (component->isAssemblyController ()) { - continue; - } - - // If the component is non-SCA compliant then we don't expect anything beyond this + DeploymentList configure_list; + ossie::ComponentDeployment* ac_deployment = 0; + for (DeploymentList::iterator depl = _deployments.begin(); depl != _deployments.end(); ++depl) { + const ossie::ComponentInfo* component = (*depl)->getComponent(); if (!component->isScaCompliant()) { - LOG_TRACE(ApplicationFactory_impl, "Skipping configure; Component is non SCA-compliant, continuing to next component"); - continue; - } - - if (!component->isResource ()) { - LOG_TRACE(ApplicationFactory_impl, "Skipping configure; Component in not resource, continuing to next component"); - continue; + // If the component is non-SCA compliant then we don't expect anything beyond this + LOG_TRACE(ApplicationFactory_impl, "Skipping configure of non SCA-compliant component " + << component->getIdentifier()); + } else if (!component->isResource()) { + LOG_TRACE(ApplicationFactory_impl, "Skipping configure of non-resource component " + << component->getIdentifier()); + } else { + // The component is configurable; if it's the assembly controller, + // save it for the end + if (component->isAssemblyController()) { + ac_deployment = *depl; + } else { + configure_list.push_back(*depl); + } } + } + // Configure the assembly controller last, if it's configurable + if (ac_deployment) { + configure_list.push_back(ac_deployment); + } + for (DeploymentList::iterator depl = configure_list.begin(); depl != configure_list.end(); ++depl) { + const ossie::ComponentInfo* component = (*depl)->getComponent(); + // Assuming 1 instantiation for each componentplacement - if (component->getNamingService ()) { + if (component->isNamingService()) { - CF::Resource_var _rsc = component->getResourcePtr(); + CF::Resource_var _rsc = (*depl)->getResourcePtr(); if (CORBA::is_nil(_rsc)) { LOG_ERROR(ApplicationFactory_impl, "Could not get component reference"); @@ -2991,174 +3005,70 @@ void createHelper::configureComponents() eout << "Could not get component reference for component: '" << component->getName() << "' with component id: '" << component->getIdentifier() << " assigned to device: '" - << component->getAssignedDeviceId()<<"'"; + << (*depl)->getAssignedDevice()->label<<"'"; eout << " in waveform '" << _waveformContextName<<"';"; eout << " error occurred near line:" <<__LINE__ << " in file:" << __FILE__ << ";"; throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EIO, eout.str().c_str()); } - if (component->isResource () && component->isConfigurable ()) { - CF::Properties partialStruct = component->containsPartialStructConfig(); - bool partialWarn = false; - if (partialStruct.length() != 0) { - ostringstream eout; - eout << "Component " << component->getIdentifier() << " contains structure: "<< partialStruct[0].id <<" with a mix of defined and nil values. The behavior for the component is undefined"; - LOG_WARN(ApplicationFactory_impl, eout.str()); - partialWarn = true; - } - try { - // try to configure the component - _rsc->configure (component->getNonNilConfigureProperties()); - } catch(CF::PropertySet::InvalidConfiguration& e) { - ostringstream eout; - eout << "Failed to 'configure' component: '"; - eout << component->getName() << "' with component id: '" << component->getIdentifier() << " assigned to device: '"<getAssignedDeviceId() << "' "; - eout << " in waveform '"<< _waveformContextName<<"';"; - eout << "InvalidConfiguration with this info: <"; - eout << e.msg << "> for these invalid properties: "; - for (unsigned int propIdx = 0; propIdx < e.invalidProperties.length(); propIdx++){ - eout << "(" << e.invalidProperties[propIdx].id << ","; - eout << ossie::any_to_string(e.invalidProperties[propIdx].value) << ")"; - } - if (partialWarn) { - eout << ". Note that this component contains a property with a mix of defined and nil values."; - } - eout << " error occurred near line:" <<__LINE__ << " in file:" << __FILE__ << ";"; - LOG_ERROR(ApplicationFactory_impl, eout.str()); - throw CF::ApplicationFactory::InvalidInitConfiguration(e.invalidProperties); - } catch(CF::PropertySet::PartialConfiguration& e) { - ostringstream eout; - eout << "Failed to instantiate component: '"; - eout << component->getName() << "' with component id: '" << component->getIdentifier() << " assigned to device: '"<getAssignedDeviceId() << "' "; - eout << " in waveform '"<< _waveformContextName<<"';"; - eout << "Failed to 'configure' component; PartialConfiguration for these invalid properties: "; - for (unsigned int propIdx = 0; propIdx < e.invalidProperties.length(); propIdx++){ - eout << "(" << e.invalidProperties[propIdx].id << ","; - eout << ossie::any_to_string(e.invalidProperties[propIdx].value) << ")"; - } - if (partialWarn) { - eout << ". Note that this component contains a property with a mix of defined and nil values."; - } - eout << " error occurred near line:" <<__LINE__ << " in file:" << __FILE__ << ";"; - LOG_ERROR(ApplicationFactory_impl, eout.str()); - throw CF::ApplicationFactory::InvalidInitConfiguration(e.invalidProperties); - } catch( ... ) { - ostringstream eout; - std::string component_version(component->spd.getSoftPkgType()); - std::string added_message = this->createVersionMismatchMessage(component_version); - eout << added_message; - eout << "Failed to instantiate component: '"; - eout << component->getName() << "' with component id: '" << component->getIdentifier() << " assigned to device: '"<getAssignedDeviceId() << "' "; - eout << " in waveform '"<< _waveformContextName<<"';"; - eout << "'configure' failed with Unknown Exception"; - if (partialWarn) { - eout << ". Note that this component contains a property with a mix of defined and nil values."; - } - eout << " error occurred near line:" <<__LINE__ << " in file:" << __FILE__ << ";"; - LOG_ERROR(ApplicationFactory_impl, eout.str()); - throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EINVAL, eout.str().c_str()); - } + CF::Properties partialStruct = component->containsPartialStructConfig(); + bool partialWarn = false; + if (partialStruct.length() != 0) { + ostringstream eout; + eout << "Component " << component->getIdentifier() << " contains structure"<< partialStruct[0].id <<" with a mix of defined and nil values. The behavior for the component is undefined"; + LOG_WARN(ApplicationFactory_impl, eout.str()); + partialWarn = true; } - } - } - - // configure the assembly controller last - for (unsigned int rc_idx = 0; rc_idx < _requiredComponents.size (); rc_idx++) { - ossie::ComponentInfo* component = _requiredComponents[rc_idx]; - - if (!component->isAssemblyController ()) { - continue; - } - - // If the component is non-SCA compliant then we don't expect anything beyond this - if (!component->isScaCompliant()) { - LOG_TRACE(ApplicationFactory_impl, "Skipping configure; Assembly controller is non SCA-compliant"); - break; - } - - if (!component->isResource ()) { - LOG_TRACE(ApplicationFactory_impl, "Skipping configure; Assembly controller is not resource"); - break; - } - - // Assuming 1 instantiation for each componentplacement - if (component->getNamingService ()) { - - CF::Resource_var _rsc = component->getResourcePtr(); - - if (CORBA::is_nil(_rsc)) { - LOG_ERROR(ApplicationFactory_impl, "Could not get Assembly Controller reference"); + try { + // try to configure the component + _rsc->configure (component->getNonNilConfigureProperties()); + } catch(CF::PropertySet::InvalidConfiguration& e) { ostringstream eout; - eout << "Could not get reference for Assembly Controller: '" - << component->getName() << "' with component id: '" - << component->getIdentifier() << " assigned to device: '" - << component->getAssignedDeviceId()<<"'"; - eout << " in waveform '" << _waveformContextName<<"';"; + eout << "Failed to 'configure' component: '"; + eout << component->getName() << "' with component id: '" << component->getIdentifier() << " assigned to device: '"<<(*depl)->getAssignedDevice()->label << "' "; + eout << " in waveform '"<< _waveformContextName<<"';"; + eout << "InvalidConfiguration with this info: <"; + eout << e.msg << "> for these invalid properties: "; + for (unsigned int propIdx = 0; propIdx < e.invalidProperties.length(); propIdx++){ + eout << "(" << e.invalidProperties[propIdx].id << ","; + eout << ossie::any_to_string(e.invalidProperties[propIdx].value) << ")"; + } + if (partialWarn) { + eout << ". Note that this component contains a property with a mix of defined and nil values."; + } eout << " error occurred near line:" <<__LINE__ << " in file:" << __FILE__ << ";"; - throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EIO, eout.str().c_str()); - } - - if (component->isResource () && component->isConfigurable ()) { - CF::Properties partialStruct = component->containsPartialStructConfig(); - bool partialWarn = false; - if (partialStruct.length() != 0) { - ostringstream eout; - eout << "Component " << component->getIdentifier() << " contains structure"<< partialStruct[0].id <<" with a mix of defined and nil values. The behavior for the component is undefined"; - LOG_WARN(ApplicationFactory_impl, eout.str()); - partialWarn = true; + LOG_ERROR(ApplicationFactory_impl, eout.str()); + throw CF::ApplicationFactory::InvalidInitConfiguration(e.invalidProperties); + } catch(CF::PropertySet::PartialConfiguration& e) { + ostringstream eout; + eout << "Failed to instantiate component: '"; + eout << component->getName() << "' with component id: '" << component->getIdentifier() << " assigned to device: '"<<(*depl)->getAssignedDevice()->label << "' "; + eout << " in waveform '"<< _waveformContextName<<"';"; + eout << "Failed to 'configure' component; PartialConfiguration for these invalid properties: "; + for (unsigned int propIdx = 0; propIdx < e.invalidProperties.length(); propIdx++){ + eout << "(" << e.invalidProperties[propIdx].id << ","; + eout << ossie::any_to_string(e.invalidProperties[propIdx].value) << ")"; } - try { - // try to configure the component - _rsc->configure (component->getNonNilConfigureProperties()); - } catch(CF::PropertySet::InvalidConfiguration& e) { - ostringstream eout; - eout << "Failed to 'configure' Assembly Controller: '"; - eout << component->getName() << "' with component id: '" << component->getIdentifier() << " assigned to device: '"<getAssignedDeviceId() << "' "; - eout << " in waveform '"<< _waveformContextName<<"';"; - eout << "InvalidConfiguration with this info: <"; - eout << e.msg << "> for these invalid properties: "; - for (unsigned int propIdx = 0; propIdx < e.invalidProperties.length(); propIdx++){ - eout << "(" << e.invalidProperties[propIdx].id << ","; - eout << ossie::any_to_string(e.invalidProperties[propIdx].value) << ")"; - } - if (partialWarn) { - eout << ". Note that this component contains a property with a mix of defined and nil values."; - } - eout << " error occurred near line:" <<__LINE__ << " in file:" << __FILE__ << ";"; - LOG_ERROR(ApplicationFactory_impl, eout.str()); - throw CF::ApplicationFactory::InvalidInitConfiguration(e.invalidProperties); - } catch(CF::PropertySet::PartialConfiguration& e) { - ostringstream eout; - eout << "Failed to instantiate Assembly Controller: '"; - eout << component->getName() << "' with component id: '" << component->getIdentifier() << " assigned to device: '"<getAssignedDeviceId() << "' "; - eout << " in waveform '"<< _waveformContextName<<"';"; - eout << "Failed to 'configure' Assembly Controller; PartialConfiguration for these invalid properties: "; - for (unsigned int propIdx = 0; propIdx < e.invalidProperties.length(); propIdx++){ - eout << "(" << e.invalidProperties[propIdx].id << ","; - eout << ossie::any_to_string(e.invalidProperties[propIdx].value) << ")"; - } - if (partialWarn) { - eout << ". Note that this component contains a property with a mix of defined and nil values."; - } - eout << " error occurred near line:" <<__LINE__ << " in file:" << __FILE__ << ";"; - LOG_ERROR(ApplicationFactory_impl, eout.str()); - throw CF::ApplicationFactory::InvalidInitConfiguration(e.invalidProperties); - } catch( ... ) { - ostringstream eout; - eout << "Failed to instantiate Assembly Controller: '"; - eout << component->getName() << "' with component id: '" << component->getIdentifier() << " assigned to device: '"<getAssignedDeviceId() << "' "; - eout << " in waveform '"<< _waveformContextName<<"';"; - eout << "'configure' failed with Unknown Exception"; - if (partialWarn) { - eout << ". Note that this component contains a property with a mix of defined and nil values."; - } - eout << " error occurred near line:" <<__LINE__ << " in file:" << __FILE__ << ";"; - LOG_ERROR(ApplicationFactory_impl, eout.str()); - throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EINVAL, eout.str().c_str()); + if (partialWarn) { + eout << ". Note that this component contains a property with a mix of defined and nil values."; + } + eout << " error occurred near line:" <<__LINE__ << " in file:" << __FILE__ << ";"; + LOG_ERROR(ApplicationFactory_impl, eout.str()); + throw CF::ApplicationFactory::InvalidInitConfiguration(e.invalidProperties); + } catch( ... ) { + ostringstream eout; + eout << "Failed to instantiate component: '"; + eout << component->getName() << "' with component id: '" << component->getIdentifier() << " assigned to device: '"<getAssignedDevice()->label << "' "; + eout << " in waveform '"<< _waveformContextName<<"';"; + eout << "'configure' failed with Unknown Exception"; + if (partialWarn) { + eout << ". Note that this component contains a property with a mix of defined and nil values."; } + eout << " error occurred near line:" <<__LINE__ << " in file:" << __FILE__ << ";"; + LOG_ERROR(ApplicationFactory_impl, eout.str()); + throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EINVAL, eout.str().c_str()); } } - break; } } @@ -3271,9 +3181,9 @@ void createHelper::_cleanupFailedCreate() */ CF::Resource_ptr createHelper::lookupComponentByInstantiationId(const std::string& identifier) { - ossie::ComponentInfo* component = findComponentByInstantiationId(identifier); - if (component) { - return component->getResourcePtr(); + ossie::ComponentDeployment* deployment = findComponentDeployment(identifier); + if (deployment) { + return deployment->getResourcePtr(); } return CF::Resource::_nil(); diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index c4ad5246d..12e7b2e67 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -147,3 +147,13 @@ const UsesDeviceInfo* ComponentDeployment::getUsesDeviceById(const std::string& } return usesDevice; } + +void ComponentDeployment::setResourcePtr(CF::Resource_ptr resource) +{ + this->resource = CF::Resource::_duplicate(resource); +} + +CF::Resource_ptr ComponentDeployment::getResourcePtr() const +{ + return CF::Resource::_duplicate(resource); +} diff --git a/redhawk/src/control/sdr/dommgr/Deployment.h b/redhawk/src/control/sdr/dommgr/Deployment.h index c2d689abf..a1b1594ea 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.h +++ b/redhawk/src/control/sdr/dommgr/Deployment.h @@ -70,8 +70,12 @@ namespace ossie { const ossie::UsesDeviceInfo* getUsesDeviceById(const std::string& usesId); + void setResourcePtr(CF::Resource_ptr resource); + CF::Resource_ptr getResourcePtr() const; + protected: boost::shared_ptr assignedDevice; + CF::Resource_var resource; }; } diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp index 144b0a888..8f5404e47 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp @@ -373,9 +373,9 @@ const char* SoftpkgInfo::getSpdFileName() return _spdFileName.c_str(); } -const char* SoftpkgInfo::getName() +const std::string& SoftpkgInfo::getName() const { - return _name.c_str(); + return _name; } SoftpkgInfo* SoftpkgInfo::buildSoftpkgInfo(CF::FileManager_ptr fileMgr, const char* spdFileName) @@ -607,7 +607,7 @@ void ComponentInfo::setIdentifier(const char* _identifier, std::string instance_ void ComponentInfo::setNamingService(const bool _isNamingService) { - isNamingService = _isNamingService; + this->_isNamingService = _isNamingService; } void ComponentInfo::setNamingServiceName(const char* _namingServiceName) @@ -729,22 +729,17 @@ void ComponentInfo::process_overrides(CF::Properties* props, const char* id, COR return; } -void ComponentInfo::setResourcePtr(CF::Resource_ptr _rsc) +const std::string& ComponentInfo::getInstantiationIdentifier() const { - rsc = CF::Resource::_duplicate(_rsc); + return instantiationId; } -const char* ComponentInfo::getInstantiationIdentifier() +const std::string& ComponentInfo::getIdentifier() const { - return instantiationId.c_str(); + return identifier; } -const char* ComponentInfo::getIdentifier() -{ - return identifier.c_str(); -} - -boost::shared_ptr ComponentInfo::getAssignedDevice() +const boost::shared_ptr& ComponentInfo::getAssignedDevice() const { return assignedDevice; } @@ -758,42 +753,43 @@ const char* ComponentInfo::getAssignedDeviceId() } } -const bool ComponentInfo::getNamingService() +bool ComponentInfo::isNamingService() const { - return isNamingService; + return _isNamingService; } -const char* ComponentInfo::getUsageName() +const char* ComponentInfo::getUsageName() const { return usageName.c_str(); } -const char* ComponentInfo::getNamingServiceName() +const char* ComponentInfo::getNamingServiceName() const { return namingServiceName.c_str(); } -const std::string ComponentInfo::getNicAssignment() { +const std::string& ComponentInfo::getNicAssignment() const +{ return nicAssignment; }; -const bool ComponentInfo::isResource() +bool ComponentInfo::isResource() const { return scd.isResource(); } -const bool ComponentInfo::isConfigurable() +bool ComponentInfo::isConfigurable() const { return scd.isConfigurable(); } -const bool ComponentInfo::isAssemblyController() +bool ComponentInfo::isAssemblyController() const { return _isAssemblyController; } -const bool ComponentInfo::isScaCompliant() +bool ComponentInfo::isScaCompliant() const { return _isScaCompliant; } @@ -803,11 +799,11 @@ bool ComponentInfo::isAssignedToDevice() const return assignedDevice; } -bool ComponentInfo::checkStruct(CF::Properties &props) +bool ComponentInfo::checkStruct(const CF::Properties &props) const { - redhawk::PropertyMap& tmpProps = redhawk::PropertyMap::cast(props); + const redhawk::PropertyMap& tmpProps = redhawk::PropertyMap::cast(props); int state = 0; // 1 set, -1 nil - for (redhawk::PropertyMap::iterator tmpP = tmpProps.begin(); tmpP != tmpProps.end(); tmpP++) { + for (redhawk::PropertyMap::const_iterator tmpP = tmpProps.begin(); tmpP != tmpProps.end(); tmpP++) { if (tmpProps[ossie::corba::returnString(tmpP->id)].isNil()) { if (state == 0) { state = -1; @@ -829,11 +825,11 @@ bool ComponentInfo::checkStruct(CF::Properties &props) return false; } -CF::Properties ComponentInfo::iteratePartialStruct(CF::Properties &props) +CF::Properties ComponentInfo::iteratePartialStruct(const CF::Properties &props) const { CF::Properties retval; - redhawk::PropertyMap& configProps = redhawk::PropertyMap::cast(props); - for (redhawk::PropertyMap::iterator cP = configProps.begin(); cP != configProps.end(); cP++) { + const redhawk::PropertyMap& configProps = redhawk::PropertyMap::cast(props); + for (redhawk::PropertyMap::const_iterator cP = configProps.begin(); cP != configProps.end(); cP++) { const ossie::Property* prop = this->prf.getProperty(ossie::corba::returnString(cP->id)); if (dynamic_cast(prop)) { CF::Properties* tmp; @@ -861,7 +857,8 @@ CF::Properties ComponentInfo::iteratePartialStruct(CF::Properties &props) return retval; } -CF::Properties ComponentInfo::containsPartialStructConfig() { +CF::Properties ComponentInfo::containsPartialStructConfig() const +{ return this->iteratePartialStruct(configureProperties); } @@ -870,7 +867,7 @@ CF::Properties ComponentInfo::containsPartialStructConstruct() return this->iteratePartialStruct(ctorProperties); } -CF::Properties ComponentInfo::getNonNilConfigureProperties() +CF::Properties ComponentInfo::getNonNilConfigureProperties() const { return ossie::getNonNilConfigureProperties(configureProperties); } @@ -1009,11 +1006,6 @@ CF::Properties ComponentInfo::getPopulatedExecParameters() return retval; } -CF::Resource_ptr ComponentInfo::getResourcePtr() -{ - return CF::Resource::_duplicate(rsc); -} - //////////////////////////////////////////////////// /* diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.h b/redhawk/src/control/sdr/dommgr/applicationSupport.h index 958ceb415..dd1f6b2aa 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.h +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.h @@ -179,7 +179,7 @@ namespace ossie ~SoftpkgInfo (); const char* getSpdFileName(); - const char* getName(); + const std::string& getName() const; void addImplementation(ImplementationInfo* impl); void getImplementations(ImplementationInfo::List& res); @@ -233,28 +233,26 @@ namespace ossie void overrideProperty(const ossie::ComponentProperty* propref); void overrideProperty(const char* id, const CORBA::Any& value); - void setResourcePtr(CF::Resource_ptr); - - const char* getInstantiationIdentifier(); - const char* getIdentifier(); - boost::shared_ptr getAssignedDevice(); + const std::string& getInstantiationIdentifier() const; + const std::string& getIdentifier() const; + const boost::shared_ptr& getAssignedDevice() const; const char* getAssignedDeviceId(); - const bool getNamingService(); - const char* getUsageName(); - const char* getNamingServiceName(); - const bool isResource(); - const bool isConfigurable(); - const bool isAssemblyController(); - const bool isScaCompliant(); - const std::string getNicAssignment(); + bool isNamingService() const; + const char* getUsageName() const; + const char* getNamingServiceName() const; + bool isResource() const; + bool isConfigurable() const; + bool isAssemblyController() const; + bool isScaCompliant() const; + const std::string& getNicAssignment() const; bool isAssignedToDevice() const; - CF::Properties containsPartialStructConfig(); + CF::Properties containsPartialStructConfig() const; CF::Properties containsPartialStructConstruct(); - CF::Properties iteratePartialStruct(CF::Properties &props); - bool checkStruct(CF::Properties &props); + CF::Properties iteratePartialStruct(const CF::Properties &props) const; + bool checkStruct(const CF::Properties &props) const; - CF::Properties getNonNilConfigureProperties(); + CF::Properties getNonNilConfigureProperties() const; CF::Properties getNonNilNonExecConstructProperties(); CF::Properties getConfigureProperties(); CF::Properties getConstructProperties(); @@ -264,8 +262,6 @@ namespace ossie CF::Properties getExecParameters(); CF::Properties getPopulatedExecParameters(); - CF::Resource_ptr getResourcePtr(); - static ComponentInfo* buildComponentInfoFromSPDFile(CF::FileManager_ptr fileMgr, const char* _SPDFile); ComponentDescriptor scd; ossie::Properties prf; @@ -277,7 +273,7 @@ namespace ossie bool _isAssemblyController; bool _isConfigurable; bool _isScaCompliant; - bool isNamingService; + bool _isNamingService; boost::shared_ptr assignedDevice; @@ -297,8 +293,6 @@ namespace ossie CF::Properties execParameters; CF::Properties affinityOptions; - CF::Resource_var rsc; - }; /* From 137e6321d01676d49b4df45647c9c9abb2c60852 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 10 May 2016 11:09:06 -0400 Subject: [PATCH 0181/1644] Use symbolic constants for options --- redhawk/src/control/sdr/dommgr/Deployment.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index 12e7b2e67..0ccdf6d4e 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -127,13 +127,13 @@ redhawk::PropertyMap ComponentDeployment::getOptions() // 3.1.3.3.3.3.6 // The specification says it's supposed to be an unsigned long, but the // parser is set to unsigned long long - options["STACK_SIZE"] = implementation->getStackSize(); + options[CF::ExecutableDevice::STACK_SIZE_ID] = implementation->getStackSize(); } if (implementation->hasPriority()) { // 3.1.3.3.3.3.7 // The specification says it's supposed to be an unsigned long, but the // parser is set to unsigned long long - options["PRIORITY"] = implementation->getPriority(); + options[CF::ExecutableDevice::PRIORITY_ID] = implementation->getPriority(); } return options; From 109ff9987ee509120213b8eed47bc74eef127483 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 10 May 2016 11:20:56 -0400 Subject: [PATCH 0182/1644] Additional const support for ComponentInfo --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 25 ++++++++----------- .../control/sdr/dommgr/applicationSupport.cpp | 4 +-- .../control/sdr/dommgr/applicationSupport.h | 4 +-- 3 files changed, 15 insertions(+), 18 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 6ece5ef01..366a9aba6 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -2801,7 +2801,7 @@ void createHelper::initializeComponents() for (unsigned int rc_idx = 0; rc_idx < _deployments.size (); rc_idx++) { ossie::ComponentDeployment* deployment = _deployments[rc_idx]; - ossie::ComponentInfo* component = deployment->getComponent(); + const ossie::ComponentInfo* component = deployment->getComponent(); // If the component is non-SCA compliant then we don't expect anything beyond this if (!component->isScaCompliant()) { @@ -2826,10 +2826,9 @@ void createHelper::initializeComponents() } if (CORBA::is_nil(resource)) { ostringstream eout; - std::string component_version(component->spd.getSoftPkgType()); - std::string added_message = this->createVersionMismatchMessage(component_version); - eout << added_message; - eout << "CF::Resource::_narrow failed with Unknown Exception for component: '" << component->getName() << "' with component id: '" << componentId << " assigned to device: '"<getAssignedDeviceId()<<"'"; + eout << "CF::Resource::_narrow failed with Unknown Exception for component: '" << component->getName() + << "' with component id: '" << componentId + << " assigned to device: '"<getAssignedDevice()->identifier<<"'"; eout << " in waveform '" << _waveformContextName<<"';"; eout << " error occurred near line:" <<__LINE__ << " in file:" << __FILE__ << ";"; throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EIO, eout.str().c_str()); @@ -2854,11 +2853,8 @@ void createHelper::initializeComponents() CF::Properties partialStruct = component->containsPartialStructConstruct(); if (partialStruct.length() != 0) { ostringstream eout; - std::string component_version(component->spd.getSoftPkgType()); - std::string added_message = this->createVersionMismatchMessage(component_version); - eout << added_message; - eout << "Failed to 'initializeProperties' component: '"; - eout << component->getName() << "' with component id: '" << component->getIdentifier() << " assigned to device: '"<getAssignedDeviceId() << "' "; + eout << "Failed to 'configure' Assembly Controller: '"; + eout << component->getName() << "' with component id: '" << component->getIdentifier() << " assigned to device: '"<getAssignedDevice()->identifier << "' "; eout << " in waveform '"<< _waveformContextName<<"';"; eout << "This component contains structure"<initializeProperties(component->getNonNilNonExecConstructProperties()); + CF::Properties initProps = component->getInitializeProperties(); + resource->initializeProperties(initProps); } catch(CF::PropertySet::InvalidConfiguration& e) { ostringstream eout; eout << "Failed to initialize component properties: '"; - eout << component->getName() << "' with component id: '" << component->getIdentifier() << " assigned to device: '"<getAssignedDeviceId() << "' "; + eout << component->getName() << "' with component id: '" << component->getIdentifier() << " assigned to device: '"<getAssignedDevice()->identifier << "' "; eout << " in waveform '"<< _waveformContextName<<"';"; eout << "InvalidConfiguration with this info: <"; eout << e.msg << "> for these invalid properties: "; @@ -2884,7 +2881,7 @@ void createHelper::initializeComponents() } catch(CF::PropertySet::PartialConfiguration& e) { ostringstream eout; eout << "Failed to initialize component properties: '"; - eout << component->getName() << "' with component id: '" << component->getIdentifier() << " assigned to device: '"<getAssignedDeviceId() << "' "; + eout << component->getName() << "' with component id: '" << component->getIdentifier() << " assigned to device: '"<getAssignedDevice()->identifier << "' "; eout << " in waveform '"<< _waveformContextName<<"';"; eout << "PartialConfiguration for these invalid properties: "; for (unsigned int propIdx = 0; propIdx < e.invalidProperties.length(); propIdx++){ @@ -2900,7 +2897,7 @@ void createHelper::initializeComponents() std::string added_message = this->createVersionMismatchMessage(component_version); eout << added_message; eout << "Failed to initialize component properties: '"; - eout << component->getName() << "' with component id: '" << component->getIdentifier() << " assigned to device: '"<getAssignedDeviceId() << "' "; + eout << component->getName() << "' with component id: '" << component->getIdentifier() << " assigned to device: '"<getAssignedDevice()->identifier << "' "; eout << " in waveform '"<< _waveformContextName<<"';"; eout << "'initializeProperties' failed with Unknown Exception"; eout << " error occurred near line:" <<__LINE__ << " in file:" << __FILE__ << ";"; diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp index 8f5404e47..72e8418ea 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp @@ -862,7 +862,7 @@ CF::Properties ComponentInfo::containsPartialStructConfig() const return this->iteratePartialStruct(configureProperties); } -CF::Properties ComponentInfo::containsPartialStructConstruct() +CF::Properties ComponentInfo::containsPartialStructConstruct() const { return this->iteratePartialStruct(ctorProperties); } @@ -872,7 +872,7 @@ CF::Properties ComponentInfo::getNonNilConfigureProperties() const return ossie::getNonNilConfigureProperties(configureProperties); } -CF::Properties ComponentInfo::getNonNilNonExecConstructProperties() +CF::Properties ComponentInfo::getInitializeProperties() const { return ossie::getNonNilProperties(ctorProperties); } diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.h b/redhawk/src/control/sdr/dommgr/applicationSupport.h index dd1f6b2aa..df5737101 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.h +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.h @@ -248,12 +248,12 @@ namespace ossie bool isAssignedToDevice() const; CF::Properties containsPartialStructConfig() const; - CF::Properties containsPartialStructConstruct(); + CF::Properties containsPartialStructConstruct() const; CF::Properties iteratePartialStruct(const CF::Properties &props) const; bool checkStruct(const CF::Properties &props) const; CF::Properties getNonNilConfigureProperties() const; - CF::Properties getNonNilNonExecConstructProperties(); + CF::Properties getInitializeProperties() const; CF::Properties getConfigureProperties(); CF::Properties getConstructProperties(); CF::Properties getOptions(); From d197bfd131975605af0308fa19ba3d6e298e6b1e Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 10 May 2016 11:34:03 -0400 Subject: [PATCH 0183/1644] Move all assigned device tracking out of ComponentInfo --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 94 +++++++++---------- .../control/sdr/dommgr/applicationSupport.cpp | 22 +---- .../control/sdr/dommgr/applicationSupport.h | 4 - 3 files changed, 47 insertions(+), 73 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 366a9aba6..8db66cb42 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -2624,7 +2624,7 @@ void createHelper::attemptComponentExecution (CF::ApplicationRegistrar_ptr regis } catch( CF::InvalidFileName& _ex ) { std::string added_message = this->createVersionMismatchMessage(component_version); ostringstream eout; - eout << "InvalidFileName when calling 'execute' on device with device id: '" << component->getAssignedDeviceId() << "' for component: '"; + eout << "InvalidFileName when calling 'execute' on device with device id: '" << device->identifier << "' for component: '"; eout << component->getName() << "' with component id: '" << component->getIdentifier() << "' "; eout << " with implementation id: '" << implementation->getId() << "'"; eout << " in waveform '" << _waveformContextName<<"'"; @@ -2635,7 +2635,7 @@ void createHelper::attemptComponentExecution (CF::ApplicationRegistrar_ptr regis } catch( CF::Device::InvalidState& _ex ) { std::string added_message = this->createVersionMismatchMessage(component_version); ostringstream eout; - eout << "InvalidState when calling 'execute' on device with device id: '" << component->getAssignedDeviceId() << "' for component: '"; + eout << "InvalidState when calling 'execute' on device with device id: '" << device->identifier << "' for component: '"; eout << component->getName() << "' with component id: '" << component->getIdentifier() << "' "; eout << " with implementation id: '" << implementation->getId() << "'"; eout << " in waveform '" << _waveformContextName<<"'"; @@ -2646,7 +2646,7 @@ void createHelper::attemptComponentExecution (CF::ApplicationRegistrar_ptr regis } catch( CF::ExecutableDevice::InvalidParameters& _ex ) { std::string added_message = this->createVersionMismatchMessage(component_version); ostringstream eout; - eout << "InvalidParameters when calling 'execute' on device with device id: '" << component->getAssignedDeviceId() << "' for component: '"; + eout << "InvalidParameters when calling 'execute' on device with device id: '" << device->identifier << "' for component: '"; eout << component->getName() << "' with component id: '" << component->getIdentifier() << "' "; eout << " with implementation id: '" << implementation->getId() << "'"; eout << " in waveform '" << _waveformContextName<<"'"; @@ -2661,7 +2661,7 @@ void createHelper::attemptComponentExecution (CF::ApplicationRegistrar_ptr regis std::string component_version(component->spd.getSoftPkgType()); std::string added_message = this->createVersionMismatchMessage(component_version); ostringstream eout; - eout << "InvalidOptions when calling 'execute' on device with device id: '" << component->getAssignedDeviceId() << "' for component: '"; + eout << "InvalidOptions when calling 'execute' on device with device id: '" << device->identifier << "' for component: '"; eout << component->getName() << "' with component id: '" << component->getIdentifier() << "' "; eout << " with implementation id: '" << implementation->getId() << "'"; eout << " in waveform '" << _waveformContextName<<"'"; @@ -2675,8 +2675,7 @@ void createHelper::attemptComponentExecution (CF::ApplicationRegistrar_ptr regis } catch (CF::ExecutableDevice::ExecuteFail& ex) { std::string added_message = this->createVersionMismatchMessage(component_version); ostringstream eout; - eout << added_message; - eout << "ExecuteFail when calling 'execute' on device with device id: '" << component->getAssignedDeviceId() << "' for component: '"; + eout << "ExecuteFail when calling 'execute' on device with device id: '" << device->identifier << "' for component: '"; eout << component->getName() << "' with component id: '" << component->getIdentifier() << "' "; eout << " with implementation id: '" << implementation->getId() << "'"; eout << " in waveform '" << _waveformContextName<<"'"; @@ -2685,8 +2684,8 @@ void createHelper::attemptComponentExecution (CF::ApplicationRegistrar_ptr regis LOG_TRACE(ApplicationFactory_impl, eout.str()) throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EIO, eout.str().c_str()); } CATCH_THROW_LOG_ERROR( - ApplicationFactory_impl, this->createVersionMismatchMessage(component_version)<<"Caught an unexpected error when calling 'execute' on device with device id: '" - << component->getAssignedDeviceId() << "' for component: '" << component->getName() + ApplicationFactory_impl, "Caught an unexpected error when calling 'execute' on device with device id: '" + << device->identifier << "' for component: '" << component->getName() << "' with component id: '" << component->getIdentifier() << "' " << " with implementation id: '" << implementation->getId() << "'" << " in waveform '" << _waveformContextName<<"'" @@ -2713,37 +2712,35 @@ void createHelper::attemptComponentExecution (CF::ApplicationRegistrar_ptr regis void createHelper::applyApplicationAffinityOptions() { - if ( _app_affinity.length() > 0 ) { - // log deployments with application affinity - for ( uint32_t i=0; i < _app_affinity.length(); i++ ) { - CF::DataType dt = _app_affinity[i]; - LOG_INFO(ApplicationFactory_impl, " Applying Application Affinity: directive id:" << dt.id << "/" << ossie::any_to_string( dt.value )) ; - } + if ( _app_affinity.length() > 0 ) { + // log deployments with application affinity + for ( uint32_t i=0; i < _app_affinity.length(); i++ ) { + CF::DataType dt = _app_affinity[i]; + LOG_INFO(ApplicationFactory_impl, " Applying Application Affinity: directive id:" << dt.id << "/" << ossie::any_to_string( dt.value )) ; + } - // - // Promote NIC affinity for all components deployed on the same device - // - boost::shared_ptr deploy_on_device; - for (unsigned int rc_idx = 0; rc_idx < _requiredComponents.size (); rc_idx++) { - ossie::ComponentInfo * comp = _requiredComponents[rc_idx]; - if ( comp->getNicAssignment() != "" ) { - deploy_on_device = comp->getAssignedDevice(); + // + // Promote NIC affinity for all components deployed on the same device + // + boost::shared_ptr deploy_on_device; + for (unsigned int rc_idx = 0; rc_idx < _deployments.size(); rc_idx++) { + ossie::ComponentDeployment* deployment = _deployments[rc_idx]; + if (!(deployment->getComponent()->getNicAssignment().empty())) { + deploy_on_device = deployment->getAssignedDevice(); + } } - } - if ( deploy_on_device ) { - for (unsigned int rc_idx = 0; rc_idx < _requiredComponents.size (); rc_idx++) { - ossie::ComponentInfo* component = _requiredComponents[rc_idx]; - boost::shared_ptr dev= component->getAssignedDevice(); - // for matching device deployments then apply nic affinity settings - if ( dev->identifier == deploy_on_device->identifier ) { - component->mergeAffinityOptions( _app_affinity ); - } + if (deploy_on_device) { + for (unsigned int rc_idx = 0; rc_idx < _deployments.size (); rc_idx++) { + ossie::ComponentDeployment* deployment = _deployments[rc_idx]; + boost::shared_ptr dev = deployment->getAssignedDevice(); + // for matching device deployments then apply nic affinity settings + if (dev->identifier == deploy_on_device->identifier) { + deployment->getComponent()->mergeAffinityOptions(_app_affinity); + } + } } } - - } - } void createHelper::waitForComponentRegistration() @@ -2769,12 +2766,13 @@ void createHelper::waitForComponentRegistration() time_t elapsed = time(NULL)-start; LOG_ERROR(ApplicationFactory_impl, "Timed out waiting for component to bind to naming context (" << elapsed << "s elapsed)"); ostringstream eout; - for (unsigned int req_idx = 0; req_idx < _requiredComponents.size(); req_idx++) { - if (expected_components.count(_requiredComponents[req_idx]->getIdentifier())) { - std::string component_version(_requiredComponents[req_idx]->spd.getSoftPkgType()); - std::string added_message = this->createVersionMismatchMessage(component_version); - eout << added_message; - eout << "Timed out waiting for component to register: '" << _requiredComponents[req_idx]->getName() << "' with component id: '" << _requiredComponents[req_idx]->getIdentifier()<< " assigned to device: '"<<_requiredComponents[req_idx]->getAssignedDeviceId()<<"'"; + for (unsigned int req_idx = 0; req_idx < _deployments.size(); req_idx++) { + ossie::ComponentDeployment* deployment = _deployments[req_idx]; + ossie::ComponentInfo* component = deployment->getComponent(); + if (expected_components.count(component->getIdentifier())) { + eout << "Timed out waiting for component to register: '" << component->getName() + << "' with component id: '" << component->getIdentifier() + << " assigned to device: '" << deployment->getAssignedDevice()->identifier; break; } } @@ -2854,7 +2852,7 @@ void createHelper::initializeComponents() if (partialStruct.length() != 0) { ostringstream eout; eout << "Failed to 'configure' Assembly Controller: '"; - eout << component->getName() << "' with component id: '" << component->getIdentifier() << " assigned to device: '"<getAssignedDevice()->identifier << "' "; + eout << component->getName() << "' with component id: '" << component->getIdentifier() << " assigned to device: '"<< deployment->getAssignedDevice()->identifier << "' "; eout << " in waveform '"<< _waveformContextName<<"';"; eout << "This component contains structure"<getName() << "' with component id: '" << component->getIdentifier() << " assigned to device: '"<getAssignedDevice()->identifier << "' "; + eout << component->getName() << "' with component id: '" << component->getIdentifier() << " assigned to device: '"<getAssignedDevice()->identifier << "' "; eout << " in waveform '"<< _waveformContextName<<"';"; eout << "InvalidConfiguration with this info: <"; eout << e.msg << "> for these invalid properties: "; @@ -2881,7 +2879,7 @@ void createHelper::initializeComponents() } catch(CF::PropertySet::PartialConfiguration& e) { ostringstream eout; eout << "Failed to initialize component properties: '"; - eout << component->getName() << "' with component id: '" << component->getIdentifier() << " assigned to device: '"<getAssignedDevice()->identifier << "' "; + eout << component->getName() << "' with component id: '" << component->getIdentifier() << " assigned to device: '"<getAssignedDevice()->identifier << "' "; eout << " in waveform '"<< _waveformContextName<<"';"; eout << "PartialConfiguration for these invalid properties: "; for (unsigned int propIdx = 0; propIdx < e.invalidProperties.length(); propIdx++){ @@ -2897,7 +2895,7 @@ void createHelper::initializeComponents() std::string added_message = this->createVersionMismatchMessage(component_version); eout << added_message; eout << "Failed to initialize component properties: '"; - eout << component->getName() << "' with component id: '" << component->getIdentifier() << " assigned to device: '"<getAssignedDevice()->identifier << "' "; + eout << component->getName() << "' with component id: '" << component->getIdentifier() << " assigned to device: '"<getAssignedDevice()->identifier << "' "; eout << " in waveform '"<< _waveformContextName<<"';"; eout << "'initializeProperties' failed with Unknown Exception"; eout << " error occurred near line:" <<__LINE__ << " in file:" << __FILE__ << ";"; @@ -3002,7 +3000,7 @@ void createHelper::configureComponents() eout << "Could not get component reference for component: '" << component->getName() << "' with component id: '" << component->getIdentifier() << " assigned to device: '" - << (*depl)->getAssignedDevice()->label<<"'"; + << (*depl)->getAssignedDevice()->identifier<<"'"; eout << " in waveform '" << _waveformContextName<<"';"; eout << " error occurred near line:" <<__LINE__ << " in file:" << __FILE__ << ";"; throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EIO, eout.str().c_str()); @@ -3022,7 +3020,7 @@ void createHelper::configureComponents() } catch(CF::PropertySet::InvalidConfiguration& e) { ostringstream eout; eout << "Failed to 'configure' component: '"; - eout << component->getName() << "' with component id: '" << component->getIdentifier() << " assigned to device: '"<<(*depl)->getAssignedDevice()->label << "' "; + eout << component->getName() << "' with component id: '" << component->getIdentifier() << " assigned to device: '"<<(*depl)->getAssignedDevice()->identifier << "' "; eout << " in waveform '"<< _waveformContextName<<"';"; eout << "InvalidConfiguration with this info: <"; eout << e.msg << "> for these invalid properties: "; @@ -3039,7 +3037,7 @@ void createHelper::configureComponents() } catch(CF::PropertySet::PartialConfiguration& e) { ostringstream eout; eout << "Failed to instantiate component: '"; - eout << component->getName() << "' with component id: '" << component->getIdentifier() << " assigned to device: '"<<(*depl)->getAssignedDevice()->label << "' "; + eout << component->getName() << "' with component id: '" << component->getIdentifier() << " assigned to device: '"<<(*depl)->getAssignedDevice()->identifier << "' "; eout << " in waveform '"<< _waveformContextName<<"';"; eout << "Failed to 'configure' component; PartialConfiguration for these invalid properties: "; for (unsigned int propIdx = 0; propIdx < e.invalidProperties.length(); propIdx++){ @@ -3055,7 +3053,7 @@ void createHelper::configureComponents() } catch( ... ) { ostringstream eout; eout << "Failed to instantiate component: '"; - eout << component->getName() << "' with component id: '" << component->getIdentifier() << " assigned to device: '"<getAssignedDevice()->label << "' "; + eout << component->getName() << "' with component id: '" << component->getIdentifier() << " assigned to device: '"<< (*depl)->getAssignedDevice()->identifier << "' "; eout << " in waveform '"<< _waveformContextName<<"';"; eout << "'configure' failed with Unknown Exception"; if (partialWarn) { diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp index 72e8418ea..aec90fd47 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp @@ -579,8 +579,7 @@ ComponentInfo* ComponentInfo::buildComponentInfoFromSPDFile(CF::FileManager_ptr ComponentInfo::ComponentInfo(const std::string& spdFileName) : SoftpkgInfo(spdFileName), _isAssemblyController(false), - _isScaCompliant(true), - assignedDevice() + _isScaCompliant(true) { nicAssignment = ""; // load common affinity property definitions @@ -739,20 +738,6 @@ const std::string& ComponentInfo::getIdentifier() const return identifier; } -const boost::shared_ptr& ComponentInfo::getAssignedDevice() const -{ - return assignedDevice; -} - -const char* ComponentInfo::getAssignedDeviceId() -{ - if (assignedDevice) { - return assignedDevice->identifier.c_str(); - } else { - return ""; - } -} - bool ComponentInfo::isNamingService() const { return _isNamingService; @@ -794,11 +779,6 @@ bool ComponentInfo::isScaCompliant() const return _isScaCompliant; } -bool ComponentInfo::isAssignedToDevice() const -{ - return assignedDevice; -} - bool ComponentInfo::checkStruct(const CF::Properties &props) const { const redhawk::PropertyMap& tmpProps = redhawk::PropertyMap::cast(props); diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.h b/redhawk/src/control/sdr/dommgr/applicationSupport.h index df5737101..278c85933 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.h +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.h @@ -235,8 +235,6 @@ namespace ossie const std::string& getInstantiationIdentifier() const; const std::string& getIdentifier() const; - const boost::shared_ptr& getAssignedDevice() const; - const char* getAssignedDeviceId(); bool isNamingService() const; const char* getUsageName() const; const char* getNamingServiceName() const; @@ -275,8 +273,6 @@ namespace ossie bool _isScaCompliant; bool _isNamingService; - boost::shared_ptr assignedDevice; - std::string usageName; std::string identifier; std::string instantiationId; From 27d583f210ce2355ac63c5fb6d4b29959f7bd4e5 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 10 May 2016 11:38:10 -0400 Subject: [PATCH 0184/1644] Add more const-safety --- redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp | 2 +- redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h | 2 +- redhawk/src/control/sdr/dommgr/applicationSupport.cpp | 4 ++-- redhawk/src/control/sdr/dommgr/applicationSupport.h | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 8db66cb42..3cd4f0b50 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -2330,7 +2330,7 @@ string ApplicationFactory_impl::getBaseWaveformContext(string waveform_context) return base_naming_context; } -void createHelper::loadDependencies(ossie::ComponentInfo& component, +void createHelper::loadDependencies(const ossie::ComponentInfo& component, CF::LoadableDevice_ptr device, const std::vector& dependencies) { diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h index 595af3c22..4d5d689fc 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h @@ -264,7 +264,7 @@ public ossie::DeviceLookup ossie::SoftpkgDeployment* resolveDependencyImplementation(ossie::SoftpkgInfo* softpkg, ossie::DeviceNode& device); // Supports loading, executing, initializing, configuring, & connecting - void loadDependencies(ossie::ComponentInfo& component, + void loadDependencies(const ossie::ComponentInfo& component, CF::LoadableDevice_ptr device, const std::vector& dependencies); diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp index aec90fd47..e96dff3fd 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp @@ -368,9 +368,9 @@ SoftpkgInfo::~SoftpkgInfo() } } -const char* SoftpkgInfo::getSpdFileName() +const std::string& SoftpkgInfo::getSpdFileName() const { - return _spdFileName.c_str(); + return _spdFileName; } const std::string& SoftpkgInfo::getName() const diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.h b/redhawk/src/control/sdr/dommgr/applicationSupport.h index 278c85933..6083e19b7 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.h +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.h @@ -178,7 +178,7 @@ namespace ossie SoftpkgInfo (const std::string& spdFileName); ~SoftpkgInfo (); - const char* getSpdFileName(); + const std::string& getSpdFileName() const; const std::string& getName() const; void addImplementation(ImplementationInfo* impl); From 150f368c637a8b2f42fe0095c1c1d01f41dd96ea Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 10 May 2016 11:44:58 -0400 Subject: [PATCH 0185/1644] Fill in specialized CPU reservation in execute function --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 25 ++++++++----------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 3cd4f0b50..ebb405352 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -2540,21 +2540,6 @@ void createHelper::loadAndExecuteComponents(CF::ApplicationRegistrar_ptr _appReg component->overrideProperty("LOGGING_CONFIG_URI", loguri); } - std::string sr_key; - if (this->specialized_reservations.find(std::string(component->getIdentifier())) != this->specialized_reservations.end()) { - sr_key = std::string(component->getIdentifier()); - } else if (this->specialized_reservations.find(std::string(component->getUsageName())) != this->specialized_reservations.end()) { - sr_key = std::string(component->getUsageName()); - } - if (not sr_key.empty()) { - CF::DataType spec_res; - spec_res.id = "RH::GPP::MODIFIED_CPU_RESERVATION_VALUE"; - //std::stringstream ss; - //ss << this->specialized_reservations[sr_key]; - spec_res.value <<= this->specialized_reservations[sr_key]; - component->addExecParameter(spec_res); - } - attemptComponentExecution(_appReg, deployment); } } @@ -2576,8 +2561,18 @@ void createHelper::attemptComponentExecution (CF::ApplicationRegistrar_ptr regis throw std::logic_error(message.str()); } + // Build up the list of command line parameters redhawk::PropertyMap execParameters(component->getPopulatedExecParameters()); + // Add specialized CPU reservation if given + std::map::iterator reservation = specialized_reservations.find(component->getIdentifier()); + if (reservation == specialized_reservations.end()) { + reservation = specialized_reservations.find(component->getUsageName()); + } + if (reservation != specialized_reservations.end()) { + execParameters["RH::GPP::MODIFIED_CPU_RESERVATION_VALUE"] = reservation->second; + } + // Add the required parameters specified in SR:163 // Naming Context IOR, Name Binding, and component identifier execParameters["COMPONENT_IDENTIFIER"] = component->getIdentifier(); From 537d146fcf5e833bbf1395e03e35b0a8a273dab4 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 10 May 2016 12:31:35 -0400 Subject: [PATCH 0186/1644] Return a const reference to the implementation list, instead of requiring the user to provide a destination container --- .../control/sdr/dommgr/ApplicationFactory_impl.cpp | 13 ++++--------- .../src/control/sdr/dommgr/applicationSupport.cpp | 4 ++-- redhawk/src/control/sdr/dommgr/applicationSupport.h | 2 +- 3 files changed, 7 insertions(+), 12 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index ebb405352..94260cc01 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -738,9 +738,8 @@ void createHelper::_resolveImplementations(PlacementList::iterator comp, Placeme if (comp == compList.end()) { return; } - ossie::ImplementationInfo::List comp_imps; + const ossie::ImplementationInfo::List& comp_imps = (*comp)->getImplementations(); std::vector tmp_res_vec = res_vec; - (*comp)->getImplementations(comp_imps); unsigned int old_res_vec_size = res_vec.size(); if (old_res_vec_size == 0) { res_vec.resize(comp_imps.size()); @@ -1624,10 +1623,6 @@ ossie::ComponentDeployment* createHelper::allocateComponent(ossie::ComponentInfo DeviceAssignmentList &appAssignedDevs, const std::string& appIdentifier) { - // get the implementations from the component - ossie::ImplementationInfo::List implementations; - component->getImplementations(implementations); - CF::Properties configureProperties = component->getConfigureProperties(); const CF::Properties &construct_props = component->getConstructProperties(); unsigned int configlen = configureProperties.length(); @@ -1659,6 +1654,7 @@ ossie::ComponentDeployment* createHelper::allocateComponent(ossie::ComponentInfo } // now attempt to find an implementation that can have it's allocation requirements met + const ossie::ImplementationInfo::List& implementations = component->getImplementations(); for (size_t implCount = 0; implCount < implementations.size(); implCount++) { ossie::ImplementationInfo* impl = implementations[implCount]; @@ -2072,8 +2068,7 @@ bool createHelper::resolveSoftpkgDependencies(ossie::SoftpkgDeployment* deployme ossie::SoftpkgDeployment* createHelper::resolveDependencyImplementation(ossie::SoftpkgInfo* softpkg, ossie::DeviceNode& device) { - ossie::ImplementationInfo::List spd_list; - softpkg->getImplementations(spd_list); + const ossie::ImplementationInfo::List& spd_list = softpkg->getImplementations(); for (size_t implCount = 0; implCount < spd_list.size(); implCount++) { ossie::ImplementationInfo* implementation = spd_list[implCount]; @@ -2763,7 +2758,7 @@ void createHelper::waitForComponentRegistration() ostringstream eout; for (unsigned int req_idx = 0; req_idx < _deployments.size(); req_idx++) { ossie::ComponentDeployment* deployment = _deployments[req_idx]; - ossie::ComponentInfo* component = deployment->getComponent(); + const ossie::ComponentInfo* component = deployment->getComponent(); if (expected_components.count(component->getIdentifier())) { eout << "Timed out waiting for component to register: '" << component->getName() << "' with component id: '" << component->getIdentifier() diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp index e96dff3fd..7df6594f5 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp @@ -437,9 +437,9 @@ void SoftpkgInfo::addImplementation(ImplementationInfo* impl) _implementations.push_back(impl); } -void SoftpkgInfo::getImplementations(ImplementationInfo::List& res) +const ImplementationInfo::List& SoftpkgInfo::getImplementations() const { - std::copy(_implementations.begin(), _implementations.end(), std::back_inserter(res)); + return _implementations; } const UsesDeviceInfo* SoftpkgInfo::getUsesDeviceById(const std::string& id) const diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.h b/redhawk/src/control/sdr/dommgr/applicationSupport.h index 6083e19b7..b3bf44228 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.h +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.h @@ -182,7 +182,7 @@ namespace ossie const std::string& getName() const; void addImplementation(ImplementationInfo* impl); - void getImplementations(ImplementationInfo::List& res); + const ImplementationInfo::List& getImplementations() const; virtual const UsesDeviceInfo* getUsesDeviceById(const std::string& id) const; From 00eda15274d8ca38009d1933385cb41b52de2a13 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 10 May 2016 13:01:40 -0400 Subject: [PATCH 0187/1644] Separate device assignment from constructor for ComponentDeployment; more const-safety --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 27 ++++++++++--------- .../sdr/dommgr/ApplicationFactory_impl.h | 7 +++-- redhawk/src/control/sdr/dommgr/Deployment.cpp | 15 ++++++----- redhawk/src/control/sdr/dommgr/Deployment.h | 10 +++---- .../control/sdr/dommgr/applicationSupport.cpp | 2 +- .../control/sdr/dommgr/applicationSupport.h | 2 +- 6 files changed, 34 insertions(+), 29 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 94260cc01..cd776c31d 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -973,7 +973,8 @@ void createHelper::_placeHostCollocation(const SoftwareAssembly::HostCollocation for (unsigned int i=0; idevice); collocAssignedDevs[i].deviceAssignment.assignedDeviceId = CORBA::string_dup(deviceId.c_str()); - ossie::ComponentDeployment* deployment = new ossie::ComponentDeployment(*comp, *impl, node); + ossie::ComponentDeployment* deployment = new ossie::ComponentDeployment(*comp, *impl); + deployment->setAssignedDevice(node); if (!resolveSoftpkgDependencies(deployment, *node)) { LOG_TRACE(ApplicationFactory_impl, "Unable to resolve softpackage dependencies for component " << (*comp)->getIdentifier() << " implementation " << (*impl)->getId()); @@ -1668,11 +1669,13 @@ ossie::ComponentDeployment* createHelper::allocateComponent(ossie::ComponentInfo << component->getIdentifier() << " implementation " << impl->getId()); continue; } + + std::auto_ptr deployment(new ossie::ComponentDeployment(component, impl)); // Found an implementation which has its 'usesdevice' dependencies // satisfied, now perform assignment/allocation of component to device LOG_DEBUG(ApplicationFactory_impl, "Trying to find the device"); - ossie::AllocationResult response = allocateComponentToDevice(component, impl, assignedDeviceId, appIdentifier); + ossie::AllocationResult response = allocateComponentToDevice(deployment.get(), assignedDeviceId, appIdentifier); if (response.first.empty()) { LOG_DEBUG(ApplicationFactory_impl, "Unable to allocate device for component " @@ -1684,14 +1687,13 @@ ossie::ComponentDeployment* createHelper::allocateComponent(ossie::ComponentInfo implAllocations.push_back(response.first); // Convert from response back into a device node + deployment->setAssignedDevice(response.second); DeviceNode& node = *(response.second); const std::string& deviceId = node.identifier; - ossie::ComponentDeployment* deployment = new ossie::ComponentDeployment(component, impl, response.second); - if (!resolveSoftpkgDependencies(deployment, node)) { + if (!resolveSoftpkgDependencies(deployment.get(), node)) { LOG_DEBUG(ApplicationFactory_impl, "Unable to resolve softpackage dependencies for component " << component->getIdentifier() << " implementation " << impl->getId()); - delete deployment; continue; } @@ -1713,7 +1715,7 @@ ossie::ComponentDeployment* createHelper::allocateComponent(ossie::ComponentInfo implAllocations.transfer(this->_allocations); std::copy(implAllocatedDevices.begin(), implAllocatedDevices.end(), std::back_inserter(appAssignedDevs)); - return deployment; + return deployment.release(); } ossie::DeviceList::iterator device; @@ -1914,11 +1916,12 @@ void createHelper::_evaluateMATHinRequest(CF::Properties &request, const CF::Pro * - If not specified in DAS, then iterate through devices looking for a device that satisfies * the allocation properties */ -ossie::AllocationResult createHelper::allocateComponentToDevice( ossie::ComponentInfo* component, - ossie::ImplementationInfo* implementation, +ossie::AllocationResult createHelper::allocateComponentToDevice(ossie::ComponentDeployment* deployment, const std::string& assignedDeviceId, const std::string& appIdentifier) { + ossie::ComponentInfo* component = deployment->getComponent(); + const ossie::ImplementationInfo* implementation = deployment->getImplementation(); ossie::DeviceList devices = _registeredDevices; // First check to see if the component was assigned in the user provided DAS @@ -2047,7 +2050,7 @@ CF::DataType createHelper::castProperty(const ossie::ComponentProperty* property bool createHelper::resolveSoftpkgDependencies(ossie::SoftpkgDeployment* deployment, ossie::DeviceNode& device) { - ossie::ImplementationInfo* implementation = deployment->getImplementation(); + const ossie::ImplementationInfo* implementation = deployment->getImplementation(); const std::vector& tmpSoftpkg = implementation->getSoftPkgDependency(); std::vector::const_iterator iterSoftpkg; @@ -2543,8 +2546,8 @@ void createHelper::loadAndExecuteComponents(CF::ApplicationRegistrar_ptr _appReg void createHelper::attemptComponentExecution (CF::ApplicationRegistrar_ptr registrar, ossie::ComponentDeployment* deployment) { - ossie::ComponentInfo* component = deployment->getComponent(); - ossie::ImplementationInfo* implementation = deployment->getImplementation(); + const ossie::ComponentInfo* component = deployment->getComponent(); + const ossie::ImplementationInfo* implementation = deployment->getImplementation(); // Get executable device reference boost::shared_ptr device = deployment->getAssignedDevice(); @@ -2557,7 +2560,7 @@ void createHelper::attemptComponentExecution (CF::ApplicationRegistrar_ptr regis } // Build up the list of command line parameters - redhawk::PropertyMap execParameters(component->getPopulatedExecParameters()); + redhawk::PropertyMap execParameters(component->getCommandLineParameters()); // Add specialized CPU reservation if given std::map::iterator reservation = specialized_reservations.find(component->getIdentifier()); diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h index 4d5d689fc..c0f0985a0 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h @@ -255,10 +255,9 @@ public ossie::DeviceLookup DeviceAssignmentList &appAssignedDevices, const std::string& appIdentifier); - ossie::AllocationResult allocateComponentToDevice(ossie::ComponentInfo* component, - ossie::ImplementationInfo* implementation, - const std::string& assignedDeviceId, - const std::string& appIdentifier); + ossie::AllocationResult allocateComponentToDevice(ossie::ComponentDeployment* deployment, + const std::string& assignedDeviceId, + const std::string& appIdentifier); bool resolveSoftpkgDependencies(ossie::SoftpkgDeployment* deployment, ossie::DeviceNode& device); ossie::SoftpkgDeployment* resolveDependencyImplementation(ossie::SoftpkgInfo* softpkg, ossie::DeviceNode& device); diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index 0ccdf6d4e..be4262b8f 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -25,7 +25,7 @@ using namespace ossie; namespace fs = boost::filesystem; -SoftpkgDeployment::SoftpkgDeployment(SoftpkgInfo* softpkg, ImplementationInfo* implementation) : +SoftpkgDeployment::SoftpkgDeployment(SoftpkgInfo* softpkg, const ImplementationInfo* implementation) : softpkg(softpkg), implementation(implementation) { @@ -43,7 +43,7 @@ SoftpkgInfo* SoftpkgDeployment::getSoftpkg() return softpkg; } -ImplementationInfo* SoftpkgDeployment::getImplementation() +const ImplementationInfo* SoftpkgDeployment::getImplementation() const { return implementation; } @@ -85,10 +85,8 @@ std::string SoftpkgDeployment::getLocalFile() return codeLocalFile.string(); } -ComponentDeployment::ComponentDeployment(ComponentInfo* component, ImplementationInfo* implementation, - const boost::shared_ptr& device) : - SoftpkgDeployment(component, implementation), - assignedDevice(device) +ComponentDeployment::ComponentDeployment(ComponentInfo* component, ImplementationInfo* implementation) : + SoftpkgDeployment(component, implementation) { } @@ -97,6 +95,11 @@ ComponentInfo* ComponentDeployment::getComponent() return dynamic_cast(getSoftpkg()); } +void ComponentDeployment::setAssignedDevice(const boost::shared_ptr& device) +{ + assignedDevice = device; +} + boost::shared_ptr ComponentDeployment::getAssignedDevice() { return assignedDevice; diff --git a/redhawk/src/control/sdr/dommgr/Deployment.h b/redhawk/src/control/sdr/dommgr/Deployment.h index a1b1594ea..23edbaa58 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.h +++ b/redhawk/src/control/sdr/dommgr/Deployment.h @@ -35,11 +35,11 @@ namespace ossie { public: typedef std::vector DeploymentList; - SoftpkgDeployment(SoftpkgInfo* softpkg, ImplementationInfo* implementation); + SoftpkgDeployment(SoftpkgInfo* softpkg, const ImplementationInfo* implementation); ~SoftpkgDeployment(); SoftpkgInfo* getSoftpkg(); - ImplementationInfo* getImplementation(); + const ImplementationInfo* getImplementation() const; std::string getLocalFile(); @@ -50,15 +50,14 @@ namespace ossie { protected: SoftpkgInfo* softpkg; - ImplementationInfo* implementation; + const ImplementationInfo* implementation; DeploymentList dependencies; }; class ComponentDeployment : public SoftpkgDeployment { public: - ComponentDeployment(ComponentInfo* component, ImplementationInfo* implementation, - const boost::shared_ptr& device); + ComponentDeployment(ComponentInfo* component, ImplementationInfo* implementation); ComponentInfo* getComponent(); @@ -66,6 +65,7 @@ namespace ossie { redhawk::PropertyMap getOptions(); + void setAssignedDevice(const boost::shared_ptr& device); boost::shared_ptr getAssignedDevice(); const ossie::UsesDeviceInfo* getUsesDeviceById(const std::string& usesId); diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp index 7df6594f5..25a3edd85 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp @@ -964,7 +964,7 @@ CF::Properties ComponentInfo::getExecParameters() return execParameters; } -CF::Properties ComponentInfo::getPopulatedExecParameters() +CF::Properties ComponentInfo::getCommandLineParameters() const { CF::Properties retval = execParameters; while (true) { diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.h b/redhawk/src/control/sdr/dommgr/applicationSupport.h index b3bf44228..fd75d4a00 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.h +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.h @@ -258,7 +258,7 @@ namespace ossie CF::Properties getAffinityOptions(); CF::Properties getAffinityOptionsWithAssignment(); CF::Properties getExecParameters(); - CF::Properties getPopulatedExecParameters(); + CF::Properties getCommandLineParameters() const; static ComponentInfo* buildComponentInfoFromSPDFile(CF::FileManager_ptr fileMgr, const char* _SPDFile); ComponentDescriptor scd; From c0418e6e99bd4126ad09674faa3bb34b791134ef Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 10 May 2016 15:24:17 -0400 Subject: [PATCH 0188/1644] Add a PropertyType constructor that takes an ID and value --- redhawk/src/base/framework/PropertyMap.cpp | 8 ++++++++ redhawk/src/base/framework/PropertyType.cpp | 7 +++++++ 2 files changed, 15 insertions(+) diff --git a/redhawk/src/base/framework/PropertyMap.cpp b/redhawk/src/base/framework/PropertyMap.cpp index 85876e1c6..2de8ac64f 100644 --- a/redhawk/src/base/framework/PropertyMap.cpp +++ b/redhawk/src/base/framework/PropertyMap.cpp @@ -117,6 +117,14 @@ const Value& PropertyMap::get(const std::string& id, const Value& def) const } } +void PropertyMap::update(const CF::Properties& properties) +{ + const PropertyMap& other = cast(properties); + for (const_iterator prop = other.begin(); prop != other.end(); ++prop) { + (*this)[prop->getId()] = prop->getValue(); + } +} + void PropertyMap::push_back(const CF::DataType& property) { ossie::corba::push_back(*this, property); diff --git a/redhawk/src/base/framework/PropertyType.cpp b/redhawk/src/base/framework/PropertyType.cpp index f6858cf0b..950f28eb6 100644 --- a/redhawk/src/base/framework/PropertyType.cpp +++ b/redhawk/src/base/framework/PropertyType.cpp @@ -32,6 +32,13 @@ PropertyType::PropertyType(const CF::DataType& dt) : { } +PropertyType::PropertyType(const std::string& identifier, const Value& value) : + CF::DataType() +{ + setId(identifier); + setValue(value); +} + PropertyType& PropertyType::operator=(const CF::DataType& dt) { CF::DataType::operator=(dt); From daa1eec2d5ec59448c5df7e03371473b986694a2 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 10 May 2016 15:25:11 -0400 Subject: [PATCH 0189/1644] Add an update() method to PropertyMap that replaces or inserts values from another CF::Properties (like the Python dict method) --- redhawk/src/base/include/ossie/PropertyMap.h | 2 ++ redhawk/src/base/include/ossie/PropertyType.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/redhawk/src/base/include/ossie/PropertyMap.h b/redhawk/src/base/include/ossie/PropertyMap.h index cefbfa9c6..a2132c428 100644 --- a/redhawk/src/base/include/ossie/PropertyMap.h +++ b/redhawk/src/base/include/ossie/PropertyMap.h @@ -62,6 +62,8 @@ namespace redhawk { const Value& get(const std::string& id, const Value& def=Value()) const; + void update(const CF::Properties& properties); + void push_back (const CF::DataType& dt); iterator begin(); diff --git a/redhawk/src/base/include/ossie/PropertyType.h b/redhawk/src/base/include/ossie/PropertyType.h index 38be85f8c..2598001b0 100644 --- a/redhawk/src/base/include/ossie/PropertyType.h +++ b/redhawk/src/base/include/ossie/PropertyType.h @@ -41,6 +41,8 @@ namespace redhawk { PropertyType(); explicit PropertyType(const CF::DataType& dt); + PropertyType(const std::string& id, const Value& value); + PropertyType& operator=(const CF::DataType& dt); void setId(const std::string& identifier); From 3da3e67f27b4796fade5529d856b4aedb4aa5376 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 10 May 2016 15:32:43 -0400 Subject: [PATCH 0190/1644] Move management of affinity and NIC allocation to deployment class --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 8 +- redhawk/src/control/sdr/dommgr/Deployment.cpp | 58 ++++++++++- redhawk/src/control/sdr/dommgr/Deployment.h | 10 ++ .../control/sdr/dommgr/applicationSupport.cpp | 95 +------------------ .../control/sdr/dommgr/applicationSupport.h | 7 +- 5 files changed, 71 insertions(+), 107 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index cd776c31d..efcca9fa8 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -1995,7 +1995,7 @@ ossie::AllocationResult createHelper::allocateComponentToDevice(ossie::Component if (identifier == alloc_id) { const std::string interface = struct_prop["nic_allocation_status::interface"].toString(); LOG_DEBUG(ApplicationFactory_impl, "Allocation NIC assignment: " << interface ); - component->setNicAssignment(interface); + deployment->setNicAssignment(interface); redhawk::PropertyType nic_execparam; nic_execparam.id = "NIC"; nic_execparam.setValue(interface); @@ -2003,7 +2003,7 @@ ossie::AllocationResult createHelper::allocateComponentToDevice(ossie::Component // RESOLVE - need SAD file directive to control this behavior.. i.e if promote_nic_to_affinity==true... // for now add nic assignment as application affinity to all components deployed by this device - _app_affinity = component->getAffinityOptionsWithAssignment(); + _app_affinity = deployment->getAffinityOptionsWithAssignment(); } } } @@ -2718,7 +2718,7 @@ void createHelper::applyApplicationAffinityOptions() { boost::shared_ptr deploy_on_device; for (unsigned int rc_idx = 0; rc_idx < _deployments.size(); rc_idx++) { ossie::ComponentDeployment* deployment = _deployments[rc_idx]; - if (!(deployment->getComponent()->getNicAssignment().empty())) { + if (!(deployment->getNicAssignment().empty())) { deploy_on_device = deployment->getAssignedDevice(); } } @@ -2729,7 +2729,7 @@ void createHelper::applyApplicationAffinityOptions() { boost::shared_ptr dev = deployment->getAssignedDevice(); // for matching device deployments then apply nic affinity settings if (dev->identifier == deploy_on_device->identifier) { - deployment->getComponent()->mergeAffinityOptions(_app_affinity); + deployment->mergeAffinityOptions(_app_affinity); } } } diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index be4262b8f..d63f1f245 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -86,13 +86,15 @@ std::string SoftpkgDeployment::getLocalFile() } ComponentDeployment::ComponentDeployment(ComponentInfo* component, ImplementationInfo* implementation) : - SoftpkgDeployment(component, implementation) + SoftpkgDeployment(component, implementation), + component(component), + affinityOptions(component->getAffinityOptions()) { } ComponentInfo* ComponentDeployment::getComponent() { - return dynamic_cast(getSoftpkg()); + return component; } void ComponentDeployment::setAssignedDevice(const boost::shared_ptr& device) @@ -123,7 +125,7 @@ std::string ComponentDeployment::getEntryPoint() redhawk::PropertyMap ComponentDeployment::getOptions() { // Get the options from the softpkg - redhawk::PropertyMap options(getComponent()->getOptions()); + redhawk::PropertyMap options(component->getOptions()); // Get the PRIORITY and STACK_SIZE from the SPD (if available) if (implementation->hasStackSize()) { @@ -139,12 +141,60 @@ redhawk::PropertyMap ComponentDeployment::getOptions() options[CF::ExecutableDevice::PRIORITY_ID] = implementation->getPriority(); } + redhawk::PropertyMap affinity = affinityOptions; + for (redhawk::PropertyMap::const_iterator prop = affinity.begin(); prop != affinity.end(); ++prop) { + RH_NL_DEBUG("DomainManager", "ComponentDeployment - Affinity Property: directive id:" + << prop->getId() << "/" << prop->getValue().toString()); + } + if (!nicAssignment.empty()) { + redhawk::PropertyMap::iterator nic_prop = affinity.find("nic"); + if (nic_prop == affinity.end() || (nic_prop->getId() != nicAssignment)) { + // No nic directive, or existing directive differs, append this one + affinity.push_back(redhawk::PropertyType("nic", nicAssignment)); + } + } + + if (!affinity.empty()) { + options["AFFINITY"] = affinity; + } + return options; } +void ComponentDeployment::setNicAssignment(const std::string& nic) +{ + nicAssignment = nic; +} + +const std::string& ComponentDeployment::getNicAssignment() const +{ + return nicAssignment; +} + +redhawk::PropertyMap ComponentDeployment::getAffinityOptionsWithAssignment() const +{ + redhawk::PropertyMap options = affinityOptions; + for (redhawk::PropertyMap::const_iterator prop = options.begin(); prop != options.end(); ++prop) { + RH_NL_DEBUG("DomainManager", "ComponentDeployment getAffinityOptionsWithAssignment ... Affinity Property: directive id:" << prop->getId() << "/" << prop->getValue().toString()); + } + + if (!nicAssignment.empty()) { + RH_NL_DEBUG("DomainManager", "ComponentDeployment getAffinityOptionsWithAssignment ... NIC AFFINITY: pol/value " << "nic" << "/" << nicAssignment); + options.push_back(redhawk::PropertyType("nic", nicAssignment)); + } + + return options; +} + +void ComponentDeployment::mergeAffinityOptions(const CF::Properties& properties) +{ + // Update existing settings with new ones + affinityOptions.update(properties); +} + const UsesDeviceInfo* ComponentDeployment::getUsesDeviceById(const std::string& usesId) { - const UsesDeviceInfo* usesDevice = getComponent()->getUsesDeviceById(usesId); + const UsesDeviceInfo* usesDevice = component->getUsesDeviceById(usesId); if (!usesDevice) { usesDevice = implementation->getUsesDeviceById(usesId); } diff --git a/redhawk/src/control/sdr/dommgr/Deployment.h b/redhawk/src/control/sdr/dommgr/Deployment.h index 23edbaa58..a42b7f5be 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.h +++ b/redhawk/src/control/sdr/dommgr/Deployment.h @@ -65,6 +65,12 @@ namespace ossie { redhawk::PropertyMap getOptions(); + redhawk::PropertyMap getAffinityOptionsWithAssignment() const; + void mergeAffinityOptions(const CF::Properties& affinity); + + void setNicAssignment(const std::string& nic); + const std::string& getNicAssignment() const; + void setAssignedDevice(const boost::shared_ptr& device); boost::shared_ptr getAssignedDevice(); @@ -74,8 +80,12 @@ namespace ossie { CF::Resource_ptr getResourcePtr() const; protected: + ComponentInfo* component; boost::shared_ptr assignedDevice; CF::Resource_var resource; + + std::string nicAssignment; + redhawk::PropertyMap affinityOptions; }; } diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp index 25a3edd85..b089fa255 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp @@ -581,7 +581,6 @@ ComponentInfo::ComponentInfo(const std::string& spdFileName) : _isAssemblyController(false), _isScaCompliant(true) { - nicAssignment = ""; // load common affinity property definitions try { std::stringstream os(redhawk::affinity::get_property_definitions()); @@ -631,11 +630,6 @@ void ComponentInfo::setIsScaCompliant(bool _isScaCompliant) this->_isScaCompliant = _isScaCompliant; } -void ComponentInfo::setNicAssignment(std::string nic) { - nicAssignment = nic; -}; - - void ComponentInfo::setAffinity( const AffinityProperties &affinity_props ) { @@ -753,11 +747,6 @@ const char* ComponentInfo::getNamingServiceName() const return namingServiceName.c_str(); } -const std::string& ComponentInfo::getNicAssignment() const -{ - return nicAssignment; -}; - bool ComponentInfo::isResource() const { return scd.isResource(); @@ -857,49 +846,11 @@ CF::Properties ComponentInfo::getInitializeProperties() const return ossie::getNonNilProperties(ctorProperties); } -CF::Properties ComponentInfo::getAffinityOptionsWithAssignment() -{ - // Add affinity setting first... - CF::Properties affinity_options; - for ( uint32_t i=0; i < affinityOptions.length(); i++ ) { - affinity_options.length(affinity_options.length()+1); - affinity_options[affinity_options.length()-1] = affinityOptions[i]; - CF::DataType dt = affinityOptions[i]; - RH_NL_DEBUG("DomainManager", "ComponentInfo getAffinityOptionsWithAssignment ... Affinity Property: directive id:" << dt.id << "/" << ossie::any_to_string( dt.value )) ; - } - - // add nic allocations to affinity list - if ( nicAssignment != "" ) { - affinity_options.length(affinity_options.length()+1); - affinity_options[affinity_options.length()-1].id = CORBA::string_dup("nic"); - affinity_options[affinity_options.length()-1].value <<= nicAssignment.c_str(); - RH_NL_DEBUG("DomainManager", "ComponentInfo getAffinityOptionsWithAssignment ... NIC AFFINITY: pol/value " << "nic" << "/" << nicAssignment ); - } - - return affinity_options; - -} - - -CF::Properties ComponentInfo::getAffinityOptions() -{ - return affinityOptions; -} - - -void ComponentInfo::mergeAffinityOptions( const CF::Properties &new_affinity ) +CF::Properties ComponentInfo::getAffinityOptions() const { - // for each new affinity setting apply settings to component's affinity options - const redhawk::PropertyMap &newmap = redhawk::PropertyMap::cast(new_affinity); - redhawk::PropertyMap ¤tAffinity = redhawk::PropertyMap::cast(affinityOptions); - redhawk::PropertyMap::const_iterator iter = newmap.begin(); - for ( ; iter != newmap.end(); iter++ ) { - std::string id = iter->getId(); - currentAffinity[id]=newmap[id]; - } + return affinityOptions; } - CF::Properties ComponentInfo::getConfigureProperties() { return configureProperties; @@ -914,48 +865,6 @@ CF::Properties ComponentInfo::getConstructProperties() CF::Properties ComponentInfo::getOptions() { - // Add affinity settings under AFFINITY property directory - CF::Properties affinity_options; - for ( uint32_t i=0; i < affinityOptions.length(); i++ ) { - affinity_options.length(affinity_options.length()+1); - affinity_options[affinity_options.length()-1] = affinityOptions[i]; - CF::DataType dt = affinityOptions[i]; - RH_NL_DEBUG("DomainManager", "ComponentInfo - Affinity Property: directive id:" << dt.id << "/" << ossie::any_to_string( dt.value )) ; - } - - // add nic allocations to affinity list - if ( nicAssignment != "" ) { - std::string id = "nic"; - const redhawk::PropertyMap &tmap = redhawk::PropertyMap::cast( affinityOptions ); - if ( !tmap.contains(id) ) { - // missing nic directive... add to map - affinity_options.length(affinity_options.length()+1); - affinity_options[affinity_options.length()-1].id = CORBA::string_dup("nic"); - affinity_options[affinity_options.length()-1].value <<= nicAssignment.c_str(); - } - else { - std::string nic_iface = tmap[id].toString(); - if ( nic_iface != nicAssignment ) { - // nic_iface is differnet add this - affinity_options.length(affinity_options.length()+1); - affinity_options[affinity_options.length()-1].id = CORBA::string_dup("nic"); - affinity_options[affinity_options.length()-1].value <<= nicAssignment.c_str(); - } - } - RH_NL_DEBUG("DomainManager", "ComponentInfo - NIC AFFINITY: pol/value " << "nic" << "/" << nicAssignment ); - } - - if ( affinity_options.length() > 0 ) { - options.length(options.length()+1); - options[options.length()-1].id = CORBA::string_dup("AFFINITY"); - options[options.length()-1].value <<= affinity_options; - RH_NL_DEBUG("DomainManager", "ComponentInfo - Extending options, adding Affinity Properties ...set length: " << affinity_options.length()); - } - - RH_NL_TRACE("DomainManager", "ComponentInfo - getOptions.... length: " << options.length()); - for ( uint32_t i=0; i < options.length(); i++ ) { - RH_NL_TRACE("DomainManager", "ComponentInfo - getOptions id:" << options[i].id << "/" << ossie::any_to_string( options[i].value )) ; - } return options; } diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.h b/redhawk/src/control/sdr/dommgr/applicationSupport.h index fd75d4a00..3f85dbfc1 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.h +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.h @@ -219,9 +219,7 @@ namespace ossie void setUsageName(const char* usageName); void setIsAssemblyController(bool isAssemblyController); void setIsScaCompliant(bool isScaCompliant); - void setNicAssignment(std::string nic); void setAffinity( const AffinityProperties &affinity ); - void mergeAffinityOptions( const CF::Properties &new_affinity ); void setLoggingConfig( const LoggingConfig &logcfg ); void addFactoryParameter(CF::DataType dt); @@ -242,7 +240,6 @@ namespace ossie bool isConfigurable() const; bool isAssemblyController() const; bool isScaCompliant() const; - const std::string& getNicAssignment() const; bool isAssignedToDevice() const; CF::Properties containsPartialStructConfig() const; @@ -255,8 +252,7 @@ namespace ossie CF::Properties getConfigureProperties(); CF::Properties getConstructProperties(); CF::Properties getOptions(); - CF::Properties getAffinityOptions(); - CF::Properties getAffinityOptionsWithAssignment(); + CF::Properties getAffinityOptions() const; CF::Properties getExecParameters(); CF::Properties getCommandLineParameters() const; @@ -277,7 +273,6 @@ namespace ossie std::string identifier; std::string instantiationId; std::string namingServiceName; - std::string nicAssignment; ossie::Properties _affinity_prf; LoggingConfig loggingConfig; From ecf36968f24152848196745ec11645a974fee555 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 10 May 2016 16:04:37 -0400 Subject: [PATCH 0191/1644] Apply the NIC execparam at execute time, allowing use of const for ComponentInfo in allocateComponentToDevice --- .../src/control/sdr/dommgr/ApplicationFactory_impl.cpp | 10 +++++----- redhawk/src/control/sdr/dommgr/applicationSupport.cpp | 4 ++-- redhawk/src/control/sdr/dommgr/applicationSupport.h | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index efcca9fa8..04f958643 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -1920,7 +1920,7 @@ ossie::AllocationResult createHelper::allocateComponentToDevice(ossie::Component const std::string& assignedDeviceId, const std::string& appIdentifier) { - ossie::ComponentInfo* component = deployment->getComponent(); + const ossie::ComponentInfo* component = deployment->getComponent(); const ossie::ImplementationInfo* implementation = deployment->getImplementation(); ossie::DeviceList devices = _registeredDevices; @@ -1996,10 +1996,6 @@ ossie::AllocationResult createHelper::allocateComponentToDevice(ossie::Component const std::string interface = struct_prop["nic_allocation_status::interface"].toString(); LOG_DEBUG(ApplicationFactory_impl, "Allocation NIC assignment: " << interface ); deployment->setNicAssignment(interface); - redhawk::PropertyType nic_execparam; - nic_execparam.id = "NIC"; - nic_execparam.setValue(interface); - component->addExecParameter(nic_execparam); // RESOLVE - need SAD file directive to control this behavior.. i.e if promote_nic_to_affinity==true... // for now add nic assignment as application affinity to all components deployed by this device @@ -2561,6 +2557,10 @@ void createHelper::attemptComponentExecution (CF::ApplicationRegistrar_ptr regis // Build up the list of command line parameters redhawk::PropertyMap execParameters(component->getCommandLineParameters()); + const std::string& nic = deployment->getNicAssignment(); + if (!nic.empty()) { + execParameters["NIC"] = nic; + } // Add specialized CPU reservation if given std::map::iterator reservation = specialized_reservations.find(component->getIdentifier()); diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp index b089fa255..7191969dc 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp @@ -851,13 +851,13 @@ CF::Properties ComponentInfo::getAffinityOptions() const return affinityOptions; } -CF::Properties ComponentInfo::getConfigureProperties() +CF::Properties ComponentInfo::getConfigureProperties() const { return configureProperties; } -CF::Properties ComponentInfo::getConstructProperties() +CF::Properties ComponentInfo::getConstructProperties() const { return ctorProperties; } diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.h b/redhawk/src/control/sdr/dommgr/applicationSupport.h index 3f85dbfc1..1970f2604 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.h +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.h @@ -249,8 +249,8 @@ namespace ossie CF::Properties getNonNilConfigureProperties() const; CF::Properties getInitializeProperties() const; - CF::Properties getConfigureProperties(); - CF::Properties getConstructProperties(); + CF::Properties getConfigureProperties() const; + CF::Properties getConstructProperties() const; CF::Properties getOptions(); CF::Properties getAffinityOptions() const; CF::Properties getExecParameters(); From d4346f7ca515e8e4766b8cc325e487fcc3d6069e Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 11 May 2016 10:17:37 -0400 Subject: [PATCH 0192/1644] Break out construction of an individual ComponentInfo into its own function; track start order in ComponentInfo --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 188 +++++++++--------- .../sdr/dommgr/ApplicationFactory_impl.h | 3 +- .../control/sdr/dommgr/applicationSupport.cpp | 17 +- .../control/sdr/dommgr/applicationSupport.h | 4 + 4 files changed, 115 insertions(+), 97 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 04f958643..9ad4f1741 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -2087,122 +2087,120 @@ ossie::SoftpkgDeployment* createHelper::resolveDependencyImplementation(ossie::S return 0; } -/* Create a vector of all the components for the SAD associated with this App Factory - * - Get component information from the SAD and store in _requiredComponents vector - */ -void createHelper::getRequiredComponents() - throw (CF::ApplicationFactory::CreateApplicationError) +ossie::ComponentInfo* createHelper::buildComponentInfo(const ComponentPlacement& component) { - TRACE_ENTER(ApplicationFactory_impl); + // Extract required data from SPD file + ossie::ComponentInfo* newComponent = 0; + LOG_TRACE(ApplicationFactory_impl, "Getting the SPD Filename"); + const char *spdFileName = _appFact._sadParser.getSPDById(component.getFileRefId()); + if (spdFileName == NULL) { + ostringstream eout; + eout << "The SPD file reference for componentfile "< componentsFromSAD = _appFact._sadParser.getAllComponents(); + LOG_TRACE(ApplicationFactory_impl, "Done building Component Info From SPD File") + // Even though it is possible for there to be more than one instantiation per component, + // the tooling doesn't support that, so supporting this at a framework level would add + // substantial complexity without providing any appreciable improvements. It is far + // easier to have multiple placements rather than multiple instantiations. + const vector& instantiations = component.getInstantiations(); - const std::string assemblyControllerRefId = _appFact._sadParser.getAssemblyControllerRefId(); + const ComponentInstantiation& instance = instantiations[0]; - // Bin the start orders based on the values in the SAD. Using a map of - // vectors, keyed on the start order value, accounts for duplicate keys and - // allows assigning the effective order easily by iterating through all - // the values. - std::map > startOrders; + ostringstream identifier; + identifier << instance.getID(); + // Violate SR:172, we use the uniquified name rather than the passed in name + identifier << ":" << _waveformContextName; + newComponent->setIdentifier(identifier.str().c_str(), instance.getID()); - for (unsigned int i = 0; i < componentsFromSAD.size(); i++) { - const ComponentPlacement& component = componentsFromSAD[i]; - - // Create a list of pairs of start orders and instantiation IDs - for (unsigned int ii = 0; ii < component.getInstantiations().size(); ii++) { - // Only add a pair if a start order was provided, and the component is not the assembly controller - if (strcmp(component.getInstantiations()[ii].getStartOrder(), "") != 0 && - component.getInstantiations()[ii].getID() != assemblyControllerRefId) { - // Get the start order of the component - int startOrder = atoi(component.getInstantiations()[ii].getStartOrder()); - std::string instId = component.getInstantiations()[ii].getID(); - startOrders[startOrder].push_back(instId); - } - } - - // Extract required data from SPD file - ossie::ComponentInfo* newComponent = 0; - LOG_TRACE(ApplicationFactory_impl, "Getting the SPD Filename") - const char *spdFileName = _appFact._sadParser.getSPDById(component.getFileRefId()); - if (spdFileName == NULL) { - ostringstream eout; - eout << "The SPD file reference for componentfile "<setNamingService(instance.isNamingService()); + + if (newComponent->isNamingService()) { + ostringstream nameBinding; + nameBinding << instance.getFindByNamingServiceName(); +#if UNIQUIFY_NAME_BINDING +// DON'T USE THIS YET AS IT WILL BREAK OTHER PARTS OF REDHAWK + nameBinding << "_" << i; // Add a _UniqueIdentifier, per SR:169 +#endif + newComponent->setNamingServiceName(nameBinding.str().c_str()); // SR:169 + } else { + if (newComponent->isScaCompliant()) { + LOG_WARN(ApplicationFactory_impl, "component instantiation is sca compliant but does not provide a 'findcomponent' name...this is probably an error") } + } - LOG_TRACE(ApplicationFactory_impl, "Done building Component Info From SPD File") - // Even though it is possible for there to be more than one instantiation per component, - // the tooling doesn't support that, so supporting this at a framework level would add - // substantial complexity without providing any appreciable improvements. It is far - // easier to have multiple placements rather than multiple instantiations. - const vector& instantiations = component.getInstantiations(); + newComponent->setUsageName(instance.getUsageName()); + newComponent->setAffinity( instance.getAffinity() ); + newComponent->setLoggingConfig( instance.getLoggingConfig() ); - const ComponentInstantiation& instance = instantiations[0]; + if (strlen(instance.getStartOrder()) > 0) { + int start_order = atoi(instance.getStartOrder()); + newComponent->setStartOrder(start_order); + } - ostringstream identifier; - identifier << instance.getID(); - // Violate SR:172, we use the uniquified name rather than the passed in name - identifier << ":" << _waveformContextName; - assert(newComponent != 0); - newComponent->setIdentifier(identifier.str().c_str(), instance.getID()); + const ossie::ComponentPropertyList & ins_prop = instance.getProperties(); - if (newComponent->getInstantiationIdentifier() == assemblyControllerRefId) { - newComponent->setIsAssemblyController(true); + int docker_image_idx = -1; + for (unsigned int i = 0; i < ins_prop.size(); ++i) { + if (ins_prop[i]._id == "__DOCKER_IMAGE__") { + docker_image_idx = i; + continue; } + newComponent->overrideProperty(&ins_prop[i]); + } - newComponent->setNamingService(instance.isNamingService()); + if (docker_image_idx > -1) { + CF::Properties tmp; + redhawk::PropertyMap& tmpProp = redhawk::PropertyMap::cast(tmp); + tmpProp["__DOCKER_IMAGE__"].setValue(dynamic_cast(ins_prop[docker_image_idx]).getValue()); + newComponent->addExecParameter(tmpProp[0]); + } - if (newComponent->isNamingService()) { - ostringstream nameBinding; - nameBinding << instance.getFindByNamingServiceName(); -#if UNIQUIFY_NAME_BINDING -// DON'T USE THIS YET AS IT WILL BREAK OTHER PARTS OF REDHAWK - nameBinding << "_" << i; // Add a _UniqueIdentifier, per SR:169 -#endif - newComponent->setNamingServiceName(nameBinding.str().c_str()); // SR:169 - } else { - if (newComponent->isScaCompliant()) { - LOG_WARN(ApplicationFactory_impl, "component instantiation is sca compliant but does not provide a 'findcomponent' name...this is probably an error") - } - } - - newComponent->setUsageName(instance.getUsageName()); - newComponent->setAffinity( instance.getAffinity() ); - newComponent->setLoggingConfig( instance.getLoggingConfig() ); + return newComponent; +} - const ossie::ComponentPropertyList & ins_prop = instance.getProperties(); +/* Create a vector of all the components for the SAD associated with this App Factory + * - Get component information from the SAD and store in _requiredComponents vector + */ +void createHelper::getRequiredComponents() +{ + TRACE_ENTER(ApplicationFactory_impl); - int docker_image_idx = -1; - for (unsigned int i = 0; i < ins_prop.size(); ++i) { - if (ins_prop[i]._id == "__DOCKER_IMAGE__") { - docker_image_idx = i; - continue; - } - newComponent->overrideProperty(&ins_prop[i]); - } + std::vector componentsFromSAD = _appFact._sadParser.getAllComponents(); - if (docker_image_idx > -1) { - CF::Properties tmp; - redhawk::PropertyMap& tmpProp = redhawk::PropertyMap::cast(tmp); - tmpProp["__DOCKER_IMAGE__"].setValue(dynamic_cast(ins_prop[docker_image_idx]).getValue()); - newComponent->addExecParameter(tmpProp[0]); - } + const std::string assemblyControllerRefId = _appFact._sadParser.getAssemblyControllerRefId(); + + // Bin the start orders based on the values in the SAD. Using a multimap, + // keyed on the start order value, accounts for duplicate keys and allows + // assigning the effective order easily by iterating through all entries. + std::multimap start_orders; - _requiredComponents.push_back(newComponent); + for (unsigned int i = 0; i < componentsFromSAD.size(); i++) { + ossie::ComponentInfo* component = buildComponentInfo(componentsFromSAD[i]); + + if (component->getInstantiationIdentifier() == assemblyControllerRefId) { + component->setIsAssemblyController(true); + } else if (component->hasStartOrder()) { + // Only track start order if it was provided, and the component is + // not the assembly controller + start_orders.insert(std::make_pair(component->getStartOrder(), component->getInstantiationIdentifier())); + } + _requiredComponents.push_back(component); } // Build the start order instantiation ID vector in the right order _startOrderIds.clear(); - for (std::map >::iterator ii = startOrders.begin(); ii != startOrders.end(); ++ii) { - _startOrderIds.insert(_startOrderIds.end(), ii->second.begin(), ii->second.end()); + for (std::multimap::iterator ii = start_orders.begin(); ii != start_orders.end(); ++ii) { + _startOrderIds.push_back(ii->second); } TRACE_EXIT(ApplicationFactory_impl); diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h index c0f0985a0..c23d145c0 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h @@ -239,7 +239,8 @@ public ossie::DeviceLookup CF::DataType castProperty(const ossie::ComponentProperty* property); // Populate _requiredComponents vector - void getRequiredComponents() throw (CF::ApplicationFactory::CreateApplicationError); + void getRequiredComponents(); + ossie::ComponentInfo* buildComponentInfo(const ossie::ComponentPlacement& component); // Supports allocation bool allocateUsesDevices(const std::string& componentIdentifier, diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp index 7191969dc..ace72888b 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp @@ -579,7 +579,8 @@ ComponentInfo* ComponentInfo::buildComponentInfoFromSPDFile(CF::FileManager_ptr ComponentInfo::ComponentInfo(const std::string& spdFileName) : SoftpkgInfo(spdFileName), _isAssemblyController(false), - _isScaCompliant(true) + _isScaCompliant(true), + startOrder(-1) { // load common affinity property definitions try { @@ -657,6 +658,10 @@ void ComponentInfo::setLoggingConfig( const LoggingConfig &logcfg ) loggingConfig = logcfg; } +void ComponentInfo::setStartOrder(int index) +{ + startOrder = index; +} void ComponentInfo::addFactoryParameter(CF::DataType dt) { @@ -768,6 +773,16 @@ bool ComponentInfo::isScaCompliant() const return _isScaCompliant; } +bool ComponentInfo::hasStartOrder() const +{ + return startOrder > -1; +} + +int ComponentInfo::getStartOrder() const +{ + return startOrder; +} + bool ComponentInfo::checkStruct(const CF::Properties &props) const { const redhawk::PropertyMap& tmpProps = redhawk::PropertyMap::cast(props); diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.h b/redhawk/src/control/sdr/dommgr/applicationSupport.h index 1970f2604..13a660578 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.h +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.h @@ -221,6 +221,7 @@ namespace ossie void setIsScaCompliant(bool isScaCompliant); void setAffinity( const AffinityProperties &affinity ); void setLoggingConfig( const LoggingConfig &logcfg ); + void setStartOrder(int index); void addFactoryParameter(CF::DataType dt); void addExecParameter(CF::DataType dt); @@ -240,6 +241,8 @@ namespace ossie bool isConfigurable() const; bool isAssemblyController() const; bool isScaCompliant() const; + bool hasStartOrder() const; + int getStartOrder() const; bool isAssignedToDevice() const; CF::Properties containsPartialStructConfig() const; @@ -273,6 +276,7 @@ namespace ossie std::string identifier; std::string instantiationId; std::string namingServiceName; + int startOrder; ossie::Properties _affinity_prf; LoggingConfig loggingConfig; From 302429f14c40019b6e82427b5e2174f722ecd61a Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 11 May 2016 11:17:42 -0400 Subject: [PATCH 0193/1644] Build the required components by walking through the host collocations first, then the single placements, instead of using the combined list from the SoftwareAssembly; eventually, this will allow better planning of deployments --- .../control/include/ossie/SoftwareAssembly.h | 2 ++ .../src/control/parser/SoftwareAssembly.cpp | 6 ++++ .../sdr/dommgr/ApplicationFactory_impl.cpp | 33 ++++++++++++++----- 3 files changed, 32 insertions(+), 9 deletions(-) diff --git a/redhawk/src/control/include/ossie/SoftwareAssembly.h b/redhawk/src/control/include/ossie/SoftwareAssembly.h index 43d7a7bae..b22276ba3 100644 --- a/redhawk/src/control/include/ossie/SoftwareAssembly.h +++ b/redhawk/src/control/include/ossie/SoftwareAssembly.h @@ -150,6 +150,8 @@ namespace ossie { std::vector getAllComponents() const; + const std::vector& getComponentPlacements() const; + const std::vector& getHostCollocations() const; const std::vector& getConnections() const; diff --git a/redhawk/src/control/parser/SoftwareAssembly.cpp b/redhawk/src/control/parser/SoftwareAssembly.cpp index e88908f78..ccb21f585 100644 --- a/redhawk/src/control/parser/SoftwareAssembly.cpp +++ b/redhawk/src/control/parser/SoftwareAssembly.cpp @@ -66,6 +66,12 @@ std::vector SoftwareAssembly::getAllComponents() const { return result; } +const std::vector& SoftwareAssembly::getComponentPlacements() const +{ + assert(_sad.get() != 0); + return _sad->partitioning.placements; +} + const std::vector& SoftwareAssembly::getHostCollocations() const { assert(_sad.get() != 0); return _sad->partitioning.collocations; diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 9ad4f1741..51999039c 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -2175,26 +2175,41 @@ void createHelper::getRequiredComponents() { TRACE_ENTER(ApplicationFactory_impl); - std::vector componentsFromSAD = _appFact._sadParser.getAllComponents(); - - const std::string assemblyControllerRefId = _appFact._sadParser.getAssemblyControllerRefId(); - - // Bin the start orders based on the values in the SAD. Using a multimap, - // keyed on the start order value, accounts for duplicate keys and allows - // assigning the effective order easily by iterating through all entries. - std::multimap start_orders; + // Walk through the host collocations first + const std::vector& collocations = _appFact._sadParser.getHostCollocations(); + for (size_t index = 0; index < collocations.size(); ++index) { + LOG_TRACE(ApplicationFactory_impl, "Building component info for host collocation " + << collocations[index].getID()); + const std::vector& placements = collocations[index].getComponents(); + for (unsigned int i = 0; i < placements.size(); i++) { + ossie::ComponentInfo* component = buildComponentInfo(placements[i]); + _requiredComponents.push_back(component); + } + } + // Then, walk through the remaining non-collocated components + const std::vector& componentsFromSAD = _appFact._sadParser.getComponentPlacements(); for (unsigned int i = 0; i < componentsFromSAD.size(); i++) { ossie::ComponentInfo* component = buildComponentInfo(componentsFromSAD[i]); + _requiredComponents.push_back(component); + } + // Now that all of the components are know, bin the start orders based on + // the values in the SAD. Using a multimap, keyed on the start order value, + // accounts for duplicate keys and allows assigning the effective order + // easily by iterating through all entries. + const std::string assemblyControllerRefId = _appFact._sadParser.getAssemblyControllerRefId(); + std::multimap start_orders; + for (size_t index = 0; index < _requiredComponents.size(); ++index) { + ossie::ComponentInfo* component = _requiredComponents[index]; if (component->getInstantiationIdentifier() == assemblyControllerRefId) { + // Mark the assembly controller while we're at it component->setIsAssemblyController(true); } else if (component->hasStartOrder()) { // Only track start order if it was provided, and the component is // not the assembly controller start_orders.insert(std::make_pair(component->getStartOrder(), component->getInstantiationIdentifier())); } - _requiredComponents.push_back(component); } // Build the start order instantiation ID vector in the right order From a10b1be2d0877a4c10f0337f256bdb3895d002ad Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 11 May 2016 12:46:58 -0400 Subject: [PATCH 0194/1644] Create a placement plan up front, which includes host collocation, and then assign devices accordingly, instead of doing three-phase placement (DAS, collocation, remainder) --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 116 ++++++++---------- .../sdr/dommgr/ApplicationFactory_impl.h | 12 +- .../control/sdr/dommgr/applicationSupport.cpp | 30 +++++ .../control/sdr/dommgr/applicationSupport.h | 19 +++ 4 files changed, 109 insertions(+), 68 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 51999039c..cfd0ef23a 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -686,36 +686,38 @@ void createHelper::_configureComponents() CF::ApplicationFactory::CreateApplicationError(CF::CF_EINVAL, "Configure of component failed (unclear where in the process this occurred)")) } -void createHelper::assignRemainingComponentsToDevices(const std::string &appIdentifier) +void createHelper::assignPlacementsToDevices(const std::string& appIdentifier, const DeviceAssignmentMap& devices) { - PlacementList::iterator componentIter; - for (componentIter = _requiredComponents.begin(); - componentIter != _requiredComponents.end(); - componentIter++) - { - boost::shared_ptr assignedDevice; - for (DeploymentList::iterator ii = _deployments.begin(); ii != _deployments.end(); ++ii) { - if ((*ii)->getComponent() == (*componentIter)) { - assignedDevice = (*ii)->getAssignedDevice(); - break; + for (PlacementPlanList::iterator plan = _placements.begin(); plan != _placements.end(); ++plan) { + const std::vector& components = (*plan)->getComponents(); + if (components.size() > 1) { + LOG_TRACE(ApplicationFactory_impl, "Placing host collocation " << (*plan)->getId() + << " " << (*plan)->getName()); + _placeHostCollocation(appIdentifier, components, devices); + LOG_TRACE(ApplicationFactory_impl, "-- Completed placement for Collocation ID:" + << (*plan)->getId() << " Components Placed: " << components.size()); + } else { + ComponentInfo* component = components[0]; + std::string assigned_device; + DeviceAssignmentMap::const_iterator device = devices.find(component->getInstantiationIdentifier()); + if (device != devices.end()) { + assigned_device = device->second; + LOG_TRACE(ApplicationFactory_impl, "Component " << component->getInstantiationIdentifier() + << " is assigned to device " << assigned_device); } - } - if (!assignedDevice) { - ossie::ComponentDeployment* deployment = allocateComponent(*componentIter, std::string(), _appUsedDevs, appIdentifier); + ossie::ComponentDeployment* deployment = allocateComponent(component, assigned_device, _appUsedDevs, appIdentifier); _deployments.push_back(deployment); } } } -void createHelper::_assignComponentsUsingDAS(const DeviceAssignmentMap& deviceAssignments, const std::string &appIdentifier) +void createHelper::_validateDAS(const DeviceAssignmentMap& deviceAssignments) { - LOG_TRACE(ApplicationFactory_impl, "Assigning " << deviceAssignments.size() - << " component(s) based on DeviceAssignmentSequence"); - + LOG_TRACE(ApplicationFactory_impl, "Validating device assignment sequence (length " + << deviceAssignments.size() << ")"); for (DeviceAssignmentMap::const_iterator ii = deviceAssignments.begin(); ii != deviceAssignments.end(); ++ii) { const std::string& componentId = ii->first; const std::string& assignedDeviceId = ii->second; - LOG_TRACE(ApplicationFactory_impl, "Component " << componentId << " is assigned to device " << assignedDeviceId); ossie::ComponentInfo* component = findComponentByInstantiationId(componentId); if (!component) { @@ -728,8 +730,6 @@ void createHelper::_assignComponentsUsingDAS(const DeviceAssignmentMap& deviceAs badDAS[0].assignedDeviceId = assignedDeviceId.c_str(); throw CF::ApplicationFactory::CreateApplicationRequestError(badDAS); } - ossie::ComponentDeployment* deployment = allocateComponent(component, assignedDeviceId, _appUsedDevs, appIdentifier); - _deployments.push_back(deployment); } } @@ -889,49 +889,30 @@ void createHelper::_consolidateAllocations(const ossie::ImplementationInfo::List } } -void createHelper::_handleHostCollocation(const std::string &appIdentifier) -{ - const std::vector& hostCollocations = - _appFact._sadParser.getHostCollocations(); - LOG_TRACE(ApplicationFactory_impl, - "Assigning " << hostCollocations.size() - << " collocated groups of components"); - - for (unsigned int ii = 0; ii < hostCollocations.size(); ++ii) { - _placeHostCollocation(hostCollocations[ii], appIdentifier); - } -} - -void createHelper::_placeHostCollocation(const SoftwareAssembly::HostCollocation& collocation, const std::string &appIdentifier) +void createHelper::_placeHostCollocation(const std::string &appIdentifier, + const PlacementList& collocatedComponents, + const DeviceAssignmentMap& devices) { - LOG_TRACE(ApplicationFactory_impl, - "-- Begin placment for Collocation " << - collocation.getName() << " " << - collocation.getID()); - - PlacementList placingComponents; - std::vector res_vec; - - // Some components may have been placed by a user DAS; keep a - // list of those that still need to be assigned to a device. - //PlacementList placingComponents; - // Keep track of devices to which some of the components have // been assigned. DeviceIDList assignedDevices; + for (PlacementList::const_iterator placement = collocatedComponents.begin(); + placement != collocatedComponents.end(); + ++placement) { + DeviceAssignmentMap::const_iterator device = devices.find((*placement)->getInstantiationIdentifier()); + if (device != devices.end()) { + assignedDevices.push_back(device->second); + } + } - const std::vector& collocatedComponents = - collocation.getComponents(); - - _getComponentsToPlace(collocatedComponents, - assignedDevices, - placingComponents); + PlacementList placingComponents = collocatedComponents; // create every combination of implementations for the components in the set // for each combination: // consolidate allocations // attempt allocation // if the allocation succeeds, break the loop + std::vector res_vec; this->_resolveImplementations(placingComponents.begin(), placingComponents, res_vec); this->_removeUnmatchedImplementations(res_vec); @@ -991,13 +972,13 @@ void createHelper::_placeHostCollocation(const SoftwareAssembly::HostCollocation _appUsedDevs.insert(_appUsedDevs.end(), collocAssignedDevs.begin(), collocAssignedDevs.end()); - LOG_TRACE(ApplicationFactory_impl, "-- Completed placement for Collocation ID:" << collocation.id << " Components Placed: " << collocatedComponents.size()); return; } } std::ostringstream eout; - eout << "Could not collocate components for collocation NAME: " << collocation.getName() << " ID:" << collocation.id; + //eout << "Could not collocate components for collocation NAME: " << collocation.getName() << " ID:" << collocation.id; + eout << "Could not collocate components for collocation"; LOG_ERROR(ApplicationFactory_impl, eout.str()); throw CF::ApplicationFactory::CreateApplicationRequestError(); } @@ -1400,14 +1381,11 @@ throw (CORBA::SystemException, std::string appIdentifier = _appFact._identifier + ":" + _waveformContextName; - // First, assign components to devices based on the caller supplied - // DAS. - _assignComponentsUsingDAS(deviceAssignments, appIdentifier); + // Catch invalid device assignments + _validateDAS(deviceAssignments); - // Second, attempt to honor host collocation. - _handleHostCollocation(appIdentifier); - - assignRemainingComponentsToDevices(appIdentifier); + // Assign all components to devices + assignPlacementsToDevices(appIdentifier, deviceAssignments); //////////////////////////////////////////////// // Create the Application servant @@ -2178,11 +2156,16 @@ void createHelper::getRequiredComponents() // Walk through the host collocations first const std::vector& collocations = _appFact._sadParser.getHostCollocations(); for (size_t index = 0; index < collocations.size(); ++index) { + const SoftwareAssembly::HostCollocation& collocation = collocations[index]; LOG_TRACE(ApplicationFactory_impl, "Building component info for host collocation " - << collocations[index].getID()); + << collocation.getID()); + ossie::PlacementPlan* plan = new ossie::PlacementPlan(collocation.getID(), collocation.getName()); + _placements.push_back(plan); + const std::vector& placements = collocations[index].getComponents(); for (unsigned int i = 0; i < placements.size(); i++) { ossie::ComponentInfo* component = buildComponentInfo(placements[i]); + plan->addComponent(component); _requiredComponents.push_back(component); } } @@ -2190,7 +2173,10 @@ void createHelper::getRequiredComponents() // Then, walk through the remaining non-collocated components const std::vector& componentsFromSAD = _appFact._sadParser.getComponentPlacements(); for (unsigned int i = 0; i < componentsFromSAD.size(); i++) { + ossie::PlacementPlan* plan = new ossie::PlacementPlan(); + _placements.push_back(plan); ossie::ComponentInfo* component = buildComponentInfo(componentsFromSAD[i]); + plan->addComponent(component); _requiredComponents.push_back(component); } @@ -3140,6 +3126,10 @@ createHelper::~createHelper() delete (*comp); } _requiredComponents.clear(); + for (PlacementPlanList::iterator plan = _placements.begin(); plan != _placements.end(); ++plan) { + delete (*plan); + } + _placements.clear(); for (DeploymentList::iterator depl = _deployments.begin(); depl != _deployments.end(); ++depl) { delete (*depl); } diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h index c23d145c0..f9d988dfd 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h @@ -204,6 +204,9 @@ public ossie::DeviceLookup ossie::ApplicationInfo _appInfo; + typedef std::vector PlacementPlanList; + PlacementPlanList _placements; + typedef std::vector DeploymentList; DeploymentList _deployments; @@ -211,9 +214,8 @@ public ossie::DeviceLookup ossie::ComponentInfo* getAssemblyController(); void overrideExternalProperties(const CF::Properties& initConfiguration); void overrideProperties(const CF::Properties& initConfiguration, ossie::ComponentInfo* component); - void assignRemainingComponentsToDevices(const std::string &appIdentifier); - void _assignComponentsUsingDAS( - const DeviceAssignmentMap& deviceAssignments, const std::string &appIdentifier); + void assignPlacementsToDevices(const std::string& appIdentifier, const DeviceAssignmentMap& devices); + void _validateDAS(const DeviceAssignmentMap& deviceAssignments); void _getComponentsToPlace( const std::vector& collocatedComponents, ossie::DeviceIDList& assignedDevices, @@ -226,8 +228,8 @@ public ossie::DeviceLookup ossie::ComponentInfo* assemblyControllerComponent) const; void setUpExternalPorts(Application_impl* application); void setUpExternalProperties(Application_impl* application); - void _handleHostCollocation(const std::string &appIdentifier); - void _placeHostCollocation(const ossie::SoftwareAssembly::HostCollocation& collocation, const std::string &appIdentifier); + void _placeHostCollocation(const std::string& appIdentifier, const PlacementList& collocatedComponents, + const DeviceAssignmentMap& devices); void _handleUsesDevices(const std::string& appName); void _resolveImplementations(PlacementList::iterator comp, PlacementList& compList, std::vector &res_vec); void _removeUnmatchedImplementations(std::vector &res_vec); diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp index ace72888b..07743b445 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp @@ -1019,3 +1019,33 @@ ComponentInfo* ApplicationInfo::findComponentByInstantiationId(const std::string } return 0; } + +PlacementPlan::PlacementPlan() +{ +} + +PlacementPlan::PlacementPlan(const std::string& id, const std::string& name) : + id(id), + name(name) +{ +} + +const std::string& PlacementPlan::getId() const +{ + return id; +} + +const std::string& PlacementPlan::getName() const +{ + return name; +} + +const std::vector& PlacementPlan::getComponents() const +{ + return components; +} + +void PlacementPlan::addComponent(ComponentInfo* component) +{ + components.push_back(component); +} diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.h b/redhawk/src/control/sdr/dommgr/applicationSupport.h index 13a660578..2141ee37e 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.h +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.h @@ -331,5 +331,24 @@ namespace ossie std::vector components; }; + class PlacementPlan + { + public: + PlacementPlan(); + PlacementPlan(const std::string& id, const std::string& name); + + const std::string& getId() const; + const std::string& getName() const; + + const std::vector& getComponents() const; + + void addComponent(ComponentInfo* component); + + protected: + std::string id; + std::string name; + std::vector components; + }; + } #endif From 5048dd5dcd73c767a6c48f5d167051ad2b439ce8 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 11 May 2016 14:26:21 -0400 Subject: [PATCH 0195/1644] Track the set of placement plans in an application object, in a function-local scope --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 23 ++++++++++--------- .../sdr/dommgr/ApplicationFactory_impl.h | 9 ++++---- .../control/sdr/dommgr/applicationSupport.cpp | 21 +++++++++++++++++ .../control/sdr/dommgr/applicationSupport.h | 16 +++++++++++++ 4 files changed, 53 insertions(+), 16 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index cfd0ef23a..7ea3240ee 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -686,9 +686,12 @@ void createHelper::_configureComponents() CF::ApplicationFactory::CreateApplicationError(CF::CF_EINVAL, "Configure of component failed (unclear where in the process this occurred)")) } -void createHelper::assignPlacementsToDevices(const std::string& appIdentifier, const DeviceAssignmentMap& devices) +void createHelper::assignPlacementsToDevices(ossie::ApplicationPlacement& appPlacement, + const std::string& appIdentifier, const DeviceAssignmentMap& devices) { - for (PlacementPlanList::iterator plan = _placements.begin(); plan != _placements.end(); ++plan) { + typedef ossie::ApplicationPlacement::PlacementList PlacementPlanList; + const PlacementPlanList& placements = appPlacement.getPlacements(); + for (PlacementPlanList::const_iterator plan = placements.begin(); plan != placements.end(); ++plan) { const std::vector& components = (*plan)->getComponents(); if (components.size() > 1) { LOG_TRACE(ApplicationFactory_impl, "Placing host collocation " << (*plan)->getId() @@ -1347,7 +1350,8 @@ throw (CORBA::SystemException, ////////////////////////////////////////////////// // Load the components to instantiate from the SAD - getRequiredComponents(); + ossie::ApplicationPlacement placement; + getRequiredComponents(placement); ossie::ComponentInfo* assemblyControllerComponent = getAssemblyController(); if (assemblyControllerComponent) { @@ -1385,7 +1389,7 @@ throw (CORBA::SystemException, _validateDAS(deviceAssignments); // Assign all components to devices - assignPlacementsToDevices(appIdentifier, deviceAssignments); + assignPlacementsToDevices(placement, appIdentifier, deviceAssignments); //////////////////////////////////////////////// // Create the Application servant @@ -2149,7 +2153,7 @@ ossie::ComponentInfo* createHelper::buildComponentInfo(const ComponentPlacement& /* Create a vector of all the components for the SAD associated with this App Factory * - Get component information from the SAD and store in _requiredComponents vector */ -void createHelper::getRequiredComponents() +void createHelper::getRequiredComponents(ossie::ApplicationPlacement& appPlacement) { TRACE_ENTER(ApplicationFactory_impl); @@ -2160,7 +2164,7 @@ void createHelper::getRequiredComponents() LOG_TRACE(ApplicationFactory_impl, "Building component info for host collocation " << collocation.getID()); ossie::PlacementPlan* plan = new ossie::PlacementPlan(collocation.getID(), collocation.getName()); - _placements.push_back(plan); + appPlacement.addPlacement(plan); const std::vector& placements = collocations[index].getComponents(); for (unsigned int i = 0; i < placements.size(); i++) { @@ -2174,7 +2178,7 @@ void createHelper::getRequiredComponents() const std::vector& componentsFromSAD = _appFact._sadParser.getComponentPlacements(); for (unsigned int i = 0; i < componentsFromSAD.size(); i++) { ossie::PlacementPlan* plan = new ossie::PlacementPlan(); - _placements.push_back(plan); + appPlacement.addPlacement(plan); ossie::ComponentInfo* component = buildComponentInfo(componentsFromSAD[i]); plan->addComponent(component); _requiredComponents.push_back(component); @@ -3126,10 +3130,7 @@ createHelper::~createHelper() delete (*comp); } _requiredComponents.clear(); - for (PlacementPlanList::iterator plan = _placements.begin(); plan != _placements.end(); ++plan) { - delete (*plan); - } - _placements.clear(); + for (DeploymentList::iterator depl = _deployments.begin(); depl != _deployments.end(); ++depl) { delete (*depl); } diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h index f9d988dfd..988b1fd7c 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h @@ -204,9 +204,6 @@ public ossie::DeviceLookup ossie::ApplicationInfo _appInfo; - typedef std::vector PlacementPlanList; - PlacementPlanList _placements; - typedef std::vector DeploymentList; DeploymentList _deployments; @@ -214,7 +211,9 @@ public ossie::DeviceLookup ossie::ComponentInfo* getAssemblyController(); void overrideExternalProperties(const CF::Properties& initConfiguration); void overrideProperties(const CF::Properties& initConfiguration, ossie::ComponentInfo* component); - void assignPlacementsToDevices(const std::string& appIdentifier, const DeviceAssignmentMap& devices); + void assignPlacementsToDevices(ossie::ApplicationPlacement& appPlacement, + const std::string& appIdentifier, + const DeviceAssignmentMap& devices); void _validateDAS(const DeviceAssignmentMap& deviceAssignments); void _getComponentsToPlace( const std::vector& collocatedComponents, @@ -241,7 +240,7 @@ public ossie::DeviceLookup CF::DataType castProperty(const ossie::ComponentProperty* property); // Populate _requiredComponents vector - void getRequiredComponents(); + void getRequiredComponents(ossie::ApplicationPlacement& appPlacement); ossie::ComponentInfo* buildComponentInfo(const ossie::ComponentPlacement& component); // Supports allocation diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp index 07743b445..efc284f58 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp @@ -1049,3 +1049,24 @@ void PlacementPlan::addComponent(ComponentInfo* component) { components.push_back(component); } + +ApplicationPlacement::ApplicationPlacement() +{ +} + +ApplicationPlacement::~ApplicationPlacement() +{ + for (std::vector::iterator place = placements.begin(); place != placements.end(); ++place) { + delete (*place); + } +} + +void ApplicationPlacement::addPlacement(PlacementPlan* placement) +{ + placements.push_back(placement); +} + +const std::vector& ApplicationPlacement::getPlacements() const +{ + return placements; +} diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.h b/redhawk/src/control/sdr/dommgr/applicationSupport.h index 2141ee37e..548d3fc98 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.h +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.h @@ -350,5 +350,21 @@ namespace ossie std::vector components; }; + class ApplicationPlacement + { + public: + typedef std::vector PlacementList; + + ApplicationPlacement(); + ~ApplicationPlacement(); + + void addPlacement(PlacementPlan* placement); + + const PlacementList& getPlacements() const; + + protected: + PlacementList placements; + }; + } #endif From 0dfd7b69f43e077fcbfffa6bcf74df0d36bfdb7e Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 11 May 2016 14:34:11 -0400 Subject: [PATCH 0196/1644] Move placement classes into their own header/source files; remove unused function --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 57 ++------------ .../sdr/dommgr/ApplicationFactory_impl.h | 5 +- redhawk/src/control/sdr/dommgr/Makefile.am | 1 + redhawk/src/control/sdr/dommgr/Placement.cpp | 74 +++++++++++++++++++ redhawk/src/control/sdr/dommgr/Placement.h | 68 +++++++++++++++++ .../control/sdr/dommgr/applicationSupport.cpp | 51 ------------- .../control/sdr/dommgr/applicationSupport.h | 35 --------- 7 files changed, 149 insertions(+), 142 deletions(-) create mode 100644 redhawk/src/control/sdr/dommgr/Placement.cpp create mode 100644 redhawk/src/control/sdr/dommgr/Placement.h diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 7ea3240ee..222e3d319 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -986,54 +986,6 @@ void createHelper::_placeHostCollocation(const std::string &appIdentifier, throw CF::ApplicationFactory::CreateApplicationRequestError(); } -void createHelper::_getComponentsToPlace( - const std::vector& collocatedComponents, - DeviceIDList& assignedDevices, - PlacementList& placingComponents) -{ - std::vector::const_iterator placement = - collocatedComponents.begin(); - - for (; placement != collocatedComponents.end(); ++placement) { - ComponentInstantiation instantiation = - (placement->getInstantiations()).at(0); - ossie::ComponentInfo* component = - findComponentByInstantiationId(instantiation.getID()); - - if (!component) { - ostringstream eout; - eout << "Failed to create application; unable to recover component Id (error parsing the SAD file: "<<_appFact._softwareProfile<<")"; - LOG_ERROR(ApplicationFactory_impl, eout.str()); - throw CF::ApplicationFactory::CreateApplicationError( - CF::CF_EAGAIN, - eout.str().c_str()); - } - LOG_TRACE(ApplicationFactory_impl, - "Collocated component " << - component->getInstantiationIdentifier()); - - boost::shared_ptr assignedDevice; - for (DeploymentList::iterator ii = _deployments.begin(); ii != _deployments.end(); ++ii) { - if ((*ii)->getComponent() == component) { - assignedDevice = (*ii)->getAssignedDevice(); - break; - } - } - if (assignedDevice) { - // This component is already assigned to a device; for collocating - // other components, the pre-assigned devices are used in the order - // they are encountered. - LOG_TRACE(ApplicationFactory_impl, - "Already assigned to device " << - assignedDevice->identifier); - assignedDevices.push_back(assignedDevice->identifier); - } else { - // This component needs to be assigned to a device. - placingComponents.push_back(component); - } - } -} - void createHelper::_handleUsesDevices(const std::string& appName) { // Gets all uses device info from the SAD file @@ -2748,9 +2700,10 @@ void createHelper::waitForComponentRegistration() // Track only SCA-compliant components; non-compliant components will never // register with the application, nor do they need to be initialized std::set expected_components; - for (PlacementList::iterator ii = _requiredComponents.begin(); ii != _requiredComponents.end(); ++ii) { - if ((*ii)->isScaCompliant()) { - expected_components.insert((*ii)->getIdentifier()); + for (DeploymentList::iterator ii = _deployments.begin(); ii != _deployments.end(); ++ii) { + ossie::ComponentInfo* component = (*ii)->getComponent(); + if (component->isScaCompliant()) { + expected_components.insert(component->getIdentifier()); } } @@ -2786,7 +2739,7 @@ void createHelper::waitForComponentRegistration() void createHelper::initializeComponents() { // Install the different components in the system - LOG_TRACE(ApplicationFactory_impl, "initializing " << _requiredComponents.size() << " waveform components") + LOG_TRACE(ApplicationFactory_impl, "initializing " << _deployments.size() << " waveform components") // Resize the _startSeq vector to the right size _startSeq.resize(_startOrderIds.size()); diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h index 988b1fd7c..1d874beb1 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h @@ -35,6 +35,7 @@ #include "PersistenceStore.h" #include "applicationSupport.h" #include "connectionSupport.h" +#include "Placement.h" #include "Deployment.h" class DomainManager_impl; @@ -215,10 +216,6 @@ public ossie::DeviceLookup const std::string& appIdentifier, const DeviceAssignmentMap& devices); void _validateDAS(const DeviceAssignmentMap& deviceAssignments); - void _getComponentsToPlace( - const std::vector& collocatedComponents, - ossie::DeviceIDList& assignedDevices, - PlacementList& placingComponents); void _connectComponents( std::vector& connections); void _configureComponents(); diff --git a/redhawk/src/control/sdr/dommgr/Makefile.am b/redhawk/src/control/sdr/dommgr/Makefile.am index 266099569..031870d37 100644 --- a/redhawk/src/control/sdr/dommgr/Makefile.am +++ b/redhawk/src/control/sdr/dommgr/Makefile.am @@ -34,6 +34,7 @@ DomainManager_SOURCES = applicationSupport.cpp \ RH_NamingContext.cpp \ DomainManager_impl.cpp \ FakeApplication.cpp \ + Placement.cpp \ Deployment.cpp \ main.cpp DomainManager_CPPFLAGS = -I../../include -I../../parser -I$(top_srcdir)/base/include -I$(top_srcdir)/base $(BOOST_CPPFLAGS) $(OMNIORB_CFLAGS) $(LOG4CXX_FLAGS) diff --git a/redhawk/src/control/sdr/dommgr/Placement.cpp b/redhawk/src/control/sdr/dommgr/Placement.cpp new file mode 100644 index 000000000..533e55fc1 --- /dev/null +++ b/redhawk/src/control/sdr/dommgr/Placement.cpp @@ -0,0 +1,74 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK core. + * + * REDHAWK core is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +#include "Placement.h" + +using namespace ossie; + +PlacementPlan::PlacementPlan() +{ +} + +PlacementPlan::PlacementPlan(const std::string& id, const std::string& name) : + id(id), + name(name) +{ +} + +const std::string& PlacementPlan::getId() const +{ + return id; +} + +const std::string& PlacementPlan::getName() const +{ + return name; +} + +const std::vector& PlacementPlan::getComponents() const +{ + return components; +} + +void PlacementPlan::addComponent(ComponentInfo* component) +{ + components.push_back(component); +} + +ApplicationPlacement::ApplicationPlacement() +{ +} + +ApplicationPlacement::~ApplicationPlacement() +{ + for (std::vector::iterator place = placements.begin(); place != placements.end(); ++place) { + delete (*place); + } +} + +void ApplicationPlacement::addPlacement(PlacementPlan* placement) +{ + placements.push_back(placement); +} + +const std::vector& ApplicationPlacement::getPlacements() const +{ + return placements; +} diff --git a/redhawk/src/control/sdr/dommgr/Placement.h b/redhawk/src/control/sdr/dommgr/Placement.h new file mode 100644 index 000000000..e6e9f46ea --- /dev/null +++ b/redhawk/src/control/sdr/dommgr/Placement.h @@ -0,0 +1,68 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK core. + * + * REDHAWK core is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +#ifndef PLACEMENT_H +#define PLACEMENT_H + +#include +#include + +#include "applicationSupport.h" + +namespace ossie { + + class PlacementPlan + { + public: + PlacementPlan(); + PlacementPlan(const std::string& id, const std::string& name); + + const std::string& getId() const; + const std::string& getName() const; + + const std::vector& getComponents() const; + + void addComponent(ComponentInfo* component); + + protected: + std::string id; + std::string name; + std::vector components; + }; + + class ApplicationPlacement + { + public: + typedef std::vector PlacementList; + + ApplicationPlacement(); + ~ApplicationPlacement(); + + void addPlacement(PlacementPlan* placement); + + const PlacementList& getPlacements() const; + + protected: + PlacementList placements; + }; + +} + +#endif // PLACEMENT_H diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp index efc284f58..ace72888b 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp @@ -1019,54 +1019,3 @@ ComponentInfo* ApplicationInfo::findComponentByInstantiationId(const std::string } return 0; } - -PlacementPlan::PlacementPlan() -{ -} - -PlacementPlan::PlacementPlan(const std::string& id, const std::string& name) : - id(id), - name(name) -{ -} - -const std::string& PlacementPlan::getId() const -{ - return id; -} - -const std::string& PlacementPlan::getName() const -{ - return name; -} - -const std::vector& PlacementPlan::getComponents() const -{ - return components; -} - -void PlacementPlan::addComponent(ComponentInfo* component) -{ - components.push_back(component); -} - -ApplicationPlacement::ApplicationPlacement() -{ -} - -ApplicationPlacement::~ApplicationPlacement() -{ - for (std::vector::iterator place = placements.begin(); place != placements.end(); ++place) { - delete (*place); - } -} - -void ApplicationPlacement::addPlacement(PlacementPlan* placement) -{ - placements.push_back(placement); -} - -const std::vector& ApplicationPlacement::getPlacements() const -{ - return placements; -} diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.h b/redhawk/src/control/sdr/dommgr/applicationSupport.h index 548d3fc98..13a660578 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.h +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.h @@ -331,40 +331,5 @@ namespace ossie std::vector components; }; - class PlacementPlan - { - public: - PlacementPlan(); - PlacementPlan(const std::string& id, const std::string& name); - - const std::string& getId() const; - const std::string& getName() const; - - const std::vector& getComponents() const; - - void addComponent(ComponentInfo* component); - - protected: - std::string id; - std::string name; - std::vector components; - }; - - class ApplicationPlacement - { - public: - typedef std::vector PlacementList; - - ApplicationPlacement(); - ~ApplicationPlacement(); - - void addPlacement(PlacementPlan* placement); - - const PlacementList& getPlacements() const; - - protected: - PlacementList placements; - }; - } #endif From 7442c0f46ce57136328ab1d91b7f4689c34fd771 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 11 May 2016 14:44:54 -0400 Subject: [PATCH 0197/1644] Get the assembly controller from the application placement object --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 18 ++++-------------- .../sdr/dommgr/ApplicationFactory_impl.h | 3 +-- redhawk/src/control/sdr/dommgr/Placement.cpp | 14 ++++++++++++++ redhawk/src/control/sdr/dommgr/Placement.h | 2 ++ 4 files changed, 21 insertions(+), 16 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 222e3d319..43f6a2c4e 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -986,7 +986,7 @@ void createHelper::_placeHostCollocation(const std::string &appIdentifier, throw CF::ApplicationFactory::CreateApplicationRequestError(); } -void createHelper::_handleUsesDevices(const std::string& appName) +void createHelper::_handleUsesDevices(ossie::ApplicationPlacement& appPlacement, const std::string& appName) { // Gets all uses device info from the SAD file const UsesDeviceInfo::List& usesDevices = _appInfo.getUsesDevices(); @@ -1014,7 +1014,7 @@ void createHelper::_handleUsesDevices(const std::string& appName) throw CF::ApplicationFactory::CreateApplicationError(CF::CF_ENOSPC, eout.str().c_str()); } for (DeviceAssignmentList::iterator dev=assignedDevices.begin(); dev!=assignedDevices.end(); dev++) { - dev->deviceAssignment.componentId = getAssemblyController()->getIdentifier().c_str(); + dev->deviceAssignment.componentId = appPlacement.getAssemblyController()->getIdentifier().c_str(); } _appUsedDevs.insert(_appUsedDevs.end(), assignedDevices.begin(), assignedDevices.end()); } @@ -1305,7 +1305,7 @@ throw (CORBA::SystemException, ossie::ApplicationPlacement placement; getRequiredComponents(placement); - ossie::ComponentInfo* assemblyControllerComponent = getAssemblyController(); + ossie::ComponentInfo* assemblyControllerComponent = placement.getAssemblyController(); if (assemblyControllerComponent) { overrideProperties(modifiedInitConfiguration, assemblyControllerComponent); } @@ -1328,7 +1328,7 @@ throw (CORBA::SystemException, //////////////////////////////////////////////// // Allocate any usesdevice capacities specified in the SAD file - _handleUsesDevices(name); + _handleUsesDevices(placement, name); // Give the application a unique identifier of the form // "softwareassemblyid:ApplicationName", where the application @@ -1449,16 +1449,6 @@ throw (CORBA::SystemException, } -ossie::ComponentInfo* createHelper::getAssemblyController() -{ - for (PlacementList::iterator ii = _requiredComponents.begin(); ii != _requiredComponents.end(); ++ii) { - if ((*ii)->isAssemblyController()) { - return *ii; - } - } - return 0; -} - void createHelper::overrideExternalProperties(const CF::Properties& initConfiguration) { const std::vector& props = _appInfo.getExternalProperties(); diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h index 1d874beb1..541fb6300 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h @@ -209,7 +209,6 @@ public ossie::DeviceLookup DeploymentList _deployments; // createHelper helper methods - ossie::ComponentInfo* getAssemblyController(); void overrideExternalProperties(const CF::Properties& initConfiguration); void overrideProperties(const CF::Properties& initConfiguration, ossie::ComponentInfo* component); void assignPlacementsToDevices(ossie::ApplicationPlacement& appPlacement, @@ -226,7 +225,7 @@ public ossie::DeviceLookup void setUpExternalProperties(Application_impl* application); void _placeHostCollocation(const std::string& appIdentifier, const PlacementList& collocatedComponents, const DeviceAssignmentMap& devices); - void _handleUsesDevices(const std::string& appName); + void _handleUsesDevices(ossie::ApplicationPlacement& appPlacement, const std::string& appName); void _resolveImplementations(PlacementList::iterator comp, PlacementList& compList, std::vector &res_vec); void _removeUnmatchedImplementations(std::vector &res_vec); void _consolidateAllocations(const ossie::ImplementationInfo::List& implementations, CF::Properties& allocs); diff --git a/redhawk/src/control/sdr/dommgr/Placement.cpp b/redhawk/src/control/sdr/dommgr/Placement.cpp index 533e55fc1..fca7dd6b1 100644 --- a/redhawk/src/control/sdr/dommgr/Placement.cpp +++ b/redhawk/src/control/sdr/dommgr/Placement.cpp @@ -72,3 +72,17 @@ const std::vector& ApplicationPlacement::getPlacements() const { return placements; } + +ComponentInfo* ApplicationPlacement::getAssemblyController() +{ + for (PlacementList::iterator placement = placements.begin(); placement != placements.end(); ++placement) { + const std::vector& components = (*placement)->getComponents(); + for (std::vector::const_iterator comp = components.begin(); comp != components.end(); ++comp) { + if ((*comp)->isAssemblyController()) { + return *comp; + } + } + } + + return 0; +} diff --git a/redhawk/src/control/sdr/dommgr/Placement.h b/redhawk/src/control/sdr/dommgr/Placement.h index e6e9f46ea..fe8ba1ce0 100644 --- a/redhawk/src/control/sdr/dommgr/Placement.h +++ b/redhawk/src/control/sdr/dommgr/Placement.h @@ -59,6 +59,8 @@ namespace ossie { const PlacementList& getPlacements() const; + ComponentInfo* getAssemblyController(); + protected: PlacementList placements; }; From fde87db1b9203b20f80253ec75af10b3e1524b5d Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 11 May 2016 15:14:44 -0400 Subject: [PATCH 0198/1644] Provide component lookup functions in placement classes, and use those in DAS validation --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 7 +++--- .../sdr/dommgr/ApplicationFactory_impl.h | 2 +- redhawk/src/control/sdr/dommgr/Placement.cpp | 25 ++++++++++++++++++- redhawk/src/control/sdr/dommgr/Placement.h | 10 ++++++-- 4 files changed, 37 insertions(+), 7 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 43f6a2c4e..e8bdbc19f 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -714,14 +714,15 @@ void createHelper::assignPlacementsToDevices(ossie::ApplicationPlacement& appPla } } -void createHelper::_validateDAS(const DeviceAssignmentMap& deviceAssignments) +void createHelper::_validateDAS(ossie::ApplicationPlacement& appPlacement, + const DeviceAssignmentMap& deviceAssignments) { LOG_TRACE(ApplicationFactory_impl, "Validating device assignment sequence (length " << deviceAssignments.size() << ")"); for (DeviceAssignmentMap::const_iterator ii = deviceAssignments.begin(); ii != deviceAssignments.end(); ++ii) { const std::string& componentId = ii->first; const std::string& assignedDeviceId = ii->second; - ossie::ComponentInfo* component = findComponentByInstantiationId(componentId); + ossie::ComponentInfo* component = appPlacement.getComponent(componentId); if (!component) { LOG_ERROR(ApplicationFactory_impl, "Failed to create application; " @@ -1338,7 +1339,7 @@ throw (CORBA::SystemException, _appFact._identifier + ":" + _waveformContextName; // Catch invalid device assignments - _validateDAS(deviceAssignments); + _validateDAS(placement, deviceAssignments); // Assign all components to devices assignPlacementsToDevices(placement, appIdentifier, deviceAssignments); diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h index 541fb6300..ba21650a7 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h @@ -214,7 +214,7 @@ public ossie::DeviceLookup void assignPlacementsToDevices(ossie::ApplicationPlacement& appPlacement, const std::string& appIdentifier, const DeviceAssignmentMap& devices); - void _validateDAS(const DeviceAssignmentMap& deviceAssignments); + void _validateDAS(ossie::ApplicationPlacement& appPlacement, const DeviceAssignmentMap& deviceAssignments); void _connectComponents( std::vector& connections); void _configureComponents(); diff --git a/redhawk/src/control/sdr/dommgr/Placement.cpp b/redhawk/src/control/sdr/dommgr/Placement.cpp index fca7dd6b1..66459e469 100644 --- a/redhawk/src/control/sdr/dommgr/Placement.cpp +++ b/redhawk/src/control/sdr/dommgr/Placement.cpp @@ -42,7 +42,7 @@ const std::string& PlacementPlan::getName() const return name; } -const std::vector& PlacementPlan::getComponents() const +const PlacementPlan::ComponentList& PlacementPlan::getComponents() const { return components; } @@ -52,6 +52,17 @@ void PlacementPlan::addComponent(ComponentInfo* component) components.push_back(component); } +ComponentInfo* PlacementPlan::getComponent(const std::string& instantiationId) +{ + for (ComponentList::iterator comp = components.begin(); comp != components.end(); ++comp) { + if (instantiationId == (*comp)->getInstantiationIdentifier()) { + return *comp; + } + } + + return 0; +} + ApplicationPlacement::ApplicationPlacement() { } @@ -73,6 +84,18 @@ const std::vector& ApplicationPlacement::getPlacements() const return placements; } +ComponentInfo* ApplicationPlacement::getComponent(const std::string& instantiationId) +{ + for (PlacementList::iterator placement = placements.begin(); placement != placements.end(); ++placement) { + ComponentInfo* component = (*placement)->getComponent(instantiationId); + if (component) { + return component; + } + } + + return 0; +} + ComponentInfo* ApplicationPlacement::getAssemblyController() { for (PlacementList::iterator placement = placements.begin(); placement != placements.end(); ++placement) { diff --git a/redhawk/src/control/sdr/dommgr/Placement.h b/redhawk/src/control/sdr/dommgr/Placement.h index fe8ba1ce0..f0b1b9ca3 100644 --- a/redhawk/src/control/sdr/dommgr/Placement.h +++ b/redhawk/src/control/sdr/dommgr/Placement.h @@ -31,20 +31,24 @@ namespace ossie { class PlacementPlan { public: + typedef std::vector ComponentList; + PlacementPlan(); PlacementPlan(const std::string& id, const std::string& name); const std::string& getId() const; const std::string& getName() const; - const std::vector& getComponents() const; + const ComponentList& getComponents() const; void addComponent(ComponentInfo* component); + ComponentInfo* getComponent(const std::string& instantiationId); + protected: std::string id; std::string name; - std::vector components; + ComponentList components; }; class ApplicationPlacement @@ -61,6 +65,8 @@ namespace ossie { ComponentInfo* getAssemblyController(); + ComponentInfo* getComponent(const std::string& instantiationId); + protected: PlacementList placements; }; From 24a4bc9e5fae7b8cbccbc628099f5585a6dd4f3c Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 11 May 2016 15:27:13 -0400 Subject: [PATCH 0199/1644] Remove unused functions --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 1 - .../control/sdr/dommgr/applicationSupport.cpp | 49 ------------------- .../control/sdr/dommgr/applicationSupport.h | 4 -- 3 files changed, 54 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index e8bdbc19f..4f5663735 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -1319,7 +1319,6 @@ throw (CORBA::SystemException, if (comp->isAssemblyController()) { _appInfo.setACProperties(comp->getConfigureProperties()); } - _appInfo.addComponent(comp); } overrideExternalProperties(modifiedInitConfiguration); diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp index ace72888b..050c6d8b5 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp @@ -970,52 +970,3 @@ void ApplicationInfo::populateApplicationInfo(const SoftwareAssembly& sad) addUsesDevice(useDev); } } - -void ApplicationInfo::populateExternalProperties(CF::Properties& vals) -{ - for (std::vector::iterator prop = externalProperties.begin(); - prop != externalProperties.end(); - ++prop) { - // Gets the property information - std::string compId = prop->comprefid; - std::string propId = prop->propid; - std::string extId = ""; - if (prop->externalpropid != "") { - extId = prop->externalpropid; - } else { - extId = prop->propid; - } - - ComponentInfo *comp = findComponentByInstantiationId(prop->comprefid); - if (comp == 0) { - LOG_WARN(ApplicationInfo, "Unable to find component: " << prop->comprefid << - " for external property: " << prop->externalpropid); - continue; - } - - CF::Properties compProps = comp->getConfigureProperties(); - for (unsigned int i = 0; i < compProps.length(); ++i) { - if (strcmp(compProps[i].id, propId.c_str()) == 0) { - int length = vals.length(); - vals.length(length + 1); - vals[length].id = CORBA::string_dup(extId.c_str()); - vals[length].value = compProps[i].value; - } - } - } -} - -void ApplicationInfo::addComponent(ComponentInfo* comp) -{ - components.push_back(comp); -} - -ComponentInfo* ApplicationInfo::findComponentByInstantiationId(const std::string id) -{ - for (unsigned int i = 0; i < components.size(); ++i) { - if (components[i]->getInstantiationIdentifier() == id) { - return components[i]; - } - } - return 0; -} diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.h b/redhawk/src/control/sdr/dommgr/applicationSupport.h index 13a660578..483c83510 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.h +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.h @@ -320,15 +320,11 @@ namespace ossie void setACProperties(const CF::Properties& props); const CF::Properties getACProperties() const; void populateApplicationInfo(const SoftwareAssembly& sad); - void populateExternalProperties(CF::Properties& props); - void addComponent(ComponentInfo* comp); - ComponentInfo* findComponentByInstantiationId(const std::string id); protected: std::vector externalPorts; std::vector externalProperties; CF::Properties acProps; - std::vector components; }; } From 1184d0aa0f5c450d29dfb727f7367a27e5188b57 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 11 May 2016 15:39:30 -0400 Subject: [PATCH 0200/1644] Remove functions and members that were just copies of SAD data --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 11 +++++----- .../control/sdr/dommgr/applicationSupport.cpp | 22 ------------------- .../control/sdr/dommgr/applicationSupport.h | 4 ---- 3 files changed, 5 insertions(+), 32 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 4f5663735..cb9506111 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -1022,13 +1022,12 @@ void createHelper::_handleUsesDevices(ossie::ApplicationPlacement& appPlacement, void createHelper::setUpExternalPorts(Application_impl* application) { - const std::vector& ports = - _appInfo.getExternalPorts(); + typedef std::vector PortList; + const PortList& ports = _appFact._sadParser.getExternalPorts(); LOG_TRACE(ApplicationFactory_impl, "Mapping " << ports.size() << " external port(s)"); - std::vector::const_iterator port; - for (port = ports.begin(); port != ports.end(); ++port) { + for (PortList::const_iterator port = ports.begin(); port != ports.end(); ++port) { LOG_TRACE(ApplicationFactory_impl, "Port component: " << port->componentrefid << " Port identifier: " << port->identifier); @@ -1087,7 +1086,7 @@ void createHelper::setUpExternalPorts(Application_impl* application) void createHelper::setUpExternalProperties(Application_impl* application) { - const std::vector& props = _appInfo.getExternalProperties(); + const std::vector& props = _appFact._sadParser.getExternalProperties(); LOG_TRACE(ApplicationFactory_impl, "Mapping " << props.size() << " external property(ies)"); for (std::vector::const_iterator prop = props.begin(); prop != props.end(); ++prop) { LOG_TRACE(ApplicationFactory_impl, "Property component: " << prop->comprefid << " Property identifier: " << prop->propid); @@ -1451,7 +1450,7 @@ throw (CORBA::SystemException, void createHelper::overrideExternalProperties(const CF::Properties& initConfiguration) { - const std::vector& props = _appInfo.getExternalProperties(); + const std::vector& props = _appFact._sadParser.getExternalProperties(); for (unsigned int i = 0; i < initConfiguration.length(); ++i) { for (std::vector::const_iterator prop = props.begin(); prop != props.end(); ++prop) { diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp index 050c6d8b5..805fb79a1 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp @@ -929,16 +929,6 @@ ApplicationInfo::~ApplicationInfo() usesDevices.clear(); } -const std::vector& ApplicationInfo::getExternalPorts() const -{ - return externalPorts; -} - -const std::vector& ApplicationInfo::getExternalProperties() const -{ - return externalProperties; -} - const CF::Properties ApplicationInfo::getACProperties() const { return acProps; @@ -951,18 +941,6 @@ void ApplicationInfo::setACProperties(const CF::Properties& props) void ApplicationInfo::populateApplicationInfo(const SoftwareAssembly& sad) { - // Gets external ports - const std::vector& ports = sad.getExternalPorts(); - for (std::vector::const_iterator port = ports.begin(); port != ports.end(); ++port) { - externalPorts.push_back(*port); - } - - // Gets external properties - const std::vector& props = sad.getExternalProperties(); - for (std::vector::const_iterator prop = props.begin(); prop != props.end(); ++prop) { - externalProperties.push_back(*prop); - } - // Gets uses device relationships const std::vector& usesDevice = sad.getUsesDevices(); for (std::vector::const_iterator use = usesDevice.begin(); use != usesDevice.end(); ++use) { diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.h b/redhawk/src/control/sdr/dommgr/applicationSupport.h index 483c83510..f48705eee 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.h +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.h @@ -315,15 +315,11 @@ namespace ossie ApplicationInfo(); ~ApplicationInfo(); - const std::vector& getExternalPorts() const; - const std::vector& getExternalProperties() const; void setACProperties(const CF::Properties& props); const CF::Properties getACProperties() const; void populateApplicationInfo(const SoftwareAssembly& sad); protected: - std::vector externalPorts; - std::vector externalProperties; CF::Properties acProps; }; From cb502b6111a3f01d8f890893472c5e3d9fef9589 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 11 May 2016 16:16:52 -0400 Subject: [PATCH 0201/1644] Get the assembly controller's properties directly from the component object, instead of copying them to another object --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 15 +++++++-------- .../src/control/sdr/dommgr/applicationSupport.cpp | 10 ---------- .../src/control/sdr/dommgr/applicationSupport.h | 5 ----- 3 files changed, 7 insertions(+), 23 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index cb9506111..bdcb91922 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -992,7 +992,12 @@ void createHelper::_handleUsesDevices(ossie::ApplicationPlacement& appPlacement, // Gets all uses device info from the SAD file const UsesDeviceInfo::List& usesDevices = _appInfo.getUsesDevices(); LOG_TRACE(ApplicationFactory_impl, "Application has " << usesDevices.size() << " usesdevice dependencies"); - const CF::Properties& appProperties = _appInfo.getACProperties(); + + // Get the assembly controller's configure properties for context in the + // allocations + ossie::ComponentInfo* assembly_controller = appPlacement.getAssemblyController(); + CF::Properties appProperties = assembly_controller->getConfigureProperties(); + // The device assignments for SAD-level usesdevices are never stored DeviceAssignmentList assignedDevices; if (!allocateUsesDevices(appName, usesDevices, appProperties, assignedDevices, this->_allocations)) { @@ -1015,7 +1020,7 @@ void createHelper::_handleUsesDevices(ossie::ApplicationPlacement& appPlacement, throw CF::ApplicationFactory::CreateApplicationError(CF::CF_ENOSPC, eout.str().c_str()); } for (DeviceAssignmentList::iterator dev=assignedDevices.begin(); dev!=assignedDevices.end(); dev++) { - dev->deviceAssignment.componentId = appPlacement.getAssemblyController()->getIdentifier().c_str(); + dev->deviceAssignment.componentId = assembly_controller->getIdentifier().c_str(); } _appUsedDevs.insert(_appUsedDevs.end(), assignedDevices.begin(), assignedDevices.end()); } @@ -1313,12 +1318,6 @@ throw (CORBA::SystemException, ////////////////////////////////////////////////// // Store information about this application _appInfo.populateApplicationInfo(_appFact._sadParser); - for (unsigned int i = 0; i < _requiredComponents.size(); ++i) { - ComponentInfo *comp = _requiredComponents[i]; - if (comp->isAssemblyController()) { - _appInfo.setACProperties(comp->getConfigureProperties()); - } - } overrideExternalProperties(modifiedInitConfiguration); diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp index 805fb79a1..72c808b34 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp @@ -929,16 +929,6 @@ ApplicationInfo::~ApplicationInfo() usesDevices.clear(); } -const CF::Properties ApplicationInfo::getACProperties() const -{ - return acProps; -} - -void ApplicationInfo::setACProperties(const CF::Properties& props) -{ - acProps = props; -} - void ApplicationInfo::populateApplicationInfo(const SoftwareAssembly& sad) { // Gets uses device relationships diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.h b/redhawk/src/control/sdr/dommgr/applicationSupport.h index f48705eee..d743803b6 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.h +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.h @@ -315,12 +315,7 @@ namespace ossie ApplicationInfo(); ~ApplicationInfo(); - void setACProperties(const CF::Properties& props); - const CF::Properties getACProperties() const; void populateApplicationInfo(const SoftwareAssembly& sad); - - protected: - CF::Properties acProps; }; } From b1d9b0f982c617694701c63f0b4bd9e56bd20ba7 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 11 May 2016 18:00:00 -0400 Subject: [PATCH 0202/1644] Track all application deployments in a top-level class --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 61 ++++++++----------- .../sdr/dommgr/ApplicationFactory_impl.h | 3 +- redhawk/src/control/sdr/dommgr/Deployment.cpp | 32 ++++++++++ redhawk/src/control/sdr/dommgr/Deployment.h | 17 ++++++ 4 files changed, 75 insertions(+), 38 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index bdcb91922..d4f006464 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -709,7 +709,7 @@ void createHelper::assignPlacementsToDevices(ossie::ApplicationPlacement& appPla << " is assigned to device " << assigned_device); } ossie::ComponentDeployment* deployment = allocateComponent(component, assigned_device, _appUsedDevs, appIdentifier); - _deployments.push_back(deployment); + _appDeployment.addComponentDeployment(deployment); } } } @@ -967,7 +967,7 @@ void createHelper::_placeHostCollocation(const std::string &appIdentifier, continue; } collocAssignedDevs[i].deviceAssignment.componentId = (*comp)->getIdentifier().c_str(); - _deployments.push_back(deployment); + _appDeployment.addComponentDeployment(deployment); } // Move the device to the front of the list @@ -1370,7 +1370,7 @@ throw (CORBA::SystemException, CF::Resource_var assemblyController; if (assemblyControllerComponent) { const std::string& assemblyControllerId = assemblyControllerComponent->getInstantiationIdentifier(); - ossie::ComponentDeployment* deployment = findComponentDeployment(assemblyControllerId); + ossie::ComponentDeployment* deployment = _appDeployment.getComponentDeployment(assemblyControllerId); assemblyController = deployment->getResourcePtr(); } _checkAssemblyController(assemblyController, assemblyControllerComponent); @@ -2197,17 +2197,6 @@ ossie::ComponentInfo* createHelper::findComponentByInstantiationId(const std::st return 0; } -ossie::ComponentDeployment* createHelper::findComponentDeployment(const std::string& instantiationId) -{ - for (DeploymentList::iterator deployment = _deployments.begin(); deployment != _deployments.end(); ++deployment) { - if (instantiationId == (*deployment)->getComponent()->getInstantiationIdentifier()) { - return (*deployment); - } - } - - return 0; -} - /* Given a waveform/application name, return a unique waveform naming context * - Returns a unique waveform naming context * THIS FUNCTION IS NOT THREAD SAFE @@ -2302,12 +2291,13 @@ void createHelper::loadDependencies(const ossie::ComponentInfo& component, */ void createHelper::loadAndExecuteComponents(CF::ApplicationRegistrar_ptr _appReg) { - LOG_TRACE(ApplicationFactory_impl, "Loading and Executing " << _deployments.size() << " components"); + const DeploymentList& deployments = _appDeployment.getComponentDeployments(); + LOG_TRACE(ApplicationFactory_impl, "Loading and Executing " << deployments.size() << " components"); // apply application affinity options to required components applyApplicationAffinityOptions(); - for (unsigned int rc_idx = 0; rc_idx < _deployments.size (); rc_idx++) { - ossie::ComponentDeployment* deployment = _deployments[rc_idx]; + for (unsigned int rc_idx = 0; rc_idx < deployments.size (); rc_idx++) { + ossie::ComponentDeployment* deployment = deployments[rc_idx]; ossie::ComponentInfo* component = deployment->getComponent(); const ossie::ImplementationInfo* implementation = deployment->getImplementation(); @@ -2659,16 +2649,17 @@ void createHelper::applyApplicationAffinityOptions() { // Promote NIC affinity for all components deployed on the same device // boost::shared_ptr deploy_on_device; - for (unsigned int rc_idx = 0; rc_idx < _deployments.size(); rc_idx++) { - ossie::ComponentDeployment* deployment = _deployments[rc_idx]; + const DeploymentList& deployments = _appDeployment.getComponentDeployments(); + for (unsigned int rc_idx = 0; rc_idx < deployments.size(); rc_idx++) { + ossie::ComponentDeployment* deployment = deployments[rc_idx]; if (!(deployment->getNicAssignment().empty())) { deploy_on_device = deployment->getAssignedDevice(); } } if (deploy_on_device) { - for (unsigned int rc_idx = 0; rc_idx < _deployments.size (); rc_idx++) { - ossie::ComponentDeployment* deployment = _deployments[rc_idx]; + for (unsigned int rc_idx = 0; rc_idx < deployments.size (); rc_idx++) { + ossie::ComponentDeployment* deployment = deployments[rc_idx]; boost::shared_ptr dev = deployment->getAssignedDevice(); // for matching device deployments then apply nic affinity settings if (dev->identifier == deploy_on_device->identifier) { @@ -2688,7 +2679,8 @@ void createHelper::waitForComponentRegistration() // Track only SCA-compliant components; non-compliant components will never // register with the application, nor do they need to be initialized std::set expected_components; - for (DeploymentList::iterator ii = _deployments.begin(); ii != _deployments.end(); ++ii) { + const DeploymentList& deployments = _appDeployment.getComponentDeployments(); + for (DeploymentList::const_iterator ii = deployments.begin(); ii != deployments.end(); ++ii) { ossie::ComponentInfo* component = (*ii)->getComponent(); if (component->isScaCompliant()) { expected_components.insert(component->getIdentifier()); @@ -2703,8 +2695,8 @@ void createHelper::waitForComponentRegistration() time_t elapsed = time(NULL)-start; LOG_ERROR(ApplicationFactory_impl, "Timed out waiting for component to bind to naming context (" << elapsed << "s elapsed)"); ostringstream eout; - for (unsigned int req_idx = 0; req_idx < _deployments.size(); req_idx++) { - ossie::ComponentDeployment* deployment = _deployments[req_idx]; + for (unsigned int req_idx = 0; req_idx < deployments.size(); req_idx++) { + ossie::ComponentDeployment* deployment = deployments[req_idx]; const ossie::ComponentInfo* component = deployment->getComponent(); if (expected_components.count(component->getIdentifier())) { eout << "Timed out waiting for component to register: '" << component->getName() @@ -2727,15 +2719,16 @@ void createHelper::waitForComponentRegistration() void createHelper::initializeComponents() { // Install the different components in the system - LOG_TRACE(ApplicationFactory_impl, "initializing " << _deployments.size() << " waveform components") + const DeploymentList& deployments = _appDeployment.getComponentDeployments(); + LOG_TRACE(ApplicationFactory_impl, "initializing " << deployments.size() << " waveform components") // Resize the _startSeq vector to the right size _startSeq.resize(_startOrderIds.size()); CF::Components_var app_registeredComponents = _application->registeredComponents(); - for (unsigned int rc_idx = 0; rc_idx < _deployments.size (); rc_idx++) { - ossie::ComponentDeployment* deployment = _deployments[rc_idx]; + for (unsigned int rc_idx = 0; rc_idx < deployments.size (); rc_idx++) { + ossie::ComponentDeployment* deployment = deployments[rc_idx]; const ossie::ComponentInfo* component = deployment->getComponent(); // If the component is non-SCA compliant then we don't expect anything beyond this @@ -2896,7 +2889,8 @@ void createHelper::configureComponents() { DeploymentList configure_list; ossie::ComponentDeployment* ac_deployment = 0; - for (DeploymentList::iterator depl = _deployments.begin(); depl != _deployments.end(); ++depl) { + const DeploymentList& deployments = _appDeployment.getComponentDeployments(); + for (DeploymentList::const_iterator depl = deployments.begin(); depl != deployments.end(); ++depl) { const ossie::ComponentInfo* component = (*depl)->getComponent(); if (!component->isScaCompliant()) { // If the component is non-SCA compliant then we don't expect anything beyond this @@ -3071,11 +3065,6 @@ createHelper::~createHelper() delete (*comp); } _requiredComponents.clear(); - - for (DeploymentList::iterator depl = _deployments.begin(); depl != _deployments.end(); ++depl) { - delete (*depl); - } - _deployments.clear(); } void createHelper::_cleanupFailedCreate() @@ -3114,7 +3103,7 @@ void createHelper::_cleanupFailedCreate() */ CF::Resource_ptr createHelper::lookupComponentByInstantiationId(const std::string& identifier) { - ossie::ComponentDeployment* deployment = findComponentDeployment(identifier); + ossie::ComponentDeployment* deployment = _appDeployment.getComponentDeployment(identifier); if (deployment) { return deployment->getResourcePtr(); } @@ -3129,7 +3118,7 @@ CF::Device_ptr createHelper::lookupDeviceThatLoadedComponentInstantiationId(cons { LOG_TRACE(ApplicationFactory_impl, "[DeviceLookup] Lookup device that loaded component " << componentId); - ossie::ComponentDeployment* deployment = findComponentDeployment(componentId); + ossie::ComponentDeployment* deployment = _appDeployment.getComponentDeployment(componentId); if (!deployment) { LOG_WARN(ApplicationFactory_impl, "[DeviceLookup] Component not found"); return CF::Device::_nil(); @@ -3151,7 +3140,7 @@ CF::Device_ptr createHelper::lookupDeviceThatLoadedComponentInstantiationId(cons CF::Device_ptr createHelper::lookupDeviceUsedByComponentInstantiationId(const std::string& componentId, const std::string& usesId) { LOG_TRACE(ApplicationFactory_impl, "[DeviceLookup] Lookup device used by component " << componentId); - ossie::ComponentDeployment* deployment = findComponentDeployment(componentId.c_str()); + ossie::ComponentDeployment* deployment = _appDeployment.getComponentDeployment(componentId); if (!deployment) { LOG_WARN(ApplicationFactory_impl, "[DeviceLookup] Component not found"); return CF::Device::_nil(); diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h index ba21650a7..bf75e5059 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h @@ -206,7 +206,7 @@ public ossie::DeviceLookup ossie::ApplicationInfo _appInfo; typedef std::vector DeploymentList; - DeploymentList _deployments; + ossie::ApplicationDeployment _appDeployment; // createHelper helper methods void overrideExternalProperties(const CF::Properties& initConfiguration); @@ -282,7 +282,6 @@ public ossie::DeviceLookup CF::Device_ptr find_device_from_id(const char*); const ossie::DeviceNode& find_device_node_from_id(const char*) throw(std::exception); ossie::ComponentInfo* findComponentByInstantiationId(const std::string& identifier); - ossie::ComponentDeployment* findComponentDeployment(const std::string& instantiationId); // Cleanup - used when create fails/doesn't succeed for some reason bool _isComplete; diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index d63f1f245..223c52c3f 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -210,3 +210,35 @@ CF::Resource_ptr ComponentDeployment::getResourcePtr() const { return CF::Resource::_duplicate(resource); } + +ApplicationDeployment::ApplicationDeployment() +{ +} + +ApplicationDeployment::~ApplicationDeployment() +{ + for (ComponentList::iterator comp = components.begin(); comp != components.end(); ++comp) { + delete *comp; + } +} + +void ApplicationDeployment::addComponentDeployment(ComponentDeployment* deployment) +{ + components.push_back(deployment); +} + +const ApplicationDeployment::ComponentList& ApplicationDeployment::getComponentDeployments() +{ + return components; +} + +ComponentDeployment* ApplicationDeployment::getComponentDeployment(const std::string& instantiationId) +{ + for (ComponentList::iterator comp = components.begin(); comp != components.end(); ++comp) { + if (instantiationId == (*comp)->getComponent()->getInstantiationIdentifier()) { + return *comp; + } + } + + return 0; +} diff --git a/redhawk/src/control/sdr/dommgr/Deployment.h b/redhawk/src/control/sdr/dommgr/Deployment.h index a42b7f5be..cf67ee222 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.h +++ b/redhawk/src/control/sdr/dommgr/Deployment.h @@ -30,6 +30,7 @@ #include "applicationSupport.h" namespace ossie { + class SoftpkgDeployment { public: @@ -87,6 +88,22 @@ namespace ossie { std::string nicAssignment; redhawk::PropertyMap affinityOptions; }; + + class ApplicationDeployment + { + public: + typedef std::vector ComponentList; + + ApplicationDeployment(); + ~ApplicationDeployment(); + + void addComponentDeployment(ComponentDeployment* deployment); + const ComponentList& getComponentDeployments(); + ComponentDeployment* getComponentDeployment(const std::string& instantiationId); + + protected: + ComponentList components; + }; } #endif // DEPLOYMENT_H From ef6f7ed8de67446c53149cb6f5d83e9b8fa87762 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 11 May 2016 18:15:15 -0400 Subject: [PATCH 0203/1644] Offload ComponentLookup interface to ApplicationDeployment --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 82 ++++++------------- .../sdr/dommgr/ApplicationFactory_impl.h | 4 - redhawk/src/control/sdr/dommgr/Deployment.cpp | 9 ++ redhawk/src/control/sdr/dommgr/Deployment.h | 6 +- .../control/sdr/dommgr/connectionSupport.h | 3 + 5 files changed, 43 insertions(+), 61 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index d4f006464..273375524 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -1038,9 +1038,8 @@ void createHelper::setUpExternalPorts(Application_impl* application) << " Port identifier: " << port->identifier); // Get the component from the instantiation identifier. - CORBA::Object_var obj = - lookupComponentByInstantiationId(port->componentrefid); - if (CORBA::is_nil(obj)) { + ossie::ComponentDeployment* deployment = _appDeployment.getComponentDeployment(port->componentrefid); + if (!deployment) { LOG_ERROR(ApplicationFactory_impl, "Invalid componentinstantiationref (" <componentrefid @@ -1050,8 +1049,11 @@ void createHelper::setUpExternalPorts(Application_impl* application) "Invalid componentinstantiationref given for external port")); } + CF::Resource_var resource = deployment->getResourcePtr(); + CORBA::Object_var obj; + if (port->type == SoftwareAssembly::Port::SUPPORTEDIDENTIFIER) { - if (!obj->_is_a(port->identifier.c_str())) { + if (!resource->_is_a(port->identifier.c_str())) { LOG_ERROR( ApplicationFactory_impl, "Component does not support requested interface: " @@ -1060,18 +1062,15 @@ void createHelper::setUpExternalPorts(Application_impl* application) CF::CF_NOTSET, "Component does not support requested interface")); } + obj = CORBA::Object::_duplicate(resource); } else { // Must be either "usesidentifier" or "providesidentifier", // which are equivalent unless you want to be extra // pedantic and check how the port is described in the // component's SCD. - - CF::PortSupplier_var portSupplier = - ossie::corba::_narrowSafe (obj); - // Try to look up the port. try { - obj = portSupplier->getPort(port->identifier.c_str()); + obj = resource->getPort(port->identifier.c_str()); } CATCH_THROW_LOG_ERROR( ApplicationFactory_impl, "Invalid port id", @@ -1081,11 +1080,11 @@ void createHelper::setUpExternalPorts(Application_impl* application) } // Add it to the list of external ports on the application object. - if (port->externalname == ""){ - application->addExternalPort(port->identifier, obj); - } else { - application->addExternalPort(port->externalname, obj); + std::string name = port->externalname; + if (name.empty()) { + name = port->identifier; } + application->addExternalPort(name, obj); } } @@ -1096,42 +1095,26 @@ void createHelper::setUpExternalProperties(Application_impl* application) for (std::vector::const_iterator prop = props.begin(); prop != props.end(); ++prop) { LOG_TRACE(ApplicationFactory_impl, "Property component: " << prop->comprefid << " Property identifier: " << prop->propid); - // Verify internal property - ComponentInfo *tmp = findComponentByInstantiationId(prop->comprefid); - if (tmp == 0) { + // Get the component from the compref identifier. + ossie::ComponentDeployment* deployment = _appDeployment.getComponentDeployment(prop->comprefid); + if (!deployment) { LOG_ERROR(ApplicationFactory_impl, "Unable to find component for comprefid " << prop->comprefid); - throw(CF::ApplicationFactory::CreateApplicationError(CF::CF_NOTSET, "Unable to find component for given comprefid")); + throw CF::ApplicationFactory::CreateApplicationError(CF::CF_NOTSET, "Unable to find component for given comprefid"); } - const std::vector& props = tmp->prf.getProperties(); - bool foundProp = false; - for (unsigned int i = 0; i < props.size(); ++i) { - if (props[i]->getID() == prop->propid){ - foundProp = true; - } - } - if (!foundProp){ + const Property* property = deployment->getComponent()->prf.getProperty(prop->propid); + if (!property){ LOG_ERROR(ApplicationFactory_impl, "Attempting to promote property: '" << prop->propid << "' that does not exist in component: '" << prop->comprefid << "'"); - throw (CF::ApplicationFactory::CreateApplicationError(CF::CF_NOTSET, - "Attempting to promote property that does not exist in component")); + throw CF::ApplicationFactory::CreateApplicationError(CF::CF_NOTSET, + "Attempting to promote property that does not exist in component"); } - // Get the component from the compref identifier. - CF::Resource_var comp = lookupComponentByInstantiationId(prop->comprefid); - if (CORBA::is_nil(comp)) { - LOG_ERROR(ApplicationFactory_impl, "Invalid comprefid (" << prop->comprefid << ") given for an external property"); - throw(CF::ApplicationFactory::CreateApplicationError(CF::CF_NOTSET, "Invalid comprefid given for external property")); - } - - if (prop->externalpropid == "") { - application->addExternalProperty(prop->propid, - prop->propid, - comp); - } else { - application->addExternalProperty(prop->propid, - prop->externalpropid, - comp); + CF::Resource_var comp = deployment->getResourcePtr(); + std::string external_id = prop->externalpropid; + if (external_id.empty()) { + external_id = prop->propid; } + application->addExternalProperty(prop->propid, external_id, comp); } } @@ -3009,7 +2992,7 @@ void createHelper::connectComponents(std::vector& connections, s // NB: Use an auto_ptr instead of a bare pointer so that it will automatically be deleted // in the event of a failure. using ossie::AppConnectionManager; - std::auto_ptr connectionManager(new AppConnectionManager(_appFact._domainManager, this, this, base_naming_context)); + std::auto_ptr connectionManager(new AppConnectionManager(_appFact._domainManager, &_appDeployment, this, base_naming_context)); // Create all resource connections LOG_TRACE(ApplicationFactory_impl, "Establishing " << _connection.size() << " waveform connections") @@ -3098,19 +3081,6 @@ void createHelper::_cleanupFailedCreate() } CATCH_LOG_WARN(ApplicationFactory_impl, "Could not destroy naming context"); } -/* Given a component instantiation id, returns the associated CORBA Resource pointer - * - Gets the Resource pointer for a particular component instantiation id - */ -CF::Resource_ptr createHelper::lookupComponentByInstantiationId(const std::string& identifier) -{ - ossie::ComponentDeployment* deployment = _appDeployment.getComponentDeployment(identifier); - if (deployment) { - return deployment->getResourcePtr(); - } - - return CF::Resource::_nil(); -} - /* Given a component instantiation id, returns the associated CORBA Device pointer * - Gets the Device pointer for a particular component instantiation id */ diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h index bf75e5059..b5a53cbfa 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h @@ -140,7 +140,6 @@ class ScopedAllocations { }; class createHelper: -public ossie::ComponentLookup, public ossie::DeviceLookup { @@ -291,9 +290,6 @@ public ossie::DeviceLookup /* Implements the ConnectionManager functions * - Makes this class compatible with the ConnectionManager */ - // ComponentLookup interface - CF::Resource_ptr lookupComponentByInstantiationId(const std::string& identifier); - // DeviceLookup interface CF::Device_ptr lookupDeviceThatLoadedComponentInstantiationId(const std::string& componentId); CF::Device_ptr lookupDeviceUsedByComponentInstantiationId( diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index 223c52c3f..f7e6a4fe7 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -242,3 +242,12 @@ ComponentDeployment* ApplicationDeployment::getComponentDeployment(const std::st return 0; } + +CF::Resource_ptr ApplicationDeployment::lookupComponentByInstantiationId(const std::string& identifier) +{ + ComponentDeployment* deployment = getComponentDeployment(identifier); + if (deployment) { + return deployment->getResourcePtr(); + } + return CF::Resource::_nil(); +} diff --git a/redhawk/src/control/sdr/dommgr/Deployment.h b/redhawk/src/control/sdr/dommgr/Deployment.h index cf67ee222..09cdb761b 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.h +++ b/redhawk/src/control/sdr/dommgr/Deployment.h @@ -28,6 +28,7 @@ #include #include "applicationSupport.h" +#include "connectionSupport.h" namespace ossie { @@ -89,7 +90,7 @@ namespace ossie { redhawk::PropertyMap affinityOptions; }; - class ApplicationDeployment + class ApplicationDeployment : public ComponentLookup { public: typedef std::vector ComponentList; @@ -101,6 +102,9 @@ namespace ossie { const ComponentList& getComponentDeployments(); ComponentDeployment* getComponentDeployment(const std::string& instantiationId); + // Adapt to ComponentLookup interface + virtual CF::Resource_ptr lookupComponentByInstantiationId(const std::string& identifier); + protected: ComponentList components; }; diff --git a/redhawk/src/control/sdr/dommgr/connectionSupport.h b/redhawk/src/control/sdr/dommgr/connectionSupport.h index b4e07376b..c3504f690 100644 --- a/redhawk/src/control/sdr/dommgr/connectionSupport.h +++ b/redhawk/src/control/sdr/dommgr/connectionSupport.h @@ -55,6 +55,9 @@ namespace ossie { public: virtual ~ComponentLookup() {}; + + /* Given a component instantiation id, returns the associated CORBA Resource pointer + */ virtual CF::Resource_ptr lookupComponentByInstantiationId(const std::string& identifier) = 0; }; From 487f1becb51669102e69594026127f80c9e73513 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 11 May 2016 18:24:29 -0400 Subject: [PATCH 0204/1644] Manage ownership of the complete application profile in the ApplicationPlacement class --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 35 ++++++------------- .../sdr/dommgr/ApplicationFactory_impl.h | 5 ++- redhawk/src/control/sdr/dommgr/Placement.cpp | 7 ++++ redhawk/src/control/sdr/dommgr/Placement.h | 3 +- 4 files changed, 21 insertions(+), 29 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 273375524..6c5a0829c 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -1302,7 +1302,7 @@ throw (CORBA::SystemException, // Store information about this application _appInfo.populateApplicationInfo(_appFact._sadParser); - overrideExternalProperties(modifiedInitConfiguration); + overrideExternalProperties(placement, modifiedInitConfiguration); //////////////////////////////////////////////// // Assign components to devices @@ -1430,7 +1430,8 @@ throw (CORBA::SystemException, } -void createHelper::overrideExternalProperties(const CF::Properties& initConfiguration) +void createHelper::overrideExternalProperties(ossie::ApplicationPlacement& appPlacement, + const CF::Properties& initConfiguration) { const std::vector& props = _appFact._sadParser.getExternalProperties(); @@ -1444,7 +1445,7 @@ void createHelper::overrideExternalProperties(const CF::Properties& initConfigur } if (id == static_cast(initConfiguration[i].id)) { - ComponentInfo *comp = findComponentByInstantiationId(prop->comprefid); + ComponentInfo *comp = appPlacement.getComponent(prop->comprefid); // Only configure on non AC components if (comp != 0 && !comp->isAssemblyController()) { comp->overrideProperty(prop->propid.c_str(), initConfiguration[i].value); @@ -2080,6 +2081,8 @@ void createHelper::getRequiredComponents(ossie::ApplicationPlacement& appPlaceme { TRACE_ENTER(ApplicationFactory_impl); + PlacementList components; + // Walk through the host collocations first const std::vector& collocations = _appFact._sadParser.getHostCollocations(); for (size_t index = 0; index < collocations.size(); ++index) { @@ -2093,7 +2096,7 @@ void createHelper::getRequiredComponents(ossie::ApplicationPlacement& appPlaceme for (unsigned int i = 0; i < placements.size(); i++) { ossie::ComponentInfo* component = buildComponentInfo(placements[i]); plan->addComponent(component); - _requiredComponents.push_back(component); + components.push_back(component); } } @@ -2104,7 +2107,7 @@ void createHelper::getRequiredComponents(ossie::ApplicationPlacement& appPlaceme appPlacement.addPlacement(plan); ossie::ComponentInfo* component = buildComponentInfo(componentsFromSAD[i]); plan->addComponent(component); - _requiredComponents.push_back(component); + components.push_back(component); } // Now that all of the components are know, bin the start orders based on @@ -2113,8 +2116,8 @@ void createHelper::getRequiredComponents(ossie::ApplicationPlacement& appPlaceme // easily by iterating through all entries. const std::string assemblyControllerRefId = _appFact._sadParser.getAssemblyControllerRefId(); std::multimap start_orders; - for (size_t index = 0; index < _requiredComponents.size(); ++index) { - ossie::ComponentInfo* component = _requiredComponents[index]; + for (size_t index = 0; index < components.size(); ++index) { + ossie::ComponentInfo* component = components[index]; if (component->getInstantiationIdentifier() == assemblyControllerRefId) { // Mark the assembly controller while we're at it component->setIsAssemblyController(true); @@ -2166,20 +2169,6 @@ const ossie::DeviceNode& createHelper::find_device_node_from_id(const char* devi throw(std::exception()); } -/* Given a component instantiation id, returns the associated ossie::ComponentInfo object - * - Gets the ComponentInfo class instance for a particular component instantiation id - */ -ossie::ComponentInfo* createHelper::findComponentByInstantiationId(const std::string& identifier) -{ - for (size_t ii = 0; ii < _requiredComponents.size(); ++ii) { - if (identifier == _requiredComponents[ii]->getInstantiationIdentifier()) { - return _requiredComponents[ii]; - } - } - - return 0; -} - /* Given a waveform/application name, return a unique waveform naming context * - Returns a unique waveform naming context * THIS FUNCTION IS NOT THREAD SAFE @@ -3044,10 +3033,6 @@ createHelper::~createHelper() if (_application) { _application->_remove_ref(); } - for (PlacementList::iterator comp = _requiredComponents.begin(); comp != _requiredComponents.end(); ++comp) { - delete (*comp); - } - _requiredComponents.clear(); } void createHelper::_cleanupFailedCreate() diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h index b5a53cbfa..a331ce42c 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h @@ -182,7 +182,6 @@ public ossie::DeviceLookup ossie::DeviceList _registeredDevices; ossie::DeviceList _executableDevices; - PlacementList _requiredComponents; std::map specialized_reservations; // @@ -208,7 +207,8 @@ public ossie::DeviceLookup ossie::ApplicationDeployment _appDeployment; // createHelper helper methods - void overrideExternalProperties(const CF::Properties& initConfiguration); + void overrideExternalProperties(ossie::ApplicationPlacement& appPlacement, + const CF::Properties& initConfiguration); void overrideProperties(const CF::Properties& initConfiguration, ossie::ComponentInfo* component); void assignPlacementsToDevices(ossie::ApplicationPlacement& appPlacement, const std::string& appIdentifier, @@ -280,7 +280,6 @@ public ossie::DeviceLookup // Functions for looking up particular components/devices CF::Device_ptr find_device_from_id(const char*); const ossie::DeviceNode& find_device_node_from_id(const char*) throw(std::exception); - ossie::ComponentInfo* findComponentByInstantiationId(const std::string& identifier); // Cleanup - used when create fails/doesn't succeed for some reason bool _isComplete; diff --git a/redhawk/src/control/sdr/dommgr/Placement.cpp b/redhawk/src/control/sdr/dommgr/Placement.cpp index 66459e469..cccc18532 100644 --- a/redhawk/src/control/sdr/dommgr/Placement.cpp +++ b/redhawk/src/control/sdr/dommgr/Placement.cpp @@ -26,6 +26,13 @@ PlacementPlan::PlacementPlan() { } +PlacementPlan::~PlacementPlan() +{ + for (ComponentList::iterator comp = components.begin(); comp != components.end(); ++comp) { + delete *comp; + } +} + PlacementPlan::PlacementPlan(const std::string& id, const std::string& name) : id(id), name(name) diff --git a/redhawk/src/control/sdr/dommgr/Placement.h b/redhawk/src/control/sdr/dommgr/Placement.h index f0b1b9ca3..bb0108729 100644 --- a/redhawk/src/control/sdr/dommgr/Placement.h +++ b/redhawk/src/control/sdr/dommgr/Placement.h @@ -35,7 +35,8 @@ namespace ossie { PlacementPlan(); PlacementPlan(const std::string& id, const std::string& name); - + ~PlacementPlan(); + const std::string& getId() const; const std::string& getName() const; From 0bcedfe2a9848505c4a24aa8da2f3f07d6755db2 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 12 May 2016 09:52:31 -0400 Subject: [PATCH 0205/1644] Keep track of uses device assignments in deployment structures instead of another parallel list --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 122 +++++++++--------- .../sdr/dommgr/ApplicationFactory_impl.h | 9 +- redhawk/src/control/sdr/dommgr/Deployment.cpp | 41 ++++++ redhawk/src/control/sdr/dommgr/Deployment.h | 32 ++++- 4 files changed, 134 insertions(+), 70 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 6c5a0829c..a2bd2cc81 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -996,11 +996,11 @@ void createHelper::_handleUsesDevices(ossie::ApplicationPlacement& appPlacement, // Get the assembly controller's configure properties for context in the // allocations ossie::ComponentInfo* assembly_controller = appPlacement.getAssemblyController(); - CF::Properties appProperties = assembly_controller->getConfigureProperties(); + CF::Properties appProperties; // The device assignments for SAD-level usesdevices are never stored - DeviceAssignmentList assignedDevices; - if (!allocateUsesDevices(appName, usesDevices, appProperties, assignedDevices, this->_allocations)) { + std::vector assignedDevices; + if (!allocateUsesDevices(usesDevices, appProperties, assignedDevices, this->_allocations)) { // There were unsatisfied usesdevices for the application ostringstream eout; eout << "Failed to satisfy 'usesdevice' dependencies "; @@ -1019,10 +1019,10 @@ void createHelper::_handleUsesDevices(ossie::ApplicationPlacement& appPlacement, LOG_DEBUG(ApplicationFactory_impl, eout.str()); throw CF::ApplicationFactory::CreateApplicationError(CF::CF_ENOSPC, eout.str().c_str()); } - for (DeviceAssignmentList::iterator dev=assignedDevices.begin(); dev!=assignedDevices.end(); dev++) { - dev->deviceAssignment.componentId = assembly_controller->getIdentifier().c_str(); + for (std::vector::iterator dev=assignedDevices.begin(); dev!=assignedDevices.end(); dev++) { + //dev->deviceAssignment.componentId = assembly_controller->getIdentifier().c_str(); + _appDeployment.addUsesDeviceAssignment(*dev); } - _appUsedDevs.insert(_appUsedDevs.end(), assignedDevices.begin(), assignedDevices.end()); } void createHelper::setUpExternalPorts(Application_impl* application) @@ -1373,6 +1373,37 @@ throw (CORBA::SystemException, // of the ConnectionManager is passed to the application. _allocations.transfer(allocationIDs); + // Fill in the uses devices for the application + typedef std::vector UsesList; + const UsesList& app_uses = _appDeployment.getUsesDeviceAssignments(); + for (UsesList::const_iterator uses = app_uses.begin(); uses != app_uses.end(); ++uses) { + DeviceAssignmentInfo assignment; + assignment.deviceAssignment.componentId = CORBA::string_dup(name); + std::string deviceId; + try { + deviceId = ossie::corba::returnString((*uses)->getAssignedDevice()->identifier()); + } catch (...) { + } + assignment.deviceAssignment.assignedDeviceId = deviceId.c_str(); + _appUsedDevs.push_back(assignment); + } + + const DeploymentList& deployments = _appDeployment.getComponentDeployments(); + for (DeploymentList::const_iterator dep = deployments.begin(); dep != deployments.end(); ++dep) { + const UsesList& dep_uses = (*dep)->getUsesDeviceAssignments(); + for (UsesList::const_iterator uses = dep_uses.begin(); uses != dep_uses.end(); ++uses) { + DeviceAssignmentInfo assignment; + assignment.deviceAssignment.componentId = (*dep)->getComponent()->getIdentifier().c_str(); + std::string deviceId; + try { + deviceId = ossie::corba::returnString((*uses)->getAssignedDevice()->identifier()); + } catch (...) { + } + assignment.deviceAssignment.assignedDeviceId = deviceId.c_str(); + _appUsedDevs.push_back(assignment); + } + } + _application->populateApplication( assemblyController, _appUsedDevs, @@ -1540,7 +1571,8 @@ ossie::ComponentDeployment* createHelper::allocateComponent(ossie::ComponentInfo // Find the devices that allocate the SPD's minimum required usesdevices properties const UsesDeviceInfo::List &usesDevVec = component->getUsesDevices(); - if (!allocateUsesDevices(component->getIdentifier(), usesDevVec, configureProperties, appAssignedDevs, this->_allocations)) { + std::vector assignedDevices; + if (!allocateUsesDevices(usesDevVec, configureProperties, assignedDevices, this->_allocations)) { // There were unsatisfied usesdevices for the component ostringstream eout; eout << "Failed to satisfy 'usesdevice' dependencies "; @@ -1559,24 +1591,28 @@ ossie::ComponentDeployment* createHelper::allocateComponent(ossie::ComponentInfo LOG_DEBUG(ApplicationFactory_impl, eout.str()); throw CF::ApplicationFactory::CreateApplicationError(CF::CF_ENOSPC, eout.str().c_str()); } - + // now attempt to find an implementation that can have it's allocation requirements met const ossie::ImplementationInfo::List& implementations = component->getImplementations(); for (size_t implCount = 0; implCount < implementations.size(); implCount++) { ossie::ImplementationInfo* impl = implementations[implCount]; // Handle 'usesdevice' dependencies for the particular implementation - DeviceAssignmentList implAllocatedDevices; + std::vector implAssignedDevices; ScopedAllocations implAllocations(*this->_allocationMgr); const UsesDeviceInfo::List &implUsesDevVec = impl->getUsesDevices(); - if (!allocateUsesDevices(component->getIdentifier(), implUsesDevVec, configureProperties, implAllocatedDevices, implAllocations)) { + if (!allocateUsesDevices(implUsesDevVec, configureProperties, implAssignedDevices, implAllocations)) { LOG_DEBUG(ApplicationFactory_impl, "Unable to satisfy 'usesdevice' dependencies for component " << component->getIdentifier() << " implementation " << impl->getId()); continue; } std::auto_ptr deployment(new ossie::ComponentDeployment(component, impl)); + for (std::vector::iterator ii = assignedDevices.begin(); + ii != assignedDevices.end(); ++ii) { + deployment->addUsesDeviceAssignment(*ii); + } // Found an implementation which has its 'usesdevice' dependencies // satisfied, now perform assignment/allocation of component to device @@ -1619,7 +1655,11 @@ ossie::ComponentDeployment* createHelper::allocateComponent(ossie::ComponentInfo // Store the implementation-specific usesdevice allocations and // device assignments implAllocations.transfer(this->_allocations); - std::copy(implAllocatedDevices.begin(), implAllocatedDevices.end(), std::back_inserter(appAssignedDevs)); + + for (std::vector::iterator ii = implAssignedDevices.begin(); + ii != implAssignedDevices.end(); ++ii) { + deployment->addUsesDeviceAssignment(*ii); + } return deployment.release(); } @@ -1659,10 +1699,9 @@ ossie::ComponentDeployment* createHelper::allocateComponent(ossie::ComponentInfo throw CF::ApplicationFactory::CreateApplicationError(CF::CF_ENOSPC, eout.str().c_str()); } -bool createHelper::allocateUsesDevices(const std::string& componentIdentifier, - const ossie::UsesDeviceInfo::List& usesDevices, +bool createHelper::allocateUsesDevices(const ossie::UsesDeviceInfo::List& usesDevices, const CF::Properties& configureProperties, - DeviceAssignmentList& deviceAssignments, + std::vector& deviceAssignments, ScopedAllocations& allocations) { // Create a temporary lookup table for reconciling allocation requests with @@ -1701,10 +1740,8 @@ bool createHelper::allocateUsesDevices(const std::string& componentIdentifier, uses->second->setAssignedDeviceId(deviceId); usesDeviceMap.erase(uses); - DeviceAssignmentInfo assignment; - assignment.deviceAssignment.componentId = componentIdentifier.c_str(); - assignment.deviceAssignment.assignedDeviceId = deviceId.c_str(); - assignment.device = CF::Device::_duplicate(response[resp].allocatedDevice); + ossie::UsesDeviceAssignment* assignment = new ossie::UsesDeviceAssignment(uses->second); + assignment->setAssignedDevice(response[resp].allocatedDevice); deviceAssignments.push_back(assignment); } @@ -2137,38 +2174,6 @@ void createHelper::getRequiredComponents(ossie::ApplicationPlacement& appPlaceme TRACE_EXIT(ApplicationFactory_impl); } -/* Given a device id, returns a CORBA pointer to the device - * - Gets a CORBA pointer for a device from a given id - */ -CF::Device_ptr createHelper::find_device_from_id(const char* device_id) -{ - try { - return CF::Device::_duplicate(find_device_node_from_id(device_id).device); - } catch ( ... ){ - } - - for (DeviceAssignmentList::iterator iter = _appUsedDevs.begin(); iter != _appUsedDevs.end(); ++iter) { - if (strcmp(device_id, iter->deviceAssignment.assignedDeviceId) == 0) { - return CF::Device::_duplicate(iter->device); - } - } - - TRACE_EXIT(ApplicationFactory_impl); - return CF::Device::_nil(); -} - -const ossie::DeviceNode& createHelper::find_device_node_from_id(const char* device_id) throw(std::exception) -{ - for (DeviceList::iterator dn = _registeredDevices.begin(); dn != _registeredDevices.end(); ++dn) { - if ((*dn)->identifier == device_id) { - return **dn; - } - } - - TRACE_EXIT(ApplicationFactory_impl); - throw(std::exception()); -} - /* Given a waveform/application name, return a unique waveform naming context * - Returns a unique waveform naming context * THIS FUNCTION IS NOT THREAD SAFE @@ -3102,32 +3107,27 @@ CF::Device_ptr createHelper::lookupDeviceUsedByComponentInstantiationId(const st } LOG_TRACE(ApplicationFactory_impl, "[DeviceLookup] Uses id " << usesId); - const ossie::UsesDeviceInfo* usesdevice = deployment->getUsesDeviceById(usesId); + const ossie::UsesDeviceAssignment* usesdevice = deployment->getUsesDeviceAssignment(usesId); if (!usesdevice) { LOG_WARN(ApplicationFactory_impl, "[DeviceLookup] UsesDevice not found"); return CF::Device::_nil(); } - std::string deviceId = usesdevice->getAssignedDeviceId(); - LOG_TRACE(ApplicationFactory_impl, "[DeviceLookup] Assigned device id " << deviceId); - - return find_device_from_id(deviceId.c_str()); + //LOG_TRACE(ApplicationFactory_impl, "[DeviceLookup] Assigned device id " << deviceId); + return usesdevice->getAssignedDevice(); } CF::Device_ptr createHelper::lookupDeviceUsedByApplication(const std::string& usesRefId) { LOG_TRACE(ApplicationFactory_impl, "[DeviceLookup] Lookup device used by application, Uses Id: " << usesRefId); - - const ossie::UsesDeviceInfo* usesdevice = _appInfo.getUsesDeviceById(usesRefId); + const ossie::UsesDeviceAssignment* usesdevice = _appDeployment.getUsesDeviceAssignment(usesRefId); if (!usesdevice) { LOG_WARN(ApplicationFactory_impl, "[DeviceLookup] UsesDevice not found"); return CF::Device::_nil(); } - std::string deviceId = usesdevice->getAssignedDeviceId(); - LOG_TRACE(ApplicationFactory_impl, "[DeviceLookup] Assigned device id " << deviceId); - - return find_device_from_id(deviceId.c_str()); + //LOG_TRACE(ApplicationFactory_impl, "[DeviceLookup] Assigned device id " << deviceId); + return usesdevice->getAssignedDevice(); } diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h index a331ce42c..b10fc7974 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h @@ -239,10 +239,9 @@ public ossie::DeviceLookup ossie::ComponentInfo* buildComponentInfo(const ossie::ComponentPlacement& component); // Supports allocation - bool allocateUsesDevices(const std::string& componentIdentifier, - const ossie::UsesDeviceInfo::List& usesDevices, + bool allocateUsesDevices(const ossie::UsesDeviceInfo::List& usesDevices, const CF::Properties& configureProperties, - DeviceAssignmentList& deviceAssignments, + std::vector& assignedDevices, ScopedAllocations& allocations); CF::AllocationManager::AllocationResponseSequence* allocateUsesDeviceProperties( const ossie::UsesDeviceInfo::List& component, @@ -277,10 +276,6 @@ public ossie::DeviceLookup std::vector& connections, std::string base_naming_context); - // Functions for looking up particular components/devices - CF::Device_ptr find_device_from_id(const char*); - const ossie::DeviceNode& find_device_node_from_id(const char*) throw(std::exception); - // Cleanup - used when create fails/doesn't succeed for some reason bool _isComplete; void _cleanupFailedCreate(); diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index f7e6a4fe7..e05e485ff 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -25,6 +25,47 @@ using namespace ossie; namespace fs = boost::filesystem; +void UsesDeviceDeployment::addUsesDeviceAssignment(UsesDeviceAssignment* assignment) +{ + assignments.push_back(assignment); +} + +UsesDeviceAssignment* UsesDeviceDeployment::getUsesDeviceAssignment(const std::string identifier) +{ + for (AssignmentList::iterator assign = assignments.begin(); assign != assignments.end(); ++assign) { + if (identifier == (*assign)->getUsesDevice()->getId()) { + return *assign; + } + } + + return 0; +} + +const UsesDeviceDeployment::AssignmentList& UsesDeviceDeployment::getUsesDeviceAssignments() +{ + return assignments; +} + +UsesDeviceAssignment::UsesDeviceAssignment(UsesDeviceInfo* usesDevice) : + usesDevice(usesDevice) +{ +} + +UsesDeviceInfo* UsesDeviceAssignment::getUsesDevice() +{ + return usesDevice; +} + +void UsesDeviceAssignment::setAssignedDevice(CF::Device_ptr device) +{ + assignedDevice = CF::Device::_duplicate(device); +} + +CF::Device_ptr UsesDeviceAssignment::getAssignedDevice() const +{ + return CF::Device::_duplicate(assignedDevice); +} + SoftpkgDeployment::SoftpkgDeployment(SoftpkgInfo* softpkg, const ImplementationInfo* implementation) : softpkg(softpkg), implementation(implementation) diff --git a/redhawk/src/control/sdr/dommgr/Deployment.h b/redhawk/src/control/sdr/dommgr/Deployment.h index 09cdb761b..0c9ad020a 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.h +++ b/redhawk/src/control/sdr/dommgr/Deployment.h @@ -32,6 +32,34 @@ namespace ossie { + class UsesDeviceAssignment + { + public: + UsesDeviceAssignment(UsesDeviceInfo* usesDevice); + + UsesDeviceInfo* getUsesDevice(); + + void setAssignedDevice(CF::Device_ptr device); + CF::Device_ptr getAssignedDevice() const; + + private: + UsesDeviceInfo* usesDevice; + CF::Device_var assignedDevice; + }; + + class UsesDeviceDeployment + { + public: + typedef std::vector AssignmentList; + + void addUsesDeviceAssignment(UsesDeviceAssignment* assignment); + UsesDeviceAssignment* getUsesDeviceAssignment(const std::string identifier); + const AssignmentList& getUsesDeviceAssignments(); + + protected: + AssignmentList assignments; + }; + class SoftpkgDeployment { public: @@ -56,7 +84,7 @@ namespace ossie { DeploymentList dependencies; }; - class ComponentDeployment : public SoftpkgDeployment + class ComponentDeployment : public SoftpkgDeployment, public UsesDeviceDeployment { public: ComponentDeployment(ComponentInfo* component, ImplementationInfo* implementation); @@ -90,7 +118,7 @@ namespace ossie { redhawk::PropertyMap affinityOptions; }; - class ApplicationDeployment : public ComponentLookup + class ApplicationDeployment : public ComponentLookup, public UsesDeviceDeployment { public: typedef std::vector ComponentList; From dd7aafde8e59f4f4689ecc1f91804c6fd200cfe1 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 12 May 2016 10:15:10 -0400 Subject: [PATCH 0206/1644] Move device lookup responsibility to application deployment class --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 69 +------------------ .../sdr/dommgr/ApplicationFactory_impl.h | 16 +---- redhawk/src/control/sdr/dommgr/Deployment.cpp | 56 +++++++++++++++ redhawk/src/control/sdr/dommgr/Deployment.h | 12 +++- .../control/sdr/dommgr/connectionSupport.h | 9 +++ 5 files changed, 79 insertions(+), 83 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index a2bd2cc81..d0a417ccd 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -2983,10 +2983,8 @@ void createHelper::connectComponents(std::vector& connections, s const std::vector& _connection = _appFact._sadParser.getConnections (); // Create an AppConnectionManager to resolve and track all connections in the application. - // NB: Use an auto_ptr instead of a bare pointer so that it will automatically be deleted - // in the event of a failure. using ossie::AppConnectionManager; - std::auto_ptr connectionManager(new AppConnectionManager(_appFact._domainManager, &_appDeployment, this, base_naming_context)); + AppConnectionManager connectionManager(_appFact._domainManager, &_appDeployment, &_appDeployment, base_naming_context); // Create all resource connections LOG_TRACE(ApplicationFactory_impl, "Establishing " << _connection.size() << " waveform connections") @@ -2996,7 +2994,7 @@ void createHelper::connectComponents(std::vector& connections, s LOG_TRACE(ApplicationFactory_impl, "Processing connection " << connection.getID()); // Attempt to resolve the connection; if any connection fails, application creation fails. - if (!connectionManager->resolveConnection(connection)) { + if (!connectionManager.resolveConnection(connection)) { LOG_ERROR(ApplicationFactory_impl, "Unable to make connection " << connection.getID()); ostringstream eout; eout << "Unable to make connection " << connection.getID(); @@ -3007,7 +3005,7 @@ void createHelper::connectComponents(std::vector& connections, s } // Copy all established connections into the connection array - const std::vector& establishedConnections = connectionManager->getConnections(); + const std::vector& establishedConnections = connectionManager.getConnections(); std::copy(establishedConnections.begin(), establishedConnections.end(), std::back_inserter(connections)); } @@ -3070,64 +3068,3 @@ void createHelper::_cleanupFailedCreate() _waveformContext->destroy(); } CATCH_LOG_WARN(ApplicationFactory_impl, "Could not destroy naming context"); } - -/* Given a component instantiation id, returns the associated CORBA Device pointer - * - Gets the Device pointer for a particular component instantiation id - */ -CF::Device_ptr createHelper::lookupDeviceThatLoadedComponentInstantiationId(const std::string& componentId) -{ - LOG_TRACE(ApplicationFactory_impl, "[DeviceLookup] Lookup device that loaded component " << componentId); - - ossie::ComponentDeployment* deployment = _appDeployment.getComponentDeployment(componentId); - if (!deployment) { - LOG_WARN(ApplicationFactory_impl, "[DeviceLookup] Component not found"); - return CF::Device::_nil(); - } - - boost::shared_ptr device = deployment->getAssignedDevice(); - if (!device) { - LOG_WARN(ApplicationFactory_impl, "[DeviceLookup] Component not assigned to device"); - return CF::Device::_nil(); - } - LOG_TRACE(ApplicationFactory_impl, "[DeviceLookup] Assigned device id " << device->identifier); - return CF::Device::_duplicate(device->device); -} - - -/* Given a component instantiation id and uses id, returns the associated CORBA Device pointer - * - Gets the Device pointer for a particular component instantiation id and uses id - */ -CF::Device_ptr createHelper::lookupDeviceUsedByComponentInstantiationId(const std::string& componentId, const std::string& usesId) -{ - LOG_TRACE(ApplicationFactory_impl, "[DeviceLookup] Lookup device used by component " << componentId); - ossie::ComponentDeployment* deployment = _appDeployment.getComponentDeployment(componentId); - if (!deployment) { - LOG_WARN(ApplicationFactory_impl, "[DeviceLookup] Component not found"); - return CF::Device::_nil(); - } - - LOG_TRACE(ApplicationFactory_impl, "[DeviceLookup] Uses id " << usesId); - const ossie::UsesDeviceAssignment* usesdevice = deployment->getUsesDeviceAssignment(usesId); - if (!usesdevice) { - LOG_WARN(ApplicationFactory_impl, "[DeviceLookup] UsesDevice not found"); - return CF::Device::_nil(); - } - - //LOG_TRACE(ApplicationFactory_impl, "[DeviceLookup] Assigned device id " << deviceId); - return usesdevice->getAssignedDevice(); -} - -CF::Device_ptr createHelper::lookupDeviceUsedByApplication(const std::string& usesRefId) -{ - LOG_TRACE(ApplicationFactory_impl, "[DeviceLookup] Lookup device used by application, Uses Id: " << usesRefId); - - const ossie::UsesDeviceAssignment* usesdevice = _appDeployment.getUsesDeviceAssignment(usesRefId); - if (!usesdevice) { - LOG_WARN(ApplicationFactory_impl, "[DeviceLookup] UsesDevice not found"); - return CF::Device::_nil(); - } - - //LOG_TRACE(ApplicationFactory_impl, "[DeviceLookup] Assigned device id " << deviceId); - return usesdevice->getAssignedDevice(); -} - diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h index b10fc7974..1ebec6366 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h @@ -139,8 +139,7 @@ class ScopedAllocations { std::list _allocations; }; -class createHelper: -public ossie::DeviceLookup +class createHelper { public: @@ -280,18 +279,5 @@ public ossie::DeviceLookup bool _isComplete; void _cleanupFailedCreate(); Application_impl* _application; - - /* Implements the ConnectionManager functions - * - Makes this class compatible with the ConnectionManager - */ - // DeviceLookup interface - CF::Device_ptr lookupDeviceThatLoadedComponentInstantiationId(const std::string& componentId); - CF::Device_ptr lookupDeviceUsedByComponentInstantiationId( - const std::string& componentId, - const std::string& usesId); - CF::Device_ptr lookupDeviceUsedByApplication(const std::string& usesRefId); - - std::string createVersionMismatchMessage(std::string &component_version); - }; #endif diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index e05e485ff..09cdb6e2f 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -20,6 +20,7 @@ #include +#include "PersistenceStore.h" #include "Deployment.h" using namespace ossie; @@ -292,3 +293,58 @@ CF::Resource_ptr ApplicationDeployment::lookupComponentByInstantiationId(const s } return CF::Resource::_nil(); } + +CF::Device_ptr ApplicationDeployment::lookupDeviceThatLoadedComponentInstantiationId(const std::string& componentId) +{ + RH_NL_TRACE("ApplicationFactory_impl", "[DeviceLookup] Lookup device that loaded component " << componentId); + + ComponentDeployment* deployment = getComponentDeployment(componentId); + if (!deployment) { + RH_NL_WARN("ApplicationFactory_impl", "[DeviceLookup] Component not found"); + return CF::Device::_nil(); + } + + boost::shared_ptr device = deployment->getAssignedDevice(); + if (!device) { + RH_NL_WARN("ApplicationFactory_impl", "[DeviceLookup] Component not assigned to device"); + return CF::Device::_nil(); + } + + RH_NL_TRACE("ApplicationFactory_impl", "[DeviceLookup] Assigned device id " << device->identifier); + return CF::Device::_duplicate(device->device); +} + +CF::Device_ptr ApplicationDeployment::lookupDeviceUsedByComponentInstantiationId(const std::string& componentId, + const std::string& usesId) +{ + RH_NL_TRACE("ApplicationFactory_impl", "[DeviceLookup] Lookup device used by component " << componentId); + + ComponentDeployment* deployment = getComponentDeployment(componentId); + if (!deployment) { + RH_NL_WARN("ApplicationFactory_impl", "[DeviceLookup] Component not found"); + return CF::Device::_nil(); + } + + UsesDeviceAssignment* uses = deployment->getUsesDeviceAssignment(usesId); + if (!uses) { + RH_NL_WARN("ApplicationFactory_impl", "[DeviceLookup] UsesDevice not found"); + return CF::Device::_nil(); + } + + //RH_NL_TRACE("ApplicationFactory_impl", "[DeviceLookup] Assigned device id " << deviceId); + return uses->getAssignedDevice(); +} + +CF::Device_ptr ApplicationDeployment::lookupDeviceUsedByApplication(const std::string& usesRefId) +{ + RH_NL_TRACE("ApplicationFactory_impl", "[DeviceLookup] Lookup device used by application, Uses Id: " << usesRefId); + + UsesDeviceAssignment* uses = getUsesDeviceAssignment(usesRefId); + if (!uses) { + RH_NL_WARN("ApplicationFactory_impl", "[DeviceLookup] UsesDevice not found"); + return CF::Device::_nil(); + } + + //RH_NL_TRACE("ApplicationFactory_impl", "[DeviceLookup] Assigned device id " << deviceId); + return uses->getAssignedDevice(); +} diff --git a/redhawk/src/control/sdr/dommgr/Deployment.h b/redhawk/src/control/sdr/dommgr/Deployment.h index 0c9ad020a..d83d8dff9 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.h +++ b/redhawk/src/control/sdr/dommgr/Deployment.h @@ -118,7 +118,7 @@ namespace ossie { redhawk::PropertyMap affinityOptions; }; - class ApplicationDeployment : public ComponentLookup, public UsesDeviceDeployment + class ApplicationDeployment : public ComponentLookup, public DeviceLookup, public UsesDeviceDeployment { public: typedef std::vector ComponentList; @@ -130,9 +130,17 @@ namespace ossie { const ComponentList& getComponentDeployments(); ComponentDeployment* getComponentDeployment(const std::string& instantiationId); - // Adapt to ComponentLookup interface + // Adapt interfaces for component and device search to support + // ConnectionManager + // ComponentLookup interface virtual CF::Resource_ptr lookupComponentByInstantiationId(const std::string& identifier); + // DeviceLookup interface + CF::Device_ptr lookupDeviceThatLoadedComponentInstantiationId(const std::string& componentId); + CF::Device_ptr lookupDeviceUsedByComponentInstantiationId(const std::string& componentId, + const std::string& usesId); + CF::Device_ptr lookupDeviceUsedByApplication(const std::string& usesRefId); + protected: ComponentList components; }; diff --git a/redhawk/src/control/sdr/dommgr/connectionSupport.h b/redhawk/src/control/sdr/dommgr/connectionSupport.h index c3504f690..a5b508ab6 100644 --- a/redhawk/src/control/sdr/dommgr/connectionSupport.h +++ b/redhawk/src/control/sdr/dommgr/connectionSupport.h @@ -77,8 +77,17 @@ namespace ossie { public: virtual ~DeviceLookup() {}; + + /* Given a component instantiation id, returns the associated CORBA Device pointer + */ virtual CF::Device_ptr lookupDeviceThatLoadedComponentInstantiationId(const std::string& componentId) = 0; + + /* Given a component instantiation id and uses id, returns the associated CORBA Device pointer + */ virtual CF::Device_ptr lookupDeviceUsedByComponentInstantiationId(const std::string& componentId, const std::string& usesId) = 0; + + /* Given a uses id, returns the associated CORBA Device pointer + */ virtual CF::Device_ptr lookupDeviceUsedByApplication(const std::string& usesRefId) = 0; }; From aaa78633408f3ea29d275840d72bbd268d3e2132 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 12 May 2016 10:16:34 -0400 Subject: [PATCH 0207/1644] Actually get the assembly controller's properties for uses device allocation, if possible --- redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index d0a417ccd..8c30fd586 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -995,8 +995,11 @@ void createHelper::_handleUsesDevices(ossie::ApplicationPlacement& appPlacement, // Get the assembly controller's configure properties for context in the // allocations - ossie::ComponentInfo* assembly_controller = appPlacement.getAssemblyController(); CF::Properties appProperties; + ossie::ComponentInfo* assembly_controller = appPlacement.getAssemblyController(); + if (assembly_controller) { + appProperties = assembly_controller->getConfigureProperties(); + } // The device assignments for SAD-level usesdevices are never stored std::vector assignedDevices; From c902e017f4f12b9dce5612777d2272027eab4c57 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 12 May 2016 10:30:50 -0400 Subject: [PATCH 0208/1644] Build the entire application used device list at point-of-use, removing member --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 30 ++++++++----------- .../sdr/dommgr/ApplicationFactory_impl.h | 5 ---- 2 files changed, 13 insertions(+), 22 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 8c30fd586..6e7ca477c 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -708,7 +708,7 @@ void createHelper::assignPlacementsToDevices(ossie::ApplicationPlacement& appPla LOG_TRACE(ApplicationFactory_impl, "Component " << component->getInstantiationIdentifier() << " is assigned to device " << assigned_device); } - ossie::ComponentDeployment* deployment = allocateComponent(component, assigned_device, _appUsedDevs, appIdentifier); + ossie::ComponentDeployment* deployment = allocateComponent(component, assigned_device, appIdentifier); _appDeployment.addComponentDeployment(deployment); } } @@ -972,10 +972,6 @@ void createHelper::_placeHostCollocation(const std::string &appIdentifier, // Move the device to the front of the list rotateDeviceList(_executableDevices, deviceId); - - _appUsedDevs.insert(_appUsedDevs.end(), - collocAssignedDevs.begin(), - collocAssignedDevs.end()); return; } } @@ -1377,6 +1373,7 @@ throw (CORBA::SystemException, _allocations.transfer(allocationIDs); // Fill in the uses devices for the application + DeviceAssignmentList app_devices; typedef std::vector UsesList; const UsesList& app_uses = _appDeployment.getUsesDeviceAssignments(); for (UsesList::const_iterator uses = app_uses.begin(); uses != app_uses.end(); ++uses) { @@ -1388,28 +1385,34 @@ throw (CORBA::SystemException, } catch (...) { } assignment.deviceAssignment.assignedDeviceId = deviceId.c_str(); - _appUsedDevs.push_back(assignment); + app_devices.push_back(assignment); } const DeploymentList& deployments = _appDeployment.getComponentDeployments(); for (DeploymentList::const_iterator dep = deployments.begin(); dep != deployments.end(); ++dep) { + ossie::ComponentInfo* component = (*dep)->getComponent(); + DeviceAssignmentInfo comp_assignment; + comp_assignment.deviceAssignment.componentId = component->getIdentifier().c_str(); + comp_assignment.deviceAssignment.assignedDeviceId = (*dep)->getAssignedDevice()->identifier.c_str(); + app_devices.push_back(comp_assignment); + const UsesList& dep_uses = (*dep)->getUsesDeviceAssignments(); for (UsesList::const_iterator uses = dep_uses.begin(); uses != dep_uses.end(); ++uses) { DeviceAssignmentInfo assignment; - assignment.deviceAssignment.componentId = (*dep)->getComponent()->getIdentifier().c_str(); + assignment.deviceAssignment.componentId = component->getIdentifier().c_str(); std::string deviceId; try { deviceId = ossie::corba::returnString((*uses)->getAssignedDevice()->identifier()); } catch (...) { } assignment.deviceAssignment.assignedDeviceId = deviceId.c_str(); - _appUsedDevs.push_back(assignment); + app_devices.push_back(assignment); } } _application->populateApplication( assemblyController, - _appUsedDevs, + app_devices, _startSeq, connections, allocationIDs); @@ -1559,9 +1562,8 @@ CF::AllocationManager::AllocationResponseSequence* createHelper::allocateUsesDev collocation request. This requires that we know and cleanup only those allocations that we made.. */ -ossie::ComponentDeployment* createHelper::allocateComponent(ossie::ComponentInfo* component, +ossie::ComponentDeployment* createHelper::allocateComponent(ossie::ComponentInfo* component, const std::string& assignedDeviceId, - DeviceAssignmentList &appAssignedDevs, const std::string& appIdentifier) { CF::Properties configureProperties = component->getConfigureProperties(); @@ -1649,12 +1651,6 @@ ossie::ComponentDeployment* createHelper::allocateComponent(ossie::ComponentInfo // Move the device to the front of the list rotateDeviceList(_executableDevices, deviceId); - ossie::DeviceAssignmentInfo dai; - dai.deviceAssignment.componentId = component->getIdentifier().c_str(); - dai.deviceAssignment.assignedDeviceId = deviceId.c_str(); - dai.device = CF::Device::_duplicate(node.device); - appAssignedDevs.push_back(dai); - // Store the implementation-specific usesdevice allocations and // device assignments implAllocations.transfer(this->_allocations); diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h index 1ebec6366..d1cc306b8 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h @@ -183,10 +183,6 @@ class createHelper ossie::DeviceList _executableDevices; std::map specialized_reservations; - // - // List of used devices allocated during application creation - // - DeviceAssignmentList _appUsedDevs; std::vector _startSeq; std::vector _startOrderIds; @@ -247,7 +243,6 @@ class createHelper const CF::Properties& configureProperties); ossie::ComponentDeployment* allocateComponent(ossie::ComponentInfo* component, const std::string& assignedDeviceId, - DeviceAssignmentList &appAssignedDevices, const std::string& appIdentifier); ossie::AllocationResult allocateComponentToDevice(ossie::ComponentDeployment* deployment, From 8903d10831e9280593713f158b2e896a81349d67 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 12 May 2016 11:04:01 -0400 Subject: [PATCH 0209/1644] Manage application deployment object as local to the create call, rather than as a member --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 85 ++++++++++--------- .../sdr/dommgr/ApplicationFactory_impl.h | 31 ++++--- 2 files changed, 64 insertions(+), 52 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 6e7ca477c..5a0ef0c68 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -661,9 +661,10 @@ void createHelper::_checkAssemblyController( } } -void createHelper::_connectComponents(std::vector& connections){ +void createHelper::_connectComponents(ossie::ApplicationDeployment& appDeployment, + std::vector& connections){ try{ - connectComponents(connections, _baseNamingContext); + connectComponents(appDeployment, connections, _baseNamingContext); } catch (CF::ApplicationFactory::CreateApplicationError& ex) { throw; } CATCH_THROW_LOG_TRACE( @@ -674,10 +675,10 @@ void createHelper::_connectComponents(std::vector& connections){ "Connecting components failed (unclear where this occurred)")); } -void createHelper::_configureComponents() +void createHelper::_configureComponents(const DeploymentList& deployments) { try{ - configureComponents(); + configureComponents(deployments); } catch (CF::ApplicationFactory::CreateApplicationError& ex) { throw; } CATCH_THROW_LOG_TRACE( @@ -687,6 +688,7 @@ void createHelper::_configureComponents() } void createHelper::assignPlacementsToDevices(ossie::ApplicationPlacement& appPlacement, + ossie::ApplicationDeployment& appDeployment, const std::string& appIdentifier, const DeviceAssignmentMap& devices) { typedef ossie::ApplicationPlacement::PlacementList PlacementPlanList; @@ -696,7 +698,7 @@ void createHelper::assignPlacementsToDevices(ossie::ApplicationPlacement& appPla if (components.size() > 1) { LOG_TRACE(ApplicationFactory_impl, "Placing host collocation " << (*plan)->getId() << " " << (*plan)->getName()); - _placeHostCollocation(appIdentifier, components, devices); + _placeHostCollocation(appDeployment, appIdentifier, components, devices); LOG_TRACE(ApplicationFactory_impl, "-- Completed placement for Collocation ID:" << (*plan)->getId() << " Components Placed: " << components.size()); } else { @@ -709,7 +711,7 @@ void createHelper::assignPlacementsToDevices(ossie::ApplicationPlacement& appPla << " is assigned to device " << assigned_device); } ossie::ComponentDeployment* deployment = allocateComponent(component, assigned_device, appIdentifier); - _appDeployment.addComponentDeployment(deployment); + appDeployment.addComponentDeployment(deployment); } } } @@ -893,7 +895,8 @@ void createHelper::_consolidateAllocations(const ossie::ImplementationInfo::List } } -void createHelper::_placeHostCollocation(const std::string &appIdentifier, +void createHelper::_placeHostCollocation(ossie::ApplicationDeployment& appDeployment, + const std::string &appIdentifier, const PlacementList& collocatedComponents, const DeviceAssignmentMap& devices) { @@ -967,7 +970,7 @@ void createHelper::_placeHostCollocation(const std::string &appIdentifier, continue; } collocAssignedDevs[i].deviceAssignment.componentId = (*comp)->getIdentifier().c_str(); - _appDeployment.addComponentDeployment(deployment); + appDeployment.addComponentDeployment(deployment); } // Move the device to the front of the list @@ -983,7 +986,9 @@ void createHelper::_placeHostCollocation(const std::string &appIdentifier, throw CF::ApplicationFactory::CreateApplicationRequestError(); } -void createHelper::_handleUsesDevices(ossie::ApplicationPlacement& appPlacement, const std::string& appName) +void createHelper::_handleUsesDevices(ossie::ApplicationPlacement& appPlacement, + ossie::ApplicationDeployment& appDeployment, + const std::string& appName) { // Gets all uses device info from the SAD file const UsesDeviceInfo::List& usesDevices = _appInfo.getUsesDevices(); @@ -1020,11 +1025,12 @@ void createHelper::_handleUsesDevices(ossie::ApplicationPlacement& appPlacement, } for (std::vector::iterator dev=assignedDevices.begin(); dev!=assignedDevices.end(); dev++) { //dev->deviceAssignment.componentId = assembly_controller->getIdentifier().c_str(); - _appDeployment.addUsesDeviceAssignment(*dev); + appDeployment.addUsesDeviceAssignment(*dev); } } -void createHelper::setUpExternalPorts(Application_impl* application) +void createHelper::setUpExternalPorts(ossie::ApplicationDeployment& appDeployment, + Application_impl* application) { typedef std::vector PortList; const PortList& ports = _appFact._sadParser.getExternalPorts(); @@ -1037,7 +1043,7 @@ void createHelper::setUpExternalPorts(Application_impl* application) << " Port identifier: " << port->identifier); // Get the component from the instantiation identifier. - ossie::ComponentDeployment* deployment = _appDeployment.getComponentDeployment(port->componentrefid); + ossie::ComponentDeployment* deployment = appDeployment.getComponentDeployment(port->componentrefid); if (!deployment) { LOG_ERROR(ApplicationFactory_impl, "Invalid componentinstantiationref (" @@ -1087,7 +1093,8 @@ void createHelper::setUpExternalPorts(Application_impl* application) } } -void createHelper::setUpExternalProperties(Application_impl* application) +void createHelper::setUpExternalProperties(ossie::ApplicationDeployment& appDeployment, + Application_impl* application) { const std::vector& props = _appFact._sadParser.getExternalProperties(); LOG_TRACE(ApplicationFactory_impl, "Mapping " << props.size() << " external property(ies)"); @@ -1095,7 +1102,7 @@ void createHelper::setUpExternalProperties(Application_impl* application) LOG_TRACE(ApplicationFactory_impl, "Property component: " << prop->comprefid << " Property identifier: " << prop->propid); // Get the component from the compref identifier. - ossie::ComponentDeployment* deployment = _appDeployment.getComponentDeployment(prop->comprefid); + ossie::ComponentDeployment* deployment = appDeployment.getComponentDeployment(prop->comprefid); if (!deployment) { LOG_ERROR(ApplicationFactory_impl, "Unable to find component for comprefid " << prop->comprefid); throw CF::ApplicationFactory::CreateApplicationError(CF::CF_NOTSET, "Unable to find component for given comprefid"); @@ -1306,9 +1313,10 @@ throw (CORBA::SystemException, //////////////////////////////////////////////// // Assign components to devices //////////////////////////////////////////////// + ossie::ApplicationDeployment app_deployment; // Allocate any usesdevice capacities specified in the SAD file - _handleUsesDevices(placement, name); + _handleUsesDevices(placement, app_deployment, name); // Give the application a unique identifier of the form // "softwareassemblyid:ApplicationName", where the application @@ -1321,7 +1329,7 @@ throw (CORBA::SystemException, _validateDAS(placement, deviceAssignments); // Assign all components to devices - assignPlacementsToDevices(placement, appIdentifier, deviceAssignments); + assignPlacementsToDevices(placement, app_deployment, appIdentifier, deviceAssignments); //////////////////////////////////////////////// // Create the Application servant @@ -1344,24 +1352,24 @@ throw (CORBA::SystemException, std::vector allocationIDs; CF::ApplicationRegistrar_var app_reg = _application->appReg(); - loadAndExecuteComponents(app_reg); - waitForComponentRegistration(); - initializeComponents(); + loadAndExecuteComponents(app_deployment.getComponentDeployments(), app_reg); + waitForComponentRegistration(app_deployment.getComponentDeployments()); + initializeComponents(app_deployment.getComponentDeployments()); // Check that the assembly controller is valid CF::Resource_var assemblyController; if (assemblyControllerComponent) { const std::string& assemblyControllerId = assemblyControllerComponent->getInstantiationIdentifier(); - ossie::ComponentDeployment* deployment = _appDeployment.getComponentDeployment(assemblyControllerId); + ossie::ComponentDeployment* deployment = app_deployment.getComponentDeployment(assemblyControllerId); assemblyController = deployment->getResourcePtr(); } _checkAssemblyController(assemblyController, assemblyControllerComponent); - _connectComponents(connections); - _configureComponents(); + _connectComponents(app_deployment, connections); + _configureComponents(app_deployment.getComponentDeployments()); - setUpExternalPorts(_application); - setUpExternalProperties(_application); + setUpExternalPorts(app_deployment, _application); + setUpExternalProperties(app_deployment, _application); //////////////////////////////////////////////// // Create the application @@ -1375,7 +1383,7 @@ throw (CORBA::SystemException, // Fill in the uses devices for the application DeviceAssignmentList app_devices; typedef std::vector UsesList; - const UsesList& app_uses = _appDeployment.getUsesDeviceAssignments(); + const UsesList& app_uses = app_deployment.getUsesDeviceAssignments(); for (UsesList::const_iterator uses = app_uses.begin(); uses != app_uses.end(); ++uses) { DeviceAssignmentInfo assignment; assignment.deviceAssignment.componentId = CORBA::string_dup(name); @@ -1388,7 +1396,7 @@ throw (CORBA::SystemException, app_devices.push_back(assignment); } - const DeploymentList& deployments = _appDeployment.getComponentDeployments(); + const DeploymentList& deployments = app_deployment.getComponentDeployments(); for (DeploymentList::const_iterator dep = deployments.begin(); dep != deployments.end(); ++dep) { ossie::ComponentInfo* component = (*dep)->getComponent(); DeviceAssignmentInfo comp_assignment; @@ -2265,12 +2273,12 @@ void createHelper::loadDependencies(const ossie::ComponentInfo& component, /* Perform 'load' and 'execute' operations to launch component on the assigned device * - Actually loads and executes the component on the given device */ -void createHelper::loadAndExecuteComponents(CF::ApplicationRegistrar_ptr _appReg) +void createHelper::loadAndExecuteComponents(const DeploymentList& deployments, + CF::ApplicationRegistrar_ptr _appReg) { - const DeploymentList& deployments = _appDeployment.getComponentDeployments(); LOG_TRACE(ApplicationFactory_impl, "Loading and Executing " << deployments.size() << " components"); // apply application affinity options to required components - applyApplicationAffinityOptions(); + applyApplicationAffinityOptions(deployments); for (unsigned int rc_idx = 0; rc_idx < deployments.size (); rc_idx++) { ossie::ComponentDeployment* deployment = deployments[rc_idx]; @@ -2612,7 +2620,7 @@ void createHelper::attemptComponentExecution (CF::ApplicationRegistrar_ptr regis } -void createHelper::applyApplicationAffinityOptions() { +void createHelper::applyApplicationAffinityOptions(const DeploymentList& deployments) { if ( _app_affinity.length() > 0 ) { // log deployments with application affinity @@ -2625,7 +2633,6 @@ void createHelper::applyApplicationAffinityOptions() { // Promote NIC affinity for all components deployed on the same device // boost::shared_ptr deploy_on_device; - const DeploymentList& deployments = _appDeployment.getComponentDeployments(); for (unsigned int rc_idx = 0; rc_idx < deployments.size(); rc_idx++) { ossie::ComponentDeployment* deployment = deployments[rc_idx]; if (!(deployment->getNicAssignment().empty())) { @@ -2646,7 +2653,8 @@ void createHelper::applyApplicationAffinityOptions() { } } -void createHelper::waitForComponentRegistration() + +void createHelper::waitForComponentRegistration(const DeploymentList& deployments) { // Wait for all components to be registered before continuing int componentBindingTimeout = _appFact._domainManager->getComponentBindingTimeout(); @@ -2655,7 +2663,6 @@ void createHelper::waitForComponentRegistration() // Track only SCA-compliant components; non-compliant components will never // register with the application, nor do they need to be initialized std::set expected_components; - const DeploymentList& deployments = _appDeployment.getComponentDeployments(); for (DeploymentList::const_iterator ii = deployments.begin(); ii != deployments.end(); ++ii) { ossie::ComponentInfo* component = (*ii)->getComponent(); if (component->isScaCompliant()) { @@ -2692,10 +2699,9 @@ void createHelper::waitForComponentRegistration() * - Ensure components have started and are bound to Naming Service * - Initialize each component */ -void createHelper::initializeComponents() +void createHelper::initializeComponents(const DeploymentList& deployments) { // Install the different components in the system - const DeploymentList& deployments = _appDeployment.getComponentDeployments(); LOG_TRACE(ApplicationFactory_impl, "initializing " << deployments.size() << " waveform components") // Resize the _startSeq vector to the right size @@ -2861,11 +2867,10 @@ void createHelper::initializeComponents() } } -void createHelper::configureComponents() +void createHelper::configureComponents(const DeploymentList& deployments) { DeploymentList configure_list; ossie::ComponentDeployment* ac_deployment = 0; - const DeploymentList& deployments = _appDeployment.getComponentDeployments(); for (DeploymentList::const_iterator depl = deployments.begin(); depl != deployments.end(); ++depl) { const ossie::ComponentInfo* component = (*depl)->getComponent(); if (!component->isScaCompliant()) { @@ -2977,13 +2982,15 @@ void createHelper::configureComponents() /* Connect the components * - Connect the components */ -void createHelper::connectComponents(std::vector& connections, string base_naming_context) +void createHelper::connectComponents(ossie::ApplicationDeployment& appDeployment, + std::vector& connections, + string base_naming_context) { const std::vector& _connection = _appFact._sadParser.getConnections (); // Create an AppConnectionManager to resolve and track all connections in the application. using ossie::AppConnectionManager; - AppConnectionManager connectionManager(_appFact._domainManager, &_appDeployment, &_appDeployment, base_naming_context); + AppConnectionManager connectionManager(_appFact._domainManager, &appDeployment, &appDeployment, base_naming_context); // Create all resource connections LOG_TRACE(ApplicationFactory_impl, "Establishing " << _connection.size() << " waveform connections") diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h index d1cc306b8..0d94a1353 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h @@ -199,27 +199,31 @@ class createHelper ossie::ApplicationInfo _appInfo; typedef std::vector DeploymentList; - ossie::ApplicationDeployment _appDeployment; // createHelper helper methods void overrideExternalProperties(ossie::ApplicationPlacement& appPlacement, const CF::Properties& initConfiguration); void overrideProperties(const CF::Properties& initConfiguration, ossie::ComponentInfo* component); void assignPlacementsToDevices(ossie::ApplicationPlacement& appPlacement, + ossie::ApplicationDeployment& appDeployment, const std::string& appIdentifier, const DeviceAssignmentMap& devices); void _validateDAS(ossie::ApplicationPlacement& appPlacement, const DeviceAssignmentMap& deviceAssignments); - void _connectComponents( + void _connectComponents(ossie::ApplicationDeployment& appDeployment, std::vector& connections); - void _configureComponents(); + void _configureComponents(const DeploymentList& deployments); void _checkAssemblyController( CF::Resource_ptr assemblyController, ossie::ComponentInfo* assemblyControllerComponent) const; - void setUpExternalPorts(Application_impl* application); - void setUpExternalProperties(Application_impl* application); - void _placeHostCollocation(const std::string& appIdentifier, const PlacementList& collocatedComponents, + void setUpExternalPorts(ossie::ApplicationDeployment& appDeployment, Application_impl* application); + void setUpExternalProperties(ossie::ApplicationDeployment& appDeployment, Application_impl* application); + void _placeHostCollocation(ossie::ApplicationDeployment& appDeployment, + const std::string& appIdentifier, + const PlacementList& collocatedComponents, const DeviceAssignmentMap& devices); - void _handleUsesDevices(ossie::ApplicationPlacement& appPlacement, const std::string& appName); + void _handleUsesDevices(ossie::ApplicationPlacement& appPlacement, + ossie::ApplicationDeployment& appDeployment, + const std::string& appName); void _resolveImplementations(PlacementList::iterator comp, PlacementList& compList, std::vector &res_vec); void _removeUnmatchedImplementations(std::vector &res_vec); void _consolidateAllocations(const ossie::ImplementationInfo::List& implementations, CF::Properties& allocs); @@ -257,16 +261,17 @@ class createHelper CF::LoadableDevice_ptr device, const std::vector& dependencies); - void loadAndExecuteComponents(CF::ApplicationRegistrar_ptr _appReg); - void applyApplicationAffinityOptions(); + void loadAndExecuteComponents(const DeploymentList& deployments, + CF::ApplicationRegistrar_ptr _appReg); + void applyApplicationAffinityOptions(const DeploymentList& deployments); void attemptComponentExecution(CF::ApplicationRegistrar_ptr registrar, ossie::ComponentDeployment* deployment); - void waitForComponentRegistration(); - void initializeComponents(); + void waitForComponentRegistration(const DeploymentList& deployments); + void initializeComponents(const DeploymentList& deployments); - void configureComponents(); - void connectComponents( + void configureComponents(const DeploymentList& deployments); + void connectComponents(ossie::ApplicationDeployment& appDeployment, std::vector& connections, std::string base_naming_context); From 6338f122463e7f17482ea95e2831c0b92c381b83 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 12 May 2016 11:31:06 -0400 Subject: [PATCH 0210/1644] Simpler reporting of failure to allocate a component, accounting for the fact that if there were no executable devices, the create call would have already failed up front; add a little extra safety when getting the device state just in case one is unreachable --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 27 ++++++++----------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 5a0ef0c68..859225dda 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -1671,24 +1671,19 @@ ossie::ComponentDeployment* createHelper::allocateComponent(ossie::ComponentInfo return deployment.release(); } - ossie::DeviceList::iterator device; - ossie::DeviceList devices = _registeredDevices; bool allBusy = true; - unsigned int num_exec_devices = 0; - for (device = devices.begin(); device != devices.end(); ++device) { - if ((*device)->isExecutable) { - num_exec_devices++; - if ((*device)->device->usageState() != CF::Device::BUSY) { - allBusy = false; - } + for (ossie::DeviceList::iterator dev = _executableDevices.begin(); dev != _executableDevices.end(); ++dev) { + CF::Device::UsageType state; + try { + state = (*dev)->device->usageState(); + } catch (...) { + LOG_WARN(ApplicationFactory_impl, "Device " << (*dev)->identifier << " is not reachable"); + continue; + } + if (state != CF::Device::BUSY) { + allBusy = false; + break; } - } - if (num_exec_devices == 0) { - // Report failure - std::ostringstream eout; - eout << "Unable to launch component '"<getName()<<"'. No executable devices (i.e.: GPP) are available in the Domain"; - LOG_DEBUG(ApplicationFactory_impl, eout.str()); - throw CF::ApplicationFactory::CreateApplicationError(CF::CF_ENOSPC, eout.str().c_str()); } if (allBusy) { // Report failure From 1f55ca9e856bfeebb2d30fd38b1d26cf66f70254 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 12 May 2016 11:41:15 -0400 Subject: [PATCH 0211/1644] Drop now-unneeded DeviceAssignmentInfo class --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 33 ++++++++----------- .../sdr/dommgr/ApplicationFactory_impl.h | 3 -- .../control/sdr/dommgr/Application_impl.cpp | 12 ++----- .../src/control/sdr/dommgr/Application_impl.h | 4 +-- .../src/control/sdr/dommgr/PersistenceStore.h | 8 +---- .../control/sdr/dommgr/applicationSupport.h | 11 ------- 6 files changed, 20 insertions(+), 51 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 859225dda..306ba6db2 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -956,11 +956,7 @@ void createHelper::_placeHostCollocation(ossie::ApplicationDeployment& appDeploy PlacementList::iterator comp = placingComponents.begin(); ossie::ImplementationInfo::List::iterator impl = res_vec[index].end()-1; - DeviceAssignmentList collocAssignedDevs; - collocAssignedDevs.resize(placingComponents.size()); - for (unsigned int i=0; idevice); - collocAssignedDevs[i].deviceAssignment.assignedDeviceId = CORBA::string_dup(deviceId.c_str()); + for (unsigned int i=0; isetAssignedDevice(node); if (!resolveSoftpkgDependencies(deployment, *node)) { @@ -969,7 +965,6 @@ void createHelper::_placeHostCollocation(ossie::ApplicationDeployment& appDeploy delete deployment; continue; } - collocAssignedDevs[i].deviceAssignment.componentId = (*comp)->getIdentifier().c_str(); appDeployment.addComponentDeployment(deployment); } @@ -1381,40 +1376,40 @@ throw (CORBA::SystemException, _allocations.transfer(allocationIDs); // Fill in the uses devices for the application - DeviceAssignmentList app_devices; + CF::DeviceAssignmentSequence app_devices; typedef std::vector UsesList; const UsesList& app_uses = app_deployment.getUsesDeviceAssignments(); for (UsesList::const_iterator uses = app_uses.begin(); uses != app_uses.end(); ++uses) { - DeviceAssignmentInfo assignment; - assignment.deviceAssignment.componentId = CORBA::string_dup(name); + CF::DeviceAssignmentType assignment; + assignment.componentId = CORBA::string_dup(name); std::string deviceId; try { deviceId = ossie::corba::returnString((*uses)->getAssignedDevice()->identifier()); } catch (...) { } - assignment.deviceAssignment.assignedDeviceId = deviceId.c_str(); - app_devices.push_back(assignment); + assignment.assignedDeviceId = deviceId.c_str(); + ossie::corba::push_back(app_devices, assignment); } const DeploymentList& deployments = app_deployment.getComponentDeployments(); for (DeploymentList::const_iterator dep = deployments.begin(); dep != deployments.end(); ++dep) { ossie::ComponentInfo* component = (*dep)->getComponent(); - DeviceAssignmentInfo comp_assignment; - comp_assignment.deviceAssignment.componentId = component->getIdentifier().c_str(); - comp_assignment.deviceAssignment.assignedDeviceId = (*dep)->getAssignedDevice()->identifier.c_str(); - app_devices.push_back(comp_assignment); + CF::DeviceAssignmentType comp_assignment; + comp_assignment.componentId = component->getIdentifier().c_str(); + comp_assignment.assignedDeviceId = (*dep)->getAssignedDevice()->identifier.c_str(); + ossie::corba::push_back(app_devices, comp_assignment); const UsesList& dep_uses = (*dep)->getUsesDeviceAssignments(); for (UsesList::const_iterator uses = dep_uses.begin(); uses != dep_uses.end(); ++uses) { - DeviceAssignmentInfo assignment; - assignment.deviceAssignment.componentId = component->getIdentifier().c_str(); + CF::DeviceAssignmentType assignment; + assignment.componentId = component->getIdentifier().c_str(); std::string deviceId; try { deviceId = ossie::corba::returnString((*uses)->getAssignedDevice()->identifier()); } catch (...) { } - assignment.deviceAssignment.assignedDeviceId = deviceId.c_str(); - app_devices.push_back(assignment); + assignment.assignedDeviceId = deviceId.c_str(); + ossie::corba::push_back(app_devices, assignment); } } diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h index 0d94a1353..b19f4d146 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h @@ -162,9 +162,6 @@ class createHelper private: - // List of used devices assignments - typedef std::vector< ossie::DeviceAssignmentInfo > DeviceAssignmentList; - // list of components that are part of a collocation typedef std::vector PlacementList; diff --git a/redhawk/src/control/sdr/dommgr/Application_impl.cpp b/redhawk/src/control/sdr/dommgr/Application_impl.cpp index 4dbe86bf9..2eaea6ee5 100644 --- a/redhawk/src/control/sdr/dommgr/Application_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/Application_impl.cpp @@ -135,14 +135,14 @@ Application_impl::Application_impl (const std::string& id, const std::string& na }; void Application_impl::populateApplication(CF::Resource_ptr _controller, - std::vector& _devSeq, + const CF::DeviceAssignmentSequence& assignedDevices, std::vector _startSeq, std::vector& connections, std::vector allocationIDs) { TRACE_ENTER(Application_impl) _connections = connections; - _componentDevices = _devSeq; + _componentDevices = assignedDevices; _appStartSeq = _startSeq; LOG_DEBUG(Application_impl, "Creating allocation sequence"); @@ -1151,13 +1151,7 @@ throw (CORBA::SystemException) CF::DeviceAssignmentSequence* Application_impl::componentDevices () throw (CORBA::SystemException) { - CF::DeviceAssignmentSequence_var result = new CF::DeviceAssignmentSequence(); - std::vector::const_iterator begin = _componentDevices.begin(); - const std::vector::const_iterator end = _componentDevices.end(); - for (; begin != end; ++begin) { - ossie::corba::push_back(result, begin->deviceAssignment); - } - return result._retn(); + return new CF::DeviceAssignmentSequence(_componentDevices); } diff --git a/redhawk/src/control/sdr/dommgr/Application_impl.h b/redhawk/src/control/sdr/dommgr/Application_impl.h index 3fcd4a9a0..8124bdb65 100644 --- a/redhawk/src/control/sdr/dommgr/Application_impl.h +++ b/redhawk/src/control/sdr/dommgr/Application_impl.h @@ -55,7 +55,7 @@ class Application_impl : public virtual POA_CF::Application, public Logging_impl CosNaming::NamingContext_ptr waveformContext, bool aware, CosNaming::NamingContext_ptr DomainContext); void populateApplication (CF::Resource_ptr _assemblyController, - std::vector& _devSequence, + const CF::DeviceAssignmentSequence& deviceAssignments, std::vector _startSeq, std::vector& connections, std::vector allocationIDs); @@ -179,7 +179,7 @@ class Application_impl : public virtual POA_CF::Application, public Logging_impl const std::string _identifier; const std::string _sadProfile; const std::string _appName; - std::vector _componentDevices; + CF::DeviceAssignmentSequence _componentDevices; std::vector _connections; std::vector _appStartSeq; std::vector _allocationIDs; diff --git a/redhawk/src/control/sdr/dommgr/PersistenceStore.h b/redhawk/src/control/sdr/dommgr/PersistenceStore.h index bc54d5fa8..9a7702660 100644 --- a/redhawk/src/control/sdr/dommgr/PersistenceStore.h +++ b/redhawk/src/control/sdr/dommgr/PersistenceStore.h @@ -99,7 +99,7 @@ namespace ossie { std::string identifier; std::string contextName; CosNaming::NamingContext_var context; - std::vector componentDevices; + CF::DeviceAssignmentSequence componentDevices; ossie::ComponentList components; CF::Resource_var assemblyController; std::vector connections; @@ -281,12 +281,6 @@ namespace boost { ar & (node.connected); } - template - void serialize(Archive& ar, ossie::DeviceAssignmentInfo& dai, const unsigned int version) { - ar & (dai.deviceAssignment); - ar & (dai.device); - } - template void serialize(Archive& ar, ossie::AllocationType& at, const unsigned int version) { ar & (at.allocationID); diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.h b/redhawk/src/control/sdr/dommgr/applicationSupport.h index d743803b6..ee66ce721 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.h +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.h @@ -290,17 +290,6 @@ namespace ossie }; - /* - * Class to store information for device assignment support - */ - class DeviceAssignmentInfo - { - - public: - CF::DeviceAssignmentType deviceAssignment; - CF::Device_var device; - }; - /* Base class to contain data for applications * - Used to store information about about: * -> ExternalPorts From 999c396b3cdb717c906be66fa075101a73a63585 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 12 May 2016 12:29:06 -0400 Subject: [PATCH 0212/1644] Reduce header file interdependence --- .../control/sdr/dommgr/AllocationManager_impl.cpp | 12 ++++++++---- .../src/control/sdr/dommgr/AllocationManager_impl.h | 6 ++---- .../control/sdr/dommgr/ApplicationFactory_impl.cpp | 2 +- .../src/control/sdr/dommgr/ApplicationFactory_impl.h | 8 ++------ .../src/control/sdr/dommgr/DomainManager_impl.cpp | 1 + redhawk/src/control/sdr/dommgr/applicationSupport.h | 6 ------ 6 files changed, 14 insertions(+), 21 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/AllocationManager_impl.cpp b/redhawk/src/control/sdr/dommgr/AllocationManager_impl.cpp index f7bb2ce11..d29d9646e 100644 --- a/redhawk/src/control/sdr/dommgr/AllocationManager_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/AllocationManager_impl.cpp @@ -23,12 +23,16 @@ #include #include +#include +#include +#include +#include +#include +#include + +#include "DomainManager_impl.h" #include "AllocationManager_impl.h" -#include "ossie/debug.h" -#include "ossie/CorbaUtils.h" -#include "ossie/ossieSupport.h" -#include "ossie/CorbaIterator.h" typedef ossie::corba::Iterator #include -#include -#include -#include -#include "DomainManager_impl.h" + +class DomainManager_impl; class AllocationManager_impl: public virtual POA_CF::AllocationManager { diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 306ba6db2..5aca07fe9 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -34,7 +34,7 @@ #include #include #include -#include +#include #include "Application_impl.h" #include "ApplicationFactory_impl.h" diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h index b19f4d146..099ed147e 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h @@ -21,20 +21,16 @@ #ifndef APPLICATIONFACTORY_H #define APPLICATIONFACTORY_H +#include #include -#include +#include #include -#include #include #include -#include -#include -#include #include "PersistenceStore.h" #include "applicationSupport.h" -#include "connectionSupport.h" #include "Placement.h" #include "Deployment.h" diff --git a/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp b/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp index ac85255f1..d188fcfab 100644 --- a/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp @@ -39,6 +39,7 @@ #include #include #include +#include #include "Application_impl.h" #include "ApplicationFactory_impl.h" diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.h b/redhawk/src/control/sdr/dommgr/applicationSupport.h index ee66ce721..7226d057e 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.h +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.h @@ -24,17 +24,13 @@ #include #include -#include #include -#include #include -#include #include #include #include #include -#include #include #include @@ -46,8 +42,6 @@ namespace ossie { - class DeviceNode; - struct ApplicationComponent { std::string identifier; std::string softwareProfile; From 2a1ace944116714182520f8e60bb6c8bcbfb6a4d Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 12 May 2016 12:32:15 -0400 Subject: [PATCH 0213/1644] Remove inaccurate comment --- redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 5aca07fe9..22f108b67 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -1328,9 +1328,6 @@ throw (CORBA::SystemException, //////////////////////////////////////////////// // Create the Application servant - - // Manage the Application servant with an auto_ptr in case - // something throws an exception. _application = new Application_impl(appIdentifier, name, _appFact._softwareProfile, From f4d9d659b9637f9edd1439ad6353bc7a7c1ec17a Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 12 May 2016 12:36:37 -0400 Subject: [PATCH 0214/1644] Remove redundant function --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 24 ++----------------- .../sdr/dommgr/ApplicationFactory_impl.h | 1 - 2 files changed, 2 insertions(+), 23 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 22f108b67..c85aae787 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -1949,7 +1949,7 @@ void createHelper::_castRequestProperties(CF::Properties& allocationProperties, { allocationProperties.length(offset+prop_refs.size()); for (unsigned int i=0; i(property) != NULL) { - const SimplePropertyRef* dependency = dynamic_cast(property); - return convertPropertyToDataType(&(*dependency)); - } else if (dynamic_cast(property) != NULL) { - const SimpleSequencePropertyRef* dependency = dynamic_cast(property); - return convertPropertyToDataType(dependency); - } else if (dynamic_cast(property) != NULL) { - const ossie::StructPropertyRef* dependency = dynamic_cast(property); - return convertPropertyToDataType(dependency); - } else if (dynamic_cast(property) != NULL) { - const ossie::StructSequencePropertyRef* dependency = dynamic_cast(property); - return convertPropertyToDataType(dependency); - } - CF::DataType dataType; - dataType.id = CORBA::string_dup(property->_id.c_str()); - return dataType; -} - bool createHelper::resolveSoftpkgDependencies(ossie::SoftpkgDeployment* deployment, ossie::DeviceNode& device) { const ossie::ImplementationInfo* implementation = deployment->getImplementation(); diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h index 099ed147e..040376357 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h @@ -224,7 +224,6 @@ class createHelper void _castRequestProperties(CF::Properties& allocationProperties, const std::vector &prop_refs, unsigned int offset=0); void _castRequestProperties(CF::Properties& allocationProperties, const std::vector &prop_refs, unsigned int offset=0); - CF::DataType castProperty(const ossie::ComponentProperty* property); // Populate _requiredComponents vector void getRequiredComponents(ossie::ApplicationPlacement& appPlacement); From 9076dce75c1d0b9ad4a093d107270656a154fd54 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 12 May 2016 12:48:19 -0400 Subject: [PATCH 0215/1644] Move createHelper to its own header to minimize header interdependence --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 1 + .../sdr/dommgr/ApplicationFactory_impl.h | 172 ---------------- redhawk/src/control/sdr/dommgr/createHelper.h | 192 ++++++++++++++++++ 3 files changed, 193 insertions(+), 172 deletions(-) create mode 100644 redhawk/src/control/sdr/dommgr/createHelper.h diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index c85aae787..c8a66d862 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -38,6 +38,7 @@ #include "Application_impl.h" #include "ApplicationFactory_impl.h" +#include "createHelper.h" #include "DomainManager_impl.h" #include "AllocationManager_impl.h" #include "RH_NamingContext.h" diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h index 040376357..36ef043cc 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h @@ -21,24 +21,13 @@ #ifndef APPLICATIONFACTORY_H #define APPLICATIONFACTORY_H -#include #include -#include #include #include #include -#include "PersistenceStore.h" -#include "applicationSupport.h" -#include "Placement.h" -#include "Deployment.h" - class DomainManager_impl; -class Application_impl; -class AllocationManager_impl; - -class createHelper; class ApplicationFactory_impl: public virtual POA_CF::ApplicationFactory { @@ -112,164 +101,3 @@ class ApplicationFactory_impl: public virtual POA_CF::ApplicationFactory friend class ScopedAllocations; }; #endif - -#ifndef CREATEHELPER_H -#define CREATEHELPER_H - -class ScopedAllocations { -public: - ScopedAllocations(AllocationManager_impl& allocator); - ~ScopedAllocations(); - - void push_back(const std::string& allocationID); - - template - void transfer(T& dest); - - void transfer(ScopedAllocations& dest); - - void deallocate(); - -private: - AllocationManager_impl& _allocator; - std::list _allocations; -}; - -class createHelper -{ - -public: - typedef std::map DeviceAssignmentMap; - - createHelper (const ApplicationFactory_impl& appFact, - std::string waveformContextName, - std::string base_naming_context, - CosNaming::NamingContext_ptr WaveformContext, - CosNaming::NamingContext_ptr DomainContext); - ~createHelper (); - - CF::Application_ptr create (const char* name, - const CF::Properties& initConfiguration, - const DeviceAssignmentMap& deviceAssignments) - throw (CF::ApplicationFactory::InvalidInitConfiguration, - CF::ApplicationFactory::CreateApplicationRequestError, - CF::ApplicationFactory::CreateApplicationError, - CORBA::SystemException); - -private: - - // list of components that are part of a collocation - typedef std::vector PlacementList; - - // Used for storing the current state of the OE & create process - const ApplicationFactory_impl& _appFact; - - // Local pointer to the allocation manager - AllocationManager_impl* _allocationMgr; - - // Tracks allocation IDs made during creation, and automates cleanup on - // failure - ScopedAllocations _allocations; - CF::Properties _app_affinity; - - ossie::DeviceList _registeredDevices; - ossie::DeviceList _executableDevices; - std::map specialized_reservations; - - std::vector _startSeq; - std::vector _startOrderIds; - - // waveform instance-specific naming context (unique to the instance of the waveform) - std::string _waveformContextName; - - // full (includes full context path) waveform instance-specific naming context - std::string _baseNamingContext; - - // CORBA naming context - CosNaming::NamingContext_var _waveformContext; - CosNaming::NamingContext_ptr _domainContext; - - ossie::ApplicationInfo _appInfo; - - typedef std::vector DeploymentList; - - // createHelper helper methods - void overrideExternalProperties(ossie::ApplicationPlacement& appPlacement, - const CF::Properties& initConfiguration); - void overrideProperties(const CF::Properties& initConfiguration, ossie::ComponentInfo* component); - void assignPlacementsToDevices(ossie::ApplicationPlacement& appPlacement, - ossie::ApplicationDeployment& appDeployment, - const std::string& appIdentifier, - const DeviceAssignmentMap& devices); - void _validateDAS(ossie::ApplicationPlacement& appPlacement, const DeviceAssignmentMap& deviceAssignments); - void _connectComponents(ossie::ApplicationDeployment& appDeployment, - std::vector& connections); - void _configureComponents(const DeploymentList& deployments); - void _checkAssemblyController( - CF::Resource_ptr assemblyController, - ossie::ComponentInfo* assemblyControllerComponent) const; - void setUpExternalPorts(ossie::ApplicationDeployment& appDeployment, Application_impl* application); - void setUpExternalProperties(ossie::ApplicationDeployment& appDeployment, Application_impl* application); - void _placeHostCollocation(ossie::ApplicationDeployment& appDeployment, - const std::string& appIdentifier, - const PlacementList& collocatedComponents, - const DeviceAssignmentMap& devices); - void _handleUsesDevices(ossie::ApplicationPlacement& appPlacement, - ossie::ApplicationDeployment& appDeployment, - const std::string& appName); - void _resolveImplementations(PlacementList::iterator comp, PlacementList& compList, std::vector &res_vec); - void _removeUnmatchedImplementations(std::vector &res_vec); - void _consolidateAllocations(const ossie::ImplementationInfo::List& implementations, CF::Properties& allocs); - void _evaluateMATHinRequest(CF::Properties &request, const CF::Properties &configureProperties); - void _castRequestProperties(CF::Properties& allocationProperties, const std::vector &prop_refs, unsigned int offset=0); - void _castRequestProperties(CF::Properties& allocationProperties, const std::vector &prop_refs, - unsigned int offset=0); - - // Populate _requiredComponents vector - void getRequiredComponents(ossie::ApplicationPlacement& appPlacement); - ossie::ComponentInfo* buildComponentInfo(const ossie::ComponentPlacement& component); - - // Supports allocation - bool allocateUsesDevices(const ossie::UsesDeviceInfo::List& usesDevices, - const CF::Properties& configureProperties, - std::vector& assignedDevices, - ScopedAllocations& allocations); - CF::AllocationManager::AllocationResponseSequence* allocateUsesDeviceProperties( - const ossie::UsesDeviceInfo::List& component, - const CF::Properties& configureProperties); - ossie::ComponentDeployment* allocateComponent(ossie::ComponentInfo* component, - const std::string& assignedDeviceId, - const std::string& appIdentifier); - - ossie::AllocationResult allocateComponentToDevice(ossie::ComponentDeployment* deployment, - const std::string& assignedDeviceId, - const std::string& appIdentifier); - - bool resolveSoftpkgDependencies(ossie::SoftpkgDeployment* deployment, ossie::DeviceNode& device); - ossie::SoftpkgDeployment* resolveDependencyImplementation(ossie::SoftpkgInfo* softpkg, ossie::DeviceNode& device); - - // Supports loading, executing, initializing, configuring, & connecting - void loadDependencies(const ossie::ComponentInfo& component, - CF::LoadableDevice_ptr device, - const std::vector& dependencies); - - void loadAndExecuteComponents(const DeploymentList& deployments, - CF::ApplicationRegistrar_ptr _appReg); - void applyApplicationAffinityOptions(const DeploymentList& deployments); - - void attemptComponentExecution(CF::ApplicationRegistrar_ptr registrar, ossie::ComponentDeployment* deployment); - - void waitForComponentRegistration(const DeploymentList& deployments); - void initializeComponents(const DeploymentList& deployments); - - void configureComponents(const DeploymentList& deployments); - void connectComponents(ossie::ApplicationDeployment& appDeployment, - std::vector& connections, - std::string base_naming_context); - - // Cleanup - used when create fails/doesn't succeed for some reason - bool _isComplete; - void _cleanupFailedCreate(); - Application_impl* _application; -}; -#endif diff --git a/redhawk/src/control/sdr/dommgr/createHelper.h b/redhawk/src/control/sdr/dommgr/createHelper.h new file mode 100644 index 000000000..a8d469dc5 --- /dev/null +++ b/redhawk/src/control/sdr/dommgr/createHelper.h @@ -0,0 +1,192 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK core. + * + * REDHAWK core is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +#ifndef CREATEHELPER_H +#define CREATEHELPER_H + +#include +#include +#include + +#include "PersistenceStore.h" +#include "applicationSupport.h" +#include "Placement.h" +#include "Deployment.h" + +class Application_impl; +class AllocationManager_impl; + +class ScopedAllocations { +public: + ScopedAllocations(AllocationManager_impl& allocator); + ~ScopedAllocations(); + + void push_back(const std::string& allocationID); + + template + void transfer(T& dest); + + void transfer(ScopedAllocations& dest); + + void deallocate(); + +private: + AllocationManager_impl& _allocator; + std::list _allocations; +}; + +class createHelper +{ + +public: + typedef std::map DeviceAssignmentMap; + + createHelper (const ApplicationFactory_impl& appFact, + std::string waveformContextName, + std::string base_naming_context, + CosNaming::NamingContext_ptr WaveformContext, + CosNaming::NamingContext_ptr DomainContext); + ~createHelper (); + + CF::Application_ptr create (const char* name, + const CF::Properties& initConfiguration, + const DeviceAssignmentMap& deviceAssignments) + throw (CF::ApplicationFactory::InvalidInitConfiguration, + CF::ApplicationFactory::CreateApplicationRequestError, + CF::ApplicationFactory::CreateApplicationError, + CORBA::SystemException); + +private: + + // list of components that are part of a collocation + typedef std::vector PlacementList; + + // Used for storing the current state of the OE & create process + const ApplicationFactory_impl& _appFact; + + // Local pointer to the allocation manager + AllocationManager_impl* _allocationMgr; + + // Tracks allocation IDs made during creation, and automates cleanup on + // failure + ScopedAllocations _allocations; + CF::Properties _app_affinity; + + ossie::DeviceList _registeredDevices; + ossie::DeviceList _executableDevices; + std::map specialized_reservations; + + std::vector _startSeq; + std::vector _startOrderIds; + + // waveform instance-specific naming context (unique to the instance of the waveform) + std::string _waveformContextName; + + // full (includes full context path) waveform instance-specific naming context + std::string _baseNamingContext; + + // CORBA naming context + CosNaming::NamingContext_var _waveformContext; + CosNaming::NamingContext_ptr _domainContext; + + ossie::ApplicationInfo _appInfo; + + typedef std::vector DeploymentList; + + // createHelper helper methods + void overrideExternalProperties(ossie::ApplicationPlacement& appPlacement, + const CF::Properties& initConfiguration); + void overrideProperties(const CF::Properties& initConfiguration, ossie::ComponentInfo* component); + void assignPlacementsToDevices(ossie::ApplicationPlacement& appPlacement, + ossie::ApplicationDeployment& appDeployment, + const std::string& appIdentifier, + const DeviceAssignmentMap& devices); + void _validateDAS(ossie::ApplicationPlacement& appPlacement, const DeviceAssignmentMap& deviceAssignments); + void _connectComponents(ossie::ApplicationDeployment& appDeployment, + std::vector& connections); + void _configureComponents(const DeploymentList& deployments); + void _checkAssemblyController( + CF::Resource_ptr assemblyController, + ossie::ComponentInfo* assemblyControllerComponent) const; + void setUpExternalPorts(ossie::ApplicationDeployment& appDeployment, Application_impl* application); + void setUpExternalProperties(ossie::ApplicationDeployment& appDeployment, Application_impl* application); + void _placeHostCollocation(ossie::ApplicationDeployment& appDeployment, + const std::string& appIdentifier, + const PlacementList& collocatedComponents, + const DeviceAssignmentMap& devices); + void _handleUsesDevices(ossie::ApplicationPlacement& appPlacement, + ossie::ApplicationDeployment& appDeployment, + const std::string& appName); + void _resolveImplementations(PlacementList::iterator comp, PlacementList& compList, std::vector &res_vec); + void _removeUnmatchedImplementations(std::vector &res_vec); + void _consolidateAllocations(const ossie::ImplementationInfo::List& implementations, CF::Properties& allocs); + void _evaluateMATHinRequest(CF::Properties &request, const CF::Properties &configureProperties); + void _castRequestProperties(CF::Properties& allocationProperties, const std::vector &prop_refs, unsigned int offset=0); + void _castRequestProperties(CF::Properties& allocationProperties, const std::vector &prop_refs, + unsigned int offset=0); + + // Populate _requiredComponents vector + void getRequiredComponents(ossie::ApplicationPlacement& appPlacement); + ossie::ComponentInfo* buildComponentInfo(const ossie::ComponentPlacement& component); + + // Supports allocation + bool allocateUsesDevices(const ossie::UsesDeviceInfo::List& usesDevices, + const CF::Properties& configureProperties, + std::vector& assignedDevices, + ScopedAllocations& allocations); + CF::AllocationManager::AllocationResponseSequence* allocateUsesDeviceProperties( + const ossie::UsesDeviceInfo::List& component, + const CF::Properties& configureProperties); + ossie::ComponentDeployment* allocateComponent(ossie::ComponentInfo* component, + const std::string& assignedDeviceId, + const std::string& appIdentifier); + + ossie::AllocationResult allocateComponentToDevice(ossie::ComponentDeployment* deployment, + const std::string& assignedDeviceId, + const std::string& appIdentifier); + + bool resolveSoftpkgDependencies(ossie::SoftpkgDeployment* deployment, ossie::DeviceNode& device); + ossie::SoftpkgDeployment* resolveDependencyImplementation(ossie::SoftpkgInfo* softpkg, ossie::DeviceNode& device); + + // Supports loading, executing, initializing, configuring, & connecting + void loadDependencies(const ossie::ComponentInfo& component, + CF::LoadableDevice_ptr device, + const std::vector& dependencies); + + void loadAndExecuteComponents(const DeploymentList& deployments, + CF::ApplicationRegistrar_ptr _appReg); + void applyApplicationAffinityOptions(const DeploymentList& deployments); + + void attemptComponentExecution(CF::ApplicationRegistrar_ptr registrar, ossie::ComponentDeployment* deployment); + + void waitForComponentRegistration(const DeploymentList& deployments); + void initializeComponents(const DeploymentList& deployments); + + void configureComponents(const DeploymentList& deployments); + void connectComponents(ossie::ApplicationDeployment& appDeployment, + std::vector& connections, + std::string base_naming_context); + + // Cleanup - used when create fails/doesn't succeed for some reason + bool _isComplete; + void _cleanupFailedCreate(); + Application_impl* _application; +}; +#endif From 8610d474b2c41f9efa8d4b855f90c99bd5071866 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 12 May 2016 13:26:46 -0400 Subject: [PATCH 0216/1644] Build the start order when needed, instead of keeping a member --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 87 ++++++++----------- redhawk/src/control/sdr/dommgr/createHelper.h | 5 +- 2 files changed, 39 insertions(+), 53 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index c8a66d862..574a19e40 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -1411,10 +1411,11 @@ throw (CORBA::SystemException, } } + std::vector start_order = getStartOrder(app_deployment.getComponentDeployments()); _application->populateApplication( assemblyController, app_devices, - _startSeq, + start_order, connections, allocationIDs); @@ -2093,7 +2094,7 @@ void createHelper::getRequiredComponents(ossie::ApplicationPlacement& appPlaceme { TRACE_ENTER(ApplicationFactory_impl); - PlacementList components; + const std::string assemblyControllerRefId = _appFact._sadParser.getAssemblyControllerRefId(); // Walk through the host collocations first const std::vector& collocations = _appFact._sadParser.getHostCollocations(); @@ -2107,8 +2108,10 @@ void createHelper::getRequiredComponents(ossie::ApplicationPlacement& appPlaceme const std::vector& placements = collocations[index].getComponents(); for (unsigned int i = 0; i < placements.size(); i++) { ossie::ComponentInfo* component = buildComponentInfo(placements[i]); + if (component->getInstantiationIdentifier() == assemblyControllerRefId) { + component->setIsAssemblyController(true); + } plan->addComponent(component); - components.push_back(component); } } @@ -2118,32 +2121,10 @@ void createHelper::getRequiredComponents(ossie::ApplicationPlacement& appPlaceme ossie::PlacementPlan* plan = new ossie::PlacementPlan(); appPlacement.addPlacement(plan); ossie::ComponentInfo* component = buildComponentInfo(componentsFromSAD[i]); - plan->addComponent(component); - components.push_back(component); - } - - // Now that all of the components are know, bin the start orders based on - // the values in the SAD. Using a multimap, keyed on the start order value, - // accounts for duplicate keys and allows assigning the effective order - // easily by iterating through all entries. - const std::string assemblyControllerRefId = _appFact._sadParser.getAssemblyControllerRefId(); - std::multimap start_orders; - for (size_t index = 0; index < components.size(); ++index) { - ossie::ComponentInfo* component = components[index]; if (component->getInstantiationIdentifier() == assemblyControllerRefId) { - // Mark the assembly controller while we're at it component->setIsAssemblyController(true); - } else if (component->hasStartOrder()) { - // Only track start order if it was provided, and the component is - // not the assembly controller - start_orders.insert(std::make_pair(component->getStartOrder(), component->getInstantiationIdentifier())); } - } - - // Build the start order instantiation ID vector in the right order - _startOrderIds.clear(); - for (std::multimap::iterator ii = start_orders.begin(); ii != start_orders.end(); ++ii) { - _startOrderIds.push_back(ii->second); + plan->addComponent(component); } TRACE_EXIT(ApplicationFactory_impl); @@ -2670,11 +2651,8 @@ void createHelper::waitForComponentRegistration(const DeploymentList& deployment void createHelper::initializeComponents(const DeploymentList& deployments) { // Install the different components in the system - LOG_TRACE(ApplicationFactory_impl, "initializing " << deployments.size() << " waveform components") + LOG_TRACE(ApplicationFactory_impl, "initializing " << deployments.size() << " waveform components"); - // Resize the _startSeq vector to the right size - _startSeq.resize(_startOrderIds.size()); - CF::Components_var app_registeredComponents = _application->registeredComponents(); for (unsigned int rc_idx = 0; rc_idx < deployments.size (); rc_idx++) { @@ -2812,26 +2790,6 @@ void createHelper::initializeComponents(const DeploymentList& deployments) LOG_ERROR(ApplicationFactory_impl, eout.str()); throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EIO, eout.str().c_str()); } - - if (!component->isAssemblyController()) { - // Try and find the right location in the vector to add the reference - unsigned int pos = 0; - for (unsigned int i = 0; i < _startOrderIds.size(); i++) { - std::string currID = _startOrderIds[i]; - currID = currID.append(":"); - currID = currID.append(_waveformContextName); - - if (componentId == currID) { - break; - } - pos++; - } - - // Add the reference if it belongs in the list - if (pos < _startOrderIds.size()) { - _startSeq[pos] = CF::Resource::_duplicate(resource); - } - } } } @@ -2983,6 +2941,35 @@ void createHelper::connectComponents(ossie::ApplicationDeployment& appDeployment std::copy(establishedConnections.begin(), establishedConnections.end(), std::back_inserter(connections)); } +std::vector createHelper::getStartOrder(const DeploymentList& deployments) +{ + // Now that all of the components are known, bin the start orders based on + // the values in the SAD. Using a multimap, keyed on the start order value, + // accounts for duplicate keys and allows assigning the effective order + // easily by iterating through all entries. + typedef std::multimap StartOrderMap; + StartOrderMap start_map; + for (size_t index = 0; index < deployments.size(); ++index) { + ossie::ComponentInfo* component = deployments[index]->getComponent(); + if (!component->isAssemblyController() && component->hasStartOrder()) { + // Only track start order if it was provided, and the component is + // not the assembly controller + start_map.insert(std::make_pair(component->getStartOrder(), deployments[index])); + } + } + + // Build the start order vector in the right order + std::vector start_order; + int index = 1; + LOG_TRACE(ApplicationFactory_impl, "Assigning start order"); + for (StartOrderMap::iterator ii = start_map.begin(); ii != start_map.end(); ++ii, ++index) { + LOG_TRACE(ApplicationFactory_impl, index << ": " + << ii->second->getComponent()->getInstantiationIdentifier()); + start_order.push_back(ii->second->getResourcePtr()); + } + return start_order; +} + createHelper::createHelper ( const ApplicationFactory_impl& appFact, string waveformContextName, diff --git a/redhawk/src/control/sdr/dommgr/createHelper.h b/redhawk/src/control/sdr/dommgr/createHelper.h index a8d469dc5..5ee8abde7 100644 --- a/redhawk/src/control/sdr/dommgr/createHelper.h +++ b/redhawk/src/control/sdr/dommgr/createHelper.h @@ -93,9 +93,6 @@ class createHelper ossie::DeviceList _executableDevices; std::map specialized_reservations; - std::vector _startSeq; - std::vector _startOrderIds; - // waveform instance-specific naming context (unique to the instance of the waveform) std::string _waveformContextName; @@ -184,6 +181,8 @@ class createHelper std::vector& connections, std::string base_naming_context); + std::vector getStartOrder(const DeploymentList& deployments); + // Cleanup - used when create fails/doesn't succeed for some reason bool _isComplete; void _cleanupFailedCreate(); From d71be646cbcda1e851c5ab599c9daf49bd1827a6 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 12 May 2016 13:32:15 -0400 Subject: [PATCH 0217/1644] Prefer initialization; remove throws clause on helper --- .../control/sdr/dommgr/ApplicationFactory_impl.cpp | 12 ++++-------- redhawk/src/control/sdr/dommgr/createHelper.h | 6 +----- 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 574a19e40..334b94a22 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -1210,10 +1210,6 @@ CF::Application_ptr createHelper::create ( const char* name, const CF::Properties& initConfiguration, const DeviceAssignmentMap& deviceAssignments) -throw (CORBA::SystemException, - CF::ApplicationFactory::CreateApplicationError, - CF::ApplicationFactory::CreateApplicationRequestError, - CF::ApplicationFactory::InvalidInitConfiguration) { TRACE_ENTER(ApplicationFactory_impl); @@ -2980,13 +2976,13 @@ createHelper::createHelper ( _appFact(appFact), _allocationMgr(_appFact._domainManager->_allocationMgr), _allocations(*_allocationMgr), + _waveformContextName(waveformContextName), + _baseNamingContext(baseNamingContext), + _waveformContext(CosNaming::NamingContext::_duplicate(waveformContext)), + _domainContext(domainContext), _isComplete(false), _application(0) { - this->_waveformContextName = waveformContextName; - this->_baseNamingContext = baseNamingContext; - this->_waveformContext = CosNaming::NamingContext::_duplicate(waveformContext); - this->_domainContext = domainContext; } createHelper::~createHelper() diff --git a/redhawk/src/control/sdr/dommgr/createHelper.h b/redhawk/src/control/sdr/dommgr/createHelper.h index 5ee8abde7..2dba66cc5 100644 --- a/redhawk/src/control/sdr/dommgr/createHelper.h +++ b/redhawk/src/control/sdr/dommgr/createHelper.h @@ -67,11 +67,7 @@ class createHelper CF::Application_ptr create (const char* name, const CF::Properties& initConfiguration, - const DeviceAssignmentMap& deviceAssignments) - throw (CF::ApplicationFactory::InvalidInitConfiguration, - CF::ApplicationFactory::CreateApplicationRequestError, - CF::ApplicationFactory::CreateApplicationError, - CORBA::SystemException); + const DeviceAssignmentMap& deviceAssignments); private: From 8a2ba2555cbdc842a564ce32997b9f6a7e295f48 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 12 May 2016 13:37:20 -0400 Subject: [PATCH 0218/1644] Move big, outer try/catch from createHelper::create to ApplicationFactory_impl::create --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 409 +++++++++--------- 1 file changed, 204 insertions(+), 205 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 334b94a22..eee712c32 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -1200,7 +1200,30 @@ throw (CORBA::SystemException, CF::ApplicationFactory::CreateApplicationError, // now actually perform the create operation LOG_TRACE(ApplicationFactory_impl, "Performing 'create' function."); - CF::Application_ptr new_app = new_createhelper.create(name, initConfiguration, deviceAssignmentMap); + CF::Application_ptr new_app; + try { + new_app = new_createhelper.create(name, initConfiguration, deviceAssignmentMap); + } catch (CF::ApplicationFactory::CreateApplicationError& ex) { + LOG_ERROR(ApplicationFactory_impl, "Error in application creation; " << ex.msg); + throw; + } catch (CF::ApplicationFactory::CreateApplicationRequestError& ex) { + LOG_ERROR(ApplicationFactory_impl, "Error in application creation") + throw; + } catch (const std::exception& ex) { + std::ostringstream eout; + eout << "The following standard exception occurred: "<>= aware_application; - modifiedInitConfiguration.length(initConfiguration.length()-1); - for (unsigned int rem_idx=0; rem_idx>= aware_application; + modifiedInitConfiguration.length(initConfiguration.length()-1); + for (unsigned int rem_idx=0; rem_idx>= reservations) { - for (unsigned int rem_idx=0; rem_idxlength(); rem_idx++) { - double value = 0; - std::string component_id((*reservations)[rem_idx].id); - if ((*reservations)[rem_idx].value >>= value) { - specialized_reservations[component_id] = value; - } + } + + if (modifiedInitConfiguration.length() == 0) { + modifiedInitConfiguration = initConfiguration; + } + + const std::string specialized_reservation("SPECIALIZED_CPU_RESERVATION"); + for (unsigned int initCount = 0; initCount < modifiedInitConfiguration.length(); initCount++) { + if (std::string(modifiedInitConfiguration[initCount].id) == specialized_reservation) { + CF::Properties *reservations; + if (modifiedInitConfiguration[initCount].value >>= reservations) { + for (unsigned int rem_idx=0; rem_idxlength(); rem_idx++) { + double value = 0; + std::string component_id((*reservations)[rem_idx].id); + if ((*reservations)[rem_idx].value >>= value) { + specialized_reservations[component_id] = value; } - } else { - // the value of the any is of the wrong type - } - for (unsigned int rem_idx=initCount; rem_idxgetRegisteredDevices(); - _executableDevices.clear(); - for (DeviceList::iterator iter = _registeredDevices.begin(); iter != _registeredDevices.end(); ++iter) { - if ((*iter)->isExecutable) { - _executableDevices.push_back(*iter); + for (unsigned int rem_idx=initCount; rem_idxgetRegisteredDevices(); + _executableDevices.clear(); + for (DeviceList::iterator iter = _registeredDevices.begin(); iter != _registeredDevices.end(); ++iter) { + if ((*iter)->isExecutable) { + _executableDevices.push_back(*iter); } + } - const std::string lastExecutableDevice = _appFact._domainManager->getLastDeviceUsedForDeployment(); - if (!lastExecutableDevice.empty()) { - LOG_TRACE(ApplicationFactory_impl, "Placing device " << lastExecutableDevice - << " first in deployment list"); - rotateDeviceList(_executableDevices, lastExecutableDevice); - } + // Fail immediately if there are no available devices to execute components + if (_executableDevices.empty()) { + const char* message = "Domain has no executable devices (GPPs) to run components"; + LOG_WARN(ApplicationFactory_impl, message); + throw CF::ApplicationFactory::CreateApplicationError(CF::CF_ENODEV, message); + } - ////////////////////////////////////////////////// - // Load the components to instantiate from the SAD - ossie::ApplicationPlacement placement; - getRequiredComponents(placement); + const std::string lastExecutableDevice = _appFact._domainManager->getLastDeviceUsedForDeployment(); + if (!lastExecutableDevice.empty()) { + LOG_TRACE(ApplicationFactory_impl, "Placing device " << lastExecutableDevice + << " first in deployment list"); + rotateDeviceList(_executableDevices, lastExecutableDevice); + } - ossie::ComponentInfo* assemblyControllerComponent = placement.getAssemblyController(); - if (assemblyControllerComponent) { - overrideProperties(modifiedInitConfiguration, assemblyControllerComponent); - } + ////////////////////////////////////////////////// + // Load the components to instantiate from the SAD + ossie::ApplicationPlacement placement; + getRequiredComponents(placement); - ////////////////////////////////////////////////// - // Store information about this application - _appInfo.populateApplicationInfo(_appFact._sadParser); + ossie::ComponentInfo* assemblyControllerComponent = placement.getAssemblyController(); + if (assemblyControllerComponent) { + overrideProperties(modifiedInitConfiguration, assemblyControllerComponent); + } - overrideExternalProperties(placement, modifiedInitConfiguration); + ////////////////////////////////////////////////// + // Store information about this application + _appInfo.populateApplicationInfo(_appFact._sadParser); - //////////////////////////////////////////////// - // Assign components to devices - //////////////////////////////////////////////// - ossie::ApplicationDeployment app_deployment; + overrideExternalProperties(placement, modifiedInitConfiguration); - // Allocate any usesdevice capacities specified in the SAD file - _handleUsesDevices(placement, app_deployment, name); + //////////////////////////////////////////////// + // Assign components to devices + //////////////////////////////////////////////// + ossie::ApplicationDeployment app_deployment; - // Give the application a unique identifier of the form - // "softwareassemblyid:ApplicationName", where the application - // name includes the serial number generated for the naming context - // (e.g. "Application_1"). - std::string appIdentifier = - _appFact._identifier + ":" + _waveformContextName; + // Allocate any usesdevice capacities specified in the SAD file + _handleUsesDevices(placement, app_deployment, name); - // Catch invalid device assignments - _validateDAS(placement, deviceAssignments); + // Give the application a unique identifier of the form + // "softwareassemblyid:ApplicationName", where the application + // name includes the serial number generated for the naming context + // (e.g. "Application_1"). + std::string appIdentifier = + _appFact._identifier + ":" + _waveformContextName; - // Assign all components to devices - assignPlacementsToDevices(placement, app_deployment, appIdentifier, deviceAssignments); + // Catch invalid device assignments + _validateDAS(placement, deviceAssignments); - //////////////////////////////////////////////// - // Create the Application servant - _application = new Application_impl(appIdentifier, - name, - _appFact._softwareProfile, - _appFact._domainManager, - _waveformContextName, - _waveformContext, - aware_application, - _domainContext); + // Assign all components to devices + assignPlacementsToDevices(placement, app_deployment, appIdentifier, deviceAssignments); - // Activate the new Application servant - PortableServer::ObjectId_var oid = Application_impl::Activate(_application); + //////////////////////////////////////////////// + // Create the Application servant + _application = new Application_impl(appIdentifier, + name, + _appFact._softwareProfile, + _appFact._domainManager, + _waveformContextName, + _waveformContext, + aware_application, + _domainContext); - std::vector connections; - std::vector allocationIDs; + // Activate the new Application servant + PortableServer::ObjectId_var oid = Application_impl::Activate(_application); - CF::ApplicationRegistrar_var app_reg = _application->appReg(); - loadAndExecuteComponents(app_deployment.getComponentDeployments(), app_reg); - waitForComponentRegistration(app_deployment.getComponentDeployments()); - initializeComponents(app_deployment.getComponentDeployments()); + std::vector connections; + std::vector allocationIDs; - // Check that the assembly controller is valid - CF::Resource_var assemblyController; - if (assemblyControllerComponent) { - const std::string& assemblyControllerId = assemblyControllerComponent->getInstantiationIdentifier(); - ossie::ComponentDeployment* deployment = app_deployment.getComponentDeployment(assemblyControllerId); - assemblyController = deployment->getResourcePtr(); - } - _checkAssemblyController(assemblyController, assemblyControllerComponent); + CF::ApplicationRegistrar_var app_reg = _application->appReg(); + loadAndExecuteComponents(app_deployment.getComponentDeployments(), app_reg); + waitForComponentRegistration(app_deployment.getComponentDeployments()); + initializeComponents(app_deployment.getComponentDeployments()); - _connectComponents(app_deployment, connections); - _configureComponents(app_deployment.getComponentDeployments()); + // Check that the assembly controller is valid + CF::Resource_var assemblyController; + if (assemblyControllerComponent) { + const std::string& assemblyControllerId = assemblyControllerComponent->getInstantiationIdentifier(); + ossie::ComponentDeployment* deployment = app_deployment.getComponentDeployment(assemblyControllerId); + assemblyController = deployment->getResourcePtr(); + } + _checkAssemblyController(assemblyController, assemblyControllerComponent); - setUpExternalPorts(app_deployment, _application); - setUpExternalProperties(app_deployment, _application); + _connectComponents(app_deployment, connections); + _configureComponents(app_deployment.getComponentDeployments()); - //////////////////////////////////////////////// - // Create the application - // - // We are assuming that all components and their resources are - // collocated. This means that we assume the SAD - // element contains the element. NB: Ownership - // of the ConnectionManager is passed to the application. - _allocations.transfer(allocationIDs); - - // Fill in the uses devices for the application - CF::DeviceAssignmentSequence app_devices; - typedef std::vector UsesList; - const UsesList& app_uses = app_deployment.getUsesDeviceAssignments(); - for (UsesList::const_iterator uses = app_uses.begin(); uses != app_uses.end(); ++uses) { + setUpExternalPorts(app_deployment, _application); + setUpExternalProperties(app_deployment, _application); + + //////////////////////////////////////////////// + // Create the application + // + // We are assuming that all components and their resources are + // collocated. This means that we assume the SAD + // element contains the element. NB: Ownership + // of the ConnectionManager is passed to the application. + _allocations.transfer(allocationIDs); + + // Fill in the uses devices for the application + CF::DeviceAssignmentSequence app_devices; + typedef std::vector UsesList; + const UsesList& app_uses = app_deployment.getUsesDeviceAssignments(); + for (UsesList::const_iterator uses = app_uses.begin(); uses != app_uses.end(); ++uses) { + CF::DeviceAssignmentType assignment; + assignment.componentId = CORBA::string_dup(name); + std::string deviceId; + try { + deviceId = ossie::corba::returnString((*uses)->getAssignedDevice()->identifier()); + } catch (...) { + } + assignment.assignedDeviceId = deviceId.c_str(); + ossie::corba::push_back(app_devices, assignment); + } + + const DeploymentList& deployments = app_deployment.getComponentDeployments(); + for (DeploymentList::const_iterator dep = deployments.begin(); dep != deployments.end(); ++dep) { + ossie::ComponentInfo* component = (*dep)->getComponent(); + CF::DeviceAssignmentType comp_assignment; + comp_assignment.componentId = component->getIdentifier().c_str(); + comp_assignment.assignedDeviceId = (*dep)->getAssignedDevice()->identifier.c_str(); + ossie::corba::push_back(app_devices, comp_assignment); + + const UsesList& dep_uses = (*dep)->getUsesDeviceAssignments(); + for (UsesList::const_iterator uses = dep_uses.begin(); uses != dep_uses.end(); ++uses) { CF::DeviceAssignmentType assignment; - assignment.componentId = CORBA::string_dup(name); + assignment.componentId = component->getIdentifier().c_str(); std::string deviceId; try { deviceId = ossie::corba::returnString((*uses)->getAssignedDevice()->identifier()); @@ -1384,85 +1425,43 @@ CF::Application_ptr createHelper::create ( assignment.assignedDeviceId = deviceId.c_str(); ossie::corba::push_back(app_devices, assignment); } + } - const DeploymentList& deployments = app_deployment.getComponentDeployments(); - for (DeploymentList::const_iterator dep = deployments.begin(); dep != deployments.end(); ++dep) { - ossie::ComponentInfo* component = (*dep)->getComponent(); - CF::DeviceAssignmentType comp_assignment; - comp_assignment.componentId = component->getIdentifier().c_str(); - comp_assignment.assignedDeviceId = (*dep)->getAssignedDevice()->identifier.c_str(); - ossie::corba::push_back(app_devices, comp_assignment); - - const UsesList& dep_uses = (*dep)->getUsesDeviceAssignments(); - for (UsesList::const_iterator uses = dep_uses.begin(); uses != dep_uses.end(); ++uses) { - CF::DeviceAssignmentType assignment; - assignment.componentId = component->getIdentifier().c_str(); - std::string deviceId; - try { - deviceId = ossie::corba::returnString((*uses)->getAssignedDevice()->identifier()); - } catch (...) { - } - assignment.assignedDeviceId = deviceId.c_str(); - ossie::corba::push_back(app_devices, assignment); - } - } - - std::vector start_order = getStartOrder(app_deployment.getComponentDeployments()); - _application->populateApplication( - assemblyController, - app_devices, - start_order, - connections, - allocationIDs); - - // Add a reference to the new application to the - // ApplicationSequence in DomainManager - CF::Application_var appObj = _application->_this(); - try { - _appFact._domainManager->addApplication(_application); - } catch (CF::DomainManager::ApplicationInstallationError& ex) { - // something bad happened - clean up - LOG_ERROR(ApplicationFactory_impl, ex.msg); - throw CF::ApplicationFactory::CreateApplicationError(ex.errorNumber, ex.msg); - } + std::vector start_order = getStartOrder(app_deployment.getComponentDeployments()); + _application->populateApplication( + assemblyController, + app_devices, + start_order, + connections, + allocationIDs); - // After all components have been deployed, we know that the first - // executable device in the list was used for the last deployment, - // so update the domain manager - _appFact._domainManager->setLastDeviceUsedForDeployment(_executableDevices.front()->identifier); + // Add a reference to the new application to the + // ApplicationSequence in DomainManager + CF::Application_var appObj = _application->_this(); + try { + _appFact._domainManager->addApplication(_application); + } catch (CF::DomainManager::ApplicationInstallationError& ex) { + // something bad happened - clean up + LOG_ERROR(ApplicationFactory_impl, ex.msg); + throw CF::ApplicationFactory::CreateApplicationError(ex.errorNumber, ex.msg); + } - if ( _appFact._domainManager ) { - _appFact._domainManager->sendAddEvent( _appFact._identifier.c_str(), - appIdentifier.c_str(), - name, - appObj, - StandardEvent::APPLICATION); - } + // After all components have been deployed, we know that the first + // executable device in the list was used for the last deployment, + // so update the domain manager + _appFact._domainManager->setLastDeviceUsedForDeployment(_executableDevices.front()->identifier); - LOG_INFO(ApplicationFactory_impl, "Done creating application " << appIdentifier << " " << name); - _isComplete = true; - return appObj._retn(); - } catch (CF::ApplicationFactory::CreateApplicationError& ex) { - LOG_ERROR(ApplicationFactory_impl, "Error in application creation; " << ex.msg); - throw; - } catch (CF::ApplicationFactory::CreateApplicationRequestError& ex) { - LOG_ERROR(ApplicationFactory_impl, "Error in application creation") - throw; - } catch ( std::exception& ex ) { - ostringstream eout; - eout << "The following standard exception occurred: "<sendAddEvent( _appFact._identifier.c_str(), + appIdentifier.c_str(), + name, + appObj, + StandardEvent::APPLICATION); } + LOG_INFO(ApplicationFactory_impl, "Done creating application " << appIdentifier << " " << name); + _isComplete = true; + return appObj._retn(); } void createHelper::overrideExternalProperties(ossie::ApplicationPlacement& appPlacement, From aee35a9ae2dda1711a4e72a0efb7ef732a407b70 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 12 May 2016 13:54:26 -0400 Subject: [PATCH 0219/1644] Move specialized CPU reservation tracking into the deployment class, removing the createHelper member --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 23 +++++++++++++------ redhawk/src/control/sdr/dommgr/Deployment.cpp | 15 ++++++++++++ redhawk/src/control/sdr/dommgr/Deployment.h | 5 ++++ redhawk/src/control/sdr/dommgr/createHelper.h | 1 - 4 files changed, 36 insertions(+), 8 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index eee712c32..6932f5f55 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -1262,6 +1262,7 @@ CF::Application_ptr createHelper::create ( } const std::string specialized_reservation("SPECIALIZED_CPU_RESERVATION"); + std::map specialized_reservations; for (unsigned int initCount = 0; initCount < modifiedInitConfiguration.length(); initCount++) { if (std::string(modifiedInitConfiguration[initCount].id) == specialized_reservation) { CF::Properties *reservations; @@ -1343,6 +1344,19 @@ CF::Application_ptr createHelper::create ( // Assign all components to devices assignPlacementsToDevices(placement, app_deployment, appIdentifier, deviceAssignments); + // Assign CPU reservations to components + const DeploymentList& deployments = app_deployment.getComponentDeployments(); + for (DeploymentList::const_iterator dep = deployments.begin(); dep != deployments.end(); ++dep) { + ossie::ComponentInfo* component = (*dep)->getComponent(); + std::map::iterator reservation = specialized_reservations.find(component->getIdentifier()); + if (reservation == specialized_reservations.end()) { + reservation = specialized_reservations.find(component->getUsageName()); + } + if (reservation != specialized_reservations.end()) { + (*dep)->setCpuReservation(reservation->second); + } + } + //////////////////////////////////////////////// // Create the Application servant _application = new Application_impl(appIdentifier, @@ -1405,7 +1419,6 @@ CF::Application_ptr createHelper::create ( ossie::corba::push_back(app_devices, assignment); } - const DeploymentList& deployments = app_deployment.getComponentDeployments(); for (DeploymentList::const_iterator dep = deployments.begin(); dep != deployments.end(); ++dep) { ossie::ComponentInfo* component = (*dep)->getComponent(); CF::DeviceAssignmentType comp_assignment; @@ -2424,12 +2437,8 @@ void createHelper::attemptComponentExecution (CF::ApplicationRegistrar_ptr regis } // Add specialized CPU reservation if given - std::map::iterator reservation = specialized_reservations.find(component->getIdentifier()); - if (reservation == specialized_reservations.end()) { - reservation = specialized_reservations.find(component->getUsageName()); - } - if (reservation != specialized_reservations.end()) { - execParameters["RH::GPP::MODIFIED_CPU_RESERVATION_VALUE"] = reservation->second; + if (deployment->hasCpuReservation()) { + execParameters["RH::GPP::MODIFIED_CPU_RESERVATION_VALUE"] = deployment->getCpuReservation(); } // Add the required parameters specified in SR:163 diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index 09cdb6e2f..19350bf76 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -213,6 +213,21 @@ const std::string& ComponentDeployment::getNicAssignment() const return nicAssignment; } +void ComponentDeployment::setCpuReservation(float reservation) +{ + cpuReservation = reservation; +} + +bool ComponentDeployment::hasCpuReservation() const +{ + return cpuReservation.isSet(); +} + +float ComponentDeployment::getCpuReservation() const +{ + return *cpuReservation; +} + redhawk::PropertyMap ComponentDeployment::getAffinityOptionsWithAssignment() const { redhawk::PropertyMap options = affinityOptions; diff --git a/redhawk/src/control/sdr/dommgr/Deployment.h b/redhawk/src/control/sdr/dommgr/Deployment.h index d83d8dff9..57c01391c 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.h +++ b/redhawk/src/control/sdr/dommgr/Deployment.h @@ -101,6 +101,10 @@ namespace ossie { void setNicAssignment(const std::string& nic); const std::string& getNicAssignment() const; + void setCpuReservation(float reservation); + bool hasCpuReservation() const; + float getCpuReservation() const; + void setAssignedDevice(const boost::shared_ptr& device); boost::shared_ptr getAssignedDevice(); @@ -115,6 +119,7 @@ namespace ossie { CF::Resource_var resource; std::string nicAssignment; + ossie::optional_value cpuReservation; redhawk::PropertyMap affinityOptions; }; diff --git a/redhawk/src/control/sdr/dommgr/createHelper.h b/redhawk/src/control/sdr/dommgr/createHelper.h index 2dba66cc5..99b310247 100644 --- a/redhawk/src/control/sdr/dommgr/createHelper.h +++ b/redhawk/src/control/sdr/dommgr/createHelper.h @@ -87,7 +87,6 @@ class createHelper ossie::DeviceList _registeredDevices; ossie::DeviceList _executableDevices; - std::map specialized_reservations; // waveform instance-specific naming context (unique to the instance of the waveform) std::string _waveformContextName; From 91490d519701965b1d6e036562ce2131771b7e77 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 12 May 2016 14:14:47 -0400 Subject: [PATCH 0220/1644] Pass file manager and SAD as arguments to functions that build the profile, so that there is no dependence on local state inside them --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 25 +++++++++++-------- redhawk/src/control/sdr/dommgr/createHelper.h | 8 ++++-- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 6932f5f55..05a4f0ec7 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -1310,7 +1310,7 @@ CF::Application_ptr createHelper::create ( ////////////////////////////////////////////////// // Load the components to instantiate from the SAD ossie::ApplicationPlacement placement; - getRequiredComponents(placement); + getRequiredComponents(_appFact._fileMgr, _appFact._sadParser, placement); ossie::ComponentInfo* assemblyControllerComponent = placement.getAssemblyController(); if (assemblyControllerComponent) { @@ -2014,19 +2014,21 @@ ossie::SoftpkgDeployment* createHelper::resolveDependencyImplementation(ossie::S return 0; } -ossie::ComponentInfo* createHelper::buildComponentInfo(const ComponentPlacement& component) +ossie::ComponentInfo* createHelper::buildComponentInfo(CF::FileManager_ptr fileMgr, + const SoftwareAssembly& sadParser, + const ComponentPlacement& component) { // Extract required data from SPD file ossie::ComponentInfo* newComponent = 0; LOG_TRACE(ApplicationFactory_impl, "Getting the SPD Filename"); - const char *spdFileName = _appFact._sadParser.getSPDById(component.getFileRefId()); + const char *spdFileName = sadParser.getSPDById(component.getFileRefId()); if (spdFileName == NULL) { ostringstream eout; eout << "The SPD file reference for componentfile "<& collocations = _appFact._sadParser.getHostCollocations(); + const std::vector& collocations = sadParser.getHostCollocations(); for (size_t index = 0; index < collocations.size(); ++index) { const SoftwareAssembly::HostCollocation& collocation = collocations[index]; LOG_TRACE(ApplicationFactory_impl, "Building component info for host collocation " @@ -2115,7 +2120,7 @@ void createHelper::getRequiredComponents(ossie::ApplicationPlacement& appPlaceme const std::vector& placements = collocations[index].getComponents(); for (unsigned int i = 0; i < placements.size(); i++) { - ossie::ComponentInfo* component = buildComponentInfo(placements[i]); + ossie::ComponentInfo* component = buildComponentInfo(fileMgr, sadParser, placements[i]); if (component->getInstantiationIdentifier() == assemblyControllerRefId) { component->setIsAssemblyController(true); } @@ -2124,11 +2129,11 @@ void createHelper::getRequiredComponents(ossie::ApplicationPlacement& appPlaceme } // Then, walk through the remaining non-collocated components - const std::vector& componentsFromSAD = _appFact._sadParser.getComponentPlacements(); + const std::vector& componentsFromSAD = sadParser.getComponentPlacements(); for (unsigned int i = 0; i < componentsFromSAD.size(); i++) { ossie::PlacementPlan* plan = new ossie::PlacementPlan(); appPlacement.addPlacement(plan); - ossie::ComponentInfo* component = buildComponentInfo(componentsFromSAD[i]); + ossie::ComponentInfo* component = buildComponentInfo(fileMgr, sadParser, componentsFromSAD[i]); if (component->getInstantiationIdentifier() == assemblyControllerRefId) { component->setIsAssemblyController(true); } diff --git a/redhawk/src/control/sdr/dommgr/createHelper.h b/redhawk/src/control/sdr/dommgr/createHelper.h index 99b310247..e5a2eb67b 100644 --- a/redhawk/src/control/sdr/dommgr/createHelper.h +++ b/redhawk/src/control/sdr/dommgr/createHelper.h @@ -135,8 +135,12 @@ class createHelper unsigned int offset=0); // Populate _requiredComponents vector - void getRequiredComponents(ossie::ApplicationPlacement& appPlacement); - ossie::ComponentInfo* buildComponentInfo(const ossie::ComponentPlacement& component); + void getRequiredComponents(CF::FileManager_ptr fileMgr, + const ossie::SoftwareAssembly& sadParser, + ossie::ApplicationPlacement& appPlacement); + ossie::ComponentInfo* buildComponentInfo(CF::FileManager_ptr fileMgr, + const ossie::SoftwareAssembly& sadParser, + const ossie::ComponentPlacement& component); // Supports allocation bool allocateUsesDevices(const ossie::UsesDeviceInfo::List& usesDevices, From 6b1914161c77ae2c954c5f210bc09a38cdffbc7b Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 12 May 2016 14:23:11 -0400 Subject: [PATCH 0221/1644] Allow FileSystem instead of more-specific FileManager --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 10 ++++----- .../control/sdr/dommgr/applicationSupport.cpp | 22 +++++++++---------- .../control/sdr/dommgr/applicationSupport.h | 8 +++---- redhawk/src/control/sdr/dommgr/createHelper.h | 4 ++-- 4 files changed, 22 insertions(+), 22 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 05a4f0ec7..bf0029658 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -2014,7 +2014,7 @@ ossie::SoftpkgDeployment* createHelper::resolveDependencyImplementation(ossie::S return 0; } -ossie::ComponentInfo* createHelper::buildComponentInfo(CF::FileManager_ptr fileMgr, +ossie::ComponentInfo* createHelper::buildComponentInfo(CF::FileSystem_ptr fileSys, const SoftwareAssembly& sadParser, const ComponentPlacement& component) { @@ -2028,7 +2028,7 @@ ossie::ComponentInfo* createHelper::buildComponentInfo(CF::FileManager_ptr fileM throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EINVAL, eout.str().c_str()); } LOG_TRACE(ApplicationFactory_impl, "Building Component Info From SPD File"); - newComponent = ossie::ComponentInfo::buildComponentInfoFromSPDFile(fileMgr, spdFileName); + newComponent = ossie::ComponentInfo::buildComponentInfoFromSPDFile(fileSys, spdFileName); if (newComponent == 0) { ostringstream eout; eout << "Error loading component information for file ref " << component.getFileRefId(); @@ -2100,7 +2100,7 @@ ossie::ComponentInfo* createHelper::buildComponentInfo(CF::FileManager_ptr fileM /* Create a vector of all the components for the SAD associated with this App Factory * - Get component information from the SAD and store in _requiredComponents vector */ -void createHelper::getRequiredComponents(CF::FileManager_ptr fileMgr, +void createHelper::getRequiredComponents(CF::FileSystem_ptr fileSys, const SoftwareAssembly& sadParser, ossie::ApplicationPlacement& appPlacement) @@ -2120,7 +2120,7 @@ void createHelper::getRequiredComponents(CF::FileManager_ptr fileMgr, const std::vector& placements = collocations[index].getComponents(); for (unsigned int i = 0; i < placements.size(); i++) { - ossie::ComponentInfo* component = buildComponentInfo(fileMgr, sadParser, placements[i]); + ossie::ComponentInfo* component = buildComponentInfo(fileSys, sadParser, placements[i]); if (component->getInstantiationIdentifier() == assemblyControllerRefId) { component->setIsAssemblyController(true); } @@ -2133,7 +2133,7 @@ void createHelper::getRequiredComponents(CF::FileManager_ptr fileMgr, for (unsigned int i = 0; i < componentsFromSAD.size(); i++) { ossie::PlacementPlan* plan = new ossie::PlacementPlan(); appPlacement.addPlacement(plan); - ossie::ComponentInfo* component = buildComponentInfo(fileMgr, sadParser, componentsFromSAD[i]); + ossie::ComponentInfo* component = buildComponentInfo(fileSys, sadParser, componentsFromSAD[i]); if (component->getInstantiationIdentifier() == assemblyControllerRefId) { component->setIsAssemblyController(true); } diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp index 72c808b34..cf9cb2c89 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp @@ -204,7 +204,7 @@ ImplementationInfo::~ImplementationInfo() } } -ImplementationInfo* ImplementationInfo::buildImplementationInfo(CF::FileManager_ptr fileMgr, const SPD::Implementation& spdImpl) +ImplementationInfo* ImplementationInfo::buildImplementationInfo(CF::FileSystem_ptr fileSys, const SPD::Implementation& spdImpl) { ImplementationInfo* impl = new ImplementationInfo(spdImpl); @@ -214,7 +214,7 @@ ImplementationInfo* ImplementationInfo::buildImplementationInfo(CF::FileManager_ std::vector::const_iterator jj; for (jj = softpkgDependencies.begin(); jj != softpkgDependencies.end(); ++jj) { LOG_TRACE(ImplementationInfo, "Loading component implementation softpkg dependency '" << *jj); - std::auto_ptr softpkg(SoftpkgInfo::buildSoftpkgInfo(fileMgr, jj->localfile.c_str())); + std::auto_ptr softpkg(SoftpkgInfo::buildSoftpkgInfo(fileSys, jj->localfile.c_str())); impl->addSoftPkgDependency(softpkg.release()); } @@ -378,23 +378,23 @@ const std::string& SoftpkgInfo::getName() const return _name; } -SoftpkgInfo* SoftpkgInfo::buildSoftpkgInfo(CF::FileManager_ptr fileMgr, const char* spdFileName) +SoftpkgInfo* SoftpkgInfo::buildSoftpkgInfo(CF::FileSystem_ptr fileSys, const char* spdFileName) { LOG_TRACE(SoftpkgInfo, "Building soft package info from file " << spdFileName); std::auto_ptr softpkg(new SoftpkgInfo(spdFileName)); - if (!softpkg->parseProfile(fileMgr)) { + if (!softpkg->parseProfile(fileSys)) { return 0; } else { return softpkg.release(); } } -bool SoftpkgInfo::parseProfile(CF::FileManager_ptr fileMgr) +bool SoftpkgInfo::parseProfile(CF::FileSystem_ptr fileSys) { try { - File_stream spd_file(fileMgr, _spdFileName.c_str()); + File_stream spd_file(fileSys, _spdFileName.c_str()); spd.load(spd_file, _spdFileName.c_str()); spd_file.close(); } catch (const ossie::parser_error& e) { @@ -416,7 +416,7 @@ bool SoftpkgInfo::parseProfile(CF::FileManager_ptr fileMgr) for (unsigned int implCount = 0; implCount < spd_i.size(); implCount++) { const SPD::Implementation& spdImpl = spd_i[implCount]; LOG_TRACE(SoftpkgInfo, "Adding implementation " << spdImpl.getID()); - ImplementationInfo* newImpl = ImplementationInfo::buildImplementationInfo(fileMgr, spdImpl); + ImplementationInfo* newImpl = ImplementationInfo::buildImplementationInfo(fileSys, spdImpl); addImplementation(newImpl); } @@ -453,20 +453,20 @@ const UsesDeviceInfo* SoftpkgInfo::getUsesDeviceById(const std::string& id) cons */ PREPARE_CF_LOGGING(ComponentInfo); -ComponentInfo* ComponentInfo::buildComponentInfoFromSPDFile(CF::FileManager_ptr fileMgr, const char* spdFileName) +ComponentInfo* ComponentInfo::buildComponentInfoFromSPDFile(CF::FileSystem_ptr fileSys, const char* spdFileName) { LOG_TRACE(ComponentInfo, "Building component info from file " << spdFileName); ossie::ComponentInfo* newComponent = new ossie::ComponentInfo(spdFileName); - if (!newComponent->parseProfile(fileMgr)) { + if (!newComponent->parseProfile(fileSys)) { delete newComponent; return 0; } if (newComponent->spd.getSCDFile() != 0) { try { - File_stream _scd(fileMgr, newComponent->spd.getSCDFile()); + File_stream _scd(fileSys, newComponent->spd.getSCDFile()); newComponent->scd.load(_scd); _scd.close(); } catch (ossie::parser_error& e) { @@ -484,7 +484,7 @@ ComponentInfo* ComponentInfo::buildComponentInfoFromSPDFile(CF::FileManager_ptr if (newComponent->spd.getPRFFile() != 0) { LOG_DEBUG(ComponentInfo, "Loading component properties from " << newComponent->spd.getPRFFile()); try { - File_stream _prf(fileMgr, newComponent->spd.getPRFFile()); + File_stream _prf(fileSys, newComponent->spd.getPRFFile()); LOG_TRACE(ComponentInfo, "Parsing component properties"); newComponent->prf.load(_prf); LOG_TRACE(ComponentInfo, "Closing PRF file") diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.h b/redhawk/src/control/sdr/dommgr/applicationSupport.h index 7226d057e..fe2aa1ece 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.h +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.h @@ -136,7 +136,7 @@ namespace ossie bool checkProcessorAndOs(const ossie::Properties& prf) const; - static ImplementationInfo* buildImplementationInfo(CF::FileManager_ptr fileMgr, const SPD::Implementation& spdImpl); + static ImplementationInfo* buildImplementationInfo(CF::FileSystem_ptr fileSys, const SPD::Implementation& spdImpl); private: ImplementationInfo (const ImplementationInfo&); @@ -180,12 +180,12 @@ namespace ossie virtual const UsesDeviceInfo* getUsesDeviceById(const std::string& id) const; - static SoftpkgInfo* buildSoftpkgInfo (CF::FileManager_ptr fileMgr, const char* spdFileName); + static SoftpkgInfo* buildSoftpkgInfo (CF::FileSystem_ptr fileSys, const char* spdFileName); SoftPkg spd; protected: - bool parseProfile (CF::FileManager_ptr fileMgr); + bool parseProfile (CF::FileSystem_ptr fileSys); const std::string _spdFileName; std::string _name; // Component name from SPD File @@ -253,7 +253,7 @@ namespace ossie CF::Properties getExecParameters(); CF::Properties getCommandLineParameters() const; - static ComponentInfo* buildComponentInfoFromSPDFile(CF::FileManager_ptr fileMgr, const char* _SPDFile); + static ComponentInfo* buildComponentInfoFromSPDFile(CF::FileSystem_ptr fileSys, const char* _SPDFile); ComponentDescriptor scd; ossie::Properties prf; diff --git a/redhawk/src/control/sdr/dommgr/createHelper.h b/redhawk/src/control/sdr/dommgr/createHelper.h index e5a2eb67b..61942f3dc 100644 --- a/redhawk/src/control/sdr/dommgr/createHelper.h +++ b/redhawk/src/control/sdr/dommgr/createHelper.h @@ -135,10 +135,10 @@ class createHelper unsigned int offset=0); // Populate _requiredComponents vector - void getRequiredComponents(CF::FileManager_ptr fileMgr, + void getRequiredComponents(CF::FileSystem_ptr fileSys, const ossie::SoftwareAssembly& sadParser, ossie::ApplicationPlacement& appPlacement); - ossie::ComponentInfo* buildComponentInfo(CF::FileManager_ptr fileMgr, + ossie::ComponentInfo* buildComponentInfo(CF::FileSystem_ptr fileSys, const ossie::SoftwareAssembly& sadParser, const ossie::ComponentPlacement& component); From bcd03d979cc29e4c383d77ce5aad6bcc53445fe1 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 12 May 2016 14:48:31 -0400 Subject: [PATCH 0222/1644] Only track of app-wide affinity where we use it, instead of keeping a member variable --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 23 +++++++++++-------- redhawk/src/control/sdr/dommgr/Deployment.cpp | 5 ++++ redhawk/src/control/sdr/dommgr/Deployment.h | 1 + redhawk/src/control/sdr/dommgr/createHelper.h | 1 - 4 files changed, 20 insertions(+), 10 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index bf0029658..6c3751999 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -1943,10 +1943,6 @@ ossie::AllocationResult createHelper::allocateComponentToDevice(ossie::Component const std::string interface = struct_prop["nic_allocation_status::interface"].toString(); LOG_DEBUG(ApplicationFactory_impl, "Allocation NIC assignment: " << interface ); deployment->setNicAssignment(interface); - - // RESOLVE - need SAD file directive to control this behavior.. i.e if promote_nic_to_affinity==true... - // for now add nic assignment as application affinity to all components deployed by this device - _app_affinity = deployment->getAffinityOptionsWithAssignment(); } } } @@ -2578,12 +2574,21 @@ void createHelper::attemptComponentExecution (CF::ApplicationRegistrar_ptr regis } -void createHelper::applyApplicationAffinityOptions(const DeploymentList& deployments) { +void createHelper::applyApplicationAffinityOptions(const DeploymentList& deployments) +{ + // RESOLVE - need SAD file directive to control this behavior.. i.e if promote_nic_to_affinity==true... + // for now add nic assignment as application affinity to all components deployed by this device + redhawk::PropertyMap app_affinity; + for (DeploymentList::const_iterator dep = deployments.begin(); dep != deployments.end(); ++dep) { + if ((*dep)->hasNicAssignment()) { + app_affinity = (*dep)->getAffinityOptionsWithAssignment(); + } + } - if ( _app_affinity.length() > 0 ) { + if (!app_affinity.empty()) { // log deployments with application affinity - for ( uint32_t i=0; i < _app_affinity.length(); i++ ) { - CF::DataType dt = _app_affinity[i]; + for ( uint32_t i=0; i < app_affinity.length(); i++ ) { + CF::DataType dt = app_affinity[i]; LOG_INFO(ApplicationFactory_impl, " Applying Application Affinity: directive id:" << dt.id << "/" << ossie::any_to_string( dt.value )) ; } @@ -2604,7 +2609,7 @@ void createHelper::applyApplicationAffinityOptions(const DeploymentList& deploym boost::shared_ptr dev = deployment->getAssignedDevice(); // for matching device deployments then apply nic affinity settings if (dev->identifier == deploy_on_device->identifier) { - deployment->mergeAffinityOptions(_app_affinity); + deployment->mergeAffinityOptions(app_affinity); } } } diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index 19350bf76..f3f31bf5d 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -208,6 +208,11 @@ void ComponentDeployment::setNicAssignment(const std::string& nic) nicAssignment = nic; } +bool ComponentDeployment::hasNicAssignment() const +{ + return !nicAssignment.empty(); +} + const std::string& ComponentDeployment::getNicAssignment() const { return nicAssignment; diff --git a/redhawk/src/control/sdr/dommgr/Deployment.h b/redhawk/src/control/sdr/dommgr/Deployment.h index 57c01391c..0860757c5 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.h +++ b/redhawk/src/control/sdr/dommgr/Deployment.h @@ -99,6 +99,7 @@ namespace ossie { void mergeAffinityOptions(const CF::Properties& affinity); void setNicAssignment(const std::string& nic); + bool hasNicAssignment() const; const std::string& getNicAssignment() const; void setCpuReservation(float reservation); diff --git a/redhawk/src/control/sdr/dommgr/createHelper.h b/redhawk/src/control/sdr/dommgr/createHelper.h index 61942f3dc..bae5fa3de 100644 --- a/redhawk/src/control/sdr/dommgr/createHelper.h +++ b/redhawk/src/control/sdr/dommgr/createHelper.h @@ -83,7 +83,6 @@ class createHelper // Tracks allocation IDs made during creation, and automates cleanup on // failure ScopedAllocations _allocations; - CF::Properties _app_affinity; ossie::DeviceList _registeredDevices; ossie::DeviceList _executableDevices; From 0d0db0799d470850491d56c3f19765523a0c20e7 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 12 May 2016 14:54:43 -0400 Subject: [PATCH 0223/1644] Use existing member to construct naming service name --- redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 6c3751999..9890a0887 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -2259,7 +2259,7 @@ void createHelper::loadAndExecuteComponents(const DeploymentList& deployments, _application->addComponent(component->getIdentifier(), component->getSpdFileName()); _application->setComponentImplementation(component->getIdentifier(), implementation->getId()); if (component->isNamingService()) { - std::string lookupName = _appFact._domainName + "/" + _waveformContextName + "/" + component->getNamingServiceName() ; + std::string lookupName = _baseNamingContext + "/" + component->getNamingServiceName() ; _application->setComponentNamingContext(component->getIdentifier(), lookupName); } _application->setComponentDevice(component->getIdentifier(), device->device); From 66bf26e2be08e447b5a13f32b0514cb8896ab7fd Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 12 May 2016 15:10:39 -0400 Subject: [PATCH 0224/1644] Add a method to retrieve the object for a specific component from the application, instead of searching through the CORBA sequence returned by registeredComponents --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 20 ++++++++++--------- .../control/sdr/dommgr/Application_impl.cpp | 11 ++++++++++ .../src/control/sdr/dommgr/Application_impl.h | 2 ++ 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 9890a0887..ff0a5b68e 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -2667,8 +2667,6 @@ void createHelper::initializeComponents(const DeploymentList& deployments) // Install the different components in the system LOG_TRACE(ApplicationFactory_impl, "initializing " << deployments.size() << " waveform components"); - CF::Components_var app_registeredComponents = _application->registeredComponents(); - for (unsigned int rc_idx = 0; rc_idx < deployments.size (); rc_idx++) { ossie::ComponentDeployment* deployment = deployments[rc_idx]; const ossie::ComponentInfo* component = deployment->getComponent(); @@ -2686,14 +2684,18 @@ void createHelper::initializeComponents(const DeploymentList& deployments) // Find the component on the Application const std::string componentId = component->getIdentifier(); - CF::Resource_var resource = CF::Resource::_nil(); - for (unsigned int comp_idx=0; comp_idxlength(); comp_idx++) { - std::string comp_id = std::string(app_registeredComponents[comp_idx].identifier); - if (comp_id == componentId) { - resource = ossie::corba::_narrowSafe(app_registeredComponents[comp_idx].componentObject); - break; - } + CORBA::Object_var objref = _application->getComponentObject(componentId); + if (CORBA::is_nil(objref)) { + ostringstream eout; + eout << "No object found for component: '" << component->getName() + << "' with component id: '" << componentId + << " assigned to device: '"<getAssignedDevice()->identifier<<"'"; + eout << " in waveform '" << _waveformContextName<<"';"; + eout << " error occurred near line:" <<__LINE__ << " in file:" << __FILE__ << ";"; + throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EIO, eout.str().c_str()); } + + CF::Resource_var resource = ossie::corba::_narrowSafe(objref); if (CORBA::is_nil(resource)) { ostringstream eout; eout << "CF::Resource::_narrow failed with Unknown Exception for component: '" << component->getName() diff --git a/redhawk/src/control/sdr/dommgr/Application_impl.cpp b/redhawk/src/control/sdr/dommgr/Application_impl.cpp index 2eaea6ee5..04ea0d0b5 100644 --- a/redhawk/src/control/sdr/dommgr/Application_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/Application_impl.cpp @@ -1349,3 +1349,14 @@ void Application_impl::addComponentLoadedFile(const std::string& identifier, con component->loadedFiles.push_back(fileName); } } + +CORBA::Object_ptr Application_impl::getComponentObject(const std::string& identifier) +{ + ossie::ApplicationComponent* component = findComponent(identifier); + if (!component) { + LOG_ERROR(Application_impl, "Cannot return object for unknown component '" << identifier << "'"); + return CORBA::Object::_nil(); + } else { + return CORBA::Object::_duplicate(component->componentObject); + } +} diff --git a/redhawk/src/control/sdr/dommgr/Application_impl.h b/redhawk/src/control/sdr/dommgr/Application_impl.h index 8124bdb65..6a98489cb 100644 --- a/redhawk/src/control/sdr/dommgr/Application_impl.h +++ b/redhawk/src/control/sdr/dommgr/Application_impl.h @@ -146,6 +146,8 @@ class Application_impl : public virtual POA_CF::Application, public Logging_impl void setComponentDevice(const std::string& identifier, CF::Device_ptr device); void addComponentLoadedFile(const std::string& identifier, const std::string& fileName); + CORBA::Object_ptr getComponentObject(const std::string& identifier); + void releaseComponents(); void terminateComponents(); void unloadComponents(); From b3cf44fd40aca0d5e84cd8335c011626f2698cd0 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 12 May 2016 15:45:34 -0400 Subject: [PATCH 0225/1644] Add string conversion for PropertyMap --- redhawk/src/base/framework/PropertyMap.cpp | 16 ++++++++++++++++ redhawk/src/base/framework/prop_helpers.cpp | 4 +++- redhawk/src/base/include/ossie/PropertyMap.h | 2 ++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/redhawk/src/base/framework/PropertyMap.cpp b/redhawk/src/base/framework/PropertyMap.cpp index 2de8ac64f..14d318471 100644 --- a/redhawk/src/base/framework/PropertyMap.cpp +++ b/redhawk/src/base/framework/PropertyMap.cpp @@ -181,3 +181,19 @@ void PropertyMap::erase(iterator first, iterator last) // Resize to remove deleted items length(length()-(last-first)); } + +std::string PropertyMap::toString() const +{ + std::ostringstream out; + out << "{"; + bool first = true; + for (const_iterator prop = begin(); prop != end(); ++prop) { + if (!first) { + out << ", "; + } + first = false; + out << prop->getId() << "=" << prop->getValue().toString(); + } + out << "}"; + return out.str(); +} diff --git a/redhawk/src/base/framework/prop_helpers.cpp b/redhawk/src/base/framework/prop_helpers.cpp index 719958f0b..3ce716fa0 100644 --- a/redhawk/src/base/framework/prop_helpers.cpp +++ b/redhawk/src/base/framework/prop_helpers.cpp @@ -658,7 +658,9 @@ std::string ossie::any_to_string(const CORBA::Any& value) std::string result; CORBA::TypeCode_var valueType = value.type(); - if (valueType->kind() == CORBA::tk_struct) { + if (valueType->equivalent(CF::_tc_Properties)) { + result = redhawk::Value::cast(value).asProperties().toString(); + } else if (valueType->kind() == CORBA::tk_struct) { result = complexAnyToString(value); } else { diff --git a/redhawk/src/base/include/ossie/PropertyMap.h b/redhawk/src/base/include/ossie/PropertyMap.h index a2132c428..8261609c1 100644 --- a/redhawk/src/base/include/ossie/PropertyMap.h +++ b/redhawk/src/base/include/ossie/PropertyMap.h @@ -78,6 +78,8 @@ namespace redhawk { void erase(const std::string& id); void erase(iterator pos); void erase(iterator first, iterator last); + + std::string toString() const; }; } From ea99b1829234af171cf557b4623b563fa78fa966 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 12 May 2016 16:06:06 -0400 Subject: [PATCH 0226/1644] Use extend instead of explicit element-wise copy --- redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index ff0a5b68e..66360845d 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -1905,11 +1905,7 @@ ossie::AllocationResult createHelper::allocateComponentToDevice(ossie::Component CF::Properties configure_props = component->getConfigureProperties(); CF::Properties construct_props = component->getConstructProperties(); - unsigned int initial_length = configure_props.length(); - configure_props.length(configure_props.length()+construct_props.length()); - for (unsigned int i=0; i_evaluateMATHinRequest(allocationProperties, configure_props); LOG_TRACE(ApplicationFactory_impl, "alloc prop size " << allocationProperties.size() ); From 9dd2e4ddb8daff70e255a8fc6297a935553dd38d Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 12 May 2016 16:13:58 -0400 Subject: [PATCH 0227/1644] Delete uses device assignments when the deployment is destroyed; support transfer of ownership for local cleanup when attempting implementation-specific uses device assignment (ugh) --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 28 ++++++++----------- redhawk/src/control/sdr/dommgr/Deployment.cpp | 13 +++++++++ redhawk/src/control/sdr/dommgr/Deployment.h | 4 +++ redhawk/src/control/sdr/dommgr/createHelper.h | 2 +- 4 files changed, 29 insertions(+), 18 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 66360845d..540890432 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -999,7 +999,7 @@ void createHelper::_handleUsesDevices(ossie::ApplicationPlacement& appPlacement, } // The device assignments for SAD-level usesdevices are never stored - std::vector assignedDevices; + ossie::UsesDeviceDeployment assignedDevices; if (!allocateUsesDevices(usesDevices, appProperties, assignedDevices, this->_allocations)) { // There were unsatisfied usesdevices for the application ostringstream eout; @@ -1019,10 +1019,8 @@ void createHelper::_handleUsesDevices(ossie::ApplicationPlacement& appPlacement, LOG_DEBUG(ApplicationFactory_impl, eout.str()); throw CF::ApplicationFactory::CreateApplicationError(CF::CF_ENOSPC, eout.str().c_str()); } - for (std::vector::iterator dev=assignedDevices.begin(); dev!=assignedDevices.end(); dev++) { - //dev->deviceAssignment.componentId = assembly_controller->getIdentifier().c_str(); - appDeployment.addUsesDeviceAssignment(*dev); - } + + assignedDevices.transferUsesDeviceAssignments(appDeployment); } void createHelper::setUpExternalPorts(ossie::ApplicationDeployment& appDeployment, @@ -1586,7 +1584,7 @@ ossie::ComponentDeployment* createHelper::allocateComponent(ossie::ComponentInfo // Find the devices that allocate the SPD's minimum required usesdevices properties const UsesDeviceInfo::List &usesDevVec = component->getUsesDevices(); - std::vector assignedDevices; + ossie::UsesDeviceDeployment assignedDevices; if (!allocateUsesDevices(usesDevVec, configureProperties, assignedDevices, this->_allocations)) { // There were unsatisfied usesdevices for the component ostringstream eout; @@ -1613,7 +1611,7 @@ ossie::ComponentDeployment* createHelper::allocateComponent(ossie::ComponentInfo ossie::ImplementationInfo* impl = implementations[implCount]; // Handle 'usesdevice' dependencies for the particular implementation - std::vector implAssignedDevices; + UsesDeviceDeployment implAssignedDevices; ScopedAllocations implAllocations(*this->_allocationMgr); const UsesDeviceInfo::List &implUsesDevVec = impl->getUsesDevices(); @@ -1624,10 +1622,9 @@ ossie::ComponentDeployment* createHelper::allocateComponent(ossie::ComponentInfo } std::auto_ptr deployment(new ossie::ComponentDeployment(component, impl)); - for (std::vector::iterator ii = assignedDevices.begin(); - ii != assignedDevices.end(); ++ii) { - deployment->addUsesDeviceAssignment(*ii); - } + + // Transfer ownership of the uses device assigments to the deployment + assignedDevices.transferUsesDeviceAssignments(*deployment); // Found an implementation which has its 'usesdevice' dependencies // satisfied, now perform assignment/allocation of component to device @@ -1665,10 +1662,7 @@ ossie::ComponentDeployment* createHelper::allocateComponent(ossie::ComponentInfo // device assignments implAllocations.transfer(this->_allocations); - for (std::vector::iterator ii = implAssignedDevices.begin(); - ii != implAssignedDevices.end(); ++ii) { - deployment->addUsesDeviceAssignment(*ii); - } + implAssignedDevices.transferUsesDeviceAssignments(*deployment); return deployment.release(); } @@ -1705,7 +1699,7 @@ ossie::ComponentDeployment* createHelper::allocateComponent(ossie::ComponentInfo bool createHelper::allocateUsesDevices(const ossie::UsesDeviceInfo::List& usesDevices, const CF::Properties& configureProperties, - std::vector& deviceAssignments, + ossie::UsesDeviceDeployment& deviceAssignments, ScopedAllocations& allocations) { // Create a temporary lookup table for reconciling allocation requests with @@ -1746,7 +1740,7 @@ bool createHelper::allocateUsesDevices(const ossie::UsesDeviceInfo::List& usesDe ossie::UsesDeviceAssignment* assignment = new ossie::UsesDeviceAssignment(uses->second); assignment->setAssignedDevice(response[resp].allocatedDevice); - deviceAssignments.push_back(assignment); + deviceAssignments.addUsesDeviceAssignment(assignment); } if (usesDeviceMap.empty()) { diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index f3f31bf5d..45ffd046a 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -26,6 +26,19 @@ using namespace ossie; namespace fs = boost::filesystem; +UsesDeviceDeployment::~UsesDeviceDeployment() +{ + for (AssignmentList::iterator assign = assignments.begin(); assign != assignments.end(); ++assign) { + delete *assign; + } +} + +void UsesDeviceDeployment::transferUsesDeviceAssignments(UsesDeviceDeployment& other) +{ + other.assignments.insert(other.assignments.end(), assignments.begin(), assignments.end()); + assignments.clear(); +} + void UsesDeviceDeployment::addUsesDeviceAssignment(UsesDeviceAssignment* assignment) { assignments.push_back(assignment); diff --git a/redhawk/src/control/sdr/dommgr/Deployment.h b/redhawk/src/control/sdr/dommgr/Deployment.h index 0860757c5..f388d1d25 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.h +++ b/redhawk/src/control/sdr/dommgr/Deployment.h @@ -52,10 +52,14 @@ namespace ossie { public: typedef std::vector AssignmentList; + ~UsesDeviceDeployment(); + void addUsesDeviceAssignment(UsesDeviceAssignment* assignment); UsesDeviceAssignment* getUsesDeviceAssignment(const std::string identifier); const AssignmentList& getUsesDeviceAssignments(); + void transferUsesDeviceAssignments(UsesDeviceDeployment& other); + protected: AssignmentList assignments; }; diff --git a/redhawk/src/control/sdr/dommgr/createHelper.h b/redhawk/src/control/sdr/dommgr/createHelper.h index bae5fa3de..95b83a233 100644 --- a/redhawk/src/control/sdr/dommgr/createHelper.h +++ b/redhawk/src/control/sdr/dommgr/createHelper.h @@ -144,7 +144,7 @@ class createHelper // Supports allocation bool allocateUsesDevices(const ossie::UsesDeviceInfo::List& usesDevices, const CF::Properties& configureProperties, - std::vector& assignedDevices, + ossie::UsesDeviceDeployment& assignedDevices, ScopedAllocations& allocations); CF::AllocationManager::AllocationResponseSequence* allocateUsesDeviceProperties( const ossie::UsesDeviceInfo::List& component, From bc5d2480c75faf8c4bc7a2cac4c28d172d9b4482 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 13 May 2016 12:59:08 -0400 Subject: [PATCH 0228/1644] Store the application identifier in ApplicationDeployment --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 27 +++++++++---------- redhawk/src/control/sdr/dommgr/Deployment.cpp | 8 +++++- redhawk/src/control/sdr/dommgr/Deployment.h | 5 +++- redhawk/src/control/sdr/dommgr/createHelper.h | 2 -- 4 files changed, 24 insertions(+), 18 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 540890432..e3dee75db 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -690,7 +690,7 @@ void createHelper::_configureComponents(const DeploymentList& deployments) void createHelper::assignPlacementsToDevices(ossie::ApplicationPlacement& appPlacement, ossie::ApplicationDeployment& appDeployment, - const std::string& appIdentifier, const DeviceAssignmentMap& devices) + const DeviceAssignmentMap& devices) { typedef ossie::ApplicationPlacement::PlacementList PlacementPlanList; const PlacementPlanList& placements = appPlacement.getPlacements(); @@ -699,7 +699,7 @@ void createHelper::assignPlacementsToDevices(ossie::ApplicationPlacement& appPla if (components.size() > 1) { LOG_TRACE(ApplicationFactory_impl, "Placing host collocation " << (*plan)->getId() << " " << (*plan)->getName()); - _placeHostCollocation(appDeployment, appIdentifier, components, devices); + _placeHostCollocation(appDeployment, components, devices); LOG_TRACE(ApplicationFactory_impl, "-- Completed placement for Collocation ID:" << (*plan)->getId() << " Components Placed: " << components.size()); } else { @@ -711,7 +711,7 @@ void createHelper::assignPlacementsToDevices(ossie::ApplicationPlacement& appPla LOG_TRACE(ApplicationFactory_impl, "Component " << component->getInstantiationIdentifier() << " is assigned to device " << assigned_device); } - ossie::ComponentDeployment* deployment = allocateComponent(component, assigned_device, appIdentifier); + ossie::ComponentDeployment* deployment = allocateComponent(component, assigned_device, appDeployment.getIdentifier()); appDeployment.addComponentDeployment(deployment); } } @@ -897,7 +897,6 @@ void createHelper::_consolidateAllocations(const ossie::ImplementationInfo::List } void createHelper::_placeHostCollocation(ossie::ApplicationDeployment& appDeployment, - const std::string &appIdentifier, const PlacementList& collocatedComponents, const DeviceAssignmentMap& devices) { @@ -946,7 +945,7 @@ void createHelper::_placeHostCollocation(ossie::ApplicationDeployment& appDeploy this->_consolidateAllocations(res_vec[index], allocationProperties); const std::string requestid = ossie::generateUUID(); - ossie::AllocationResult response = this->_allocationMgr->allocateDeployment(requestid, allocationProperties, deploymentDevices, appIdentifier, processorDeps, osDeps); + ossie::AllocationResult response = this->_allocationMgr->allocateDeployment(requestid, allocationProperties, deploymentDevices, appDeployment.getIdentifier(), processorDeps, osDeps); if (!response.first.empty()) { // Ensure that all capacities get cleaned up this->_allocations.push_back(response.first); @@ -1321,14 +1320,6 @@ CF::Application_ptr createHelper::create ( overrideExternalProperties(placement, modifiedInitConfiguration); - //////////////////////////////////////////////// - // Assign components to devices - //////////////////////////////////////////////// - ossie::ApplicationDeployment app_deployment; - - // Allocate any usesdevice capacities specified in the SAD file - _handleUsesDevices(placement, app_deployment, name); - // Give the application a unique identifier of the form // "softwareassemblyid:ApplicationName", where the application // name includes the serial number generated for the naming context @@ -1336,11 +1327,19 @@ CF::Application_ptr createHelper::create ( std::string appIdentifier = _appFact._identifier + ":" + _waveformContextName; + //////////////////////////////////////////////// + // Assign components to devices + //////////////////////////////////////////////// + ossie::ApplicationDeployment app_deployment(appIdentifier); + + // Allocate any usesdevice capacities specified in the SAD file + _handleUsesDevices(placement, app_deployment, name); + // Catch invalid device assignments _validateDAS(placement, deviceAssignments); // Assign all components to devices - assignPlacementsToDevices(placement, app_deployment, appIdentifier, deviceAssignments); + assignPlacementsToDevices(placement, app_deployment, deviceAssignments); // Assign CPU reservations to components const DeploymentList& deployments = app_deployment.getComponentDeployments(); diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index 45ffd046a..853fb0bd4 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -286,7 +286,8 @@ CF::Resource_ptr ComponentDeployment::getResourcePtr() const return CF::Resource::_duplicate(resource); } -ApplicationDeployment::ApplicationDeployment() +ApplicationDeployment::ApplicationDeployment(const std::string& identifier) : + identifier(identifier) { } @@ -297,6 +298,11 @@ ApplicationDeployment::~ApplicationDeployment() } } +const std::string& ApplicationDeployment::getIdentifier() const +{ + return identifier; +} + void ApplicationDeployment::addComponentDeployment(ComponentDeployment* deployment) { components.push_back(deployment); diff --git a/redhawk/src/control/sdr/dommgr/Deployment.h b/redhawk/src/control/sdr/dommgr/Deployment.h index f388d1d25..28dec2fd1 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.h +++ b/redhawk/src/control/sdr/dommgr/Deployment.h @@ -133,9 +133,11 @@ namespace ossie { public: typedef std::vector ComponentList; - ApplicationDeployment(); + ApplicationDeployment(const std::string& identifier); ~ApplicationDeployment(); + const std::string& getIdentifier() const; + void addComponentDeployment(ComponentDeployment* deployment); const ComponentList& getComponentDeployments(); ComponentDeployment* getComponentDeployment(const std::string& instantiationId); @@ -152,6 +154,7 @@ namespace ossie { CF::Device_ptr lookupDeviceUsedByApplication(const std::string& usesRefId); protected: + const std::string identifier; ComponentList components; }; } diff --git a/redhawk/src/control/sdr/dommgr/createHelper.h b/redhawk/src/control/sdr/dommgr/createHelper.h index 95b83a233..2ba241f80 100644 --- a/redhawk/src/control/sdr/dommgr/createHelper.h +++ b/redhawk/src/control/sdr/dommgr/createHelper.h @@ -107,7 +107,6 @@ class createHelper void overrideProperties(const CF::Properties& initConfiguration, ossie::ComponentInfo* component); void assignPlacementsToDevices(ossie::ApplicationPlacement& appPlacement, ossie::ApplicationDeployment& appDeployment, - const std::string& appIdentifier, const DeviceAssignmentMap& devices); void _validateDAS(ossie::ApplicationPlacement& appPlacement, const DeviceAssignmentMap& deviceAssignments); void _connectComponents(ossie::ApplicationDeployment& appDeployment, @@ -119,7 +118,6 @@ class createHelper void setUpExternalPorts(ossie::ApplicationDeployment& appDeployment, Application_impl* application); void setUpExternalProperties(ossie::ApplicationDeployment& appDeployment, Application_impl* application); void _placeHostCollocation(ossie::ApplicationDeployment& appDeployment, - const std::string& appIdentifier, const PlacementList& collocatedComponents, const DeviceAssignmentMap& devices); void _handleUsesDevices(ossie::ApplicationPlacement& appPlacement, From b96c5b6b541b6b0131d15d76e162a7f142a80297 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 13 May 2016 13:58:52 -0400 Subject: [PATCH 0229/1644] Honor const-ness to avoid making a copy of the placement list in collocation --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 16 ++++++++-------- redhawk/src/control/sdr/dommgr/createHelper.h | 4 +++- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index e3dee75db..261982c39 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -740,9 +740,11 @@ void createHelper::_validateDAS(ossie::ApplicationPlacement& appPlacement, } } -void createHelper::_resolveImplementations(PlacementList::iterator comp, PlacementList& compList, std::vector &res_vec) +void createHelper::_resolveImplementations(PlacementList::const_iterator comp, + PlacementList::const_iterator end, + std::vector &res_vec) { - if (comp == compList.end()) { + if (comp == end) { return; } const ossie::ImplementationInfo::List& comp_imps = (*comp)->getImplementations(); @@ -764,7 +766,7 @@ void createHelper::_resolveImplementations(PlacementList::iterator comp, Placeme } } } - this->_resolveImplementations(++comp, compList, res_vec); + this->_resolveImplementations(++comp, end, res_vec); return; } @@ -912,15 +914,13 @@ void createHelper::_placeHostCollocation(ossie::ApplicationDeployment& appDeploy } } - PlacementList placingComponents = collocatedComponents; - // create every combination of implementations for the components in the set // for each combination: // consolidate allocations // attempt allocation // if the allocation succeeds, break the loop std::vector res_vec; - this->_resolveImplementations(placingComponents.begin(), placingComponents, res_vec); + this->_resolveImplementations(collocatedComponents.begin(), collocatedComponents.end(), res_vec); this->_removeUnmatchedImplementations(res_vec); // Get the executable devices for the domain; if there were any devices @@ -954,9 +954,9 @@ void createHelper::_placeHostCollocation(ossie::ApplicationDeployment& appDeploy boost::shared_ptr& node = response.second; const std::string& deviceId = node->identifier; - PlacementList::iterator comp = placingComponents.begin(); + PlacementList::const_iterator comp = collocatedComponents.begin(); ossie::ImplementationInfo::List::iterator impl = res_vec[index].end()-1; - for (unsigned int i=0; isetAssignedDevice(node); if (!resolveSoftpkgDependencies(deployment, *node)) { diff --git a/redhawk/src/control/sdr/dommgr/createHelper.h b/redhawk/src/control/sdr/dommgr/createHelper.h index 2ba241f80..3f3c43cb2 100644 --- a/redhawk/src/control/sdr/dommgr/createHelper.h +++ b/redhawk/src/control/sdr/dommgr/createHelper.h @@ -123,7 +123,9 @@ class createHelper void _handleUsesDevices(ossie::ApplicationPlacement& appPlacement, ossie::ApplicationDeployment& appDeployment, const std::string& appName); - void _resolveImplementations(PlacementList::iterator comp, PlacementList& compList, std::vector &res_vec); + void _resolveImplementations(PlacementList::const_iterator comp, + PlacementList::const_iterator end, + std::vector& res_vec); void _removeUnmatchedImplementations(std::vector &res_vec); void _consolidateAllocations(const ossie::ImplementationInfo::List& implementations, CF::Properties& allocs); void _evaluateMATHinRequest(CF::Properties &request, const CF::Properties &configureProperties); From 52a712295666a17cbbfb8f3aeac0a5b56a40815a Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 16 May 2016 14:32:14 -0400 Subject: [PATCH 0230/1644] Combine generation of implementation combinations and processor/OS dependency filtering for host collocation into a single recursive method --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 190 ++++++------------ redhawk/src/control/sdr/dommgr/createHelper.h | 15 +- 2 files changed, 71 insertions(+), 134 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 261982c39..44dd9477d 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -163,7 +163,29 @@ static std::vector mergeOsDeps(const ossie::Impleme return osDeps; } -PREPARE_CF_LOGGING(ApplicationFactory_impl); +namespace { + template + inline bool mergeDependencies(std::vector& first, const std::vector& second) + { + if (second.empty()) { + return true; + } else if (first.empty()) { + first = second; + return true; + } else { + for (typename std::vector::iterator iter = first.begin(); iter != first.end(); ) { + if (std::find(second.begin(), second.end(), *iter) == second.end()) { + iter = first.erase(iter); + } else { + ++iter; + } + } + return !first.empty(); + } + } +} + +PREPARE_LOGGING(ApplicationFactory_impl); void ApplicationFactory_impl::ValidateFileLocation( CF::FileManager_ptr fileMgr, const std::string &profile_file) @@ -740,138 +762,45 @@ void createHelper::_validateDAS(ossie::ApplicationPlacement& appPlacement, } } -void createHelper::_resolveImplementations(PlacementList::const_iterator comp, - PlacementList::const_iterator end, - std::vector &res_vec) +void createHelper::_matchImplementations(PlacementList::const_iterator comp, + PlacementList::const_iterator end, + CollocationList& matches, + const ImplementationList& current, + const ProcessorList& processorDeps, + const OSList& osDeps) { if (comp == end) { + // Reached the end of the components, 'current' is a valid and complete + // set of implementations + matches.push_back(current); return; } - const ossie::ImplementationInfo::List& comp_imps = (*comp)->getImplementations(); - std::vector tmp_res_vec = res_vec; - unsigned int old_res_vec_size = res_vec.size(); - if (old_res_vec_size == 0) { - res_vec.resize(comp_imps.size()); - for (unsigned int ii=0; ii_resolveImplementations(++comp, end, res_vec); - return; -} -void createHelper::_removeUnmatchedImplementations(std::vector &res_vec) -{ - std::vector::iterator impl_list = res_vec.begin(); - while (impl_list != res_vec.end()) { - std::vector::iterator old_impl_list = impl_list; - ossie::ImplementationInfo::List::iterator impl = (*impl_list).begin(); - std::vector reference_pair = (*impl)->getOsDeps(); - std::vector reference_procs = (*impl)->getProcessorDeps(); - bool os_init_to_zero = (reference_pair.size()==0); - bool proc_init_to_zero = (reference_procs.size()==0); - impl++; - bool match = true; - while (impl != (*impl_list).end()) { - std::vector pair = (*impl)->getOsDeps(); - std::vector procs = (*impl)->getProcessorDeps(); - bool os_must_match = false; - bool proc_must_match = false; - if (os_init_to_zero) - os_must_match = false; - if (proc_init_to_zero) - proc_must_match = false; - if ((reference_pair.size() != 0) and (pair.size() != 0)) {os_must_match = true;} - if ((reference_procs.size() != 0) and (procs.size() != 0)) {proc_must_match = true;} - // if os must match (because both lists are non-zero length), check that at least one of the sets matches - if (os_must_match) { - bool at_least_one_match = false; - for (std::vector::iterator ref=reference_pair.begin(); ref::iterator cur=pair.begin(); cur::iterator ref=reference_procs.begin(); ref::iterator cur=procs.begin(); curpair.size()) { - for (std::vector::iterator ref=reference_pair.begin(); ref::iterator cur=pair.begin(); curprocs.size()) { - for (std::vector::iterator ref=reference_procs.begin(); ref::iterator cur=procs.begin(); cur::iterator cur=pair.begin(); cur::iterator cur=procs.begin(); curgetImplementations(); + ++comp; + for (ImplementationList::const_iterator impl = comp_impls.begin(); impl != comp_impls.end(); ++impl) { + // Check that the processor dependencies are compatible, filtering out + // anything not compatible with the current component + std::vector proc_list = processorDeps;; + if (!mergeDependencies(proc_list, (*impl)->getProcessorDeps())) { + continue; } - if (not match) { - (*impl_list).erase(impl); + + // Check that the OS dependencies are compatible, again filtering out + // anything not compatible with the current component + std::vector os_list = osDeps; + if (!mergeDependencies(os_list, (*impl)->getOsDeps())) { + continue; } - impl_list++; + + // Add this implementation to the pontential matches and recurse one + // more level + ImplementationList match = current; + match.push_back(*impl); + _matchImplementations(comp, end, matches, match, proc_list, os_list); } - return; } void createHelper::_consolidateAllocations(const ossie::ImplementationInfo::List& impls, CF::Properties& allocs) @@ -914,14 +843,15 @@ void createHelper::_placeHostCollocation(ossie::ApplicationDeployment& appDeploy } } + LOG_TRACE(ApplicationFactory_impl, "Placing " << collocatedComponents.size() << " components"); + // create every combination of implementations for the components in the set // for each combination: // consolidate allocations // attempt allocation // if the allocation succeeds, break the loop - std::vector res_vec; - this->_resolveImplementations(collocatedComponents.begin(), collocatedComponents.end(), res_vec); - this->_removeUnmatchedImplementations(res_vec); + CollocationList res_vec; + _matchImplementations(collocatedComponents.begin(), collocatedComponents.end(), res_vec); // Get the executable devices for the domain; if there were any devices // assigned, filter out all other devices @@ -955,8 +885,8 @@ void createHelper::_placeHostCollocation(ossie::ApplicationDeployment& appDeploy const std::string& deviceId = node->identifier; PlacementList::const_iterator comp = collocatedComponents.begin(); - ossie::ImplementationInfo::List::iterator impl = res_vec[index].end()-1; - for (; comp != collocatedComponents.end(); ++comp, --impl) { + ossie::ImplementationInfo::List::iterator impl = res_vec[index].begin(); + for (; comp != collocatedComponents.end(); ++comp, ++impl) { ossie::ComponentDeployment* deployment = new ossie::ComponentDeployment(*comp, *impl); deployment->setAssignedDevice(node); if (!resolveSoftpkgDependencies(deployment, *node)) { diff --git a/redhawk/src/control/sdr/dommgr/createHelper.h b/redhawk/src/control/sdr/dommgr/createHelper.h index 3f3c43cb2..8a4a845c4 100644 --- a/redhawk/src/control/sdr/dommgr/createHelper.h +++ b/redhawk/src/control/sdr/dommgr/createHelper.h @@ -123,10 +123,17 @@ class createHelper void _handleUsesDevices(ossie::ApplicationPlacement& appPlacement, ossie::ApplicationDeployment& appDeployment, const std::string& appName); - void _resolveImplementations(PlacementList::const_iterator comp, - PlacementList::const_iterator end, - std::vector& res_vec); - void _removeUnmatchedImplementations(std::vector &res_vec); + + typedef ossie::ImplementationInfo::List ImplementationList; + typedef std::vector CollocationList; + typedef std::vector ProcessorList; + typedef std::vector OSList; + void _matchImplementations(PlacementList::const_iterator comp, + PlacementList::const_iterator end, + CollocationList& matches, + const ImplementationList& current=ImplementationList(), + const ProcessorList& processorDeps=ProcessorList(), + const OSList& osDeps=OSList()); void _consolidateAllocations(const ossie::ImplementationInfo::List& implementations, CF::Properties& allocs); void _evaluateMATHinRequest(CF::Properties &request, const CF::Properties &configureProperties); void _castRequestProperties(CF::Properties& allocationProperties, const std::vector &prop_refs, unsigned int offset=0); From 064605f4fd00621c069caa45e9a75c8f1d773dc4 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 16 May 2016 16:25:04 -0400 Subject: [PATCH 0231/1644] Attempt allocation for collocated components as soon as a potential set is found, rather than building up a list of combinations and searching through them --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 246 +++++++----------- redhawk/src/control/sdr/dommgr/Deployment.cpp | 17 +- redhawk/src/control/sdr/dommgr/Deployment.h | 3 + redhawk/src/control/sdr/dommgr/createHelper.h | 28 +- 4 files changed, 130 insertions(+), 164 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 44dd9477d..0d4a8adeb 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -103,66 +103,6 @@ static void rotateDeviceList(DeviceList& devices, const std::string& identifier) } } -static std::vector mergeProcessorDeps(const ossie::ImplementationInfo::List& implementations) -{ - // this function merges the overlap in processors between the different components that have been selected - std::vector processorDeps; - for (ossie::ImplementationInfo::List::const_iterator impl = implementations.begin(); impl != implementations.end(); ++impl) { - const std::vector& implDeps = (*impl)->getProcessorDeps(); - if (!implDeps.empty()) { - if (processorDeps.empty()) { - // No prior processor dependencies, so overwrite - processorDeps = implDeps; - } else { - std::vector toremove; - toremove.resize(0); - for (std::vector::iterator proc = processorDeps.begin(); proc != processorDeps.end(); ++proc) { - if (std::find(implDeps.begin(), implDeps.end(), *proc) == implDeps.end()) { - toremove.push_back(*proc); - } - } - for (std::vector::iterator _rem = toremove.begin(); _rem != toremove.end(); ++_rem) { - std::vector::iterator proc = std::find(processorDeps.begin(), processorDeps.end(), *_rem); - if (proc != processorDeps.end()) { - processorDeps.erase(proc); - } - } - } - } - } - return processorDeps; -} - -static std::vector mergeOsDeps(const ossie::ImplementationInfo::List& implementations) -{ - // this function merges the overlap in operating systems between the different components that have been selected - std::vector osDeps; - for (ossie::ImplementationInfo::List::const_iterator impl = implementations.begin(); impl != implementations.end(); ++impl) { - const std::vector& implDeps = (*impl)->getOsDeps(); - if (!implDeps.empty()) { - if (osDeps.empty()) { - // No prior OS dependencies, so overwrite - osDeps = implDeps; - } else { - std::vector toremove; - toremove.resize(0); - for (std::vector::iterator pair = osDeps.begin(); pair != osDeps.end(); ++pair) { - if (std::find(implDeps.begin(), implDeps.end(), *pair) == implDeps.end()) { - toremove.push_back(*pair); - } - } - for (std::vector::iterator _rem = toremove.begin(); _rem != toremove.end(); ++_rem) { - std::vector::iterator pair = std::find(osDeps.begin(), osDeps.end(), *_rem); - if (pair != osDeps.end()) { - osDeps.erase(pair); - } - } - } - } - } - return osDeps; -} - namespace { template inline bool mergeDependencies(std::vector& first, const std::vector& second) @@ -762,29 +702,35 @@ void createHelper::_validateDAS(ossie::ApplicationPlacement& appPlacement, } } -void createHelper::_matchImplementations(PlacementList::const_iterator comp, - PlacementList::const_iterator end, - CollocationList& matches, - const ImplementationList& current, - const ProcessorList& processorDeps, - const OSList& osDeps) +bool createHelper::placeHostCollocation(ossie::ApplicationDeployment& appDeployment, + const DeploymentList& components, + DeploymentList::const_iterator current, + ossie::DeviceList& deploymentDevices, + const ProcessorList& processorDeps, + const OSList& osDeps) { - if (comp == end) { - // Reached the end of the components, 'current' is a valid and complete - // set of implementations - matches.push_back(current); - return; + if (current == components.end()) { + // Reached the end of the component deployments; all implementations + // should be set, so give it a try + return allocateHostCollocation(appDeployment, components, deploymentDevices, processorDeps, osDeps); } // Try all of the implementations from the current component for matches // with the processor and OS dependencies - const ImplementationList& comp_impls = (*comp)->getImplementations(); - ++comp; + ossie::ComponentDeployment* deployment = *current; + const ImplementationList& comp_impls = deployment->getComponent()->getImplementations(); + LOG_TRACE(ApplicationFactory_impl, "Finding collocation-compatible implementations for component " + << deployment->getComponent()->getInstantiationIdentifier()); + ++current; for (ImplementationList::const_iterator impl = comp_impls.begin(); impl != comp_impls.end(); ++impl) { + LOG_TRACE(ApplicationFactory_impl, "Checking implementation " << (*impl)->getId()); + // Check that the processor dependencies are compatible, filtering out // anything not compatible with the current component std::vector proc_list = processorDeps;; if (!mergeDependencies(proc_list, (*impl)->getProcessorDeps())) { + LOG_TRACE(ApplicationFactory_impl, "Skipping implementation " << (*impl)->getId() + << ": no processor match"); continue; } @@ -792,50 +738,89 @@ void createHelper::_matchImplementations(PlacementList::const_iterator comp, // anything not compatible with the current component std::vector os_list = osDeps; if (!mergeDependencies(os_list, (*impl)->getOsDeps())) { + LOG_TRACE(ApplicationFactory_impl, "Skipping implementation " << (*impl)->getId() << ": no OS match"); continue; } - // Add this implementation to the pontential matches and recurse one - // more level - ImplementationList match = current; - match.push_back(*impl); - _matchImplementations(comp, end, matches, match, proc_list, os_list); + // Set this implementation for deployment and recurse one more level + deployment->setImplementation(*impl); + if (placeHostCollocation(appDeployment, components, current, deploymentDevices, proc_list, os_list)) { + return true; + } } + + return false; } -void createHelper::_consolidateAllocations(const ossie::ImplementationInfo::List& impls, CF::Properties& allocs) +bool createHelper::allocateHostCollocation(ossie::ApplicationDeployment& appDeployment, + const DeploymentList& components, + ossie::DeviceList& deploymentDevices, + const ProcessorList& processorDeps, + const OSList& osDeps) { - allocs.length(0); - for (ossie::ImplementationInfo::List::const_iterator impl= impls.begin(); impl != impls.end(); ++impl) { - const std::vector& deps = (*impl)->getDependencyProperties(); + // Consolidate the allocation properties into a single list + CF::Properties allocationProperties = _consolidateAllocations(components); + + LOG_TRACE(ApplicationFactory_impl, "Allocating deployment for " << components.size() + << " collocated components"); + for (DeploymentList::const_iterator depl = components.begin(); depl != components.end(); ++depl) { + LOG_TRACE(ApplicationFactory_impl, "Component " << (*depl)->getComponent()->getInstantiationIdentifier() + << " implementation " << (*depl)->getImplementation()->getId()); + } + + const std::string requestid = ossie::generateUUID(); + ossie::AllocationResult response = _allocationMgr->allocateDeployment(requestid, allocationProperties, deploymentDevices, appDeployment.getIdentifier(), processorDeps, osDeps); + if (!response.first.empty()) { + // Ensure that all capacities get cleaned up + _allocations.push_back(response.first); + + // Convert from response back into a device node + boost::shared_ptr& node = response.second; + const std::string& deviceId = node->identifier; + + for (DeploymentList::const_iterator depl = components.begin(); depl != components.end(); ++depl) { + if (!resolveSoftpkgDependencies(*depl, *node)) { + LOG_TRACE(ApplicationFactory_impl, "Unable to resolve softpackage dependencies for component " + << (*depl)->getComponent()->getIdentifier() + << " implementation " << (*depl)->getImplementation()->getId()); + (*depl)->clearDependencies(); + return false; + } + (*depl)->setAssignedDevice(node); + } + + // Move the device to the front of the list + rotateDeviceList(_executableDevices, deviceId); + + LOG_TRACE(ApplicationFactory_impl, "Successful collocation allocation"); + return true; + } + LOG_TRACE(ApplicationFactory_impl, "Failed collocation allocation"); + return false; + } + +CF::Properties createHelper::_consolidateAllocations(const DeploymentList& deployments) +{ + CF::Properties allocs; + for (DeploymentList::const_iterator depl = deployments.begin(); depl != deployments.end(); ++depl) { + const std::vector& deps = (*depl)->getImplementation()->getDependencyProperties(); for (std::vector::const_iterator dep = deps.begin(); dep != deps.end(); ++dep) { ossie::ComponentProperty *prop = dep->property.get(); - if (dynamic_cast( prop ) != NULL) { - const SimplePropertyRef* dependency = dynamic_cast(prop); - ossie::corba::push_back(allocs, convertPropertyToDataType(dependency)); - } else if (dynamic_cast(prop) != NULL) { - const SimpleSequencePropertyRef* dependency = dynamic_cast(prop); - ossie::corba::push_back(allocs, convertPropertyToDataType(dependency)); - } else if (dynamic_cast(prop) != NULL) { - const ossie::StructPropertyRef* dependency = dynamic_cast(prop); - ossie::corba::push_back(allocs, convertPropertyToDataType(dependency)); - } else if (dynamic_cast(prop) != NULL) { - const ossie::StructSequencePropertyRef* dependency = dynamic_cast(prop); - ossie::corba::push_back(allocs, convertPropertyToDataType(dependency)); - } + ossie::corba::push_back(allocs, ossie::convertPropertyRefToDataType(prop)); } } + return allocs; } void createHelper::_placeHostCollocation(ossie::ApplicationDeployment& appDeployment, - const PlacementList& collocatedComponents, + const PlacementList& components, const DeviceAssignmentMap& devices) { // Keep track of devices to which some of the components have // been assigned. DeviceIDList assignedDevices; - for (PlacementList::const_iterator placement = collocatedComponents.begin(); - placement != collocatedComponents.end(); + for (PlacementList::const_iterator placement = components.begin(); + placement != components.end(); ++placement) { DeviceAssignmentMap::const_iterator device = devices.find((*placement)->getInstantiationIdentifier()); if (device != devices.end()) { @@ -843,16 +828,6 @@ void createHelper::_placeHostCollocation(ossie::ApplicationDeployment& appDeploy } } - LOG_TRACE(ApplicationFactory_impl, "Placing " << collocatedComponents.size() << " components"); - - // create every combination of implementations for the components in the set - // for each combination: - // consolidate allocations - // attempt allocation - // if the allocation succeeds, break the loop - CollocationList res_vec; - _matchImplementations(collocatedComponents.begin(), collocatedComponents.end(), res_vec); - // Get the executable devices for the domain; if there were any devices // assigned, filter out all other devices ossie::DeviceList deploymentDevices = _executableDevices; @@ -864,51 +839,22 @@ void createHelper::_placeHostCollocation(ossie::ApplicationDeployment& appDeploy } } + LOG_TRACE(ApplicationFactory_impl, "Placing " << components.size() << " components"); - for (size_t index = 0; index < res_vec.size(); ++index) { - // Merge processor and OS dependencies from all implementations - std::vector processorDeps = mergeProcessorDeps(res_vec[index]); - std::vector osDeps = mergeOsDeps(res_vec[index]); - - // Consolidate the allocation properties into a single list - CF::Properties allocationProperties; - this->_consolidateAllocations(res_vec[index], allocationProperties); - - const std::string requestid = ossie::generateUUID(); - ossie::AllocationResult response = this->_allocationMgr->allocateDeployment(requestid, allocationProperties, deploymentDevices, appDeployment.getIdentifier(), processorDeps, osDeps); - if (!response.first.empty()) { - // Ensure that all capacities get cleaned up - this->_allocations.push_back(response.first); - - // Convert from response back into a device node - boost::shared_ptr& node = response.second; - const std::string& deviceId = node->identifier; - - PlacementList::const_iterator comp = collocatedComponents.begin(); - ossie::ImplementationInfo::List::iterator impl = res_vec[index].begin(); - for (; comp != collocatedComponents.end(); ++comp, ++impl) { - ossie::ComponentDeployment* deployment = new ossie::ComponentDeployment(*comp, *impl); - deployment->setAssignedDevice(node); - if (!resolveSoftpkgDependencies(deployment, *node)) { - LOG_TRACE(ApplicationFactory_impl, "Unable to resolve softpackage dependencies for component " - << (*comp)->getIdentifier() << " implementation " << (*impl)->getId()); - delete deployment; - continue; - } - appDeployment.addComponentDeployment(deployment); - } - - // Move the device to the front of the list - rotateDeviceList(_executableDevices, deviceId); - return; - } + DeploymentList deployments; + for (PlacementList::const_iterator comp = components.begin(); comp != components.end(); ++comp) { + ossie::ComponentDeployment* deployment = new ossie::ComponentDeployment(*comp, 0); + deployments.push_back(deployment); + appDeployment.addComponentDeployment(deployment); } - std::ostringstream eout; - //eout << "Could not collocate components for collocation NAME: " << collocation.getName() << " ID:" << collocation.id; - eout << "Could not collocate components for collocation"; - LOG_ERROR(ApplicationFactory_impl, eout.str()); - throw CF::ApplicationFactory::CreateApplicationRequestError(); + if (!placeHostCollocation(appDeployment, deployments, deployments.begin(), deploymentDevices)) { + std::ostringstream eout; + //eout << "Could not collocate components for collocation NAME: " << collocation.getName() << " ID:" << collocation.id; + eout << "Could not collocate components for collocation"; + LOG_ERROR(ApplicationFactory_impl, eout.str()); + throw CF::ApplicationFactory::CreateApplicationRequestError(); + } } void createHelper::_handleUsesDevices(ossie::ApplicationPlacement& appPlacement, diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index 853fb0bd4..7c41fb054 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -88,9 +88,7 @@ SoftpkgDeployment::SoftpkgDeployment(SoftpkgInfo* softpkg, const ImplementationI SoftpkgDeployment::~SoftpkgDeployment() { - for (DeploymentList::iterator dependency = dependencies.begin(); dependency != dependencies.end(); ++dependency) { - delete (*dependency); - } + clearDependencies(); } SoftpkgInfo* SoftpkgDeployment::getSoftpkg() @@ -98,6 +96,11 @@ SoftpkgInfo* SoftpkgDeployment::getSoftpkg() return softpkg; } +void SoftpkgDeployment::setImplementation(const ImplementationInfo* implementation) +{ + this->implementation = implementation; +} + const ImplementationInfo* SoftpkgDeployment::getImplementation() const { return implementation; @@ -113,6 +116,14 @@ const std::vector& SoftpkgDeployment::getDependencies() return dependencies; } +void SoftpkgDeployment::clearDependencies() +{ + for (DeploymentList::iterator dependency = dependencies.begin(); dependency != dependencies.end(); ++dependency) { + delete (*dependency); + } + dependencies.clear(); +} + std::vector SoftpkgDeployment::getDependencyLocalFiles() { std::vector files; diff --git a/redhawk/src/control/sdr/dommgr/Deployment.h b/redhawk/src/control/sdr/dommgr/Deployment.h index 28dec2fd1..8e83770ab 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.h +++ b/redhawk/src/control/sdr/dommgr/Deployment.h @@ -73,12 +73,15 @@ namespace ossie { ~SoftpkgDeployment(); SoftpkgInfo* getSoftpkg(); + + void setImplementation(const ImplementationInfo* implementation); const ImplementationInfo* getImplementation() const; std::string getLocalFile(); void addDependency(SoftpkgDeployment* dependency); const DeploymentList& getDependencies(); + void clearDependencies(); std::vector getDependencyLocalFiles(); diff --git a/redhawk/src/control/sdr/dommgr/createHelper.h b/redhawk/src/control/sdr/dommgr/createHelper.h index 8a4a845c4..7f6339a72 100644 --- a/redhawk/src/control/sdr/dommgr/createHelper.h +++ b/redhawk/src/control/sdr/dommgr/createHelper.h @@ -100,6 +100,10 @@ class createHelper ossie::ApplicationInfo _appInfo; typedef std::vector DeploymentList; + typedef ossie::ImplementationInfo::List ImplementationList; + typedef std::vector CollocationList; + typedef std::vector ProcessorList; + typedef std::vector OSList; // createHelper helper methods void overrideExternalProperties(ossie::ApplicationPlacement& appPlacement, @@ -120,21 +124,17 @@ class createHelper void _placeHostCollocation(ossie::ApplicationDeployment& appDeployment, const PlacementList& collocatedComponents, const DeviceAssignmentMap& devices); + bool placeHostCollocation(ossie::ApplicationDeployment& appDeployment, + const DeploymentList& components, + DeploymentList::const_iterator current, + ossie::DeviceList& deploymentDevices, + const ProcessorList& processorDeps=ProcessorList(), + const OSList& osDeps=OSList()); void _handleUsesDevices(ossie::ApplicationPlacement& appPlacement, ossie::ApplicationDeployment& appDeployment, const std::string& appName); - typedef ossie::ImplementationInfo::List ImplementationList; - typedef std::vector CollocationList; - typedef std::vector ProcessorList; - typedef std::vector OSList; - void _matchImplementations(PlacementList::const_iterator comp, - PlacementList::const_iterator end, - CollocationList& matches, - const ImplementationList& current=ImplementationList(), - const ProcessorList& processorDeps=ProcessorList(), - const OSList& osDeps=OSList()); - void _consolidateAllocations(const ossie::ImplementationInfo::List& implementations, CF::Properties& allocs); + CF::Properties _consolidateAllocations(const DeploymentList& implementations); void _evaluateMATHinRequest(CF::Properties &request, const CF::Properties &configureProperties); void _castRequestProperties(CF::Properties& allocationProperties, const std::vector &prop_refs, unsigned int offset=0); void _castRequestProperties(CF::Properties& allocationProperties, const std::vector &prop_refs, @@ -164,6 +164,12 @@ class createHelper const std::string& assignedDeviceId, const std::string& appIdentifier); + bool allocateHostCollocation(ossie::ApplicationDeployment& appDeployment, + const DeploymentList& components, + ossie::DeviceList& deploymentDevices, + const ProcessorList& processorDeps, + const OSList& osDeps); + bool resolveSoftpkgDependencies(ossie::SoftpkgDeployment* deployment, ossie::DeviceNode& device); ossie::SoftpkgDeployment* resolveDependencyImplementation(ossie::SoftpkgInfo* softpkg, ossie::DeviceNode& device); From 42009c1ea9c4056fa74476a658d0c1aff3dd5f54 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 17 May 2016 09:39:17 -0400 Subject: [PATCH 0232/1644] Don't transfer ownership of allocations until all collocated components' dependencies are resolved (probably rare, but technically possible); clear results from a prior run before attempting to re-resolve the dependencies instead of clearing just the failed component after an unsuccessful attempt --- .../control/sdr/dommgr/ApplicationFactory_impl.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 0d4a8adeb..02e7f8362 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -771,24 +771,32 @@ bool createHelper::allocateHostCollocation(ossie::ApplicationDeployment& appDepl const std::string requestid = ossie::generateUUID(); ossie::AllocationResult response = _allocationMgr->allocateDeployment(requestid, allocationProperties, deploymentDevices, appDeployment.getIdentifier(), processorDeps, osDeps); if (!response.first.empty()) { - // Ensure that all capacities get cleaned up - _allocations.push_back(response.first); + // Ensure that all capacities get cleaned up, keeping ownership local + // to this scope until it's clear that the device can support all of + // the collocated components' dependencies + ScopedAllocations local_allocations(*_allocationMgr); + local_allocations.push_back(response.first); // Convert from response back into a device node boost::shared_ptr& node = response.second; const std::string& deviceId = node->identifier; for (DeploymentList::const_iterator depl = components.begin(); depl != components.end(); ++depl) { + // Reset any dependencies that may have been resolved in a prior attempt + (*depl)->clearDependencies(); if (!resolveSoftpkgDependencies(*depl, *node)) { LOG_TRACE(ApplicationFactory_impl, "Unable to resolve softpackage dependencies for component " << (*depl)->getComponent()->getIdentifier() << " implementation " << (*depl)->getImplementation()->getId()); - (*depl)->clearDependencies(); return false; } (*depl)->setAssignedDevice(node); } + // Once all the dependencies have been resolved, take ownership of the + // allocations + local_allocations.transfer(_allocations); + // Move the device to the front of the list rotateDeviceList(_executableDevices, deviceId); From 830fd4ae22d45092a7c776a384129685e0c1fe63 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 17 May 2016 16:14:30 -0400 Subject: [PATCH 0233/1644] Merge ApplicationPlacement into ApplicationDeployment class --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 55 ++++---- redhawk/src/control/sdr/dommgr/Deployment.cpp | 89 +++++++++++++ redhawk/src/control/sdr/dommgr/Deployment.h | 34 +++++ redhawk/src/control/sdr/dommgr/Makefile.am | 1 - redhawk/src/control/sdr/dommgr/Placement.cpp | 118 ------------------ redhawk/src/control/sdr/dommgr/Placement.h | 77 ------------ redhawk/src/control/sdr/dommgr/createHelper.h | 13 +- 7 files changed, 154 insertions(+), 233 deletions(-) delete mode 100644 redhawk/src/control/sdr/dommgr/Placement.cpp delete mode 100644 redhawk/src/control/sdr/dommgr/Placement.h diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 02e7f8362..940e5495e 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -650,12 +650,11 @@ void createHelper::_configureComponents(const DeploymentList& deployments) CF::ApplicationFactory::CreateApplicationError(CF::CF_EINVAL, "Configure of component failed (unclear where in the process this occurred)")) } -void createHelper::assignPlacementsToDevices(ossie::ApplicationPlacement& appPlacement, - ossie::ApplicationDeployment& appDeployment, +void createHelper::assignPlacementsToDevices(ossie::ApplicationDeployment& appDeployment, const DeviceAssignmentMap& devices) { - typedef ossie::ApplicationPlacement::PlacementList PlacementPlanList; - const PlacementPlanList& placements = appPlacement.getPlacements(); + typedef ossie::ApplicationDeployment::PlacementList PlacementPlanList; + const PlacementPlanList& placements = appDeployment.getPlacements(); for (PlacementPlanList::const_iterator plan = placements.begin(); plan != placements.end(); ++plan) { const std::vector& components = (*plan)->getComponents(); if (components.size() > 1) { @@ -679,7 +678,7 @@ void createHelper::assignPlacementsToDevices(ossie::ApplicationPlacement& appPla } } -void createHelper::_validateDAS(ossie::ApplicationPlacement& appPlacement, +void createHelper::_validateDAS(ossie::ApplicationDeployment& appDeployment, const DeviceAssignmentMap& deviceAssignments) { LOG_TRACE(ApplicationFactory_impl, "Validating device assignment sequence (length " @@ -687,7 +686,7 @@ void createHelper::_validateDAS(ossie::ApplicationPlacement& appPlacement, for (DeviceAssignmentMap::const_iterator ii = deviceAssignments.begin(); ii != deviceAssignments.end(); ++ii) { const std::string& componentId = ii->first; const std::string& assignedDeviceId = ii->second; - ossie::ComponentInfo* component = appPlacement.getComponent(componentId); + ossie::ComponentInfo* component = appDeployment.getComponent(componentId); if (!component) { LOG_ERROR(ApplicationFactory_impl, "Failed to create application; " @@ -865,8 +864,7 @@ void createHelper::_placeHostCollocation(ossie::ApplicationDeployment& appDeploy } } -void createHelper::_handleUsesDevices(ossie::ApplicationPlacement& appPlacement, - ossie::ApplicationDeployment& appDeployment, +void createHelper::_handleUsesDevices(ossie::ApplicationDeployment& appDeployment, const std::string& appName) { // Gets all uses device info from the SAD file @@ -876,7 +874,7 @@ void createHelper::_handleUsesDevices(ossie::ApplicationPlacement& appPlacement, // Get the assembly controller's configure properties for context in the // allocations CF::Properties appProperties; - ossie::ComponentInfo* assembly_controller = appPlacement.getAssemblyController(); + ossie::ComponentInfo* assembly_controller = appDeployment.getAssemblyController(); if (assembly_controller) { appProperties = assembly_controller->getConfigureProperties(); } @@ -1188,12 +1186,19 @@ CF::Application_ptr createHelper::create ( rotateDeviceList(_executableDevices, lastExecutableDevice); } + // Give the application a unique identifier of the form + // "softwareassemblyid:ApplicationName", where the application + // name includes the serial number generated for the naming context + // (e.g. "Application_1"). + std::string appIdentifier = + _appFact._identifier + ":" + _waveformContextName; + ////////////////////////////////////////////////// // Load the components to instantiate from the SAD - ossie::ApplicationPlacement placement; - getRequiredComponents(_appFact._fileMgr, _appFact._sadParser, placement); + ossie::ApplicationDeployment app_deployment(appIdentifier); + getRequiredComponents(_appFact._fileMgr, _appFact._sadParser, app_deployment); - ossie::ComponentInfo* assemblyControllerComponent = placement.getAssemblyController(); + ossie::ComponentInfo* assemblyControllerComponent = app_deployment.getAssemblyController(); if (assemblyControllerComponent) { overrideProperties(modifiedInitConfiguration, assemblyControllerComponent); } @@ -1202,28 +1207,20 @@ CF::Application_ptr createHelper::create ( // Store information about this application _appInfo.populateApplicationInfo(_appFact._sadParser); - overrideExternalProperties(placement, modifiedInitConfiguration); - - // Give the application a unique identifier of the form - // "softwareassemblyid:ApplicationName", where the application - // name includes the serial number generated for the naming context - // (e.g. "Application_1"). - std::string appIdentifier = - _appFact._identifier + ":" + _waveformContextName; + overrideExternalProperties(app_deployment, modifiedInitConfiguration); //////////////////////////////////////////////// // Assign components to devices //////////////////////////////////////////////// - ossie::ApplicationDeployment app_deployment(appIdentifier); // Allocate any usesdevice capacities specified in the SAD file - _handleUsesDevices(placement, app_deployment, name); + _handleUsesDevices(app_deployment, name); // Catch invalid device assignments - _validateDAS(placement, deviceAssignments); + _validateDAS(app_deployment, deviceAssignments); // Assign all components to devices - assignPlacementsToDevices(placement, app_deployment, deviceAssignments); + assignPlacementsToDevices(app_deployment, deviceAssignments); // Assign CPU reservations to components const DeploymentList& deployments = app_deployment.getComponentDeployments(); @@ -1358,7 +1355,7 @@ CF::Application_ptr createHelper::create ( return appObj._retn(); } -void createHelper::overrideExternalProperties(ossie::ApplicationPlacement& appPlacement, +void createHelper::overrideExternalProperties(ossie::ApplicationDeployment& appDeployment, const CF::Properties& initConfiguration) { const std::vector& props = _appFact._sadParser.getExternalProperties(); @@ -1373,7 +1370,7 @@ void createHelper::overrideExternalProperties(ossie::ApplicationPlacement& appPl } if (id == static_cast(initConfiguration[i].id)) { - ComponentInfo *comp = appPlacement.getComponent(prop->comprefid); + ComponentInfo *comp = appDeployment.getComponent(prop->comprefid); // Only configure on non AC components if (comp != 0 && !comp->isAssemblyController()) { comp->overrideProperty(prop->propid.c_str(), initConfiguration[i].value); @@ -1971,7 +1968,7 @@ ossie::ComponentInfo* createHelper::buildComponentInfo(CF::FileSystem_ptr fileSy */ void createHelper::getRequiredComponents(CF::FileSystem_ptr fileSys, const SoftwareAssembly& sadParser, - ossie::ApplicationPlacement& appPlacement) + ossie::ApplicationDeployment& appDeployment) { TRACE_ENTER(ApplicationFactory_impl); @@ -1985,7 +1982,7 @@ void createHelper::getRequiredComponents(CF::FileSystem_ptr fileSys, LOG_TRACE(ApplicationFactory_impl, "Building component info for host collocation " << collocation.getID()); ossie::PlacementPlan* plan = new ossie::PlacementPlan(collocation.getID(), collocation.getName()); - appPlacement.addPlacement(plan); + appDeployment.addPlacement(plan); const std::vector& placements = collocations[index].getComponents(); for (unsigned int i = 0; i < placements.size(); i++) { @@ -2001,7 +1998,7 @@ void createHelper::getRequiredComponents(CF::FileSystem_ptr fileSys, const std::vector& componentsFromSAD = sadParser.getComponentPlacements(); for (unsigned int i = 0; i < componentsFromSAD.size(); i++) { ossie::PlacementPlan* plan = new ossie::PlacementPlan(); - appPlacement.addPlacement(plan); + appDeployment.addPlacement(plan); ossie::ComponentInfo* component = buildComponentInfo(fileSys, sadParser, componentsFromSAD[i]); if (component->getInstantiationIdentifier() == assemblyControllerRefId) { component->setIsAssemblyController(true); diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index 7c41fb054..b2641484b 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -297,6 +297,56 @@ CF::Resource_ptr ComponentDeployment::getResourcePtr() const return CF::Resource::_duplicate(resource); } + +PlacementPlan::PlacementPlan() +{ +} + +PlacementPlan::~PlacementPlan() +{ + for (ComponentList::iterator comp = components.begin(); comp != components.end(); ++comp) { + delete *comp; + } +} + +PlacementPlan::PlacementPlan(const std::string& id, const std::string& name) : + id(id), + name(name) +{ +} + +const std::string& PlacementPlan::getId() const +{ + return id; +} + +const std::string& PlacementPlan::getName() const +{ + return name; +} + +const PlacementPlan::ComponentList& PlacementPlan::getComponents() const +{ + return components; +} + +void PlacementPlan::addComponent(ComponentInfo* component) +{ + components.push_back(component); +} + +ComponentInfo* PlacementPlan::getComponent(const std::string& instantiationId) +{ + for (ComponentList::iterator comp = components.begin(); comp != components.end(); ++comp) { + if (instantiationId == (*comp)->getInstantiationIdentifier()) { + return *comp; + } + } + + return 0; +} + + ApplicationDeployment::ApplicationDeployment(const std::string& identifier) : identifier(identifier) { @@ -307,6 +357,9 @@ ApplicationDeployment::~ApplicationDeployment() for (ComponentList::iterator comp = components.begin(); comp != components.end(); ++comp) { delete *comp; } + for (std::vector::iterator place = placements.begin(); place != placements.end(); ++place) { + delete (*place); + } } const std::string& ApplicationDeployment::getIdentifier() const @@ -314,6 +367,42 @@ const std::string& ApplicationDeployment::getIdentifier() const return identifier; } +void ApplicationDeployment::addPlacement(PlacementPlan* placement) +{ + placements.push_back(placement); +} + +const std::vector& ApplicationDeployment::getPlacements() const +{ + return placements; +} + +ComponentInfo* ApplicationDeployment::getComponent(const std::string& instantiationId) +{ + for (PlacementList::iterator placement = placements.begin(); placement != placements.end(); ++placement) { + ComponentInfo* component = (*placement)->getComponent(instantiationId); + if (component) { + return component; + } + } + + return 0; +} + +ComponentInfo* ApplicationDeployment::getAssemblyController() +{ + for (PlacementList::iterator placement = placements.begin(); placement != placements.end(); ++placement) { + const std::vector& components = (*placement)->getComponents(); + for (std::vector::const_iterator comp = components.begin(); comp != components.end(); ++comp) { + if ((*comp)->isAssemblyController()) { + return *comp; + } + } + } + + return 0; +} + void ApplicationDeployment::addComponentDeployment(ComponentDeployment* deployment) { components.push_back(deployment); diff --git a/redhawk/src/control/sdr/dommgr/Deployment.h b/redhawk/src/control/sdr/dommgr/Deployment.h index 8e83770ab..fd3a8b190 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.h +++ b/redhawk/src/control/sdr/dommgr/Deployment.h @@ -131,9 +131,34 @@ namespace ossie { redhawk::PropertyMap affinityOptions; }; + class PlacementPlan + { + public: + typedef std::vector ComponentList; + + PlacementPlan(); + PlacementPlan(const std::string& id, const std::string& name); + ~PlacementPlan(); + + const std::string& getId() const; + const std::string& getName() const; + + const ComponentList& getComponents() const; + + void addComponent(ComponentInfo* component); + + ComponentInfo* getComponent(const std::string& instantiationId); + + protected: + std::string id; + std::string name; + ComponentList components; + }; + class ApplicationDeployment : public ComponentLookup, public DeviceLookup, public UsesDeviceDeployment { public: + typedef std::vector PlacementList; typedef std::vector ComponentList; ApplicationDeployment(const std::string& identifier); @@ -141,6 +166,14 @@ namespace ossie { const std::string& getIdentifier() const; + void addPlacement(PlacementPlan* placement); + + const PlacementList& getPlacements() const; + + ComponentInfo* getAssemblyController(); + + ComponentInfo* getComponent(const std::string& instantiationId); + void addComponentDeployment(ComponentDeployment* deployment); const ComponentList& getComponentDeployments(); ComponentDeployment* getComponentDeployment(const std::string& instantiationId); @@ -158,6 +191,7 @@ namespace ossie { protected: const std::string identifier; + PlacementList placements; ComponentList components; }; } diff --git a/redhawk/src/control/sdr/dommgr/Makefile.am b/redhawk/src/control/sdr/dommgr/Makefile.am index 031870d37..266099569 100644 --- a/redhawk/src/control/sdr/dommgr/Makefile.am +++ b/redhawk/src/control/sdr/dommgr/Makefile.am @@ -34,7 +34,6 @@ DomainManager_SOURCES = applicationSupport.cpp \ RH_NamingContext.cpp \ DomainManager_impl.cpp \ FakeApplication.cpp \ - Placement.cpp \ Deployment.cpp \ main.cpp DomainManager_CPPFLAGS = -I../../include -I../../parser -I$(top_srcdir)/base/include -I$(top_srcdir)/base $(BOOST_CPPFLAGS) $(OMNIORB_CFLAGS) $(LOG4CXX_FLAGS) diff --git a/redhawk/src/control/sdr/dommgr/Placement.cpp b/redhawk/src/control/sdr/dommgr/Placement.cpp deleted file mode 100644 index cccc18532..000000000 --- a/redhawk/src/control/sdr/dommgr/Placement.cpp +++ /dev/null @@ -1,118 +0,0 @@ -/* - * This file is protected by Copyright. Please refer to the COPYRIGHT file - * distributed with this source distribution. - * - * This file is part of REDHAWK core. - * - * REDHAWK core is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see http://www.gnu.org/licenses/. - */ - -#include "Placement.h" - -using namespace ossie; - -PlacementPlan::PlacementPlan() -{ -} - -PlacementPlan::~PlacementPlan() -{ - for (ComponentList::iterator comp = components.begin(); comp != components.end(); ++comp) { - delete *comp; - } -} - -PlacementPlan::PlacementPlan(const std::string& id, const std::string& name) : - id(id), - name(name) -{ -} - -const std::string& PlacementPlan::getId() const -{ - return id; -} - -const std::string& PlacementPlan::getName() const -{ - return name; -} - -const PlacementPlan::ComponentList& PlacementPlan::getComponents() const -{ - return components; -} - -void PlacementPlan::addComponent(ComponentInfo* component) -{ - components.push_back(component); -} - -ComponentInfo* PlacementPlan::getComponent(const std::string& instantiationId) -{ - for (ComponentList::iterator comp = components.begin(); comp != components.end(); ++comp) { - if (instantiationId == (*comp)->getInstantiationIdentifier()) { - return *comp; - } - } - - return 0; -} - -ApplicationPlacement::ApplicationPlacement() -{ -} - -ApplicationPlacement::~ApplicationPlacement() -{ - for (std::vector::iterator place = placements.begin(); place != placements.end(); ++place) { - delete (*place); - } -} - -void ApplicationPlacement::addPlacement(PlacementPlan* placement) -{ - placements.push_back(placement); -} - -const std::vector& ApplicationPlacement::getPlacements() const -{ - return placements; -} - -ComponentInfo* ApplicationPlacement::getComponent(const std::string& instantiationId) -{ - for (PlacementList::iterator placement = placements.begin(); placement != placements.end(); ++placement) { - ComponentInfo* component = (*placement)->getComponent(instantiationId); - if (component) { - return component; - } - } - - return 0; -} - -ComponentInfo* ApplicationPlacement::getAssemblyController() -{ - for (PlacementList::iterator placement = placements.begin(); placement != placements.end(); ++placement) { - const std::vector& components = (*placement)->getComponents(); - for (std::vector::const_iterator comp = components.begin(); comp != components.end(); ++comp) { - if ((*comp)->isAssemblyController()) { - return *comp; - } - } - } - - return 0; -} diff --git a/redhawk/src/control/sdr/dommgr/Placement.h b/redhawk/src/control/sdr/dommgr/Placement.h deleted file mode 100644 index bb0108729..000000000 --- a/redhawk/src/control/sdr/dommgr/Placement.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * This file is protected by Copyright. Please refer to the COPYRIGHT file - * distributed with this source distribution. - * - * This file is part of REDHAWK core. - * - * REDHAWK core is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see http://www.gnu.org/licenses/. - */ - -#ifndef PLACEMENT_H -#define PLACEMENT_H - -#include -#include - -#include "applicationSupport.h" - -namespace ossie { - - class PlacementPlan - { - public: - typedef std::vector ComponentList; - - PlacementPlan(); - PlacementPlan(const std::string& id, const std::string& name); - ~PlacementPlan(); - - const std::string& getId() const; - const std::string& getName() const; - - const ComponentList& getComponents() const; - - void addComponent(ComponentInfo* component); - - ComponentInfo* getComponent(const std::string& instantiationId); - - protected: - std::string id; - std::string name; - ComponentList components; - }; - - class ApplicationPlacement - { - public: - typedef std::vector PlacementList; - - ApplicationPlacement(); - ~ApplicationPlacement(); - - void addPlacement(PlacementPlan* placement); - - const PlacementList& getPlacements() const; - - ComponentInfo* getAssemblyController(); - - ComponentInfo* getComponent(const std::string& instantiationId); - - protected: - PlacementList placements; - }; - -} - -#endif // PLACEMENT_H diff --git a/redhawk/src/control/sdr/dommgr/createHelper.h b/redhawk/src/control/sdr/dommgr/createHelper.h index 7f6339a72..cc630420a 100644 --- a/redhawk/src/control/sdr/dommgr/createHelper.h +++ b/redhawk/src/control/sdr/dommgr/createHelper.h @@ -27,7 +27,6 @@ #include "PersistenceStore.h" #include "applicationSupport.h" -#include "Placement.h" #include "Deployment.h" class Application_impl; @@ -106,13 +105,12 @@ class createHelper typedef std::vector OSList; // createHelper helper methods - void overrideExternalProperties(ossie::ApplicationPlacement& appPlacement, + void overrideExternalProperties(ossie::ApplicationDeployment& appDeployment, const CF::Properties& initConfiguration); void overrideProperties(const CF::Properties& initConfiguration, ossie::ComponentInfo* component); - void assignPlacementsToDevices(ossie::ApplicationPlacement& appPlacement, - ossie::ApplicationDeployment& appDeployment, + void assignPlacementsToDevices(ossie::ApplicationDeployment& appDeployment, const DeviceAssignmentMap& devices); - void _validateDAS(ossie::ApplicationPlacement& appPlacement, const DeviceAssignmentMap& deviceAssignments); + void _validateDAS(ossie::ApplicationDeployment& appDeployment, const DeviceAssignmentMap& deviceAssignments); void _connectComponents(ossie::ApplicationDeployment& appDeployment, std::vector& connections); void _configureComponents(const DeploymentList& deployments); @@ -130,8 +128,7 @@ class createHelper ossie::DeviceList& deploymentDevices, const ProcessorList& processorDeps=ProcessorList(), const OSList& osDeps=OSList()); - void _handleUsesDevices(ossie::ApplicationPlacement& appPlacement, - ossie::ApplicationDeployment& appDeployment, + void _handleUsesDevices(ossie::ApplicationDeployment& appDeployment, const std::string& appName); CF::Properties _consolidateAllocations(const DeploymentList& implementations); @@ -143,7 +140,7 @@ class createHelper // Populate _requiredComponents vector void getRequiredComponents(CF::FileSystem_ptr fileSys, const ossie::SoftwareAssembly& sadParser, - ossie::ApplicationPlacement& appPlacement); + ossie::ApplicationDeployment& appDeployment); ossie::ComponentInfo* buildComponentInfo(CF::FileSystem_ptr fileSys, const ossie::SoftwareAssembly& sadParser, const ossie::ComponentPlacement& component); From 02b584e8b657e1d9cc5e8e6925241276efa624bb Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 18 May 2016 12:32:12 -0400 Subject: [PATCH 0234/1644] Move responsibility for performing load to deployment classes --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 69 ++++--------------- redhawk/src/control/sdr/dommgr/Deployment.cpp | 53 ++++++++++++++ redhawk/src/control/sdr/dommgr/Deployment.h | 8 +++ redhawk/src/control/sdr/dommgr/createHelper.h | 4 -- 4 files changed, 74 insertions(+), 60 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 940e5495e..c5dc84c9a 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -2068,36 +2068,6 @@ string ApplicationFactory_impl::getBaseWaveformContext(string waveform_context) return base_naming_context; } -void createHelper::loadDependencies(const ossie::ComponentInfo& component, - CF::LoadableDevice_ptr device, - const std::vector& dependencies) -{ - for (std::vector::const_iterator deployment = dependencies.begin(); deployment != dependencies.end(); ++deployment) { - ossie::SoftpkgInfo* dep = (*deployment)->getSoftpkg(); - const ossie::ImplementationInfo* implementation = (*deployment)->getImplementation(); - if (!implementation) { - LOG_ERROR(ApplicationFactory_impl, "No implementation selected for dependency " << dep->getName()); - throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EINVAL, "Missing implementation"); - } - - // Recursively load dependencies - LOG_TRACE(ApplicationFactory_impl, "Loading dependencies for soft package " << dep->getName()); - loadDependencies(component, device, (*deployment)->getDependencies()); - - // Determine absolute path of dependency's local file - CF::LoadableDevice::LoadType codeType = implementation->getCodeType(); - const std::string fileName = (*deployment)->getLocalFile(); - LOG_DEBUG(ApplicationFactory_impl, "Loading dependency local file " << fileName); - try { - device->load(_appFact._fileMgr, fileName.c_str(), codeType); - } catch (...) { - LOG_ERROR(ApplicationFactory_impl, "Failure loading file " << fileName); - throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EINVAL, "Failed to load file"); - } - _application->addComponentLoadedFile(component.getIdentifier(), fileName); - } -} - /* Perform 'load' and 'execute' operations to launch component on the assigned device * - Actually loads and executes the component on the given device */ @@ -2158,36 +2128,23 @@ void createHelper::loadAndExecuteComponents(const DeploymentList& deployments, std::ostringstream message; message << "component " << component->getIdentifier() << " was assigned to non-loadable device " << device->identifier; + LOG_ERROR(ApplicationFactory_impl, message); throw std::logic_error(message.str()); } - loadDependencies(*component, loadabledev, deployment->getDependencies()); - - // load the file(s) - ostringstream load_eout; // used for any error messages dealing with load + LOG_TRACE(ApplicationFactory_impl, "Loading " << codeLocalFile << " and dependencies on device " + << device->label); try { - try { - LOG_TRACE(ApplicationFactory_impl, "loading " << codeLocalFile << " on device " << ossie::corba::returnString(loadabledev->label())); - loadabledev->load(_appFact._fileMgr, codeLocalFile.c_str(), implementation->getCodeType()); - } catch( ... ) { - load_eout << "'load' failed for component: '"; - load_eout << component->getName() << "' with component id: '" << component->getIdentifier() << "' "; - load_eout << " with implementation id: '" << implementation->getId() << "';"; - load_eout << " on device id: '" << device->identifier << "'"; - load_eout << " in waveform '" << _waveformContextName<<"'"; - load_eout << "\nError occurred near line:" <<__LINE__ << " in file:" << __FILE__ << ";"; - throw; - } - } catch( CF::InvalidFileName& _ex ) { - load_eout << " with error: <" << _ex.msg << ">;"; - throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EIO, load_eout.str().c_str()); - } catch( CF::Device::InvalidState& _ex ) { - load_eout << " with error: <" << _ex.msg << ">;"; - throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EIO, load_eout.str().c_str()); - } CATCH_THROW_LOG_TRACE(ApplicationFactory_impl, "", CF::ApplicationFactory::CreateApplicationError(CF::CF_EIO, load_eout.str().c_str())); - - // Mark the file as loaded - _application->addComponentLoadedFile(component->getIdentifier(), codeLocalFile); + deployment->load(_application, _appFact._fileMgr, loadabledev); + } catch (const std::exception& exc) { + std::ostringstream message; + message << "Unable to load component " << component->getName() + << " implementation " << implementation->getId() + << " on device " << device->identifier + << ": " << exc.what(); + LOG_ERROR(ApplicationFactory_impl, message.str()); + throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EIO, message.str().c_str()); + } // OSSIE extends section D.2.1.6.3 to support loading a directory // and execute a file in that directory using a entrypoint diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index b2641484b..8181457ec 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -20,6 +20,7 @@ #include +#include "Application_impl.h" #include "PersistenceStore.h" #include "Deployment.h" @@ -135,6 +136,52 @@ std::vector SoftpkgDeployment::getDependencyLocalFiles() return files; } +void SoftpkgDeployment::load(Application_impl* application, CF::FileSystem_ptr fileSystem, + CF::LoadableDevice_ptr device, const std::string& componentId) +{ + if (!implementation) { + throw std::logic_error("no implementation selected for soft package " + softpkg->getName()); + } + + // Recursively load dependencies + if (!dependencies.empty()) { + RH_NL_TRACE("ApplicationFactory_impl", "Loading " << dependencies.size() << + "dependency(ies) for soft package " << softpkg->getName()); + for (DeploymentList::iterator dep = dependencies.begin(); dep != dependencies.end(); ++dep) { + (*dep)->load(application, fileSystem, device, componentId); + } + } + + // Determine absolute path of local file + CF::LoadableDevice::LoadType codeType = implementation->getCodeType(); + const std::string fileName = getLocalFile(); + RH_NL_DEBUG("ApplicationFactory_impl", "Loading file " << fileName + << " for soft package " << softpkg->getName()); + try { + device->load(fileSystem, fileName.c_str(), codeType); + } catch (const CF::Device::InvalidState& exc) { + std::string message = "device is in invalid state: "; + message += exc.msg; + throw std::runtime_error(message); + } catch (const CF::LoadableDevice::InvalidLoadKind& exc) { + throw std::runtime_error("invalid load kind for file " + fileName); + } catch (const CF::InvalidFileName& exc) { + std::string message = "file name '" + fileName + "' is invalid: "; + message += exc.msg; + throw std::runtime_error(message); + } catch (const CF::LoadableDevice::LoadFail& exc) { + std::string message = "failure loading file '" + fileName + "': "; + message += exc.msg; + throw std::runtime_error(message); + } catch (const CORBA::SystemException& exc) { + std::string message = "CORBA system exception "; + message += exc._name(); + message += " loading " + fileName; + throw std::runtime_error(message); + } + application->addComponentLoadedFile(componentId, fileName); +} + std::string SoftpkgDeployment::getLocalFile() { fs::path codeLocalFile = fs::path(implementation->getLocalFileName()); @@ -297,6 +344,12 @@ CF::Resource_ptr ComponentDeployment::getResourcePtr() const return CF::Resource::_duplicate(resource); } +void ComponentDeployment::load(Application_impl* application, CF::FileSystem_ptr fileSystem, + CF::LoadableDevice_ptr device) +{ + SoftpkgDeployment::load(application, fileSystem, device, component->getIdentifier()); +} + PlacementPlan::PlacementPlan() { diff --git a/redhawk/src/control/sdr/dommgr/Deployment.h b/redhawk/src/control/sdr/dommgr/Deployment.h index fd3a8b190..e094407a8 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.h +++ b/redhawk/src/control/sdr/dommgr/Deployment.h @@ -30,6 +30,8 @@ #include "applicationSupport.h" #include "connectionSupport.h" +class Application_impl; + namespace ossie { class UsesDeviceAssignment @@ -86,6 +88,9 @@ namespace ossie { std::vector getDependencyLocalFiles(); protected: + void load(Application_impl* application, CF::FileSystem_ptr fileSystem, + CF::LoadableDevice_ptr device, const std::string& componentId); + SoftpkgInfo* softpkg; const ImplementationInfo* implementation; DeploymentList dependencies; @@ -121,6 +126,9 @@ namespace ossie { void setResourcePtr(CF::Resource_ptr resource); CF::Resource_ptr getResourcePtr() const; + void load(Application_impl* application, CF::FileSystem_ptr fileSystem, + CF::LoadableDevice_ptr device); + protected: ComponentInfo* component; boost::shared_ptr assignedDevice; diff --git a/redhawk/src/control/sdr/dommgr/createHelper.h b/redhawk/src/control/sdr/dommgr/createHelper.h index cc630420a..bcff7827b 100644 --- a/redhawk/src/control/sdr/dommgr/createHelper.h +++ b/redhawk/src/control/sdr/dommgr/createHelper.h @@ -171,10 +171,6 @@ class createHelper ossie::SoftpkgDeployment* resolveDependencyImplementation(ossie::SoftpkgInfo* softpkg, ossie::DeviceNode& device); // Supports loading, executing, initializing, configuring, & connecting - void loadDependencies(const ossie::ComponentInfo& component, - CF::LoadableDevice_ptr device, - const std::vector& dependencies); - void loadAndExecuteComponents(const DeploymentList& deployments, CF::ApplicationRegistrar_ptr _appReg); void applyApplicationAffinityOptions(const DeploymentList& deployments); From 38b149821c1e1dad3876ca2adddac7d95a5ec3a6 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 18 May 2016 15:02:29 -0400 Subject: [PATCH 0235/1644] Start of refactor to use a tree structure and visitor pattern to manage the application profile --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 4 +- .../control/sdr/dommgr/ApplicationProfile.cpp | 147 ++++++++++++++++++ .../control/sdr/dommgr/ApplicationProfile.h | 124 +++++++++++++++ redhawk/src/control/sdr/dommgr/Makefile.am | 1 + .../control/sdr/dommgr/applicationSupport.cpp | 29 ---- .../control/sdr/dommgr/applicationSupport.h | 17 -- redhawk/src/control/sdr/dommgr/createHelper.h | 3 +- 7 files changed, 276 insertions(+), 49 deletions(-) create mode 100644 redhawk/src/control/sdr/dommgr/ApplicationProfile.cpp create mode 100644 redhawk/src/control/sdr/dommgr/ApplicationProfile.h diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index c5dc84c9a..17314038f 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -868,7 +868,7 @@ void createHelper::_handleUsesDevices(ossie::ApplicationDeployment& appDeploymen const std::string& appName) { // Gets all uses device info from the SAD file - const UsesDeviceInfo::List& usesDevices = _appInfo.getUsesDevices(); + const UsesDeviceInfo::List& usesDevices = _appProfile.getUsesDevices(); LOG_TRACE(ApplicationFactory_impl, "Application has " << usesDevices.size() << " usesdevice dependencies"); // Get the assembly controller's configure properties for context in the @@ -1205,7 +1205,7 @@ CF::Application_ptr createHelper::create ( ////////////////////////////////////////////////// // Store information about this application - _appInfo.populateApplicationInfo(_appFact._sadParser); + _appProfile.populateApplicationProfile(_appFact._sadParser); overrideExternalProperties(app_deployment, modifiedInitConfiguration); diff --git a/redhawk/src/control/sdr/dommgr/ApplicationProfile.cpp b/redhawk/src/control/sdr/dommgr/ApplicationProfile.cpp new file mode 100644 index 000000000..28db4b9c3 --- /dev/null +++ b/redhawk/src/control/sdr/dommgr/ApplicationProfile.cpp @@ -0,0 +1,147 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK core. + * + * REDHAWK core is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +#include "ApplicationProfile.h" + +using namespace ossie; + +SinglePlacement::SinglePlacement(const ComponentInstantiation* instantiation) : + instantiation(instantiation) +{ +} + +void SinglePlacement::accept(ApplicationVisitor* visitor) +{ + visitor->visitComponentPlacement(this); +} + +const ComponentInstantiation* SinglePlacement::getComponentInstantiation() const +{ + return instantiation; +} + + +CollocationPlacement::CollocationPlacement(const std::string& id, const std::string& name) : + id(id), + name(name) +{ +} + +void CollocationPlacement::accept(ApplicationVisitor* visitor) +{ + visitor->visitHostCollocation(this); +} + +const std::string& CollocationPlacement::getId() const +{ + return id; +} + +const std::string& CollocationPlacement::getName() const +{ + return name; +} + +const CollocationPlacement::PlacementList& CollocationPlacement::getPlacements() const +{ + return placements; +} + +void CollocationPlacement::addPlacement(SinglePlacement* placement) +{ + placements.push_back(placement); +} + +//////////////////////////////////////////////////// +/* + * ApplicationProfile member function definitions + */ +PREPARE_LOGGING(ApplicationProfile); + +ApplicationProfile::ApplicationProfile() +{ +} + +ApplicationProfile::~ApplicationProfile() +{ + for (PlacementList::iterator placement = placements.begin(); placement != placements.end(); ++placement) { + delete *placement; + } +} + +void ApplicationProfile::accept(ApplicationVisitor* visitor) +{ + visitor->visitApplication(this); +} + +void ApplicationProfile::populateApplicationProfile(const SoftwareAssembly& sad) +{ + // Gets uses device relationships + const std::vector& usesDevice = sad.getUsesDevices(); + for (std::vector::const_iterator use = usesDevice.begin(); use != usesDevice.end(); ++use) { + UsesDeviceInfo* useDev = new UsesDeviceInfo(use->getId(), use->getType(), use->getDependencies()); + addUsesDevice(useDev); + } + + // Walk through the host collocations first + const std::vector& collocations = sad.getHostCollocations(); + for (size_t index = 0; index < collocations.size(); ++index) { + const SoftwareAssembly::HostCollocation& collocation = collocations[index]; + LOG_TRACE(ApplicationProfile, "Building component info for host collocation " + << collocation.getID()); + CollocationPlacement* placement = new CollocationPlacement(collocation.getID(), collocation.getName()); + placements.push_back(placement); + + const std::vector& components = collocations[index].getComponents(); + for (unsigned int i = 0; i < components.size(); i++) { + SinglePlacement* component = buildComponentPlacement(components[i]); + placement->addPlacement(component); + } + } + + // Then, walk through the remaining non-collocated components + const std::vector& components = sad.getComponentPlacements(); + for (unsigned int i = 0; i < components.size(); i++) { + // ossie::ComponentInfo* component = buildComponentInfo(fileSys, sadParser, componentsFromSAD[i]); + // if (component->getInstantiationIdentifier() == assemblyControllerRefId) { + // component->setIsAssemblyController(true); + // } + SinglePlacement* placement = buildComponentPlacement(components[i]); + placements.push_back(placement); + } +} + +SinglePlacement* ApplicationProfile::buildComponentPlacement(const ComponentPlacement& placement) +{ + // Even though it is possible for there to be more than one instantiation + // per component, the tooling doesn't support that, so supporting this at a + // framework level would add substantial complexity without providing any + // appreciable improvements. It is far easier to have multiple placements + // rather than multiple instantiations. + const std::vector& instantiations = placement.getInstantiations(); + const ComponentInstantiation& instance = instantiations[0]; + + return new SinglePlacement(&instance); +} + +const ApplicationProfile::PlacementList& ApplicationProfile::getPlacements() const +{ + return placements; +} diff --git a/redhawk/src/control/sdr/dommgr/ApplicationProfile.h b/redhawk/src/control/sdr/dommgr/ApplicationProfile.h new file mode 100644 index 000000000..bc0fde04e --- /dev/null +++ b/redhawk/src/control/sdr/dommgr/ApplicationProfile.h @@ -0,0 +1,124 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK core. + * + * REDHAWK core is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + + +#ifndef APPLICATIONPROFILE_H +#define APPLICATIONPROFILE_H + +#include +#include + +#include "applicationSupport.h" + +namespace ossie { + + class ApplicationVisitor; + + class Placement + { + public: + virtual ~Placement() { } + virtual void accept(ApplicationVisitor* visitor) = 0; + }; + + class SinglePlacement : public Placement + { + public: + SinglePlacement(const ComponentInstantiation* instantiation); + + virtual void accept(ApplicationVisitor* visitor); + + const ComponentInstantiation* getComponentInstantiation() const; + + protected: + const ComponentInstantiation* instantiation; + }; + + class CollocationPlacement : public Placement + { + public: + typedef std::vector PlacementList; + + CollocationPlacement(const std::string& id, const std::string& name); + + virtual void accept(ApplicationVisitor* visitor); + + const std::string& getId() const; + const std::string& getName() const; + + const PlacementList& getPlacements() const; + + void addPlacement(SinglePlacement* placement); + + protected: + const std::string id; + const std::string name; + PlacementList placements; + }; + + /* Base class to contain data for applications + * - Used to store information about about: + * -> ExternalPorts + * -> External Properties + * -> UsesDevice relationships + */ + class ApplicationProfile : public UsesDeviceContext + { + ENABLE_LOGGING; + + public: + typedef std::vector PlacementList; + + ApplicationProfile(); + ~ApplicationProfile(); + + void accept(ApplicationVisitor* visitor); + + void populateApplicationProfile(const SoftwareAssembly& sad); + + const PlacementList& getPlacements() const; + + protected: + SinglePlacement* buildComponentPlacement(const ComponentPlacement& placement); + + PlacementList placements; + }; + + class ApplicationVisitor + { + public: + virtual ~ApplicationVisitor() { } + + virtual void visitApplication(ApplicationProfile* application) + { + } + + virtual void visitComponentPlacement(SinglePlacement* placement) + { + } + + virtual void visitHostCollocation(CollocationPlacement* collocation) + { + } + }; + +} + +#endif // APPLICATIONPROFILE_H diff --git a/redhawk/src/control/sdr/dommgr/Makefile.am b/redhawk/src/control/sdr/dommgr/Makefile.am index 266099569..f52ba4ce7 100644 --- a/redhawk/src/control/sdr/dommgr/Makefile.am +++ b/redhawk/src/control/sdr/dommgr/Makefile.am @@ -35,6 +35,7 @@ DomainManager_SOURCES = applicationSupport.cpp \ DomainManager_impl.cpp \ FakeApplication.cpp \ Deployment.cpp \ + ApplicationProfile.cpp \ main.cpp DomainManager_CPPFLAGS = -I../../include -I../../parser -I$(top_srcdir)/base/include -I$(top_srcdir)/base $(BOOST_CPPFLAGS) $(OMNIORB_CFLAGS) $(LOG4CXX_FLAGS) DomainManager_CXXFLAGS = -Wall diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp index cf9cb2c89..80070c05b 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp @@ -909,32 +909,3 @@ CF::Properties ComponentInfo::getCommandLineParameters() const } return retval; } - - -//////////////////////////////////////////////////// -/* - * ApplicationInfo member function definitions - */ -PREPARE_CF_LOGGING(ApplicationInfo); - -ApplicationInfo::ApplicationInfo() -{ -} - -ApplicationInfo::~ApplicationInfo() -{ - for (unsigned int ii = 0; ii < usesDevices.size(); ++ii) { - delete usesDevices[ii]; - } - usesDevices.clear(); -} - -void ApplicationInfo::populateApplicationInfo(const SoftwareAssembly& sad) -{ - // Gets uses device relationships - const std::vector& usesDevice = sad.getUsesDevices(); - for (std::vector::const_iterator use = usesDevice.begin(); use != usesDevice.end(); ++use) { - UsesDeviceInfo* useDev = new UsesDeviceInfo(use->getId(), use->getType(), use->getDependencies()); - addUsesDevice(useDev); - } -} diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.h b/redhawk/src/control/sdr/dommgr/applicationSupport.h index fe2aa1ece..a6cf0df48 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.h +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.h @@ -284,22 +284,5 @@ namespace ossie }; - /* Base class to contain data for applications - * - Used to store information about about: - * -> ExternalPorts - * -> External Properties - * -> UsesDevice relationships - */ - class ApplicationInfo : public UsesDeviceContext - { - ENABLE_LOGGING; - - public: - ApplicationInfo(); - ~ApplicationInfo(); - - void populateApplicationInfo(const SoftwareAssembly& sad); - }; - } #endif diff --git a/redhawk/src/control/sdr/dommgr/createHelper.h b/redhawk/src/control/sdr/dommgr/createHelper.h index bcff7827b..60318ba2f 100644 --- a/redhawk/src/control/sdr/dommgr/createHelper.h +++ b/redhawk/src/control/sdr/dommgr/createHelper.h @@ -27,6 +27,7 @@ #include "PersistenceStore.h" #include "applicationSupport.h" +#include "ApplicationProfile.h" #include "Deployment.h" class Application_impl; @@ -96,7 +97,7 @@ class createHelper CosNaming::NamingContext_var _waveformContext; CosNaming::NamingContext_ptr _domainContext; - ossie::ApplicationInfo _appInfo; + ossie::ApplicationProfile _appProfile; typedef std::vector DeploymentList; typedef ossie::ImplementationInfo::List ImplementationList; From a823bed48fa1d51fbbfc05a0f1056878a7c6b848 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 18 May 2016 16:19:29 -0400 Subject: [PATCH 0236/1644] Return SAD strings by const reference instead of bouncing through const char* --- .../control/include/ossie/SoftwareAssembly.h | 22 +++++++++---------- .../src/control/parser/SoftwareAssembly.cpp | 12 +++++----- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/redhawk/src/control/include/ossie/SoftwareAssembly.h b/redhawk/src/control/include/ossie/SoftwareAssembly.h index b22276ba3..f30fa1638 100644 --- a/redhawk/src/control/include/ossie/SoftwareAssembly.h +++ b/redhawk/src/control/include/ossie/SoftwareAssembly.h @@ -36,12 +36,12 @@ namespace ossie { std::string name; std::vector placements; - const char* getID() const { - return id.c_str(); + const std::string& getID() const { + return id; } - const char* getName() const { - return name.c_str(); + const std::string& getName() const { + return name; } const std::vector& getComponents() const { @@ -110,12 +110,12 @@ namespace ossie { std::string type; std::vector dependencies; - const char* getId() const { - return id.c_str(); + const std::string& getId() const { + return id; } - const char* getType() const { - return type.c_str(); + const std::string& getType() const { + return type; } const std::vector& getDependencies() const { @@ -142,9 +142,9 @@ namespace ossie { void load(std::istream& input) throw (ossie::parser_error); - const char* getID() const; + const std::string& getID() const; - const char* getName() const; + const std::string& getName() const; const std::vector& getComponentFiles() const; @@ -158,7 +158,7 @@ namespace ossie { const char* getSPDById(const char* refid) const; - const char* getAssemblyControllerRefId() const; + const std::string& getAssemblyControllerRefId() const; const std::vector& getExternalPorts() const; diff --git a/redhawk/src/control/parser/SoftwareAssembly.cpp b/redhawk/src/control/parser/SoftwareAssembly.cpp index ccb21f585..a8fb2ae2e 100644 --- a/redhawk/src/control/parser/SoftwareAssembly.cpp +++ b/redhawk/src/control/parser/SoftwareAssembly.cpp @@ -32,14 +32,14 @@ void SoftwareAssembly::load(std::istream& input) throw (ossie::parser_error) _sad = ossie::internalparser::parseSAD(input); } -const char* SoftwareAssembly::getID() const { +const std::string& SoftwareAssembly::getID() const { assert(_sad.get() != 0); - return _sad->id.c_str(); + return _sad->id; } -const char* SoftwareAssembly::getName() const { +const std::string& SoftwareAssembly::getName() const { assert(_sad.get() != 0); - return _sad->name.c_str(); + return _sad->name; } const std::vector& SoftwareAssembly::getComponentFiles() const { @@ -95,9 +95,9 @@ const char* SoftwareAssembly::getSPDById(const char* refid) const { return 0; } -const char* SoftwareAssembly::getAssemblyControllerRefId() const { +const std::string& SoftwareAssembly::getAssemblyControllerRefId() const { assert(_sad.get() != 0); - return _sad->assemblycontroller.c_str(); + return _sad->assemblycontroller; } const std::vector& SoftwareAssembly::getExternalPorts() const { From 1f5651b6d0349a738c5a23e8d04a2db9c8996fd8 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 18 May 2016 16:50:26 -0400 Subject: [PATCH 0237/1644] Return a pointer to a ComponentFile, rather than a const char* --- redhawk/src/control/include/ossie/SoftwareAssembly.h | 2 +- redhawk/src/control/parser/SoftwareAssembly.cpp | 6 +++--- .../control/sdr/dommgr/ApplicationFactory_impl.cpp | 12 ++++++------ 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/redhawk/src/control/include/ossie/SoftwareAssembly.h b/redhawk/src/control/include/ossie/SoftwareAssembly.h index f30fa1638..d7624ee29 100644 --- a/redhawk/src/control/include/ossie/SoftwareAssembly.h +++ b/redhawk/src/control/include/ossie/SoftwareAssembly.h @@ -156,7 +156,7 @@ namespace ossie { const std::vector& getConnections() const; - const char* getSPDById(const char* refid) const; + const ComponentFile* getComponentFile(const std::string& refid) const; const std::string& getAssemblyControllerRefId() const; diff --git a/redhawk/src/control/parser/SoftwareAssembly.cpp b/redhawk/src/control/parser/SoftwareAssembly.cpp index a8fb2ae2e..fb16e01c9 100644 --- a/redhawk/src/control/parser/SoftwareAssembly.cpp +++ b/redhawk/src/control/parser/SoftwareAssembly.cpp @@ -82,13 +82,13 @@ const std::vector& SoftwareAssembly::getConnections() const { return _sad->connections; } -const char* SoftwareAssembly::getSPDById(const char* refid) const { +const ComponentFile* SoftwareAssembly::getComponentFile(const std::string& refid) const { assert(_sad.get() != 0); const std::vector& componentFiles = getComponentFiles(); std::vector::const_iterator i; for (i = componentFiles.begin(); i != componentFiles.end(); ++i) { - if (strcmp(i->getID(), refid) == 0) { - return i->getFileName(); + if (i->getID() == refid) { + return &(*i); } } diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 17314038f..10b418631 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -486,8 +486,8 @@ ApplicationFactory_impl::ApplicationFactory_impl (const std::string& softwarePro SoftPkg comp_pkg; std::string p_name; try { - if ( _sadParser.getSPDById(comp->getFileRefId())) { - p_name = _sadParser.getSPDById(comp->getFileRefId()); + if ( _sadParser.getComponentFile(comp->getFileRefId())) { + p_name = _sadParser.getComponentFile(comp->getFileRefId())->getFileName(); LOG_DEBUG(ApplicationFactory_impl, "Validating... COMP profile: " << p_name); ValidateSPD(_fileMgr, _domainManager, comp_pkg, p_name) ; } @@ -522,7 +522,7 @@ ApplicationFactory_impl::ApplicationFactory_impl (const std::string& softwarePro compInst != compInstantiations.end(); ++compInst){ if (assemblyControllerId == compInst->instantiationId) { ac_spd = comp_pkg; - ac_profile = _sadParser.getSPDById(comp->getFileRefId()); + ac_profile = _sadParser.getComponentFile(comp->getFileRefId())->getFileName(); ac_found = true; break; } @@ -1887,14 +1887,14 @@ ossie::ComponentInfo* createHelper::buildComponentInfo(CF::FileSystem_ptr fileSy // Extract required data from SPD file ossie::ComponentInfo* newComponent = 0; LOG_TRACE(ApplicationFactory_impl, "Getting the SPD Filename"); - const char *spdFileName = sadParser.getSPDById(component.getFileRefId()); - if (spdFileName == NULL) { + const ComponentFile* componentfile = sadParser.getComponentFile(component.getFileRefId()); + if (!componentfile) { ostringstream eout; eout << "The SPD file reference for componentfile "<getFileName()); if (newComponent == 0) { ostringstream eout; eout << "Error loading component information for file ref " << component.getFileRefId(); From 553c5488aafd0cfc4b392de114778f6c0a13ee27 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 18 May 2016 17:09:27 -0400 Subject: [PATCH 0238/1644] ComponentFile returns a const string reference instead of const char* --- redhawk/src/control/include/ossie/componentProfile.h | 6 +++--- .../control/parser/DeviceManagerConfiguration.cpp | 4 ++-- redhawk/src/control/parser/componentProfile.cpp | 12 ++++++------ .../src/control/sdr/devmgr/DeviceManager_impl.cpp | 6 +++--- .../control/sdr/dommgr/ApplicationFactory_impl.cpp | 4 ++-- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/redhawk/src/control/include/ossie/componentProfile.h b/redhawk/src/control/include/ossie/componentProfile.h index b5ea16222..b60ca36be 100644 --- a/redhawk/src/control/include/ossie/componentProfile.h +++ b/redhawk/src/control/include/ossie/componentProfile.h @@ -42,9 +42,9 @@ namespace ossie { std::string type; public: - const char* getFileName() const; + const std::string& getFileName() const; - const char* getID() const; + const std::string& getID() const; }; /* @@ -225,7 +225,7 @@ namespace ossie { const std::vector& getInstantiations() const; - const char* getFileRefId() const; + const std::string& getFileRefId() const; bool isDeployOn() const; diff --git a/redhawk/src/control/parser/DeviceManagerConfiguration.cpp b/redhawk/src/control/parser/DeviceManagerConfiguration.cpp index da9b6af34..4675d81e9 100644 --- a/redhawk/src/control/parser/DeviceManagerConfiguration.cpp +++ b/redhawk/src/control/parser/DeviceManagerConfiguration.cpp @@ -75,8 +75,8 @@ const char* DeviceManagerConfiguration::getFileNameFromRefId(const char* refid) const std::vector& componentFiles = getComponentFiles(); std::vector::const_iterator i; for (i = componentFiles.begin(); i != componentFiles.end(); ++i) { - if (strcmp(i->getID(), refid) == 0) { - return i->getFileName(); + if (i->getID() == refid) { + return i->getFileName().c_str(); } } diff --git a/redhawk/src/control/parser/componentProfile.cpp b/redhawk/src/control/parser/componentProfile.cpp index 5689b15a5..d3cf6f89c 100644 --- a/redhawk/src/control/parser/componentProfile.cpp +++ b/redhawk/src/control/parser/componentProfile.cpp @@ -35,12 +35,12 @@ ComponentProperty *ossie::new_clone(const ComponentProperty &a) { // // ComponentFile // -const char* ComponentFile::getFileName() const { - return filename.c_str(); +const std::string& ComponentFile::getFileName() const { + return filename; }; -const char* ComponentFile::getID() const { - return id.c_str(); +const std::string& ComponentFile::getID() const { + return id; }; // @@ -224,8 +224,8 @@ const std::vector& ComponentPlacement::getInstantiations return instantiations; }; -const char* ComponentPlacement::getFileRefId() const { - return _componentFileRef.c_str(); +const std::string& ComponentPlacement::getFileRefId() const { + return _componentFileRef; } bool ComponentPlacement::isDeployOn() const { diff --git a/redhawk/src/control/sdr/devmgr/DeviceManager_impl.cpp b/redhawk/src/control/sdr/devmgr/DeviceManager_impl.cpp index a596b2bb9..be30c4337 100644 --- a/redhawk/src/control/sdr/devmgr/DeviceManager_impl.cpp +++ b/redhawk/src/control/sdr/devmgr/DeviceManager_impl.cpp @@ -201,7 +201,7 @@ bool DeviceManager_impl::loadSPD( const ComponentPlacement& componentPlacement) { LOG_TRACE(DeviceManager_impl, "Getting file name for refid " << componentPlacement.getFileRefId()); - const char* spdFile = DCDParser.getFileNameFromRefId(componentPlacement.getFileRefId()); + const char* spdFile = DCDParser.getFileNameFromRefId(componentPlacement.getFileRefId().c_str()); if (spdFile == 0) { LOG_ERROR(DeviceManager_impl, "Cannot instantiate component; component file for id " << componentPlacement.getFileRefId() << " isn't defined") return false; @@ -736,7 +736,7 @@ void DeviceManager_impl::createDeviceExecStatement( if (componentType == "device") { new_argv.push_back("PROFILE_NAME"); - new_argv.push_back(DCDParser.getFileNameFromRefId(componentPlacement.getFileRefId())); + new_argv.push_back(DCDParser.getFileNameFromRefId(componentPlacement.getFileRefId().c_str())); new_argv.push_back( "DEVICE_ID"); new_argv.push_back(instantiation.getID()); new_argv.push_back( "DEVICE_LABEL"); @@ -850,7 +850,7 @@ DeviceManager_impl::ExecparamList DeviceManager_impl::createDeviceExecparams( std::string logcfg_path(""); deviceMgrIOR = ossie::corba::objectToString(myObj); if (componentType == "device") { - execparams.push_back(std::make_pair("PROFILE_NAME", DCDParser.getFileNameFromRefId(componentPlacement.getFileRefId()))); + execparams.push_back(std::make_pair("PROFILE_NAME", DCDParser.getFileNameFromRefId(componentPlacement.getFileRefId().c_str()))); execparams.push_back(std::make_pair("DEVICE_ID", instantiation.getID())); execparams.push_back(std::make_pair("DEVICE_LABEL", usageName)); if (componentPlacement.isCompositePartOf()) { diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 10b418631..70b78e611 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -478,7 +478,7 @@ ApplicationFactory_impl::ApplicationFactory_impl (const std::string& softwarePro // component instantiation to find a matching ID to the AC's std::string assemblyControllerId = _sadParser.getAssemblyControllerRefId(); SoftPkg ac_spd; - CORBA::String_var ac_profile = ""; + std::string ac_profile; bool ac_found = false; std::vector components = _sadParser.getAllComponents(); for (std::vector::const_iterator comp = components.begin(); @@ -1894,7 +1894,7 @@ ossie::ComponentInfo* createHelper::buildComponentInfo(CF::FileSystem_ptr fileSy throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EINVAL, eout.str().c_str()); } LOG_TRACE(ApplicationFactory_impl, "Building Component Info From SPD File"); - newComponent = ossie::ComponentInfo::buildComponentInfoFromSPDFile(fileSys, componentfile->getFileName()); + newComponent = ossie::ComponentInfo::buildComponentInfoFromSPDFile(fileSys, componentfile->getFileName().c_str()); if (newComponent == 0) { ostringstream eout; eout << "Error loading component information for file ref " << component.getFileRefId(); From 756cee3b726efd1bb88ef60f622d9dcfbedb14ff Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 18 May 2016 17:14:27 -0400 Subject: [PATCH 0239/1644] Start building up a new softpkg profile class to handle the components for ApplicationProfile --- .../control/sdr/dommgr/ApplicationProfile.cpp | 74 +++++++++++++++++-- .../control/sdr/dommgr/ApplicationProfile.h | 33 ++++++++- 2 files changed, 99 insertions(+), 8 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationProfile.cpp b/redhawk/src/control/sdr/dommgr/ApplicationProfile.cpp index 28db4b9c3..8a1740cee 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationProfile.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationProfile.cpp @@ -18,12 +18,39 @@ * along with this program. If not, see http://www.gnu.org/licenses/. */ +#include + #include "ApplicationProfile.h" using namespace ossie; -SinglePlacement::SinglePlacement(const ComponentInstantiation* instantiation) : - instantiation(instantiation) +SoftpkgProfile::SoftpkgProfile(const std::string& filename) : + spdFilename(filename), + loaded(false) +{ +} + +const std::string& SoftpkgProfile::getSpdFileName() const +{ + return spdFilename; +} + +bool SoftpkgProfile::isLoaded() const +{ + return loaded; +} + +void SoftpkgProfile::load(CF::FileSystem_ptr fileSystem) +{ + File_stream spd_stream(fileSystem, spdFilename.c_str()); + spd.load(spd_stream, spdFilename); + loaded = true; +} + +SinglePlacement::SinglePlacement(const ComponentInstantiation* instantiation, + const SoftpkgProfile* softpkg) : + instantiation(instantiation), + softpkg(softpkg) { } @@ -37,6 +64,11 @@ const ComponentInstantiation* SinglePlacement::getComponentInstantiation() const return instantiation; } +const SoftpkgProfile* SinglePlacement::getComponentProfile() const +{ + return softpkg; +} + CollocationPlacement::CollocationPlacement(const std::string& id, const std::string& name) : id(id), @@ -91,8 +123,15 @@ void ApplicationProfile::accept(ApplicationVisitor* visitor) visitor->visitApplication(this); } +const std::string& ApplicationProfile::getIdentifier() +{ + return identifier; +} + void ApplicationProfile::populateApplicationProfile(const SoftwareAssembly& sad) { + identifier = sad.getID(); + // Gets uses device relationships const std::vector& usesDevice = sad.getUsesDevices(); for (std::vector::const_iterator use = usesDevice.begin(); use != usesDevice.end(); ++use) { @@ -111,7 +150,7 @@ void ApplicationProfile::populateApplicationProfile(const SoftwareAssembly& sad) const std::vector& components = collocations[index].getComponents(); for (unsigned int i = 0; i < components.size(); i++) { - SinglePlacement* component = buildComponentPlacement(components[i]); + SinglePlacement* component = buildComponentPlacement(sad, components[i]); placement->addPlacement(component); } } @@ -123,13 +162,36 @@ void ApplicationProfile::populateApplicationProfile(const SoftwareAssembly& sad) // if (component->getInstantiationIdentifier() == assemblyControllerRefId) { // component->setIsAssemblyController(true); // } - SinglePlacement* placement = buildComponentPlacement(components[i]); + SinglePlacement* placement = buildComponentPlacement(sad, components[i]); placements.push_back(placement); } } -SinglePlacement* ApplicationProfile::buildComponentPlacement(const ComponentPlacement& placement) +const SoftpkgProfile* ApplicationProfile::findSoftpkgProfile(const std::string& filename) const +{ + for (ProfileList::const_iterator profile = profiles.begin(); profile != profiles.end(); ++profile) { + if ((*profile)->getSpdFileName() == filename) { + return *profile; + } + } + return 0; +} + +SinglePlacement* ApplicationProfile::buildComponentPlacement(const SoftwareAssembly& sad, + const ComponentPlacement& placement) { + const ComponentFile *componentfile = sad.getComponentFile(placement.getFileRefId()); + if (!componentfile) { + throw std::runtime_error("componentplacement has invalid componentfileref " + placement.getFileRefId()); + } + const SoftpkgProfile* softpkg = findSoftpkgProfile(componentfile->getFileName()); + if (!softpkg) { + LOG_TRACE(ApplicationProfile, "Loading profile " << componentfile->getFileName()); + SoftpkgProfile* profile = new SoftpkgProfile(componentfile->getFileName()); + profiles.push_back(profile); + softpkg = profile; + } + // Even though it is possible for there to be more than one instantiation // per component, the tooling doesn't support that, so supporting this at a // framework level would add substantial complexity without providing any @@ -138,7 +200,7 @@ SinglePlacement* ApplicationProfile::buildComponentPlacement(const ComponentPlac const std::vector& instantiations = placement.getInstantiations(); const ComponentInstantiation& instance = instantiations[0]; - return new SinglePlacement(&instance); + return new SinglePlacement(&instance, softpkg); } const ApplicationProfile::PlacementList& ApplicationProfile::getPlacements() const diff --git a/redhawk/src/control/sdr/dommgr/ApplicationProfile.h b/redhawk/src/control/sdr/dommgr/ApplicationProfile.h index bc0fde04e..6ea33cec0 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationProfile.h +++ b/redhawk/src/control/sdr/dommgr/ApplicationProfile.h @@ -31,6 +31,23 @@ namespace ossie { class ApplicationVisitor; + class SoftpkgProfile + { + public: + SoftpkgProfile(const std::string& filename); + + const std::string& getSpdFileName() const; + + bool isLoaded() const; + + void load(CF::FileSystem_ptr fileSystem); + + protected: + const std::string spdFilename; + SoftPkg spd; + bool loaded; + }; + class Placement { public: @@ -41,14 +58,17 @@ namespace ossie { class SinglePlacement : public Placement { public: - SinglePlacement(const ComponentInstantiation* instantiation); + SinglePlacement(const ComponentInstantiation* instantiation, const SoftpkgProfile* softpkg); virtual void accept(ApplicationVisitor* visitor); const ComponentInstantiation* getComponentInstantiation() const; + const SoftpkgProfile* getComponentProfile() const; + protected: const ComponentInstantiation* instantiation; + const SoftpkgProfile* softpkg; }; class CollocationPlacement : public Placement @@ -91,13 +111,22 @@ namespace ossie { void accept(ApplicationVisitor* visitor); + const std::string& getIdentifier(); + void populateApplicationProfile(const SoftwareAssembly& sad); const PlacementList& getPlacements() const; protected: - SinglePlacement* buildComponentPlacement(const ComponentPlacement& placement); + typedef std::vector ProfileList; + + const SoftpkgProfile* findSoftpkgProfile(const std::string& filename) const; + + SinglePlacement* buildComponentPlacement(const SoftwareAssembly& sad, + const ComponentPlacement& placement); + std::string identifier; + ProfileList profiles; PlacementList placements; }; From f8bf777a2d9c1d433f7e76a8851c6e00eda4c074 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 19 May 2016 08:50:06 -0400 Subject: [PATCH 0240/1644] Replace more char* returns with string references --- redhawk/src/control/framework/nodebooter.cpp | 2 +- redhawk/src/control/include/ossie/SoftPkg.h | 32 +++++++++---------- redhawk/src/control/sdr/devmgr/spdSupport.cpp | 2 +- .../control/sdr/dommgr/applicationSupport.cpp | 10 +----- .../control/sdr/dommgr/applicationSupport.h | 1 - 5 files changed, 19 insertions(+), 28 deletions(-) diff --git a/redhawk/src/control/framework/nodebooter.cpp b/redhawk/src/control/framework/nodebooter.cpp index d79c2911d..4a273c3f5 100644 --- a/redhawk/src/control/framework/nodebooter.cpp +++ b/redhawk/src/control/framework/nodebooter.cpp @@ -240,7 +240,7 @@ static pid_t launchSPD ( // Create a C string array of the arguments to the executable from the code file name (0th argument) // and execparams. Note the importance of the final NULL, which terminates the array. std::vector argv; - argv.push_back(impl->getCodeFile()); + argv.push_back(impl->getCodeFile().c_str()); for (ExecParams::const_iterator param = execParams.begin(); param != execParams.end(); ++param) { LOG_TRACE(nodebooter, "EXEC_PARAM: " << param->first << "=\"" << param->second << "\""); argv.push_back(param->first.c_str()); diff --git a/redhawk/src/control/include/ossie/SoftPkg.h b/redhawk/src/control/include/ossie/SoftPkg.h index 646c94425..bddde8358 100644 --- a/redhawk/src/control/include/ossie/SoftPkg.h +++ b/redhawk/src/control/include/ossie/SoftPkg.h @@ -101,12 +101,12 @@ namespace ossie { std::vector dependencies; std::vector softPkgDependencies; - const char* getID() const { - return id.c_str(); + const std::string& getID() const { + return id; } - const char* getType() const { - return type.c_str(); + const std::string& getType() const { + return type; } const std::vector& getDependencies() const { @@ -176,8 +176,8 @@ namespace ossie { NameVersionPair runtime; public: - const char* getID() const { - return implementationID.c_str(); + const std::string& getID() const { + return implementationID; } const std::vector& getProcessors() const { @@ -199,8 +199,8 @@ namespace ossie { } } - const char * getCodeFile() const { - return code.localfile.c_str(); + const std::string& getCodeFile() const { + return code.localfile; } const char * getCodeType() const { @@ -266,14 +266,14 @@ namespace ossie { public: void load(std::istream& input, const std::string& _spdFile) throw (ossie::parser_error); - const char* getSoftPkgID() const { + const std::string& getSoftPkgID() const { assert(_spd.get() != 0); - return _spd->id.c_str(); + return _spd->id; } - const char* getSoftPkgName() const { + const std::string& getSoftPkgName() const { assert(_spd.get() != 0); - return _spd->name.c_str(); + return _spd->name; } const char* getSoftPkgType() const { @@ -312,12 +312,12 @@ namespace ossie { } } - const char* getSPDPath() const { - return _spdPath.c_str(); + const std::string& getSPDPath() const { + return _spdPath; } - const char* getSPDFile() const { - return _spdFile.c_str(); + const std::string& getSPDFile() const { + return _spdFile; } const char* getPRFFile() const { diff --git a/redhawk/src/control/sdr/devmgr/spdSupport.cpp b/redhawk/src/control/sdr/devmgr/spdSupport.cpp index 7f226c7cf..169c0c6e1 100644 --- a/redhawk/src/control/sdr/devmgr/spdSupport.cpp +++ b/redhawk/src/control/sdr/devmgr/spdSupport.cpp @@ -69,7 +69,7 @@ ImplementationInfo::ImplementationInfo(const SPD::Implementation& spdImpl) : osDeps(spdImpl.getOsDeps()), dependencyProperties() { - setLocalFileName(spdImpl.getCodeFile()); + setLocalFileName(spdImpl.getCodeFile().c_str()); setEntryPoint(spdImpl.getEntryPoint()); setCodeType(spdImpl.getCodeType()); setStackSize(spdImpl.code.stacksize.get()); diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp index 80070c05b..226664436 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp @@ -165,13 +165,12 @@ PREPARE_CF_LOGGING(ImplementationInfo); ImplementationInfo::ImplementationInfo(const SPD::Implementation& spdImpl) : id(spdImpl.getID()), codeType(), - localFileName(), + localFileName(spdImpl.getCodeFile()), entryPoint(), processorDeps(spdImpl.getProcessors()), osDeps(spdImpl.getOsDeps()), dependencyProperties() { - setLocalFileName(spdImpl.getCodeFile()); setEntryPoint(spdImpl.getEntryPoint()); setCodeType(spdImpl.getCodeType()); setStackSize(spdImpl.code.stacksize.get()); @@ -297,13 +296,6 @@ void ImplementationInfo::setCodeType(const char* _type) } } -void ImplementationInfo::setLocalFileName(const char* fileName) -{ - if (fileName) { - localFileName = fileName; - } -} - void ImplementationInfo::setEntryPoint(const char* _entryPoint) { if (_entryPoint) { diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.h b/redhawk/src/control/sdr/dommgr/applicationSupport.h index a6cf0df48..9108a660c 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.h +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.h @@ -140,7 +140,6 @@ namespace ossie private: ImplementationInfo (const ImplementationInfo&); - void setLocalFileName(const char* fileName); void setEntryPoint(const char* fileName); void setCodeType(const char* _type); void setStackSize(const unsigned long long *_stackSize); From 33a5d461dc7866345db88e508d7c884d57c50eb3 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 19 May 2016 09:11:48 -0400 Subject: [PATCH 0241/1644] Add visitor support for SoftpkgProfile and reduce const restriction --- .../control/sdr/dommgr/ApplicationProfile.cpp | 35 ++++++++++++++----- .../control/sdr/dommgr/ApplicationProfile.h | 23 ++++++++---- 2 files changed, 42 insertions(+), 16 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationProfile.cpp b/redhawk/src/control/sdr/dommgr/ApplicationProfile.cpp index 8a1740cee..73d41b386 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationProfile.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationProfile.cpp @@ -24,12 +24,20 @@ using namespace ossie; +/** + * SoftpkgProfile + */ SoftpkgProfile::SoftpkgProfile(const std::string& filename) : spdFilename(filename), loaded(false) { } +void SoftpkgProfile::accept(ApplicationVisitor* visitor) +{ + visitor->visitSoftpkg(this); +} + const std::string& SoftpkgProfile::getSpdFileName() const { return spdFilename; @@ -47,8 +55,16 @@ void SoftpkgProfile::load(CF::FileSystem_ptr fileSystem) loaded = true; } +const SoftPkg& SoftpkgProfile::getSPD() const +{ + return spd; +} + +/** + * SinglePlacement + */ SinglePlacement::SinglePlacement(const ComponentInstantiation* instantiation, - const SoftpkgProfile* softpkg) : + SoftpkgProfile* softpkg) : instantiation(instantiation), softpkg(softpkg) { @@ -64,7 +80,7 @@ const ComponentInstantiation* SinglePlacement::getComponentInstantiation() const return instantiation; } -const SoftpkgProfile* SinglePlacement::getComponentProfile() const +SoftpkgProfile* SinglePlacement::getComponentProfile() { return softpkg; } @@ -123,12 +139,12 @@ void ApplicationProfile::accept(ApplicationVisitor* visitor) visitor->visitApplication(this); } -const std::string& ApplicationProfile::getIdentifier() +const std::string& ApplicationProfile::getIdentifier() const { return identifier; } -void ApplicationProfile::populateApplicationProfile(const SoftwareAssembly& sad) +void ApplicationProfile::load(CF::FileSystem_ptr fileSystem, const SoftwareAssembly& sad) { identifier = sad.getID(); @@ -150,7 +166,7 @@ void ApplicationProfile::populateApplicationProfile(const SoftwareAssembly& sad) const std::vector& components = collocations[index].getComponents(); for (unsigned int i = 0; i < components.size(); i++) { - SinglePlacement* component = buildComponentPlacement(sad, components[i]); + SinglePlacement* component = buildComponentPlacement(fileSystem, sad, components[i]); placement->addPlacement(component); } } @@ -162,12 +178,12 @@ void ApplicationProfile::populateApplicationProfile(const SoftwareAssembly& sad) // if (component->getInstantiationIdentifier() == assemblyControllerRefId) { // component->setIsAssemblyController(true); // } - SinglePlacement* placement = buildComponentPlacement(sad, components[i]); + SinglePlacement* placement = buildComponentPlacement(fileSystem, sad, components[i]); placements.push_back(placement); } } -const SoftpkgProfile* ApplicationProfile::findSoftpkgProfile(const std::string& filename) const +SoftpkgProfile* ApplicationProfile::findSoftpkgProfile(const std::string& filename) { for (ProfileList::const_iterator profile = profiles.begin(); profile != profiles.end(); ++profile) { if ((*profile)->getSpdFileName() == filename) { @@ -177,14 +193,15 @@ const SoftpkgProfile* ApplicationProfile::findSoftpkgProfile(const std::string& return 0; } -SinglePlacement* ApplicationProfile::buildComponentPlacement(const SoftwareAssembly& sad, +SinglePlacement* ApplicationProfile::buildComponentPlacement(CF::FileSystem_ptr fileSystem, + const SoftwareAssembly& sad, const ComponentPlacement& placement) { const ComponentFile *componentfile = sad.getComponentFile(placement.getFileRefId()); if (!componentfile) { throw std::runtime_error("componentplacement has invalid componentfileref " + placement.getFileRefId()); } - const SoftpkgProfile* softpkg = findSoftpkgProfile(componentfile->getFileName()); + SoftpkgProfile* softpkg = findSoftpkgProfile(componentfile->getFileName()); if (!softpkg) { LOG_TRACE(ApplicationProfile, "Loading profile " << componentfile->getFileName()); SoftpkgProfile* profile = new SoftpkgProfile(componentfile->getFileName()); diff --git a/redhawk/src/control/sdr/dommgr/ApplicationProfile.h b/redhawk/src/control/sdr/dommgr/ApplicationProfile.h index 6ea33cec0..8e8f5eb58 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationProfile.h +++ b/redhawk/src/control/sdr/dommgr/ApplicationProfile.h @@ -36,12 +36,16 @@ namespace ossie { public: SoftpkgProfile(const std::string& filename); + void accept(ApplicationVisitor* visitor); + const std::string& getSpdFileName() const; bool isLoaded() const; void load(CF::FileSystem_ptr fileSystem); + const SoftPkg& getSPD() const; + protected: const std::string spdFilename; SoftPkg spd; @@ -58,17 +62,17 @@ namespace ossie { class SinglePlacement : public Placement { public: - SinglePlacement(const ComponentInstantiation* instantiation, const SoftpkgProfile* softpkg); + SinglePlacement(const ComponentInstantiation* instantiation, SoftpkgProfile* softpkg); virtual void accept(ApplicationVisitor* visitor); const ComponentInstantiation* getComponentInstantiation() const; - const SoftpkgProfile* getComponentProfile() const; + SoftpkgProfile* getComponentProfile(); protected: const ComponentInstantiation* instantiation; - const SoftpkgProfile* softpkg; + SoftpkgProfile* softpkg; }; class CollocationPlacement : public Placement @@ -111,18 +115,19 @@ namespace ossie { void accept(ApplicationVisitor* visitor); - const std::string& getIdentifier(); + const std::string& getIdentifier() const; - void populateApplicationProfile(const SoftwareAssembly& sad); + void load(CF::FileSystem_ptr fileSystem, const SoftwareAssembly& sad); const PlacementList& getPlacements() const; protected: typedef std::vector ProfileList; - const SoftpkgProfile* findSoftpkgProfile(const std::string& filename) const; + SoftpkgProfile* findSoftpkgProfile(const std::string& filename); - SinglePlacement* buildComponentPlacement(const SoftwareAssembly& sad, + SinglePlacement* buildComponentPlacement(CF::FileSystem_ptr fileSystem, + const SoftwareAssembly& sad, const ComponentPlacement& placement); std::string identifier; @@ -146,6 +151,10 @@ namespace ossie { virtual void visitHostCollocation(CollocationPlacement* collocation) { } + + virtual void visitSoftpkg(SoftpkgProfile* softpkg) + { + } }; } From 132ed2e53ddcd36b893d50be127e1c31be0e459e Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 19 May 2016 10:00:10 -0400 Subject: [PATCH 0242/1644] Add a profile object for implementations, with visitor support --- .../control/sdr/dommgr/ApplicationProfile.cpp | 34 +++++++++++++++++++ .../control/sdr/dommgr/ApplicationProfile.h | 26 ++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationProfile.cpp b/redhawk/src/control/sdr/dommgr/ApplicationProfile.cpp index 73d41b386..9aa379f3c 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationProfile.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationProfile.cpp @@ -24,6 +24,29 @@ using namespace ossie; +/** + * ImplementationProfile + */ +ImplementationProfile::ImplementationProfile(const SPD::Implementation& implementation) : + implementation(&implementation) +{ +} + +void ImplementationProfile::accept(ApplicationVisitor* visitor) +{ + visitor->visitImplementation(this); +} + +const std::string& ImplementationProfile::getIdentifier() const +{ + return implementation->getID(); +} + +const std::string& ImplementationProfile::getLocalfile() const +{ + return implementation->getCodeFile(); +} + /** * SoftpkgProfile */ @@ -53,6 +76,12 @@ void SoftpkgProfile::load(CF::FileSystem_ptr fileSystem) File_stream spd_stream(fileSystem, spdFilename.c_str()); spd.load(spd_stream, spdFilename); loaded = true; + + typedef std::vector SpdImplementations; + const SpdImplementations& spd_impls = spd.getImplementations(); + for (SpdImplementations::const_iterator impl = spd_impls.begin(); impl != spd_impls.end(); ++impl) { + implementations.push_back(ImplementationProfile(*impl)); + } } const SoftPkg& SoftpkgProfile::getSPD() const @@ -60,6 +89,11 @@ const SoftPkg& SoftpkgProfile::getSPD() const return spd; } +SoftpkgProfile::ImplementationList& SoftpkgProfile::getImplementations() +{ + return implementations; +} + /** * SinglePlacement */ diff --git a/redhawk/src/control/sdr/dommgr/ApplicationProfile.h b/redhawk/src/control/sdr/dommgr/ApplicationProfile.h index 8e8f5eb58..b155c5bbd 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationProfile.h +++ b/redhawk/src/control/sdr/dommgr/ApplicationProfile.h @@ -31,9 +31,28 @@ namespace ossie { class ApplicationVisitor; + class SoftpkgProfile; + + class ImplementationProfile + { + public: + ImplementationProfile(const SPD::Implementation& implementation); + + void accept(ApplicationVisitor* visitor); + + const std::string& getIdentifier() const; + + const std::string& getLocalfile() const; + + protected: + const SPD::Implementation* implementation; + }; + class SoftpkgProfile { public: + typedef std::vector ImplementationList; + SoftpkgProfile(const std::string& filename); void accept(ApplicationVisitor* visitor); @@ -46,9 +65,12 @@ namespace ossie { const SoftPkg& getSPD() const; + ImplementationList& getImplementations(); + protected: const std::string spdFilename; SoftPkg spd; + ImplementationList implementations; bool loaded; }; @@ -155,6 +177,10 @@ namespace ossie { virtual void visitSoftpkg(SoftpkgProfile* softpkg) { } + + virtual void visitImplementation(ImplementationProfile* implementation) + { + } }; } From 529a496816d23d9d246cedd790b994ea3e751da3 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 19 May 2016 10:15:08 -0400 Subject: [PATCH 0243/1644] Remove unused (and probably accidental) member in UsesDevice --- redhawk/src/control/include/ossie/SoftPkg.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/redhawk/src/control/include/ossie/SoftPkg.h b/redhawk/src/control/include/ossie/SoftPkg.h index bddde8358..5109aa3a5 100644 --- a/redhawk/src/control/include/ossie/SoftPkg.h +++ b/redhawk/src/control/include/ossie/SoftPkg.h @@ -99,7 +99,6 @@ namespace ossie { std::string id; std::string type; std::vector dependencies; - std::vector softPkgDependencies; const std::string& getID() const { return id; @@ -112,10 +111,6 @@ namespace ossie { const std::vector& getDependencies() const { return dependencies; } - - const std::vector& getSoftPkgDependencies() const { - return softPkgDependencies; - } }; class Code { From 550302accbb4ab6a675c6571cb812c3cc43cab55 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 19 May 2016 11:11:27 -0400 Subject: [PATCH 0244/1644] Consolidate SAD and SPD parser property references --- .../src/control/include/ossie/PropertyRef.h | 77 +++++++++++++++++++ redhawk/src/control/include/ossie/SoftPkg.h | 46 +---------- .../control/include/ossie/SoftwareAssembly.h | 29 +------ redhawk/src/control/parser/Makefile.am | 1 + redhawk/src/control/parser/PropertyRef.cpp | 32 ++++++++ redhawk/src/control/parser/SoftPkg.cpp | 8 -- .../src/control/parser/internal/sad-pimpl.cpp | 6 +- .../src/control/parser/internal/sad-pimpl.h | 4 +- redhawk/src/control/parser/internal/sad.map | 2 +- .../src/control/parser/internal/spd-pimpl.cpp | 26 +++---- .../src/control/parser/internal/spd-pimpl.h | 12 +-- redhawk/src/control/parser/internal/spd.map | 4 +- redhawk/src/control/sdr/devmgr/spdSupport.cpp | 8 +- redhawk/src/control/sdr/devmgr/spdSupport.h | 6 +- .../sdr/dommgr/ApplicationFactory_impl.cpp | 27 ++----- .../control/sdr/dommgr/applicationSupport.cpp | 25 ++---- .../control/sdr/dommgr/applicationSupport.h | 15 ++-- redhawk/src/control/sdr/dommgr/createHelper.h | 4 +- 18 files changed, 168 insertions(+), 164 deletions(-) create mode 100644 redhawk/src/control/include/ossie/PropertyRef.h create mode 100644 redhawk/src/control/parser/PropertyRef.cpp diff --git a/redhawk/src/control/include/ossie/PropertyRef.h b/redhawk/src/control/include/ossie/PropertyRef.h new file mode 100644 index 000000000..04710103d --- /dev/null +++ b/redhawk/src/control/include/ossie/PropertyRef.h @@ -0,0 +1,77 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK core. + * + * REDHAWK core is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +#ifndef __PROPERTYREF_H__ +#define __PROPERTYREF_H__ + +#include + +namespace ossie { + + class ComponentProperty; + + class DependencyRef { + public: + std::string type; + + virtual const std::string asString() const = 0; + + virtual ~DependencyRef() {}; + }; + + class PropertyRef : public DependencyRef + { + public: + PropertyRef() : + property() + { + } + + PropertyRef(ComponentProperty* prop) : + property(prop) + { + } + + PropertyRef(const ComponentProperty &prop) : + property(prop.clone()) + { + } + + PropertyRef(const PropertyRef& other) : + property(other.property->clone()) + { + } + + boost::shared_ptr property; + + virtual const std::string asString() const; + virtual ~PropertyRef(); + }; + + template< typename charT, typename Traits> + std::basic_ostream& operator<<(std::basic_ostream &out, const DependencyRef& ref) + { + out << ref.asString(); + return out; + } + +} + +#endif diff --git a/redhawk/src/control/include/ossie/SoftPkg.h b/redhawk/src/control/include/ossie/SoftPkg.h index 5109aa3a5..f428d0f65 100644 --- a/redhawk/src/control/include/ossie/SoftPkg.h +++ b/redhawk/src/control/include/ossie/SoftPkg.h @@ -31,49 +31,14 @@ #include "ossie/ossieparser.h" #include "ossie/componentProfile.h" +#include "PropertyRef.h" + namespace ossie { class SPD { public: typedef std::pair NameVersionPair; - class DependencyRef { - public: - std::string type; - - virtual const std::string asString() const = 0; - - virtual ~DependencyRef() {}; - }; - - class PropertyRef : public DependencyRef { - public: - PropertyRef() : - property() - { - } - - PropertyRef(ComponentProperty* prop) : - property(prop) - { - } - - PropertyRef(const ComponentProperty &prop) : - property(prop.clone()) - { - } - - PropertyRef(const PropertyRef& other) : - property(other.property->clone()) - { - } - - boost::shared_ptr< ossie::ComponentProperty > property; - - virtual const std::string asString() const; - virtual ~PropertyRef(); - }; - class SoftPkgRef : public DependencyRef { public: std::string localfile; @@ -372,13 +337,6 @@ namespace ossie { return out; } - template< typename charT, typename Traits> - std::basic_ostream& operator<<(std::basic_ostream &out, const SPD::DependencyRef& ref) - { - out << ref.asString(); - return out; - } - template< typename charT, typename Traits> std::basic_ostream& operator<<(std::basic_ostream &out, const SPD::UsesDevice& usesdev) { diff --git a/redhawk/src/control/include/ossie/SoftwareAssembly.h b/redhawk/src/control/include/ossie/SoftwareAssembly.h index d7624ee29..a085d37be 100644 --- a/redhawk/src/control/include/ossie/SoftwareAssembly.h +++ b/redhawk/src/control/include/ossie/SoftwareAssembly.h @@ -27,6 +27,8 @@ #include"ossie/componentProfile.h" #include"ossie/exceptions.h" +#include "PropertyRef.h" + namespace ossie { class SoftwareAssembly { public: @@ -77,33 +79,6 @@ namespace ossie { std::string externalpropid; }; - class PropertyRef { - public: - PropertyRef (ComponentProperty* prop) : - property (prop) - { - } - - PropertyRef(const ComponentProperty &prop) : - property(prop.clone()) - { - } - - PropertyRef (const PropertyRef& copy) : - property (copy.property->clone()) - { - } - - virtual ~PropertyRef () - { - - } - - std::string refId; - boost::shared_ptr< ossie::ComponentProperty > property; - - }; - class UsesDevice { public: std::string id; diff --git a/redhawk/src/control/parser/Makefile.am b/redhawk/src/control/parser/Makefile.am index da691660f..fa20c53d3 100644 --- a/redhawk/src/control/parser/Makefile.am +++ b/redhawk/src/control/parser/Makefile.am @@ -24,6 +24,7 @@ noinst_LTLIBRARIES = libossieparser.la libossieparser_la_SOURCES = Properties.cpp \ debug.cpp \ SoftPkg.cpp \ + PropertyRef.cpp \ DomainManagerConfiguration.cpp \ ComponentDescriptor.cpp \ DeviceManagerConfiguration.cpp \ diff --git a/redhawk/src/control/parser/PropertyRef.cpp b/redhawk/src/control/parser/PropertyRef.cpp new file mode 100644 index 000000000..29661695a --- /dev/null +++ b/redhawk/src/control/parser/PropertyRef.cpp @@ -0,0 +1,32 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK core. + * + * REDHAWK core is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +#include +#include + +using namespace ossie; + +PropertyRef::~PropertyRef() { + property.reset(); +} + +const std::string PropertyRef::asString() const { + return property->asString(); +} diff --git a/redhawk/src/control/parser/SoftPkg.cpp b/redhawk/src/control/parser/SoftPkg.cpp index 0c90a147f..4ee9f9365 100644 --- a/redhawk/src/control/parser/SoftPkg.cpp +++ b/redhawk/src/control/parser/SoftPkg.cpp @@ -53,14 +53,6 @@ void SoftPkg::load(std::istream& input, const std::string& spdFile) throw (ossie } } -SPD::PropertyRef::~PropertyRef() { - property.reset(); -} - -const std::string SPD::PropertyRef::asString() const { - return property->asString(); -} - const std::string SPD::SoftPkgRef::asString() const { std::ostringstream out; out << "SoftPkgRef localfile: " << this->localfile << " implref: " << this->implref; diff --git a/redhawk/src/control/parser/internal/sad-pimpl.cpp b/redhawk/src/control/parser/internal/sad-pimpl.cpp index 4f8c77660..2daff9933 100644 --- a/redhawk/src/control/parser/internal/sad-pimpl.cpp +++ b/redhawk/src/control/parser/internal/sad-pimpl.cpp @@ -1300,7 +1300,7 @@ namespace sad } void usesdevice_pimpl:: - propertyref (const ossie::SoftwareAssembly::PropertyRef& propRef) + propertyref (const ossie::PropertyRef& propRef) { uses->dependencies.push_back(propRef); } @@ -1368,10 +1368,10 @@ namespace sad propRef->_value = value; } - ossie::SoftwareAssembly::PropertyRef propertyref_pimpl:: + ossie::PropertyRef propertyref_pimpl:: post_propertyref () { - return ossie::SoftwareAssembly::PropertyRef(propRef->clone()); + return ossie::PropertyRef(propRef->clone()); } } diff --git a/redhawk/src/control/parser/internal/sad-pimpl.h b/redhawk/src/control/parser/internal/sad-pimpl.h index 2e510d86a..8677eae98 100644 --- a/redhawk/src/control/parser/internal/sad-pimpl.h +++ b/redhawk/src/control/parser/internal/sad-pimpl.h @@ -864,7 +864,7 @@ namespace sad pre (); virtual void - propertyref (const ossie::SoftwareAssembly::PropertyRef&); + propertyref (const ossie::PropertyRef&); virtual void simpleref (const ossie::SimplePropertyRef&); @@ -903,7 +903,7 @@ namespace sad virtual void value (const ::std::string&); - virtual ::ossie::SoftwareAssembly::PropertyRef + virtual ::ossie::PropertyRef post_propertyref (); private: diff --git a/redhawk/src/control/parser/internal/sad.map b/redhawk/src/control/parser/internal/sad.map index fe4d47730..631ab8033 100644 --- a/redhawk/src/control/parser/internal/sad.map +++ b/redhawk/src/control/parser/internal/sad.map @@ -62,7 +62,7 @@ namespace urn:mil:jpeojtrs:sca:sad { property "ossie::SoftwareAssembly::Property"; usesdevicedependencies "::std::vector"; usesdevice "ossie::SoftwareAssembly::UsesDevice"; - propertyref "ossie::SoftwareAssembly::PropertyRef"; + propertyref "ossie::PropertyRef"; affinity "const ossie::ComponentInstantiation::AffinityProperties&" "const ossie::ComponentInstantiation::AffinityProperties&"; loggingconfig "const ossie::ComponentInstantiation::LoggingConfig&" "const ossie::ComponentInstantiation::LoggingConfig&"; } diff --git a/redhawk/src/control/parser/internal/spd-pimpl.cpp b/redhawk/src/control/parser/internal/spd-pimpl.cpp index 753c6a66f..ba198ac25 100644 --- a/redhawk/src/control/parser/internal/spd-pimpl.cpp +++ b/redhawk/src/control/parser/internal/spd-pimpl.cpp @@ -296,12 +296,12 @@ processor (const ::std::string& processor) } void implementation_pimpl:: -dependency (ossie::SPD::DependencyRef* dep) +dependency (ossie::DependencyRef* dep) { assert(dep != 0); LOG_TRACE(spd_parser, "add implementation dependencies " << *dep) - if (dynamic_cast(dep) != NULL) { - implementation->dependencies.push_back(*dynamic_cast(dep)); + if (dynamic_cast(dep) != NULL) { + implementation->dependencies.push_back(*dynamic_cast(dep)); } else if (dynamic_cast(dep) != NULL) { implementation->softPkgDependencies.push_back(*dynamic_cast(dep)); } @@ -523,38 +523,38 @@ softpkgref (const ossie::SPD::SoftPkgRef& ref) } void dependency_pimpl:: -propertyref (const ossie::SPD::PropertyRef& ref) +propertyref (const ossie::PropertyRef& ref) { LOG_TRACE(spd_parser, "property ref dep: " << ref) - _ref.reset(new ossie::SPD::PropertyRef(ref)); + _ref.reset(new ossie::PropertyRef(ref)); } void dependency_pimpl:: simpleref (const ossie::SimplePropertyRef& ref) { LOG_TRACE(spd_parser, "simple property ref dep: " << ref); - _ref.reset(new ossie::SPD::PropertyRef(ref)); + _ref.reset(new ossie::PropertyRef(ref)); } void dependency_pimpl:: simplesequenceref (const ossie::SimpleSequencePropertyRef& ref) { LOG_TRACE(spd_parser, "simple sequence property ref dep: " << ref); - _ref.reset(new ossie::SPD::PropertyRef(ref)); + _ref.reset(new ossie::PropertyRef(ref)); } void dependency_pimpl:: structref (const ossie::StructPropertyRef& ref) { LOG_TRACE(spd_parser, "struct property ref dep: " << ref); - _ref.reset(new ossie::SPD::PropertyRef(ref)); + _ref.reset(new ossie::PropertyRef(ref)); } void dependency_pimpl:: structsequenceref (const ossie::StructSequencePropertyRef& ref) { LOG_TRACE(spd_parser, "struct sequence property ref dep: " << ref); - _ref.reset(new ossie::SPD::PropertyRef(ref)); + _ref.reset(new ossie::PropertyRef(ref)); } void dependency_pimpl:: @@ -564,7 +564,7 @@ type (const ::std::string& type) // } -ossie::SPD::DependencyRef* dependency_pimpl:: +ossie::DependencyRef* dependency_pimpl:: post_dependency () { assert(_ref.get() != 0); @@ -620,10 +620,10 @@ value (const ::std::string& value) _ref._value = value; } -ossie::SPD::PropertyRef propertyRef_pimpl:: +ossie::PropertyRef propertyRef_pimpl:: post_propertyRef () { - return ossie::SPD::PropertyRef(_ref); + return ossie::PropertyRef(_ref); } // softPkgRef_pimpl @@ -683,7 +683,7 @@ pre () } void usesDevice_pimpl:: -propertyref (const ossie::SPD::PropertyRef& propertyRef) +propertyref (const ossie::PropertyRef& propertyRef) { _uses->dependencies.push_back(propertyRef); } diff --git a/redhawk/src/control/parser/internal/spd-pimpl.h b/redhawk/src/control/parser/internal/spd-pimpl.h index a6910fd81..71bff4347 100644 --- a/redhawk/src/control/parser/internal/spd-pimpl.h +++ b/redhawk/src/control/parser/internal/spd-pimpl.h @@ -187,7 +187,7 @@ namespace spd processor (const ::std::string&); virtual void - dependency (ossie::SPD::DependencyRef*); + dependency (ossie::DependencyRef*); virtual void usesdevice (const ossie::SPD::UsesDevice&); @@ -326,7 +326,7 @@ namespace spd softpkgref (const ossie::SPD::SoftPkgRef& ref); virtual void - propertyref (const ossie::SPD::PropertyRef&); + propertyref (const ossie::PropertyRef&); virtual void simpleref (const ossie::SimplePropertyRef&); @@ -343,11 +343,11 @@ namespace spd virtual void type (const ::std::string&); - virtual ossie::SPD::DependencyRef* + virtual ossie::DependencyRef* post_dependency (); private: - std::auto_ptr _ref; + std::auto_ptr _ref; }; class runtime_pimpl: public virtual runtime_pskel @@ -381,7 +381,7 @@ namespace spd virtual void value (const ::std::string&); - virtual ossie::SPD::PropertyRef + virtual ossie::PropertyRef post_propertyRef (); private: @@ -432,7 +432,7 @@ namespace spd pre (); virtual void - propertyref (const ossie::SPD::PropertyRef&); + propertyref (const ossie::PropertyRef&); virtual void simpleref (const ossie::SimplePropertyRef&); diff --git a/redhawk/src/control/parser/internal/spd.map b/redhawk/src/control/parser/internal/spd.map index e7b0ca3ce..7c911de2c 100644 --- a/redhawk/src/control/parser/internal/spd.map +++ b/redhawk/src/control/parser/internal/spd.map @@ -34,13 +34,13 @@ descriptor "::std::string"; author "ossie::SPD::Author"; usesDevice "ossie::SPD::UsesDevice"; implementation "ossie::SPD::Implementation"; -dependency "ossie::SPD::DependencyRef*"; +dependency "ossie::DependencyRef*"; codeFileType "::std::string"; code "ossie::SPD::Code"; compiler "ossie::SPD::NameVersionPair"; humanlangauge "::std::string"; programminglanguage "ossie::SPD::NameVersionPair"; -propertyRef "ossie::SPD::PropertyRef"; +propertyRef "ossie::PropertyRef"; softPkgRef "ossie::SPD::SoftPkgRef"; implRef "::std::string"; os "ossie::SPD::NameVersionPair"; diff --git a/redhawk/src/control/sdr/devmgr/spdSupport.cpp b/redhawk/src/control/sdr/devmgr/spdSupport.cpp index 169c0c6e1..f85f7b205 100644 --- a/redhawk/src/control/sdr/devmgr/spdSupport.cpp +++ b/redhawk/src/control/sdr/devmgr/spdSupport.cpp @@ -77,8 +77,8 @@ ImplementationInfo::ImplementationInfo(const SPD::Implementation& spdImpl) : // Handle allocation property dependencies LOG_TRACE(ImplementationInfo, "Loading component implementation property dependencies") - const std::vector& dependencies = spdImpl.getDependencies(); - std::vector::const_iterator ii; + const std::vector& dependencies = spdImpl.getDependencies(); + std::vector::const_iterator ii; for (ii = dependencies.begin(); ii != dependencies.end(); ++ii) { LOG_TRACE(ImplementationInfo, "Loading component implementation property dependency '" << *ii); addDependencyProperty(*ii); @@ -198,7 +198,7 @@ const bool ImplementationInfo::hasPriority() const return _hasPriority; } -const std::vector& ImplementationInfo::getDependencyProperties() const +const std::vector& ImplementationInfo::getDependencyProperties() const { return dependencyProperties; } @@ -251,7 +251,7 @@ void ImplementationInfo::setPriority(const unsigned long long* _priority) } } -void ImplementationInfo::addDependencyProperty(const SPD::PropertyRef& property) +void ImplementationInfo::addDependencyProperty(const PropertyRef& property) { dependencyProperties.push_back(property); } diff --git a/redhawk/src/control/sdr/devmgr/spdSupport.h b/redhawk/src/control/sdr/devmgr/spdSupport.h index 46f357438..58818adce 100644 --- a/redhawk/src/control/sdr/devmgr/spdSupport.h +++ b/redhawk/src/control/sdr/devmgr/spdSupport.h @@ -90,7 +90,7 @@ namespace ossie const CORBA::ULong getPriority() const; const bool hasStackSize() const; const bool hasPriority() const; - const std::vector& getDependencyProperties() const; + const std::vector& getDependencyProperties() const; const std::vector& getSoftPkgDependency() const; bool checkProcessorAndOs(const ossie::Properties& prf) const; @@ -107,7 +107,7 @@ namespace ossie void setCodeType(const char* _type); void setStackSize(const unsigned long long *_stackSize); void setPriority(const unsigned long long *_priority); - void addDependencyProperty(const ossie::SPD::PropertyRef& property); + void addDependencyProperty(const ossie::PropertyRef& property); void addSoftPkgDependency(SoftpkgInfo &softpkg); std::string id; @@ -120,7 +120,7 @@ namespace ossie bool _hasPriority; std::vector processorDeps; std::vector osDeps; - std::vector dependencyProperties; + std::vector dependencyProperties; std::vector softPkgDependencies; }; diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 70b78e611..7131b56ed 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -810,8 +810,8 @@ CF::Properties createHelper::_consolidateAllocations(const DeploymentList& deplo { CF::Properties allocs; for (DeploymentList::const_iterator depl = deployments.begin(); depl != deployments.end(); ++depl) { - const std::vector& deps = (*depl)->getImplementation()->getDependencyProperties(); - for (std::vector::const_iterator dep = deps.begin(); dep != deps.end(); ++dep) { + const std::vector& deps = (*depl)->getImplementation()->getDependencyProperties(); + for (std::vector::const_iterator dep = deps.begin(); dep != deps.end(); ++dep) { ossie::ComponentProperty *prop = dep->property.get(); ossie::corba::push_back(allocs, ossie::convertPropertyRefToDataType(prop)); } @@ -1205,7 +1205,7 @@ CF::Application_ptr createHelper::create ( ////////////////////////////////////////////////// // Store information about this application - _appProfile.populateApplicationProfile(_appFact._sadParser); + _appProfile.load(_appFact._fileMgr, _appFact._sadParser); overrideExternalProperties(app_deployment, modifiedInitConfiguration); @@ -1423,16 +1423,11 @@ CF::AllocationManager::AllocationResponseSequence* createHelper::allocateUsesDev const std::string requestid = usesDevices[usesdev_idx]->getId(); request[usesdev_idx].requestID = requestid.c_str(); - // Get the usesdevice dependency properties, first from the SPD... + // Get the usesdevice dependency properties CF::Properties& allocationProperties = request[usesdev_idx].allocationProperties; - const std::vector&prop_refs = usesDevices[usesdev_idx]->getProperties(); + const std::vector&prop_refs = usesDevices[usesdev_idx]->getProperties(); this->_castRequestProperties(allocationProperties, prop_refs); - // ...then from the SAD; in practice, these are mutually exclusive, but - // there is no harm in doing both, as one set will always be empty - const std::vector& sad_refs = usesDevices[usesdev_idx]->getSadDeps(); - this->_castRequestProperties(allocationProperties, sad_refs, allocationProperties.length()); - this->_evaluateMATHinRequest(allocationProperties, configureProperties); } @@ -1773,7 +1768,7 @@ ossie::AllocationResult createHelper::allocateComponentToDevice(ossie::Component } const std::string requestid = ossie::generateUUID(); - std::vector prop_refs = implementation->getDependencyProperties(); + const std::vector& prop_refs = implementation->getDependencyProperties(); redhawk::PropertyMap allocationProperties; this->_castRequestProperties(allocationProperties, prop_refs); @@ -1821,15 +1816,7 @@ ossie::AllocationResult createHelper::allocateComponentToDevice(ossie::Component return response; } -void createHelper::_castRequestProperties(CF::Properties& allocationProperties, const std::vector &prop_refs, unsigned int offset) -{ - allocationProperties.length(offset+prop_refs.size()); - for (unsigned int i=0; i &prop_refs, unsigned int offset) +void createHelper::_castRequestProperties(CF::Properties& allocationProperties, const std::vector &prop_refs, unsigned int offset) { allocationProperties.length(offset+prop_refs.size()); for (unsigned int i=0; i& _properties) : +UsesDeviceInfo::UsesDeviceInfo(const std::string& _id, const std::string& _type, const std::vector& _properties) : id(_id), type(_type), properties(_properties) @@ -68,14 +68,6 @@ UsesDeviceInfo::UsesDeviceInfo(const std::string& _id, const std::string& _type, } -UsesDeviceInfo::UsesDeviceInfo(const std::string& _id, const std::string& _type, const std::vector& _sadDeps) : - id(_id), - type(_type), - sadDeps(_sadDeps) -{ - -} - UsesDeviceInfo::~UsesDeviceInfo() { } @@ -90,16 +82,11 @@ const std::string& UsesDeviceInfo::getType() const return type; } -const std::vector& UsesDeviceInfo::getProperties() const +const std::vector& UsesDeviceInfo::getProperties() const { return properties; } -const std::vector& UsesDeviceInfo::getSadDeps() const -{ - return sadDeps; -} - const std::string& UsesDeviceInfo::getAssignedDeviceId() const { return assignedDeviceId; @@ -188,8 +175,8 @@ ImplementationInfo::ImplementationInfo(const SPD::Implementation& spdImpl) : // Handle allocation property dependencies LOG_TRACE(ImplementationInfo, "Loading component implementation property dependencies") - const std::vector& dependencies = spdImpl.getDependencies(); - std::vector::const_iterator ii; + const std::vector& dependencies = spdImpl.getDependencies(); + std::vector::const_iterator ii; for (ii = dependencies.begin(); ii != dependencies.end(); ++ii) { LOG_TRACE(ImplementationInfo, "Loading component implementation property dependency '" << *ii); addDependencyProperty(*ii); @@ -275,7 +262,7 @@ const bool ImplementationInfo::hasPriority() const return _hasPriority; } -const std::vector& ImplementationInfo::getDependencyProperties() const +const std::vector& ImplementationInfo::getDependencyProperties() const { return dependencyProperties; } @@ -321,7 +308,7 @@ void ImplementationInfo::setPriority(const unsigned long long* _priority) } } -void ImplementationInfo::addDependencyProperty(const SPD::PropertyRef& property) +void ImplementationInfo::addDependencyProperty(const PropertyRef& property) { dependencyProperties.push_back(property); } diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.h b/redhawk/src/control/sdr/dommgr/applicationSupport.h index 9108a660c..11c74b58c 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.h +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.h @@ -63,14 +63,12 @@ namespace ossie public: typedef std::vector< UsesDeviceInfo * > List; - UsesDeviceInfo(const std::string& id, const std::string& type, const std::vector& _properties); - UsesDeviceInfo(const std::string& id, const std::string& type, const std::vector& _sadDeps); + UsesDeviceInfo(const std::string& id, const std::string& type, const std::vector& _properties); ~UsesDeviceInfo(); const std::string& getId() const; const std::string& getType() const; - const std::vector& getProperties() const; - const std::vector& getSadDeps() const; + const std::vector& getProperties() const; const std::string& getAssignedDeviceId() const; void setAssignedDeviceId(const std::string& deviceId); @@ -79,8 +77,7 @@ namespace ossie private: std::string id; std::string type; - std::vector properties; - std::vector sadDeps; + std::vector properties; std::string assignedDeviceId; }; @@ -131,7 +128,7 @@ namespace ossie const CORBA::ULong getPriority() const; const bool hasStackSize() const; const bool hasPriority() const; - const std::vector& getDependencyProperties() const; + const std::vector& getDependencyProperties() const; const std::vector& getSoftPkgDependency() const; bool checkProcessorAndOs(const ossie::Properties& prf) const; @@ -144,7 +141,7 @@ namespace ossie void setCodeType(const char* _type); void setStackSize(const unsigned long long *_stackSize); void setPriority(const unsigned long long *_priority); - void addDependencyProperty(const ossie::SPD::PropertyRef& property); + void addDependencyProperty(const ossie::PropertyRef& property); void addSoftPkgDependency(SoftpkgInfo* softpkg); std::string id; @@ -157,7 +154,7 @@ namespace ossie bool _hasPriority; std::vector processorDeps; std::vector osDeps; - std::vector dependencyProperties; + std::vector dependencyProperties; std::vector softPkgDependencies; }; diff --git a/redhawk/src/control/sdr/dommgr/createHelper.h b/redhawk/src/control/sdr/dommgr/createHelper.h index 60318ba2f..16159ce3c 100644 --- a/redhawk/src/control/sdr/dommgr/createHelper.h +++ b/redhawk/src/control/sdr/dommgr/createHelper.h @@ -134,9 +134,7 @@ class createHelper CF::Properties _consolidateAllocations(const DeploymentList& implementations); void _evaluateMATHinRequest(CF::Properties &request, const CF::Properties &configureProperties); - void _castRequestProperties(CF::Properties& allocationProperties, const std::vector &prop_refs, unsigned int offset=0); - void _castRequestProperties(CF::Properties& allocationProperties, const std::vector &prop_refs, - unsigned int offset=0); + void _castRequestProperties(CF::Properties& allocationProperties, const std::vector &prop_refs, unsigned int offset=0); // Populate _requiredComponents vector void getRequiredComponents(CF::FileSystem_ptr fileSys, From 6d5d705669d5bcf70df569c0aeb0cbc4b34a5154 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 19 May 2016 11:21:26 -0400 Subject: [PATCH 0245/1644] Consolidate SAD and SPD parser usesdevice --- redhawk/src/control/include/ossie/SoftPkg.h | 30 +--------- .../control/include/ossie/SoftwareAssembly.h | 24 +------- .../src/control/include/ossie/UsesDevice.h | 56 +++++++++++++++++++ .../src/control/parser/SoftwareAssembly.cpp | 2 +- .../src/control/parser/internal/sad-pimpl.cpp | 10 ++-- .../src/control/parser/internal/sad-pimpl.h | 12 ++-- redhawk/src/control/parser/internal/sad.map | 4 +- .../src/control/parser/internal/spd-pimpl.cpp | 8 +-- .../src/control/parser/internal/spd-pimpl.h | 8 +-- redhawk/src/control/parser/internal/spd.map | 4 +- .../control/sdr/dommgr/ApplicationProfile.cpp | 6 +- .../control/sdr/dommgr/applicationSupport.cpp | 8 +-- 12 files changed, 93 insertions(+), 79 deletions(-) create mode 100644 redhawk/src/control/include/ossie/UsesDevice.h diff --git a/redhawk/src/control/include/ossie/SoftPkg.h b/redhawk/src/control/include/ossie/SoftPkg.h index f428d0f65..fe42521e6 100644 --- a/redhawk/src/control/include/ossie/SoftPkg.h +++ b/redhawk/src/control/include/ossie/SoftPkg.h @@ -32,6 +32,7 @@ #include "ossie/componentProfile.h" #include "PropertyRef.h" +#include "UsesDevice.h" namespace ossie { @@ -59,24 +60,6 @@ namespace ossie { optional_value webpage; }; - class UsesDevice { - public: - std::string id; - std::string type; - std::vector dependencies; - - const std::string& getID() const { - return id; - } - - const std::string& getType() const { - return type; - } - - const std::vector& getDependencies() const { - return dependencies; - } - }; class Code { public: @@ -179,7 +162,7 @@ namespace ossie { } } - const std::vector& getUsesDevices() const { + const std::vector& getUsesDevices() const { return usesDevice; }; @@ -309,7 +292,7 @@ namespace ossie { return _spd->implementations; } - const std::vector& getUsesDevices() const { + const std::vector& getUsesDevices() const { assert(_spd.get() != 0); return _spd->usesDevice; }; @@ -337,12 +320,5 @@ namespace ossie { return out; } - template< typename charT, typename Traits> - std::basic_ostream& operator<<(std::basic_ostream &out, const SPD::UsesDevice& usesdev) - { - out << "Uses Device id: " << usesdev.id << " type: " << usesdev.type; - return out; - } - } #endif diff --git a/redhawk/src/control/include/ossie/SoftwareAssembly.h b/redhawk/src/control/include/ossie/SoftwareAssembly.h index a085d37be..bf200c3bf 100644 --- a/redhawk/src/control/include/ossie/SoftwareAssembly.h +++ b/redhawk/src/control/include/ossie/SoftwareAssembly.h @@ -28,6 +28,7 @@ #include"ossie/exceptions.h" #include "PropertyRef.h" +#include "UsesDevice.h" namespace ossie { class SoftwareAssembly { @@ -79,25 +80,6 @@ namespace ossie { std::string externalpropid; }; - class UsesDevice { - public: - std::string id; - std::string type; - std::vector dependencies; - - const std::string& getId() const { - return id; - } - - const std::string& getType() const { - return type; - } - - const std::vector& getDependencies() const { - return dependencies; - } - }; - class SAD { public: std::string id; @@ -108,7 +90,7 @@ namespace ossie { std::vector componentfiles; std::vector externalports; std::vector externalproperties; - std::vector usesdevice; + std::vector usesdevice; }; SoftwareAssembly() : _sad(0) {} @@ -139,7 +121,7 @@ namespace ossie { const std::vector& getExternalProperties() const; - const std::vector& getUsesDevices() const; + const std::vector& getUsesDevices() const; protected: std::auto_ptr _sad; diff --git a/redhawk/src/control/include/ossie/UsesDevice.h b/redhawk/src/control/include/ossie/UsesDevice.h new file mode 100644 index 000000000..2f14efb41 --- /dev/null +++ b/redhawk/src/control/include/ossie/UsesDevice.h @@ -0,0 +1,56 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK core. + * + * REDHAWK core is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +#ifndef __USESDEVICE_H__ +#define __USESDEVICE_H__ + +#include +#include + +#include "PropertyRef.h" + +namespace ossie { + class UsesDevice { + public: + std::string id; + std::string type; + std::vector dependencies; + + const std::string& getID() const { + return id; + } + + const std::string& getType() const { + return type; + } + + const std::vector& getDependencies() const { + return dependencies; + } + }; + + inline std::ostream& operator<<(std::ostream& out, const UsesDevice& usesdev) + { + out << "Uses Device id: " << usesdev.id << " type: " << usesdev.type; + return out; + } +} + +#endif diff --git a/redhawk/src/control/parser/SoftwareAssembly.cpp b/redhawk/src/control/parser/SoftwareAssembly.cpp index fb16e01c9..8699e15ed 100644 --- a/redhawk/src/control/parser/SoftwareAssembly.cpp +++ b/redhawk/src/control/parser/SoftwareAssembly.cpp @@ -110,7 +110,7 @@ const std::vector& SoftwareAssembly::getExternalProp return _sad->externalproperties; } -const std::vector& SoftwareAssembly::getUsesDevices() const { +const std::vector& SoftwareAssembly::getUsesDevices() const { assert(_sad.get() != 0); return _sad->usesdevice; } diff --git a/redhawk/src/control/parser/internal/sad-pimpl.cpp b/redhawk/src/control/parser/internal/sad-pimpl.cpp index 2daff9933..0c95abe69 100644 --- a/redhawk/src/control/parser/internal/sad-pimpl.cpp +++ b/redhawk/src/control/parser/internal/sad-pimpl.cpp @@ -86,7 +86,7 @@ namespace sad } void softwareassembly_pimpl:: - usesdevicedependencies (const ::std::vector& usesdevices) + usesdevicedependencies (const ::std::vector& usesdevices) { _sad->usesdevice = usesdevices; } @@ -1279,12 +1279,12 @@ namespace sad } void usesdevicedependencies_pimpl:: - usesdevice (const ossie::SoftwareAssembly::UsesDevice& use) + usesdevice (const ossie::UsesDevice& use) { usesDevices.push_back(use); } - ::std::vector usesdevicedependencies_pimpl:: + ::std::vector usesdevicedependencies_pimpl:: post_usesdevicedependencies () { return usesDevices; @@ -1296,7 +1296,7 @@ namespace sad void usesdevice_pimpl:: pre () { - uses.reset(new ossie::SoftwareAssembly::UsesDevice()); + uses.reset(new ossie::UsesDevice()); } void usesdevice_pimpl:: @@ -1341,7 +1341,7 @@ namespace sad uses->type = type; } - ossie::SoftwareAssembly::UsesDevice usesdevice_pimpl:: + ossie::UsesDevice usesdevice_pimpl:: post_usesdevice () { return *uses; diff --git a/redhawk/src/control/parser/internal/sad-pimpl.h b/redhawk/src/control/parser/internal/sad-pimpl.h index 8677eae98..d84ddafe9 100644 --- a/redhawk/src/control/parser/internal/sad-pimpl.h +++ b/redhawk/src/control/parser/internal/sad-pimpl.h @@ -59,7 +59,7 @@ namespace sad externalproperties (const ::std::vector&); virtual void - usesdevicedependencies (const ::std::vector&); + usesdevicedependencies (const ::std::vector&); virtual void id (const ::std::string&); @@ -848,13 +848,13 @@ namespace sad pre (); virtual void - usesdevice (const ossie::SoftwareAssembly::UsesDevice&); + usesdevice (const ossie::UsesDevice&); - virtual ::std::vector + virtual ::std::vector post_usesdevicedependencies (); private: - std::vector usesDevices; + std::vector usesDevices; }; class usesdevice_pimpl: public virtual usesdevice_pskel @@ -884,11 +884,11 @@ namespace sad virtual void type (const ::std::string&); - virtual ossie::SoftwareAssembly::UsesDevice + virtual ossie::UsesDevice post_usesdevice (); private: - std::auto_ptr uses; + std::auto_ptr uses; }; class propertyref_pimpl: public virtual propertyref_pskel diff --git a/redhawk/src/control/parser/internal/sad.map b/redhawk/src/control/parser/internal/sad.map index 631ab8033..ec24414a1 100644 --- a/redhawk/src/control/parser/internal/sad.map +++ b/redhawk/src/control/parser/internal/sad.map @@ -60,8 +60,8 @@ namespace urn:mil:jpeojtrs:sca:sad { supportedidentifier "::std::string"; externalproperties "::std::vector"; property "ossie::SoftwareAssembly::Property"; - usesdevicedependencies "::std::vector"; - usesdevice "ossie::SoftwareAssembly::UsesDevice"; + usesdevicedependencies "::std::vector"; + usesdevice "ossie::UsesDevice"; propertyref "ossie::PropertyRef"; affinity "const ossie::ComponentInstantiation::AffinityProperties&" "const ossie::ComponentInstantiation::AffinityProperties&"; loggingconfig "const ossie::ComponentInstantiation::LoggingConfig&" "const ossie::ComponentInstantiation::LoggingConfig&"; diff --git a/redhawk/src/control/parser/internal/spd-pimpl.cpp b/redhawk/src/control/parser/internal/spd-pimpl.cpp index ba198ac25..deab39764 100644 --- a/redhawk/src/control/parser/internal/spd-pimpl.cpp +++ b/redhawk/src/control/parser/internal/spd-pimpl.cpp @@ -80,7 +80,7 @@ implementation (const ossie::SPD::Implementation& implementation) } void softPkg_pimpl:: -usesdevice (const ossie::SPD::UsesDevice& usesdev) +usesdevice (const ossie::UsesDevice& usesdev) { LOG_TRACE(spd_parser, "softpkg usesdev " << usesdev) _spd->usesDevice.push_back(usesdev); @@ -308,7 +308,7 @@ dependency (ossie::DependencyRef* dep) } void implementation_pimpl:: -usesdevice (const ossie::SPD::UsesDevice& usesdev) +usesdevice (const ossie::UsesDevice& usesdev) { LOG_TRACE(spd_parser, "implementation usesdev " << usesdev) implementation->usesDevice.push_back(usesdev); @@ -679,7 +679,7 @@ post_implRef () void usesDevice_pimpl:: pre () { - _uses.reset(new ossie::SPD::UsesDevice()); + _uses.reset(new ossie::UsesDevice()); } void usesDevice_pimpl:: @@ -724,7 +724,7 @@ type (const ::std::string& type) _uses->type = type; } -ossie::SPD::UsesDevice usesDevice_pimpl:: +ossie::UsesDevice usesDevice_pimpl:: post_usesDevice () { assert(_uses.get() != 0); diff --git a/redhawk/src/control/parser/internal/spd-pimpl.h b/redhawk/src/control/parser/internal/spd-pimpl.h index 71bff4347..680af1ed9 100644 --- a/redhawk/src/control/parser/internal/spd-pimpl.h +++ b/redhawk/src/control/parser/internal/spd-pimpl.h @@ -56,7 +56,7 @@ namespace spd implementation (const ossie::SPD::Implementation&); virtual void - usesdevice (const ossie::SPD::UsesDevice&); + usesdevice (const ossie::UsesDevice&); virtual void id (const ::std::string&); @@ -190,7 +190,7 @@ namespace spd dependency (ossie::DependencyRef*); virtual void - usesdevice (const ossie::SPD::UsesDevice&); + usesdevice (const ossie::UsesDevice&); virtual void id (const ::std::string&); @@ -452,11 +452,11 @@ namespace spd virtual void type (const ::std::string&); - virtual ossie::SPD::UsesDevice + virtual ossie::UsesDevice post_usesDevice (); private: - std::auto_ptr _uses; + std::auto_ptr _uses; }; class aepcompliance_pimpl: public virtual aepcompliance_pskel, diff --git a/redhawk/src/control/parser/internal/spd.map b/redhawk/src/control/parser/internal/spd.map index 7c911de2c..9ac79e375 100644 --- a/redhawk/src/control/parser/internal/spd.map +++ b/redhawk/src/control/parser/internal/spd.map @@ -32,7 +32,7 @@ softPkg "std::auto_ptr"; propertyFile "::std::string"; descriptor "::std::string"; author "ossie::SPD::Author"; -usesDevice "ossie::SPD::UsesDevice"; +usesDevice "ossie::UsesDevice"; implementation "ossie::SPD::Implementation"; dependency "ossie::DependencyRef*"; codeFileType "::std::string"; @@ -46,7 +46,7 @@ implRef "::std::string"; os "ossie::SPD::NameVersionPair"; processor "::std::string"; runtime "ossie::SPD::NameVersionPair"; -usesdevice "::std::vector"; +usesdevice "::std::vector"; simpleref "const ossie::SimplePropertyRef &" "const ossie::SimplePropertyRef &"; simplesequenceref "const ossie::SimpleSequencePropertyRef &" "const ossie::SimpleSequencePropertyRef &"; structref "const ossie::StructPropertyRef &" "const ossie::StructPropertyRef &"; diff --git a/redhawk/src/control/sdr/dommgr/ApplicationProfile.cpp b/redhawk/src/control/sdr/dommgr/ApplicationProfile.cpp index 9aa379f3c..6d609931a 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationProfile.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationProfile.cpp @@ -183,9 +183,9 @@ void ApplicationProfile::load(CF::FileSystem_ptr fileSystem, const SoftwareAssem identifier = sad.getID(); // Gets uses device relationships - const std::vector& usesDevice = sad.getUsesDevices(); - for (std::vector::const_iterator use = usesDevice.begin(); use != usesDevice.end(); ++use) { - UsesDeviceInfo* useDev = new UsesDeviceInfo(use->getId(), use->getType(), use->getDependencies()); + const std::vector& usesDevice = sad.getUsesDevices(); + for (std::vector::const_iterator use = usesDevice.begin(); use != usesDevice.end(); ++use) { + UsesDeviceInfo* useDev = new UsesDeviceInfo(use->getID(), use->getType(), use->getDependencies()); addUsesDevice(useDev); } diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp index 0b45ce2af..c097e664a 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp @@ -165,9 +165,9 @@ ImplementationInfo::ImplementationInfo(const SPD::Implementation& spdImpl) : // Create local copies for all of the usesdevice entries for this implementation. LOG_TRACE(ImplementationInfo, "Loading component implementation uses device") - const std::vector& spdUsesDevices = spdImpl.getUsesDevices(); + const std::vector& spdUsesDevices = spdImpl.getUsesDevices(); for (size_t ii = 0; ii < spdUsesDevices.size(); ++ii) { - const SPD::UsesDevice& spdUsesDev = spdUsesDevices[ii]; + const UsesDevice& spdUsesDev = spdUsesDevices[ii]; UsesDeviceInfo* usesDevice = new UsesDeviceInfo(spdUsesDev.getID(), spdUsesDev.getType(), spdUsesDev.getDependencies()); addUsesDevice(usesDevice); @@ -400,9 +400,9 @@ bool SoftpkgInfo::parseProfile(CF::FileSystem_ptr fileSys) } // Create local copies for all of the usesdevice entries for this implementation. - const std::vector& spdUsesDevices = spd.getUsesDevices(); + const std::vector& spdUsesDevices = spd.getUsesDevices(); for (size_t ii = 0; ii < spdUsesDevices.size(); ++ii) { - const SPD::UsesDevice& spdUsesDev = spdUsesDevices[ii]; + const UsesDevice& spdUsesDev = spdUsesDevices[ii]; UsesDeviceInfo* usesDevice = new UsesDeviceInfo(spdUsesDev.getID(), spdUsesDev.getType(), spdUsesDev.getDependencies()); addUsesDevice(usesDevice); From 01960d24505cc3f254819e114778cd77a6fa8e7f Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 19 May 2016 11:27:05 -0400 Subject: [PATCH 0246/1644] Remove unused vestigial member and method --- redhawk/src/control/include/ossie/componentProfile.h | 3 --- redhawk/src/control/parser/componentProfile.cpp | 4 ---- 2 files changed, 7 deletions(-) diff --git a/redhawk/src/control/include/ossie/componentProfile.h b/redhawk/src/control/include/ossie/componentProfile.h index b60ca36be..b52bb9cf1 100644 --- a/redhawk/src/control/include/ossie/componentProfile.h +++ b/redhawk/src/control/include/ossie/componentProfile.h @@ -208,7 +208,6 @@ namespace ossie { */ class ComponentPlacement { public: - bool ifDomainManager; std::string _componentFileRef; ossie::optional_value deployOnDeviceID; @@ -230,8 +229,6 @@ namespace ossie { bool isDeployOn() const; bool isCompositePartOf() const; - - bool isDomainManager() const; }; /* diff --git a/redhawk/src/control/parser/componentProfile.cpp b/redhawk/src/control/parser/componentProfile.cpp index d3cf6f89c..07c2d17aa 100644 --- a/redhawk/src/control/parser/componentProfile.cpp +++ b/redhawk/src/control/parser/componentProfile.cpp @@ -235,7 +235,3 @@ bool ComponentPlacement::isDeployOn() const { bool ComponentPlacement::isCompositePartOf() const { return compositePartOfDeviceID.isSet(); } - -bool ComponentPlacement::isDomainManager() const { - return false; -} From d0cdf5688b45ee8863a3820b5c1587f7e4d7cd21 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 19 May 2016 11:43:42 -0400 Subject: [PATCH 0247/1644] Separate device placement out of basic component placement --- .../ossie/DeviceManagerConfiguration.h | 23 +++++++++- .../control/include/ossie/componentProfile.h | 13 ------ .../parser/DeviceManagerConfiguration.cpp | 42 +++++++++++++++++-- .../src/control/parser/componentProfile.cpp | 32 -------------- .../src/control/parser/internal/dcd-pimpl.cpp | 10 ++--- .../src/control/parser/internal/dcd-pimpl.h | 14 +++---- redhawk/src/control/parser/internal/dcd.map | 4 +- .../control/sdr/devmgr/DeviceManager_impl.cpp | 34 +++++++-------- .../control/sdr/devmgr/DeviceManager_impl.h | 22 +++++----- .../control/sdr/dommgr/DomainManager_impl.cpp | 6 +-- 10 files changed, 105 insertions(+), 95 deletions(-) diff --git a/redhawk/src/control/include/ossie/DeviceManagerConfiguration.h b/redhawk/src/control/include/ossie/DeviceManagerConfiguration.h index 17b31040d..2c31c397f 100644 --- a/redhawk/src/control/include/ossie/DeviceManagerConfiguration.h +++ b/redhawk/src/control/include/ossie/DeviceManagerConfiguration.h @@ -32,6 +32,25 @@ #include "ossie/componentProfile.h" namespace ossie { + + class DevicePlacement : public ComponentPlacement + { + public: + ossie::optional_value deployOnDeviceID; + ossie::optional_value compositePartOfDeviceID; + ossie::optional_value DPDFile; + + const char* getDeployOnDeviceID() const; + + const char* getCompositePartOfDeviceID() const; + + const std::string getDPDFile() const; + + bool isDeployOn() const; + + bool isCompositePartOf() const; + }; + class DeviceManagerConfiguration { ENABLE_LOGGING @@ -47,7 +66,7 @@ namespace ossie { std::string deviceManagerSoftPkg; std::string domainManagerName; std::vector componentFiles; - std::vector componentPlacements; + std::vector componentPlacements; std::vector connections; }; @@ -86,7 +105,7 @@ namespace ossie { const std::vector& getComponentFiles(); - const std::vector& getComponentPlacements(); + const std::vector& getComponentPlacements(); const std::vector& getConnections(); diff --git a/redhawk/src/control/include/ossie/componentProfile.h b/redhawk/src/control/include/ossie/componentProfile.h index b52bb9cf1..41363e5ee 100644 --- a/redhawk/src/control/include/ossie/componentProfile.h +++ b/redhawk/src/control/include/ossie/componentProfile.h @@ -210,25 +210,12 @@ namespace ossie { public: std::string _componentFileRef; - ossie::optional_value deployOnDeviceID; - ossie::optional_value compositePartOfDeviceID; - ossie::optional_value DPDFile; std::vector instantiations; public: - const char* getDeployOnDeviceID() const; - - const char* getCompositePartOfDeviceID() const; - - const std::string getDPDFile() const; - const std::vector& getInstantiations() const; const std::string& getFileRefId() const; - - bool isDeployOn() const; - - bool isCompositePartOf() const; }; /* diff --git a/redhawk/src/control/parser/DeviceManagerConfiguration.cpp b/redhawk/src/control/parser/DeviceManagerConfiguration.cpp index 4675d81e9..cae5b2459 100644 --- a/redhawk/src/control/parser/DeviceManagerConfiguration.cpp +++ b/redhawk/src/control/parser/DeviceManagerConfiguration.cpp @@ -60,7 +60,7 @@ const std::vector& DeviceManagerConfiguration::getComponentFiles( return _dcd->componentFiles; } -const std::vector& DeviceManagerConfiguration::getComponentPlacements() { +const std::vector& DeviceManagerConfiguration::getComponentPlacements() { assert(_dcd.get() != 0); return _dcd->componentPlacements; } @@ -84,8 +84,8 @@ const char* DeviceManagerConfiguration::getFileNameFromRefId(const char* refid) } const ComponentInstantiation& DeviceManagerConfiguration::getComponentInstantiationById(std::string id) throw(std::out_of_range) { - const std::vector& componentPlacements = getComponentPlacements(); - std::vector::const_iterator i; + const std::vector& componentPlacements = getComponentPlacements(); + std::vector::const_iterator i; for (i = componentPlacements.begin(); i != componentPlacements.end(); ++i) { assert(i->getInstantiations().size() > 0); const ComponentInstantiation& instantiation = i->getInstantiations().at(0); @@ -96,3 +96,39 @@ const ComponentInstantiation& DeviceManagerConfiguration::getComponentInstantiat } throw std::out_of_range("No instantiation with id " + id); } + + +// +// DevicePlacement +// +const char* DevicePlacement::getDeployOnDeviceID() const { + if (deployOnDeviceID.isSet()) { + return deployOnDeviceID->c_str(); + } else { + return 0; + } +} + +const char* DevicePlacement::getCompositePartOfDeviceID() const { + if (compositePartOfDeviceID.isSet()) { + return compositePartOfDeviceID->c_str(); + } else { + return 0; + } +} + +const std::string DevicePlacement::getDPDFile() const { + if (DPDFile.isSet()) { + return DPDFile->c_str(); + } else { + return 0; + } +} + +bool DevicePlacement::isDeployOn() const { + return deployOnDeviceID.isSet(); +} + +bool DevicePlacement::isCompositePartOf() const { + return compositePartOfDeviceID.isSet(); +} diff --git a/redhawk/src/control/parser/componentProfile.cpp b/redhawk/src/control/parser/componentProfile.cpp index 07c2d17aa..108c4e663 100644 --- a/redhawk/src/control/parser/componentProfile.cpp +++ b/redhawk/src/control/parser/componentProfile.cpp @@ -196,30 +196,6 @@ const ComponentInstantiation::LoggingConfig &ComponentInstantiation::getLoggingC // // ComponentPlacement // -const char* ComponentPlacement::getDeployOnDeviceID() const { - if (deployOnDeviceID.isSet()) { - return deployOnDeviceID->c_str(); - } else { - return 0; - } -} - -const char* ComponentPlacement::getCompositePartOfDeviceID() const { - if (compositePartOfDeviceID.isSet()) { - return compositePartOfDeviceID->c_str(); - } else { - return 0; - } -} - -const std::string ComponentPlacement::getDPDFile() const { - if (DPDFile.isSet()) { - return DPDFile->c_str(); - } else { - return 0; - } -} - const std::vector& ComponentPlacement::getInstantiations() const { return instantiations; }; @@ -227,11 +203,3 @@ const std::vector& ComponentPlacement::getInstantiations const std::string& ComponentPlacement::getFileRefId() const { return _componentFileRef; } - -bool ComponentPlacement::isDeployOn() const { - return deployOnDeviceID.isSet(); -} - -bool ComponentPlacement::isCompositePartOf() const { - return compositePartOfDeviceID.isSet(); -} diff --git a/redhawk/src/control/parser/internal/dcd-pimpl.cpp b/redhawk/src/control/parser/internal/dcd-pimpl.cpp index 6ed35d46c..d2ece82b0 100644 --- a/redhawk/src/control/parser/internal/dcd-pimpl.cpp +++ b/redhawk/src/control/parser/internal/dcd-pimpl.cpp @@ -63,7 +63,7 @@ namespace dcd } void deviceconfiguration_pimpl:: - partitioning (const ::std::vector& partitioning) + partitioning (const ::std::vector& partitioning) { LOG_TRACE(dcd_parser, "set partitioning") assert(_dcd.get() != 0); @@ -221,13 +221,13 @@ const ::ossie::ComponentFile &componentfile_pimpl:: } void partitioning_pimpl:: - componentplacement (const ::ossie::ComponentPlacement& componentplacement) + componentplacement (const ::ossie::DevicePlacement& componentplacement) { LOG_TRACE(dcd_parser, "adding component placement " << componentplacement.getFileRefId()); componentPlacements.push_back(componentplacement); } - ::std::vector partitioning_pimpl:: + ::std::vector partitioning_pimpl:: post_partitioning () { LOG_TRACE(dcd_parser, "post partitioning"); @@ -240,7 +240,7 @@ const ::ossie::ComponentFile &componentfile_pimpl:: void componentplacement_pimpl:: pre () { - componentPlacement = ossie::ComponentPlacement(); + componentPlacement = ossie::DevicePlacement(); } void componentplacement_pimpl:: @@ -274,7 +274,7 @@ const ::ossie::ComponentFile &componentfile_pimpl:: componentPlacement.instantiations.push_back(componentinstantiation); } - const ::ossie::ComponentPlacement& componentplacement_pimpl:: + const ::ossie::DevicePlacement& componentplacement_pimpl:: post_componentplacement () { LOG_TRACE(dcd_parser, "post componentplacement"); diff --git a/redhawk/src/control/parser/internal/dcd-pimpl.h b/redhawk/src/control/parser/internal/dcd-pimpl.h index 78041f3dc..f3c4745cb 100644 --- a/redhawk/src/control/parser/internal/dcd-pimpl.h +++ b/redhawk/src/control/parser/internal/dcd-pimpl.h @@ -47,7 +47,7 @@ namespace dcd componentfiles (const ::std::vector&); virtual void - partitioning (const ::std::vector&); + partitioning (const ::std::vector&); virtual void domainmanager (const ::std::string&); @@ -148,13 +148,13 @@ namespace dcd pre (); virtual void - componentplacement (const ::ossie::ComponentPlacement&); + componentplacement (const ::ossie::DevicePlacement&); - virtual ::std::vector + virtual ::std::vector post_partitioning (); private: - std::vector componentPlacements; + std::vector componentPlacements; }; class componentplacement_pimpl: public virtual componentplacement_pskel @@ -178,12 +178,12 @@ namespace dcd virtual void componentinstantiation (const ::ossie::ComponentInstantiation&); - virtual const ::ossie::ComponentPlacement& + virtual const ::ossie::DevicePlacement& post_componentplacement (); private: - //std::auto_ptr componentPlacement; - ossie::ComponentPlacement componentPlacement; + //std::auto_ptr componentPlacement; + ossie::DevicePlacement componentPlacement; }; class componentfileref_pimpl: public virtual componentfileref_pskel diff --git a/redhawk/src/control/parser/internal/dcd.map b/redhawk/src/control/parser/internal/dcd.map index 2e9b544b0..4c580272f 100644 --- a/redhawk/src/control/parser/internal/dcd.map +++ b/redhawk/src/control/parser/internal/dcd.map @@ -25,8 +25,8 @@ namespace urn:mil:jpeojtrs:sca:dcd { deviceconfiguration "::std::auto_ptr"; componentfiles "const ::std::vector&" "const ::std::vector&"; componentfile "const ::ossie::ComponentFile&" "const ::ossie::ComponentFile&"; - componentplacement "const ::ossie::ComponentPlacement&" "const ::ossie::ComponentPlacement&"; - partitioning "::std::vector"; + componentplacement "const ::ossie::DevicePlacement&" "const ::ossie::DevicePlacement&"; + partitioning "::std::vector"; componentinstantiation "const ::ossie::ComponentInstantiation&" "const ::ossie::ComponentInstantiation&"; connections "::std::vector"; connectinterface "::ossie::Connection"; diff --git a/redhawk/src/control/sdr/devmgr/DeviceManager_impl.cpp b/redhawk/src/control/sdr/devmgr/DeviceManager_impl.cpp index be30c4337..e4e414353 100644 --- a/redhawk/src/control/sdr/devmgr/DeviceManager_impl.cpp +++ b/redhawk/src/control/sdr/devmgr/DeviceManager_impl.cpp @@ -198,7 +198,7 @@ void DeviceManager_impl::resolveNamingContext(){ bool DeviceManager_impl::loadSPD( SoftPkg& SPDParser, DeviceManagerConfiguration& DCDParser, - const ComponentPlacement& componentPlacement) { + const DevicePlacement& componentPlacement) { LOG_TRACE(DeviceManager_impl, "Getting file name for refid " << componentPlacement.getFileRefId()); const char* spdFile = DCDParser.getFileNameFromRefId(componentPlacement.getFileRefId().c_str()); @@ -434,9 +434,9 @@ void DeviceManager_impl::registerDeviceManagerWithDomainManager( } void DeviceManager_impl::getCompositeDeviceIOR( - std::string& compositeDeviceIOR, - const std::vector& componentPlacements, - const ossie::ComponentPlacement& componentPlacementInst) { + std::string& compositeDeviceIOR, + const std::vector& componentPlacements, + const ossie::DevicePlacement& componentPlacementInst) { //see if component is composite part of device LOG_TRACE(DeviceManager_impl, "Checking composite part of device"); @@ -699,14 +699,14 @@ void DeviceManager_impl::createDeviceCacheLocation( */ void DeviceManager_impl::createDeviceExecStatement( std::vector< std::string >& new_argv, - const ossie::ComponentPlacement& componentPlacement, + const ossie::DevicePlacement& componentPlacement, const std::string& componentType, std::map* pOverloadprops, const std::string& codeFilePath, ossie::DeviceManagerConfiguration& DCDParser, const ossie::ComponentInstantiation& instantiation, const std::string& usageName, - const std::vector& componentPlacements, + const std::vector& componentPlacements, const std::string& compositeDeviceIOR, const ossie::ComponentPropertyList& instanceprops) { @@ -834,7 +834,7 @@ void DeviceManager_impl::createDeviceExecStatement( } DeviceManager_impl::ExecparamList DeviceManager_impl::createDeviceExecparams( - const ossie::ComponentPlacement& componentPlacement, + const ossie::DevicePlacement& componentPlacement, const std::string& componentType, std::map* pOverloadprops, const std::string& codeFilePath, @@ -941,14 +941,14 @@ DeviceManager_impl::ExecparamList DeviceManager_impl::createDeviceExecparams( } void DeviceManager_impl::createDeviceThreadAndHandleExceptions( - const ossie::ComponentPlacement& componentPlacement, + const ossie::DevicePlacement& componentPlacement, const std::string& componentType, std::map* pOverloadprops, const std::string& codeFilePath, const ossie::SoftPkg& SPDParser, ossie::DeviceManagerConfiguration& DCDParser, const ossie::ComponentInstantiation& instantiation, - const std::vector& componentPlacements, + const std::vector& componentPlacements, const std::string& compositeDeviceIOR, const ossie::ComponentPropertyList& instanceprops) { @@ -988,7 +988,7 @@ void DeviceManager_impl::createDeviceThreadAndHandleExceptions( } void DeviceManager_impl::createDeviceThread( - const ossie::ComponentPlacement& componentPlacement, + const ossie::DevicePlacement& componentPlacement, const std::string& componentType, std::map* pOverloadprops, const std::string& codeFilePath, @@ -997,7 +997,7 @@ void DeviceManager_impl::createDeviceThread( const ossie::ComponentInstantiation& instantiation, const std::string& devcache, const std::string& usageName, - const std::vector& componentPlacements, + const std::vector& componentPlacements, const std::string& compositeDeviceIOR, const ossie::ComponentPropertyList& instanceprops) { @@ -1365,12 +1365,12 @@ void DeviceManager_impl::postConstructor ( //Parse local components from DCD files LOG_TRACE(DeviceManager_impl, "Grabbing component placements") - const std::vector& componentPlacements = DCDParser.getComponentPlacements(); + const std::vector& componentPlacements = DCDParser.getComponentPlacements(); LOG_TRACE(DeviceManager_impl, "ComponentPlacement size is " << componentPlacements.size()) // Organize componentPlacements by standalone/deployOnDevice - std::vector::const_iterator constCompPlaceIter; - std::vector::iterator compPlaceIter; + std::vector::const_iterator constCompPlaceIter; + std::vector::iterator compPlaceIter; //////////////////////////////////////////////////////////////////////////// // Split component placements by compositePartOf tag @@ -1378,8 +1378,8 @@ void DeviceManager_impl::postConstructor ( // - Split non-deployOnDevice from deployOnDevice compPlacements // - Iterate and launch all non-deployOnDevice compPlacements // - Iterate and launch all deployOnDevice compPlacements - std::vector standaloneComponentPlacements; - std::vector compositePartDeviceComponentPlacements; + std::vector standaloneComponentPlacements; + std::vector compositePartDeviceComponentPlacements; for (constCompPlaceIter = componentPlacements.begin(); constCompPlaceIter != componentPlacements.end(); constCompPlaceIter++) { @@ -1521,7 +1521,7 @@ void DeviceManager_impl::postConstructor ( const SPD::Implementation* matchedDeviceImpl = NULL; bool foundCompositePart = false; - std::vector::iterator compositePartIter; + std::vector::iterator compositePartIter; for (compositePartIter = standaloneComponentPlacements.begin(); compositePartIter != standaloneComponentPlacements.end(); compositePartIter++) { diff --git a/redhawk/src/control/sdr/devmgr/DeviceManager_impl.h b/redhawk/src/control/sdr/devmgr/DeviceManager_impl.h index dca34ae9a..65c1965f9 100644 --- a/redhawk/src/control/sdr/devmgr/DeviceManager_impl.h +++ b/redhawk/src/control/sdr/devmgr/DeviceManager_impl.h @@ -219,9 +219,9 @@ class DeviceManager_impl: CF::DeviceManager_var& my_object_var); void getCompositeDeviceIOR( - std::string& compositeDeviceIOR, - const std::vector& componentPlacements, - const ossie::ComponentPlacement& componentPlacementInst); + std::string& compositeDeviceIOR, + const std::vector& componentPlacements, + const ossie::DevicePlacement& componentPlacementInst); bool loadDeviceProperties ( const ossie::SoftPkg& softpkg, @@ -256,31 +256,31 @@ class DeviceManager_impl: void createDeviceExecStatement( std::vector< std::string >& new_argv, - const ossie::ComponentPlacement& componentPlacement, + const ossie::DevicePlacement& componentPlacement, const std::string& componentType, std::map* pOverloadprops, const std::string& codeFilePath, ossie::DeviceManagerConfiguration& DCDParser, const ossie::ComponentInstantiation& instantiation, const std::string& usageName, - const std::vector& componentPlacements, + const std::vector& componentPlacements, const std::string& compositeDeviceIOR, const ossie::ComponentPropertyList& instanceprops) ; void createDeviceThreadAndHandleExceptions( - const ossie::ComponentPlacement& componentPlacement, + const ossie::DevicePlacement& componentPlacement, const std::string& componentType, std::map* pOverloadprops, const std::string& codeFilePath, const ossie::SoftPkg& SPDParser, ossie::DeviceManagerConfiguration& DCDParser, const ossie::ComponentInstantiation& instantiation, - const std::vector& componentPlacements, + const std::vector& componentPlacements, const std::string& compositeDeviceIOR, const ossie::ComponentPropertyList& instanceprops); void createDeviceThread( - const ossie::ComponentPlacement& componentPlacement, + const ossie::DevicePlacement& componentPlacement, const std::string& componentType, std::map* pOverloadprops, const std::string& codeFilePath, @@ -289,14 +289,14 @@ class DeviceManager_impl: const ossie::ComponentInstantiation& instantiation, const std::string& devcache, const std::string& usageName, - const std::vector& componentPlacements, + const std::vector& componentPlacements, const std::string& compositeDeviceIOR, const ossie::ComponentPropertyList& instanceprops); typedef std::list > ExecparamList; ExecparamList createDeviceExecparams( - const ossie::ComponentPlacement& componentPlacement, + const ossie::DevicePlacement& componentPlacement, const std::string& componentType, std::map* pOverloadprops, const std::string& codeFilePath, @@ -309,7 +309,7 @@ class DeviceManager_impl: bool loadSPD( ossie::SoftPkg& SPDParser, ossie::DeviceManagerConfiguration& DCDParser, - const ossie::ComponentPlacement& componentPlacement); + const ossie::DevicePlacement& componentPlacement); void recordComponentInstantiationId( const ossie::ComponentInstantiation& instantiation, diff --git a/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp b/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp index d188fcfab..2d645f6b6 100644 --- a/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp @@ -52,10 +52,10 @@ using namespace ossie; using namespace std; -static const ComponentInstantiation* findComponentInstantiation (const std::vector& placements, +static const ComponentInstantiation* findComponentInstantiation (const std::vector& placements, const std::string& identifier) { - for (std::vector::const_iterator iter = placements.begin(); iter != placements.end(); ++iter) { + for (std::vector::const_iterator iter = placements.begin(); iter != placements.end(); ++iter) { const std::vector& instantiations = iter->getInstantiations(); for (std::vector::const_iterator ii = instantiations.begin(); ii != instantiations.end(); ++ii) { if (identifier == ii->getID()) { @@ -2002,7 +2002,7 @@ void DomainManager_impl::_local_registerService (CORBA::Object_ptr registeringSe readDCD = false; } if (readDCD) { - const std::vector& componentPlacements = _DCDParser.getComponentPlacements(); + const std::vector& componentPlacements = _DCDParser.getComponentPlacements(); bool foundId = false; for (unsigned int i = 0; i < componentPlacements.size(); i++) { for (unsigned int j=0; j Date: Thu, 19 May 2016 13:43:08 -0400 Subject: [PATCH 0248/1644] Add shared pointers to the parsed PRF and SCD in parser's SoftPkg to support moving more structure into the parser classes --- redhawk/src/control/include/ossie/SoftPkg.h | 27 ++++++++++++++++++- .../control/sdr/dommgr/ApplicationProfile.cpp | 18 +++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/redhawk/src/control/include/ossie/SoftPkg.h b/redhawk/src/control/include/ossie/SoftPkg.h index fe42521e6..75e0b55fd 100644 --- a/redhawk/src/control/include/ossie/SoftPkg.h +++ b/redhawk/src/control/include/ossie/SoftPkg.h @@ -36,6 +36,9 @@ namespace ossie { + class Properties; + class ComponentDescriptor; + class SPD { public: typedef std::pair NameVersionPair; @@ -306,9 +309,31 @@ namespace ossie { assert(_spd.get() != 0); return (strcmp(getSoftPkgType(), "sca_non_compliant") == 0); } - + + const boost::shared_ptr& getProperties() + { + return _properties; + } + + void setProperties(const boost::shared_ptr& properties) + { + _properties = properties; + } + + const boost::shared_ptr& getDescriptor() + { + return _descriptor; + } + + void setDescriptor(const boost::shared_ptr& descriptor) + { + _descriptor = descriptor; + } + protected: std::auto_ptr _spd; + boost::shared_ptr _properties; + boost::shared_ptr _descriptor; std::string _spdFile; std::string _spdPath; }; diff --git a/redhawk/src/control/sdr/dommgr/ApplicationProfile.cpp b/redhawk/src/control/sdr/dommgr/ApplicationProfile.cpp index 6d609931a..521f6f243 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationProfile.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationProfile.cpp @@ -18,6 +18,8 @@ * along with this program. If not, see http://www.gnu.org/licenses/. */ +#include + #include #include "ApplicationProfile.h" @@ -75,6 +77,22 @@ void SoftpkgProfile::load(CF::FileSystem_ptr fileSystem) { File_stream spd_stream(fileSystem, spdFilename.c_str()); spd.load(spd_stream, spdFilename); + spd_stream.close(); + + if (spd.getPRFFile()) { + File_stream prf_stream(fileSystem, spd.getPRFFile()); + boost::shared_ptr prf = boost::make_shared(); + prf->load(prf_stream); + spd.setProperties(prf); + } + + if (spd.getSCDFile()) { + File_stream scd_stream(fileSystem, spd.getSCDFile()); + boost::shared_ptr scd = boost::make_shared(); + scd->load(scd_stream); + spd.setDescriptor(scd); + } + loaded = true; typedef std::vector SpdImplementations; From abca07f74722222b494b9d31347f43171b0c447f Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 19 May 2016 13:52:34 -0400 Subject: [PATCH 0249/1644] Remove ImplementationProfile class, with the intent that SPD::Implementation can be used directly instead --- .../control/sdr/dommgr/ApplicationProfile.cpp | 34 ------------------- .../control/sdr/dommgr/ApplicationProfile.h | 26 -------------- 2 files changed, 60 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationProfile.cpp b/redhawk/src/control/sdr/dommgr/ApplicationProfile.cpp index 521f6f243..2ff9a4c03 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationProfile.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationProfile.cpp @@ -26,29 +26,6 @@ using namespace ossie; -/** - * ImplementationProfile - */ -ImplementationProfile::ImplementationProfile(const SPD::Implementation& implementation) : - implementation(&implementation) -{ -} - -void ImplementationProfile::accept(ApplicationVisitor* visitor) -{ - visitor->visitImplementation(this); -} - -const std::string& ImplementationProfile::getIdentifier() const -{ - return implementation->getID(); -} - -const std::string& ImplementationProfile::getLocalfile() const -{ - return implementation->getCodeFile(); -} - /** * SoftpkgProfile */ @@ -94,12 +71,6 @@ void SoftpkgProfile::load(CF::FileSystem_ptr fileSystem) } loaded = true; - - typedef std::vector SpdImplementations; - const SpdImplementations& spd_impls = spd.getImplementations(); - for (SpdImplementations::const_iterator impl = spd_impls.begin(); impl != spd_impls.end(); ++impl) { - implementations.push_back(ImplementationProfile(*impl)); - } } const SoftPkg& SoftpkgProfile::getSPD() const @@ -107,11 +78,6 @@ const SoftPkg& SoftpkgProfile::getSPD() const return spd; } -SoftpkgProfile::ImplementationList& SoftpkgProfile::getImplementations() -{ - return implementations; -} - /** * SinglePlacement */ diff --git a/redhawk/src/control/sdr/dommgr/ApplicationProfile.h b/redhawk/src/control/sdr/dommgr/ApplicationProfile.h index b155c5bbd..8e8f5eb58 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationProfile.h +++ b/redhawk/src/control/sdr/dommgr/ApplicationProfile.h @@ -31,28 +31,9 @@ namespace ossie { class ApplicationVisitor; - class SoftpkgProfile; - - class ImplementationProfile - { - public: - ImplementationProfile(const SPD::Implementation& implementation); - - void accept(ApplicationVisitor* visitor); - - const std::string& getIdentifier() const; - - const std::string& getLocalfile() const; - - protected: - const SPD::Implementation* implementation; - }; - class SoftpkgProfile { public: - typedef std::vector ImplementationList; - SoftpkgProfile(const std::string& filename); void accept(ApplicationVisitor* visitor); @@ -65,12 +46,9 @@ namespace ossie { const SoftPkg& getSPD() const; - ImplementationList& getImplementations(); - protected: const std::string spdFilename; SoftPkg spd; - ImplementationList implementations; bool loaded; }; @@ -177,10 +155,6 @@ namespace ossie { virtual void visitSoftpkg(SoftpkgProfile* softpkg) { } - - virtual void visitImplementation(ImplementationProfile* implementation) - { - } }; } From 880b873a9e7e6fbdded0a65dbec570fdf4b494ad Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 19 May 2016 15:01:40 -0400 Subject: [PATCH 0250/1644] Remove SoftpkgProfile class, with the intent that SoftPkg can be used directly instead --- .../control/sdr/dommgr/ApplicationProfile.cpp | 93 ++++++------------- .../control/sdr/dommgr/ApplicationProfile.h | 35 ++----- 2 files changed, 35 insertions(+), 93 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationProfile.cpp b/redhawk/src/control/sdr/dommgr/ApplicationProfile.cpp index 2ff9a4c03..51041b269 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationProfile.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationProfile.cpp @@ -19,6 +19,7 @@ */ #include +#include #include @@ -26,63 +27,11 @@ using namespace ossie; -/** - * SoftpkgProfile - */ -SoftpkgProfile::SoftpkgProfile(const std::string& filename) : - spdFilename(filename), - loaded(false) -{ -} - -void SoftpkgProfile::accept(ApplicationVisitor* visitor) -{ - visitor->visitSoftpkg(this); -} - -const std::string& SoftpkgProfile::getSpdFileName() const -{ - return spdFilename; -} - -bool SoftpkgProfile::isLoaded() const -{ - return loaded; -} - -void SoftpkgProfile::load(CF::FileSystem_ptr fileSystem) -{ - File_stream spd_stream(fileSystem, spdFilename.c_str()); - spd.load(spd_stream, spdFilename); - spd_stream.close(); - - if (spd.getPRFFile()) { - File_stream prf_stream(fileSystem, spd.getPRFFile()); - boost::shared_ptr prf = boost::make_shared(); - prf->load(prf_stream); - spd.setProperties(prf); - } - - if (spd.getSCDFile()) { - File_stream scd_stream(fileSystem, spd.getSCDFile()); - boost::shared_ptr scd = boost::make_shared(); - scd->load(scd_stream); - spd.setDescriptor(scd); - } - - loaded = true; -} - -const SoftPkg& SoftpkgProfile::getSPD() const -{ - return spd; -} - /** * SinglePlacement */ SinglePlacement::SinglePlacement(const ComponentInstantiation* instantiation, - SoftpkgProfile* softpkg) : + const boost::shared_ptr& softpkg) : instantiation(instantiation), softpkg(softpkg) { @@ -98,7 +47,7 @@ const ComponentInstantiation* SinglePlacement::getComponentInstantiation() const return instantiation; } -SoftpkgProfile* SinglePlacement::getComponentProfile() +const boost::shared_ptr& SinglePlacement::getComponentProfile() { return softpkg; } @@ -201,14 +150,36 @@ void ApplicationProfile::load(CF::FileSystem_ptr fileSystem, const SoftwareAssem } } -SoftpkgProfile* ApplicationProfile::findSoftpkgProfile(const std::string& filename) +boost::shared_ptr ApplicationProfile::loadProfile(CF::FileSystem_ptr fileSystem, + const std::string& filename) { for (ProfileList::const_iterator profile = profiles.begin(); profile != profiles.end(); ++profile) { - if ((*profile)->getSpdFileName() == filename) { + if ((*profile)->getSPDFile() == filename) { + LOG_TRACE(ApplicationProfile, "Found existing profile " << filename); return *profile; } } - return 0; + + File_stream spd_stream(fileSystem, filename.c_str()); + boost::shared_ptr spd = boost::make_shared(boost::ref(spd_stream), filename); + spd_stream.close(); + + if (spd->getPRFFile()) { + File_stream prf_stream(fileSystem, spd->getPRFFile()); + boost::shared_ptr prf = boost::make_shared(); + prf->load(prf_stream); + spd->setProperties(prf); + } + + if (spd->getSCDFile()) { + File_stream scd_stream(fileSystem, spd->getSCDFile()); + boost::shared_ptr scd = boost::make_shared(); + scd->load(scd_stream); + spd->setDescriptor(scd); + } + + profiles.push_back(spd); + return spd; } SinglePlacement* ApplicationProfile::buildComponentPlacement(CF::FileSystem_ptr fileSystem, @@ -219,13 +190,7 @@ SinglePlacement* ApplicationProfile::buildComponentPlacement(CF::FileSystem_ptr if (!componentfile) { throw std::runtime_error("componentplacement has invalid componentfileref " + placement.getFileRefId()); } - SoftpkgProfile* softpkg = findSoftpkgProfile(componentfile->getFileName()); - if (!softpkg) { - LOG_TRACE(ApplicationProfile, "Loading profile " << componentfile->getFileName()); - SoftpkgProfile* profile = new SoftpkgProfile(componentfile->getFileName()); - profiles.push_back(profile); - softpkg = profile; - } + boost::shared_ptr softpkg = loadProfile(fileSystem, componentfile->getFileName()); // Even though it is possible for there to be more than one instantiation // per component, the tooling doesn't support that, so supporting this at a diff --git a/redhawk/src/control/sdr/dommgr/ApplicationProfile.h b/redhawk/src/control/sdr/dommgr/ApplicationProfile.h index 8e8f5eb58..ccde17f51 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationProfile.h +++ b/redhawk/src/control/sdr/dommgr/ApplicationProfile.h @@ -31,27 +31,6 @@ namespace ossie { class ApplicationVisitor; - class SoftpkgProfile - { - public: - SoftpkgProfile(const std::string& filename); - - void accept(ApplicationVisitor* visitor); - - const std::string& getSpdFileName() const; - - bool isLoaded() const; - - void load(CF::FileSystem_ptr fileSystem); - - const SoftPkg& getSPD() const; - - protected: - const std::string spdFilename; - SoftPkg spd; - bool loaded; - }; - class Placement { public: @@ -62,17 +41,18 @@ namespace ossie { class SinglePlacement : public Placement { public: - SinglePlacement(const ComponentInstantiation* instantiation, SoftpkgProfile* softpkg); + SinglePlacement(const ComponentInstantiation* instantiation, + const boost::shared_ptr& softpkg); virtual void accept(ApplicationVisitor* visitor); const ComponentInstantiation* getComponentInstantiation() const; - SoftpkgProfile* getComponentProfile(); + const boost::shared_ptr& getComponentProfile(); protected: const ComponentInstantiation* instantiation; - SoftpkgProfile* softpkg; + boost::shared_ptr softpkg; }; class CollocationPlacement : public Placement @@ -122,9 +102,9 @@ namespace ossie { const PlacementList& getPlacements() const; protected: - typedef std::vector ProfileList; + typedef std::vector > ProfileList; - SoftpkgProfile* findSoftpkgProfile(const std::string& filename); + boost::shared_ptr loadProfile(CF::FileSystem_ptr fileSystem, const std::string& filename); SinglePlacement* buildComponentPlacement(CF::FileSystem_ptr fileSystem, const SoftwareAssembly& sad, @@ -152,9 +132,6 @@ namespace ossie { { } - virtual void visitSoftpkg(SoftpkgProfile* softpkg) - { - } }; } From c3cd57b9f49b156df707cbf21c77239b9245f237 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 19 May 2016 16:06:17 -0400 Subject: [PATCH 0251/1644] Recursively resolve soft package dependencies; better error handling for invalid PRF and SCD --- redhawk/src/control/include/ossie/SoftPkg.h | 14 +++++++ .../control/sdr/dommgr/ApplicationProfile.cpp | 40 ++++++++++++++----- 2 files changed, 45 insertions(+), 9 deletions(-) diff --git a/redhawk/src/control/include/ossie/SoftPkg.h b/redhawk/src/control/include/ossie/SoftPkg.h index 75e0b55fd..e91b49d23 100644 --- a/redhawk/src/control/include/ossie/SoftPkg.h +++ b/redhawk/src/control/include/ossie/SoftPkg.h @@ -36,6 +36,7 @@ namespace ossie { + class SoftPkg; class Properties; class ComponentDescriptor; @@ -50,6 +51,19 @@ namespace ossie { virtual const std::string asString() const; virtual ~SoftPkgRef() {}; + + const boost::shared_ptr& getReference() const + { + return _softpkg; + } + + void setReference(const boost::shared_ptr& softpkg) + { + _softpkg = softpkg; + } + + private: + boost::shared_ptr _softpkg; }; diff --git a/redhawk/src/control/sdr/dommgr/ApplicationProfile.cpp b/redhawk/src/control/sdr/dommgr/ApplicationProfile.cpp index 51041b269..e7a986960 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationProfile.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationProfile.cpp @@ -160,22 +160,44 @@ boost::shared_ptr ApplicationProfile::loadProfile(CF::FileSystem_ptr fi } } + LOG_TRACE(ApplicationProfile, "Loading SPD file " << filename); + boost::shared_ptr spd; File_stream spd_stream(fileSystem, filename.c_str()); - boost::shared_ptr spd = boost::make_shared(boost::ref(spd_stream), filename); + spd = boost::make_shared(boost::ref(spd_stream), filename); spd_stream.close(); + const SPD::Implementations& spd_impls = spd->getImplementations(); + for (SPD::Implementations::const_iterator impl = spd_impls.begin(); impl != spd_impls.end(); ++impl) { + const SPD::SoftPkgDependencies& deps = impl->getSoftPkgDependencies(); + for (SPD::SoftPkgDependencies::const_iterator dep = deps.begin(); dep != deps.end(); ++dep) { + SPD::SoftPkgRef& ref = const_cast(*dep); + LOG_TRACE(ApplicationProfile, "Resolving soft package reference " << ref.localfile); + ref.setReference(loadProfile(fileSystem, ref.localfile)); + } + } + if (spd->getPRFFile()) { - File_stream prf_stream(fileSystem, spd->getPRFFile()); - boost::shared_ptr prf = boost::make_shared(); - prf->load(prf_stream); - spd->setProperties(prf); + LOG_TRACE(ApplicationProfile, "Loading PRF file " << spd->getPRFFile()); + try { + File_stream prf_stream(fileSystem, spd->getPRFFile()); + boost::shared_ptr prf = boost::make_shared(); + prf->load(prf_stream); + spd->setProperties(prf); + } catch (const std::exception& exc) { + LOG_ERROR(ApplicationProfile, "Invalid PRF file " << spd->getPRFFile()); + } } if (spd->getSCDFile()) { - File_stream scd_stream(fileSystem, spd->getSCDFile()); - boost::shared_ptr scd = boost::make_shared(); - scd->load(scd_stream); - spd->setDescriptor(scd); + LOG_TRACE(ApplicationProfile, "Loading SCD file " << spd->getSCDFile()); + try { + File_stream scd_stream(fileSystem, spd->getSCDFile()); + boost::shared_ptr scd = boost::make_shared(); + scd->load(scd_stream); + spd->setDescriptor(scd); + } catch (const std::exception& exc) { + LOG_ERROR(ApplicationProfile, "Invalid SCD file " << spd->getSCDFile()); + } } profiles.push_back(spd); From f1fe94936b8a54b6e74439bbc40d96639e9389a9 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 20 May 2016 13:17:55 -0400 Subject: [PATCH 0252/1644] Use swap to transfer ownership of parser results instead of making copies --- .../src/control/parser/internal/sad-pimpl.cpp | 42 +++++++++---------- .../src/control/parser/internal/sad-pimpl.h | 28 ++++++------- redhawk/src/control/parser/internal/sad.map | 14 +++---- 3 files changed, 42 insertions(+), 42 deletions(-) diff --git a/redhawk/src/control/parser/internal/sad-pimpl.cpp b/redhawk/src/control/parser/internal/sad-pimpl.cpp index 0c95abe69..2f0606121 100644 --- a/redhawk/src/control/parser/internal/sad-pimpl.cpp +++ b/redhawk/src/control/parser/internal/sad-pimpl.cpp @@ -50,9 +50,9 @@ namespace sad } void softwareassembly_pimpl:: - componentfiles (const ::std::vector& componentfiles) + componentfiles (::std::vector& componentfiles) { - _sad->componentfiles = componentfiles; + _sad->componentfiles.swap(componentfiles); } void softwareassembly_pimpl:: @@ -68,27 +68,27 @@ namespace sad } void softwareassembly_pimpl:: - connections (const ::std::vector& connections) + connections (::std::vector& connections) { - _sad->connections = connections; + _sad->connections.swap(connections); } void softwareassembly_pimpl:: - externalports (const ::std::vector& externalports) + externalports (::std::vector& externalports) { - _sad->externalports = externalports; + _sad->externalports.swap(externalports); } void softwareassembly_pimpl:: - externalproperties (const ::std::vector& externalproperties) + externalproperties (::std::vector& externalproperties) { - _sad->externalproperties = externalproperties; + _sad->externalproperties.swap(externalproperties); } void softwareassembly_pimpl:: - usesdevicedependencies (const ::std::vector& usesdevices) + usesdevicedependencies (::std::vector& usesdevices) { - _sad->usesdevice = usesdevices; + _sad->usesdevice.swap(usesdevices); } void softwareassembly_pimpl:: @@ -124,7 +124,7 @@ namespace sad componentFiles.push_back(componentfile); } - ::std::vector componentfiles_pimpl:: + ::std::vector& componentfiles_pimpl:: post_componentfiles () { return componentFiles; @@ -288,9 +288,9 @@ namespace sad } void componentinstantiation_pimpl:: - componentproperties ( const ossie::ComponentPropertyList& componentproperties) + componentproperties (ossie::ComponentPropertyList& componentproperties) { - componentInstantiation.properties = componentproperties; + componentInstantiation.properties.swap(componentproperties); } void componentinstantiation_pimpl:: @@ -307,10 +307,10 @@ namespace sad } void componentinstantiation_pimpl:: - affinity (const ossie::ComponentInstantiation::AffinityProperties& affinityProperties) + affinity (ossie::ComponentInstantiation::AffinityProperties& affinityProperties) { LOG_TRACE(sad_parser, "affinity properties"); - componentInstantiation.affinityProperties= affinityProperties; + componentInstantiation.affinityProperties.swap(affinityProperties); } void componentinstantiation_pimpl::loggingconfig ( const ossie::ComponentInstantiation::LoggingConfig& log_cfg ) @@ -359,7 +359,7 @@ namespace sad affinityProperties.push_back(structsequenceref.clone()); } - const ossie::ComponentInstantiation::AffinityProperties& affinity_pimpl::post_affinity () + ossie::ComponentInstantiation::AffinityProperties& affinity_pimpl::post_affinity () { return affinityProperties; } @@ -416,7 +416,7 @@ namespace sad componentProperties.push_back(structsequenceref.clone()); } - const ossie::ComponentPropertyList& componentproperties_pimpl:: + ossie::ComponentPropertyList& componentproperties_pimpl:: post_componentproperties () { return componentProperties; @@ -931,7 +931,7 @@ namespace sad LOG_TRACE(sad_parser, "added connection id " << connections.back().getID() << " type " << connections.back().getType()); } - ::std::vector connections_pimpl:: + ::std::vector& connections_pimpl:: post_connections () { return connections; @@ -1154,7 +1154,7 @@ namespace sad extPorts.push_back(port); } - ::std::vector externalports_pimpl:: + ::std::vector& externalports_pimpl:: post_externalports () { return extPorts; @@ -1230,7 +1230,7 @@ namespace sad extProps.push_back(prop); } - ::std::vector externalproperties_pimpl:: + ::std::vector& externalproperties_pimpl:: post_externalproperties () { return extProps; @@ -1284,7 +1284,7 @@ namespace sad usesDevices.push_back(use); } - ::std::vector usesdevicedependencies_pimpl:: + ::std::vector& usesdevicedependencies_pimpl:: post_usesdevicedependencies () { return usesDevices; diff --git a/redhawk/src/control/parser/internal/sad-pimpl.h b/redhawk/src/control/parser/internal/sad-pimpl.h index d84ddafe9..c4c5ae1f1 100644 --- a/redhawk/src/control/parser/internal/sad-pimpl.h +++ b/redhawk/src/control/parser/internal/sad-pimpl.h @@ -41,7 +41,7 @@ namespace sad description (const ::std::string&); virtual void - componentfiles (const ::std::vector&); + componentfiles (::std::vector&); virtual void partitioning (const ossie::SoftwareAssembly::Partitioning&); @@ -50,16 +50,16 @@ namespace sad assemblycontroller (const ::std::string&); virtual void - connections (const ::std::vector&); + connections (::std::vector&); virtual void - externalports (const ::std::vector&); + externalports (::std::vector&); virtual void - externalproperties (const ::std::vector&); + externalproperties (::std::vector&); virtual void - usesdevicedependencies (const ::std::vector&); + usesdevicedependencies (::std::vector&); virtual void id (const ::std::string&); @@ -83,7 +83,7 @@ namespace sad virtual void componentfile (const ::ossie::ComponentFile&); - virtual ::std::vector + virtual ::std::vector& post_componentfiles (); private: @@ -192,7 +192,7 @@ namespace sad usagename (const ::std::string&); virtual void - componentproperties ( const ossie::ComponentPropertyList&); + componentproperties (ossie::ComponentPropertyList&); virtual void findcomponent (const ::std::string&); @@ -204,7 +204,7 @@ namespace sad startorder (const ::std::string&); virtual void - affinity (const ossie::ComponentInstantiation::AffinityProperties&); + affinity (ossie::ComponentInstantiation::AffinityProperties&); virtual void loggingconfig (const ossie::ComponentInstantiation::LoggingConfig&); @@ -234,7 +234,7 @@ namespace sad virtual void structsequenceref (const ossie::StructSequencePropertyRef&); - const ossie::ComponentInstantiation::AffinityProperties& + ossie::ComponentInstantiation::AffinityProperties& post_affinity (); private: @@ -277,7 +277,7 @@ namespace sad virtual void structsequenceref (const ossie::StructSequencePropertyRef&); - virtual const ossie::ComponentPropertyList& + virtual ossie::ComponentPropertyList& post_componentproperties (); private: @@ -628,7 +628,7 @@ namespace sad virtual void connectinterface (const ::ossie::Connection&); - virtual ::std::vector + virtual ::std::vector& post_connections (); private: @@ -765,7 +765,7 @@ namespace sad virtual void port (const ossie::SoftwareAssembly::Port&); - virtual ::std::vector + virtual ::std::vector& post_externalports (); private: @@ -812,7 +812,7 @@ namespace sad virtual void property (const ossie::SoftwareAssembly::Property&); - virtual ::std::vector + virtual ::std::vector& post_externalproperties (); private: @@ -850,7 +850,7 @@ namespace sad virtual void usesdevice (const ossie::UsesDevice&); - virtual ::std::vector + virtual ::std::vector& post_usesdevicedependencies (); private: diff --git a/redhawk/src/control/parser/internal/sad.map b/redhawk/src/control/parser/internal/sad.map index ec24414a1..63347b835 100644 --- a/redhawk/src/control/parser/internal/sad.map +++ b/redhawk/src/control/parser/internal/sad.map @@ -23,13 +23,13 @@ namespace urn:mil:jpeojtrs:sca:sad { include "memory"; include "../include/ossie/SoftwareAssembly.h"; softwareassembly "::std::auto_ptr"; - componentfiles "::std::vector"; + componentfiles "::std::vector &"; componentfile "::ossie::ComponentFile"; componentplacement "const ::ossie::ComponentPlacement&" "const ::ossie::ComponentPlacement&"; partitioning "ossie::SoftwareAssembly::Partitioning"; hostcollocation "::ossie::SoftwareAssembly::HostCollocation"; componentinstantiation "const ::ossie::ComponentInstantiation &" "const ::ossie::ComponentInstantiation &"; - connections "::std::vector"; + connections "::std::vector &"; connectinterface "::ossie::Connection"; usesport "::ossie::UsesPort"; providesport "::ossie::ProvidesPort"; @@ -39,7 +39,7 @@ namespace urn:mil:jpeojtrs:sca:sad { findby "::ossie::FindBy"; namingservice "::std::string"; domainfinder "::std::pair"; - componentproperties "const ossie::ComponentPropertyList &" "const ossie::ComponentPropertyList &"; + componentproperties "ossie::ComponentPropertyList &"; simpleref "const ossie::SimplePropertyRef &" "const ossie::SimplePropertyRef &"; simplesequenceref "const ossie::SimpleSequencePropertyRef &" "const ossie::SimpleSequencePropertyRef &"; structref "const ossie::StructPropertyRef &" "const ossie::StructPropertyRef &"; @@ -53,17 +53,17 @@ namespace urn:mil:jpeojtrs:sca:sad { devicethatloadedthiscomponentref "::std::string"; deviceusedbythiscomponentref "::std::pair"; deviceusedbyapplication "::std::string"; - externalports "::std::vector"; + externalports "::std::vector &"; port "ossie::SoftwareAssembly::Port"; usesidentifier "::std::string"; providesidentifier "::std::string"; supportedidentifier "::std::string"; - externalproperties "::std::vector"; + externalproperties "::std::vector &"; property "ossie::SoftwareAssembly::Property"; - usesdevicedependencies "::std::vector"; + usesdevicedependencies "::std::vector &"; usesdevice "ossie::UsesDevice"; propertyref "ossie::PropertyRef"; - affinity "const ossie::ComponentInstantiation::AffinityProperties&" "const ossie::ComponentInstantiation::AffinityProperties&"; + affinity "ossie::ComponentInstantiation::AffinityProperties&"; loggingconfig "const ossie::ComponentInstantiation::LoggingConfig&" "const ossie::ComponentInstantiation::LoggingConfig&"; } From a1a7fb20ff67215641032ad9ba1be64cdd3a5e6c Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 23 May 2016 12:06:21 -0400 Subject: [PATCH 0253/1644] Do some early validation and model linking of componentfilerefs and assemblycontroller in the SAD parser --- .../control/include/ossie/SoftwareAssembly.h | 5 ++- .../control/include/ossie/componentProfile.h | 1 + .../src/control/parser/SoftwareAssembly.cpp | 45 ++++++++++++++++++- .../sdr/dommgr/ApplicationFactory_impl.cpp | 17 +++---- 4 files changed, 54 insertions(+), 14 deletions(-) diff --git a/redhawk/src/control/include/ossie/SoftwareAssembly.h b/redhawk/src/control/include/ossie/SoftwareAssembly.h index bf200c3bf..51e0d21d4 100644 --- a/redhawk/src/control/include/ossie/SoftwareAssembly.h +++ b/redhawk/src/control/include/ossie/SoftwareAssembly.h @@ -93,7 +93,7 @@ namespace ossie { std::vector usesdevice; }; - SoftwareAssembly() : _sad(0) {} + SoftwareAssembly(); SoftwareAssembly(std::istream& input) throw (ossie::parser_error); @@ -124,7 +124,10 @@ namespace ossie { const std::vector& getUsesDevices() const; protected: + void validateComponentPlacements(std::vector& placements); + std::auto_ptr _sad; + ComponentInstantiation* _assemblyController; }; } #endif diff --git a/redhawk/src/control/include/ossie/componentProfile.h b/redhawk/src/control/include/ossie/componentProfile.h index 41363e5ee..a74bcb7ed 100644 --- a/redhawk/src/control/include/ossie/componentProfile.h +++ b/redhawk/src/control/include/ossie/componentProfile.h @@ -212,6 +212,7 @@ namespace ossie { std::vector instantiations; + const ComponentFile* componentFile; public: const std::vector& getInstantiations() const; diff --git a/redhawk/src/control/parser/SoftwareAssembly.cpp b/redhawk/src/control/parser/SoftwareAssembly.cpp index 8699e15ed..9e6e4bc92 100644 --- a/redhawk/src/control/parser/SoftwareAssembly.cpp +++ b/redhawk/src/control/parser/SoftwareAssembly.cpp @@ -18,18 +18,61 @@ * along with this program. If not, see http://www.gnu.org/licenses/. */ +#include + #include "ossie/SoftwareAssembly.h" #include "internal/sad-parser.h" using namespace ossie; -SoftwareAssembly::SoftwareAssembly(std::istream& input) throw (ossie::parser_error) { +SoftwareAssembly::SoftwareAssembly() : + _sad(0), + _assemblyController(0) +{ +} + +SoftwareAssembly::SoftwareAssembly(std::istream& input) throw (ossie::parser_error) : + _sad(0), + _assemblyController(0) +{ this->load(input); } void SoftwareAssembly::load(std::istream& input) throw (ossie::parser_error) { _sad = ossie::internalparser::parseSAD(input); + + // Validate that all componentplacement elements, both in hostcollocation + // elements and in partitioning, have componentfileref values referencing + // valid componentfile elements + BOOST_FOREACH(HostCollocation& collocation, _sad->partitioning.collocations) { + validateComponentPlacements(collocation.placements); + } + validateComponentPlacements(_sad->partitioning.placements); + + // If assemblycontroller is set, make sure it was found during component + // validation + if (!_sad->assemblycontroller.empty() && !_assemblyController) { + throw ossie::parser_error("assemblycontroller has invalid componentinstantiationref " + _sad->assemblycontroller); + } +} + +void SoftwareAssembly::validateComponentPlacements(std::vector& placements) +{ + BOOST_FOREACH(ComponentPlacement& placement, placements) { + const std::string& file_ref = placement.getFileRefId(); + const ComponentFile* file = getComponentFile(file_ref); + if (!file) { + throw ossie::parser_error("componentplacement has invalid componentfileref " + file_ref); + } + placement.componentFile = file; + + BOOST_FOREACH(ComponentInstantiation& instance, placement.instantiations) { + if (!_sad->assemblycontroller.empty() && _sad->assemblycontroller == instance.instantiationId) { + _assemblyController = &instance; + } + } + } } const std::string& SoftwareAssembly::getID() const { diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 7131b56ed..aa24046d6 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -484,17 +484,10 @@ ApplicationFactory_impl::ApplicationFactory_impl (const std::string& softwarePro for (std::vector::const_iterator comp = components.begin(); comp != components.end(); ++comp) { SoftPkg comp_pkg; - std::string p_name; + const std::string& p_name = comp->componentFile->filename; try { - if ( _sadParser.getComponentFile(comp->getFileRefId())) { - p_name = _sadParser.getComponentFile(comp->getFileRefId())->getFileName(); - LOG_DEBUG(ApplicationFactory_impl, "Validating... COMP profile: " << p_name); - ValidateSPD(_fileMgr, _domainManager, comp_pkg, p_name) ; - } - else { - LOG_ERROR(ApplicationFactory_impl, "installApplication: invalid componentfileref: " << comp->getFileRefId() ); - throw CF::DomainManager::ApplicationInstallationError (CF::CF_EBADF, "installApplication: invalid componentfileref"); - } + LOG_DEBUG(ApplicationFactory_impl, "Validating... COMP profile: " << p_name); + ValidateSPD( _fileMgr, comp_pkg, p_name.c_str() ) ; } catch (CF::FileException& ex) { LOG_ERROR(ApplicationFactory_impl, "installApplication: While validating the SAD profile: " << ex.msg); throw CF::DomainManager::ApplicationInstallationError (CF::CF_EBADF, ex.msg); @@ -522,7 +515,7 @@ ApplicationFactory_impl::ApplicationFactory_impl (const std::string& softwarePro compInst != compInstantiations.end(); ++compInst){ if (assemblyControllerId == compInst->instantiationId) { ac_spd = comp_pkg; - ac_profile = _sadParser.getComponentFile(comp->getFileRefId())->getFileName(); + ac_profile = comp->componentFile->filename; ac_found = true; break; } @@ -1874,7 +1867,7 @@ ossie::ComponentInfo* createHelper::buildComponentInfo(CF::FileSystem_ptr fileSy // Extract required data from SPD file ossie::ComponentInfo* newComponent = 0; LOG_TRACE(ApplicationFactory_impl, "Getting the SPD Filename"); - const ComponentFile* componentfile = sadParser.getComponentFile(component.getFileRefId()); + const ComponentFile* componentfile = component.componentFile; if (!componentfile) { ostringstream eout; eout << "The SPD file reference for componentfile "< Date: Mon, 23 May 2016 13:08:36 -0400 Subject: [PATCH 0254/1644] Return more const string references instead of bouncing through const char* --- redhawk/src/control/include/ossie/componentProfile.h | 4 ++-- redhawk/src/control/parser/componentProfile.cpp | 8 ++++---- redhawk/src/control/sdr/devmgr/DeviceManager_impl.cpp | 6 +++--- redhawk/src/control/sdr/devmgr/DeviceManager_impl.h | 2 +- .../src/control/sdr/dommgr/ApplicationFactory_impl.cpp | 4 ++-- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/redhawk/src/control/include/ossie/componentProfile.h b/redhawk/src/control/include/ossie/componentProfile.h index a74bcb7ed..473ed451c 100644 --- a/redhawk/src/control/include/ossie/componentProfile.h +++ b/redhawk/src/control/include/ossie/componentProfile.h @@ -186,9 +186,9 @@ namespace ossie { virtual ~ComponentInstantiation(); public: - const char* getID() const; + const std::string& getID() const; - const char* getStartOrder() const; + const std::string& getStartOrder() const; const char* getUsageName() const; diff --git a/redhawk/src/control/parser/componentProfile.cpp b/redhawk/src/control/parser/componentProfile.cpp index 108c4e663..dbd005572 100644 --- a/redhawk/src/control/parser/componentProfile.cpp +++ b/redhawk/src/control/parser/componentProfile.cpp @@ -151,12 +151,12 @@ ComponentInstantiation& ComponentInstantiation::operator=(const ComponentInstant ComponentInstantiation::~ComponentInstantiation() { } -const char* ComponentInstantiation::getID() const { - return instantiationId.c_str(); +const std::string& ComponentInstantiation::getID() const { + return instantiationId; } -const char* ComponentInstantiation::getStartOrder() const { - return _startOrder.c_str(); +const std::string& ComponentInstantiation::getStartOrder() const { + return _startOrder; } const char* ComponentInstantiation::getUsageName() const { diff --git a/redhawk/src/control/sdr/devmgr/DeviceManager_impl.cpp b/redhawk/src/control/sdr/devmgr/DeviceManager_impl.cpp index e4e414353..7d1739401 100644 --- a/redhawk/src/control/sdr/devmgr/DeviceManager_impl.cpp +++ b/redhawk/src/control/sdr/devmgr/DeviceManager_impl.cpp @@ -447,8 +447,8 @@ void DeviceManager_impl::getCompositeDeviceIOR( for (unsigned int cp_idx = 0; cp_idx < componentPlacements.size(); cp_idx++) { // must match to a particular instance for (unsigned int ci_idx = 0; ci_idx < componentPlacements[cp_idx].getInstantiations().size(); ci_idx++) { - const char* instanceID = componentPlacements[cp_idx].instantiations[ci_idx].getID(); - if (strcmp(instanceID, parentDeviceRefid.c_str()) == 0) { + const std::string& instanceID = componentPlacements[cp_idx].instantiations[ci_idx].getID(); + if (instanceID == parentDeviceRefid) { LOG_TRACE(DeviceManager_impl, "CompositePartOfDevice: Found parent device instance <" << componentPlacements[cp_idx].getInstantiations()[ci_idx].getID() << "> for child device <" << componentPlacementInst.getFileRefId() << ">"); @@ -2721,7 +2721,7 @@ CF::DeviceSequence* DeviceManager_impl::registeredDevices () throw (CORBA::Syste return result._retn(); } -std::string DeviceManager_impl::getIORfromID(const char* instanceid) +std::string DeviceManager_impl::getIORfromID(const std::string& instanceid) { boost::recursive_mutex::scoped_lock lock(registeredDevicesmutex); diff --git a/redhawk/src/control/sdr/devmgr/DeviceManager_impl.h b/redhawk/src/control/sdr/devmgr/DeviceManager_impl.h index 65c1965f9..c69733b4e 100644 --- a/redhawk/src/control/sdr/devmgr/DeviceManager_impl.h +++ b/redhawk/src/control/sdr/devmgr/DeviceManager_impl.h @@ -345,7 +345,7 @@ class DeviceManager_impl: void deleteFileSystems(); bool makeDirectory(std::string path); - std::string getIORfromID(const char* instanceid); + std::string getIORfromID(const std::string& instanceid); std::string deviceMgrIOR; std::string fileSysIOR; bool *_internalShutdown; diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index aa24046d6..5ab1c466f 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -1917,8 +1917,8 @@ ossie::ComponentInfo* createHelper::buildComponentInfo(CF::FileSystem_ptr fileSy newComponent->setAffinity( instance.getAffinity() ); newComponent->setLoggingConfig( instance.getLoggingConfig() ); - if (strlen(instance.getStartOrder()) > 0) { - int start_order = atoi(instance.getStartOrder()); + if (!instance.getStartOrder().empty()) { + int start_order = atoi(instance.getStartOrder().c_str()); newComponent->setStartOrder(start_order); } From 60ce86a7e63d2081b0fd76c2d726ca2d8063767a Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 23 May 2016 14:21:42 -0400 Subject: [PATCH 0255/1644] Allow linking of ComponentFileRef to SoftPkg instances --- .../control/include/ossie/componentProfile.h | 17 +++++++++++++++++ .../control/sdr/dommgr/ApplicationProfile.cpp | 10 +++++----- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/redhawk/src/control/include/ossie/componentProfile.h b/redhawk/src/control/include/ossie/componentProfile.h index 473ed451c..bf7794767 100644 --- a/redhawk/src/control/include/ossie/componentProfile.h +++ b/redhawk/src/control/include/ossie/componentProfile.h @@ -29,9 +29,13 @@ #include #include #include +#include #include "ossie/ossieparser.h" namespace ossie { + + class SoftPkg; + /* * */ @@ -45,6 +49,19 @@ namespace ossie { const std::string& getFileName() const; const std::string& getID() const; + + const boost::shared_ptr& getSoftPkg() const + { + return _softpkg; + } + + void setSoftPkg(const boost::shared_ptr& softpkg) + { + _softpkg = softpkg; + } + + private: + boost::shared_ptr _softpkg; }; /* diff --git a/redhawk/src/control/sdr/dommgr/ApplicationProfile.cpp b/redhawk/src/control/sdr/dommgr/ApplicationProfile.cpp index e7a986960..ef7819195 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationProfile.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationProfile.cpp @@ -208,11 +208,11 @@ SinglePlacement* ApplicationProfile::buildComponentPlacement(CF::FileSystem_ptr const SoftwareAssembly& sad, const ComponentPlacement& placement) { - const ComponentFile *componentfile = sad.getComponentFile(placement.getFileRefId()); - if (!componentfile) { - throw std::runtime_error("componentplacement has invalid componentfileref " + placement.getFileRefId()); + assert(placement.componentFile); + ComponentFile* componentFile = const_cast(placement.componentFile); + if (!componentFile->getSoftPkg()) { + componentFile->setSoftPkg(loadProfile(fileSystem, componentFile->getFileName())); } - boost::shared_ptr softpkg = loadProfile(fileSystem, componentfile->getFileName()); // Even though it is possible for there to be more than one instantiation // per component, the tooling doesn't support that, so supporting this at a @@ -222,7 +222,7 @@ SinglePlacement* ApplicationProfile::buildComponentPlacement(CF::FileSystem_ptr const std::vector& instantiations = placement.getInstantiations(); const ComponentInstantiation& instance = instantiations[0]; - return new SinglePlacement(&instance, softpkg); + return new SinglePlacement(&instance, componentFile->getSoftPkg()); } const ApplicationProfile::PlacementList& ApplicationProfile::getPlacements() const From 40b56de35b911987b5fad009d43c6fc229c2578c Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 23 May 2016 14:34:34 -0400 Subject: [PATCH 0256/1644] Change lifetime and creation of ComponentDeployment class; instances are constructed by an ApplicationDeployment object, and the deployment object is created prior to attempting component allocation --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 22 +++++++++---------- redhawk/src/control/sdr/dommgr/Deployment.cpp | 8 ++++--- redhawk/src/control/sdr/dommgr/Deployment.h | 7 +++--- redhawk/src/control/sdr/dommgr/createHelper.h | 6 ++--- 4 files changed, 23 insertions(+), 20 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 5ab1c466f..5839bd6ba 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -665,8 +665,8 @@ void createHelper::assignPlacementsToDevices(ossie::ApplicationDeployment& appDe LOG_TRACE(ApplicationFactory_impl, "Component " << component->getInstantiationIdentifier() << " is assigned to device " << assigned_device); } - ossie::ComponentDeployment* deployment = allocateComponent(component, assigned_device, appDeployment.getIdentifier()); - appDeployment.addComponentDeployment(deployment); + ossie::ComponentDeployment* deployment = appDeployment.createComponentDeployment(component); + allocateComponent(deployment, assigned_device, appDeployment.getIdentifier()); } } } @@ -843,9 +843,8 @@ void createHelper::_placeHostCollocation(ossie::ApplicationDeployment& appDeploy DeploymentList deployments; for (PlacementList::const_iterator comp = components.begin(); comp != components.end(); ++comp) { - ossie::ComponentDeployment* deployment = new ossie::ComponentDeployment(*comp, 0); + ossie::ComponentDeployment* deployment = appDeployment.createComponentDeployment(*comp); deployments.push_back(deployment); - appDeployment.addComponentDeployment(deployment); } if (!placeHostCollocation(appDeployment, deployments, deployments.begin(), deploymentDevices)) { @@ -1438,10 +1437,11 @@ CF::AllocationManager::AllocationResponseSequence* createHelper::allocateUsesDev collocation request. This requires that we know and cleanup only those allocations that we made.. */ -ossie::ComponentDeployment* createHelper::allocateComponent(ossie::ComponentInfo* component, - const std::string& assignedDeviceId, - const std::string& appIdentifier) +void createHelper::allocateComponent(ossie::ComponentDeployment* deployment, + const std::string& assignedDeviceId, + const std::string& appIdentifier) { + ossie::ComponentInfo* component = deployment->getComponent(); CF::Properties configureProperties = component->getConfigureProperties(); const CF::Properties &construct_props = component->getConstructProperties(); unsigned int configlen = configureProperties.length(); @@ -1489,7 +1489,7 @@ ossie::ComponentDeployment* createHelper::allocateComponent(ossie::ComponentInfo continue; } - std::auto_ptr deployment(new ossie::ComponentDeployment(component, impl)); + deployment->setImplementation(impl); // Transfer ownership of the uses device assigments to the deployment assignedDevices.transferUsesDeviceAssignments(*deployment); @@ -1497,7 +1497,7 @@ ossie::ComponentDeployment* createHelper::allocateComponent(ossie::ComponentInfo // Found an implementation which has its 'usesdevice' dependencies // satisfied, now perform assignment/allocation of component to device LOG_DEBUG(ApplicationFactory_impl, "Trying to find the device"); - ossie::AllocationResult response = allocateComponentToDevice(deployment.get(), assignedDeviceId, appIdentifier); + ossie::AllocationResult response = allocateComponentToDevice(deployment, assignedDeviceId, appIdentifier); if (response.first.empty()) { LOG_DEBUG(ApplicationFactory_impl, "Unable to allocate device for component " @@ -1513,7 +1513,7 @@ ossie::ComponentDeployment* createHelper::allocateComponent(ossie::ComponentInfo DeviceNode& node = *(response.second); const std::string& deviceId = node.identifier; - if (!resolveSoftpkgDependencies(deployment.get(), node)) { + if (!resolveSoftpkgDependencies(deployment, node)) { LOG_DEBUG(ApplicationFactory_impl, "Unable to resolve softpackage dependencies for component " << component->getIdentifier() << " implementation " << impl->getId()); continue; @@ -1532,7 +1532,7 @@ ossie::ComponentDeployment* createHelper::allocateComponent(ossie::ComponentInfo implAssignedDevices.transferUsesDeviceAssignments(*deployment); - return deployment.release(); + return; } bool allBusy = true; diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index 8181457ec..01d04b6c8 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -198,8 +198,8 @@ std::string SoftpkgDeployment::getLocalFile() return codeLocalFile.string(); } -ComponentDeployment::ComponentDeployment(ComponentInfo* component, ImplementationInfo* implementation) : - SoftpkgDeployment(component, implementation), +ComponentDeployment::ComponentDeployment(ComponentInfo* component) : + SoftpkgDeployment(component), component(component), affinityOptions(component->getAffinityOptions()) { @@ -456,9 +456,11 @@ ComponentInfo* ApplicationDeployment::getAssemblyController() return 0; } -void ApplicationDeployment::addComponentDeployment(ComponentDeployment* deployment) +ComponentDeployment* ApplicationDeployment::createComponentDeployment(ComponentInfo* component) { + ComponentDeployment* deployment = new ComponentDeployment(component); components.push_back(deployment); + return deployment; } const ApplicationDeployment::ComponentList& ApplicationDeployment::getComponentDeployments() diff --git a/redhawk/src/control/sdr/dommgr/Deployment.h b/redhawk/src/control/sdr/dommgr/Deployment.h index e094407a8..54de1667b 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.h +++ b/redhawk/src/control/sdr/dommgr/Deployment.h @@ -71,7 +71,7 @@ namespace ossie { public: typedef std::vector DeploymentList; - SoftpkgDeployment(SoftpkgInfo* softpkg, const ImplementationInfo* implementation); + SoftpkgDeployment(SoftpkgInfo* softpkg, const ImplementationInfo* implementation=0); ~SoftpkgDeployment(); SoftpkgInfo* getSoftpkg(); @@ -99,7 +99,7 @@ namespace ossie { class ComponentDeployment : public SoftpkgDeployment, public UsesDeviceDeployment { public: - ComponentDeployment(ComponentInfo* component, ImplementationInfo* implementation); + ComponentDeployment(ComponentInfo* component); ComponentInfo* getComponent(); @@ -182,7 +182,8 @@ namespace ossie { ComponentInfo* getComponent(const std::string& instantiationId); - void addComponentDeployment(ComponentDeployment* deployment); + ComponentDeployment* createComponentDeployment(ComponentInfo* component); + const ComponentList& getComponentDeployments(); ComponentDeployment* getComponentDeployment(const std::string& instantiationId); diff --git a/redhawk/src/control/sdr/dommgr/createHelper.h b/redhawk/src/control/sdr/dommgr/createHelper.h index 16159ce3c..4dd0d5e79 100644 --- a/redhawk/src/control/sdr/dommgr/createHelper.h +++ b/redhawk/src/control/sdr/dommgr/createHelper.h @@ -152,9 +152,9 @@ class createHelper CF::AllocationManager::AllocationResponseSequence* allocateUsesDeviceProperties( const ossie::UsesDeviceInfo::List& component, const CF::Properties& configureProperties); - ossie::ComponentDeployment* allocateComponent(ossie::ComponentInfo* component, - const std::string& assignedDeviceId, - const std::string& appIdentifier); + void allocateComponent(ossie::ComponentDeployment* deployment, + const std::string& assignedDeviceId, + const std::string& appIdentifier); ossie::AllocationResult allocateComponentToDevice(ossie::ComponentDeployment* deployment, const std::string& assignedDeviceId, From ce3aaf4a878d0880131156940f04e3854b39d26b Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 23 May 2016 14:47:09 -0400 Subject: [PATCH 0257/1644] Start moving deployment-related accessors into the ComponentDeployment class, with the intent of moving the state there later --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 117 +++++++++--------- redhawk/src/control/sdr/dommgr/Deployment.cpp | 20 +++ redhawk/src/control/sdr/dommgr/Deployment.h | 13 ++ 3 files changed, 89 insertions(+), 61 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 5839bd6ba..26de126ae 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -712,7 +712,7 @@ bool createHelper::placeHostCollocation(ossie::ApplicationDeployment& appDeploym ossie::ComponentDeployment* deployment = *current; const ImplementationList& comp_impls = deployment->getComponent()->getImplementations(); LOG_TRACE(ApplicationFactory_impl, "Finding collocation-compatible implementations for component " - << deployment->getComponent()->getInstantiationIdentifier()); + << deployment->getInstantiationIdentifier()); ++current; for (ImplementationList::const_iterator impl = comp_impls.begin(); impl != comp_impls.end(); ++impl) { LOG_TRACE(ApplicationFactory_impl, "Checking implementation " << (*impl)->getId()); @@ -756,7 +756,7 @@ bool createHelper::allocateHostCollocation(ossie::ApplicationDeployment& appDepl LOG_TRACE(ApplicationFactory_impl, "Allocating deployment for " << components.size() << " collocated components"); for (DeploymentList::const_iterator depl = components.begin(); depl != components.end(); ++depl) { - LOG_TRACE(ApplicationFactory_impl, "Component " << (*depl)->getComponent()->getInstantiationIdentifier() + LOG_TRACE(ApplicationFactory_impl, "Component " << (*depl)->getInstantiationIdentifier() << " implementation " << (*depl)->getImplementation()->getId()); } @@ -778,7 +778,7 @@ bool createHelper::allocateHostCollocation(ossie::ApplicationDeployment& appDepl (*depl)->clearDependencies(); if (!resolveSoftpkgDependencies(*depl, *node)) { LOG_TRACE(ApplicationFactory_impl, "Unable to resolve softpackage dependencies for component " - << (*depl)->getComponent()->getIdentifier() + << (*depl)->getIdentifier() << " implementation " << (*depl)->getImplementation()->getId()); return false; } @@ -1290,16 +1290,15 @@ CF::Application_ptr createHelper::create ( } for (DeploymentList::const_iterator dep = deployments.begin(); dep != deployments.end(); ++dep) { - ossie::ComponentInfo* component = (*dep)->getComponent(); CF::DeviceAssignmentType comp_assignment; - comp_assignment.componentId = component->getIdentifier().c_str(); + comp_assignment.componentId = (*dep)->getIdentifier().c_str(); comp_assignment.assignedDeviceId = (*dep)->getAssignedDevice()->identifier.c_str(); ossie::corba::push_back(app_devices, comp_assignment); const UsesList& dep_uses = (*dep)->getUsesDeviceAssignments(); for (UsesList::const_iterator uses = dep_uses.begin(); uses != dep_uses.end(); ++uses) { CF::DeviceAssignmentType assignment; - assignment.componentId = component->getIdentifier().c_str(); + assignment.componentId = (*dep)->getIdentifier().c_str(); std::string deviceId; try { deviceId = ossie::corba::returnString((*uses)->getAssignedDevice()->identifier()); @@ -1441,16 +1440,11 @@ void createHelper::allocateComponent(ossie::ComponentDeployment* deployment, const std::string& assignedDeviceId, const std::string& appIdentifier) { - ossie::ComponentInfo* component = deployment->getComponent(); - CF::Properties configureProperties = component->getConfigureProperties(); - const CF::Properties &construct_props = component->getConstructProperties(); - unsigned int configlen = configureProperties.length(); - configureProperties.length(configureProperties.length()+construct_props.length()); - for (unsigned int i=0; igetConfigureProperties(); + ossie::corba::extend(configureProperties, deployment->getConstructProperties()); // Find the devices that allocate the SPD's minimum required usesdevices properties + ossie::ComponentInfo* component = deployment->getComponent(); const UsesDeviceInfo::List &usesDevVec = component->getUsesDevices(); ossie::UsesDeviceDeployment assignedDevices; if (!allocateUsesDevices(usesDevVec, configureProperties, assignedDevices, this->_allocations)) { @@ -1468,7 +1462,7 @@ void createHelper::allocateComponent(ossie::ComponentDeployment* deployment, eout << (*uses)->getId(); } } - eout << "for component '" << component->getIdentifier() << "'"; + eout << "for component '" << deployment->getIdentifier() << "'"; LOG_DEBUG(ApplicationFactory_impl, eout.str()); throw CF::ApplicationFactory::CreateApplicationError(CF::CF_ENOSPC, eout.str().c_str()); } @@ -1485,7 +1479,7 @@ void createHelper::allocateComponent(ossie::ComponentDeployment* deployment, if (!allocateUsesDevices(implUsesDevVec, configureProperties, implAssignedDevices, implAllocations)) { LOG_DEBUG(ApplicationFactory_impl, "Unable to satisfy 'usesdevice' dependencies for component " - << component->getIdentifier() << " implementation " << impl->getId()); + << deployment->getIdentifier() << " implementation " << impl->getId()); continue; } @@ -1501,7 +1495,7 @@ void createHelper::allocateComponent(ossie::ComponentDeployment* deployment, if (response.first.empty()) { LOG_DEBUG(ApplicationFactory_impl, "Unable to allocate device for component " - << component->getIdentifier() << " implementation " << impl->getId()); + << deployment->getIdentifier() << " implementation " << impl->getId()); continue; } @@ -1515,12 +1509,12 @@ void createHelper::allocateComponent(ossie::ComponentDeployment* deployment, if (!resolveSoftpkgDependencies(deployment, node)) { LOG_DEBUG(ApplicationFactory_impl, "Unable to resolve softpackage dependencies for component " - << component->getIdentifier() << " implementation " << impl->getId()); + << deployment->getIdentifier() << " implementation " << impl->getId()); continue; } // Allocation to a device succeeded - LOG_DEBUG(ApplicationFactory_impl, "Assigned component " << component->getInstantiationIdentifier() + LOG_DEBUG(ApplicationFactory_impl, "Assigned component " << deployment->getInstantiationIdentifier() << " implementation " << impl->getId() << " to device " << deviceId); // Move the device to the front of the list @@ -1560,7 +1554,7 @@ void createHelper::allocateComponent(ossie::ComponentDeployment* deployment, // Report failure std::ostringstream eout; eout << "Failed to satisfy device dependencies for component: '"; - eout << component->getName() << "' with component id: '" << component->getIdentifier() << "'"; + eout << component->getName() << "' with component id: '" << deployment->getIdentifier() << "'"; LOG_DEBUG(ApplicationFactory_impl, eout.str()); throw CF::ApplicationFactory::CreateApplicationError(CF::CF_ENOSPC, eout.str().c_str()); } @@ -1747,10 +1741,10 @@ ossie::AllocationResult createHelper::allocateComponentToDevice(ossie::Component if (device == devices.end()) { LOG_DEBUG(ApplicationFactory_impl, "DAS specified unknown device " << assignedDeviceId << - " for component " << component->getIdentifier()); + " for component " << deployment->getIdentifier()); CF::DeviceAssignmentSequence badDAS; badDAS.length(1); - badDAS[0].componentId = component->getIdentifier().c_str(); + badDAS[0].componentId = deployment->getIdentifier().c_str(); badDAS[0].assignedDeviceId = assignedDeviceId.c_str(); throw CF::ApplicationFactory::CreateApplicationRequestError(badDAS); } @@ -2066,7 +2060,7 @@ void createHelper::loadAndExecuteComponents(const DeploymentList& deployments, boost::shared_ptr device = deployment->getAssignedDevice(); if (!device) { std::ostringstream message; - message << "component " << component->getIdentifier() << " was not assigned to a device"; + message << "component " << deployment->getIdentifier() << " was not assigned to a device"; throw std::logic_error(message.str()); } @@ -2076,13 +2070,13 @@ void createHelper::loadAndExecuteComponents(const DeploymentList& deployments, << component->getIdentifier() << " ASSIGNED TO DEVICE ID/LABEL: " << device->identifier << "/" << device->label); // Let the application know to expect the given component - _application->addComponent(component->getIdentifier(), component->getSpdFileName()); - _application->setComponentImplementation(component->getIdentifier(), implementation->getId()); + _application->addComponent(deployment->getIdentifier(), component->getSpdFileName()); + _application->setComponentImplementation(deployment->getIdentifier(), implementation->getId()); if (component->isNamingService()) { std::string lookupName = _baseNamingContext + "/" + component->getNamingServiceName() ; - _application->setComponentNamingContext(component->getIdentifier(), lookupName); + _application->setComponentNamingContext(deployment->getIdentifier(), lookupName); } - _application->setComponentDevice(component->getIdentifier(), device->device); + _application->setComponentDevice(deployment->getIdentifier(), device->device); // get the code.localfile LOG_TRACE(ApplicationFactory_impl, "Host is " << device->label << " Local file name is " @@ -2093,7 +2087,7 @@ void createHelper::loadAndExecuteComponents(const DeploymentList& deployments, if (codeLocalFile.empty()) { ostringstream eout; eout << "code.localfile is empty for component: '"; - eout << component->getName() << "' with component id: '" << component->getIdentifier() << "' "; + eout << component->getName() << "' with component id: '" << deployment->getIdentifier() << "' "; eout << " with implementation id: '" << implementation->getId() << "'"; eout << " on device id: '" << device->identifier << "'"; eout << " in waveform '" << _waveformContextName<<"'"; @@ -2106,7 +2100,7 @@ void createHelper::loadAndExecuteComponents(const DeploymentList& deployments, CF::LoadableDevice_var loadabledev = ossie::corba::_narrowSafe(device->device); if (CORBA::is_nil(loadabledev)) { std::ostringstream message; - message << "component " << component->getIdentifier() << " was assigned to non-loadable device " + message << "component " << deployment->getIdentifier() << " was assigned to non-loadable device " << device->identifier; LOG_ERROR(ApplicationFactory_impl, message); throw std::logic_error(message.str()); @@ -2232,7 +2226,7 @@ void createHelper::attemptComponentExecution (CF::ApplicationRegistrar_ptr regis CF::ExecutableDevice_var execdev = ossie::corba::_narrowSafe(device->device); if (CORBA::is_nil(execdev)){ std::ostringstream message; - message << "component " << component->getIdentifier() << " was assigned to non-executable device " + message << "component " << deployment->getIdentifier() << " was assigned to non-executable device " << device->identifier; throw std::logic_error(message.str()); } @@ -2251,7 +2245,7 @@ void createHelper::attemptComponentExecution (CF::ApplicationRegistrar_ptr regis // Add the required parameters specified in SR:163 // Naming Context IOR, Name Binding, and component identifier - execParameters["COMPONENT_IDENTIFIER"] = component->getIdentifier(); + execParameters["COMPONENT_IDENTIFIER"] = deployment->getIdentifier(); execParameters["NAME_BINDING"] = component->getNamingServiceName(); execParameters["DOM_PATH"] = _baseNamingContext; execParameters["PROFILE_NAME"] = component->getSpdFileName(); @@ -2296,7 +2290,7 @@ void createHelper::attemptComponentExecution (CF::ApplicationRegistrar_ptr regis std::string added_message = this->createVersionMismatchMessage(component_version); ostringstream eout; eout << "InvalidFileName when calling 'execute' on device with device id: '" << device->identifier << "' for component: '"; - eout << component->getName() << "' with component id: '" << component->getIdentifier() << "' "; + eout << component->getName() << "' with component id: '" << deployment->getIdentifier() << "' "; eout << " with implementation id: '" << implementation->getId() << "'"; eout << " in waveform '" << _waveformContextName<<"'"; eout << " with error: <" << _ex.msg << ">;"; @@ -2307,7 +2301,7 @@ void createHelper::attemptComponentExecution (CF::ApplicationRegistrar_ptr regis std::string added_message = this->createVersionMismatchMessage(component_version); ostringstream eout; eout << "InvalidState when calling 'execute' on device with device id: '" << device->identifier << "' for component: '"; - eout << component->getName() << "' with component id: '" << component->getIdentifier() << "' "; + eout << component->getName() << "' with component id: '" << deployment->getIdentifier() << "' "; eout << " with implementation id: '" << implementation->getId() << "'"; eout << " in waveform '" << _waveformContextName<<"'"; eout << " with error: <" << _ex.msg << ">;"; @@ -2318,7 +2312,7 @@ void createHelper::attemptComponentExecution (CF::ApplicationRegistrar_ptr regis std::string added_message = this->createVersionMismatchMessage(component_version); ostringstream eout; eout << "InvalidParameters when calling 'execute' on device with device id: '" << device->identifier << "' for component: '"; - eout << component->getName() << "' with component id: '" << component->getIdentifier() << "' "; + eout << component->getName() << "' with component id: '" << deployment->getIdentifier() << "' "; eout << " with implementation id: '" << implementation->getId() << "'"; eout << " in waveform '" << _waveformContextName<<"'"; eout << " with invalid params: <"; @@ -2333,7 +2327,7 @@ void createHelper::attemptComponentExecution (CF::ApplicationRegistrar_ptr regis std::string added_message = this->createVersionMismatchMessage(component_version); ostringstream eout; eout << "InvalidOptions when calling 'execute' on device with device id: '" << device->identifier << "' for component: '"; - eout << component->getName() << "' with component id: '" << component->getIdentifier() << "' "; + eout << component->getName() << "' with component id: '" << deployment->getIdentifier() << "' "; eout << " with implementation id: '" << implementation->getId() << "'"; eout << " in waveform '" << _waveformContextName<<"'"; eout << " with invalid options: <"; @@ -2347,7 +2341,7 @@ void createHelper::attemptComponentExecution (CF::ApplicationRegistrar_ptr regis std::string added_message = this->createVersionMismatchMessage(component_version); ostringstream eout; eout << "ExecuteFail when calling 'execute' on device with device id: '" << device->identifier << "' for component: '"; - eout << component->getName() << "' with component id: '" << component->getIdentifier() << "' "; + eout << component->getName() << "' with component id: '" << deployment->getIdentifier() << "' "; eout << " with implementation id: '" << implementation->getId() << "'"; eout << " in waveform '" << _waveformContextName<<"'"; eout << " with message: '" << ex.msg << "'"; @@ -2357,7 +2351,7 @@ void createHelper::attemptComponentExecution (CF::ApplicationRegistrar_ptr regis } CATCH_THROW_LOG_ERROR( ApplicationFactory_impl, "Caught an unexpected error when calling 'execute' on device with device id: '" << device->identifier << "' for component: '" << component->getName() - << "' with component id: '" << component->getIdentifier() << "' " + << "' with component id: '" << deployment->getIdentifier() << "' " << " with implementation id: '" << implementation->getId() << "'" << " in waveform '" << _waveformContextName<<"'" << " error occurred near line:" <<__LINE__ << " in file:" << __FILE__, @@ -2369,14 +2363,14 @@ void createHelper::attemptComponentExecution (CF::ApplicationRegistrar_ptr regis ostringstream eout; eout << added_message; eout << "Failed to 'execute' component for component: '"; - eout << component->getName() << "' with component id: '" << component->getIdentifier() << "' "; + eout << component->getName() << "' with component id: '" << deployment->getIdentifier() << "' "; eout << " with implementation id: '" << implementation->getId() << "'"; eout << " in waveform '" << _waveformContextName<<"'"; eout << " error occurred near line:" <<__LINE__ << " in file:" << __FILE__ << ";"; LOG_TRACE(ApplicationFactory_impl, eout.str()) throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EAGAIN, eout.str().c_str()); } else { - _application->setComponentPid(component->getIdentifier(), tempPid); + _application->setComponentPid(deployment->getIdentifier(), tempPid); } } @@ -2433,10 +2427,10 @@ void createHelper::waitForComponentRegistration(const DeploymentList& deployment // Track only SCA-compliant components; non-compliant components will never // register with the application, nor do they need to be initialized std::set expected_components; - for (DeploymentList::const_iterator ii = deployments.begin(); ii != deployments.end(); ++ii) { - ossie::ComponentInfo* component = (*ii)->getComponent(); + for (DeploymentList::const_iterator dep = deployments.begin(); dep != deployments.end(); ++dep) { + ossie::ComponentInfo* component = (*dep)->getComponent(); if (component->isScaCompliant()) { - expected_components.insert(component->getIdentifier()); + expected_components.insert((*dep)->getIdentifier()); } } @@ -2451,9 +2445,9 @@ void createHelper::waitForComponentRegistration(const DeploymentList& deployment for (unsigned int req_idx = 0; req_idx < deployments.size(); req_idx++) { ossie::ComponentDeployment* deployment = deployments[req_idx]; const ossie::ComponentInfo* component = deployment->getComponent(); - if (expected_components.count(component->getIdentifier())) { + if (expected_components.count(deployment->getIdentifier())) { eout << "Timed out waiting for component to register: '" << component->getName() - << "' with component id: '" << component->getIdentifier() + << "' with component id: '" << deployment->getIdentifier() << " assigned to device: '" << deployment->getAssignedDevice()->identifier; break; } @@ -2490,7 +2484,7 @@ void createHelper::initializeComponents(const DeploymentList& deployments) } // Find the component on the Application - const std::string componentId = component->getIdentifier(); + const std::string componentId = deployment->getIdentifier(); CORBA::Object_var objref = _application->getComponentObject(componentId); if (CORBA::is_nil(objref)) { ostringstream eout; @@ -2519,7 +2513,7 @@ void createHelper::initializeComponents(const DeploymentList& deployments) while ( initAttempts > 0 ) { initAttempts--; if ( ossie::corba::objectExists(resource) == true ) { initAttempts = 0; continue; } - LOG_DEBUG(ApplicationFactory_impl, "Retrying component ping............ comp:" << component->getIdentifier() << " waveform: " << _waveformContextName); + LOG_DEBUG(ApplicationFactory_impl, "Retrying component ping............ comp:" << deployment->getIdentifier() << " waveform: " << _waveformContextName); usleep(1000); } @@ -2533,7 +2527,7 @@ void createHelper::initializeComponents(const DeploymentList& deployments) if (partialStruct.length() != 0) { ostringstream eout; eout << "Failed to 'configure' Assembly Controller: '"; - eout << component->getName() << "' with component id: '" << component->getIdentifier() << " assigned to device: '"<< deployment->getAssignedDevice()->identifier << "' "; + eout << component->getName() << "' with component id: '" << deployment->getIdentifier() << " assigned to device: '"<< deployment->getAssignedDevice()->identifier << "' "; eout << " in waveform '"<< _waveformContextName<<"';"; eout << "This component contains structure"<getName() << "' with component id: '" << component->getIdentifier() << " assigned to device: '"<getAssignedDevice()->identifier << "' "; + eout << component->getName() << "' with component id: '" << deployment->getIdentifier() << " assigned to device: '"<getAssignedDevice()->identifier << "' "; eout << " in waveform '"<< _waveformContextName<<"';"; eout << "InvalidConfiguration with this info: <"; eout << e.msg << "> for these invalid properties: "; @@ -2560,7 +2554,7 @@ void createHelper::initializeComponents(const DeploymentList& deployments) } catch(CF::PropertySet::PartialConfiguration& e) { ostringstream eout; eout << "Failed to initialize component properties: '"; - eout << component->getName() << "' with component id: '" << component->getIdentifier() << " assigned to device: '"<getAssignedDevice()->identifier << "' "; + eout << component->getName() << "' with component id: '" << deployment->getIdentifier() << " assigned to device: '"<getAssignedDevice()->identifier << "' "; eout << " in waveform '"<< _waveformContextName<<"';"; eout << "PartialConfiguration for these invalid properties: "; for (unsigned int propIdx = 0; propIdx < e.invalidProperties.length(); propIdx++){ @@ -2576,7 +2570,7 @@ void createHelper::initializeComponents(const DeploymentList& deployments) std::string added_message = this->createVersionMismatchMessage(component_version); eout << added_message; eout << "Failed to initialize component properties: '"; - eout << component->getName() << "' with component id: '" << component->getIdentifier() << " assigned to device: '"<getAssignedDevice()->identifier << "' "; + eout << component->getName() << "' with component id: '" << deployment->getIdentifier() << " assigned to device: '"<getAssignedDevice()->identifier << "' "; eout << " in waveform '"<< _waveformContextName<<"';"; eout << "'initializeProperties' failed with Unknown Exception"; eout << " error occurred near line:" <<__LINE__ << " in file:" << __FILE__ << ";"; @@ -2625,10 +2619,10 @@ void createHelper::configureComponents(const DeploymentList& deployments) if (!component->isScaCompliant()) { // If the component is non-SCA compliant then we don't expect anything beyond this LOG_TRACE(ApplicationFactory_impl, "Skipping configure of non SCA-compliant component " - << component->getIdentifier()); + << (*depl)->getIdentifier()); } else if (!component->isResource()) { LOG_TRACE(ApplicationFactory_impl, "Skipping configure of non-resource component " - << component->getIdentifier()); + << (*depl)->getIdentifier()); } else { // The component is configurable; if it's the assembly controller, // save it for the end @@ -2645,12 +2639,13 @@ void createHelper::configureComponents(const DeploymentList& deployments) } for (DeploymentList::iterator depl = configure_list.begin(); depl != configure_list.end(); ++depl) { - const ossie::ComponentInfo* component = (*depl)->getComponent(); + ossie::ComponentDeployment* deployment = *depl; + const ossie::ComponentInfo* component = deployment->getComponent(); // Assuming 1 instantiation for each componentplacement if (component->isNamingService()) { - CF::Resource_var _rsc = (*depl)->getResourcePtr(); + CF::Resource_var _rsc = deployment->getResourcePtr(); if (CORBA::is_nil(_rsc)) { LOG_ERROR(ApplicationFactory_impl, "Could not get component reference"); @@ -2660,8 +2655,8 @@ void createHelper::configureComponents(const DeploymentList& deployments) eout << added_message; eout << "Could not get component reference for component: '" << component->getName() << "' with component id: '" - << component->getIdentifier() << " assigned to device: '" - << (*depl)->getAssignedDevice()->identifier<<"'"; + << deployment->getIdentifier() << " assigned to device: '" + << deployment->getAssignedDevice()->identifier<<"'"; eout << " in waveform '" << _waveformContextName<<"';"; eout << " error occurred near line:" <<__LINE__ << " in file:" << __FILE__ << ";"; throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EIO, eout.str().c_str()); @@ -2671,7 +2666,7 @@ void createHelper::configureComponents(const DeploymentList& deployments) bool partialWarn = false; if (partialStruct.length() != 0) { ostringstream eout; - eout << "Component " << component->getIdentifier() << " contains structure"<< partialStruct[0].id <<" with a mix of defined and nil values. The behavior for the component is undefined"; + eout << "Component " << deployment->getIdentifier() << " contains structure"<< partialStruct[0].id <<" with a mix of defined and nil values. The behavior for the component is undefined"; LOG_WARN(ApplicationFactory_impl, eout.str()); partialWarn = true; } @@ -2681,7 +2676,7 @@ void createHelper::configureComponents(const DeploymentList& deployments) } catch(CF::PropertySet::InvalidConfiguration& e) { ostringstream eout; eout << "Failed to 'configure' component: '"; - eout << component->getName() << "' with component id: '" << component->getIdentifier() << " assigned to device: '"<<(*depl)->getAssignedDevice()->identifier << "' "; + eout << component->getName() << "' with component id: '" << deployment->getIdentifier() << " assigned to device: '"<getAssignedDevice()->identifier << "' "; eout << " in waveform '"<< _waveformContextName<<"';"; eout << "InvalidConfiguration with this info: <"; eout << e.msg << "> for these invalid properties: "; @@ -2698,7 +2693,7 @@ void createHelper::configureComponents(const DeploymentList& deployments) } catch(CF::PropertySet::PartialConfiguration& e) { ostringstream eout; eout << "Failed to instantiate component: '"; - eout << component->getName() << "' with component id: '" << component->getIdentifier() << " assigned to device: '"<<(*depl)->getAssignedDevice()->identifier << "' "; + eout << component->getName() << "' with component id: '" << deployment->getIdentifier() << " assigned to device: '"<getAssignedDevice()->identifier << "' "; eout << " in waveform '"<< _waveformContextName<<"';"; eout << "Failed to 'configure' component; PartialConfiguration for these invalid properties: "; for (unsigned int propIdx = 0; propIdx < e.invalidProperties.length(); propIdx++){ @@ -2714,7 +2709,7 @@ void createHelper::configureComponents(const DeploymentList& deployments) } catch( ... ) { ostringstream eout; eout << "Failed to instantiate component: '"; - eout << component->getName() << "' with component id: '" << component->getIdentifier() << " assigned to device: '"<< (*depl)->getAssignedDevice()->identifier << "' "; + eout << component->getName() << "' with component id: '" << deployment->getIdentifier() << " assigned to device: '"<< deployment->getAssignedDevice()->identifier << "' "; eout << " in waveform '"<< _waveformContextName<<"';"; eout << "'configure' failed with Unknown Exception"; if (partialWarn) { @@ -2787,7 +2782,7 @@ std::vector createHelper::getStartOrder(const DeploymentList& LOG_TRACE(ApplicationFactory_impl, "Assigning start order"); for (StartOrderMap::iterator ii = start_map.begin(); ii != start_map.end(); ++ii, ++index) { LOG_TRACE(ApplicationFactory_impl, index << ": " - << ii->second->getComponent()->getInstantiationIdentifier()); + << ii->second->getInstantiationIdentifier()); start_order.push_back(ii->second->getResourcePtr()); } return start_order; diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index 01d04b6c8..bbb186f22 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -210,6 +210,16 @@ ComponentInfo* ComponentDeployment::getComponent() return component; } +const std::string& ComponentDeployment::getIdentifier() const +{ + return component->getIdentifier(); +} + +const std::string& ComponentDeployment::getInstantiationIdentifier() const +{ + return component->getInstantiationIdentifier(); +} + void ComponentDeployment::setAssignedDevice(const boost::shared_ptr& device) { assignedDevice = device; @@ -304,6 +314,16 @@ float ComponentDeployment::getCpuReservation() const return *cpuReservation; } +CF::Properties ComponentDeployment::getConfigureProperties() const +{ + return component->getConfigureProperties(); +} + +CF::Properties ComponentDeployment::getConstructProperties() const +{ + return component->getConstructProperties(); +} + redhawk::PropertyMap ComponentDeployment::getAffinityOptionsWithAssignment() const { redhawk::PropertyMap options = affinityOptions; diff --git a/redhawk/src/control/sdr/dommgr/Deployment.h b/redhawk/src/control/sdr/dommgr/Deployment.h index 54de1667b..db35c906d 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.h +++ b/redhawk/src/control/sdr/dommgr/Deployment.h @@ -103,6 +103,16 @@ namespace ossie { ComponentInfo* getComponent(); + /** + * @brief Returns the component's runtime identifier + */ + const std::string& getIdentifier() const; + + /** + * @brief Returns the component's identifier within the waveform + */ + const std::string& getInstantiationIdentifier() const; + std::string getEntryPoint(); redhawk::PropertyMap getOptions(); @@ -118,6 +128,9 @@ namespace ossie { bool hasCpuReservation() const; float getCpuReservation() const; + CF::Properties getConfigureProperties() const; + CF::Properties getConstructProperties() const; + void setAssignedDevice(const boost::shared_ptr& device); boost::shared_ptr getAssignedDevice(); From d91d5f73f622159a1d304d72d1dbf695f2a621ac Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 23 May 2016 15:28:52 -0400 Subject: [PATCH 0258/1644] Move per-instance unique identifier into deployment class --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 23 +++++------------ redhawk/src/control/sdr/dommgr/Deployment.cpp | 25 +++++++++++++------ redhawk/src/control/sdr/dommgr/Deployment.h | 7 ++++-- .../control/sdr/dommgr/applicationSupport.cpp | 11 ++------ .../control/sdr/dommgr/applicationSupport.h | 4 +-- 5 files changed, 32 insertions(+), 38 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 26de126ae..fb5a3423f 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -1178,16 +1178,9 @@ CF::Application_ptr createHelper::create ( rotateDeviceList(_executableDevices, lastExecutableDevice); } - // Give the application a unique identifier of the form - // "softwareassemblyid:ApplicationName", where the application - // name includes the serial number generated for the naming context - // (e.g. "Application_1"). - std::string appIdentifier = - _appFact._identifier + ":" + _waveformContextName; - ////////////////////////////////////////////////// // Load the components to instantiate from the SAD - ossie::ApplicationDeployment app_deployment(appIdentifier); + ossie::ApplicationDeployment app_deployment(_appFact._sadParser, _waveformContextName); getRequiredComponents(_appFact._fileMgr, _appFact._sadParser, app_deployment); ossie::ComponentInfo* assemblyControllerComponent = app_deployment.getAssemblyController(); @@ -1218,7 +1211,7 @@ CF::Application_ptr createHelper::create ( const DeploymentList& deployments = app_deployment.getComponentDeployments(); for (DeploymentList::const_iterator dep = deployments.begin(); dep != deployments.end(); ++dep) { ossie::ComponentInfo* component = (*dep)->getComponent(); - std::map::iterator reservation = specialized_reservations.find(component->getIdentifier()); + std::map::iterator reservation = specialized_reservations.find((*dep)->getIdentifier()); if (reservation == specialized_reservations.end()) { reservation = specialized_reservations.find(component->getUsageName()); } @@ -1229,7 +1222,7 @@ CF::Application_ptr createHelper::create ( //////////////////////////////////////////////// // Create the Application servant - _application = new Application_impl(appIdentifier, + _application = new Application_impl(app_deployment.getIdentifier(), name, _appFact._softwareProfile, _appFact._domainManager, @@ -1335,13 +1328,13 @@ CF::Application_ptr createHelper::create ( if ( _appFact._domainManager ) { _appFact._domainManager->sendAddEvent( _appFact._identifier.c_str(), - appIdentifier.c_str(), + app_deployment.getIdentifier().c_str(), name, appObj, StandardEvent::APPLICATION); } - LOG_INFO(ApplicationFactory_impl, "Done creating application " << appIdentifier << " " << name); + LOG_INFO(ApplicationFactory_impl, "Done creating application " << app_deployment.getIdentifier() << " " << name); _isComplete = true; return appObj._retn(); } @@ -1885,11 +1878,7 @@ ossie::ComponentInfo* createHelper::buildComponentInfo(CF::FileSystem_ptr fileSy const ComponentInstantiation& instance = instantiations[0]; - ostringstream identifier; - identifier << instance.getID(); - // Violate SR:172, we use the uniquified name rather than the passed in name - identifier << ":" << _waveformContextName; - newComponent->setIdentifier(identifier.str().c_str(), instance.getID()); + newComponent->setIdentifier(instance.getID()); newComponent->setNamingService(instance.isNamingService()); diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index bbb186f22..0ce9d22d8 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -198,9 +198,10 @@ std::string SoftpkgDeployment::getLocalFile() return codeLocalFile.string(); } -ComponentDeployment::ComponentDeployment(ComponentInfo* component) : +ComponentDeployment::ComponentDeployment(ComponentInfo* component, const std::string& identifier) : SoftpkgDeployment(component), component(component), + identifier(identifier), affinityOptions(component->getAffinityOptions()) { } @@ -212,7 +213,7 @@ ComponentInfo* ComponentDeployment::getComponent() const std::string& ComponentDeployment::getIdentifier() const { - return component->getIdentifier(); + return identifier; } const std::string& ComponentDeployment::getInstantiationIdentifier() const @@ -367,7 +368,7 @@ CF::Resource_ptr ComponentDeployment::getResourcePtr() const void ComponentDeployment::load(Application_impl* application, CF::FileSystem_ptr fileSystem, CF::LoadableDevice_ptr device) { - SoftpkgDeployment::load(application, fileSystem, device, component->getIdentifier()); + SoftpkgDeployment::load(application, fileSystem, device, identifier); } @@ -420,8 +421,13 @@ ComponentInfo* PlacementPlan::getComponent(const std::string& instantiationId) } -ApplicationDeployment::ApplicationDeployment(const std::string& identifier) : - identifier(identifier) +ApplicationDeployment::ApplicationDeployment(const SoftwareAssembly& sad, const std::string& instanceName) : + // Give the application a unique identifier of the form + // "softwareassemblyid:ApplicationName", where the application name + // includes the serial number generated for the naming context + // (e.g. "Application_1"). + identifier(sad.getID() + ":" + instanceName), + instanceName(instanceName) { } @@ -478,8 +484,13 @@ ComponentInfo* ApplicationDeployment::getAssemblyController() ComponentDeployment* ApplicationDeployment::createComponentDeployment(ComponentInfo* component) { - ComponentDeployment* deployment = new ComponentDeployment(component); + // Create a unique identifier for this component instance by appending the + // application instance's unique name + std::string component_id = component->getInstantiationIdentifier() + ":" + instanceName; + + ComponentDeployment* deployment = new ComponentDeployment(component, component_id); components.push_back(deployment); + return deployment; } @@ -491,7 +502,7 @@ const ApplicationDeployment::ComponentList& ApplicationDeployment::getComponentD ComponentDeployment* ApplicationDeployment::getComponentDeployment(const std::string& instantiationId) { for (ComponentList::iterator comp = components.begin(); comp != components.end(); ++comp) { - if (instantiationId == (*comp)->getComponent()->getInstantiationIdentifier()) { + if (instantiationId == (*comp)->getInstantiationIdentifier()) { return *comp; } } diff --git a/redhawk/src/control/sdr/dommgr/Deployment.h b/redhawk/src/control/sdr/dommgr/Deployment.h index db35c906d..391ebce0c 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.h +++ b/redhawk/src/control/sdr/dommgr/Deployment.h @@ -99,7 +99,7 @@ namespace ossie { class ComponentDeployment : public SoftpkgDeployment, public UsesDeviceDeployment { public: - ComponentDeployment(ComponentInfo* component); + ComponentDeployment(ComponentInfo* component, const std::string& identifier); ComponentInfo* getComponent(); @@ -144,6 +144,8 @@ namespace ossie { protected: ComponentInfo* component; + const std::string identifier; + boost::shared_ptr assignedDevice; CF::Resource_var resource; @@ -182,7 +184,7 @@ namespace ossie { typedef std::vector PlacementList; typedef std::vector ComponentList; - ApplicationDeployment(const std::string& identifier); + ApplicationDeployment(const SoftwareAssembly& sad, const std::string& instanceName); ~ApplicationDeployment(); const std::string& getIdentifier() const; @@ -213,6 +215,7 @@ namespace ossie { protected: const std::string identifier; + const std::string instanceName; PlacementList placements; ComponentList components; }; diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp index c097e664a..f208952ce 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp @@ -576,11 +576,9 @@ ComponentInfo::~ComponentInfo () { } -void ComponentInfo::setIdentifier(const char* _identifier, std::string instance_id) +void ComponentInfo::setIdentifier(const std::string& _identifier) { - identifier = _identifier; - // Per the SCA spec, the identifier is the instantiation ID:waveform_name - instantiationId = instance_id; + instantiationId = _identifier; } void ComponentInfo::setNamingService(const bool _isNamingService) @@ -711,11 +709,6 @@ const std::string& ComponentInfo::getInstantiationIdentifier() const return instantiationId; } -const std::string& ComponentInfo::getIdentifier() const -{ - return identifier; -} - bool ComponentInfo::isNamingService() const { return _isNamingService; diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.h b/redhawk/src/control/sdr/dommgr/applicationSupport.h index 11c74b58c..91b9900d4 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.h +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.h @@ -203,7 +203,7 @@ namespace ossie ComponentInfo (const std::string& spdFileName); ~ComponentInfo (); - void setIdentifier(const char* identifier, std::string instance_id); + void setIdentifier(const std::string& identifier); void setNamingService(const bool isNamingService); void setNamingServiceName(const char* NamingServiceName); void setUsageName(const char* usageName); @@ -223,7 +223,6 @@ namespace ossie void overrideProperty(const char* id, const CORBA::Any& value); const std::string& getInstantiationIdentifier() const; - const std::string& getIdentifier() const; bool isNamingService() const; const char* getUsageName() const; const char* getNamingServiceName() const; @@ -263,7 +262,6 @@ namespace ossie bool _isNamingService; std::string usageName; - std::string identifier; std::string instantiationId; std::string namingServiceName; int startOrder; From 5a1eaa2db7f4c9df6d1c40a2f8edfd5014e24c1c Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 23 May 2016 16:03:01 -0400 Subject: [PATCH 0259/1644] Carry the ComponentInstantiation object in ComponentInfo for use by ComponentDeployment --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 18 ++++++++++-------- redhawk/src/control/sdr/dommgr/Deployment.cpp | 12 ++++++++---- redhawk/src/control/sdr/dommgr/Deployment.h | 4 +++- .../control/sdr/dommgr/applicationSupport.cpp | 16 ++++++++++++---- .../control/sdr/dommgr/applicationSupport.h | 11 ++++++++--- 5 files changed, 41 insertions(+), 20 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index fb5a3423f..8b60d2ab2 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -1851,6 +1851,13 @@ ossie::ComponentInfo* createHelper::buildComponentInfo(CF::FileSystem_ptr fileSy const SoftwareAssembly& sadParser, const ComponentPlacement& component) { + // Even though it is possible for there to be more than one instantiation per component, + // the tooling doesn't support that, so supporting this at a framework level would add + // substantial complexity without providing any appreciable improvements. It is far + // easier to have multiple placements rather than multiple instantiations. + const vector& instantiations = component.getInstantiations(); + const ComponentInstantiation& instance = instantiations[0]; + // Extract required data from SPD file ossie::ComponentInfo* newComponent = 0; LOG_TRACE(ApplicationFactory_impl, "Getting the SPD Filename"); @@ -1861,7 +1868,9 @@ ossie::ComponentInfo* createHelper::buildComponentInfo(CF::FileSystem_ptr fileSy throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EINVAL, eout.str().c_str()); } LOG_TRACE(ApplicationFactory_impl, "Building Component Info From SPD File"); - newComponent = ossie::ComponentInfo::buildComponentInfoFromSPDFile(fileSys, componentfile->getFileName().c_str()); + newComponent = ossie::ComponentInfo::buildComponentInfoFromSPDFile(fileSys, + componentfile->getFileName(), + &instance); if (newComponent == 0) { ostringstream eout; eout << "Error loading component information for file ref " << component.getFileRefId(); @@ -1870,13 +1879,6 @@ ossie::ComponentInfo* createHelper::buildComponentInfo(CF::FileSystem_ptr fileSy } LOG_TRACE(ApplicationFactory_impl, "Done building Component Info From SPD File") - // Even though it is possible for there to be more than one instantiation per component, - // the tooling doesn't support that, so supporting this at a framework level would add - // substantial complexity without providing any appreciable improvements. It is far - // easier to have multiple placements rather than multiple instantiations. - const vector& instantiations = component.getInstantiations(); - - const ComponentInstantiation& instance = instantiations[0]; newComponent->setIdentifier(instance.getID()); diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index 0ce9d22d8..f52bce891 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -198,9 +198,12 @@ std::string SoftpkgDeployment::getLocalFile() return codeLocalFile.string(); } -ComponentDeployment::ComponentDeployment(ComponentInfo* component, const std::string& identifier) : +ComponentDeployment::ComponentDeployment(ComponentInfo* component, + const ComponentInstantiation* instantiation, + const std::string& identifier) : SoftpkgDeployment(component), component(component), + instantiation(instantiation), identifier(identifier), affinityOptions(component->getAffinityOptions()) { @@ -218,7 +221,7 @@ const std::string& ComponentDeployment::getIdentifier() const const std::string& ComponentDeployment::getInstantiationIdentifier() const { - return component->getInstantiationIdentifier(); + return instantiation->getID(); } void ComponentDeployment::setAssignedDevice(const boost::shared_ptr& device) @@ -486,9 +489,10 @@ ComponentDeployment* ApplicationDeployment::createComponentDeployment(ComponentI { // Create a unique identifier for this component instance by appending the // application instance's unique name - std::string component_id = component->getInstantiationIdentifier() + ":" + instanceName; + const ComponentInstantiation* instantiation = component->getInstantiation(); + std::string component_id = instantiation->getID() + ":" + instanceName; - ComponentDeployment* deployment = new ComponentDeployment(component, component_id); + ComponentDeployment* deployment = new ComponentDeployment(component, instantiation, component_id); components.push_back(deployment); return deployment; diff --git a/redhawk/src/control/sdr/dommgr/Deployment.h b/redhawk/src/control/sdr/dommgr/Deployment.h index 391ebce0c..33df9bfd1 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.h +++ b/redhawk/src/control/sdr/dommgr/Deployment.h @@ -99,7 +99,8 @@ namespace ossie { class ComponentDeployment : public SoftpkgDeployment, public UsesDeviceDeployment { public: - ComponentDeployment(ComponentInfo* component, const std::string& identifier); + ComponentDeployment(ComponentInfo* component, const ComponentInstantiation* instantiation, + const std::string& identifier); ComponentInfo* getComponent(); @@ -144,6 +145,7 @@ namespace ossie { protected: ComponentInfo* component; + const ComponentInstantiation* instantiation; const std::string identifier; boost::shared_ptr assignedDevice; diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp index f208952ce..ab2ac72bd 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp @@ -432,11 +432,13 @@ const UsesDeviceInfo* SoftpkgInfo::getUsesDeviceById(const std::string& id) cons */ PREPARE_CF_LOGGING(ComponentInfo); -ComponentInfo* ComponentInfo::buildComponentInfoFromSPDFile(CF::FileSystem_ptr fileSys, const char* spdFileName) +ComponentInfo* ComponentInfo::buildComponentInfoFromSPDFile(CF::FileSystem_ptr fileSys, + const std::string& spdFileName, + const ComponentInstantiation* instantiation) { LOG_TRACE(ComponentInfo, "Building component info from file " << spdFileName); - ossie::ComponentInfo* newComponent = new ossie::ComponentInfo(spdFileName); + ossie::ComponentInfo* newComponent = new ossie::ComponentInfo(spdFileName, instantiation); if (!newComponent->parseProfile(fileSys)) { delete newComponent; @@ -555,11 +557,12 @@ ComponentInfo* ComponentInfo::buildComponentInfoFromSPDFile(CF::FileSystem_ptr f return newComponent; } -ComponentInfo::ComponentInfo(const std::string& spdFileName) : +ComponentInfo::ComponentInfo(const std::string& spdFileName, const ComponentInstantiation* instantiation) : SoftpkgInfo(spdFileName), _isAssemblyController(false), _isScaCompliant(true), - startOrder(-1) + startOrder(-1), + instantiation(instantiation) { // load common affinity property definitions try { @@ -576,6 +579,11 @@ ComponentInfo::~ComponentInfo () { } +const ComponentInstantiation* ComponentInfo::getInstantiation() const +{ + return instantiation; +} + void ComponentInfo::setIdentifier(const std::string& _identifier) { instantiationId = _identifier; diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.h b/redhawk/src/control/sdr/dommgr/applicationSupport.h index 91b9900d4..38dffdf4a 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.h +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.h @@ -200,9 +200,11 @@ namespace ossie typedef ossie::ComponentInstantiation::AffinityProperties AffinityProperties; typedef ossie::ComponentInstantiation::LoggingConfig LoggingConfig; - ComponentInfo (const std::string& spdFileName); + ComponentInfo (const std::string& spdFileName, const ComponentInstantiation* instantiation); ~ComponentInfo (); + const ComponentInstantiation* getInstantiation() const; + void setIdentifier(const std::string& identifier); void setNamingService(const bool isNamingService); void setNamingServiceName(const char* NamingServiceName); @@ -248,7 +250,9 @@ namespace ossie CF::Properties getExecParameters(); CF::Properties getCommandLineParameters() const; - static ComponentInfo* buildComponentInfoFromSPDFile(CF::FileSystem_ptr fileSys, const char* _SPDFile); + static ComponentInfo* buildComponentInfoFromSPDFile(CF::FileSystem_ptr fileSys, + const std::string& spdFileName, + const ComponentInstantiation* instantiation); ComponentDescriptor scd; ossie::Properties prf; @@ -275,7 +279,8 @@ namespace ossie CF::Properties factoryParameters; CF::Properties execParameters; CF::Properties affinityOptions; - + + const ComponentInstantiation* instantiation; }; } From f5afe15fa17fe9664d83c2bb07b4a1b56430ec45 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 23 May 2016 17:15:33 -0400 Subject: [PATCH 0260/1644] Move start order to ComponentDeployment; drop unused logging configuration --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 13 ++++------- redhawk/src/control/sdr/dommgr/Deployment.cpp | 10 +++++++++ redhawk/src/control/sdr/dommgr/Deployment.h | 3 +++ .../control/sdr/dommgr/applicationSupport.cpp | 22 ------------------- .../control/sdr/dommgr/applicationSupport.h | 8 ------- 5 files changed, 17 insertions(+), 39 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 8b60d2ab2..087b363d9 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -1900,12 +1900,6 @@ ossie::ComponentInfo* createHelper::buildComponentInfo(CF::FileSystem_ptr fileSy newComponent->setUsageName(instance.getUsageName()); newComponent->setAffinity( instance.getAffinity() ); - newComponent->setLoggingConfig( instance.getLoggingConfig() ); - - if (!instance.getStartOrder().empty()) { - int start_order = atoi(instance.getStartOrder().c_str()); - newComponent->setStartOrder(start_order); - } const ossie::ComponentPropertyList & ins_prop = instance.getProperties(); @@ -2759,11 +2753,12 @@ std::vector createHelper::getStartOrder(const DeploymentList& typedef std::multimap StartOrderMap; StartOrderMap start_map; for (size_t index = 0; index < deployments.size(); ++index) { - ossie::ComponentInfo* component = deployments[index]->getComponent(); - if (!component->isAssemblyController() && component->hasStartOrder()) { + ossie::ComponentDeployment* deployment = deployments[index]; + ossie::ComponentInfo* component = deployment->getComponent(); + if (!component->isAssemblyController() && deployment->hasStartOrder()) { // Only track start order if it was provided, and the component is // not the assembly controller - start_map.insert(std::make_pair(component->getStartOrder(), deployments[index])); + start_map.insert(std::make_pair(deployment->getStartOrder(), deployments[index])); } } diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index f52bce891..13ba4d7ed 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -224,6 +224,16 @@ const std::string& ComponentDeployment::getInstantiationIdentifier() const return instantiation->getID(); } +bool ComponentDeployment::hasStartOrder() const +{ + return !(instantiation->getStartOrder().empty()); +} + +int ComponentDeployment::getStartOrder() const +{ + return atoi(instantiation->getStartOrder().c_str()); +} + void ComponentDeployment::setAssignedDevice(const boost::shared_ptr& device) { assignedDevice = device; diff --git a/redhawk/src/control/sdr/dommgr/Deployment.h b/redhawk/src/control/sdr/dommgr/Deployment.h index 33df9bfd1..4f76fe302 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.h +++ b/redhawk/src/control/sdr/dommgr/Deployment.h @@ -114,6 +114,9 @@ namespace ossie { */ const std::string& getInstantiationIdentifier() const; + bool hasStartOrder() const; + int getStartOrder() const; + std::string getEntryPoint(); redhawk::PropertyMap getOptions(); diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp index ab2ac72bd..cc8a48991 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp @@ -561,7 +561,6 @@ ComponentInfo::ComponentInfo(const std::string& spdFileName, const ComponentInst SoftpkgInfo(spdFileName), _isAssemblyController(false), _isScaCompliant(true), - startOrder(-1), instantiation(instantiation) { // load common affinity property definitions @@ -637,17 +636,6 @@ void ComponentInfo::setAffinity( const AffinityProperties &affinity_props ) } - -void ComponentInfo::setLoggingConfig( const LoggingConfig &logcfg ) -{ - loggingConfig = logcfg; -} - -void ComponentInfo::setStartOrder(int index) -{ - startOrder = index; -} - void ComponentInfo::addFactoryParameter(CF::DataType dt) { addProperty(dt, factoryParameters); @@ -753,16 +741,6 @@ bool ComponentInfo::isScaCompliant() const return _isScaCompliant; } -bool ComponentInfo::hasStartOrder() const -{ - return startOrder > -1; -} - -int ComponentInfo::getStartOrder() const -{ - return startOrder; -} - bool ComponentInfo::checkStruct(const CF::Properties &props) const { const redhawk::PropertyMap& tmpProps = redhawk::PropertyMap::cast(props); diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.h b/redhawk/src/control/sdr/dommgr/applicationSupport.h index 38dffdf4a..490a88574 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.h +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.h @@ -198,7 +198,6 @@ namespace ossie public: typedef ossie::ComponentInstantiation::AffinityProperties AffinityProperties; - typedef ossie::ComponentInstantiation::LoggingConfig LoggingConfig; ComponentInfo (const std::string& spdFileName, const ComponentInstantiation* instantiation); ~ComponentInfo (); @@ -212,8 +211,6 @@ namespace ossie void setIsAssemblyController(bool isAssemblyController); void setIsScaCompliant(bool isScaCompliant); void setAffinity( const AffinityProperties &affinity ); - void setLoggingConfig( const LoggingConfig &logcfg ); - void setStartOrder(int index); void addFactoryParameter(CF::DataType dt); void addExecParameter(CF::DataType dt); @@ -232,10 +229,7 @@ namespace ossie bool isConfigurable() const; bool isAssemblyController() const; bool isScaCompliant() const; - bool hasStartOrder() const; - int getStartOrder() const; - bool isAssignedToDevice() const; CF::Properties containsPartialStructConfig() const; CF::Properties containsPartialStructConstruct() const; CF::Properties iteratePartialStruct(const CF::Properties &props) const; @@ -268,10 +262,8 @@ namespace ossie std::string usageName; std::string instantiationId; std::string namingServiceName; - int startOrder; ossie::Properties _affinity_prf; - LoggingConfig loggingConfig; CF::Properties configureProperties; CF::Properties ctorProperties; From edfb3446f2a9a96718d780770e2d84a2d85a0cc2 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 23 May 2016 17:37:39 -0400 Subject: [PATCH 0261/1644] Remove more unneeded members and methods from ComponentInfo; add some methods to ComponentDeployment for accessing instantiation --- .../control/include/ossie/componentProfile.h | 2 +- .../src/control/parser/componentProfile.cpp | 8 ++--- .../sdr/dommgr/ApplicationFactory_impl.cpp | 30 +++++-------------- redhawk/src/control/sdr/dommgr/Deployment.cpp | 10 +++++++ redhawk/src/control/sdr/dommgr/Deployment.h | 3 ++ .../control/sdr/dommgr/applicationSupport.cpp | 27 +---------------- .../control/sdr/dommgr/applicationSupport.h | 8 ----- 7 files changed, 25 insertions(+), 63 deletions(-) diff --git a/redhawk/src/control/include/ossie/componentProfile.h b/redhawk/src/control/include/ossie/componentProfile.h index bf7794767..4aefd403f 100644 --- a/redhawk/src/control/include/ossie/componentProfile.h +++ b/redhawk/src/control/include/ossie/componentProfile.h @@ -217,7 +217,7 @@ namespace ossie { bool isNamingService() const; - const char* getFindByNamingServiceName() const; + const std::string& getFindByNamingServiceName() const; }; /* diff --git a/redhawk/src/control/parser/componentProfile.cpp b/redhawk/src/control/parser/componentProfile.cpp index dbd005572..c55def544 100644 --- a/redhawk/src/control/parser/componentProfile.cpp +++ b/redhawk/src/control/parser/componentProfile.cpp @@ -175,12 +175,8 @@ bool ComponentInstantiation::isNamingService() const { return namingservicename.isSet(); } -const char* ComponentInstantiation::getFindByNamingServiceName() const { - if (namingservicename.isSet()) { - return namingservicename->c_str(); - } else { - return 0; - } +const std::string& ComponentInstantiation::getFindByNamingServiceName() const { + return *namingservicename; } diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 087b363d9..e00ef8654 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -1880,22 +1880,8 @@ ossie::ComponentInfo* createHelper::buildComponentInfo(CF::FileSystem_ptr fileSy LOG_TRACE(ApplicationFactory_impl, "Done building Component Info From SPD File") - newComponent->setIdentifier(instance.getID()); - - newComponent->setNamingService(instance.isNamingService()); - - if (newComponent->isNamingService()) { - ostringstream nameBinding; - nameBinding << instance.getFindByNamingServiceName(); -#if UNIQUIFY_NAME_BINDING -// DON'T USE THIS YET AS IT WILL BREAK OTHER PARTS OF REDHAWK - nameBinding << "_" << i; // Add a _UniqueIdentifier, per SR:169 -#endif - newComponent->setNamingServiceName(nameBinding.str().c_str()); // SR:169 - } else { - if (newComponent->isScaCompliant()) { - LOG_WARN(ApplicationFactory_impl, "component instantiation is sca compliant but does not provide a 'findcomponent' name...this is probably an error") - } + if (newComponent->isScaCompliant() && !instance.isNamingService()) { + LOG_WARN(ApplicationFactory_impl, "component instantiation is sca compliant but does not provide a 'findcomponent' name...this is probably an error"); } newComponent->setUsageName(instance.getUsageName()); @@ -2057,8 +2043,8 @@ void createHelper::loadAndExecuteComponents(const DeploymentList& deployments, // Let the application know to expect the given component _application->addComponent(deployment->getIdentifier(), component->getSpdFileName()); _application->setComponentImplementation(deployment->getIdentifier(), implementation->getId()); - if (component->isNamingService()) { - std::string lookupName = _baseNamingContext + "/" + component->getNamingServiceName() ; + if (deployment->isNamingService()) { + std::string lookupName = _baseNamingContext + "/" + deployment->getNamingServiceName() ; _application->setComponentNamingContext(deployment->getIdentifier(), lookupName); } _application->setComponentDevice(deployment->getIdentifier(), device->device); @@ -2129,7 +2115,7 @@ void createHelper::loadAndExecuteComponents(const DeploymentList& deployments, logcfg_prop = &execParameters[i]; const char* tmpstr; if ( ossie::any::isNull(logcfg_prop->value) == true ) { - LOG_WARN(ApplicationFactory_impl, "Missing value for LOGGING_CONFIG_URI, component: " << _baseNamingContext << "/" << component->getNamingServiceName() ); + LOG_WARN(ApplicationFactory_impl, "Missing value for LOGGING_CONFIG_URI, component: " << _baseNamingContext << "/" << deployment->getNamingServiceName() ); } else { logcfg_prop->value >>= tmpstr; @@ -2142,7 +2128,7 @@ void createHelper::loadAndExecuteComponents(const DeploymentList& deployments, } ossie::logging::LogConfigUriResolverPtr logcfg_resolver = ossie::logging::GetLogConfigUriResolver(); - std::string logcfg_path = ossie::logging::GetComponentPath( _appFact._domainName, _waveformContextName, component->getNamingServiceName() ); + std::string logcfg_path = ossie::logging::GetComponentPath( _appFact._domainName, _waveformContextName, deployment->getNamingServiceName() ); if ( _appFact._domainManager->getUseLogConfigResolver() && logcfg_resolver ) { std::string t_uri = logcfg_resolver->get_uri( logcfg_path ); LOG_DEBUG(ApplicationFactory_impl, "Using LogConfigResolver plugin: path " << logcfg_path << " logcfg:" << t_uri ); @@ -2231,7 +2217,7 @@ void createHelper::attemptComponentExecution (CF::ApplicationRegistrar_ptr regis // Add the required parameters specified in SR:163 // Naming Context IOR, Name Binding, and component identifier execParameters["COMPONENT_IDENTIFIER"] = deployment->getIdentifier(); - execParameters["NAME_BINDING"] = component->getNamingServiceName(); + execParameters["NAME_BINDING"] = deployment->getNamingServiceName(); execParameters["DOM_PATH"] = _baseNamingContext; execParameters["PROFILE_NAME"] = component->getSpdFileName(); @@ -2628,7 +2614,7 @@ void createHelper::configureComponents(const DeploymentList& deployments) const ossie::ComponentInfo* component = deployment->getComponent(); // Assuming 1 instantiation for each componentplacement - if (component->isNamingService()) { + if (deployment->isNamingService()) { CF::Resource_var _rsc = deployment->getResourcePtr(); diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index 13ba4d7ed..d1611ee1d 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -224,6 +224,16 @@ const std::string& ComponentDeployment::getInstantiationIdentifier() const return instantiation->getID(); } +bool ComponentDeployment::isNamingService() const +{ + return instantiation->isNamingService(); +} + +const std::string& ComponentDeployment::getNamingServiceName() const +{ + return instantiation->getFindByNamingServiceName(); +} + bool ComponentDeployment::hasStartOrder() const { return !(instantiation->getStartOrder().empty()); diff --git a/redhawk/src/control/sdr/dommgr/Deployment.h b/redhawk/src/control/sdr/dommgr/Deployment.h index 4f76fe302..72a02e251 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.h +++ b/redhawk/src/control/sdr/dommgr/Deployment.h @@ -114,6 +114,9 @@ namespace ossie { */ const std::string& getInstantiationIdentifier() const; + bool isNamingService() const; + const std::string& getNamingServiceName() const; + bool hasStartOrder() const; int getStartOrder() const; diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp index cc8a48991..99428eec3 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp @@ -583,21 +583,6 @@ const ComponentInstantiation* ComponentInfo::getInstantiation() const return instantiation; } -void ComponentInfo::setIdentifier(const std::string& _identifier) -{ - instantiationId = _identifier; -} - -void ComponentInfo::setNamingService(const bool _isNamingService) -{ - this->_isNamingService = _isNamingService; -} - -void ComponentInfo::setNamingServiceName(const char* _namingServiceName) -{ - namingServiceName = _namingServiceName; -} - void ComponentInfo::setUsageName(const char* _usageName) { if (_usageName != 0) { @@ -702,12 +687,7 @@ void ComponentInfo::process_overrides(CF::Properties* props, const char* id, COR const std::string& ComponentInfo::getInstantiationIdentifier() const { - return instantiationId; -} - -bool ComponentInfo::isNamingService() const -{ - return _isNamingService; + return instantiation->getID(); } const char* ComponentInfo::getUsageName() const @@ -715,11 +695,6 @@ const char* ComponentInfo::getUsageName() const return usageName.c_str(); } -const char* ComponentInfo::getNamingServiceName() const -{ - return namingServiceName.c_str(); -} - bool ComponentInfo::isResource() const { return scd.isResource(); diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.h b/redhawk/src/control/sdr/dommgr/applicationSupport.h index 490a88574..211c8a23b 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.h +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.h @@ -204,9 +204,6 @@ namespace ossie const ComponentInstantiation* getInstantiation() const; - void setIdentifier(const std::string& identifier); - void setNamingService(const bool isNamingService); - void setNamingServiceName(const char* NamingServiceName); void setUsageName(const char* usageName); void setIsAssemblyController(bool isAssemblyController); void setIsScaCompliant(bool isScaCompliant); @@ -222,9 +219,7 @@ namespace ossie void overrideProperty(const char* id, const CORBA::Any& value); const std::string& getInstantiationIdentifier() const; - bool isNamingService() const; const char* getUsageName() const; - const char* getNamingServiceName() const; bool isResource() const; bool isConfigurable() const; bool isAssemblyController() const; @@ -257,11 +252,8 @@ namespace ossie bool _isAssemblyController; bool _isConfigurable; bool _isScaCompliant; - bool _isNamingService; std::string usageName; - std::string instantiationId; - std::string namingServiceName; ossie::Properties _affinity_prf; From fe08eaf69586ad62cc0800b0545939f2d5cbfeee Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 23 May 2016 18:17:20 -0400 Subject: [PATCH 0262/1644] Use empty string to signify no namingservicename, instead of optional value (may want to turn empty namingservicename into an exception) --- redhawk/src/control/include/ossie/componentProfile.h | 2 +- redhawk/src/control/parser/componentProfile.cpp | 4 ++-- redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp | 4 +++- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/redhawk/src/control/include/ossie/componentProfile.h b/redhawk/src/control/include/ossie/componentProfile.h index 4aefd403f..7ca47adf1 100644 --- a/redhawk/src/control/include/ossie/componentProfile.h +++ b/redhawk/src/control/include/ossie/componentProfile.h @@ -187,7 +187,7 @@ namespace ossie { typedef ossie::ComponentPropertyList AffinityProperties; std::string instantiationId; - ossie::optional_value namingservicename; + std::string namingservicename; ossie::optional_value usageName; ossie::ComponentPropertyList properties; std::string _startOrder; diff --git a/redhawk/src/control/parser/componentProfile.cpp b/redhawk/src/control/parser/componentProfile.cpp index c55def544..e24ba9766 100644 --- a/redhawk/src/control/parser/componentProfile.cpp +++ b/redhawk/src/control/parser/componentProfile.cpp @@ -172,11 +172,11 @@ const ossie::ComponentPropertyList & ComponentInstantiation::getProperties() con } bool ComponentInstantiation::isNamingService() const { - return namingservicename.isSet(); + return !namingservicename.empty(); } const std::string& ComponentInstantiation::getFindByNamingServiceName() const { - return *namingservicename; + return namingservicename; } diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index e00ef8654..fabec4cf7 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -2217,7 +2217,9 @@ void createHelper::attemptComponentExecution (CF::ApplicationRegistrar_ptr regis // Add the required parameters specified in SR:163 // Naming Context IOR, Name Binding, and component identifier execParameters["COMPONENT_IDENTIFIER"] = deployment->getIdentifier(); - execParameters["NAME_BINDING"] = deployment->getNamingServiceName(); + if (deployment->isNamingService()) { + execParameters["NAME_BINDING"] = deployment->getNamingServiceName(); + } execParameters["DOM_PATH"] = _baseNamingContext; execParameters["PROFILE_NAME"] = component->getSpdFileName(); From 6766c39d76808cd88b38bdeb5c3feb9d230f998e Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 23 May 2016 18:31:39 -0400 Subject: [PATCH 0263/1644] Always supply a usagename value from the parser object instead of an option value, since it's not really used as an optional value anyway (again, may want to make an empty value an exception) --- .../control/include/ossie/componentProfile.h | 8 ++--- .../src/control/parser/componentProfile.cpp | 30 ++----------------- .../control/sdr/devmgr/DeviceManager_impl.cpp | 4 +-- .../sdr/dommgr/ApplicationFactory_impl.cpp | 4 +-- redhawk/src/control/sdr/dommgr/Deployment.cpp | 5 ++++ redhawk/src/control/sdr/dommgr/Deployment.h | 2 ++ 6 files changed, 14 insertions(+), 39 deletions(-) diff --git a/redhawk/src/control/include/ossie/componentProfile.h b/redhawk/src/control/include/ossie/componentProfile.h index 7ca47adf1..da73b872c 100644 --- a/redhawk/src/control/include/ossie/componentProfile.h +++ b/redhawk/src/control/include/ossie/componentProfile.h @@ -188,7 +188,7 @@ namespace ossie { std::string instantiationId; std::string namingservicename; - ossie::optional_value usageName; + std::string usageName; ossie::ComponentPropertyList properties; std::string _startOrder; AffinityProperties affinityProperties; @@ -196,10 +196,6 @@ namespace ossie { public: ComponentInstantiation(); - ComponentInstantiation(const ComponentInstantiation& other); - - ComponentInstantiation& operator=(const ComponentInstantiation &other); - virtual ~ComponentInstantiation(); public: @@ -207,7 +203,7 @@ namespace ossie { const std::string& getStartOrder() const; - const char* getUsageName() const; + const std::string& getUsageName() const; const ossie::ComponentPropertyList & getProperties() const; diff --git a/redhawk/src/control/parser/componentProfile.cpp b/redhawk/src/control/parser/componentProfile.cpp index e24ba9766..226f3ba13 100644 --- a/redhawk/src/control/parser/componentProfile.cpp +++ b/redhawk/src/control/parser/componentProfile.cpp @@ -126,28 +126,6 @@ ComponentInstantiation::ComponentInstantiation() { } -ComponentInstantiation::ComponentInstantiation(const ComponentInstantiation& other) { - instantiationId = other.instantiationId; - _startOrder = other._startOrder; - usageName = other.usageName; - namingservicename = other.namingservicename; - affinityProperties = other.affinityProperties; - loggingConfig = other.loggingConfig; - properties = other.properties; - -} - -ComponentInstantiation& ComponentInstantiation::operator=(const ComponentInstantiation &other) { - instantiationId = other.instantiationId; - _startOrder = other._startOrder; - usageName = other.usageName; - namingservicename = other.namingservicename; - properties = other.properties; - affinityProperties = other.affinityProperties; - loggingConfig = other.loggingConfig; - return *this; -} - ComponentInstantiation::~ComponentInstantiation() { } @@ -159,12 +137,8 @@ const std::string& ComponentInstantiation::getStartOrder() const { return _startOrder; } -const char* ComponentInstantiation::getUsageName() const { - if (usageName.isSet()) { - return usageName->c_str(); - } else { - return 0; - } +const std::string& ComponentInstantiation::getUsageName() const { + return usageName; } const ossie::ComponentPropertyList & ComponentInstantiation::getProperties() const { diff --git a/redhawk/src/control/sdr/devmgr/DeviceManager_impl.cpp b/redhawk/src/control/sdr/devmgr/DeviceManager_impl.cpp index 7d1739401..b7bf9e2f1 100644 --- a/redhawk/src/control/sdr/devmgr/DeviceManager_impl.cpp +++ b/redhawk/src/control/sdr/devmgr/DeviceManager_impl.cpp @@ -678,7 +678,7 @@ void DeviceManager_impl::createDeviceCacheLocation( // create device cache location std::string baseDevCache = _cacheroot + "/." + _label; - if (instantiation.getUsageName() == 0) { + if (instantiation.getUsageName().empty()) { // no usage name was given, so create one. By definition, the instantiation id must be unique usageName = instantiation.instantiationId; } else { @@ -1941,7 +1941,7 @@ throw (CORBA::SystemException, CF::InvalidObjectReference) std::string deviceid = ossie::corba::returnString(registeringDevice->identifier()); try { const ComponentInstantiation& instantiation = DCDParser.getComponentInstantiationById(deviceid); - if (instantiation.getUsageName() != NULL) + if (!instantiation.getUsageName().empty()) std::string tmp_name = instantiation.getUsageName(); // this is here to get rid of a warning } catch (std::out_of_range& e) { std::ostringstream eout; diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index fabec4cf7..ce05ddefa 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -1210,10 +1210,9 @@ CF::Application_ptr createHelper::create ( // Assign CPU reservations to components const DeploymentList& deployments = app_deployment.getComponentDeployments(); for (DeploymentList::const_iterator dep = deployments.begin(); dep != deployments.end(); ++dep) { - ossie::ComponentInfo* component = (*dep)->getComponent(); std::map::iterator reservation = specialized_reservations.find((*dep)->getIdentifier()); if (reservation == specialized_reservations.end()) { - reservation = specialized_reservations.find(component->getUsageName()); + reservation = specialized_reservations.find((*dep)->getUsageName()); } if (reservation != specialized_reservations.end()) { (*dep)->setCpuReservation(reservation->second); @@ -1884,7 +1883,6 @@ ossie::ComponentInfo* createHelper::buildComponentInfo(CF::FileSystem_ptr fileSy LOG_WARN(ApplicationFactory_impl, "component instantiation is sca compliant but does not provide a 'findcomponent' name...this is probably an error"); } - newComponent->setUsageName(instance.getUsageName()); newComponent->setAffinity( instance.getAffinity() ); const ossie::ComponentPropertyList & ins_prop = instance.getProperties(); diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index d1611ee1d..b55c73c29 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -224,6 +224,11 @@ const std::string& ComponentDeployment::getInstantiationIdentifier() const return instantiation->getID(); } +const std::string& ComponentDeployment::getUsageName() const +{ + return instantiation->getUsageName(); +} + bool ComponentDeployment::isNamingService() const { return instantiation->isNamingService(); diff --git a/redhawk/src/control/sdr/dommgr/Deployment.h b/redhawk/src/control/sdr/dommgr/Deployment.h index 72a02e251..44c580c5e 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.h +++ b/redhawk/src/control/sdr/dommgr/Deployment.h @@ -114,6 +114,8 @@ namespace ossie { */ const std::string& getInstantiationIdentifier() const; + const std::string& getUsageName() const; + bool isNamingService() const; const std::string& getNamingServiceName() const; From 0aeff54dee069744f56d721dee993aeed18c20f5 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 24 May 2016 09:26:54 -0400 Subject: [PATCH 0264/1644] Expose the ComponentInstantiation from ComponentDeployment and remove some methods that just forwarded to the instantiation --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 29 +++++++++++-------- redhawk/src/control/sdr/dommgr/Deployment.cpp | 21 ++------------ redhawk/src/control/sdr/dommgr/Deployment.h | 10 +------ 3 files changed, 21 insertions(+), 39 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index ce05ddefa..dd3210aaa 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -712,7 +712,7 @@ bool createHelper::placeHostCollocation(ossie::ApplicationDeployment& appDeploym ossie::ComponentDeployment* deployment = *current; const ImplementationList& comp_impls = deployment->getComponent()->getImplementations(); LOG_TRACE(ApplicationFactory_impl, "Finding collocation-compatible implementations for component " - << deployment->getInstantiationIdentifier()); + << deployment->getInstantiation()->getID()); ++current; for (ImplementationList::const_iterator impl = comp_impls.begin(); impl != comp_impls.end(); ++impl) { LOG_TRACE(ApplicationFactory_impl, "Checking implementation " << (*impl)->getId()); @@ -756,7 +756,7 @@ bool createHelper::allocateHostCollocation(ossie::ApplicationDeployment& appDepl LOG_TRACE(ApplicationFactory_impl, "Allocating deployment for " << components.size() << " collocated components"); for (DeploymentList::const_iterator depl = components.begin(); depl != components.end(); ++depl) { - LOG_TRACE(ApplicationFactory_impl, "Component " << (*depl)->getInstantiationIdentifier() + LOG_TRACE(ApplicationFactory_impl, "Component " << (*depl)->getInstantiation()->getID() << " implementation " << (*depl)->getImplementation()->getId()); } @@ -1212,7 +1212,7 @@ CF::Application_ptr createHelper::create ( for (DeploymentList::const_iterator dep = deployments.begin(); dep != deployments.end(); ++dep) { std::map::iterator reservation = specialized_reservations.find((*dep)->getIdentifier()); if (reservation == specialized_reservations.end()) { - reservation = specialized_reservations.find((*dep)->getUsageName()); + reservation = specialized_reservations.find((*dep)->getInstantiation()->getUsageName()); } if (reservation != specialized_reservations.end()) { (*dep)->setCpuReservation(reservation->second); @@ -1506,7 +1506,7 @@ void createHelper::allocateComponent(ossie::ComponentDeployment* deployment, } // Allocation to a device succeeded - LOG_DEBUG(ApplicationFactory_impl, "Assigned component " << deployment->getInstantiationIdentifier() + LOG_DEBUG(ApplicationFactory_impl, "Assigned component " << deployment->getInstantiation()->getID() << " implementation " << impl->getId() << " to device " << deviceId); // Move the device to the front of the list @@ -2024,6 +2024,7 @@ void createHelper::loadAndExecuteComponents(const DeploymentList& deployments, for (unsigned int rc_idx = 0; rc_idx < deployments.size (); rc_idx++) { ossie::ComponentDeployment* deployment = deployments[rc_idx]; ossie::ComponentInfo* component = deployment->getComponent(); + const ossie::ComponentInstantiation* instantiation = deployment->getInstantiation(); const ossie::ImplementationInfo* implementation = deployment->getImplementation(); boost::shared_ptr device = deployment->getAssignedDevice(); @@ -2041,8 +2042,8 @@ void createHelper::loadAndExecuteComponents(const DeploymentList& deployments, // Let the application know to expect the given component _application->addComponent(deployment->getIdentifier(), component->getSpdFileName()); _application->setComponentImplementation(deployment->getIdentifier(), implementation->getId()); - if (deployment->isNamingService()) { - std::string lookupName = _baseNamingContext + "/" + deployment->getNamingServiceName() ; + if (instantiation->isNamingService()) { + std::string lookupName = _baseNamingContext + "/" + instantiation->getFindByNamingServiceName(); _application->setComponentNamingContext(deployment->getIdentifier(), lookupName); } _application->setComponentDevice(deployment->getIdentifier(), device->device); @@ -2107,13 +2108,16 @@ void createHelper::loadAndExecuteComponents(const DeploymentList& deployments, std::string logging_uri(""); CF::DataType* logcfg_prop = NULL; CF::Properties execParameters = component->getExecParameters(); + const ossie::ComponentInstantiation* instantiation = deployment->getInstantiation(); for (unsigned int i = 0; i < execParameters.length(); ++i) { std::string propid = static_cast(execParameters[i].id); if (propid == "LOGGING_CONFIG_URI") { logcfg_prop = &execParameters[i]; const char* tmpstr; if ( ossie::any::isNull(logcfg_prop->value) == true ) { - LOG_WARN(ApplicationFactory_impl, "Missing value for LOGGING_CONFIG_URI, component: " << _baseNamingContext << "/" << deployment->getNamingServiceName() ); + LOG_WARN(ApplicationFactory_impl, "Missing value for LOGGING_CONFIG_URI, component: " + << _baseNamingContext << "/" + << instantiation->getFindByNamingServiceName()); } else { logcfg_prop->value >>= tmpstr; @@ -2126,7 +2130,8 @@ void createHelper::loadAndExecuteComponents(const DeploymentList& deployments, } ossie::logging::LogConfigUriResolverPtr logcfg_resolver = ossie::logging::GetLogConfigUriResolver(); - std::string logcfg_path = ossie::logging::GetComponentPath( _appFact._domainName, _waveformContextName, deployment->getNamingServiceName() ); + std::string logcfg_path = ossie::logging::GetComponentPath(_appFact._domainName, _waveformContextName, + instantiation->getFindByNamingServiceName()); if ( _appFact._domainManager->getUseLogConfigResolver() && logcfg_resolver ) { std::string t_uri = logcfg_resolver->get_uri( logcfg_path ); LOG_DEBUG(ApplicationFactory_impl, "Using LogConfigResolver plugin: path " << logcfg_path << " logcfg:" << t_uri ); @@ -2215,8 +2220,8 @@ void createHelper::attemptComponentExecution (CF::ApplicationRegistrar_ptr regis // Add the required parameters specified in SR:163 // Naming Context IOR, Name Binding, and component identifier execParameters["COMPONENT_IDENTIFIER"] = deployment->getIdentifier(); - if (deployment->isNamingService()) { - execParameters["NAME_BINDING"] = deployment->getNamingServiceName(); + if (deployment->getInstantiation()->isNamingService()) { + execParameters["NAME_BINDING"] = deployment->getInstantiation()->getFindByNamingServiceName(); } execParameters["DOM_PATH"] = _baseNamingContext; execParameters["PROFILE_NAME"] = component->getSpdFileName(); @@ -2614,7 +2619,7 @@ void createHelper::configureComponents(const DeploymentList& deployments) const ossie::ComponentInfo* component = deployment->getComponent(); // Assuming 1 instantiation for each componentplacement - if (deployment->isNamingService()) { + if (deployment->getInstantiation()->isNamingService()) { CF::Resource_var _rsc = deployment->getResourcePtr(); @@ -2754,7 +2759,7 @@ std::vector createHelper::getStartOrder(const DeploymentList& LOG_TRACE(ApplicationFactory_impl, "Assigning start order"); for (StartOrderMap::iterator ii = start_map.begin(); ii != start_map.end(); ++ii, ++index) { LOG_TRACE(ApplicationFactory_impl, index << ": " - << ii->second->getInstantiationIdentifier()); + << ii->second->getInstantiation()->getID()); start_order.push_back(ii->second->getResourcePtr()); } return start_order; diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index b55c73c29..ffdda2082 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -219,24 +219,9 @@ const std::string& ComponentDeployment::getIdentifier() const return identifier; } -const std::string& ComponentDeployment::getInstantiationIdentifier() const +const ComponentInstantiation* ComponentDeployment::getInstantiation() const { - return instantiation->getID(); -} - -const std::string& ComponentDeployment::getUsageName() const -{ - return instantiation->getUsageName(); -} - -bool ComponentDeployment::isNamingService() const -{ - return instantiation->isNamingService(); -} - -const std::string& ComponentDeployment::getNamingServiceName() const -{ - return instantiation->getFindByNamingServiceName(); + return instantiation; } bool ComponentDeployment::hasStartOrder() const @@ -531,7 +516,7 @@ const ApplicationDeployment::ComponentList& ApplicationDeployment::getComponentD ComponentDeployment* ApplicationDeployment::getComponentDeployment(const std::string& instantiationId) { for (ComponentList::iterator comp = components.begin(); comp != components.end(); ++comp) { - if (instantiationId == (*comp)->getInstantiationIdentifier()) { + if (instantiationId == (*comp)->getInstantiation()->getID()) { return *comp; } } diff --git a/redhawk/src/control/sdr/dommgr/Deployment.h b/redhawk/src/control/sdr/dommgr/Deployment.h index 44c580c5e..bd7193d33 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.h +++ b/redhawk/src/control/sdr/dommgr/Deployment.h @@ -109,15 +109,7 @@ namespace ossie { */ const std::string& getIdentifier() const; - /** - * @brief Returns the component's identifier within the waveform - */ - const std::string& getInstantiationIdentifier() const; - - const std::string& getUsageName() const; - - bool isNamingService() const; - const std::string& getNamingServiceName() const; + const ComponentInstantiation* getInstantiation() const; bool hasStartOrder() const; int getStartOrder() const; From f66c5ba093b4399745d121f8066fc0b2b2844728 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 24 May 2016 10:00:17 -0400 Subject: [PATCH 0265/1644] Convert startorder into an integer in the parser, and reference it directly instead of via the deployment class --- redhawk/src/control/include/ossie/componentProfile.h | 7 ++++--- redhawk/src/control/parser/componentProfile.cpp | 8 ++++++-- redhawk/src/control/parser/internal/sad-pimpl.cpp | 4 +++- .../src/control/sdr/dommgr/ApplicationFactory_impl.cpp | 5 +++-- redhawk/src/control/sdr/dommgr/Deployment.cpp | 10 ---------- redhawk/src/control/sdr/dommgr/Deployment.h | 3 --- 6 files changed, 16 insertions(+), 21 deletions(-) diff --git a/redhawk/src/control/include/ossie/componentProfile.h b/redhawk/src/control/include/ossie/componentProfile.h index da73b872c..c69a7b1d4 100644 --- a/redhawk/src/control/include/ossie/componentProfile.h +++ b/redhawk/src/control/include/ossie/componentProfile.h @@ -190,7 +190,7 @@ namespace ossie { std::string namingservicename; std::string usageName; ossie::ComponentPropertyList properties; - std::string _startOrder; + ossie::optional_value startOrder; AffinityProperties affinityProperties; LoggingConfig loggingConfig; public: @@ -200,8 +200,9 @@ namespace ossie { public: const std::string& getID() const; - - const std::string& getStartOrder() const; + + bool hasStartOrder() const; + int getStartOrder() const; const std::string& getUsageName() const; diff --git a/redhawk/src/control/parser/componentProfile.cpp b/redhawk/src/control/parser/componentProfile.cpp index 226f3ba13..8cb54528f 100644 --- a/redhawk/src/control/parser/componentProfile.cpp +++ b/redhawk/src/control/parser/componentProfile.cpp @@ -133,8 +133,12 @@ const std::string& ComponentInstantiation::getID() const { return instantiationId; } -const std::string& ComponentInstantiation::getStartOrder() const { - return _startOrder; +bool ComponentInstantiation::hasStartOrder() const { + return startOrder.isSet(); +} + +int ComponentInstantiation::getStartOrder() const { + return *startOrder; } const std::string& ComponentInstantiation::getUsageName() const { diff --git a/redhawk/src/control/parser/internal/sad-pimpl.cpp b/redhawk/src/control/parser/internal/sad-pimpl.cpp index 2f0606121..4a7f12a0a 100644 --- a/redhawk/src/control/parser/internal/sad-pimpl.cpp +++ b/redhawk/src/control/parser/internal/sad-pimpl.cpp @@ -278,7 +278,9 @@ namespace sad void componentinstantiation_pimpl:: startorder (const ::std::string& startorder) { - componentInstantiation._startOrder = startorder; + // We have to parse the string into an integer here, rather than declaring + // startorder as an integer in the schema, for backwards compatibility. + componentInstantiation.startOrder = atoi(startorder.c_str()); } void componentinstantiation_pimpl:: diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index dd3210aaa..cea8688a1 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -2746,10 +2746,11 @@ std::vector createHelper::getStartOrder(const DeploymentList& for (size_t index = 0; index < deployments.size(); ++index) { ossie::ComponentDeployment* deployment = deployments[index]; ossie::ComponentInfo* component = deployment->getComponent(); - if (!component->isAssemblyController() && deployment->hasStartOrder()) { + const ossie::ComponentInstantiation* instantiation = deployment->getInstantiation(); + if (!component->isAssemblyController() && instantiation->hasStartOrder()) { // Only track start order if it was provided, and the component is // not the assembly controller - start_map.insert(std::make_pair(deployment->getStartOrder(), deployments[index])); + start_map.insert(std::make_pair(instantiation->getStartOrder(), deployment)); } } diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index ffdda2082..866fe4787 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -224,16 +224,6 @@ const ComponentInstantiation* ComponentDeployment::getInstantiation() const return instantiation; } -bool ComponentDeployment::hasStartOrder() const -{ - return !(instantiation->getStartOrder().empty()); -} - -int ComponentDeployment::getStartOrder() const -{ - return atoi(instantiation->getStartOrder().c_str()); -} - void ComponentDeployment::setAssignedDevice(const boost::shared_ptr& device) { assignedDevice = device; diff --git a/redhawk/src/control/sdr/dommgr/Deployment.h b/redhawk/src/control/sdr/dommgr/Deployment.h index bd7193d33..7fd27f8a9 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.h +++ b/redhawk/src/control/sdr/dommgr/Deployment.h @@ -111,9 +111,6 @@ namespace ossie { const ComponentInstantiation* getInstantiation() const; - bool hasStartOrder() const; - int getStartOrder() const; - std::string getEntryPoint(); redhawk::PropertyMap getOptions(); From 419e69b5862352ef3a842263d15cee15c61168cb Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 24 May 2016 11:22:55 -0400 Subject: [PATCH 0266/1644] Simplify handling of SCA compliance in SoftPkg and related classes --- redhawk/src/control/include/ossie/SoftPkg.h | 27 ++++++++----------- redhawk/src/control/sdr/devmgr/spdSupport.cpp | 18 ++----------- redhawk/src/control/sdr/devmgr/spdSupport.h | 2 -- .../control/sdr/dommgr/applicationSupport.cpp | 14 +--------- .../control/sdr/dommgr/applicationSupport.h | 2 -- 5 files changed, 14 insertions(+), 49 deletions(-) diff --git a/redhawk/src/control/include/ossie/SoftPkg.h b/redhawk/src/control/include/ossie/SoftPkg.h index e91b49d23..727d14642 100644 --- a/redhawk/src/control/include/ossie/SoftPkg.h +++ b/redhawk/src/control/include/ossie/SoftPkg.h @@ -197,9 +197,14 @@ namespace ossie { // SPD Members public: + SPD() : + type("sca_compliant") + { + } + std::string id; std::string name; - optional_value type; + std::string type; optional_value version; optional_value title; optional_value description; @@ -236,13 +241,8 @@ namespace ossie { return _spd->name; } - const char* getSoftPkgType() const { - assert(_spd.get() != 0); - if (_spd->type.isSet()) { - return _spd->type->c_str(); - } else { - return "sca_compliant"; - } + const std::string& getSoftPkgType() const { + return _spd->type; } const char* getSoftPkgVersion() const { @@ -303,7 +303,6 @@ namespace ossie { return _spd->authors; } - //const std::vector& getImplementations() const { const ossie::SPD::Implementations& getImplementations() const { assert(_spd.get() != 0); return _spd->implementations; @@ -314,16 +313,12 @@ namespace ossie { return _spd->usesDevice; }; - bool isScaCompliant() { + bool isScaCompliant() const { assert(_spd.get() != 0); - return (strcmp(getSoftPkgType(), "sca_compliant") == 0); + // Assume compliant unless explicitly set to non-compliant + return _spd->type != "sca_non_compliant"; } - bool isScaNonCompliant() { - assert(_spd.get() != 0); - return (strcmp(getSoftPkgType(), "sca_non_compliant") == 0); - } - const boost::shared_ptr& getProperties() { return _properties; diff --git a/redhawk/src/control/sdr/devmgr/spdSupport.cpp b/redhawk/src/control/sdr/devmgr/spdSupport.cpp index f85f7b205..5734caf47 100644 --- a/redhawk/src/control/sdr/devmgr/spdSupport.cpp +++ b/redhawk/src/control/sdr/devmgr/spdSupport.cpp @@ -465,12 +465,6 @@ void ResourceInfo::LoadResource(CF::FileSystem_ptr fileSys, } } - if (newComponent.spd.isScaNonCompliant()) { - newComponent.setIsScaCompliant(false); - } else { - newComponent.setIsScaCompliant(true); - } - // Extract Properties from the implementation-agnostic PRF file // once we match the component to a device we can grab the implementation // specific PRF file @@ -530,8 +524,7 @@ void ResourceInfo::LoadResource(CF::FileSystem_ptr fileSys, ResourceInfo::ResourceInfo(const std::string& spdFileName) : SoftpkgInfo(spdFileName), - _isAssemblyController(false), - _isScaCompliant(true) + _isAssemblyController(false) { resolved_softpkg_dependencies.resize(0); @@ -563,7 +556,6 @@ void ResourceInfo::_copy( const ResourceInfo& src) scd = src.scd; _isAssemblyController = src._isAssemblyController; _isConfigurable = src._isConfigurable; - _isScaCompliant = src._isScaCompliant; isNamingService = src.isNamingService; usageName = src.usageName; identifier = src.identifier; @@ -623,12 +615,6 @@ void ResourceInfo::setIsAssemblyController(bool _isAssemblyController) this->_isAssemblyController = _isAssemblyController; } -void ResourceInfo::setIsScaCompliant(bool _isScaCompliant) -{ - this->_isScaCompliant = _isScaCompliant; -} - - void ResourceInfo::setAffinity( const AffinityProperties &affinity_props ) { for (unsigned int i = 0; i < affinity_props.size(); ++i) { @@ -790,7 +776,7 @@ const bool ResourceInfo::isAssemblyController() const bool ResourceInfo::isScaCompliant() { - return _isScaCompliant; + return spd.isScaCompliant(); } CF::Properties ResourceInfo::getNonNilConfigureProperties() diff --git a/redhawk/src/control/sdr/devmgr/spdSupport.h b/redhawk/src/control/sdr/devmgr/spdSupport.h index 58818adce..2d7400898 100644 --- a/redhawk/src/control/sdr/devmgr/spdSupport.h +++ b/redhawk/src/control/sdr/devmgr/spdSupport.h @@ -188,7 +188,6 @@ namespace ossie void setNamingServiceName(const char* NamingServiceName); void setUsageName(const char* usageName); void setIsAssemblyController(bool isAssemblyController); - void setIsScaCompliant(bool isScaCompliant); void setNicAssignment(std::string nic); void setAffinity( const AffinityProperties &affinity ); void mergeAffinityOptions( const CF::Properties &new_affinity ); @@ -238,7 +237,6 @@ namespace ossie void _copy( const ResourceInfo &src ); bool _isAssemblyController; bool _isConfigurable; - bool _isScaCompliant; bool isNamingService; std::string usageName; diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp index 99428eec3..c2d539ffb 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp @@ -482,12 +482,6 @@ ComponentInfo* ComponentInfo::buildComponentInfoFromSPDFile(CF::FileSystem_ptr f } } - if (newComponent->spd.isScaNonCompliant()) { - newComponent->setIsScaCompliant(false); - } else { - newComponent->setIsScaCompliant(true); - } - // Extract Properties from the implementation-agnostic PRF file // once we match the component to a device we can grab the implementation // specific PRF file @@ -560,7 +554,6 @@ ComponentInfo* ComponentInfo::buildComponentInfoFromSPDFile(CF::FileSystem_ptr f ComponentInfo::ComponentInfo(const std::string& spdFileName, const ComponentInstantiation* instantiation) : SoftpkgInfo(spdFileName), _isAssemblyController(false), - _isScaCompliant(true), instantiation(instantiation) { // load common affinity property definitions @@ -595,11 +588,6 @@ void ComponentInfo::setIsAssemblyController(bool _isAssemblyController) this->_isAssemblyController = _isAssemblyController; } -void ComponentInfo::setIsScaCompliant(bool _isScaCompliant) -{ - this->_isScaCompliant = _isScaCompliant; -} - void ComponentInfo::setAffinity( const AffinityProperties &affinity_props ) { @@ -713,7 +701,7 @@ bool ComponentInfo::isAssemblyController() const bool ComponentInfo::isScaCompliant() const { - return _isScaCompliant; + return spd.isScaCompliant(); } bool ComponentInfo::checkStruct(const CF::Properties &props) const diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.h b/redhawk/src/control/sdr/dommgr/applicationSupport.h index 211c8a23b..bc09a795c 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.h +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.h @@ -206,7 +206,6 @@ namespace ossie void setUsageName(const char* usageName); void setIsAssemblyController(bool isAssemblyController); - void setIsScaCompliant(bool isScaCompliant); void setAffinity( const AffinityProperties &affinity ); void addFactoryParameter(CF::DataType dt); @@ -251,7 +250,6 @@ namespace ossie void process_overrides(CF::Properties* props, const char* id, CORBA::Any value); bool _isAssemblyController; bool _isConfigurable; - bool _isScaCompliant; std::string usageName; From 39c248eda36ecdcc2349b95f0aa5d610b5699655 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 24 May 2016 11:53:08 -0400 Subject: [PATCH 0267/1644] Provide access to the SoftPkg object from deployment objects and start using that instead of ComponentInfo; remove redundant "SoftPkg" in getSoftPkgName() --- redhawk/src/control/framework/nodebooter.cpp | 2 +- redhawk/src/control/include/ossie/SoftPkg.h | 2 +- .../control/sdr/devmgr/DeviceManager_impl.cpp | 12 ++--- redhawk/src/control/sdr/devmgr/spdSupport.cpp | 7 +-- redhawk/src/control/sdr/devmgr/spdSupport.h | 1 - .../sdr/dommgr/ApplicationFactory_impl.cpp | 48 ++++++++++--------- redhawk/src/control/sdr/dommgr/Deployment.cpp | 5 ++ redhawk/src/control/sdr/dommgr/Deployment.h | 2 + .../control/sdr/dommgr/applicationSupport.cpp | 5 +- .../control/sdr/dommgr/applicationSupport.h | 1 - 10 files changed, 43 insertions(+), 42 deletions(-) diff --git a/redhawk/src/control/framework/nodebooter.cpp b/redhawk/src/control/framework/nodebooter.cpp index 4a273c3f5..1a65b5a38 100644 --- a/redhawk/src/control/framework/nodebooter.cpp +++ b/redhawk/src/control/framework/nodebooter.cpp @@ -194,7 +194,7 @@ static pid_t launchSPD ( LOG_DEBUG(nodebooter, "Loaded SPD file " << spdFile); LOG_DEBUG(nodebooter, "SPD Id: " << spd.getSoftPkgID()); - LOG_DEBUG(nodebooter, "SPD Name: " << spd.getSoftPkgName()); + LOG_DEBUG(nodebooter, "SPD Name: " << spd.getName()); // Find an implementation that we can run. const ossie::SPD::Implementation* impl = matchImplementation(spd.getImplementations(), deviceProps); diff --git a/redhawk/src/control/include/ossie/SoftPkg.h b/redhawk/src/control/include/ossie/SoftPkg.h index 727d14642..f32ed4057 100644 --- a/redhawk/src/control/include/ossie/SoftPkg.h +++ b/redhawk/src/control/include/ossie/SoftPkg.h @@ -236,7 +236,7 @@ namespace ossie { return _spd->id; } - const std::string& getSoftPkgName() const { + const std::string& getName() const { assert(_spd.get() != 0); return _spd->name; } diff --git a/redhawk/src/control/sdr/devmgr/DeviceManager_impl.cpp b/redhawk/src/control/sdr/devmgr/DeviceManager_impl.cpp index b7bf9e2f1..1fdad7be4 100644 --- a/redhawk/src/control/sdr/devmgr/DeviceManager_impl.cpp +++ b/redhawk/src/control/sdr/devmgr/DeviceManager_impl.cpp @@ -1392,7 +1392,7 @@ void DeviceManager_impl::postConstructor ( const SPD::Implementation* matchedDeviceImpl = locateMatchingDeviceImpl(SPDParser, devManImpl); if (matchedDeviceImpl == NULL) { LOG_ERROR(DeviceManager_impl, - "Skipping instantiation of device '" << SPDParser.getSoftPkgName() << "' - '" << SPDParser.getSoftPkgID() << "; " + "Skipping instantiation of device '" << SPDParser.getName() << "' - '" << SPDParser.getSoftPkgID() << "; " << "no available device implementations match device manager properties for deployOnDevice") continue; } @@ -1433,7 +1433,7 @@ void DeviceManager_impl::postConstructor ( if (matchedDeviceImpl == NULL) { LOG_ERROR(DeviceManager_impl, - "Skipping instantiation of device '" << SPDParser.getSoftPkgName() << "' - '" << SPDParser.getSoftPkgID() << "; " + "Skipping instantiation of device '" << SPDParser.getName() << "' - '" << SPDParser.getSoftPkgID() << "; " << "no available device implementations match device manager properties") continue; } @@ -1442,7 +1442,7 @@ void DeviceManager_impl::postConstructor ( ossie::Properties deviceProperties; if (!loadDeviceProperties(SPDParser, *matchedDeviceImpl, deviceProperties)) { - LOG_INFO(DeviceManager_impl, "Skipping instantiation of device '" << SPDParser.getSoftPkgName() << "'"); + LOG_INFO(DeviceManager_impl, "Skipping instantiation of device '" << SPDParser.getName() << "'"); continue; } @@ -1553,7 +1553,7 @@ void DeviceManager_impl::postConstructor ( if (matchedDeviceImpl == NULL) { LOG_ERROR(DeviceManager_impl, - "Skipping instantiation of device '" << SPDParser.getSoftPkgName() << "' - '" << SPDParser.getSoftPkgID() << "; " + "Skipping instantiation of device '" << SPDParser.getName() << "' - '" << SPDParser.getSoftPkgID() << "; " << "no available device implementations match device manager properties") continue; } @@ -1561,7 +1561,7 @@ void DeviceManager_impl::postConstructor ( // store the matchedDeviceImpl's implementation ID in a map for use with "getComponentImplementationId" ossie::Properties deviceProperties; if (!loadDeviceProperties(SPDParser, *matchedDeviceImpl, deviceProperties)) { - LOG_INFO(DeviceManager_impl, "Skipping instantiation of device '" << SPDParser.getSoftPkgName() << "'"); + LOG_INFO(DeviceManager_impl, "Skipping instantiation of device '" << SPDParser.getName() << "'"); continue; } @@ -1660,7 +1660,7 @@ const SPD::Implementation* DeviceManager_impl::locateMatchingDeviceImpl(const So unsigned int implIndex = 0; while( implIndex < impls.size() ) { LOG_TRACE(DeviceManager_impl, - "Attempting to match device " << devSpd.getSoftPkgName() + "Attempting to match device " << devSpd.getName() << " implementation id: " << impls[implIndex].getID() << " to device manager implementation " << deployOnImpl->getID()); diff --git a/redhawk/src/control/sdr/devmgr/spdSupport.cpp b/redhawk/src/control/sdr/devmgr/spdSupport.cpp index 5734caf47..da6228384 100644 --- a/redhawk/src/control/sdr/devmgr/spdSupport.cpp +++ b/redhawk/src/control/sdr/devmgr/spdSupport.cpp @@ -303,13 +303,11 @@ SoftpkgInfo::~SoftpkgInfo() SoftpkgInfo::SoftpkgInfo ( const SoftpkgInfo &src ) { - _name = src._name; _identifier = src._identifier; _implementations = src._implementations; } SoftpkgInfo &SoftpkgInfo::operator=(const SoftpkgInfo &src ) { - _name = src._name; _identifier = src._identifier; _implementations = src._implementations; return *this; @@ -324,7 +322,7 @@ const char* SoftpkgInfo::getSpdFileName() const char* SoftpkgInfo::getName() { - return _name.c_str(); + return spd.getName().c_str(); } const char* SoftpkgInfo::getID() @@ -363,9 +361,8 @@ bool SoftpkgInfo::parseProfile(CF::FileSystem_ptr fileSys) } // Set name from the SPD - _name = spd.getSoftPkgName(); _identifier = spd.getSoftPkgID(); - LOG_DEBUG(SoftpkgInfo, "name/id " << _name << "/" << _identifier); + LOG_DEBUG(SoftpkgInfo, "name/id " << spd.getName() << "/" << _identifier); // Extract implementation data from SPD file const std::vector & spd_i = spd.getImplementations(); diff --git a/redhawk/src/control/sdr/devmgr/spdSupport.h b/redhawk/src/control/sdr/devmgr/spdSupport.h index 2d7400898..4bdf2dfc7 100644 --- a/redhawk/src/control/sdr/devmgr/spdSupport.h +++ b/redhawk/src/control/sdr/devmgr/spdSupport.h @@ -159,7 +159,6 @@ namespace ossie bool parseProfile (CF::FileSystem_ptr fileSys); const std::string _spdFileName; - std::string _name; // name from SPD File std::string _identifier; // identifier from SPD File ImplementationInfo::List _implementations; diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index cea8688a1..2a8395611 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -2194,6 +2194,7 @@ void createHelper::attemptComponentExecution (CF::ApplicationRegistrar_ptr regis { const ossie::ComponentInfo* component = deployment->getComponent(); const ossie::ImplementationInfo* implementation = deployment->getImplementation(); + const ossie::SoftPkg* softpkg = deployment->getSPD(); // Get executable device reference boost::shared_ptr device = deployment->getAssignedDevice(); @@ -2224,7 +2225,7 @@ void createHelper::attemptComponentExecution (CF::ApplicationRegistrar_ptr regis execParameters["NAME_BINDING"] = deployment->getInstantiation()->getFindByNamingServiceName(); } execParameters["DOM_PATH"] = _baseNamingContext; - execParameters["PROFILE_NAME"] = component->getSpdFileName(); + execParameters["PROFILE_NAME"] = softpkg->getSPDFile(); // Add the Naming Context IOR last to make it easier to parse the command line execParameters["NAMING_CONTEXT_IOR"] = ossie::corba::objectToString(registrar); @@ -2266,7 +2267,7 @@ void createHelper::attemptComponentExecution (CF::ApplicationRegistrar_ptr regis std::string added_message = this->createVersionMismatchMessage(component_version); ostringstream eout; eout << "InvalidFileName when calling 'execute' on device with device id: '" << device->identifier << "' for component: '"; - eout << component->getName() << "' with component id: '" << deployment->getIdentifier() << "' "; + eout << softpkg->getName() << "' with component id: '" << deployment->getIdentifier() << "' "; eout << " with implementation id: '" << implementation->getId() << "'"; eout << " in waveform '" << _waveformContextName<<"'"; eout << " with error: <" << _ex.msg << ">;"; @@ -2277,7 +2278,7 @@ void createHelper::attemptComponentExecution (CF::ApplicationRegistrar_ptr regis std::string added_message = this->createVersionMismatchMessage(component_version); ostringstream eout; eout << "InvalidState when calling 'execute' on device with device id: '" << device->identifier << "' for component: '"; - eout << component->getName() << "' with component id: '" << deployment->getIdentifier() << "' "; + eout << softpkg->getName() << "' with component id: '" << deployment->getIdentifier() << "' "; eout << " with implementation id: '" << implementation->getId() << "'"; eout << " in waveform '" << _waveformContextName<<"'"; eout << " with error: <" << _ex.msg << ">;"; @@ -2288,7 +2289,7 @@ void createHelper::attemptComponentExecution (CF::ApplicationRegistrar_ptr regis std::string added_message = this->createVersionMismatchMessage(component_version); ostringstream eout; eout << "InvalidParameters when calling 'execute' on device with device id: '" << device->identifier << "' for component: '"; - eout << component->getName() << "' with component id: '" << deployment->getIdentifier() << "' "; + eout << softpkg->getName() << "' with component id: '" << deployment->getIdentifier() << "' "; eout << " with implementation id: '" << implementation->getId() << "'"; eout << " in waveform '" << _waveformContextName<<"'"; eout << " with invalid params: <"; @@ -2303,7 +2304,7 @@ void createHelper::attemptComponentExecution (CF::ApplicationRegistrar_ptr regis std::string added_message = this->createVersionMismatchMessage(component_version); ostringstream eout; eout << "InvalidOptions when calling 'execute' on device with device id: '" << device->identifier << "' for component: '"; - eout << component->getName() << "' with component id: '" << deployment->getIdentifier() << "' "; + eout << softpkg->getName() << "' with component id: '" << deployment->getIdentifier() << "' "; eout << " with implementation id: '" << implementation->getId() << "'"; eout << " in waveform '" << _waveformContextName<<"'"; eout << " with invalid options: <"; @@ -2317,7 +2318,7 @@ void createHelper::attemptComponentExecution (CF::ApplicationRegistrar_ptr regis std::string added_message = this->createVersionMismatchMessage(component_version); ostringstream eout; eout << "ExecuteFail when calling 'execute' on device with device id: '" << device->identifier << "' for component: '"; - eout << component->getName() << "' with component id: '" << deployment->getIdentifier() << "' "; + eout << softpkg->getName() << "' with component id: '" << deployment->getIdentifier() << "' "; eout << " with implementation id: '" << implementation->getId() << "'"; eout << " in waveform '" << _waveformContextName<<"'"; eout << " with message: '" << ex.msg << "'"; @@ -2326,7 +2327,7 @@ void createHelper::attemptComponentExecution (CF::ApplicationRegistrar_ptr regis throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EIO, eout.str().c_str()); } CATCH_THROW_LOG_ERROR( ApplicationFactory_impl, "Caught an unexpected error when calling 'execute' on device with device id: '" - << device->identifier << "' for component: '" << component->getName() + << device->identifier << "' for component: '" << softpkg->getName() << "' with component id: '" << deployment->getIdentifier() << "' " << " with implementation id: '" << implementation->getId() << "'" << " in waveform '" << _waveformContextName<<"'" @@ -2339,7 +2340,7 @@ void createHelper::attemptComponentExecution (CF::ApplicationRegistrar_ptr regis ostringstream eout; eout << added_message; eout << "Failed to 'execute' component for component: '"; - eout << component->getName() << "' with component id: '" << deployment->getIdentifier() << "' "; + eout << softpkg->getName() << "' with component id: '" << deployment->getIdentifier() << "' "; eout << " with implementation id: '" << implementation->getId() << "'"; eout << " in waveform '" << _waveformContextName<<"'"; eout << " error occurred near line:" <<__LINE__ << " in file:" << __FILE__ << ";"; @@ -2404,8 +2405,7 @@ void createHelper::waitForComponentRegistration(const DeploymentList& deployment // register with the application, nor do they need to be initialized std::set expected_components; for (DeploymentList::const_iterator dep = deployments.begin(); dep != deployments.end(); ++dep) { - ossie::ComponentInfo* component = (*dep)->getComponent(); - if (component->isScaCompliant()) { + if ((*dep)->getSPD()->isScaCompliant()) { expected_components.insert((*dep)->getIdentifier()); } } @@ -2420,9 +2420,8 @@ void createHelper::waitForComponentRegistration(const DeploymentList& deployment ostringstream eout; for (unsigned int req_idx = 0; req_idx < deployments.size(); req_idx++) { ossie::ComponentDeployment* deployment = deployments[req_idx]; - const ossie::ComponentInfo* component = deployment->getComponent(); if (expected_components.count(deployment->getIdentifier())) { - eout << "Timed out waiting for component to register: '" << component->getName() + eout << "Timed out waiting for component to register: '" << deployment->getSPD()->getName() << "' with component id: '" << deployment->getIdentifier() << " assigned to device: '" << deployment->getAssignedDevice()->identifier; break; @@ -2446,10 +2445,11 @@ void createHelper::initializeComponents(const DeploymentList& deployments) for (unsigned int rc_idx = 0; rc_idx < deployments.size (); rc_idx++) { ossie::ComponentDeployment* deployment = deployments[rc_idx]; + const ossie::SoftPkg* softpkg = deployment->getSPD(); const ossie::ComponentInfo* component = deployment->getComponent(); // If the component is non-SCA compliant then we don't expect anything beyond this - if (!component->isScaCompliant()) { + if (!softpkg->isScaCompliant()) { LOG_TRACE(ApplicationFactory_impl, "Component is non SCA-compliant, continuing to next component"); continue; } @@ -2464,7 +2464,7 @@ void createHelper::initializeComponents(const DeploymentList& deployments) CORBA::Object_var objref = _application->getComponentObject(componentId); if (CORBA::is_nil(objref)) { ostringstream eout; - eout << "No object found for component: '" << component->getName() + eout << "No object found for component: '" << softpkg->getName() << "' with component id: '" << componentId << " assigned to device: '"<getAssignedDevice()->identifier<<"'"; eout << " in waveform '" << _waveformContextName<<"';"; @@ -2475,7 +2475,8 @@ void createHelper::initializeComponents(const DeploymentList& deployments) CF::Resource_var resource = ossie::corba::_narrowSafe(objref); if (CORBA::is_nil(resource)) { ostringstream eout; - eout << "CF::Resource::_narrow failed with Unknown Exception for component: '" << component->getName() + eout << "CF::Resource::_narrow failed with Unknown Exception for component: '" + << softpkg->getName() << "' with component id: '" << componentId << " assigned to device: '"<getAssignedDevice()->identifier<<"'"; eout << " in waveform '" << _waveformContextName<<"';"; @@ -2503,7 +2504,7 @@ void createHelper::initializeComponents(const DeploymentList& deployments) if (partialStruct.length() != 0) { ostringstream eout; eout << "Failed to 'configure' Assembly Controller: '"; - eout << component->getName() << "' with component id: '" << deployment->getIdentifier() << " assigned to device: '"<< deployment->getAssignedDevice()->identifier << "' "; + eout << softpkg->getName() << "' with component id: '" << deployment->getIdentifier() << " assigned to device: '"<< deployment->getAssignedDevice()->identifier << "' "; eout << " in waveform '"<< _waveformContextName<<"';"; eout << "This component contains structure"<getName() << "' with component id: '" << deployment->getIdentifier() << " assigned to device: '"<getAssignedDevice()->identifier << "' "; + eout << softpkg->getName() << "' with component id: '" << deployment->getIdentifier() << " assigned to device: '"<getAssignedDevice()->identifier << "' "; eout << " in waveform '"<< _waveformContextName<<"';"; eout << "InvalidConfiguration with this info: <"; eout << e.msg << "> for these invalid properties: "; @@ -2530,7 +2531,7 @@ void createHelper::initializeComponents(const DeploymentList& deployments) } catch(CF::PropertySet::PartialConfiguration& e) { ostringstream eout; eout << "Failed to initialize component properties: '"; - eout << component->getName() << "' with component id: '" << deployment->getIdentifier() << " assigned to device: '"<getAssignedDevice()->identifier << "' "; + eout << softpkg->getName() << "' with component id: '" << deployment->getIdentifier() << " assigned to device: '"<getAssignedDevice()->identifier << "' "; eout << " in waveform '"<< _waveformContextName<<"';"; eout << "PartialConfiguration for these invalid properties: "; for (unsigned int propIdx = 0; propIdx < e.invalidProperties.length(); propIdx++){ @@ -2546,7 +2547,7 @@ void createHelper::initializeComponents(const DeploymentList& deployments) std::string added_message = this->createVersionMismatchMessage(component_version); eout << added_message; eout << "Failed to initialize component properties: '"; - eout << component->getName() << "' with component id: '" << deployment->getIdentifier() << " assigned to device: '"<getAssignedDevice()->identifier << "' "; + eout << softpkg->getName() << "' with component id: '" << deployment->getIdentifier() << " assigned to device: '"<getAssignedDevice()->identifier << "' "; eout << " in waveform '"<< _waveformContextName<<"';"; eout << "'initializeProperties' failed with Unknown Exception"; eout << " error occurred near line:" <<__LINE__ << " in file:" << __FILE__ << ";"; @@ -2616,6 +2617,7 @@ void createHelper::configureComponents(const DeploymentList& deployments) for (DeploymentList::iterator depl = configure_list.begin(); depl != configure_list.end(); ++depl) { ossie::ComponentDeployment* deployment = *depl; + const ossie::SoftPkg* softpkg = deployment->getSPD(); const ossie::ComponentInfo* component = deployment->getComponent(); // Assuming 1 instantiation for each componentplacement @@ -2630,7 +2632,7 @@ void createHelper::configureComponents(const DeploymentList& deployments) std::string added_message = this->createVersionMismatchMessage(component_version); eout << added_message; eout << "Could not get component reference for component: '" - << component->getName() << "' with component id: '" + << softpkg->getName() << "' with component id: '" << deployment->getIdentifier() << " assigned to device: '" << deployment->getAssignedDevice()->identifier<<"'"; eout << " in waveform '" << _waveformContextName<<"';"; @@ -2652,7 +2654,7 @@ void createHelper::configureComponents(const DeploymentList& deployments) } catch(CF::PropertySet::InvalidConfiguration& e) { ostringstream eout; eout << "Failed to 'configure' component: '"; - eout << component->getName() << "' with component id: '" << deployment->getIdentifier() << " assigned to device: '"<getAssignedDevice()->identifier << "' "; + eout << softpkg->getName() << "' with component id: '" << deployment->getIdentifier() << " assigned to device: '"<getAssignedDevice()->identifier << "' "; eout << " in waveform '"<< _waveformContextName<<"';"; eout << "InvalidConfiguration with this info: <"; eout << e.msg << "> for these invalid properties: "; @@ -2669,7 +2671,7 @@ void createHelper::configureComponents(const DeploymentList& deployments) } catch(CF::PropertySet::PartialConfiguration& e) { ostringstream eout; eout << "Failed to instantiate component: '"; - eout << component->getName() << "' with component id: '" << deployment->getIdentifier() << " assigned to device: '"<getAssignedDevice()->identifier << "' "; + eout << softpkg->getName() << "' with component id: '" << deployment->getIdentifier() << " assigned to device: '"<getAssignedDevice()->identifier << "' "; eout << " in waveform '"<< _waveformContextName<<"';"; eout << "Failed to 'configure' component; PartialConfiguration for these invalid properties: "; for (unsigned int propIdx = 0; propIdx < e.invalidProperties.length(); propIdx++){ @@ -2685,7 +2687,7 @@ void createHelper::configureComponents(const DeploymentList& deployments) } catch( ... ) { ostringstream eout; eout << "Failed to instantiate component: '"; - eout << component->getName() << "' with component id: '" << deployment->getIdentifier() << " assigned to device: '"<< deployment->getAssignedDevice()->identifier << "' "; + eout << softpkg->getName() << "' with component id: '" << deployment->getIdentifier() << " assigned to device: '"<< deployment->getAssignedDevice()->identifier << "' "; eout << " in waveform '"<< _waveformContextName<<"';"; eout << "'configure' failed with Unknown Exception"; if (partialWarn) { diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index 866fe4787..f93aae4c7 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -97,6 +97,11 @@ SoftpkgInfo* SoftpkgDeployment::getSoftpkg() return softpkg; } +const SoftPkg* SoftpkgDeployment::getSPD() const +{ + return &(softpkg->spd); +} + void SoftpkgDeployment::setImplementation(const ImplementationInfo* implementation) { this->implementation = implementation; diff --git a/redhawk/src/control/sdr/dommgr/Deployment.h b/redhawk/src/control/sdr/dommgr/Deployment.h index 7fd27f8a9..a23815840 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.h +++ b/redhawk/src/control/sdr/dommgr/Deployment.h @@ -76,6 +76,8 @@ namespace ossie { SoftpkgInfo* getSoftpkg(); + const SoftPkg* getSPD() const; + void setImplementation(const ImplementationInfo* implementation); const ImplementationInfo* getImplementation() const; diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp index c2d539ffb..9be1bedec 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp @@ -354,7 +354,7 @@ const std::string& SoftpkgInfo::getSpdFileName() const const std::string& SoftpkgInfo::getName() const { - return _name; + return spd.getName(); } SoftpkgInfo* SoftpkgInfo::buildSoftpkgInfo(CF::FileSystem_ptr fileSys, const char* spdFileName) @@ -385,9 +385,6 @@ bool SoftpkgInfo::parseProfile(CF::FileSystem_ptr fileSys) return false; } - // Set name from the SPD - _name = spd.getSoftPkgName(); - // Extract implementation data from SPD file const std::vector & spd_i = spd.getImplementations(); diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.h b/redhawk/src/control/sdr/dommgr/applicationSupport.h index bc09a795c..d5b99912b 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.h +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.h @@ -184,7 +184,6 @@ namespace ossie bool parseProfile (CF::FileSystem_ptr fileSys); const std::string _spdFileName; - std::string _name; // Component name from SPD File ImplementationInfo::List _implementations; }; From 328a9efb106c05058624be39a7641f91663f35aa Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 24 May 2016 12:09:07 -0400 Subject: [PATCH 0268/1644] Remove UsesDeviceInfo device assignment methods, since the responsibility has been moved to UsesDeviceAssignment --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 6 ++-- redhawk/src/control/sdr/dommgr/Deployment.cpp | 9 ------ redhawk/src/control/sdr/dommgr/Deployment.h | 2 -- .../control/sdr/dommgr/applicationSupport.cpp | 32 ------------------- .../control/sdr/dommgr/applicationSupport.h | 9 ------ 5 files changed, 2 insertions(+), 56 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 2a8395611..b0b497855 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -879,7 +879,7 @@ void createHelper::_handleUsesDevices(ossie::ApplicationDeployment& appDeploymen eout << "Failed to satisfy 'usesdevice' dependencies "; bool first = true; for (UsesDeviceInfo::List::const_iterator uses = usesDevices.begin(); uses != usesDevices.end(); ++uses) { - if ((*uses)->getAssignedDeviceId().empty()) { + if (!assignedDevices.getUsesDeviceAssignment((*uses)->getId())) { if (!first) { eout << ", "; } else { @@ -1445,7 +1445,7 @@ void createHelper::allocateComponent(ossie::ComponentDeployment* deployment, eout << "Failed to satisfy 'usesdevice' dependencies "; bool first = true; for (UsesDeviceInfo::List::const_iterator uses = usesDevVec.begin(); uses != usesDevVec.end(); ++uses) { - if ((*uses)->getAssignedDeviceId().empty()) { + if (!assignedDevices.getUsesDeviceAssignment((*uses)->getId())) { if (!first) { eout << ", "; } else { @@ -1563,7 +1563,6 @@ bool createHelper::allocateUsesDevices(const ossie::UsesDeviceInfo::List& usesDe for (UsesDeviceInfo::List::const_iterator iter = usesDevices.begin(); iter != usesDevices.end(); ++iter) { // Ensure that no devices are assigned to start; the caller can check // for unassigned devices to report which usesdevices failed - (*iter)->clearAssignedDeviceId(); usesDeviceMap[(*iter)->getId()] = *iter; } @@ -1589,7 +1588,6 @@ bool createHelper::allocateUsesDevices(const ossie::UsesDeviceInfo::List& usesDe continue; } const std::string deviceId = ossie::corba::returnString(response[resp].allocatedDevice->identifier()); - uses->second->setAssignedDeviceId(deviceId); usesDeviceMap.erase(uses); ossie::UsesDeviceAssignment* assignment = new ossie::UsesDeviceAssignment(uses->second); diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index f93aae4c7..12111dace 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -354,15 +354,6 @@ void ComponentDeployment::mergeAffinityOptions(const CF::Properties& properties) affinityOptions.update(properties); } -const UsesDeviceInfo* ComponentDeployment::getUsesDeviceById(const std::string& usesId) -{ - const UsesDeviceInfo* usesDevice = component->getUsesDeviceById(usesId); - if (!usesDevice) { - usesDevice = implementation->getUsesDeviceById(usesId); - } - return usesDevice; -} - void ComponentDeployment::setResourcePtr(CF::Resource_ptr resource) { this->resource = CF::Resource::_duplicate(resource); diff --git a/redhawk/src/control/sdr/dommgr/Deployment.h b/redhawk/src/control/sdr/dommgr/Deployment.h index a23815840..21b05ffca 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.h +++ b/redhawk/src/control/sdr/dommgr/Deployment.h @@ -134,8 +134,6 @@ namespace ossie { void setAssignedDevice(const boost::shared_ptr& device); boost::shared_ptr getAssignedDevice(); - const ossie::UsesDeviceInfo* getUsesDeviceById(const std::string& usesId); - void setResourcePtr(CF::Resource_ptr resource); CF::Resource_ptr getResourcePtr() const; diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp index 9be1bedec..8ec7cd2d3 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp @@ -87,21 +87,6 @@ const std::vector& UsesDeviceInfo::getProperties() const return properties; } -const std::string& UsesDeviceInfo::getAssignedDeviceId() const -{ - return assignedDeviceId; -} - -void UsesDeviceInfo::setAssignedDeviceId(const std::string& deviceId) -{ - assignedDeviceId = deviceId; -} - -void UsesDeviceInfo::clearAssignedDeviceId() -{ - assignedDeviceId.clear(); -} - //////////////////////////////////////////////////// /* * UsesDeviceContext member function definitions @@ -131,18 +116,6 @@ const std::vector& UsesDeviceContext::getUsesDevices() const return usesDevices; } -const UsesDeviceInfo* UsesDeviceContext::getUsesDeviceById(const std::string& id) const -{ - for (size_t ii = 0; ii < usesDevices.size(); ++ii) { - if (usesDevices[ii]->getId() == id) { - return usesDevices[ii]; - } - } - - return 0; -} - - //////////////////////////////////////////////////// /* * ImplementationInfo member function definitions @@ -418,11 +391,6 @@ const ImplementationInfo::List& SoftpkgInfo::getImplementations() const return _implementations; } -const UsesDeviceInfo* SoftpkgInfo::getUsesDeviceById(const std::string& id) const -{ - return UsesDeviceContext::getUsesDeviceById(id); -} - //////////////////////////////////////////////////// /* * ComponentInfo member function definitions diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.h b/redhawk/src/control/sdr/dommgr/applicationSupport.h index d5b99912b..2f322cf92 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.h +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.h @@ -69,16 +69,11 @@ namespace ossie const std::string& getId() const; const std::string& getType() const; const std::vector& getProperties() const; - const std::string& getAssignedDeviceId() const; - - void setAssignedDeviceId(const std::string& deviceId); - void clearAssignedDeviceId(); private: std::string id; std::string type; std::vector properties; - std::string assignedDeviceId; }; /* Base class to contain data for components and implementations @@ -96,8 +91,6 @@ namespace ossie void addUsesDevice(UsesDeviceInfo* usesDevice); const UsesDeviceInfo::List & getUsesDevices() const; - virtual const UsesDeviceInfo* getUsesDeviceById(const std::string& id) const; - protected: UsesDeviceInfo::List usesDevices; @@ -174,8 +167,6 @@ namespace ossie void addImplementation(ImplementationInfo* impl); const ImplementationInfo::List& getImplementations() const; - virtual const UsesDeviceInfo* getUsesDeviceById(const std::string& id) const; - static SoftpkgInfo* buildSoftpkgInfo (CF::FileSystem_ptr fileSys, const char* spdFileName); SoftPkg spd; From 7451510e32e17f17b5df0885a31f641325ee9ffe Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 24 May 2016 12:32:11 -0400 Subject: [PATCH 0269/1644] Drop UsesDeviceInfo and UsesDeviceContext entirely --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 32 +++--- .../control/sdr/dommgr/ApplicationProfile.cpp | 7 -- .../control/sdr/dommgr/ApplicationProfile.h | 2 +- redhawk/src/control/sdr/dommgr/Deployment.cpp | 6 +- redhawk/src/control/sdr/dommgr/Deployment.h | 6 +- .../control/sdr/dommgr/applicationSupport.cpp | 106 +++--------------- .../control/sdr/dommgr/applicationSupport.h | 57 ++-------- redhawk/src/control/sdr/dommgr/createHelper.h | 4 +- 8 files changed, 51 insertions(+), 169 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index b0b497855..6cf634f9c 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -860,7 +860,7 @@ void createHelper::_handleUsesDevices(ossie::ApplicationDeployment& appDeploymen const std::string& appName) { // Gets all uses device info from the SAD file - const UsesDeviceInfo::List& usesDevices = _appProfile.getUsesDevices(); + const std::vector& usesDevices = _appFact._sadParser.getUsesDevices(); LOG_TRACE(ApplicationFactory_impl, "Application has " << usesDevices.size() << " usesdevice dependencies"); // Get the assembly controller's configure properties for context in the @@ -878,14 +878,14 @@ void createHelper::_handleUsesDevices(ossie::ApplicationDeployment& appDeploymen ostringstream eout; eout << "Failed to satisfy 'usesdevice' dependencies "; bool first = true; - for (UsesDeviceInfo::List::const_iterator uses = usesDevices.begin(); uses != usesDevices.end(); ++uses) { - if (!assignedDevices.getUsesDeviceAssignment((*uses)->getId())) { + for (std::vector::const_iterator uses = usesDevices.begin(); uses != usesDevices.end(); ++uses) { + if (!assignedDevices.getUsesDeviceAssignment(uses->getID())) { if (!first) { eout << ", "; } else { first = false; } - eout << (*uses)->getId(); + eout << uses->getID(); } } eout << "for application '" << appName << "'"; @@ -1397,18 +1397,18 @@ void createHelper::overrideProperties(const CF::Properties& initConfiguration, } } -CF::AllocationManager::AllocationResponseSequence* createHelper::allocateUsesDeviceProperties(const UsesDeviceInfo::List& usesDevices, const CF::Properties& configureProperties) +CF::AllocationManager::AllocationResponseSequence* createHelper::allocateUsesDeviceProperties(const std::vector& usesDevices, const CF::Properties& configureProperties) { CF::AllocationManager::AllocationRequestSequence request; request.length(usesDevices.size()); for (unsigned int usesdev_idx=0; usesdev_idx< usesDevices.size(); usesdev_idx++) { - const std::string requestid = usesDevices[usesdev_idx]->getId(); + const std::string requestid = usesDevices[usesdev_idx].getID(); request[usesdev_idx].requestID = requestid.c_str(); // Get the usesdevice dependency properties CF::Properties& allocationProperties = request[usesdev_idx].allocationProperties; - const std::vector&prop_refs = usesDevices[usesdev_idx]->getProperties(); + const std::vector&prop_refs = usesDevices[usesdev_idx].getDependencies(); this->_castRequestProperties(allocationProperties, prop_refs); this->_evaluateMATHinRequest(allocationProperties, configureProperties); @@ -1437,21 +1437,21 @@ void createHelper::allocateComponent(ossie::ComponentDeployment* deployment, // Find the devices that allocate the SPD's minimum required usesdevices properties ossie::ComponentInfo* component = deployment->getComponent(); - const UsesDeviceInfo::List &usesDevVec = component->getUsesDevices(); + const std::vector& usesDevVec = component->getUsesDevices(); ossie::UsesDeviceDeployment assignedDevices; if (!allocateUsesDevices(usesDevVec, configureProperties, assignedDevices, this->_allocations)) { // There were unsatisfied usesdevices for the component ostringstream eout; eout << "Failed to satisfy 'usesdevice' dependencies "; bool first = true; - for (UsesDeviceInfo::List::const_iterator uses = usesDevVec.begin(); uses != usesDevVec.end(); ++uses) { - if (!assignedDevices.getUsesDeviceAssignment((*uses)->getId())) { + for (std::vector::const_iterator uses = usesDevVec.begin(); uses != usesDevVec.end(); ++uses) { + if (!assignedDevices.getUsesDeviceAssignment(uses->getID())) { if (!first) { eout << ", "; } else { first = false; } - eout << (*uses)->getId(); + eout << uses->getID(); } } eout << "for component '" << deployment->getIdentifier() << "'"; @@ -1467,7 +1467,7 @@ void createHelper::allocateComponent(ossie::ComponentDeployment* deployment, // Handle 'usesdevice' dependencies for the particular implementation UsesDeviceDeployment implAssignedDevices; ScopedAllocations implAllocations(*this->_allocationMgr); - const UsesDeviceInfo::List &implUsesDevVec = impl->getUsesDevices(); + const std::vector& implUsesDevVec = impl->getUsesDevices(); if (!allocateUsesDevices(implUsesDevVec, configureProperties, implAssignedDevices, implAllocations)) { LOG_DEBUG(ApplicationFactory_impl, "Unable to satisfy 'usesdevice' dependencies for component " @@ -1551,19 +1551,19 @@ void createHelper::allocateComponent(ossie::ComponentDeployment* deployment, throw CF::ApplicationFactory::CreateApplicationError(CF::CF_ENOSPC, eout.str().c_str()); } -bool createHelper::allocateUsesDevices(const ossie::UsesDeviceInfo::List& usesDevices, +bool createHelper::allocateUsesDevices(const std::vector& usesDevices, const CF::Properties& configureProperties, ossie::UsesDeviceDeployment& deviceAssignments, ScopedAllocations& allocations) { // Create a temporary lookup table for reconciling allocation requests with // usesdevice identifiers - typedef std::map UsesDeviceMap; + typedef std::map UsesDeviceMap; UsesDeviceMap usesDeviceMap; - for (UsesDeviceInfo::List::const_iterator iter = usesDevices.begin(); iter != usesDevices.end(); ++iter) { + for (std::vector::const_iterator iter = usesDevices.begin(); iter != usesDevices.end(); ++iter) { // Ensure that no devices are assigned to start; the caller can check // for unassigned devices to report which usesdevices failed - usesDeviceMap[(*iter)->getId()] = *iter; + usesDeviceMap[iter->getID()] = &(*iter); } // Track allocations made internally, either to clean up on failure or to diff --git a/redhawk/src/control/sdr/dommgr/ApplicationProfile.cpp b/redhawk/src/control/sdr/dommgr/ApplicationProfile.cpp index ef7819195..adc85bd3a 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationProfile.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationProfile.cpp @@ -115,13 +115,6 @@ void ApplicationProfile::load(CF::FileSystem_ptr fileSystem, const SoftwareAssem { identifier = sad.getID(); - // Gets uses device relationships - const std::vector& usesDevice = sad.getUsesDevices(); - for (std::vector::const_iterator use = usesDevice.begin(); use != usesDevice.end(); ++use) { - UsesDeviceInfo* useDev = new UsesDeviceInfo(use->getID(), use->getType(), use->getDependencies()); - addUsesDevice(useDev); - } - // Walk through the host collocations first const std::vector& collocations = sad.getHostCollocations(); for (size_t index = 0; index < collocations.size(); ++index) { diff --git a/redhawk/src/control/sdr/dommgr/ApplicationProfile.h b/redhawk/src/control/sdr/dommgr/ApplicationProfile.h index ccde17f51..b0b67bea4 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationProfile.h +++ b/redhawk/src/control/sdr/dommgr/ApplicationProfile.h @@ -83,7 +83,7 @@ namespace ossie { * -> External Properties * -> UsesDevice relationships */ - class ApplicationProfile : public UsesDeviceContext + class ApplicationProfile { ENABLE_LOGGING; diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index 12111dace..d78c9561d 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -48,7 +48,7 @@ void UsesDeviceDeployment::addUsesDeviceAssignment(UsesDeviceAssignment* assignm UsesDeviceAssignment* UsesDeviceDeployment::getUsesDeviceAssignment(const std::string identifier) { for (AssignmentList::iterator assign = assignments.begin(); assign != assignments.end(); ++assign) { - if (identifier == (*assign)->getUsesDevice()->getId()) { + if (identifier == (*assign)->getUsesDevice()->getID()) { return *assign; } } @@ -61,12 +61,12 @@ const UsesDeviceDeployment::AssignmentList& UsesDeviceDeployment::getUsesDeviceA return assignments; } -UsesDeviceAssignment::UsesDeviceAssignment(UsesDeviceInfo* usesDevice) : +UsesDeviceAssignment::UsesDeviceAssignment(const UsesDevice* usesDevice) : usesDevice(usesDevice) { } -UsesDeviceInfo* UsesDeviceAssignment::getUsesDevice() +const UsesDevice* UsesDeviceAssignment::getUsesDevice() const { return usesDevice; } diff --git a/redhawk/src/control/sdr/dommgr/Deployment.h b/redhawk/src/control/sdr/dommgr/Deployment.h index 21b05ffca..9dc3497e4 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.h +++ b/redhawk/src/control/sdr/dommgr/Deployment.h @@ -37,15 +37,15 @@ namespace ossie { class UsesDeviceAssignment { public: - UsesDeviceAssignment(UsesDeviceInfo* usesDevice); + UsesDeviceAssignment(const UsesDevice* usesDevice); - UsesDeviceInfo* getUsesDevice(); + const UsesDevice* getUsesDevice() const; void setAssignedDevice(CF::Device_ptr device); CF::Device_ptr getAssignedDevice() const; private: - UsesDeviceInfo* usesDevice; + const UsesDevice* usesDevice; CF::Device_var assignedDevice; }; diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp index 8ec7cd2d3..c22a0b65a 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp @@ -56,66 +56,6 @@ static void addProperty(const CF::DataType& dt, CF::Properties& prop) prop[index] = dt; } -//////////////////////////////////////////////////// -/* - * UsesDeviceInfo member function definitions - */ -UsesDeviceInfo::UsesDeviceInfo(const std::string& _id, const std::string& _type, const std::vector& _properties) : - id(_id), - type(_type), - properties(_properties) -{ - -} - -UsesDeviceInfo::~UsesDeviceInfo() -{ -} - -const std::string& UsesDeviceInfo::getId() const -{ - return id; -} - -const std::string& UsesDeviceInfo::getType() const -{ - return type; -} - -const std::vector& UsesDeviceInfo::getProperties() const -{ - return properties; -} - -//////////////////////////////////////////////////// -/* - * UsesDeviceContext member function definitions - */ -PREPARE_CF_LOGGING(UsesDeviceContext); - -UsesDeviceContext::UsesDeviceContext() : - usesDevices() -{ -} - -UsesDeviceContext::~UsesDeviceContext() -{ - for (size_t ii = 0; ii < usesDevices.size(); ++ii) { - delete usesDevices[ii]; - } - usesDevices.clear(); -} - -void UsesDeviceContext::addUsesDevice(UsesDeviceInfo* _usesDevice) -{ - usesDevices.push_back(_usesDevice); -} - -const std::vector& UsesDeviceContext::getUsesDevices() const -{ - return usesDevices; -} - //////////////////////////////////////////////////// /* * ImplementationInfo member function definitions @@ -123,12 +63,9 @@ const std::vector& UsesDeviceContext::getUsesDevices() const PREPARE_CF_LOGGING(ImplementationInfo); ImplementationInfo::ImplementationInfo(const SPD::Implementation& spdImpl) : - id(spdImpl.getID()), + implementation(&spdImpl), codeType(), - localFileName(spdImpl.getCodeFile()), entryPoint(), - processorDeps(spdImpl.getProcessors()), - osDeps(spdImpl.getOsDeps()), dependencyProperties() { setEntryPoint(spdImpl.getEntryPoint()); @@ -136,16 +73,6 @@ ImplementationInfo::ImplementationInfo(const SPD::Implementation& spdImpl) : setStackSize(spdImpl.code.stacksize.get()); setPriority(spdImpl.code.priority.get()); - // Create local copies for all of the usesdevice entries for this implementation. - LOG_TRACE(ImplementationInfo, "Loading component implementation uses device") - const std::vector& spdUsesDevices = spdImpl.getUsesDevices(); - for (size_t ii = 0; ii < spdUsesDevices.size(); ++ii) { - const UsesDevice& spdUsesDev = spdUsesDevices[ii]; - UsesDeviceInfo* usesDevice = new UsesDeviceInfo(spdUsesDev.getID(), spdUsesDev.getType(), - spdUsesDev.getDependencies()); - addUsesDevice(usesDevice); - } - // Handle allocation property dependencies LOG_TRACE(ImplementationInfo, "Loading component implementation property dependencies") const std::vector& dependencies = spdImpl.getDependencies(); @@ -182,12 +109,12 @@ ImplementationInfo* ImplementationInfo::buildImplementationInfo(CF::FileSystem_p const std::string& ImplementationInfo::getId() const { - return id; + return implementation->getID(); } const std::vector& ImplementationInfo::getProcessorDeps() const { - return processorDeps; + return implementation->getProcessors(); } const std::vector& ImplementationInfo::getSoftPkgDependency() const @@ -197,7 +124,7 @@ const std::vector& ImplementationInfo::getSoftPkgDependency() cons const std::vector& ImplementationInfo::getOsDeps() const { - return osDeps; + return implementation->getOsDeps(); } CF::LoadableDevice::LoadType ImplementationInfo::getCodeType() const @@ -207,7 +134,7 @@ CF::LoadableDevice::LoadType ImplementationInfo::getCodeType() const const std::string& ImplementationInfo::getLocalFileName() const { - return localFileName; + return implementation->getCodeFile(); } const std::string& ImplementationInfo::getEntryPoint() const @@ -240,6 +167,11 @@ const std::vector& ImplementationInfo::getDependencyProperties() co return dependencyProperties; } +const std::vector& ImplementationInfo::getUsesDevices() const +{ + return implementation->getUsesDevices(); +} + void ImplementationInfo::setCodeType(const char* _type) { std::string type(_type); @@ -293,8 +225,8 @@ void ImplementationInfo::addSoftPkgDependency(SoftpkgInfo* softpkg) bool ImplementationInfo::checkProcessorAndOs(const Properties& _prf) const { - bool matchProcessor = checkProcessor(processorDeps, _prf.getAllocationProperties()); - bool matchOs = checkOs(osDeps, _prf.getAllocationProperties()); + bool matchProcessor = checkProcessor(getProcessorDeps(), _prf.getAllocationProperties()); + bool matchOs = checkOs(getOsDeps(), _prf.getAllocationProperties()); if (!matchProcessor) { LOG_DEBUG(ImplementationInfo, "Failed to match component processor to device allocation properties"); @@ -369,15 +301,6 @@ bool SoftpkgInfo::parseProfile(CF::FileSystem_ptr fileSys) addImplementation(newImpl); } - // Create local copies for all of the usesdevice entries for this implementation. - const std::vector& spdUsesDevices = spd.getUsesDevices(); - for (size_t ii = 0; ii < spdUsesDevices.size(); ++ii) { - const UsesDevice& spdUsesDev = spdUsesDevices[ii]; - UsesDeviceInfo* usesDevice = new UsesDeviceInfo(spdUsesDev.getID(), spdUsesDev.getType(), - spdUsesDev.getDependencies()); - addUsesDevice(usesDevice); - } - return true; } @@ -391,6 +314,11 @@ const ImplementationInfo::List& SoftpkgInfo::getImplementations() const return _implementations; } +const std::vector& SoftpkgInfo::getUsesDevices() const +{ + return spd.getUsesDevices(); +} + //////////////////////////////////////////////////// /* * ComponentInfo member function definitions diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.h b/redhawk/src/control/sdr/dommgr/applicationSupport.h index 2f322cf92..4dab821e4 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.h +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.h @@ -54,54 +54,12 @@ namespace ossie }; typedef std::list ComponentList; - /* - * - */ - class UsesDeviceInfo - { - - public: - typedef std::vector< UsesDeviceInfo * > List; - - UsesDeviceInfo(const std::string& id, const std::string& type, const std::vector& _properties); - ~UsesDeviceInfo(); - - const std::string& getId() const; - const std::string& getType() const; - const std::vector& getProperties() const; - - private: - std::string id; - std::string type; - std::vector properties; - }; - - /* Base class to contain data for components and implementations - * - Used to store information about about UsesDevice relationships - * since these are handled the same for both components and - * component implementations. - */ - class UsesDeviceContext - { - ENABLE_LOGGING; - - public: - UsesDeviceContext(); - virtual ~UsesDeviceContext(); - - void addUsesDevice(UsesDeviceInfo* usesDevice); - const UsesDeviceInfo::List & getUsesDevices() const; - - protected: - UsesDeviceInfo::List usesDevices; - }; - class SoftpkgInfo; /* Base class to contain data for implementations * - Used to store information about about implementations */ - class ImplementationInfo : public UsesDeviceContext + class ImplementationInfo { ENABLE_LOGGING; @@ -126,8 +84,11 @@ namespace ossie bool checkProcessorAndOs(const ossie::Properties& prf) const; + const std::vector & getUsesDevices() const; + static ImplementationInfo* buildImplementationInfo(CF::FileSystem_ptr fileSys, const SPD::Implementation& spdImpl); + private: ImplementationInfo (const ImplementationInfo&); void setEntryPoint(const char* fileName); @@ -137,22 +98,20 @@ namespace ossie void addDependencyProperty(const ossie::PropertyRef& property); void addSoftPkgDependency(SoftpkgInfo* softpkg); - std::string id; + const ossie::SPD::Implementation* implementation; + CF::LoadableDevice::LoadType codeType; - std::string localFileName; std::string entryPoint; CORBA::ULong stackSize; CORBA::ULong priority; bool _hasStackSize; bool _hasPriority; - std::vector processorDeps; - std::vector osDeps; std::vector dependencyProperties; std::vector softPkgDependencies; }; - class SoftpkgInfo : public UsesDeviceContext + class SoftpkgInfo { ENABLE_LOGGING @@ -167,6 +126,8 @@ namespace ossie void addImplementation(ImplementationInfo* impl); const ImplementationInfo::List& getImplementations() const; + const std::vector & getUsesDevices() const; + static SoftpkgInfo* buildSoftpkgInfo (CF::FileSystem_ptr fileSys, const char* spdFileName); SoftPkg spd; diff --git a/redhawk/src/control/sdr/dommgr/createHelper.h b/redhawk/src/control/sdr/dommgr/createHelper.h index 4dd0d5e79..1c8b90c6b 100644 --- a/redhawk/src/control/sdr/dommgr/createHelper.h +++ b/redhawk/src/control/sdr/dommgr/createHelper.h @@ -145,12 +145,12 @@ class createHelper const ossie::ComponentPlacement& component); // Supports allocation - bool allocateUsesDevices(const ossie::UsesDeviceInfo::List& usesDevices, + bool allocateUsesDevices(const std::vector& usesDevices, const CF::Properties& configureProperties, ossie::UsesDeviceDeployment& assignedDevices, ScopedAllocations& allocations); CF::AllocationManager::AllocationResponseSequence* allocateUsesDeviceProperties( - const ossie::UsesDeviceInfo::List& component, + const std::vector& component, const CF::Properties& configureProperties); void allocateComponent(ossie::ComponentDeployment* deployment, const std::string& assignedDeviceId, From bb00f50610ddca6c790cf385884334771c2092f7 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 24 May 2016 12:50:07 -0400 Subject: [PATCH 0270/1644] Implement SoftpkgDeployment entirely in terms of SoftPkg, instead of SoftpkgInfo --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 12 ++++++------ redhawk/src/control/sdr/dommgr/Deployment.cpp | 15 +++++---------- redhawk/src/control/sdr/dommgr/Deployment.h | 8 +++----- 3 files changed, 14 insertions(+), 21 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 6cf634f9c..40c2fb6e7 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -1833,7 +1833,7 @@ ossie::SoftpkgDeployment* createHelper::resolveDependencyImplementation(ossie::S continue; } - ossie::SoftpkgDeployment* dependency = new ossie::SoftpkgDeployment(softpkg, implementation); + ossie::SoftpkgDeployment* dependency = new ossie::SoftpkgDeployment(&(softpkg->spd), implementation); // Recursively check any softpkg dependencies if (resolveSoftpkgDependencies(dependency, device)) { return dependency; @@ -2192,7 +2192,7 @@ void createHelper::attemptComponentExecution (CF::ApplicationRegistrar_ptr regis { const ossie::ComponentInfo* component = deployment->getComponent(); const ossie::ImplementationInfo* implementation = deployment->getImplementation(); - const ossie::SoftPkg* softpkg = deployment->getSPD(); + const ossie::SoftPkg* softpkg = deployment->getSoftPkg(); // Get executable device reference boost::shared_ptr device = deployment->getAssignedDevice(); @@ -2403,7 +2403,7 @@ void createHelper::waitForComponentRegistration(const DeploymentList& deployment // register with the application, nor do they need to be initialized std::set expected_components; for (DeploymentList::const_iterator dep = deployments.begin(); dep != deployments.end(); ++dep) { - if ((*dep)->getSPD()->isScaCompliant()) { + if ((*dep)->getSoftPkg()->isScaCompliant()) { expected_components.insert((*dep)->getIdentifier()); } } @@ -2419,7 +2419,7 @@ void createHelper::waitForComponentRegistration(const DeploymentList& deployment for (unsigned int req_idx = 0; req_idx < deployments.size(); req_idx++) { ossie::ComponentDeployment* deployment = deployments[req_idx]; if (expected_components.count(deployment->getIdentifier())) { - eout << "Timed out waiting for component to register: '" << deployment->getSPD()->getName() + eout << "Timed out waiting for component to register: '" << deployment->getSoftPkg()->getName() << "' with component id: '" << deployment->getIdentifier() << " assigned to device: '" << deployment->getAssignedDevice()->identifier; break; @@ -2443,7 +2443,7 @@ void createHelper::initializeComponents(const DeploymentList& deployments) for (unsigned int rc_idx = 0; rc_idx < deployments.size (); rc_idx++) { ossie::ComponentDeployment* deployment = deployments[rc_idx]; - const ossie::SoftPkg* softpkg = deployment->getSPD(); + const ossie::SoftPkg* softpkg = deployment->getSoftPkg(); const ossie::ComponentInfo* component = deployment->getComponent(); // If the component is non-SCA compliant then we don't expect anything beyond this @@ -2615,7 +2615,7 @@ void createHelper::configureComponents(const DeploymentList& deployments) for (DeploymentList::iterator depl = configure_list.begin(); depl != configure_list.end(); ++depl) { ossie::ComponentDeployment* deployment = *depl; - const ossie::SoftPkg* softpkg = deployment->getSPD(); + const ossie::SoftPkg* softpkg = deployment->getSoftPkg(); const ossie::ComponentInfo* component = deployment->getComponent(); // Assuming 1 instantiation for each componentplacement diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index d78c9561d..7e7033d47 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -81,7 +81,7 @@ CF::Device_ptr UsesDeviceAssignment::getAssignedDevice() const return CF::Device::_duplicate(assignedDevice); } -SoftpkgDeployment::SoftpkgDeployment(SoftpkgInfo* softpkg, const ImplementationInfo* implementation) : +SoftpkgDeployment::SoftpkgDeployment(const SoftPkg* softpkg, const ImplementationInfo* implementation) : softpkg(softpkg), implementation(implementation) { @@ -92,16 +92,11 @@ SoftpkgDeployment::~SoftpkgDeployment() clearDependencies(); } -SoftpkgInfo* SoftpkgDeployment::getSoftpkg() +const SoftPkg* SoftpkgDeployment::getSoftPkg() const { return softpkg; } -const SoftPkg* SoftpkgDeployment::getSPD() const -{ - return &(softpkg->spd); -} - void SoftpkgDeployment::setImplementation(const ImplementationInfo* implementation) { this->implementation = implementation; @@ -192,7 +187,7 @@ std::string SoftpkgDeployment::getLocalFile() fs::path codeLocalFile = fs::path(implementation->getLocalFileName()); if (!codeLocalFile.has_root_directory()) { // Path is relative to SPD file location - fs::path base_dir = fs::path(softpkg->getSpdFileName()).parent_path(); + fs::path base_dir = fs::path(softpkg->getSPDFile()).parent_path(); codeLocalFile = base_dir / codeLocalFile; } codeLocalFile = codeLocalFile.normalize(); @@ -206,7 +201,7 @@ std::string SoftpkgDeployment::getLocalFile() ComponentDeployment::ComponentDeployment(ComponentInfo* component, const ComponentInstantiation* instantiation, const std::string& identifier) : - SoftpkgDeployment(component), + SoftpkgDeployment(&(component->spd)), component(component), instantiation(instantiation), identifier(identifier), @@ -246,7 +241,7 @@ std::string ComponentDeployment::getEntryPoint() fs::path entryPointPath = fs::path(entryPoint); if (!entryPointPath.has_root_directory()) { // Path is relative to SPD file location - fs::path base_dir = fs::path(softpkg->getSpdFileName()).parent_path(); + fs::path base_dir = fs::path(softpkg->getSPDFile()).parent_path(); entryPointPath = base_dir / entryPointPath; } entryPoint = entryPointPath.normalize().string(); diff --git a/redhawk/src/control/sdr/dommgr/Deployment.h b/redhawk/src/control/sdr/dommgr/Deployment.h index 9dc3497e4..2c9b7ac6c 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.h +++ b/redhawk/src/control/sdr/dommgr/Deployment.h @@ -71,12 +71,10 @@ namespace ossie { public: typedef std::vector DeploymentList; - SoftpkgDeployment(SoftpkgInfo* softpkg, const ImplementationInfo* implementation=0); + SoftpkgDeployment(const SoftPkg* softpkg, const ImplementationInfo* implementation=0); ~SoftpkgDeployment(); - SoftpkgInfo* getSoftpkg(); - - const SoftPkg* getSPD() const; + const SoftPkg* getSoftPkg() const; void setImplementation(const ImplementationInfo* implementation); const ImplementationInfo* getImplementation() const; @@ -93,7 +91,7 @@ namespace ossie { void load(Application_impl* application, CF::FileSystem_ptr fileSystem, CF::LoadableDevice_ptr device, const std::string& componentId); - SoftpkgInfo* softpkg; + const SoftPkg* softpkg; const ImplementationInfo* implementation; DeploymentList dependencies; }; From 7394c4c90a939bbd532ffdd2070b4c3676176166 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 24 May 2016 13:20:55 -0400 Subject: [PATCH 0271/1644] Move flag for tracking whether a given instantiation is the assembly controller to ComponentInstantiation --- .../control/include/ossie/componentProfile.h | 11 ++++++-- .../src/control/parser/SoftwareAssembly.cpp | 1 + .../src/control/parser/componentProfile.cpp | 9 ++++++ .../sdr/dommgr/ApplicationFactory_impl.cpp | 28 ++++++++----------- .../control/sdr/dommgr/applicationSupport.cpp | 8 +----- .../control/sdr/dommgr/applicationSupport.h | 2 -- 6 files changed, 31 insertions(+), 28 deletions(-) diff --git a/redhawk/src/control/include/ossie/componentProfile.h b/redhawk/src/control/include/ossie/componentProfile.h index c69a7b1d4..5030c9a3f 100644 --- a/redhawk/src/control/include/ossie/componentProfile.h +++ b/redhawk/src/control/include/ossie/componentProfile.h @@ -183,8 +183,8 @@ namespace ossie { */ class ComponentInstantiation { public: - typedef std::pair LoggingConfig; - typedef ossie::ComponentPropertyList AffinityProperties; + typedef std::pair LoggingConfig; + typedef ossie::ComponentPropertyList AffinityProperties; std::string instantiationId; std::string namingservicename; @@ -193,6 +193,7 @@ namespace ossie { ossie::optional_value startOrder; AffinityProperties affinityProperties; LoggingConfig loggingConfig; + public: ComponentInstantiation(); @@ -215,6 +216,12 @@ namespace ossie { bool isNamingService() const; const std::string& getFindByNamingServiceName() const; + + bool isAssemblyController() const; + void setIsAssemblyController(bool state); + + private: + bool _isAssemblyController; }; /* diff --git a/redhawk/src/control/parser/SoftwareAssembly.cpp b/redhawk/src/control/parser/SoftwareAssembly.cpp index 9e6e4bc92..7782bf0ec 100644 --- a/redhawk/src/control/parser/SoftwareAssembly.cpp +++ b/redhawk/src/control/parser/SoftwareAssembly.cpp @@ -69,6 +69,7 @@ void SoftwareAssembly::validateComponentPlacements(std::vectorassemblycontroller.empty() && _sad->assemblycontroller == instance.instantiationId) { + instance.setIsAssemblyController(true); _assemblyController = &instance; } } diff --git a/redhawk/src/control/parser/componentProfile.cpp b/redhawk/src/control/parser/componentProfile.cpp index 8cb54528f..885e53ef7 100644 --- a/redhawk/src/control/parser/componentProfile.cpp +++ b/redhawk/src/control/parser/componentProfile.cpp @@ -166,6 +166,15 @@ const ComponentInstantiation::LoggingConfig &ComponentInstantiation::getLoggingC return loggingConfig; } +bool ComponentInstantiation::isAssemblyController() const +{ + return _isAssemblyController; +} + +void ComponentInstantiation::setIsAssemblyController(bool state) +{ + _isAssemblyController = state; +} // // ComponentPlacement diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 40c2fb6e7..8927249f3 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -1436,8 +1436,7 @@ void createHelper::allocateComponent(ossie::ComponentDeployment* deployment, ossie::corba::extend(configureProperties, deployment->getConstructProperties()); // Find the devices that allocate the SPD's minimum required usesdevices properties - ossie::ComponentInfo* component = deployment->getComponent(); - const std::vector& usesDevVec = component->getUsesDevices(); + const std::vector& usesDevVec = deployment->getSoftPkg()->getUsesDevices(); ossie::UsesDeviceDeployment assignedDevices; if (!allocateUsesDevices(usesDevVec, configureProperties, assignedDevices, this->_allocations)) { // There were unsatisfied usesdevices for the component @@ -1460,6 +1459,7 @@ void createHelper::allocateComponent(ossie::ComponentDeployment* deployment, } // now attempt to find an implementation that can have it's allocation requirements met + ossie::ComponentInfo* component = deployment->getComponent(); const ossie::ImplementationInfo::List& implementations = component->getImplementations(); for (size_t implCount = 0; implCount < implementations.size(); implCount++) { ossie::ImplementationInfo* impl = implementations[implCount]; @@ -1928,9 +1928,6 @@ void createHelper::getRequiredComponents(CF::FileSystem_ptr fileSys, const std::vector& placements = collocations[index].getComponents(); for (unsigned int i = 0; i < placements.size(); i++) { ossie::ComponentInfo* component = buildComponentInfo(fileSys, sadParser, placements[i]); - if (component->getInstantiationIdentifier() == assemblyControllerRefId) { - component->setIsAssemblyController(true); - } plan->addComponent(component); } } @@ -1941,9 +1938,6 @@ void createHelper::getRequiredComponents(CF::FileSystem_ptr fileSys, ossie::PlacementPlan* plan = new ossie::PlacementPlan(); appDeployment.addPlacement(plan); ossie::ComponentInfo* component = buildComponentInfo(fileSys, sadParser, componentsFromSAD[i]); - if (component->getInstantiationIdentifier() == assemblyControllerRefId) { - component->setIsAssemblyController(true); - } plan->addComponent(component); } @@ -2590,21 +2584,22 @@ void createHelper::configureComponents(const DeploymentList& deployments) DeploymentList configure_list; ossie::ComponentDeployment* ac_deployment = 0; for (DeploymentList::const_iterator depl = deployments.begin(); depl != deployments.end(); ++depl) { - const ossie::ComponentInfo* component = (*depl)->getComponent(); - if (!component->isScaCompliant()) { + ossie::ComponentDeployment* deployment = (*depl); + const ossie::ComponentInfo* component = deployment->getComponent(); + if (!deployment->getSoftPkg()->isScaCompliant()) { // If the component is non-SCA compliant then we don't expect anything beyond this LOG_TRACE(ApplicationFactory_impl, "Skipping configure of non SCA-compliant component " - << (*depl)->getIdentifier()); + << deployment->getIdentifier()); } else if (!component->isResource()) { LOG_TRACE(ApplicationFactory_impl, "Skipping configure of non-resource component " - << (*depl)->getIdentifier()); + << deployment->getIdentifier()); } else { // The component is configurable; if it's the assembly controller, // save it for the end - if (component->isAssemblyController()) { - ac_deployment = *depl; + if (deployment->getInstantiation()->isAssemblyController()) { + ac_deployment = deployment; } else { - configure_list.push_back(*depl); + configure_list.push_back(deployment); } } } @@ -2745,9 +2740,8 @@ std::vector createHelper::getStartOrder(const DeploymentList& StartOrderMap start_map; for (size_t index = 0; index < deployments.size(); ++index) { ossie::ComponentDeployment* deployment = deployments[index]; - ossie::ComponentInfo* component = deployment->getComponent(); const ossie::ComponentInstantiation* instantiation = deployment->getInstantiation(); - if (!component->isAssemblyController() && instantiation->hasStartOrder()) { + if (!instantiation->isAssemblyController() && instantiation->hasStartOrder()) { // Only track start order if it was provided, and the component is // not the assembly controller start_map.insert(std::make_pair(instantiation->getStartOrder(), deployment)); diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp index c22a0b65a..2ebe38a84 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp @@ -446,7 +446,6 @@ ComponentInfo* ComponentInfo::buildComponentInfoFromSPDFile(CF::FileSystem_ptr f ComponentInfo::ComponentInfo(const std::string& spdFileName, const ComponentInstantiation* instantiation) : SoftpkgInfo(spdFileName), - _isAssemblyController(false), instantiation(instantiation) { // load common affinity property definitions @@ -476,11 +475,6 @@ void ComponentInfo::setUsageName(const char* _usageName) } } -void ComponentInfo::setIsAssemblyController(bool _isAssemblyController) -{ - this->_isAssemblyController = _isAssemblyController; -} - void ComponentInfo::setAffinity( const AffinityProperties &affinity_props ) { @@ -589,7 +583,7 @@ bool ComponentInfo::isConfigurable() const bool ComponentInfo::isAssemblyController() const { - return _isAssemblyController; + return instantiation->isAssemblyController(); } bool ComponentInfo::isScaCompliant() const diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.h b/redhawk/src/control/sdr/dommgr/applicationSupport.h index 4dab821e4..4e434132f 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.h +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.h @@ -156,7 +156,6 @@ namespace ossie const ComponentInstantiation* getInstantiation() const; void setUsageName(const char* usageName); - void setIsAssemblyController(bool isAssemblyController); void setAffinity( const AffinityProperties &affinity ); void addFactoryParameter(CF::DataType dt); @@ -199,7 +198,6 @@ namespace ossie ComponentInfo (const ComponentInfo&); void process_overrides(CF::Properties* props, const char* id, CORBA::Any value); - bool _isAssemblyController; bool _isConfigurable; std::string usageName; From 0f13e7d3d791ef02386ed87ec1d368f9a9747292 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 24 May 2016 13:52:27 -0400 Subject: [PATCH 0272/1644] Fix problem with object lifetime in DeviceManager's ResourceInfo class that led to crashes --- .../control/sdr/devmgr/DeviceManager_impl.cpp | 4 +- redhawk/src/control/sdr/devmgr/spdSupport.cpp | 83 +++++-------------- redhawk/src/control/sdr/devmgr/spdSupport.h | 8 +- 3 files changed, 25 insertions(+), 70 deletions(-) diff --git a/redhawk/src/control/sdr/devmgr/DeviceManager_impl.cpp b/redhawk/src/control/sdr/devmgr/DeviceManager_impl.cpp index 1fdad7be4..d34304449 100644 --- a/redhawk/src/control/sdr/devmgr/DeviceManager_impl.cpp +++ b/redhawk/src/control/sdr/devmgr/DeviceManager_impl.cpp @@ -1900,9 +1900,9 @@ throw (CORBA::SystemException, CF::InvalidObjectReference) // Open the SPD file using the SCA FileSystem LOG_TRACE(DeviceManager_impl, "Building Device Info From SPD File"); - ossie::SpdSupport::ResourceInfo spdinfo; + ossie::SpdSupport::ResourceInfo spdinfo(spdFile); try { - ossie::SpdSupport::ResourceInfo::LoadResource(_fileSys, spdFile.c_str(), spdinfo); + spdinfo.load(_fileSys); } catch(...) { std::ostringstream eout; diff --git a/redhawk/src/control/sdr/devmgr/spdSupport.cpp b/redhawk/src/control/sdr/devmgr/spdSupport.cpp index da6228384..cb998a92f 100644 --- a/redhawk/src/control/sdr/devmgr/spdSupport.cpp +++ b/redhawk/src/control/sdr/devmgr/spdSupport.cpp @@ -417,22 +417,18 @@ const ImplementationInfo &SoftpkgInfo::getSelectedImplementation() const */ PREPARE_CF_LOGGING(ResourceInfo); -void ResourceInfo::LoadResource(CF::FileSystem_ptr fileSys, - const char* spdFileName, - ResourceInfo &rsc) +void ResourceInfo::load(CF::FileSystem_ptr fileSys) { - LOG_TRACE(ResourceInfo, "Building component info from file " << spdFileName); + LOG_TRACE(ResourceInfo, "Building component info from file " << _spdFileName); - ResourceInfo newComponent(spdFileName); - - if (!newComponent.parseProfile(fileSys)) { + if (!parseProfile(fileSys)) { throw 0; } - if (newComponent.spd.getSCDFile() != 0) { + if (spd.getSCDFile() != 0) { try { - File_stream _scd(fileSys, newComponent.spd.getSCDFile()); - newComponent.scd.load(_scd); + File_stream _scd(fileSys, spd.getSCDFile()); + scd.load(_scd); _scd.close(); } catch (ossie::parser_error& e) { std::string parser_error_line = ossie::retrieveParserErrorLineNumber(e.what()); @@ -444,12 +440,12 @@ void ResourceInfo::LoadResource(CF::FileSystem_ptr fileSys, } } - if (newComponent.spd.getPRFFile() != 0) { - LOG_DEBUG(ResourceInfo, "Loading component properties from " << newComponent.spd.getPRFFile()); + if (spd.getPRFFile() != 0) { + LOG_DEBUG(ResourceInfo, "Loading component properties from " << spd.getPRFFile()); try { - File_stream _prf(fileSys, newComponent.spd.getPRFFile()); + File_stream _prf(fileSys, spd.getPRFFile()); LOG_DEBUG(ResourceInfo, "Parsing component properties"); - newComponent.prf.load(_prf); + prf.load(_prf); LOG_TRACE(ResourceInfo, "Closing PRF file") _prf.close(); } catch (ossie::parser_error& e) { @@ -465,20 +461,20 @@ void ResourceInfo::LoadResource(CF::FileSystem_ptr fileSys, // Extract Properties from the implementation-agnostic PRF file // once we match the component to a device we can grab the implementation // specific PRF file - if (newComponent.spd.getPRFFile() != 0) { + if (spd.getPRFFile() != 0) { // Handle component properties LOG_TRACE(ResourceInfo, "Adding factory params") - const std::vector& fprop = newComponent.prf.getFactoryParamProperties(); + const std::vector& fprop = prf.getFactoryParamProperties(); for (unsigned int i = 0; i < fprop.size(); i++) { - newComponent.addFactoryParameter(convertPropertyToDataType(fprop[i])); + addFactoryParameter(convertPropertyToDataType(fprop[i])); } LOG_TRACE(ResourceInfo, "Adding exec params") - const std::vector& eprop = newComponent.prf.getExecParamProperties(); + const std::vector& eprop = prf.getExecParamProperties(); for (unsigned int i = 0; i < eprop.size(); i++) { if (std::string(eprop[i]->getMode()) != "readonly") { LOG_TRACE(ResourceInfo, "Adding exec param " << eprop[i]->getID() << " " << eprop[i]->getName()); - newComponent.addExecParameter(convertPropertyToDataType(eprop[i])); + addExecParameter(convertPropertyToDataType(eprop[i])); } else { LOG_TRACE(ResourceInfo, "Ignoring readonly exec param " << eprop[i]->getID() << " " << eprop[i]->getName()); } @@ -494,29 +490,27 @@ void ResourceInfo::LoadResource(CF::FileSystem_ptr fileSys, // newComponent.addAllocationCapacity((*prop)[i]->getDataType()); //} - const std::vector& prop = newComponent.prf.getConfigureProperties(); + const std::vector& prop = prf.getConfigureProperties(); for (unsigned int i = 0; i < prop.size(); i++) { if (!prop[i]->isReadOnly()) { LOG_TRACE(ResourceInfo, "Adding configure prop " << prop[i]->getID() << " " << prop[i]->getName() << " " << prop[i]->isReadOnly()) - newComponent.addConfigureProperty(convertPropertyToDataType(prop[i])); + addConfigureProperty(convertPropertyToDataType(prop[i])); } } - const std::vector& cprop = newComponent.prf.getConstructProperties(); + const std::vector& cprop = prf.getConstructProperties(); for (unsigned int i = 0; i < cprop.size(); i++) { LOG_TRACE(ResourceInfo, "Adding construct prop " << cprop[i]->getID() << " " << cprop[i]->getName() << " " << cprop[i]->isReadOnly()); if (cprop[i]->isCommandLine()) { - newComponent.addExecParameter(convertPropertyToDataType(cprop[i])); + addExecParameter(convertPropertyToDataType(cprop[i])); } else { - newComponent.addConstructProperty(convertPropertyToDataType(cprop[i])); + addConstructProperty(convertPropertyToDataType(cprop[i])); } } } - LOG_TRACE(ResourceInfo, "Done building component info from file " << spdFileName); - rsc = newComponent; - return; + LOG_TRACE(ResourceInfo, "Done building component info from file " << _spdFileName); } ResourceInfo::ResourceInfo(const std::string& spdFileName) : @@ -535,41 +529,6 @@ ResourceInfo::ResourceInfo(const std::string& spdFileName) : } - -ResourceInfo & ResourceInfo::operator=( const ResourceInfo& src) { - SoftpkgInfo::operator=(src); - _copy(src); - return *this; -} - -ResourceInfo::ResourceInfo( const ResourceInfo& src) : SoftpkgInfo(src) -{ - _copy(src); -} - -void ResourceInfo::_copy( const ResourceInfo& src) -{ - prf = src.prf; - scd = src.scd; - _isAssemblyController = src._isAssemblyController; - _isConfigurable = src._isConfigurable; - isNamingService = src.isNamingService; - usageName = src.usageName; - identifier = src.identifier; - instantiationId = src.instantiationId; - namingServiceName = src.namingServiceName; - loggingConfig = src.loggingConfig; - configureProperties = src.configureProperties; - ctorProperties = src.ctorProperties; - options = src.options; - factoryParameters = src.factoryParameters; - execParameters = src.execParameters; - affinityOptions = src.affinityOptions; - resolved_softpkg_dependencies.resize(src.resolved_softpkg_dependencies.size()); - std::copy( src.resolved_softpkg_dependencies.begin(), - src.resolved_softpkg_dependencies.end(), resolved_softpkg_dependencies.begin() ); -} - ResourceInfo::~ResourceInfo () { } diff --git a/redhawk/src/control/sdr/devmgr/spdSupport.h b/redhawk/src/control/sdr/devmgr/spdSupport.h index 4bdf2dfc7..4bd751c1b 100644 --- a/redhawk/src/control/sdr/devmgr/spdSupport.h +++ b/redhawk/src/control/sdr/devmgr/spdSupport.h @@ -177,8 +177,6 @@ namespace ossie typedef ossie::ComponentInstantiation::LoggingConfig LoggingConfig; ResourceInfo (const std::string& spdFileName); - ResourceInfo ( const ResourceInfo&); - ResourceInfo (){}; ~ResourceInfo (); ResourceInfo &operator=( const ResourceInfo&); @@ -224,16 +222,14 @@ namespace ossie CF::Properties getAffinityOptions(); CF::Properties getExecParameters(); - static void LoadResource(CF::FileSystem_ptr fileSystem, - const char* _SPDFile, - ResourceInfo &rsc); + void load(CF::FileSystem_ptr fileSystem); + ComponentDescriptor scd; ossie::Properties prf; protected: void process_overrides(CF::Properties* props, const char* id, CORBA::Any value); - void _copy( const ResourceInfo &src ); bool _isAssemblyController; bool _isConfigurable; bool isNamingService; From bec9b7d12bb97e4d67eb704ab41b0f9836f1c6b3 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 24 May 2016 14:05:25 -0400 Subject: [PATCH 0273/1644] Default assembly controller state is false --- redhawk/src/control/parser/componentProfile.cpp | 3 ++- .../src/control/sdr/dommgr/ApplicationFactory_impl.cpp | 8 ++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/redhawk/src/control/parser/componentProfile.cpp b/redhawk/src/control/parser/componentProfile.cpp index 885e53ef7..211b6a507 100644 --- a/redhawk/src/control/parser/componentProfile.cpp +++ b/redhawk/src/control/parser/componentProfile.cpp @@ -122,7 +122,8 @@ const std::string StructSequencePropertyRef::_asString() const { // // ComponentInstantiation // -ComponentInstantiation::ComponentInstantiation() +ComponentInstantiation::ComponentInstantiation() : + _isAssemblyController(false) { } diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 8927249f3..5bcddfb7b 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -2732,6 +2732,8 @@ void createHelper::connectComponents(ossie::ApplicationDeployment& appDeployment std::vector createHelper::getStartOrder(const DeploymentList& deployments) { + LOG_TRACE(ApplicationFactory_impl, "Assigning start order"); + // Now that all of the components are known, bin the start orders based on // the values in the SAD. Using a multimap, keyed on the start order value, // accounts for duplicate keys and allows assigning the effective order @@ -2741,7 +2743,10 @@ std::vector createHelper::getStartOrder(const DeploymentList& for (size_t index = 0; index < deployments.size(); ++index) { ossie::ComponentDeployment* deployment = deployments[index]; const ossie::ComponentInstantiation* instantiation = deployment->getInstantiation(); - if (!instantiation->isAssemblyController() && instantiation->hasStartOrder()) { + if (instantiation->isAssemblyController()) { + LOG_TRACE(ApplicationFactory_impl, "Component " << instantiation->getID() + << " is the assembly controller"); + } else if (instantiation->hasStartOrder()) { // Only track start order if it was provided, and the component is // not the assembly controller start_map.insert(std::make_pair(instantiation->getStartOrder(), deployment)); @@ -2751,7 +2756,6 @@ std::vector createHelper::getStartOrder(const DeploymentList& // Build the start order vector in the right order std::vector start_order; int index = 1; - LOG_TRACE(ApplicationFactory_impl, "Assigning start order"); for (StartOrderMap::iterator ii = start_map.begin(); ii != start_map.end(); ++ii, ++index) { LOG_TRACE(ApplicationFactory_impl, index << ": " << ii->second->getInstantiation()->getID()); From 2683dd207cf4f4bcfbea86ac65023ca3e3548a97 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 24 May 2016 14:34:52 -0400 Subject: [PATCH 0274/1644] Add component instantation search methods to application profile objects --- .../control/include/ossie/SoftwareAssembly.h | 4 +++ .../control/include/ossie/componentProfile.h | 2 ++ .../src/control/parser/SoftwareAssembly.cpp | 28 +++++++++++++++++++ .../src/control/parser/componentProfile.cpp | 12 ++++++++ .../sdr/dommgr/ApplicationFactory_impl.cpp | 3 +- 5 files changed, 47 insertions(+), 2 deletions(-) diff --git a/redhawk/src/control/include/ossie/SoftwareAssembly.h b/redhawk/src/control/include/ossie/SoftwareAssembly.h index 51e0d21d4..c7330c8ee 100644 --- a/redhawk/src/control/include/ossie/SoftwareAssembly.h +++ b/redhawk/src/control/include/ossie/SoftwareAssembly.h @@ -50,6 +50,8 @@ namespace ossie { const std::vector& getComponents() const { return placements; } + + const ComponentInstantiation* getInstantiation(const std::string& refid) const; }; class Partitioning { @@ -123,6 +125,8 @@ namespace ossie { const std::vector& getUsesDevices() const; + const ComponentInstantiation* getComponentInstantiation(const std::string& refid) const; + protected: void validateComponentPlacements(std::vector& placements); diff --git a/redhawk/src/control/include/ossie/componentProfile.h b/redhawk/src/control/include/ossie/componentProfile.h index 5030c9a3f..37b425c06 100644 --- a/redhawk/src/control/include/ossie/componentProfile.h +++ b/redhawk/src/control/include/ossie/componentProfile.h @@ -238,6 +238,8 @@ namespace ossie { const std::vector& getInstantiations() const; const std::string& getFileRefId() const; + + const ComponentInstantiation* getInstantiation(const std::string& refid) const; }; /* diff --git a/redhawk/src/control/parser/SoftwareAssembly.cpp b/redhawk/src/control/parser/SoftwareAssembly.cpp index 7782bf0ec..3b854f399 100644 --- a/redhawk/src/control/parser/SoftwareAssembly.cpp +++ b/redhawk/src/control/parser/SoftwareAssembly.cpp @@ -25,6 +25,17 @@ using namespace ossie; +const ComponentInstantiation* SoftwareAssembly::HostCollocation::getInstantiation(const std::string& refid) const +{ + BOOST_FOREACH(const ComponentPlacement& placement, placements) { + const ComponentInstantiation* instantiation = placement.getInstantiation(refid); + if (instantiation) { + return instantiation; + } + } + return 0; +} + SoftwareAssembly::SoftwareAssembly() : _sad(0), _assemblyController(0) @@ -158,3 +169,20 @@ const std::vector& SoftwareAssembly::getUsesDevices() const { assert(_sad.get() != 0); return _sad->usesdevice; } + +const ComponentInstantiation* SoftwareAssembly::getComponentInstantiation(const std::string& refid) const +{ + BOOST_FOREACH(HostCollocation& collocation, _sad->partitioning.collocations) { + const ComponentInstantiation* instantiation = collocation.getInstantiation(refid); + if (instantiation) { + return instantiation; + } + } + BOOST_FOREACH(const ComponentPlacement& placement, _sad->partitioning.placements) { + const ComponentInstantiation* instantiation = placement.getInstantiation(refid); + if (instantiation) { + return instantiation; + } + } + return 0; +} diff --git a/redhawk/src/control/parser/componentProfile.cpp b/redhawk/src/control/parser/componentProfile.cpp index 211b6a507..8c7b74563 100644 --- a/redhawk/src/control/parser/componentProfile.cpp +++ b/redhawk/src/control/parser/componentProfile.cpp @@ -18,6 +18,8 @@ * along with this program. If not, see http://www.gnu.org/licenses/. */ +#include + #include "ossie/componentProfile.h" using namespace ossie; @@ -187,3 +189,13 @@ const std::vector& ComponentPlacement::getInstantiations const std::string& ComponentPlacement::getFileRefId() const { return _componentFileRef; } + +const ComponentInstantiation* ComponentPlacement::getInstantiation(const std::string& refid) const +{ + BOOST_FOREACH(const ComponentInstantiation& instantiation, instantiations) { + if (instantiation.getID() == refid) { + return &instantiation; + } + } + return 0; +} diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 5bcddfb7b..d37bc5eec 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -679,9 +679,8 @@ void createHelper::_validateDAS(ossie::ApplicationDeployment& appDeployment, for (DeviceAssignmentMap::const_iterator ii = deviceAssignments.begin(); ii != deviceAssignments.end(); ++ii) { const std::string& componentId = ii->first; const std::string& assignedDeviceId = ii->second; - ossie::ComponentInfo* component = appDeployment.getComponent(componentId); - if (!component) { + if (!_appFact._sadParser.getComponentInstantiation(componentId)) { LOG_ERROR(ApplicationFactory_impl, "Failed to create application; " << "unknown component " << componentId << " in user assignment (DAS)"); From 01699e561a30e2d2f7ee7be408a6bd3c7442be7b Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 24 May 2016 15:05:59 -0400 Subject: [PATCH 0275/1644] Use SPD::Implementation in more places instead of ImplementationInfo --- redhawk/src/control/include/ossie/SoftPkg.h | 18 ------ .../sdr/dommgr/ApplicationFactory_impl.cpp | 61 ++++++++++--------- redhawk/src/control/sdr/dommgr/Deployment.cpp | 23 ++++++- redhawk/src/control/sdr/dommgr/Deployment.h | 2 + .../control/sdr/dommgr/applicationSupport.cpp | 50 ++------------- .../control/sdr/dommgr/applicationSupport.h | 8 +-- 6 files changed, 64 insertions(+), 98 deletions(-) diff --git a/redhawk/src/control/include/ossie/SoftPkg.h b/redhawk/src/control/include/ossie/SoftPkg.h index f32ed4057..930084bb5 100644 --- a/redhawk/src/control/include/ossie/SoftPkg.h +++ b/redhawk/src/control/include/ossie/SoftPkg.h @@ -95,24 +95,6 @@ namespace ossie { stacksize((unsigned long long)0), priority((unsigned long long)0) {} - - Code(const Code& other) : - localfile(other.localfile), - type(other.type), - entrypoint(other.entrypoint), - stacksize(other.stacksize), - priority(other.priority) - {} - - Code& operator=(const Code& other) - { - localfile = other.localfile; - type = other.type; - entrypoint = other.entrypoint; - stacksize = other.stacksize; - priority = other.priority; - return *this; - } }; class Implementation { diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index d37bc5eec..8afdc2e5c 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -714,13 +714,14 @@ bool createHelper::placeHostCollocation(ossie::ApplicationDeployment& appDeploym << deployment->getInstantiation()->getID()); ++current; for (ImplementationList::const_iterator impl = comp_impls.begin(); impl != comp_impls.end(); ++impl) { - LOG_TRACE(ApplicationFactory_impl, "Checking implementation " << (*impl)->getId()); + const ossie::SPD::Implementation* implementation = (*impl)->getImplementation(); + LOG_TRACE(ApplicationFactory_impl, "Checking implementation " << implementation->getID()); // Check that the processor dependencies are compatible, filtering out // anything not compatible with the current component std::vector proc_list = processorDeps;; - if (!mergeDependencies(proc_list, (*impl)->getProcessorDeps())) { - LOG_TRACE(ApplicationFactory_impl, "Skipping implementation " << (*impl)->getId() + if (!mergeDependencies(proc_list, implementation->getProcessors())) { + LOG_TRACE(ApplicationFactory_impl, "Skipping implementation " << implementation->getID() << ": no processor match"); continue; } @@ -728,8 +729,9 @@ bool createHelper::placeHostCollocation(ossie::ApplicationDeployment& appDeploym // Check that the OS dependencies are compatible, again filtering out // anything not compatible with the current component std::vector os_list = osDeps; - if (!mergeDependencies(os_list, (*impl)->getOsDeps())) { - LOG_TRACE(ApplicationFactory_impl, "Skipping implementation " << (*impl)->getId() << ": no OS match"); + if (!mergeDependencies(os_list, implementation->getOsDeps())) { + LOG_TRACE(ApplicationFactory_impl, "Skipping implementation " << implementation->getID() + << ": no OS match"); continue; } @@ -802,7 +804,7 @@ CF::Properties createHelper::_consolidateAllocations(const DeploymentList& deplo { CF::Properties allocs; for (DeploymentList::const_iterator depl = deployments.begin(); depl != deployments.end(); ++depl) { - const std::vector& deps = (*depl)->getImplementation()->getDependencyProperties(); + const std::vector& deps = (*depl)->getSPDImplementation()->getDependencies(); for (std::vector::const_iterator dep = deps.begin(); dep != deps.end(); ++dep) { ossie::ComponentProperty *prop = dep->property.get(); ossie::corba::push_back(allocs, ossie::convertPropertyRefToDataType(prop)); @@ -1462,15 +1464,16 @@ void createHelper::allocateComponent(ossie::ComponentDeployment* deployment, const ossie::ImplementationInfo::List& implementations = component->getImplementations(); for (size_t implCount = 0; implCount < implementations.size(); implCount++) { ossie::ImplementationInfo* impl = implementations[implCount]; + const ossie::SPD::Implementation* implementation = impl->getImplementation(); // Handle 'usesdevice' dependencies for the particular implementation UsesDeviceDeployment implAssignedDevices; ScopedAllocations implAllocations(*this->_allocationMgr); - const std::vector& implUsesDevVec = impl->getUsesDevices(); + const std::vector& implUsesDevVec = implementation->getUsesDevices(); if (!allocateUsesDevices(implUsesDevVec, configureProperties, implAssignedDevices, implAllocations)) { LOG_DEBUG(ApplicationFactory_impl, "Unable to satisfy 'usesdevice' dependencies for component " - << deployment->getIdentifier() << " implementation " << impl->getId()); + << deployment->getIdentifier() << " implementation " << implementation->getID()); continue; } @@ -1486,7 +1489,7 @@ void createHelper::allocateComponent(ossie::ComponentDeployment* deployment, if (response.first.empty()) { LOG_DEBUG(ApplicationFactory_impl, "Unable to allocate device for component " - << deployment->getIdentifier() << " implementation " << impl->getId()); + << deployment->getIdentifier() << " implementation " << implementation->getID()); continue; } @@ -1500,13 +1503,13 @@ void createHelper::allocateComponent(ossie::ComponentDeployment* deployment, if (!resolveSoftpkgDependencies(deployment, node)) { LOG_DEBUG(ApplicationFactory_impl, "Unable to resolve softpackage dependencies for component " - << deployment->getIdentifier() << " implementation " << impl->getId()); + << deployment->getIdentifier() << " implementation " << implementation->getID()); continue; } // Allocation to a device succeeded LOG_DEBUG(ApplicationFactory_impl, "Assigned component " << deployment->getInstantiation()->getID() - << " implementation " << impl->getId() << " to device " << deviceId); + << " implementation " << implementation->getID() << " to device " << deviceId); // Move the device to the front of the list rotateDeviceList(_executableDevices, deviceId); @@ -1713,7 +1716,7 @@ ossie::AllocationResult createHelper::allocateComponentToDevice(ossie::Component const std::string& appIdentifier) { const ossie::ComponentInfo* component = deployment->getComponent(); - const ossie::ImplementationInfo* implementation = deployment->getImplementation(); + const ossie::SPD::Implementation* implementation = deployment->getSPDImplementation(); ossie::DeviceList devices = _registeredDevices; // First check to see if the component was assigned in the user provided DAS @@ -1744,7 +1747,7 @@ ossie::AllocationResult createHelper::allocateComponentToDevice(ossie::Component } const std::string requestid = ossie::generateUUID(); - const std::vector& prop_refs = implementation->getDependencyProperties(); + const std::vector& prop_refs = implementation->getDependencies(); redhawk::PropertyMap allocationProperties; this->_castRequestProperties(allocationProperties, prop_refs); @@ -1770,7 +1773,7 @@ ossie::AllocationResult createHelper::allocateComponentToDevice(ossie::Component } } - ossie::AllocationResult response = this->_allocationMgr->allocateDeployment(requestid, allocationProperties, devices, appIdentifier, implementation->getProcessorDeps(), implementation->getOsDeps()); + ossie::AllocationResult response = this->_allocationMgr->allocateDeployment(requestid, allocationProperties, devices, appIdentifier, implementation->getProcessors(), implementation->getOsDeps()); if (allocationProperties.contains("nic_allocation")) { if (!response.first.empty()) { redhawk::PropertyMap query_props; @@ -2016,7 +2019,7 @@ void createHelper::loadAndExecuteComponents(const DeploymentList& deployments, ossie::ComponentDeployment* deployment = deployments[rc_idx]; ossie::ComponentInfo* component = deployment->getComponent(); const ossie::ComponentInstantiation* instantiation = deployment->getInstantiation(); - const ossie::ImplementationInfo* implementation = deployment->getImplementation(); + const ossie::SPD::Implementation* implementation = deployment->getSPDImplementation(); boost::shared_ptr device = deployment->getAssignedDevice(); if (!device) { @@ -2032,7 +2035,7 @@ void createHelper::loadAndExecuteComponents(const DeploymentList& deployments, // Let the application know to expect the given component _application->addComponent(deployment->getIdentifier(), component->getSpdFileName()); - _application->setComponentImplementation(deployment->getIdentifier(), implementation->getId()); + _application->setComponentImplementation(deployment->getIdentifier(), implementation->getID()); if (instantiation->isNamingService()) { std::string lookupName = _baseNamingContext + "/" + instantiation->getFindByNamingServiceName(); _application->setComponentNamingContext(deployment->getIdentifier(), lookupName); @@ -2041,7 +2044,7 @@ void createHelper::loadAndExecuteComponents(const DeploymentList& deployments, // get the code.localfile LOG_TRACE(ApplicationFactory_impl, "Host is " << device->label << " Local file name is " - << implementation->getLocalFileName()); + << deployment->getLocalFile()); // Get file name, load if it is not empty std::string codeLocalFile = deployment->getLocalFile(); @@ -2049,7 +2052,7 @@ void createHelper::loadAndExecuteComponents(const DeploymentList& deployments, ostringstream eout; eout << "code.localfile is empty for component: '"; eout << component->getName() << "' with component id: '" << deployment->getIdentifier() << "' "; - eout << " with implementation id: '" << implementation->getId() << "'"; + eout << " with implementation id: '" << implementation->getID() << "'"; eout << " on device id: '" << device->identifier << "'"; eout << " in waveform '" << _waveformContextName<<"'"; eout << " error occurred near line:" <<__LINE__ << " in file:" << __FILE__ << ";"; @@ -2074,7 +2077,7 @@ void createHelper::loadAndExecuteComponents(const DeploymentList& deployments, } catch (const std::exception& exc) { std::ostringstream message; message << "Unable to load component " << component->getName() - << " implementation " << implementation->getId() + << " implementation " << implementation->getID() << " on device " << device->identifier << ": " << exc.what(); LOG_ERROR(ApplicationFactory_impl, message.str()); @@ -2090,8 +2093,8 @@ void createHelper::loadAndExecuteComponents(const DeploymentList& deployments, // 3. SharedLibrary means dynamic linking. // 4. A (SharedLibrary) Without a code entrypoint element means load only. // 5. A (SharedLibrary) With a code entrypoint element means load and CF Device::execute. - if (((implementation->getCodeType() == CF::LoadableDevice::EXECUTABLE) || - (implementation->getCodeType() == CF::LoadableDevice::SHARED_LIBRARY)) && (implementation->getEntryPoint().size() != 0)) { + if (((deployment->getCodeType() == CF::LoadableDevice::EXECUTABLE) || + (deployment->getCodeType() == CF::LoadableDevice::SHARED_LIBRARY)) && (deployment->getEntryPoint().size() != 0)) { // See if the LOGGING_CONFIG_URI has already been set // via or initParams @@ -2184,7 +2187,7 @@ void createHelper::attemptComponentExecution (CF::ApplicationRegistrar_ptr regis ossie::ComponentDeployment* deployment) { const ossie::ComponentInfo* component = deployment->getComponent(); - const ossie::ImplementationInfo* implementation = deployment->getImplementation(); + const ossie::SPD::Implementation* implementation = deployment->getSPDImplementation(); const ossie::SoftPkg* softpkg = deployment->getSoftPkg(); // Get executable device reference @@ -2259,7 +2262,7 @@ void createHelper::attemptComponentExecution (CF::ApplicationRegistrar_ptr regis ostringstream eout; eout << "InvalidFileName when calling 'execute' on device with device id: '" << device->identifier << "' for component: '"; eout << softpkg->getName() << "' with component id: '" << deployment->getIdentifier() << "' "; - eout << " with implementation id: '" << implementation->getId() << "'"; + eout << " with implementation id: '" << implementation->getID() << "'"; eout << " in waveform '" << _waveformContextName<<"'"; eout << " with error: <" << _ex.msg << ">;"; eout << " error occurred near line:" <<__LINE__ << " in file:" << __FILE__ << ";"; @@ -2270,7 +2273,7 @@ void createHelper::attemptComponentExecution (CF::ApplicationRegistrar_ptr regis ostringstream eout; eout << "InvalidState when calling 'execute' on device with device id: '" << device->identifier << "' for component: '"; eout << softpkg->getName() << "' with component id: '" << deployment->getIdentifier() << "' "; - eout << " with implementation id: '" << implementation->getId() << "'"; + eout << " with implementation id: '" << implementation->getID() << "'"; eout << " in waveform '" << _waveformContextName<<"'"; eout << " with error: <" << _ex.msg << ">;"; eout << " error occurred near line:" <<__LINE__ << " in file:" << __FILE__ << ";"; @@ -2281,7 +2284,7 @@ void createHelper::attemptComponentExecution (CF::ApplicationRegistrar_ptr regis ostringstream eout; eout << "InvalidParameters when calling 'execute' on device with device id: '" << device->identifier << "' for component: '"; eout << softpkg->getName() << "' with component id: '" << deployment->getIdentifier() << "' "; - eout << " with implementation id: '" << implementation->getId() << "'"; + eout << " with implementation id: '" << implementation->getID() << "'"; eout << " in waveform '" << _waveformContextName<<"'"; eout << " with invalid params: <"; for (unsigned int propIdx = 0; propIdx < _ex.invalidParms.length(); propIdx++){ @@ -2296,7 +2299,7 @@ void createHelper::attemptComponentExecution (CF::ApplicationRegistrar_ptr regis ostringstream eout; eout << "InvalidOptions when calling 'execute' on device with device id: '" << device->identifier << "' for component: '"; eout << softpkg->getName() << "' with component id: '" << deployment->getIdentifier() << "' "; - eout << " with implementation id: '" << implementation->getId() << "'"; + eout << " with implementation id: '" << implementation->getID() << "'"; eout << " in waveform '" << _waveformContextName<<"'"; eout << " with invalid options: <"; for (unsigned int propIdx = 0; propIdx < _ex.invalidOpts.length(); propIdx++){ @@ -2310,7 +2313,7 @@ void createHelper::attemptComponentExecution (CF::ApplicationRegistrar_ptr regis ostringstream eout; eout << "ExecuteFail when calling 'execute' on device with device id: '" << device->identifier << "' for component: '"; eout << softpkg->getName() << "' with component id: '" << deployment->getIdentifier() << "' "; - eout << " with implementation id: '" << implementation->getId() << "'"; + eout << " with implementation id: '" << implementation->getID() << "'"; eout << " in waveform '" << _waveformContextName<<"'"; eout << " with message: '" << ex.msg << "'"; eout << " error occurred near line:" <<__LINE__ << " in file:" << __FILE__ << ";"; @@ -2320,7 +2323,7 @@ void createHelper::attemptComponentExecution (CF::ApplicationRegistrar_ptr regis ApplicationFactory_impl, "Caught an unexpected error when calling 'execute' on device with device id: '" << device->identifier << "' for component: '" << softpkg->getName() << "' with component id: '" << deployment->getIdentifier() << "' " - << " with implementation id: '" << implementation->getId() << "'" + << " with implementation id: '" << implementation->getID() << "'" << " in waveform '" << _waveformContextName<<"'" << " error occurred near line:" <<__LINE__ << " in file:" << __FILE__, CF::ApplicationFactory::CreateApplicationError(CF::CF_EINVAL, "Caught an unexpected error when calling 'execute' on device")); @@ -2332,7 +2335,7 @@ void createHelper::attemptComponentExecution (CF::ApplicationRegistrar_ptr regis eout << added_message; eout << "Failed to 'execute' component for component: '"; eout << softpkg->getName() << "' with component id: '" << deployment->getIdentifier() << "' "; - eout << " with implementation id: '" << implementation->getId() << "'"; + eout << " with implementation id: '" << implementation->getID() << "'"; eout << " in waveform '" << _waveformContextName<<"'"; eout << " error occurred near line:" <<__LINE__ << " in file:" << __FILE__ << ";"; LOG_TRACE(ApplicationFactory_impl, eout.str()) diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index 7e7033d47..a24486764 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -107,6 +107,11 @@ const ImplementationInfo* SoftpkgDeployment::getImplementation() const return implementation; } +const SPD::Implementation* SoftpkgDeployment::getSPDImplementation() const +{ + return implementation->getImplementation(); +} + void SoftpkgDeployment::addDependency(SoftpkgDeployment* dependency) { dependencies.push_back(dependency); @@ -153,7 +158,7 @@ void SoftpkgDeployment::load(Application_impl* application, CF::FileSystem_ptr f } // Determine absolute path of local file - CF::LoadableDevice::LoadType codeType = implementation->getCodeType(); + CF::LoadableDevice::LoadType codeType = getCodeType(); const std::string fileName = getLocalFile(); RH_NL_DEBUG("ApplicationFactory_impl", "Loading file " << fileName << " for soft package " << softpkg->getName()); @@ -198,6 +203,22 @@ std::string SoftpkgDeployment::getLocalFile() return codeLocalFile.string(); } +CF::LoadableDevice::LoadType SoftpkgDeployment::getCodeType() const +{ + const std::string type = implementation->getImplementation()->getCodeType(); + if (type == "KernelModule") { + return CF::LoadableDevice::KERNEL_MODULE; + } else if (type == "SharedLibrary") { + return CF::LoadableDevice::SHARED_LIBRARY; + } else if (type == "Executable") { + return CF::LoadableDevice::EXECUTABLE; + } else if (type == "Driver") { + return CF::LoadableDevice::DRIVER; + } else { + return CF::LoadableDevice::LoadType(); + } +} + ComponentDeployment::ComponentDeployment(ComponentInfo* component, const ComponentInstantiation* instantiation, const std::string& identifier) : diff --git a/redhawk/src/control/sdr/dommgr/Deployment.h b/redhawk/src/control/sdr/dommgr/Deployment.h index 2c9b7ac6c..4acc8572b 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.h +++ b/redhawk/src/control/sdr/dommgr/Deployment.h @@ -78,8 +78,10 @@ namespace ossie { void setImplementation(const ImplementationInfo* implementation); const ImplementationInfo* getImplementation() const; + const SPD::Implementation* getSPDImplementation() const; std::string getLocalFile(); + CF::LoadableDevice::LoadType getCodeType() const; void addDependency(SoftpkgDeployment* dependency); const DeploymentList& getDependencies(); diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp index 2ebe38a84..fc38a9b55 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp @@ -64,23 +64,11 @@ PREPARE_CF_LOGGING(ImplementationInfo); ImplementationInfo::ImplementationInfo(const SPD::Implementation& spdImpl) : implementation(&spdImpl), - codeType(), - entryPoint(), - dependencyProperties() + entryPoint() { setEntryPoint(spdImpl.getEntryPoint()); - setCodeType(spdImpl.getCodeType()); setStackSize(spdImpl.code.stacksize.get()); setPriority(spdImpl.code.priority.get()); - - // Handle allocation property dependencies - LOG_TRACE(ImplementationInfo, "Loading component implementation property dependencies") - const std::vector& dependencies = spdImpl.getDependencies(); - std::vector::const_iterator ii; - for (ii = dependencies.begin(); ii != dependencies.end(); ++ii) { - LOG_TRACE(ImplementationInfo, "Loading component implementation property dependency '" << *ii); - addDependencyProperty(*ii); - } } ImplementationInfo::~ImplementationInfo() @@ -107,6 +95,11 @@ ImplementationInfo* ImplementationInfo::buildImplementationInfo(CF::FileSystem_p return impl; } +const ossie::SPD::Implementation* ImplementationInfo::getImplementation() const +{ + return implementation; +} + const std::string& ImplementationInfo::getId() const { return implementation->getID(); @@ -127,11 +120,6 @@ const std::vector& ImplementationInfo::getOsDeps() return implementation->getOsDeps(); } -CF::LoadableDevice::LoadType ImplementationInfo::getCodeType() const -{ - return codeType; -} - const std::string& ImplementationInfo::getLocalFileName() const { return implementation->getCodeFile(); @@ -162,32 +150,11 @@ const bool ImplementationInfo::hasPriority() const return _hasPriority; } -const std::vector& ImplementationInfo::getDependencyProperties() const -{ - return dependencyProperties; -} - const std::vector& ImplementationInfo::getUsesDevices() const { return implementation->getUsesDevices(); } -void ImplementationInfo::setCodeType(const char* _type) -{ - std::string type(_type); - if (type == "KernelModule") { - codeType = CF::LoadableDevice::KERNEL_MODULE; - } else if (type == "SharedLibrary") { - codeType = CF::LoadableDevice::SHARED_LIBRARY; - } else if (type == "Executable") { - codeType = CF::LoadableDevice::EXECUTABLE; - } else if (type == "Driver") { - codeType = CF::LoadableDevice::DRIVER; - } else { - LOG_WARN(ImplementationInfo, "Bad code type " << type); - } -} - void ImplementationInfo::setEntryPoint(const char* _entryPoint) { if (_entryPoint) { @@ -213,11 +180,6 @@ void ImplementationInfo::setPriority(const unsigned long long* _priority) } } -void ImplementationInfo::addDependencyProperty(const PropertyRef& property) -{ - dependencyProperties.push_back(property); -} - void ImplementationInfo::addSoftPkgDependency(SoftpkgInfo* softpkg) { softPkgDependencies.push_back(softpkg); diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.h b/redhawk/src/control/sdr/dommgr/applicationSupport.h index 4e434132f..82b181661 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.h +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.h @@ -69,8 +69,9 @@ namespace ossie ImplementationInfo(const SPD::Implementation& spdImpl); ~ImplementationInfo(); + const ossie::SPD::Implementation* getImplementation() const; + const std::string& getId() const; - CF::LoadableDevice::LoadType getCodeType() const; const std::vector& getProcessorDeps() const; const std::vector& getOsDeps() const; const std::string& getLocalFileName() const; @@ -79,7 +80,6 @@ namespace ossie const CORBA::ULong getPriority() const; const bool hasStackSize() const; const bool hasPriority() const; - const std::vector& getDependencyProperties() const; const std::vector& getSoftPkgDependency() const; bool checkProcessorAndOs(const ossie::Properties& prf) const; @@ -92,21 +92,17 @@ namespace ossie private: ImplementationInfo (const ImplementationInfo&); void setEntryPoint(const char* fileName); - void setCodeType(const char* _type); void setStackSize(const unsigned long long *_stackSize); void setPriority(const unsigned long long *_priority); - void addDependencyProperty(const ossie::PropertyRef& property); void addSoftPkgDependency(SoftpkgInfo* softpkg); const ossie::SPD::Implementation* implementation; - CF::LoadableDevice::LoadType codeType; std::string entryPoint; CORBA::ULong stackSize; CORBA::ULong priority; bool _hasStackSize; bool _hasPriority; - std::vector dependencyProperties; std::vector softPkgDependencies; }; From 3f2a12c0e921ebbb930db6d3ebf9d465cf551e2e Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 24 May 2016 15:25:27 -0400 Subject: [PATCH 0276/1644] Remove unneeded members from Info classes --- redhawk/src/control/sdr/dommgr/Deployment.cpp | 19 ++--- .../control/sdr/dommgr/applicationSupport.cpp | 71 +------------------ .../control/sdr/dommgr/applicationSupport.h | 16 ----- 3 files changed, 11 insertions(+), 95 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index a24486764..32a985ddb 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -189,7 +189,7 @@ void SoftpkgDeployment::load(Application_impl* application, CF::FileSystem_ptr f std::string SoftpkgDeployment::getLocalFile() { - fs::path codeLocalFile = fs::path(implementation->getLocalFileName()); + fs::path codeLocalFile = fs::path(implementation->getImplementation()->getCodeFile()); if (!codeLocalFile.has_root_directory()) { // Path is relative to SPD file location fs::path base_dir = fs::path(softpkg->getSPDFile()).parent_path(); @@ -257,36 +257,37 @@ boost::shared_ptr ComponentDeployment::getAssignedDevice() std::string ComponentDeployment::getEntryPoint() { - std::string entryPoint = implementation->getEntryPoint(); - if (!entryPoint.empty()) { + const char* entryPoint = implementation->getImplementation()->getEntryPoint(); + if (entryPoint) { fs::path entryPointPath = fs::path(entryPoint); if (!entryPointPath.has_root_directory()) { // Path is relative to SPD file location fs::path base_dir = fs::path(softpkg->getSPDFile()).parent_path(); entryPointPath = base_dir / entryPointPath; } - entryPoint = entryPointPath.normalize().string(); + return entryPointPath.normalize().string(); } - return entryPoint; + return std::string(); } redhawk::PropertyMap ComponentDeployment::getOptions() { // Get the options from the softpkg redhawk::PropertyMap options(component->getOptions()); + const ossie::SPD::Code& code = implementation->getImplementation()->code; // Get the PRIORITY and STACK_SIZE from the SPD (if available) - if (implementation->hasStackSize()) { + if (code.stacksize.isSet()) { // 3.1.3.3.3.3.6 // The specification says it's supposed to be an unsigned long, but the // parser is set to unsigned long long - options[CF::ExecutableDevice::STACK_SIZE_ID] = implementation->getStackSize(); + options[CF::ExecutableDevice::STACK_SIZE_ID] = code.stacksize.get(); } - if (implementation->hasPriority()) { + if (code.priority.isSet()) { // 3.1.3.3.3.3.7 // The specification says it's supposed to be an unsigned long, but the // parser is set to unsigned long long - options[CF::ExecutableDevice::PRIORITY_ID] = implementation->getPriority(); + options[CF::ExecutableDevice::PRIORITY_ID] = code.priority.get(); } redhawk::PropertyMap affinity = affinityOptions; diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp index fc38a9b55..ca4b46615 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp @@ -63,12 +63,8 @@ static void addProperty(const CF::DataType& dt, CF::Properties& prop) PREPARE_CF_LOGGING(ImplementationInfo); ImplementationInfo::ImplementationInfo(const SPD::Implementation& spdImpl) : - implementation(&spdImpl), - entryPoint() + implementation(&spdImpl) { - setEntryPoint(spdImpl.getEntryPoint()); - setStackSize(spdImpl.code.stacksize.get()); - setPriority(spdImpl.code.priority.get()); } ImplementationInfo::~ImplementationInfo() @@ -120,66 +116,6 @@ const std::vector& ImplementationInfo::getOsDeps() return implementation->getOsDeps(); } -const std::string& ImplementationInfo::getLocalFileName() const -{ - return implementation->getCodeFile(); -} - -const std::string& ImplementationInfo::getEntryPoint() const -{ - return entryPoint; -} - -const CORBA::ULong ImplementationInfo::getStackSize() const -{ - return stackSize; -} - -const CORBA::ULong ImplementationInfo::getPriority() const -{ - return priority; -} - -const bool ImplementationInfo::hasStackSize() const -{ - return _hasStackSize; -} - -const bool ImplementationInfo::hasPriority() const -{ - return _hasPriority; -} - -const std::vector& ImplementationInfo::getUsesDevices() const -{ - return implementation->getUsesDevices(); -} - -void ImplementationInfo::setEntryPoint(const char* _entryPoint) -{ - if (_entryPoint) { - entryPoint = _entryPoint; - } -} - -void ImplementationInfo::setStackSize(const unsigned long long* _stackSize) -{ - _hasStackSize = false; - if (_stackSize) { - stackSize = *_stackSize; - _hasStackSize = true; - } -} - -void ImplementationInfo::setPriority(const unsigned long long* _priority) -{ - _hasPriority = false; - if (_priority) { - priority = *_priority; - _hasPriority = true; - } -} - void ImplementationInfo::addSoftPkgDependency(SoftpkgInfo* softpkg) { softPkgDependencies.push_back(softpkg); @@ -276,11 +212,6 @@ const ImplementationInfo::List& SoftpkgInfo::getImplementations() const return _implementations; } -const std::vector& SoftpkgInfo::getUsesDevices() const -{ - return spd.getUsesDevices(); -} - //////////////////////////////////////////////////// /* * ComponentInfo member function definitions diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.h b/redhawk/src/control/sdr/dommgr/applicationSupport.h index 82b181661..ade8e6a85 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.h +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.h @@ -74,35 +74,21 @@ namespace ossie const std::string& getId() const; const std::vector& getProcessorDeps() const; const std::vector& getOsDeps() const; - const std::string& getLocalFileName() const; - const std::string& getEntryPoint() const; - const CORBA::ULong getStackSize() const; - const CORBA::ULong getPriority() const; - const bool hasStackSize() const; - const bool hasPriority() const; const std::vector& getSoftPkgDependency() const; bool checkProcessorAndOs(const ossie::Properties& prf) const; - const std::vector & getUsesDevices() const; - static ImplementationInfo* buildImplementationInfo(CF::FileSystem_ptr fileSys, const SPD::Implementation& spdImpl); private: ImplementationInfo (const ImplementationInfo&); - void setEntryPoint(const char* fileName); void setStackSize(const unsigned long long *_stackSize); void setPriority(const unsigned long long *_priority); void addSoftPkgDependency(SoftpkgInfo* softpkg); const ossie::SPD::Implementation* implementation; - std::string entryPoint; - CORBA::ULong stackSize; - CORBA::ULong priority; - bool _hasStackSize; - bool _hasPriority; std::vector softPkgDependencies; }; @@ -122,8 +108,6 @@ namespace ossie void addImplementation(ImplementationInfo* impl); const ImplementationInfo::List& getImplementations() const; - const std::vector & getUsesDevices() const; - static SoftpkgInfo* buildSoftpkgInfo (CF::FileSystem_ptr fileSys, const char* spdFileName); SoftPkg spd; From 32d5aeca686c31d59374b6d2c65e22de2ba006ec Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 24 May 2016 16:01:55 -0400 Subject: [PATCH 0277/1644] Use existing SoftPkg profile for Info classes --- redhawk/src/control/include/ossie/SoftPkg.h | 2 +- .../sdr/dommgr/ApplicationFactory_impl.cpp | 12 +- redhawk/src/control/sdr/dommgr/Deployment.cpp | 2 +- .../control/sdr/dommgr/applicationSupport.cpp | 165 +++++------------- .../control/sdr/dommgr/applicationSupport.h | 21 +-- 5 files changed, 53 insertions(+), 149 deletions(-) diff --git a/redhawk/src/control/include/ossie/SoftPkg.h b/redhawk/src/control/include/ossie/SoftPkg.h index 930084bb5..954535914 100644 --- a/redhawk/src/control/include/ossie/SoftPkg.h +++ b/redhawk/src/control/include/ossie/SoftPkg.h @@ -301,7 +301,7 @@ namespace ossie { return _spd->type != "sca_non_compliant"; } - const boost::shared_ptr& getProperties() + const boost::shared_ptr& getProperties() const { return _properties; } diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 8afdc2e5c..899471291 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -975,7 +975,7 @@ void createHelper::setUpExternalProperties(ossie::ApplicationDeployment& appDepl LOG_ERROR(ApplicationFactory_impl, "Unable to find component for comprefid " << prop->comprefid); throw CF::ApplicationFactory::CreateApplicationError(CF::CF_NOTSET, "Unable to find component for given comprefid"); } - const Property* property = deployment->getComponent()->prf.getProperty(prop->propid); + const Property* property = deployment->getSoftPkg()->getProperties()->getProperty(prop->propid); if (!property){ LOG_ERROR(ApplicationFactory_impl, "Attempting to promote property: '" << prop->propid << "' that does not exist in component: '" << prop->comprefid << "'"); @@ -1181,6 +1181,7 @@ CF::Application_ptr createHelper::create ( ////////////////////////////////////////////////// // Load the components to instantiate from the SAD + _appProfile.load(_appFact._fileMgr, _appFact._sadParser); ossie::ApplicationDeployment app_deployment(_appFact._sadParser, _waveformContextName); getRequiredComponents(_appFact._fileMgr, _appFact._sadParser, app_deployment); @@ -1191,8 +1192,6 @@ CF::Application_ptr createHelper::create ( ////////////////////////////////////////////////// // Store information about this application - _appProfile.load(_appFact._fileMgr, _appFact._sadParser); - overrideExternalProperties(app_deployment, modifiedInitConfiguration); //////////////////////////////////////////////// @@ -1835,7 +1834,7 @@ ossie::SoftpkgDeployment* createHelper::resolveDependencyImplementation(ossie::S continue; } - ossie::SoftpkgDeployment* dependency = new ossie::SoftpkgDeployment(&(softpkg->spd), implementation); + ossie::SoftpkgDeployment* dependency = new ossie::SoftpkgDeployment(&(*softpkg->spd), implementation); // Recursively check any softpkg dependencies if (resolveSoftpkgDependencies(dependency, device)) { return dependency; @@ -1867,9 +1866,8 @@ ossie::ComponentInfo* createHelper::buildComponentInfo(CF::FileSystem_ptr fileSy throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EINVAL, eout.str().c_str()); } LOG_TRACE(ApplicationFactory_impl, "Building Component Info From SPD File"); - newComponent = ossie::ComponentInfo::buildComponentInfoFromSPDFile(fileSys, - componentfile->getFileName(), - &instance); + const boost::shared_ptr& softpkg = componentfile->getSoftPkg(); + newComponent = ossie::ComponentInfo::buildComponentInfoFromSPDFile(softpkg, &instance); if (newComponent == 0) { ostringstream eout; eout << "Error loading component information for file ref " << component.getFileRefId(); diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index 32a985ddb..a11000c52 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -222,7 +222,7 @@ CF::LoadableDevice::LoadType SoftpkgDeployment::getCodeType() const ComponentDeployment::ComponentDeployment(ComponentInfo* component, const ComponentInstantiation* instantiation, const std::string& identifier) : - SoftpkgDeployment(&(component->spd)), + SoftpkgDeployment(&(*component->spd)), component(component), instantiation(instantiation), identifier(identifier), diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp index ca4b46615..c4944f4b3 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp @@ -65,30 +65,21 @@ PREPARE_CF_LOGGING(ImplementationInfo); ImplementationInfo::ImplementationInfo(const SPD::Implementation& spdImpl) : implementation(&spdImpl) { -} - -ImplementationInfo::~ImplementationInfo() -{ - for (std::vector::iterator ii = softPkgDependencies.begin(); ii != softPkgDependencies.end(); ++ii) { - delete (*ii); - } -} - -ImplementationInfo* ImplementationInfo::buildImplementationInfo(CF::FileSystem_ptr fileSys, const SPD::Implementation& spdImpl) -{ - ImplementationInfo* impl = new ImplementationInfo(spdImpl); - // Handle allocation property dependencies LOG_TRACE(ImplementationInfo, "Loading component implementation softpkg dependencies") const std::vector& softpkgDependencies = spdImpl.getSoftPkgDependencies(); std::vector::const_iterator jj; for (jj = softpkgDependencies.begin(); jj != softpkgDependencies.end(); ++jj) { LOG_TRACE(ImplementationInfo, "Loading component implementation softpkg dependency '" << *jj); - std::auto_ptr softpkg(SoftpkgInfo::buildSoftpkgInfo(fileSys, jj->localfile.c_str())); - impl->addSoftPkgDependency(softpkg.release()); + addSoftPkgDependency(new SoftpkgInfo(jj->getReference())); } +} - return impl; +ImplementationInfo::~ImplementationInfo() +{ + for (std::vector::iterator ii = softPkgDependencies.begin(); ii != softPkgDependencies.end(); ++ii) { + delete (*ii); + } } const ossie::SPD::Implementation* ImplementationInfo::getImplementation() const @@ -138,9 +129,19 @@ bool ImplementationInfo::checkProcessorAndOs(const Properties& _prf) const PREPARE_CF_LOGGING(SoftpkgInfo); -SoftpkgInfo::SoftpkgInfo(const std::string& spdFileName): - _spdFileName(spdFileName) +SoftpkgInfo::SoftpkgInfo(const boost::shared_ptr& softpkg): + spd(softpkg) { + // Extract implementation data from SPD file + const std::vector & spd_i = spd->getImplementations(); + + // Assume only one implementation, use first available result [0] + for (unsigned int implCount = 0; implCount < spd_i.size(); implCount++) { + const SPD::Implementation& spdImpl = spd_i[implCount]; + LOG_TRACE(SoftpkgInfo, "Adding implementation " << spdImpl.getID()); + ImplementationInfo* newImpl = new ImplementationInfo(spdImpl); + addImplementation(newImpl); + } } SoftpkgInfo::~SoftpkgInfo() @@ -152,54 +153,12 @@ SoftpkgInfo::~SoftpkgInfo() const std::string& SoftpkgInfo::getSpdFileName() const { - return _spdFileName; + return spd->getSPDFile(); } const std::string& SoftpkgInfo::getName() const { - return spd.getName(); -} - -SoftpkgInfo* SoftpkgInfo::buildSoftpkgInfo(CF::FileSystem_ptr fileSys, const char* spdFileName) -{ - LOG_TRACE(SoftpkgInfo, "Building soft package info from file " << spdFileName); - - std::auto_ptr softpkg(new SoftpkgInfo(spdFileName)); - - if (!softpkg->parseProfile(fileSys)) { - return 0; - } else { - return softpkg.release(); - } -} - -bool SoftpkgInfo::parseProfile(CF::FileSystem_ptr fileSys) -{ - try { - File_stream spd_file(fileSys, _spdFileName.c_str()); - spd.load(spd_file, _spdFileName.c_str()); - spd_file.close(); - } catch (const ossie::parser_error& e) { - std::string parser_error_line = ossie::retrieveParserErrorLineNumber(e.what()); - LOG_ERROR(SoftpkgInfo, "Building component info problem; error parsing SPD: " << _spdFileName << ". " << parser_error_line << " The XML parser returned the following error: " << e.what()); - return false; - } catch (...) { - LOG_ERROR(SoftpkgInfo, "Building component info problem; unknown error parsing SPD: " << _spdFileName ); - return false; - } - - // Extract implementation data from SPD file - const std::vector & spd_i = spd.getImplementations(); - - // Assume only one implementation, use first available result [0] - for (unsigned int implCount = 0; implCount < spd_i.size(); implCount++) { - const SPD::Implementation& spdImpl = spd_i[implCount]; - LOG_TRACE(SoftpkgInfo, "Adding implementation " << spdImpl.getID()); - ImplementationInfo* newImpl = ImplementationInfo::buildImplementationInfo(fileSys, spdImpl); - addImplementation(newImpl); - } - - return true; + return spd->getName(); } void SoftpkgInfo::addImplementation(ImplementationInfo* impl) @@ -218,69 +177,27 @@ const ImplementationInfo::List& SoftpkgInfo::getImplementations() const */ PREPARE_CF_LOGGING(ComponentInfo); -ComponentInfo* ComponentInfo::buildComponentInfoFromSPDFile(CF::FileSystem_ptr fileSys, - const std::string& spdFileName, +ComponentInfo* ComponentInfo::buildComponentInfoFromSPDFile(const boost::shared_ptr& softpkg, const ComponentInstantiation* instantiation) { - LOG_TRACE(ComponentInfo, "Building component info from file " << spdFileName); - - ossie::ComponentInfo* newComponent = new ossie::ComponentInfo(spdFileName, instantiation); + LOG_TRACE(ComponentInfo, "Building component info from softpkg " << softpkg->getName()); - if (!newComponent->parseProfile(fileSys)) { - delete newComponent; - return 0; - } - - if (newComponent->spd.getSCDFile() != 0) { - try { - File_stream _scd(fileSys, newComponent->spd.getSCDFile()); - newComponent->scd.load(_scd); - _scd.close(); - } catch (ossie::parser_error& e) { - std::string parser_error_line = ossie::retrieveParserErrorLineNumber(e.what()); - LOG_ERROR(ComponentInfo, "Building component info problem; error parsing SCD: " << newComponent->spd.getSCDFile() << ". " << parser_error_line << " The XML parser returned the following error: " << e.what()); - delete newComponent; - return 0; - } catch( ... ) { - LOG_ERROR(ComponentInfo, "Building component info problem; unknown error parsing SCD: " << newComponent->spd.getSCDFile() ); - delete newComponent; - return 0; - } - } - - if (newComponent->spd.getPRFFile() != 0) { - LOG_DEBUG(ComponentInfo, "Loading component properties from " << newComponent->spd.getPRFFile()); - try { - File_stream _prf(fileSys, newComponent->spd.getPRFFile()); - LOG_TRACE(ComponentInfo, "Parsing component properties"); - newComponent->prf.load(_prf); - LOG_TRACE(ComponentInfo, "Closing PRF file") - _prf.close(); - } catch (ossie::parser_error& e) { - std::string parser_error_line = ossie::retrieveParserErrorLineNumber(e.what()); - LOG_ERROR(ComponentInfo, "Building component info problem; error parsing PRF: " << newComponent->spd.getPRFFile() << ". " << parser_error_line << " The XML parser returned the following error: " << e.what()); - delete newComponent; - return 0; - } catch( ... ) { - LOG_ERROR(ComponentInfo, "Building component info problem; unknown error parsing PRF: " << newComponent->spd.getPRFFile()); - delete newComponent; - return 0; - } - } + ossie::ComponentInfo* newComponent = new ossie::ComponentInfo(softpkg, instantiation); // Extract Properties from the implementation-agnostic PRF file // once we match the component to a device we can grab the implementation // specific PRF file - if (newComponent->spd.getPRFFile() != 0) { + if (softpkg->getProperties()) { // Handle component properties - LOG_TRACE(ComponentInfo, "Adding factory params") - const std::vector& fprop = newComponent->prf.getFactoryParamProperties(); + LOG_TRACE(ComponentInfo, "Adding factory params"); + Properties& prf = *softpkg->getProperties(); + const std::vector& fprop = prf.getFactoryParamProperties(); for (unsigned int i = 0; i < fprop.size(); i++) { newComponent->addFactoryParameter(convertPropertyToDataType(fprop[i])); } LOG_TRACE(ComponentInfo, "Adding exec params") - const std::vector& eprop = newComponent->prf.getExecParamProperties(); + const std::vector& eprop = prf.getExecParamProperties(); for (unsigned int i = 0; i < eprop.size(); i++) { if (std::string(eprop[i]->getMode()) != "readonly") { LOG_TRACE(ComponentInfo, "Adding exec param " << eprop[i]->getID() << " " << eprop[i]->getName()); @@ -300,7 +217,7 @@ ComponentInfo* ComponentInfo::buildComponentInfoFromSPDFile(CF::FileSystem_ptr f // newComponent->addAllocationCapacity((*prop)[i]->getDataType()); //} - const std::vector& prop = newComponent->prf.getConfigureProperties(); + const std::vector& prop = prf.getConfigureProperties(); for (unsigned int i = 0; i < prop.size(); i++) { if (!prop[i]->isReadOnly()) { LOG_TRACE(ComponentInfo, "Adding configure prop " << prop[i]->getID() << " " << prop[i]->getName() << " " << prop[i]->isReadOnly()) @@ -308,7 +225,7 @@ ComponentInfo* ComponentInfo::buildComponentInfoFromSPDFile(CF::FileSystem_ptr f } } - const std::vector& cprop = newComponent->prf.getConstructProperties(); + const std::vector& cprop = prf.getConstructProperties(); for (unsigned int i = 0; i < cprop.size(); i++) { LOG_TRACE(ComponentInfo, "Adding construct prop " << cprop[i]->getID() << " " << cprop[i]->getName() << " " << cprop[i]->isReadOnly()); bool isExec = false; @@ -333,12 +250,12 @@ ComponentInfo* ComponentInfo::buildComponentInfoFromSPDFile(CF::FileSystem_ptr f } - LOG_TRACE(ComponentInfo, "Done building component info from file " << spdFileName); + LOG_TRACE(ComponentInfo, "Done building component info from soft package " << softpkg->getName()); return newComponent; } -ComponentInfo::ComponentInfo(const std::string& spdFileName, const ComponentInstantiation* instantiation) : - SoftpkgInfo(spdFileName), +ComponentInfo::ComponentInfo(const boost::shared_ptr& softpkg, const ComponentInstantiation* instantiation) : + SoftpkgInfo(softpkg), instantiation(instantiation) { // load common affinity property definitions @@ -411,8 +328,8 @@ void ComponentInfo::addConstructProperty(CF::DataType dt) void ComponentInfo::overrideProperty(const ossie::ComponentProperty* propref) { std::string propId = propref->getID(); - LOG_TRACE(ComponentInfo, "Instantiation property id = " << propId) - const Property* prop = prf.getProperty(propId); + LOG_TRACE(ComponentInfo, "Instantiation property id = " << propId); + const Property* prop = spd->getProperties()->getProperty(propId); // Without a prop, we don't know how to convert the strings to the property any type if (prop == NULL) { LOG_WARN(ComponentInfo, "ignoring attempt to override property " << propId << " that does not exist in component") @@ -425,7 +342,7 @@ void ComponentInfo::overrideProperty(const ossie::ComponentProperty* propref) { void ComponentInfo::overrideProperty(const char* id, const CORBA::Any& value) { - const Property* prop = prf.getProperty(id); + const Property* prop = spd->getProperties()->getProperty(id); if (prop != NULL) { if (prop->isReadOnly()) { LOG_WARN(ComponentInfo, "ignoring attempt to override readonly property " << id); @@ -465,12 +382,12 @@ const char* ComponentInfo::getUsageName() const bool ComponentInfo::isResource() const { - return scd.isResource(); + return spd->getDescriptor()->isResource(); } bool ComponentInfo::isConfigurable() const { - return scd.isConfigurable(); + return spd->getDescriptor()->isConfigurable(); } @@ -481,7 +398,7 @@ bool ComponentInfo::isAssemblyController() const bool ComponentInfo::isScaCompliant() const { - return spd.isScaCompliant(); + return spd->isScaCompliant(); } bool ComponentInfo::checkStruct(const CF::Properties &props) const @@ -515,7 +432,7 @@ CF::Properties ComponentInfo::iteratePartialStruct(const CF::Properties &props) CF::Properties retval; const redhawk::PropertyMap& configProps = redhawk::PropertyMap::cast(props); for (redhawk::PropertyMap::const_iterator cP = configProps.begin(); cP != configProps.end(); cP++) { - const ossie::Property* prop = this->prf.getProperty(ossie::corba::returnString(cP->id)); + const ossie::Property* prop = spd->getProperties()->getProperty(ossie::corba::returnString(cP->id)); if (dynamic_cast(prop)) { CF::Properties* tmp; if (!(cP->value >>= tmp)) diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.h b/redhawk/src/control/sdr/dommgr/applicationSupport.h index ade8e6a85..9bd45a0f3 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.h +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.h @@ -78,9 +78,6 @@ namespace ossie bool checkProcessorAndOs(const ossie::Properties& prf) const; - static ImplementationInfo* buildImplementationInfo(CF::FileSystem_ptr fileSys, const SPD::Implementation& spdImpl); - - private: ImplementationInfo (const ImplementationInfo&); void setStackSize(const unsigned long long *_stackSize); @@ -99,23 +96,18 @@ namespace ossie public: - SoftpkgInfo (const std::string& spdFileName); + SoftpkgInfo (const boost::shared_ptr& softpkg); ~SoftpkgInfo (); const std::string& getSpdFileName() const; const std::string& getName() const; - void addImplementation(ImplementationInfo* impl); const ImplementationInfo::List& getImplementations() const; - static SoftpkgInfo* buildSoftpkgInfo (CF::FileSystem_ptr fileSys, const char* spdFileName); - - SoftPkg spd; + boost::shared_ptr spd; protected: - bool parseProfile (CF::FileSystem_ptr fileSys); - - const std::string _spdFileName; + void addImplementation(ImplementationInfo* impl); ImplementationInfo::List _implementations; }; @@ -130,7 +122,7 @@ namespace ossie public: typedef ossie::ComponentInstantiation::AffinityProperties AffinityProperties; - ComponentInfo (const std::string& spdFileName, const ComponentInstantiation* instantiation); + ComponentInfo (const boost::shared_ptr& softpkg, const ComponentInstantiation* instantiation); ~ComponentInfo (); const ComponentInstantiation* getInstantiation() const; @@ -168,11 +160,8 @@ namespace ossie CF::Properties getExecParameters(); CF::Properties getCommandLineParameters() const; - static ComponentInfo* buildComponentInfoFromSPDFile(CF::FileSystem_ptr fileSys, - const std::string& spdFileName, + static ComponentInfo* buildComponentInfoFromSPDFile(const boost::shared_ptr& softpkg, const ComponentInstantiation* instantiation); - ComponentDescriptor scd; - ossie::Properties prf; private: ComponentInfo (const ComponentInfo&); From bc6e328dfca55119eea32a8c5ac33b3892951442 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 24 May 2016 16:29:26 -0400 Subject: [PATCH 0278/1644] Drop ImplementationInfo and SoftpkgInfo classes entirely --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 53 ++++---- redhawk/src/control/sdr/dommgr/Deployment.cpp | 24 ++-- redhawk/src/control/sdr/dommgr/Deployment.h | 11 +- .../control/sdr/dommgr/applicationSupport.cpp | 126 ++---------------- .../control/sdr/dommgr/applicationSupport.h | 65 +-------- redhawk/src/control/sdr/dommgr/createHelper.h | 5 +- 6 files changed, 61 insertions(+), 223 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 899471291..607cc791f 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -709,12 +709,12 @@ bool createHelper::placeHostCollocation(ossie::ApplicationDeployment& appDeploym // Try all of the implementations from the current component for matches // with the processor and OS dependencies ossie::ComponentDeployment* deployment = *current; - const ImplementationList& comp_impls = deployment->getComponent()->getImplementations(); + const SPD::Implementations& comp_impls = deployment->getSoftPkg()->getImplementations(); LOG_TRACE(ApplicationFactory_impl, "Finding collocation-compatible implementations for component " << deployment->getInstantiation()->getID()); ++current; - for (ImplementationList::const_iterator impl = comp_impls.begin(); impl != comp_impls.end(); ++impl) { - const ossie::SPD::Implementation* implementation = (*impl)->getImplementation(); + for (SPD::Implementations::const_iterator impl = comp_impls.begin(); impl != comp_impls.end(); ++impl) { + const ossie::SPD::Implementation* implementation = &(*impl); LOG_TRACE(ApplicationFactory_impl, "Checking implementation " << implementation->getID()); // Check that the processor dependencies are compatible, filtering out @@ -736,7 +736,7 @@ bool createHelper::placeHostCollocation(ossie::ApplicationDeployment& appDeploym } // Set this implementation for deployment and recurse one more level - deployment->setImplementation(*impl); + deployment->setImplementation(implementation); if (placeHostCollocation(appDeployment, components, current, deploymentDevices, proc_list, os_list)) { return true; } @@ -758,7 +758,7 @@ bool createHelper::allocateHostCollocation(ossie::ApplicationDeployment& appDepl << " collocated components"); for (DeploymentList::const_iterator depl = components.begin(); depl != components.end(); ++depl) { LOG_TRACE(ApplicationFactory_impl, "Component " << (*depl)->getInstantiation()->getID() - << " implementation " << (*depl)->getImplementation()->getId()); + << " implementation " << (*depl)->getImplementation()->getID()); } const std::string requestid = ossie::generateUUID(); @@ -780,7 +780,7 @@ bool createHelper::allocateHostCollocation(ossie::ApplicationDeployment& appDepl if (!resolveSoftpkgDependencies(*depl, *node)) { LOG_TRACE(ApplicationFactory_impl, "Unable to resolve softpackage dependencies for component " << (*depl)->getIdentifier() - << " implementation " << (*depl)->getImplementation()->getId()); + << " implementation " << (*depl)->getImplementation()->getID()); return false; } (*depl)->setAssignedDevice(node); @@ -804,7 +804,7 @@ CF::Properties createHelper::_consolidateAllocations(const DeploymentList& deplo { CF::Properties allocs; for (DeploymentList::const_iterator depl = deployments.begin(); depl != deployments.end(); ++depl) { - const std::vector& deps = (*depl)->getSPDImplementation()->getDependencies(); + const std::vector& deps = (*depl)->getImplementation()->getDependencies(); for (std::vector::const_iterator dep = deps.begin(); dep != deps.end(); ++dep) { ossie::ComponentProperty *prop = dep->property.get(); ossie::corba::push_back(allocs, ossie::convertPropertyRefToDataType(prop)); @@ -1459,11 +1459,9 @@ void createHelper::allocateComponent(ossie::ComponentDeployment* deployment, } // now attempt to find an implementation that can have it's allocation requirements met - ossie::ComponentInfo* component = deployment->getComponent(); - const ossie::ImplementationInfo::List& implementations = component->getImplementations(); + const SPD::Implementations& implementations = deployment->getSoftPkg()->getImplementations(); for (size_t implCount = 0; implCount < implementations.size(); implCount++) { - ossie::ImplementationInfo* impl = implementations[implCount]; - const ossie::SPD::Implementation* implementation = impl->getImplementation(); + const ossie::SPD::Implementation* implementation = &implementations[implCount]; // Handle 'usesdevice' dependencies for the particular implementation UsesDeviceDeployment implAssignedDevices; @@ -1476,7 +1474,7 @@ void createHelper::allocateComponent(ossie::ComponentDeployment* deployment, continue; } - deployment->setImplementation(impl); + deployment->setImplementation(implementation); // Transfer ownership of the uses device assigments to the deployment assignedDevices.transferUsesDeviceAssignments(*deployment); @@ -1539,7 +1537,7 @@ void createHelper::allocateComponent(ossie::ComponentDeployment* deployment, if (allBusy) { // Report failure std::ostringstream eout; - eout << "Unable to launch component '"<getName()<<"'. All executable devices (i.e.: GPP) in the Domain are busy"; + eout << "Unable to launch component '"<getComponent()->getName()<<"'. All executable devices (i.e.: GPP) in the Domain are busy"; LOG_DEBUG(ApplicationFactory_impl, eout.str()); throw CF::ApplicationFactory::CreateApplicationError(CF::CF_ENOSPC, eout.str().c_str()); } @@ -1547,7 +1545,7 @@ void createHelper::allocateComponent(ossie::ComponentDeployment* deployment, // Report failure std::ostringstream eout; eout << "Failed to satisfy device dependencies for component: '"; - eout << component->getName() << "' with component id: '" << deployment->getIdentifier() << "'"; + eout << deployment->getComponent()->getName() << "' with component id: '" << deployment->getIdentifier() << "'"; LOG_DEBUG(ApplicationFactory_impl, eout.str()); throw CF::ApplicationFactory::CreateApplicationError(CF::CF_ENOSPC, eout.str().c_str()); } @@ -1715,7 +1713,7 @@ ossie::AllocationResult createHelper::allocateComponentToDevice(ossie::Component const std::string& appIdentifier) { const ossie::ComponentInfo* component = deployment->getComponent(); - const ossie::SPD::Implementation* implementation = deployment->getSPDImplementation(); + const ossie::SPD::Implementation* implementation = deployment->getImplementation(); ossie::DeviceList devices = _registeredDevices; // First check to see if the component was assigned in the user provided DAS @@ -1804,11 +1802,11 @@ void createHelper::_castRequestProperties(CF::Properties& allocationProperties, bool createHelper::resolveSoftpkgDependencies(ossie::SoftpkgDeployment* deployment, ossie::DeviceNode& device) { - const ossie::ImplementationInfo* implementation = deployment->getImplementation(); - const std::vector& tmpSoftpkg = implementation->getSoftPkgDependency(); - std::vector::const_iterator iterSoftpkg; + const ossie::SPD::Implementation* implementation = deployment->getImplementation(); + const SPD::SoftPkgDependencies& deps = implementation->getSoftPkgDependencies(); + SPD::SoftPkgDependencies::const_iterator iterSoftpkg; - for (iterSoftpkg = tmpSoftpkg.begin(); iterSoftpkg != tmpSoftpkg.end(); ++iterSoftpkg) { + for (iterSoftpkg = deps.begin(); iterSoftpkg != deps.end(); ++iterSoftpkg) { // Find an implementation whose dependencies match ossie::SoftpkgDeployment* dependency = resolveDependencyImplementation(*iterSoftpkg, device); if (dependency) { @@ -1822,19 +1820,22 @@ bool createHelper::resolveSoftpkgDependencies(ossie::SoftpkgDeployment* deployme return true; } -ossie::SoftpkgDeployment* createHelper::resolveDependencyImplementation(ossie::SoftpkgInfo* softpkg, +ossie::SoftpkgDeployment* createHelper::resolveDependencyImplementation(const ossie::SPD::SoftPkgRef& ref, ossie::DeviceNode& device) { - const ossie::ImplementationInfo::List& spd_list = softpkg->getImplementations(); + const boost::shared_ptr& softpkg = ref.getReference(); + const SPD::Implementations& spd_list = softpkg->getImplementations(); for (size_t implCount = 0; implCount < spd_list.size(); implCount++) { - ossie::ImplementationInfo* implementation = spd_list[implCount]; + const ossie::SPD::Implementation& implementation = spd_list[implCount]; // Check that this implementation can run on the device - if (!implementation->checkProcessorAndOs(device.prf)) { + if (!checkProcessor(implementation.getProcessors(), device.prf.getAllocationProperties())) { + continue; + } else if (!checkOs(implementation.getOsDeps(), device.prf.getAllocationProperties())) { continue; } - ossie::SoftpkgDeployment* dependency = new ossie::SoftpkgDeployment(&(*softpkg->spd), implementation); + ossie::SoftpkgDeployment* dependency = new ossie::SoftpkgDeployment(softpkg, &implementation); // Recursively check any softpkg dependencies if (resolveSoftpkgDependencies(dependency, device)) { return dependency; @@ -2017,7 +2018,7 @@ void createHelper::loadAndExecuteComponents(const DeploymentList& deployments, ossie::ComponentDeployment* deployment = deployments[rc_idx]; ossie::ComponentInfo* component = deployment->getComponent(); const ossie::ComponentInstantiation* instantiation = deployment->getInstantiation(); - const ossie::SPD::Implementation* implementation = deployment->getSPDImplementation(); + const ossie::SPD::Implementation* implementation = deployment->getImplementation(); boost::shared_ptr device = deployment->getAssignedDevice(); if (!device) { @@ -2185,7 +2186,7 @@ void createHelper::attemptComponentExecution (CF::ApplicationRegistrar_ptr regis ossie::ComponentDeployment* deployment) { const ossie::ComponentInfo* component = deployment->getComponent(); - const ossie::SPD::Implementation* implementation = deployment->getSPDImplementation(); + const ossie::SPD::Implementation* implementation = deployment->getImplementation(); const ossie::SoftPkg* softpkg = deployment->getSoftPkg(); // Get executable device reference diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index a11000c52..f2aef9e03 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -81,7 +81,8 @@ CF::Device_ptr UsesDeviceAssignment::getAssignedDevice() const return CF::Device::_duplicate(assignedDevice); } -SoftpkgDeployment::SoftpkgDeployment(const SoftPkg* softpkg, const ImplementationInfo* implementation) : +SoftpkgDeployment::SoftpkgDeployment(const boost::shared_ptr& softpkg, + const SPD::Implementation* implementation) : softpkg(softpkg), implementation(implementation) { @@ -94,24 +95,19 @@ SoftpkgDeployment::~SoftpkgDeployment() const SoftPkg* SoftpkgDeployment::getSoftPkg() const { - return softpkg; + return &(*softpkg); } -void SoftpkgDeployment::setImplementation(const ImplementationInfo* implementation) +void SoftpkgDeployment::setImplementation(const SPD::Implementation* implementation) { this->implementation = implementation; } -const ImplementationInfo* SoftpkgDeployment::getImplementation() const +const SPD::Implementation* SoftpkgDeployment::getImplementation() const { return implementation; } -const SPD::Implementation* SoftpkgDeployment::getSPDImplementation() const -{ - return implementation->getImplementation(); -} - void SoftpkgDeployment::addDependency(SoftpkgDeployment* dependency) { dependencies.push_back(dependency); @@ -189,7 +185,7 @@ void SoftpkgDeployment::load(Application_impl* application, CF::FileSystem_ptr f std::string SoftpkgDeployment::getLocalFile() { - fs::path codeLocalFile = fs::path(implementation->getImplementation()->getCodeFile()); + fs::path codeLocalFile = fs::path(implementation->getCodeFile()); if (!codeLocalFile.has_root_directory()) { // Path is relative to SPD file location fs::path base_dir = fs::path(softpkg->getSPDFile()).parent_path(); @@ -205,7 +201,7 @@ std::string SoftpkgDeployment::getLocalFile() CF::LoadableDevice::LoadType SoftpkgDeployment::getCodeType() const { - const std::string type = implementation->getImplementation()->getCodeType(); + const std::string type = implementation->getCodeType(); if (type == "KernelModule") { return CF::LoadableDevice::KERNEL_MODULE; } else if (type == "SharedLibrary") { @@ -222,7 +218,7 @@ CF::LoadableDevice::LoadType SoftpkgDeployment::getCodeType() const ComponentDeployment::ComponentDeployment(ComponentInfo* component, const ComponentInstantiation* instantiation, const std::string& identifier) : - SoftpkgDeployment(&(*component->spd)), + SoftpkgDeployment(component->spd), component(component), instantiation(instantiation), identifier(identifier), @@ -257,7 +253,7 @@ boost::shared_ptr ComponentDeployment::getAssignedDevice() std::string ComponentDeployment::getEntryPoint() { - const char* entryPoint = implementation->getImplementation()->getEntryPoint(); + const char* entryPoint = implementation->getEntryPoint(); if (entryPoint) { fs::path entryPointPath = fs::path(entryPoint); if (!entryPointPath.has_root_directory()) { @@ -274,7 +270,7 @@ redhawk::PropertyMap ComponentDeployment::getOptions() { // Get the options from the softpkg redhawk::PropertyMap options(component->getOptions()); - const ossie::SPD::Code& code = implementation->getImplementation()->code; + const ossie::SPD::Code& code = implementation->code; // Get the PRIORITY and STACK_SIZE from the SPD (if available) if (code.stacksize.isSet()) { diff --git a/redhawk/src/control/sdr/dommgr/Deployment.h b/redhawk/src/control/sdr/dommgr/Deployment.h index 4acc8572b..5dc7ab402 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.h +++ b/redhawk/src/control/sdr/dommgr/Deployment.h @@ -71,14 +71,13 @@ namespace ossie { public: typedef std::vector DeploymentList; - SoftpkgDeployment(const SoftPkg* softpkg, const ImplementationInfo* implementation=0); + SoftpkgDeployment(const boost::shared_ptr& softpkg, const SPD::Implementation* implementation=0); ~SoftpkgDeployment(); const SoftPkg* getSoftPkg() const; - void setImplementation(const ImplementationInfo* implementation); - const ImplementationInfo* getImplementation() const; - const SPD::Implementation* getSPDImplementation() const; + void setImplementation(const SPD::Implementation* implementation); + const SPD::Implementation* getImplementation() const; std::string getLocalFile(); CF::LoadableDevice::LoadType getCodeType() const; @@ -93,8 +92,8 @@ namespace ossie { void load(Application_impl* application, CF::FileSystem_ptr fileSystem, CF::LoadableDevice_ptr device, const std::string& componentId); - const SoftPkg* softpkg; - const ImplementationInfo* implementation; + boost::shared_ptr softpkg; + const SPD::Implementation* implementation; DeploymentList dependencies; }; diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp index c4944f4b3..acea9faac 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp @@ -56,120 +56,6 @@ static void addProperty(const CF::DataType& dt, CF::Properties& prop) prop[index] = dt; } -//////////////////////////////////////////////////// -/* - * ImplementationInfo member function definitions - */ -PREPARE_CF_LOGGING(ImplementationInfo); - -ImplementationInfo::ImplementationInfo(const SPD::Implementation& spdImpl) : - implementation(&spdImpl) -{ - // Handle allocation property dependencies - LOG_TRACE(ImplementationInfo, "Loading component implementation softpkg dependencies") - const std::vector& softpkgDependencies = spdImpl.getSoftPkgDependencies(); - std::vector::const_iterator jj; - for (jj = softpkgDependencies.begin(); jj != softpkgDependencies.end(); ++jj) { - LOG_TRACE(ImplementationInfo, "Loading component implementation softpkg dependency '" << *jj); - addSoftPkgDependency(new SoftpkgInfo(jj->getReference())); - } -} - -ImplementationInfo::~ImplementationInfo() -{ - for (std::vector::iterator ii = softPkgDependencies.begin(); ii != softPkgDependencies.end(); ++ii) { - delete (*ii); - } -} - -const ossie::SPD::Implementation* ImplementationInfo::getImplementation() const -{ - return implementation; -} - -const std::string& ImplementationInfo::getId() const -{ - return implementation->getID(); -} - -const std::vector& ImplementationInfo::getProcessorDeps() const -{ - return implementation->getProcessors(); -} - -const std::vector& ImplementationInfo::getSoftPkgDependency() const -{ - return softPkgDependencies; -} - -const std::vector& ImplementationInfo::getOsDeps() const -{ - return implementation->getOsDeps(); -} - -void ImplementationInfo::addSoftPkgDependency(SoftpkgInfo* softpkg) -{ - softPkgDependencies.push_back(softpkg); -} - -bool ImplementationInfo::checkProcessorAndOs(const Properties& _prf) const -{ - bool matchProcessor = checkProcessor(getProcessorDeps(), _prf.getAllocationProperties()); - bool matchOs = checkOs(getOsDeps(), _prf.getAllocationProperties()); - - if (!matchProcessor) { - LOG_DEBUG(ImplementationInfo, "Failed to match component processor to device allocation properties"); - } - if (!matchOs) { - LOG_DEBUG(ImplementationInfo, "Failed to match component os to device allocation properties"); - } - return matchProcessor && matchOs; -} - - -PREPARE_CF_LOGGING(SoftpkgInfo); - -SoftpkgInfo::SoftpkgInfo(const boost::shared_ptr& softpkg): - spd(softpkg) -{ - // Extract implementation data from SPD file - const std::vector & spd_i = spd->getImplementations(); - - // Assume only one implementation, use first available result [0] - for (unsigned int implCount = 0; implCount < spd_i.size(); implCount++) { - const SPD::Implementation& spdImpl = spd_i[implCount]; - LOG_TRACE(SoftpkgInfo, "Adding implementation " << spdImpl.getID()); - ImplementationInfo* newImpl = new ImplementationInfo(spdImpl); - addImplementation(newImpl); - } -} - -SoftpkgInfo::~SoftpkgInfo() -{ - for (ImplementationInfo::List::iterator ii = _implementations.begin(); ii != _implementations.end(); ++ii) { - delete *ii; - } -} - -const std::string& SoftpkgInfo::getSpdFileName() const -{ - return spd->getSPDFile(); -} - -const std::string& SoftpkgInfo::getName() const -{ - return spd->getName(); -} - -void SoftpkgInfo::addImplementation(ImplementationInfo* impl) -{ - _implementations.push_back(impl); -} - -const ImplementationInfo::List& SoftpkgInfo::getImplementations() const -{ - return _implementations; -} //////////////////////////////////////////////////// /* @@ -255,7 +141,7 @@ ComponentInfo* ComponentInfo::buildComponentInfoFromSPDFile(const boost::shared_ } ComponentInfo::ComponentInfo(const boost::shared_ptr& softpkg, const ComponentInstantiation* instantiation) : - SoftpkgInfo(softpkg), + spd(softpkg), instantiation(instantiation) { // load common affinity property definitions @@ -273,6 +159,16 @@ ComponentInfo::~ComponentInfo () { } +const std::string& ComponentInfo::getSpdFileName() const +{ + return spd->getSPDFile(); +} + +const std::string& ComponentInfo::getName() const +{ + return spd->getName(); +} + const ComponentInstantiation* ComponentInfo::getInstantiation() const { return instantiation; diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.h b/redhawk/src/control/sdr/dommgr/applicationSupport.h index 9bd45a0f3..d342efced 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.h +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.h @@ -54,68 +54,10 @@ namespace ossie }; typedef std::list ComponentList; - class SoftpkgInfo; - - /* Base class to contain data for implementations - * - Used to store information about about implementations - */ - class ImplementationInfo - { - ENABLE_LOGGING; - - public: - typedef std::vector< ImplementationInfo* > List; - - ImplementationInfo(const SPD::Implementation& spdImpl); - ~ImplementationInfo(); - - const ossie::SPD::Implementation* getImplementation() const; - - const std::string& getId() const; - const std::vector& getProcessorDeps() const; - const std::vector& getOsDeps() const; - const std::vector& getSoftPkgDependency() const; - - bool checkProcessorAndOs(const ossie::Properties& prf) const; - - private: - ImplementationInfo (const ImplementationInfo&); - void setStackSize(const unsigned long long *_stackSize); - void setPriority(const unsigned long long *_priority); - void addSoftPkgDependency(SoftpkgInfo* softpkg); - - const ossie::SPD::Implementation* implementation; - - std::vector softPkgDependencies; - - }; - - class SoftpkgInfo - { - ENABLE_LOGGING - - public: - - SoftpkgInfo (const boost::shared_ptr& softpkg); - ~SoftpkgInfo (); - - const std::string& getSpdFileName() const; - const std::string& getName() const; - - const ImplementationInfo::List& getImplementations() const; - - boost::shared_ptr spd; - - protected: - void addImplementation(ImplementationInfo* impl); - - ImplementationInfo::List _implementations; - }; - /* Base class to contain data for components * - Used to store information about about components */ - class ComponentInfo : public SoftpkgInfo + class ComponentInfo { ENABLE_LOGGING @@ -125,6 +67,11 @@ namespace ossie ComponentInfo (const boost::shared_ptr& softpkg, const ComponentInstantiation* instantiation); ~ComponentInfo (); + const std::string& getSpdFileName() const; + const std::string& getName() const; + + boost::shared_ptr spd; + const ComponentInstantiation* getInstantiation() const; void setUsageName(const char* usageName); diff --git a/redhawk/src/control/sdr/dommgr/createHelper.h b/redhawk/src/control/sdr/dommgr/createHelper.h index 1c8b90c6b..6ffc3f657 100644 --- a/redhawk/src/control/sdr/dommgr/createHelper.h +++ b/redhawk/src/control/sdr/dommgr/createHelper.h @@ -100,8 +100,6 @@ class createHelper ossie::ApplicationProfile _appProfile; typedef std::vector DeploymentList; - typedef ossie::ImplementationInfo::List ImplementationList; - typedef std::vector CollocationList; typedef std::vector ProcessorList; typedef std::vector OSList; @@ -167,7 +165,8 @@ class createHelper const OSList& osDeps); bool resolveSoftpkgDependencies(ossie::SoftpkgDeployment* deployment, ossie::DeviceNode& device); - ossie::SoftpkgDeployment* resolveDependencyImplementation(ossie::SoftpkgInfo* softpkg, ossie::DeviceNode& device); + ossie::SoftpkgDeployment* resolveDependencyImplementation(const ossie::SPD::SoftPkgRef& ref, + ossie::DeviceNode& device); // Supports loading, executing, initializing, configuring, & connecting void loadAndExecuteComponents(const DeploymentList& deployments, From ac36d9d9980d28aa920acbd360bb491b38289e21 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 24 May 2016 16:38:19 -0400 Subject: [PATCH 0279/1644] Remove more unused code --- redhawk/src/control/sdr/dommgr/applicationSupport.cpp | 5 ----- redhawk/src/control/sdr/dommgr/applicationSupport.h | 2 -- 2 files changed, 7 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp index acea9faac..317f26c05 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp @@ -271,11 +271,6 @@ const std::string& ComponentInfo::getInstantiationIdentifier() const return instantiation->getID(); } -const char* ComponentInfo::getUsageName() const -{ - return usageName.c_str(); -} - bool ComponentInfo::isResource() const { return spd->getDescriptor()->isResource(); diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.h b/redhawk/src/control/sdr/dommgr/applicationSupport.h index d342efced..a2ca901ee 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.h +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.h @@ -87,7 +87,6 @@ namespace ossie void overrideProperty(const char* id, const CORBA::Any& value); const std::string& getInstantiationIdentifier() const; - const char* getUsageName() const; bool isResource() const; bool isConfigurable() const; bool isAssemblyController() const; @@ -114,7 +113,6 @@ namespace ossie ComponentInfo (const ComponentInfo&); void process_overrides(CF::Properties* props, const char* id, CORBA::Any value); - bool _isConfigurable; std::string usageName; From 8dcff2ee494af2d8efd4448d98c0eab675ffa3e0 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 25 May 2016 09:09:37 -0400 Subject: [PATCH 0280/1644] Store the values for stacksize and priority correctly, and default to not set instead of 0 --- redhawk/src/control/include/ossie/SoftPkg.h | 4 ++-- redhawk/src/control/sdr/dommgr/Deployment.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/redhawk/src/control/include/ossie/SoftPkg.h b/redhawk/src/control/include/ossie/SoftPkg.h index 954535914..dc140d866 100644 --- a/redhawk/src/control/include/ossie/SoftPkg.h +++ b/redhawk/src/control/include/ossie/SoftPkg.h @@ -92,8 +92,8 @@ namespace ossie { localfile(""), type(""), entrypoint(), - stacksize((unsigned long long)0), - priority((unsigned long long)0) + stacksize(), + priority() {} }; diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index f2aef9e03..55c71f776 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -277,13 +277,13 @@ redhawk::PropertyMap ComponentDeployment::getOptions() // 3.1.3.3.3.3.6 // The specification says it's supposed to be an unsigned long, but the // parser is set to unsigned long long - options[CF::ExecutableDevice::STACK_SIZE_ID] = code.stacksize.get(); + options[CF::ExecutableDevice::STACK_SIZE_ID] = static_cast(*code.stacksize); } if (code.priority.isSet()) { // 3.1.3.3.3.3.7 // The specification says it's supposed to be an unsigned long, but the // parser is set to unsigned long long - options[CF::ExecutableDevice::PRIORITY_ID] = code.priority.get(); + options[CF::ExecutableDevice::PRIORITY_ID] = static_cast(*code.priority); } redhawk::PropertyMap affinity = affinityOptions; From 9b5f7c5833fb967fa099581db11181ba6501fbe4 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 25 May 2016 09:33:47 -0400 Subject: [PATCH 0281/1644] Create the Propterties and Descriptor objects for a SoftPkg before parsing their respective XML, so that they at least has empty values instead of nothing (although it seems like an invalid PRF or SCD should be a validation error) --- .../src/control/sdr/dommgr/ApplicationProfile.cpp | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationProfile.cpp b/redhawk/src/control/sdr/dommgr/ApplicationProfile.cpp index adc85bd3a..e3f93785a 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationProfile.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationProfile.cpp @@ -172,24 +172,22 @@ boost::shared_ptr ApplicationProfile::loadProfile(CF::FileSystem_ptr fi if (spd->getPRFFile()) { LOG_TRACE(ApplicationProfile, "Loading PRF file " << spd->getPRFFile()); try { + spd->setProperties(boost::make_shared()); File_stream prf_stream(fileSystem, spd->getPRFFile()); - boost::shared_ptr prf = boost::make_shared(); - prf->load(prf_stream); - spd->setProperties(prf); + spd->getProperties()->load(prf_stream); } catch (const std::exception& exc) { - LOG_ERROR(ApplicationProfile, "Invalid PRF file " << spd->getPRFFile()); + LOG_ERROR(ApplicationProfile, "Invalid PRF file " << spd->getPRFFile() << ": " << exc.what()); } } if (spd->getSCDFile()) { LOG_TRACE(ApplicationProfile, "Loading SCD file " << spd->getSCDFile()); try { + spd->setDescriptor(boost::make_shared()); File_stream scd_stream(fileSystem, spd->getSCDFile()); - boost::shared_ptr scd = boost::make_shared(); - scd->load(scd_stream); - spd->setDescriptor(scd); + spd->getDescriptor()->load(scd_stream); } catch (const std::exception& exc) { - LOG_ERROR(ApplicationProfile, "Invalid SCD file " << spd->getSCDFile()); + LOG_ERROR(ApplicationProfile, "Invalid SCD file " << spd->getSCDFile() << ": " << exc.what()); } } From 38be24271821d943eb0caa3d9c445066f49c750d Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 25 May 2016 09:35:28 -0400 Subject: [PATCH 0282/1644] Be more defensive about the possibility of not having a Properties object in a SoftPkg --- .../src/control/sdr/dommgr/applicationSupport.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp index 317f26c05..1575a93a2 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp @@ -225,9 +225,12 @@ void ComponentInfo::addConstructProperty(CF::DataType dt) void ComponentInfo::overrideProperty(const ossie::ComponentProperty* propref) { std::string propId = propref->getID(); LOG_TRACE(ComponentInfo, "Instantiation property id = " << propId); - const Property* prop = spd->getProperties()->getProperty(propId); + const Property* prop = 0; + if (spd->getProperties()) { + prop = spd->getProperties()->getProperty(propId); + } // Without a prop, we don't know how to convert the strings to the property any type - if (prop == NULL) { + if (!prop) { LOG_WARN(ComponentInfo, "ignoring attempt to override property " << propId << " that does not exist in component") return; } @@ -238,9 +241,10 @@ void ComponentInfo::overrideProperty(const ossie::ComponentProperty* propref) { void ComponentInfo::overrideProperty(const char* id, const CORBA::Any& value) { - const Property* prop = spd->getProperties()->getProperty(id); - if (prop != NULL) { - if (prop->isReadOnly()) { + const Property* prop = 0; + if (spd->getProperties()) { + prop = spd->getProperties()->getProperty(id); + if (prop && prop->isReadOnly()) { LOG_WARN(ComponentInfo, "ignoring attempt to override readonly property " << id); return; } From 381173c87f3c1ecf8af6d8dff8aeada116228d99 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 25 May 2016 09:59:29 -0400 Subject: [PATCH 0283/1644] Fix logging message --- redhawk/src/control/sdr/dommgr/Deployment.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index 55c71f776..44097b9f7 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -147,7 +147,7 @@ void SoftpkgDeployment::load(Application_impl* application, CF::FileSystem_ptr f // Recursively load dependencies if (!dependencies.empty()) { RH_NL_TRACE("ApplicationFactory_impl", "Loading " << dependencies.size() << - "dependency(ies) for soft package " << softpkg->getName()); + " dependency(ies) for soft package " << softpkg->getName()); for (DeploymentList::iterator dep = dependencies.begin(); dep != dependencies.end(); ++dep) { (*dep)->load(application, fileSystem, device, componentId); } From d298756bdecc3c4802aeb27d214b8dc5100b4a18 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 25 May 2016 10:08:26 -0400 Subject: [PATCH 0284/1644] Remove links from ComponentFile and SoftPkgRef to SoftPkg instances, instead resolving the link at point-of-use, to avoid modifying the profile objects. This means that the SoftwareAssembly can be effectively const once it's parsed. --- redhawk/src/control/include/ossie/SoftPkg.h | 13 ------------ .../control/include/ossie/componentProfile.h | 14 ------------- .../sdr/dommgr/ApplicationFactory_impl.cpp | 4 ++-- .../control/sdr/dommgr/ApplicationProfile.cpp | 20 ++++++++++++++----- .../control/sdr/dommgr/ApplicationProfile.h | 2 ++ 5 files changed, 19 insertions(+), 34 deletions(-) diff --git a/redhawk/src/control/include/ossie/SoftPkg.h b/redhawk/src/control/include/ossie/SoftPkg.h index dc140d866..f0e613d80 100644 --- a/redhawk/src/control/include/ossie/SoftPkg.h +++ b/redhawk/src/control/include/ossie/SoftPkg.h @@ -51,19 +51,6 @@ namespace ossie { virtual const std::string asString() const; virtual ~SoftPkgRef() {}; - - const boost::shared_ptr& getReference() const - { - return _softpkg; - } - - void setReference(const boost::shared_ptr& softpkg) - { - _softpkg = softpkg; - } - - private: - boost::shared_ptr _softpkg; }; diff --git a/redhawk/src/control/include/ossie/componentProfile.h b/redhawk/src/control/include/ossie/componentProfile.h index 37b425c06..3fc7c805c 100644 --- a/redhawk/src/control/include/ossie/componentProfile.h +++ b/redhawk/src/control/include/ossie/componentProfile.h @@ -29,7 +29,6 @@ #include #include #include -#include #include "ossie/ossieparser.h" namespace ossie { @@ -49,19 +48,6 @@ namespace ossie { const std::string& getFileName() const; const std::string& getID() const; - - const boost::shared_ptr& getSoftPkg() const - { - return _softpkg; - } - - void setSoftPkg(const boost::shared_ptr& softpkg) - { - _softpkg = softpkg; - } - - private: - boost::shared_ptr _softpkg; }; /* diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 607cc791f..477800d14 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -1823,7 +1823,7 @@ bool createHelper::resolveSoftpkgDependencies(ossie::SoftpkgDeployment* deployme ossie::SoftpkgDeployment* createHelper::resolveDependencyImplementation(const ossie::SPD::SoftPkgRef& ref, ossie::DeviceNode& device) { - const boost::shared_ptr& softpkg = ref.getReference(); + const boost::shared_ptr& softpkg = _appProfile.getSoftPkg(ref.localfile); const SPD::Implementations& spd_list = softpkg->getImplementations(); for (size_t implCount = 0; implCount < spd_list.size(); implCount++) { @@ -1867,7 +1867,7 @@ ossie::ComponentInfo* createHelper::buildComponentInfo(CF::FileSystem_ptr fileSy throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EINVAL, eout.str().c_str()); } LOG_TRACE(ApplicationFactory_impl, "Building Component Info From SPD File"); - const boost::shared_ptr& softpkg = componentfile->getSoftPkg(); + const boost::shared_ptr& softpkg = _appProfile.getSoftPkg(componentfile->getFileName()); newComponent = ossie::ComponentInfo::buildComponentInfoFromSPDFile(softpkg, &instance); if (newComponent == 0) { ostringstream eout; diff --git a/redhawk/src/control/sdr/dommgr/ApplicationProfile.cpp b/redhawk/src/control/sdr/dommgr/ApplicationProfile.cpp index e3f93785a..274d78c7f 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationProfile.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationProfile.cpp @@ -18,6 +18,7 @@ * along with this program. If not, see http://www.gnu.org/licenses/. */ +#include #include #include @@ -143,6 +144,17 @@ void ApplicationProfile::load(CF::FileSystem_ptr fileSystem, const SoftwareAssem } } +const boost::shared_ptr& ApplicationProfile::getSoftPkg(const std::string& filename) const +{ + BOOST_FOREACH(const boost::shared_ptr& softpkg, profiles) { + if (softpkg->getSPDFile() == filename) { + return softpkg; + } + } + + throw std::logic_error(filename + " was never loaded"); +} + boost::shared_ptr ApplicationProfile::loadProfile(CF::FileSystem_ptr fileSystem, const std::string& filename) { @@ -165,7 +177,7 @@ boost::shared_ptr ApplicationProfile::loadProfile(CF::FileSystem_ptr fi for (SPD::SoftPkgDependencies::const_iterator dep = deps.begin(); dep != deps.end(); ++dep) { SPD::SoftPkgRef& ref = const_cast(*dep); LOG_TRACE(ApplicationProfile, "Resolving soft package reference " << ref.localfile); - ref.setReference(loadProfile(fileSystem, ref.localfile)); + loadProfile(fileSystem, ref.localfile); } } @@ -201,9 +213,7 @@ SinglePlacement* ApplicationProfile::buildComponentPlacement(CF::FileSystem_ptr { assert(placement.componentFile); ComponentFile* componentFile = const_cast(placement.componentFile); - if (!componentFile->getSoftPkg()) { - componentFile->setSoftPkg(loadProfile(fileSystem, componentFile->getFileName())); - } + const boost::shared_ptr& softpkg = loadProfile(fileSystem, componentFile->getFileName()); // Even though it is possible for there to be more than one instantiation // per component, the tooling doesn't support that, so supporting this at a @@ -213,7 +223,7 @@ SinglePlacement* ApplicationProfile::buildComponentPlacement(CF::FileSystem_ptr const std::vector& instantiations = placement.getInstantiations(); const ComponentInstantiation& instance = instantiations[0]; - return new SinglePlacement(&instance, componentFile->getSoftPkg()); + return new SinglePlacement(&instance, softpkg); } const ApplicationProfile::PlacementList& ApplicationProfile::getPlacements() const diff --git a/redhawk/src/control/sdr/dommgr/ApplicationProfile.h b/redhawk/src/control/sdr/dommgr/ApplicationProfile.h index b0b67bea4..8593d950d 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationProfile.h +++ b/redhawk/src/control/sdr/dommgr/ApplicationProfile.h @@ -101,6 +101,8 @@ namespace ossie { const PlacementList& getPlacements() const; + const boost::shared_ptr& getSoftPkg(const std::string& filename) const; + protected: typedef std::vector > ProfileList; From 69a5e60d3782b57f311032b065df58d9d91ce0f4 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 25 May 2016 10:24:27 -0400 Subject: [PATCH 0285/1644] Drop use of boost::shared_ptr for SoftPkg profile objects now that there are no arbitrary cross-profile references --- redhawk/src/control/include/ossie/SoftPkg.h | 2 +- .../sdr/dommgr/ApplicationFactory_impl.cpp | 4 +-- .../control/sdr/dommgr/ApplicationProfile.cpp | 29 +++++++++---------- .../control/sdr/dommgr/ApplicationProfile.h | 14 +++++---- redhawk/src/control/sdr/dommgr/Deployment.cpp | 2 +- redhawk/src/control/sdr/dommgr/Deployment.h | 4 +-- .../control/sdr/dommgr/applicationSupport.cpp | 4 +-- .../control/sdr/dommgr/applicationSupport.h | 6 ++-- 8 files changed, 33 insertions(+), 32 deletions(-) diff --git a/redhawk/src/control/include/ossie/SoftPkg.h b/redhawk/src/control/include/ossie/SoftPkg.h index f0e613d80..7f8b4996d 100644 --- a/redhawk/src/control/include/ossie/SoftPkg.h +++ b/redhawk/src/control/include/ossie/SoftPkg.h @@ -298,7 +298,7 @@ namespace ossie { _properties = properties; } - const boost::shared_ptr& getDescriptor() + const boost::shared_ptr& getDescriptor() const { return _descriptor; } diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 477800d14..f63b68dcc 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -1823,7 +1823,7 @@ bool createHelper::resolveSoftpkgDependencies(ossie::SoftpkgDeployment* deployme ossie::SoftpkgDeployment* createHelper::resolveDependencyImplementation(const ossie::SPD::SoftPkgRef& ref, ossie::DeviceNode& device) { - const boost::shared_ptr& softpkg = _appProfile.getSoftPkg(ref.localfile); + const SoftPkg* softpkg = _appProfile.getSoftPkg(ref.localfile); const SPD::Implementations& spd_list = softpkg->getImplementations(); for (size_t implCount = 0; implCount < spd_list.size(); implCount++) { @@ -1867,7 +1867,7 @@ ossie::ComponentInfo* createHelper::buildComponentInfo(CF::FileSystem_ptr fileSy throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EINVAL, eout.str().c_str()); } LOG_TRACE(ApplicationFactory_impl, "Building Component Info From SPD File"); - const boost::shared_ptr& softpkg = _appProfile.getSoftPkg(componentfile->getFileName()); + const SoftPkg* softpkg = _appProfile.getSoftPkg(componentfile->getFileName()); newComponent = ossie::ComponentInfo::buildComponentInfoFromSPDFile(softpkg, &instance); if (newComponent == 0) { ostringstream eout; diff --git a/redhawk/src/control/sdr/dommgr/ApplicationProfile.cpp b/redhawk/src/control/sdr/dommgr/ApplicationProfile.cpp index 274d78c7f..2e5468bee 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationProfile.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationProfile.cpp @@ -32,7 +32,7 @@ using namespace ossie; * SinglePlacement */ SinglePlacement::SinglePlacement(const ComponentInstantiation* instantiation, - const boost::shared_ptr& softpkg) : + const SoftPkg* softpkg) : instantiation(instantiation), softpkg(softpkg) { @@ -48,7 +48,7 @@ const ComponentInstantiation* SinglePlacement::getComponentInstantiation() const return instantiation; } -const boost::shared_ptr& SinglePlacement::getComponentProfile() +const SoftPkg* SinglePlacement::getComponentProfile() { return softpkg; } @@ -144,31 +144,31 @@ void ApplicationProfile::load(CF::FileSystem_ptr fileSystem, const SoftwareAssem } } -const boost::shared_ptr& ApplicationProfile::getSoftPkg(const std::string& filename) const +const SoftPkg* ApplicationProfile::getSoftPkg(const std::string& filename) const { - BOOST_FOREACH(const boost::shared_ptr& softpkg, profiles) { - if (softpkg->getSPDFile() == filename) { - return softpkg; + BOOST_FOREACH(const SoftPkg& softpkg, profiles) { + if (softpkg.getSPDFile() == filename) { + return &softpkg; } } throw std::logic_error(filename + " was never loaded"); } -boost::shared_ptr ApplicationProfile::loadProfile(CF::FileSystem_ptr fileSystem, - const std::string& filename) +const SoftPkg* ApplicationProfile::loadProfile(CF::FileSystem_ptr fileSystem, + const std::string& filename) { - for (ProfileList::const_iterator profile = profiles.begin(); profile != profiles.end(); ++profile) { - if ((*profile)->getSPDFile() == filename) { + BOOST_FOREACH(const SoftPkg& profile, profiles) { + if (profile.getSPDFile() == filename) { LOG_TRACE(ApplicationProfile, "Found existing profile " << filename); - return *profile; + return &profile; } } LOG_TRACE(ApplicationProfile, "Loading SPD file " << filename); - boost::shared_ptr spd; File_stream spd_stream(fileSystem, filename.c_str()); - spd = boost::make_shared(boost::ref(spd_stream), filename); + SoftPkg* spd = new SoftPkg(spd_stream, filename); + profiles.push_back(spd); spd_stream.close(); const SPD::Implementations& spd_impls = spd->getImplementations(); @@ -203,7 +203,6 @@ boost::shared_ptr ApplicationProfile::loadProfile(CF::FileSystem_ptr fi } } - profiles.push_back(spd); return spd; } @@ -213,7 +212,7 @@ SinglePlacement* ApplicationProfile::buildComponentPlacement(CF::FileSystem_ptr { assert(placement.componentFile); ComponentFile* componentFile = const_cast(placement.componentFile); - const boost::shared_ptr& softpkg = loadProfile(fileSystem, componentFile->getFileName()); + const SoftPkg* softpkg = loadProfile(fileSystem, componentFile->getFileName()); // Even though it is possible for there to be more than one instantiation // per component, the tooling doesn't support that, so supporting this at a diff --git a/redhawk/src/control/sdr/dommgr/ApplicationProfile.h b/redhawk/src/control/sdr/dommgr/ApplicationProfile.h index 8593d950d..3910e0956 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationProfile.h +++ b/redhawk/src/control/sdr/dommgr/ApplicationProfile.h @@ -25,6 +25,8 @@ #include #include +#include + #include "applicationSupport.h" namespace ossie { @@ -42,17 +44,17 @@ namespace ossie { { public: SinglePlacement(const ComponentInstantiation* instantiation, - const boost::shared_ptr& softpkg); + const SoftPkg* softpkg); virtual void accept(ApplicationVisitor* visitor); const ComponentInstantiation* getComponentInstantiation() const; - const boost::shared_ptr& getComponentProfile(); + const SoftPkg* getComponentProfile(); protected: const ComponentInstantiation* instantiation; - boost::shared_ptr softpkg; + const SoftPkg* softpkg; }; class CollocationPlacement : public Placement @@ -101,12 +103,12 @@ namespace ossie { const PlacementList& getPlacements() const; - const boost::shared_ptr& getSoftPkg(const std::string& filename) const; + const SoftPkg* getSoftPkg(const std::string& filename) const; protected: - typedef std::vector > ProfileList; + typedef boost::ptr_vector ProfileList; - boost::shared_ptr loadProfile(CF::FileSystem_ptr fileSystem, const std::string& filename); + const SoftPkg* loadProfile(CF::FileSystem_ptr fileSystem, const std::string& filename); SinglePlacement* buildComponentPlacement(CF::FileSystem_ptr fileSystem, const SoftwareAssembly& sad, diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index 44097b9f7..ba1469f35 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -81,7 +81,7 @@ CF::Device_ptr UsesDeviceAssignment::getAssignedDevice() const return CF::Device::_duplicate(assignedDevice); } -SoftpkgDeployment::SoftpkgDeployment(const boost::shared_ptr& softpkg, +SoftpkgDeployment::SoftpkgDeployment(const SoftPkg* softpkg, const SPD::Implementation* implementation) : softpkg(softpkg), implementation(implementation) diff --git a/redhawk/src/control/sdr/dommgr/Deployment.h b/redhawk/src/control/sdr/dommgr/Deployment.h index 5dc7ab402..2ece64cbb 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.h +++ b/redhawk/src/control/sdr/dommgr/Deployment.h @@ -71,7 +71,7 @@ namespace ossie { public: typedef std::vector DeploymentList; - SoftpkgDeployment(const boost::shared_ptr& softpkg, const SPD::Implementation* implementation=0); + SoftpkgDeployment(const SoftPkg* softpkg, const SPD::Implementation* implementation=0); ~SoftpkgDeployment(); const SoftPkg* getSoftPkg() const; @@ -92,7 +92,7 @@ namespace ossie { void load(Application_impl* application, CF::FileSystem_ptr fileSystem, CF::LoadableDevice_ptr device, const std::string& componentId); - boost::shared_ptr softpkg; + const SoftPkg* softpkg; const SPD::Implementation* implementation; DeploymentList dependencies; }; diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp index 1575a93a2..49c282404 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp @@ -63,7 +63,7 @@ static void addProperty(const CF::DataType& dt, CF::Properties& prop) */ PREPARE_CF_LOGGING(ComponentInfo); -ComponentInfo* ComponentInfo::buildComponentInfoFromSPDFile(const boost::shared_ptr& softpkg, +ComponentInfo* ComponentInfo::buildComponentInfoFromSPDFile(const SoftPkg* softpkg, const ComponentInstantiation* instantiation) { LOG_TRACE(ComponentInfo, "Building component info from softpkg " << softpkg->getName()); @@ -140,7 +140,7 @@ ComponentInfo* ComponentInfo::buildComponentInfoFromSPDFile(const boost::shared_ return newComponent; } -ComponentInfo::ComponentInfo(const boost::shared_ptr& softpkg, const ComponentInstantiation* instantiation) : +ComponentInfo::ComponentInfo(const SoftPkg* softpkg, const ComponentInstantiation* instantiation) : spd(softpkg), instantiation(instantiation) { diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.h b/redhawk/src/control/sdr/dommgr/applicationSupport.h index a2ca901ee..a604be3a3 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.h +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.h @@ -64,13 +64,13 @@ namespace ossie public: typedef ossie::ComponentInstantiation::AffinityProperties AffinityProperties; - ComponentInfo (const boost::shared_ptr& softpkg, const ComponentInstantiation* instantiation); + ComponentInfo (const SoftPkg* softpkg, const ComponentInstantiation* instantiation); ~ComponentInfo (); const std::string& getSpdFileName() const; const std::string& getName() const; - boost::shared_ptr spd; + const SoftPkg* spd; const ComponentInstantiation* getInstantiation() const; @@ -106,7 +106,7 @@ namespace ossie CF::Properties getExecParameters(); CF::Properties getCommandLineParameters() const; - static ComponentInfo* buildComponentInfoFromSPDFile(const boost::shared_ptr& softpkg, + static ComponentInfo* buildComponentInfoFromSPDFile(const SoftPkg* softpkg, const ComponentInstantiation* instantiation); private: From 9182ff4a6f60b25b370e7ee58db5470180b54e14 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 25 May 2016 10:39:39 -0400 Subject: [PATCH 0286/1644] Drop visitor pattern in ApplicationProfile --- .../control/sdr/dommgr/ApplicationProfile.cpp | 19 ------------- .../control/sdr/dommgr/ApplicationProfile.h | 28 ------------------- 2 files changed, 47 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationProfile.cpp b/redhawk/src/control/sdr/dommgr/ApplicationProfile.cpp index 2e5468bee..0c731934a 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationProfile.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationProfile.cpp @@ -38,11 +38,6 @@ SinglePlacement::SinglePlacement(const ComponentInstantiation* instantiation, { } -void SinglePlacement::accept(ApplicationVisitor* visitor) -{ - visitor->visitComponentPlacement(this); -} - const ComponentInstantiation* SinglePlacement::getComponentInstantiation() const { return instantiation; @@ -60,11 +55,6 @@ CollocationPlacement::CollocationPlacement(const std::string& id, const std::str { } -void CollocationPlacement::accept(ApplicationVisitor* visitor) -{ - visitor->visitHostCollocation(this); -} - const std::string& CollocationPlacement::getId() const { return id; @@ -102,11 +92,6 @@ ApplicationProfile::~ApplicationProfile() } } -void ApplicationProfile::accept(ApplicationVisitor* visitor) -{ - visitor->visitApplication(this); -} - const std::string& ApplicationProfile::getIdentifier() const { return identifier; @@ -135,10 +120,6 @@ void ApplicationProfile::load(CF::FileSystem_ptr fileSystem, const SoftwareAssem // Then, walk through the remaining non-collocated components const std::vector& components = sad.getComponentPlacements(); for (unsigned int i = 0; i < components.size(); i++) { - // ossie::ComponentInfo* component = buildComponentInfo(fileSys, sadParser, componentsFromSAD[i]); - // if (component->getInstantiationIdentifier() == assemblyControllerRefId) { - // component->setIsAssemblyController(true); - // } SinglePlacement* placement = buildComponentPlacement(fileSystem, sad, components[i]); placements.push_back(placement); } diff --git a/redhawk/src/control/sdr/dommgr/ApplicationProfile.h b/redhawk/src/control/sdr/dommgr/ApplicationProfile.h index 3910e0956..4dba4ce81 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationProfile.h +++ b/redhawk/src/control/sdr/dommgr/ApplicationProfile.h @@ -31,13 +31,10 @@ namespace ossie { - class ApplicationVisitor; - class Placement { public: virtual ~Placement() { } - virtual void accept(ApplicationVisitor* visitor) = 0; }; class SinglePlacement : public Placement @@ -46,8 +43,6 @@ namespace ossie { SinglePlacement(const ComponentInstantiation* instantiation, const SoftPkg* softpkg); - virtual void accept(ApplicationVisitor* visitor); - const ComponentInstantiation* getComponentInstantiation() const; const SoftPkg* getComponentProfile(); @@ -64,8 +59,6 @@ namespace ossie { CollocationPlacement(const std::string& id, const std::string& name); - virtual void accept(ApplicationVisitor* visitor); - const std::string& getId() const; const std::string& getName() const; @@ -95,8 +88,6 @@ namespace ossie { ApplicationProfile(); ~ApplicationProfile(); - void accept(ApplicationVisitor* visitor); - const std::string& getIdentifier() const; void load(CF::FileSystem_ptr fileSystem, const SoftwareAssembly& sad); @@ -119,25 +110,6 @@ namespace ossie { PlacementList placements; }; - class ApplicationVisitor - { - public: - virtual ~ApplicationVisitor() { } - - virtual void visitApplication(ApplicationProfile* application) - { - } - - virtual void visitComponentPlacement(SinglePlacement* placement) - { - } - - virtual void visitHostCollocation(CollocationPlacement* collocation) - { - } - - }; - } #endif // APPLICATIONPROFILE_H From 6c4172e90bc43fa59620b3aff8e284167ba9de1d Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 25 May 2016 10:46:39 -0400 Subject: [PATCH 0287/1644] Remove more unneeded code --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 6 ++--- redhawk/src/control/sdr/dommgr/Deployment.cpp | 9 +++---- .../control/sdr/dommgr/applicationSupport.cpp | 24 ------------------- .../control/sdr/dommgr/applicationSupport.h | 7 ------ 4 files changed, 8 insertions(+), 38 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index f63b68dcc..e5925c057 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -607,7 +607,7 @@ void createHelper::_checkAssemblyController( { if (CORBA::is_nil(assemblyController)) { if ((assemblyControllerComponent==NULL) || - (assemblyControllerComponent->isScaCompliant()) + (assemblyControllerComponent->spd->isScaCompliant()) ) { LOG_DEBUG(ApplicationFactory_impl, "assembly controller is not Sca Compliant or has not been assigned"); throw (CF::ApplicationFactory::CreateApplicationError( @@ -1355,7 +1355,7 @@ void createHelper::overrideExternalProperties(ossie::ApplicationDeployment& appD if (id == static_cast(initConfiguration[i].id)) { ComponentInfo *comp = appDeployment.getComponent(prop->comprefid); // Only configure on non AC components - if (comp != 0 && !comp->isAssemblyController()) { + if (comp != 0 && !comp->getInstantiation()->isAssemblyController()) { comp->overrideProperty(prop->propid.c_str(), initConfiguration[i].value); } } @@ -1878,7 +1878,7 @@ ossie::ComponentInfo* createHelper::buildComponentInfo(CF::FileSystem_ptr fileSy LOG_TRACE(ApplicationFactory_impl, "Done building Component Info From SPD File") - if (newComponent->isScaCompliant() && !instance.isNamingService()) { + if (newComponent->spd->isScaCompliant() && !instance.isNamingService()) { LOG_WARN(ApplicationFactory_impl, "component instantiation is sca compliant but does not provide a 'findcomponent' name...this is probably an error"); } diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index ba1469f35..226fb4969 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -268,11 +268,12 @@ std::string ComponentDeployment::getEntryPoint() redhawk::PropertyMap ComponentDeployment::getOptions() { - // Get the options from the softpkg - redhawk::PropertyMap options(component->getOptions()); - const ossie::SPD::Code& code = implementation->code; + // In prior versions, the options could be overridden, at least from the + // perspective of ComponentInfo; this may need to be re-implemented + redhawk::PropertyMap options; // Get the PRIORITY and STACK_SIZE from the SPD (if available) + const ossie::SPD::Code& code = implementation->code; if (code.stacksize.isSet()) { // 3.1.3.3.3.3.6 // The specification says it's supposed to be an unsigned long, but the @@ -485,7 +486,7 @@ ComponentInfo* ApplicationDeployment::getAssemblyController() for (PlacementList::iterator placement = placements.begin(); placement != placements.end(); ++placement) { const std::vector& components = (*placement)->getComponents(); for (std::vector::const_iterator comp = components.begin(); comp != components.end(); ++comp) { - if ((*comp)->isAssemblyController()) { + if ((*comp)->getInstantiation()->isAssemblyController()) { return *comp; } } diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp index 49c282404..3bd305295 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp @@ -174,13 +174,6 @@ const ComponentInstantiation* ComponentInfo::getInstantiation() const return instantiation; } -void ComponentInfo::setUsageName(const char* _usageName) -{ - if (_usageName != 0) { - usageName = _usageName; - } -} - void ComponentInfo::setAffinity( const AffinityProperties &affinity_props ) { @@ -251,7 +244,6 @@ void ComponentInfo::overrideProperty(const char* id, const CORBA::Any& value) } process_overrides(&ctorProperties, id, value); process_overrides(&configureProperties, id, value); - process_overrides(&options, id, value); process_overrides(&factoryParameters, id, value); process_overrides(&execParameters, id, value); } @@ -285,17 +277,6 @@ bool ComponentInfo::isConfigurable() const return spd->getDescriptor()->isConfigurable(); } - -bool ComponentInfo::isAssemblyController() const -{ - return instantiation->isAssemblyController(); -} - -bool ComponentInfo::isScaCompliant() const -{ - return spd->isScaCompliant(); -} - bool ComponentInfo::checkStruct(const CF::Properties &props) const { const redhawk::PropertyMap& tmpProps = redhawk::PropertyMap::cast(props); @@ -391,11 +372,6 @@ CF::Properties ComponentInfo::getConstructProperties() const } -CF::Properties ComponentInfo::getOptions() -{ - return options; -} - CF::Properties ComponentInfo::getExecParameters() { return execParameters; diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.h b/redhawk/src/control/sdr/dommgr/applicationSupport.h index a604be3a3..dd3011aee 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.h +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.h @@ -74,7 +74,6 @@ namespace ossie const ComponentInstantiation* getInstantiation() const; - void setUsageName(const char* usageName); void setAffinity( const AffinityProperties &affinity ); void addFactoryParameter(CF::DataType dt); @@ -89,8 +88,6 @@ namespace ossie const std::string& getInstantiationIdentifier() const; bool isResource() const; bool isConfigurable() const; - bool isAssemblyController() const; - bool isScaCompliant() const; CF::Properties containsPartialStructConfig() const; CF::Properties containsPartialStructConstruct() const; @@ -101,7 +98,6 @@ namespace ossie CF::Properties getInitializeProperties() const; CF::Properties getConfigureProperties() const; CF::Properties getConstructProperties() const; - CF::Properties getOptions(); CF::Properties getAffinityOptions() const; CF::Properties getExecParameters(); CF::Properties getCommandLineParameters() const; @@ -114,13 +110,10 @@ namespace ossie void process_overrides(CF::Properties* props, const char* id, CORBA::Any value); - std::string usageName; - ossie::Properties _affinity_prf; CF::Properties configureProperties; CF::Properties ctorProperties; - CF::Properties options; CF::Properties factoryParameters; CF::Properties execParameters; CF::Properties affinityOptions; From e54ce673e275b0701130fb9a3107f60405ae2a81 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 25 May 2016 11:07:52 -0400 Subject: [PATCH 0288/1644] Return a const string reference instead of const char* from ComponentProperty::getID() --- redhawk/src/control/framework/prop_utils.cpp | 8 ++++---- redhawk/src/control/include/ossie/componentProfile.h | 2 +- redhawk/src/control/parser/componentProfile.cpp | 4 ++-- redhawk/src/control/sdr/devmgr/DeviceManager_impl.cpp | 8 ++++---- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/redhawk/src/control/framework/prop_utils.cpp b/redhawk/src/control/framework/prop_utils.cpp index fc1ca5490..f6febe25a 100644 --- a/redhawk/src/control/framework/prop_utils.cpp +++ b/redhawk/src/control/framework/prop_utils.cpp @@ -516,7 +516,7 @@ CF::AllocationManager::AllocationResponseType ossie::assembleResponse(std::strin CF::DataType ossie::convertPropertyToDataType(const SimplePropertyRef* prop) { CF::DataType dataType; - dataType.id = CORBA::string_dup(prop->getID()); + dataType.id = prop->getID().c_str(); if (prop->getValue() != NULL) { std::string value(prop->getValue()); @@ -527,14 +527,14 @@ CF::DataType ossie::convertPropertyToDataType(const SimplePropertyRef* prop) { CF::DataType ossie::convertPropertyToDataType(const SimpleSequencePropertyRef* prop) { CF::DataType dataType; - dataType.id = CORBA::string_dup(prop->getID()); + dataType.id = prop->getID().c_str(); dataType.value = ossie::strings_to_any(prop->getValues(), CORBA::tk_string); return dataType; } CF::DataType ossie::convertPropertyToDataType(const StructPropertyRef* prop) { CF::DataType dataType; - dataType.id = CORBA::string_dup(prop->getID()); + dataType.id = prop->getID().c_str(); CF::Properties structval_; StructPropertyRef::ValuesMap::const_iterator i; @@ -550,7 +550,7 @@ CF::DataType ossie::convertPropertyToDataType(const StructPropertyRef* prop) { CF::DataType ossie::convertPropertyToDataType(const StructSequencePropertyRef* prop) { CF::DataType dataType; - dataType.id = CORBA::string_dup(prop->getID()); + dataType.id = prop->getID().c_str(); const StructSequencePropertyRef::ValuesList propValues = prop->getValues(); CORBA::AnySeq values; diff --git a/redhawk/src/control/include/ossie/componentProfile.h b/redhawk/src/control/include/ossie/componentProfile.h index 3fc7c805c..87df93a1d 100644 --- a/redhawk/src/control/include/ossie/componentProfile.h +++ b/redhawk/src/control/include/ossie/componentProfile.h @@ -61,7 +61,7 @@ namespace ossie { virtual ~ComponentProperty() {}; - const char* getID() const; + const std::string& getID() const; ComponentProperty* clone() const { return _clone(); diff --git a/redhawk/src/control/parser/componentProfile.cpp b/redhawk/src/control/parser/componentProfile.cpp index 8c7b74563..c10bb62a7 100644 --- a/redhawk/src/control/parser/componentProfile.cpp +++ b/redhawk/src/control/parser/componentProfile.cpp @@ -48,8 +48,8 @@ const std::string& ComponentFile::getID() const { // // ComponentProperty // -const char* ComponentProperty::getID() const { - return _id.c_str(); +const std::string& ComponentProperty::getID() const { + return _id; } diff --git a/redhawk/src/control/sdr/devmgr/DeviceManager_impl.cpp b/redhawk/src/control/sdr/devmgr/DeviceManager_impl.cpp index d34304449..1c5328af2 100644 --- a/redhawk/src/control/sdr/devmgr/DeviceManager_impl.cpp +++ b/redhawk/src/control/sdr/devmgr/DeviceManager_impl.cpp @@ -535,7 +535,7 @@ void DeviceManager_impl::getOverloadprops( // see if this exec param has been overloaded (NOTE: we know that execparams are simple elements via the spec) for (iprops_iter = instanceprops.begin(); iprops_iter != instanceprops.end(); iprops_iter++) { // property has been overloaded in instantiation from DCD - if (strcmp( iprops_iter->getID(), (*jprops_iter)->getID()) == 0) { + if (iprops_iter->getID() == (*jprops_iter)->getID()) { if (dynamic_cast( &(*iprops_iter)) == NULL) { LOG_WARN(DeviceManager_impl, "ignoring attempt to override exec param with non-simple ref"); } else { @@ -581,7 +581,7 @@ void DeviceManager_impl::getOverloadprops( // see if this property has been overloaded (NOTE: we know that property are simple elements via the spec) for (iprops_iter = instanceprops.begin(); iprops_iter != instanceprops.end(); iprops_iter++) { // property has been overloaded in instantiation from DCD - if (strcmp( iprops_iter->getID(), (*jprops_iter)->getID()) == 0) { + if (iprops_iter->getID() == (*jprops_iter)->getID()) { if (dynamic_cast(&(*iprops_iter)) == NULL) { LOG_WARN(DeviceManager_impl, "ignoring attempt to override property with non-simple ref"); } else { @@ -760,7 +760,7 @@ void DeviceManager_impl::createDeviceExecStatement( // get logging info if available logging_uri = ""; for (iprops_iter = instanceprops.begin(); iprops_iter != instanceprops.end(); iprops_iter++) { - if ((strcmp(iprops_iter->getID(), "LOGGING_CONFIG_URI") == 0) + if ((iprops_iter->getID() == "LOGGING_CONFIG_URI") && (dynamic_cast(&(*iprops_iter)) != NULL)) { const SimplePropertyRef* simpleref = dynamic_cast(&(*iprops_iter)); logging_uri = simpleref->getValue(); @@ -875,7 +875,7 @@ DeviceManager_impl::ExecparamList DeviceManager_impl::createDeviceExecparams( ossie::ComponentPropertyList::const_iterator iprops_iter; logging_uri = ""; for (iprops_iter = instanceprops.begin(); iprops_iter != instanceprops.end(); iprops_iter++) { - if ((strcmp(iprops_iter->getID(), "LOGGING_CONFIG_URI") == 0) + if ((iprops_iter->getID() == "LOGGING_CONFIG_URI") && (dynamic_cast(&(*iprops_iter)) != NULL)) { const SimplePropertyRef* simpleref = dynamic_cast(&(*iprops_iter)); logging_uri = simpleref->getValue(); From 79a8d4e1d0bedd5cf6ac8b5b8eb30ee7f445d5b8 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 25 May 2016 11:30:32 -0400 Subject: [PATCH 0289/1644] Move responsibility for fetching properties for initializeProperties() and initial configure() to the deployment class --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 5 +- redhawk/src/control/sdr/dommgr/Deployment.cpp | 55 +++++++++++++++++++ redhawk/src/control/sdr/dommgr/Deployment.h | 6 ++ .../control/sdr/dommgr/applicationSupport.cpp | 10 ---- .../control/sdr/dommgr/applicationSupport.h | 2 - 5 files changed, 64 insertions(+), 14 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index e5925c057..adb9a07c0 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -2505,7 +2505,7 @@ void createHelper::initializeComponents(const DeploymentList& deployments) } try { // Try to set the initial values for the component's properties - CF::Properties initProps = component->getInitializeProperties(); + redhawk::PropertyMap initProps = deployment->getInitializeProperties(); resource->initializeProperties(initProps); } catch(CF::PropertySet::InvalidConfiguration& e) { ostringstream eout; @@ -2644,7 +2644,8 @@ void createHelper::configureComponents(const DeploymentList& deployments) } try { // try to configure the component - _rsc->configure (component->getNonNilConfigureProperties()); + redhawk::PropertyMap config_props = deployment->getInitialConfigureProperties(); + _rsc->configure(config_props); } catch(CF::PropertySet::InvalidConfiguration& e) { ostringstream eout; eout << "Failed to 'configure' component: '"; diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index 226fb4969..6d4acf979 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -19,6 +19,9 @@ */ #include +#include + +#include #include "Application_impl.h" #include "PersistenceStore.h" @@ -347,6 +350,58 @@ CF::Properties ComponentDeployment::getConstructProperties() const return component->getConstructProperties(); } +redhawk::PropertyMap ComponentDeployment::getInitialConfigureProperties() const +{ + redhawk::PropertyMap properties; + if (softpkg->getProperties()) { + BOOST_FOREACH(const Property* property, softpkg->getProperties()->getProperties()) { + if (property->isConfigure() && !property->isReadOnly()) { + CF::DataType dt = getPropertyValue(property); + if (!ossie::any::isNull(dt.value)) { + properties.push_back(dt); + } + } + } + } + return properties; +} + +redhawk::PropertyMap ComponentDeployment::getInitializeProperties() const +{ + redhawk::PropertyMap properties; + if (softpkg->getProperties()) { + BOOST_FOREACH(const Property* property, softpkg->getProperties()->getProperties()) { + if (property->isProperty() && !property->isCommandLine()) { + CF::DataType dt = getPropertyValue(property); + if (!ossie::any::isNull(dt.value)) { + properties.push_back(dt); + } + } + } + } + return properties; +} + +CF::DataType ComponentDeployment::getPropertyValue(const Property* property) const +{ + const ComponentProperty* override = getPropertyOverride(property->getID()); + if (override) { + return ossie::overridePropertyValue(property, override); + } else { + return ossie::convertPropertyToDataType(property); + } +} + +const ComponentProperty* ComponentDeployment::getPropertyOverride(const std::string& id) const +{ + BOOST_FOREACH(const ComponentProperty& override, instantiation->getProperties()) { + if (override.getID() == id) { + return &override; + } + } + return 0; +} + redhawk::PropertyMap ComponentDeployment::getAffinityOptionsWithAssignment() const { redhawk::PropertyMap options = affinityOptions; diff --git a/redhawk/src/control/sdr/dommgr/Deployment.h b/redhawk/src/control/sdr/dommgr/Deployment.h index 2ece64cbb..0de667bee 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.h +++ b/redhawk/src/control/sdr/dommgr/Deployment.h @@ -130,6 +130,9 @@ namespace ossie { CF::Properties getConfigureProperties() const; CF::Properties getConstructProperties() const; + redhawk::PropertyMap getInitialConfigureProperties() const; + redhawk::PropertyMap getInitializeProperties() const; + void setAssignedDevice(const boost::shared_ptr& device); boost::shared_ptr getAssignedDevice(); @@ -140,6 +143,9 @@ namespace ossie { CF::LoadableDevice_ptr device); protected: + CF::DataType getPropertyValue(const Property* property) const; + const ComponentProperty* getPropertyOverride(const std::string& id) const; + ComponentInfo* component; const ComponentInstantiation* instantiation; const std::string identifier; diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp index 3bd305295..128d9aae8 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp @@ -345,16 +345,6 @@ CF::Properties ComponentInfo::containsPartialStructConstruct() const return this->iteratePartialStruct(ctorProperties); } -CF::Properties ComponentInfo::getNonNilConfigureProperties() const -{ - return ossie::getNonNilConfigureProperties(configureProperties); -} - -CF::Properties ComponentInfo::getInitializeProperties() const -{ - return ossie::getNonNilProperties(ctorProperties); -} - CF::Properties ComponentInfo::getAffinityOptions() const { return affinityOptions; diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.h b/redhawk/src/control/sdr/dommgr/applicationSupport.h index dd3011aee..cad608c5a 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.h +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.h @@ -94,8 +94,6 @@ namespace ossie CF::Properties iteratePartialStruct(const CF::Properties &props) const; bool checkStruct(const CF::Properties &props) const; - CF::Properties getNonNilConfigureProperties() const; - CF::Properties getInitializeProperties() const; CF::Properties getConfigureProperties() const; CF::Properties getConstructProperties() const; CF::Properties getAffinityOptions() const; From bec48ed456fc8842cae688078c1199a0ce256e30 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 25 May 2016 11:37:07 -0400 Subject: [PATCH 0290/1644] Remove more methods from ComponentInfo --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 31 ++++++++++--------- redhawk/src/control/sdr/dommgr/Deployment.cpp | 12 ++++++- redhawk/src/control/sdr/dommgr/Deployment.h | 3 ++ .../control/sdr/dommgr/applicationSupport.cpp | 25 --------------- .../control/sdr/dommgr/applicationSupport.h | 8 ----- 5 files changed, 30 insertions(+), 49 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index adb9a07c0..34da96905 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -659,10 +659,10 @@ void createHelper::assignPlacementsToDevices(ossie::ApplicationDeployment& appDe } else { ComponentInfo* component = components[0]; std::string assigned_device; - DeviceAssignmentMap::const_iterator device = devices.find(component->getInstantiationIdentifier()); + DeviceAssignmentMap::const_iterator device = devices.find(component->getInstantiation()->getID()); if (device != devices.end()) { assigned_device = device->second; - LOG_TRACE(ApplicationFactory_impl, "Component " << component->getInstantiationIdentifier() + LOG_TRACE(ApplicationFactory_impl, "Component " << component->getInstantiation()->getID() << " is assigned to device " << assigned_device); } ossie::ComponentDeployment* deployment = appDeployment.createComponentDeployment(component); @@ -823,7 +823,7 @@ void createHelper::_placeHostCollocation(ossie::ApplicationDeployment& appDeploy for (PlacementList::const_iterator placement = components.begin(); placement != components.end(); ++placement) { - DeviceAssignmentMap::const_iterator device = devices.find((*placement)->getInstantiationIdentifier()); + DeviceAssignmentMap::const_iterator device = devices.find((*placement)->getInstantiation()->getID()); if (device != devices.end()) { assignedDevices.push_back(device->second); } @@ -1244,7 +1244,7 @@ CF::Application_ptr createHelper::create ( // Check that the assembly controller is valid CF::Resource_var assemblyController; if (assemblyControllerComponent) { - const std::string& assemblyControllerId = assemblyControllerComponent->getInstantiationIdentifier(); + const std::string& assemblyControllerId = assemblyControllerComponent->getInstantiation()->getID(); ossie::ComponentDeployment* deployment = app_deployment.getComponentDeployment(assemblyControllerId); assemblyController = deployment->getResourcePtr(); } @@ -1537,7 +1537,7 @@ void createHelper::allocateComponent(ossie::ComponentDeployment* deployment, if (allBusy) { // Report failure std::ostringstream eout; - eout << "Unable to launch component '"<getComponent()->getName()<<"'. All executable devices (i.e.: GPP) in the Domain are busy"; + eout << "Unable to launch component '"<getSoftPkg()->getName()<<"'. All executable devices (i.e.: GPP) in the Domain are busy"; LOG_DEBUG(ApplicationFactory_impl, eout.str()); throw CF::ApplicationFactory::CreateApplicationError(CF::CF_ENOSPC, eout.str().c_str()); } @@ -1545,7 +1545,7 @@ void createHelper::allocateComponent(ossie::ComponentDeployment* deployment, // Report failure std::ostringstream eout; eout << "Failed to satisfy device dependencies for component: '"; - eout << deployment->getComponent()->getName() << "' with component id: '" << deployment->getIdentifier() << "'"; + eout << deployment->getSoftPkg()->getName() << "' with component id: '" << deployment->getIdentifier() << "'"; LOG_DEBUG(ApplicationFactory_impl, eout.str()); throw CF::ApplicationFactory::CreateApplicationError(CF::CF_ENOSPC, eout.str().c_str()); } @@ -1719,7 +1719,7 @@ ossie::AllocationResult createHelper::allocateComponentToDevice(ossie::Component // First check to see if the component was assigned in the user provided DAS // See if a device was assigned in the DAS if (!assignedDeviceId.empty()) { - LOG_TRACE(ApplicationFactory_impl, "User-provided DAS: Component: '" << component->getName() << + LOG_TRACE(ApplicationFactory_impl, "User-provided DAS: Component: '" << deployment->getSoftPkg()->getName() << "' Assigned device: '" << assignedDeviceId << "'"); ossie::DeviceList::iterator device; for (device = devices.begin(); device != devices.end(); ++device) { @@ -2017,6 +2017,7 @@ void createHelper::loadAndExecuteComponents(const DeploymentList& deployments, for (unsigned int rc_idx = 0; rc_idx < deployments.size (); rc_idx++) { ossie::ComponentDeployment* deployment = deployments[rc_idx]; ossie::ComponentInfo* component = deployment->getComponent(); + const ossie::SoftPkg* softpkg = deployment->getSoftPkg(); const ossie::ComponentInstantiation* instantiation = deployment->getInstantiation(); const ossie::SPD::Implementation* implementation = deployment->getImplementation(); @@ -2027,13 +2028,13 @@ void createHelper::loadAndExecuteComponents(const DeploymentList& deployments, throw std::logic_error(message.str()); } - LOG_TRACE(ApplicationFactory_impl, "Component - " << component->getName() + LOG_TRACE(ApplicationFactory_impl, "Component - " << softpkg->getName() << " Assigned device - " << device->identifier); LOG_INFO(ApplicationFactory_impl, "APPLICATION: " << _waveformContextName << " COMPONENT ID: " << component->getIdentifier() << " ASSIGNED TO DEVICE ID/LABEL: " << device->identifier << "/" << device->label); // Let the application know to expect the given component - _application->addComponent(deployment->getIdentifier(), component->getSpdFileName()); + _application->addComponent(deployment->getIdentifier(), softpkg->getSPDFile()); _application->setComponentImplementation(deployment->getIdentifier(), implementation->getID()); if (instantiation->isNamingService()) { std::string lookupName = _baseNamingContext + "/" + instantiation->getFindByNamingServiceName(); @@ -2050,7 +2051,8 @@ void createHelper::loadAndExecuteComponents(const DeploymentList& deployments, if (codeLocalFile.empty()) { ostringstream eout; eout << "code.localfile is empty for component: '"; - eout << component->getName() << "' with component id: '" << deployment->getIdentifier() << "' "; + eout << softpkg->getName(); + eout << "' with component id: '" << deployment->getIdentifier() << "' "; eout << " with implementation id: '" << implementation->getID() << "'"; eout << " on device id: '" << device->identifier << "'"; eout << " in waveform '" << _waveformContextName<<"'"; @@ -2075,7 +2077,7 @@ void createHelper::loadAndExecuteComponents(const DeploymentList& deployments, deployment->load(_application, _appFact._fileMgr, loadabledev); } catch (const std::exception& exc) { std::ostringstream message; - message << "Unable to load component " << component->getName() + message << "Unable to load component " << softpkg->getName() << " implementation " << implementation->getID() << " on device " << device->identifier << ": " << exc.what(); @@ -2447,7 +2449,7 @@ void createHelper::initializeComponents(const DeploymentList& deployments) continue; } - if (!component->isResource()) { + if (!deployment->isResource()) { LOG_TRACE(ApplicationFactory_impl, "Component is not a resource, continuing to next component"); continue; } @@ -2492,7 +2494,7 @@ void createHelper::initializeComponents(const DeploymentList& deployments) // call resource's initializeProperties method to handle any properties required for construction // LOG_DEBUG(ApplicationFactory_impl, "Initialize properties for component " << componentId); - if (component->isResource () && component->isConfigurable ()) { + if (deployment->isResource() && deployment->isConfigurable()) { CF::Properties partialStruct = component->containsPartialStructConstruct(); if (partialStruct.length() != 0) { ostringstream eout; @@ -2586,12 +2588,11 @@ void createHelper::configureComponents(const DeploymentList& deployments) ossie::ComponentDeployment* ac_deployment = 0; for (DeploymentList::const_iterator depl = deployments.begin(); depl != deployments.end(); ++depl) { ossie::ComponentDeployment* deployment = (*depl); - const ossie::ComponentInfo* component = deployment->getComponent(); if (!deployment->getSoftPkg()->isScaCompliant()) { // If the component is non-SCA compliant then we don't expect anything beyond this LOG_TRACE(ApplicationFactory_impl, "Skipping configure of non SCA-compliant component " << deployment->getIdentifier()); - } else if (!component->isResource()) { + } else if (!deployment->isResource()) { LOG_TRACE(ApplicationFactory_impl, "Skipping configure of non-resource component " << deployment->getIdentifier()); } else { diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index 6d4acf979..00eb2e422 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -244,6 +244,16 @@ const ComponentInstantiation* ComponentDeployment::getInstantiation() const return instantiation; } +bool ComponentDeployment::isResource() const +{ + return softpkg->getDescriptor()->isResource(); +} + +bool ComponentDeployment::isConfigurable() const +{ + return softpkg->getDescriptor()->isConfigurable(); +} + void ComponentDeployment::setAssignedDevice(const boost::shared_ptr& device) { assignedDevice = device; @@ -480,7 +490,7 @@ void PlacementPlan::addComponent(ComponentInfo* component) ComponentInfo* PlacementPlan::getComponent(const std::string& instantiationId) { for (ComponentList::iterator comp = components.begin(); comp != components.end(); ++comp) { - if (instantiationId == (*comp)->getInstantiationIdentifier()) { + if (instantiationId == (*comp)->getInstantiation()->getID()) { return *comp; } } diff --git a/redhawk/src/control/sdr/dommgr/Deployment.h b/redhawk/src/control/sdr/dommgr/Deployment.h index 0de667bee..1ef31800c 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.h +++ b/redhawk/src/control/sdr/dommgr/Deployment.h @@ -112,6 +112,9 @@ namespace ossie { const ComponentInstantiation* getInstantiation() const; + bool isResource() const; + bool isConfigurable() const; + std::string getEntryPoint(); redhawk::PropertyMap getOptions(); diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp index 128d9aae8..dac6a08f2 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp @@ -159,16 +159,6 @@ ComponentInfo::~ComponentInfo () { } -const std::string& ComponentInfo::getSpdFileName() const -{ - return spd->getSPDFile(); -} - -const std::string& ComponentInfo::getName() const -{ - return spd->getName(); -} - const ComponentInstantiation* ComponentInfo::getInstantiation() const { return instantiation; @@ -262,21 +252,6 @@ void ComponentInfo::process_overrides(CF::Properties* props, const char* id, COR return; } -const std::string& ComponentInfo::getInstantiationIdentifier() const -{ - return instantiation->getID(); -} - -bool ComponentInfo::isResource() const -{ - return spd->getDescriptor()->isResource(); -} - -bool ComponentInfo::isConfigurable() const -{ - return spd->getDescriptor()->isConfigurable(); -} - bool ComponentInfo::checkStruct(const CF::Properties &props) const { const redhawk::PropertyMap& tmpProps = redhawk::PropertyMap::cast(props); diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.h b/redhawk/src/control/sdr/dommgr/applicationSupport.h index cad608c5a..b6d942253 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.h +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.h @@ -67,9 +67,6 @@ namespace ossie ComponentInfo (const SoftPkg* softpkg, const ComponentInstantiation* instantiation); ~ComponentInfo (); - const std::string& getSpdFileName() const; - const std::string& getName() const; - const SoftPkg* spd; const ComponentInstantiation* getInstantiation() const; @@ -78,17 +75,12 @@ namespace ossie void addFactoryParameter(CF::DataType dt); void addExecParameter(CF::DataType dt); - void addDependencyProperty(std::string implId, CF::DataType dt); void addConfigureProperty(CF::DataType dt); void addConstructProperty(CF::DataType dt); void overrideProperty(const ossie::ComponentProperty* propref); void overrideProperty(const char* id, const CORBA::Any& value); - const std::string& getInstantiationIdentifier() const; - bool isResource() const; - bool isConfigurable() const; - CF::Properties containsPartialStructConfig() const; CF::Properties containsPartialStructConstruct() const; CF::Properties iteratePartialStruct(const CF::Properties &props) const; From 778586934e0f0054945e1703de1e88338d7df8af Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 25 May 2016 12:21:58 -0400 Subject: [PATCH 0291/1644] Make a clearly-named method for getting the set of properties used to perform allocations at deployment time --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 14 +++++--------- redhawk/src/control/sdr/dommgr/Deployment.cpp | 11 ++++------- redhawk/src/control/sdr/dommgr/Deployment.h | 16 ++++++++++++++-- 3 files changed, 23 insertions(+), 18 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 34da96905..cfa389c30 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -1432,13 +1432,12 @@ void createHelper::allocateComponent(ossie::ComponentDeployment* deployment, const std::string& assignedDeviceId, const std::string& appIdentifier) { - CF::Properties configureProperties = deployment->getConfigureProperties(); - ossie::corba::extend(configureProperties, deployment->getConstructProperties()); + redhawk::PropertyMap alloc_context = deployment->getAllocationContext(); // Find the devices that allocate the SPD's minimum required usesdevices properties const std::vector& usesDevVec = deployment->getSoftPkg()->getUsesDevices(); ossie::UsesDeviceDeployment assignedDevices; - if (!allocateUsesDevices(usesDevVec, configureProperties, assignedDevices, this->_allocations)) { + if (!allocateUsesDevices(usesDevVec, alloc_context, assignedDevices, this->_allocations)) { // There were unsatisfied usesdevices for the component ostringstream eout; eout << "Failed to satisfy 'usesdevice' dependencies "; @@ -1468,7 +1467,7 @@ void createHelper::allocateComponent(ossie::ComponentDeployment* deployment, ScopedAllocations implAllocations(*this->_allocationMgr); const std::vector& implUsesDevVec = implementation->getUsesDevices(); - if (!allocateUsesDevices(implUsesDevVec, configureProperties, implAssignedDevices, implAllocations)) { + if (!allocateUsesDevices(implUsesDevVec, alloc_context, implAssignedDevices, implAllocations)) { LOG_DEBUG(ApplicationFactory_impl, "Unable to satisfy 'usesdevice' dependencies for component " << deployment->getIdentifier() << " implementation " << implementation->getID()); continue; @@ -1712,7 +1711,6 @@ ossie::AllocationResult createHelper::allocateComponentToDevice(ossie::Component const std::string& assignedDeviceId, const std::string& appIdentifier) { - const ossie::ComponentInfo* component = deployment->getComponent(); const ossie::SPD::Implementation* implementation = deployment->getImplementation(); ossie::DeviceList devices = _registeredDevices; @@ -1748,10 +1746,8 @@ ossie::AllocationResult createHelper::allocateComponentToDevice(ossie::Component redhawk::PropertyMap allocationProperties; this->_castRequestProperties(allocationProperties, prop_refs); - CF::Properties configure_props = component->getConfigureProperties(); - CF::Properties construct_props = component->getConstructProperties(); - ossie::corba::extend(configure_props, construct_props); - this->_evaluateMATHinRequest(allocationProperties, configure_props); + redhawk::PropertyMap alloc_context = deployment->getAllocationContext(); + this->_evaluateMATHinRequest(allocationProperties, alloc_context); LOG_TRACE(ApplicationFactory_impl, "alloc prop size " << allocationProperties.size() ); redhawk::PropertyMap::iterator iter=allocationProperties.begin(); diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index 00eb2e422..992faf5ca 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -350,14 +350,11 @@ float ComponentDeployment::getCpuReservation() const return *cpuReservation; } -CF::Properties ComponentDeployment::getConfigureProperties() const +redhawk::PropertyMap ComponentDeployment::getAllocationContext() const { - return component->getConfigureProperties(); -} - -CF::Properties ComponentDeployment::getConstructProperties() const -{ - return component->getConstructProperties(); + redhawk::PropertyMap properties(component->getConfigureProperties()); + ossie::corba::extend(properties, component->getConstructProperties()); + return properties; } redhawk::PropertyMap ComponentDeployment::getInitialConfigureProperties() const diff --git a/redhawk/src/control/sdr/dommgr/Deployment.h b/redhawk/src/control/sdr/dommgr/Deployment.h index 1ef31800c..326fbf664 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.h +++ b/redhawk/src/control/sdr/dommgr/Deployment.h @@ -130,10 +130,22 @@ namespace ossie { bool hasCpuReservation() const; float getCpuReservation() const; - CF::Properties getConfigureProperties() const; - CF::Properties getConstructProperties() const; + /** + * Returns the properties used for evaluating math statements in + * allocation + */ + redhawk::PropertyMap getAllocationContext() const; + /** + * Returns the properties used for the initial call to configure() + * during deployment + */ redhawk::PropertyMap getInitialConfigureProperties() const; + + /** + * Returns the properties used for initializePropertes() during + * deployment + */ redhawk::PropertyMap getInitializeProperties() const; void setAssignedDevice(const boost::shared_ptr& device); From a6eb5a6f384b89274cbd6d0ef0deac614d9a5a84 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 25 May 2016 12:31:37 -0400 Subject: [PATCH 0292/1644] Move allocation context for application-wide usesdevices to a method on ApplicationDeployment --- .../control/sdr/dommgr/ApplicationFactory_impl.cpp | 6 +----- redhawk/src/control/sdr/dommgr/Deployment.cpp | 14 ++++++++++++-- redhawk/src/control/sdr/dommgr/Deployment.h | 8 +++++++- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index cfa389c30..5b386b763 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -866,11 +866,7 @@ void createHelper::_handleUsesDevices(ossie::ApplicationDeployment& appDeploymen // Get the assembly controller's configure properties for context in the // allocations - CF::Properties appProperties; - ossie::ComponentInfo* assembly_controller = appDeployment.getAssemblyController(); - if (assembly_controller) { - appProperties = assembly_controller->getConfigureProperties(); - } + CF::Properties appProperties = appDeployment.getAllocationContext(); // The device assignments for SAD-level usesdevices are never stored ossie::UsesDeviceDeployment assignedDevices; diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index 992faf5ca..1a3141001 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -543,9 +543,9 @@ ComponentInfo* ApplicationDeployment::getComponent(const std::string& instantiat return 0; } -ComponentInfo* ApplicationDeployment::getAssemblyController() +ComponentInfo* ApplicationDeployment::getAssemblyController() const { - for (PlacementList::iterator placement = placements.begin(); placement != placements.end(); ++placement) { + for (PlacementList::const_iterator placement = placements.begin(); placement != placements.end(); ++placement) { const std::vector& components = (*placement)->getComponents(); for (std::vector::const_iterator comp = components.begin(); comp != components.end(); ++comp) { if ((*comp)->getInstantiation()->isAssemblyController()) { @@ -557,6 +557,16 @@ ComponentInfo* ApplicationDeployment::getAssemblyController() return 0; } +redhawk::PropertyMap ApplicationDeployment::getAllocationContext() const +{ + redhawk::PropertyMap properties; + const ossie::ComponentInfo* assembly_controller = getAssemblyController(); + if (assembly_controller) { + properties = assembly_controller->getConfigureProperties(); + } + return properties; +} + ComponentDeployment* ApplicationDeployment::createComponentDeployment(ComponentInfo* component) { // Create a unique identifier for this component instance by appending the diff --git a/redhawk/src/control/sdr/dommgr/Deployment.h b/redhawk/src/control/sdr/dommgr/Deployment.h index 326fbf664..89fc0e860 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.h +++ b/redhawk/src/control/sdr/dommgr/Deployment.h @@ -212,7 +212,13 @@ namespace ossie { const PlacementList& getPlacements() const; - ComponentInfo* getAssemblyController(); + /** + * Returns the properties used for evaluating math statements in + * allocation + */ + redhawk::PropertyMap getAllocationContext() const; + + ComponentInfo* getAssemblyController() const; ComponentInfo* getComponent(const std::string& instantiationId); From a40ed23be1a362ae19ac0c6201be05797b2948b8 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 25 May 2016 13:31:17 -0400 Subject: [PATCH 0293/1644] Apply CPU reservations in a method on ApplicationDeployment --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 12 ++---------- redhawk/src/control/sdr/dommgr/Deployment.cpp | 17 +++++++++++++++++ redhawk/src/control/sdr/dommgr/Deployment.h | 3 +++ 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 5b386b763..fa3262936 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -1204,16 +1204,7 @@ CF::Application_ptr createHelper::create ( assignPlacementsToDevices(app_deployment, deviceAssignments); // Assign CPU reservations to components - const DeploymentList& deployments = app_deployment.getComponentDeployments(); - for (DeploymentList::const_iterator dep = deployments.begin(); dep != deployments.end(); ++dep) { - std::map::iterator reservation = specialized_reservations.find((*dep)->getIdentifier()); - if (reservation == specialized_reservations.end()) { - reservation = specialized_reservations.find((*dep)->getInstantiation()->getUsageName()); - } - if (reservation != specialized_reservations.end()) { - (*dep)->setCpuReservation(reservation->second); - } - } + app_deployment.applyCpuReservations(specialized_reservations); //////////////////////////////////////////////// // Create the Application servant @@ -1277,6 +1268,7 @@ CF::Application_ptr createHelper::create ( ossie::corba::push_back(app_devices, assignment); } + const DeploymentList& deployments = app_deployment.getComponentDeployments(); for (DeploymentList::const_iterator dep = deployments.begin(); dep != deployments.end(); ++dep) { CF::DeviceAssignmentType comp_assignment; comp_assignment.componentId = (*dep)->getIdentifier().c_str(); diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index 1a3141001..a9e4cd770 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -596,6 +596,23 @@ ComponentDeployment* ApplicationDeployment::getComponentDeployment(const std::st return 0; } +void ApplicationDeployment::applyCpuReservations(const CpuReservations& reservations) +{ + BOOST_FOREACH(ComponentDeployment* deployment, components) { + CpuReservations::const_iterator reserved = reservations.find(deployment->getIdentifier()); + if (reserved == reservations.end()) { + // NB: Check for the usage name for consistency with 2.0, although + // the instantiation ID would make more sense. In most cases, this + // is probably a moot point, since the IDE uses the same value for + // both. + reserved = reservations.find(deployment->getInstantiation()->getUsageName()); + } + if (reserved != reservations.end()) { + deployment->setCpuReservation(reserved->second); + } + } +} + CF::Resource_ptr ApplicationDeployment::lookupComponentByInstantiationId(const std::string& identifier) { ComponentDeployment* deployment = getComponentDeployment(identifier); diff --git a/redhawk/src/control/sdr/dommgr/Deployment.h b/redhawk/src/control/sdr/dommgr/Deployment.h index 89fc0e860..88f0f253c 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.h +++ b/redhawk/src/control/sdr/dommgr/Deployment.h @@ -202,6 +202,7 @@ namespace ossie { public: typedef std::vector PlacementList; typedef std::vector ComponentList; + typedef std::map CpuReservations; ApplicationDeployment(const SoftwareAssembly& sad, const std::string& instanceName); ~ApplicationDeployment(); @@ -227,6 +228,8 @@ namespace ossie { const ComponentList& getComponentDeployments(); ComponentDeployment* getComponentDeployment(const std::string& instantiationId); + void applyCpuReservations(const CpuReservations& reservations); + // Adapt interfaces for component and device search to support // ConnectionManager // ComponentLookup interface From baa2b4fd41ae0d92e03d5382467211e63ed59d44 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 25 May 2016 14:23:32 -0400 Subject: [PATCH 0294/1644] Override external properties on the ComponentDeployment instance instead of ComponentInfo --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 31 +------------ redhawk/src/control/sdr/dommgr/Deployment.cpp | 44 ++++++++++++++++--- redhawk/src/control/sdr/dommgr/Deployment.h | 9 +++- redhawk/src/control/sdr/dommgr/createHelper.h | 2 - 4 files changed, 48 insertions(+), 38 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index fa3262936..c99bf37b1 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -1178,7 +1178,7 @@ CF::Application_ptr createHelper::create ( ////////////////////////////////////////////////// // Load the components to instantiate from the SAD _appProfile.load(_appFact._fileMgr, _appFact._sadParser); - ossie::ApplicationDeployment app_deployment(_appFact._sadParser, _waveformContextName); + ossie::ApplicationDeployment app_deployment(_appFact._sadParser, _waveformContextName, modifiedInitConfiguration); getRequiredComponents(_appFact._fileMgr, _appFact._sadParser, app_deployment); ossie::ComponentInfo* assemblyControllerComponent = app_deployment.getAssemblyController(); @@ -1186,10 +1186,6 @@ CF::Application_ptr createHelper::create ( overrideProperties(modifiedInitConfiguration, assemblyControllerComponent); } - ////////////////////////////////////////////////// - // Store information about this application - overrideExternalProperties(app_deployment, modifiedInitConfiguration); - //////////////////////////////////////////////// // Assign components to devices //////////////////////////////////////////////// @@ -1326,31 +1322,6 @@ CF::Application_ptr createHelper::create ( return appObj._retn(); } -void createHelper::overrideExternalProperties(ossie::ApplicationDeployment& appDeployment, - const CF::Properties& initConfiguration) -{ - const std::vector& props = _appFact._sadParser.getExternalProperties(); - - for (unsigned int i = 0; i < initConfiguration.length(); ++i) { - for (std::vector::const_iterator prop = props.begin(); prop != props.end(); ++prop) { - std::string id; - if (prop->externalpropid == "") { - id = prop->propid; - } else { - id = prop->externalpropid; - } - - if (id == static_cast(initConfiguration[i].id)) { - ComponentInfo *comp = appDeployment.getComponent(prop->comprefid); - // Only configure on non AC components - if (comp != 0 && !comp->getInstantiation()->isAssemblyController()) { - comp->overrideProperty(prop->propid.c_str(), initConfiguration[i].value); - } - } - } - } -} - void createHelper::overrideProperties(const CF::Properties& initConfiguration, ossie::ComponentInfo* component) { // Override properties diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index a9e4cd770..dcb3abff3 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -389,12 +389,24 @@ redhawk::PropertyMap ComponentDeployment::getInitializeProperties() const return properties; } +void ComponentDeployment::overrideProperty(const std::string& id, const CORBA::Any& value) +{ + overrides[id] = value; +} + CF::DataType ComponentDeployment::getPropertyValue(const Property* property) const { - const ComponentProperty* override = getPropertyOverride(property->getID()); - if (override) { - return ossie::overridePropertyValue(property, override); + // Check for a runtime override first + redhawk::PropertyMap::const_iterator override = overrides.find(property->getID()); + if (override != overrides.end()) { + return *override; + } + // Then, check for an override in the component instantiation + const ComponentProperty* propref = getPropertyOverride(property->getID()); + if (propref) { + return ossie::overridePropertyValue(property, propref); } else { + // Default to the PRF value return ossie::convertPropertyToDataType(property); } } @@ -496,13 +508,17 @@ ComponentInfo* PlacementPlan::getComponent(const std::string& instantiationId) } -ApplicationDeployment::ApplicationDeployment(const SoftwareAssembly& sad, const std::string& instanceName) : +ApplicationDeployment::ApplicationDeployment(const SoftwareAssembly& sad, + const std::string& instanceName, + const CF::Properties& initConfiguration) : + sad(sad), // Give the application a unique identifier of the form // "softwareassemblyid:ApplicationName", where the application name // includes the serial number generated for the naming context // (e.g. "Application_1"). identifier(sad.getID() + ":" + instanceName), - instanceName(instanceName) + instanceName(instanceName), + initConfiguration(initConfiguration) { } @@ -577,6 +593,24 @@ ComponentDeployment* ApplicationDeployment::createComponentDeployment(ComponentI ComponentDeployment* deployment = new ComponentDeployment(component, instantiation, component_id); components.push_back(deployment); + // Override external properties from initial configuration + if (!instantiation->isAssemblyController()) { + BOOST_FOREACH(const SoftwareAssembly::Property& property, sad.getExternalProperties()) { + if (property.comprefid == instantiation->getID()) { + std::string property_id = property.externalpropid; + if (property_id.empty()) { + property_id = property.propid; + } + redhawk::PropertyMap::iterator override = initConfiguration.find(property_id); + if (override != initConfiguration.end()) { + RH_NL_TRACE("ApplicationFactory_impl", "Overriding external property " << property_id + << " (" << property.propid << ") = " << override->getValue().toString()); + deployment->overrideProperty(property.propid, override->getValue()); + } + } + } + } + return deployment; } diff --git a/redhawk/src/control/sdr/dommgr/Deployment.h b/redhawk/src/control/sdr/dommgr/Deployment.h index 88f0f253c..315372ff4 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.h +++ b/redhawk/src/control/sdr/dommgr/Deployment.h @@ -148,6 +148,8 @@ namespace ossie { */ redhawk::PropertyMap getInitializeProperties() const; + void overrideProperty(const std::string& id, const CORBA::Any& value); + void setAssignedDevice(const boost::shared_ptr& device); boost::shared_ptr getAssignedDevice(); @@ -168,6 +170,7 @@ namespace ossie { boost::shared_ptr assignedDevice; CF::Resource_var resource; + redhawk::PropertyMap overrides; std::string nicAssignment; ossie::optional_value cpuReservation; redhawk::PropertyMap affinityOptions; @@ -204,7 +207,9 @@ namespace ossie { typedef std::vector ComponentList; typedef std::map CpuReservations; - ApplicationDeployment(const SoftwareAssembly& sad, const std::string& instanceName); + ApplicationDeployment(const SoftwareAssembly& sad, + const std::string& instanceName, + const CF::Properties& initConfiguration); ~ApplicationDeployment(); const std::string& getIdentifier() const; @@ -242,8 +247,10 @@ namespace ossie { CF::Device_ptr lookupDeviceUsedByApplication(const std::string& usesRefId); protected: + const SoftwareAssembly& sad; const std::string identifier; const std::string instanceName; + redhawk::PropertyMap initConfiguration; PlacementList placements; ComponentList components; }; diff --git a/redhawk/src/control/sdr/dommgr/createHelper.h b/redhawk/src/control/sdr/dommgr/createHelper.h index 6ffc3f657..d272131dc 100644 --- a/redhawk/src/control/sdr/dommgr/createHelper.h +++ b/redhawk/src/control/sdr/dommgr/createHelper.h @@ -104,8 +104,6 @@ class createHelper typedef std::vector OSList; // createHelper helper methods - void overrideExternalProperties(ossie::ApplicationDeployment& appDeployment, - const CF::Properties& initConfiguration); void overrideProperties(const CF::Properties& initConfiguration, ossie::ComponentInfo* component); void assignPlacementsToDevices(ossie::ApplicationDeployment& appDeployment, const DeviceAssignmentMap& devices); From b9e5b6d3d04564faaf8f60a192c4ad190f833725 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 25 May 2016 14:34:59 -0400 Subject: [PATCH 0295/1644] Get the command line parameters from the ComponentDeployment instance instead of ComponentInfo --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 3 +-- redhawk/src/control/sdr/dommgr/Deployment.cpp | 26 +++++++++++++++++-- redhawk/src/control/sdr/dommgr/Deployment.h | 6 +++++ .../control/sdr/dommgr/applicationSupport.cpp | 22 ---------------- .../control/sdr/dommgr/applicationSupport.h | 1 - 5 files changed, 31 insertions(+), 27 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index c99bf37b1..b86ea8465 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -2142,7 +2142,6 @@ void createHelper::loadAndExecuteComponents(const DeploymentList& deployments, void createHelper::attemptComponentExecution (CF::ApplicationRegistrar_ptr registrar, ossie::ComponentDeployment* deployment) { - const ossie::ComponentInfo* component = deployment->getComponent(); const ossie::SPD::Implementation* implementation = deployment->getImplementation(); const ossie::SoftPkg* softpkg = deployment->getSoftPkg(); @@ -2157,7 +2156,7 @@ void createHelper::attemptComponentExecution (CF::ApplicationRegistrar_ptr regis } // Build up the list of command line parameters - redhawk::PropertyMap execParameters(component->getCommandLineParameters()); + redhawk::PropertyMap execParameters = deployment->getCommandLineParameters(); const std::string& nic = deployment->getNicAssignment(); if (!nic.empty()) { execParameters["NIC"] = nic; diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index dcb3abff3..91e3c8404 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -357,12 +357,12 @@ redhawk::PropertyMap ComponentDeployment::getAllocationContext() const return properties; } -redhawk::PropertyMap ComponentDeployment::getInitialConfigureProperties() const +redhawk::PropertyMap ComponentDeployment::getCommandLineParameters() const { redhawk::PropertyMap properties; if (softpkg->getProperties()) { BOOST_FOREACH(const Property* property, softpkg->getProperties()->getProperties()) { - if (property->isConfigure() && !property->isReadOnly()) { + if (property->isExecParam() || (property->isProperty() && property->isCommandLine())) { CF::DataType dt = getPropertyValue(property); if (!ossie::any::isNull(dt.value)) { properties.push_back(dt); @@ -373,6 +373,28 @@ redhawk::PropertyMap ComponentDeployment::getInitialConfigureProperties() const return properties; } +redhawk::PropertyMap ComponentDeployment::getInitialConfigureProperties() const +{ + redhawk::PropertyMap properties; + if (softpkg->getProperties()) { + BOOST_FOREACH(const Property* property, softpkg->getProperties()->getProperties()) { + if (property->isConfigure() && !property->isReadOnly()) { + CF::DataType dt = getPropertyValue(property); + if (!ossie::any::isNull(dt.value)) { + properties.push_back(dt); + } + } + } + } + + // Handle special Docker image property if set in component instantiation + const ComponentProperty* docker = getPropertyOverride("__DOCKER_IMAGE__"); + if (docker) { + properties["__DOCKER_IMAGE__"] = dynamic_cast(docker)->getValue(); + } + return properties; +} + redhawk::PropertyMap ComponentDeployment::getInitializeProperties() const { redhawk::PropertyMap properties; diff --git a/redhawk/src/control/sdr/dommgr/Deployment.h b/redhawk/src/control/sdr/dommgr/Deployment.h index 315372ff4..acfad437a 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.h +++ b/redhawk/src/control/sdr/dommgr/Deployment.h @@ -136,6 +136,12 @@ namespace ossie { */ redhawk::PropertyMap getAllocationContext() const; + /** + * Returns the properties whose values are passed on the command line + * in execute + */ + redhawk::PropertyMap getCommandLineParameters() const; + /** * Returns the properties used for the initial call to configure() * during deployment diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp index dac6a08f2..1095231f0 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp @@ -341,25 +341,3 @@ CF::Properties ComponentInfo::getExecParameters() { return execParameters; } - -CF::Properties ComponentInfo::getCommandLineParameters() const -{ - CF::Properties retval = execParameters; - while (true) { - unsigned int i; - for (i=0; ikind() == CORBA::tk_null) { - break; - } - } - if (i == retval.length()) { - break; - } - for (unsigned int j=i+1; j Date: Wed, 25 May 2016 14:38:45 -0400 Subject: [PATCH 0296/1644] Dump factory params, which have never been used --- .../src/control/sdr/dommgr/applicationSupport.cpp | 12 ------------ redhawk/src/control/sdr/dommgr/applicationSupport.h | 2 -- 2 files changed, 14 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp index 1095231f0..b301f3365 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp @@ -75,13 +75,7 @@ ComponentInfo* ComponentInfo::buildComponentInfoFromSPDFile(const SoftPkg* softp // specific PRF file if (softpkg->getProperties()) { // Handle component properties - LOG_TRACE(ComponentInfo, "Adding factory params"); Properties& prf = *softpkg->getProperties(); - const std::vector& fprop = prf.getFactoryParamProperties(); - for (unsigned int i = 0; i < fprop.size(); i++) { - newComponent->addFactoryParameter(convertPropertyToDataType(fprop[i])); - } - LOG_TRACE(ComponentInfo, "Adding exec params") const std::vector& eprop = prf.getExecParamProperties(); for (unsigned int i = 0; i < eprop.size(); i++) { @@ -185,11 +179,6 @@ void ComponentInfo::setAffinity( const AffinityProperties &affinity_props ) } -void ComponentInfo::addFactoryParameter(CF::DataType dt) -{ - addProperty(dt, factoryParameters); -} - void ComponentInfo::addExecParameter(CF::DataType dt) { addProperty(dt, execParameters); @@ -234,7 +223,6 @@ void ComponentInfo::overrideProperty(const char* id, const CORBA::Any& value) } process_overrides(&ctorProperties, id, value); process_overrides(&configureProperties, id, value); - process_overrides(&factoryParameters, id, value); process_overrides(&execParameters, id, value); } diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.h b/redhawk/src/control/sdr/dommgr/applicationSupport.h index 143d25d5e..1b872eefb 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.h +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.h @@ -73,7 +73,6 @@ namespace ossie void setAffinity( const AffinityProperties &affinity ); - void addFactoryParameter(CF::DataType dt); void addExecParameter(CF::DataType dt); void addConfigureProperty(CF::DataType dt); void addConstructProperty(CF::DataType dt); @@ -103,7 +102,6 @@ namespace ossie CF::Properties configureProperties; CF::Properties ctorProperties; - CF::Properties factoryParameters; CF::Properties execParameters; CF::Properties affinityOptions; From 55b9cf0e3adcd72b2f66d864741582577b4e09f1 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 25 May 2016 14:48:27 -0400 Subject: [PATCH 0297/1644] Remove duplicate special Docker image property handling --- .../src/control/sdr/dommgr/ApplicationFactory_impl.cpp | 9 --------- 1 file changed, 9 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index b86ea8465..3c47aaeb5 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -1841,22 +1841,13 @@ ossie::ComponentInfo* createHelper::buildComponentInfo(CF::FileSystem_ptr fileSy const ossie::ComponentPropertyList & ins_prop = instance.getProperties(); - int docker_image_idx = -1; for (unsigned int i = 0; i < ins_prop.size(); ++i) { if (ins_prop[i]._id == "__DOCKER_IMAGE__") { - docker_image_idx = i; continue; } newComponent->overrideProperty(&ins_prop[i]); } - if (docker_image_idx > -1) { - CF::Properties tmp; - redhawk::PropertyMap& tmpProp = redhawk::PropertyMap::cast(tmp); - tmpProp["__DOCKER_IMAGE__"].setValue(dynamic_cast(ins_prop[docker_image_idx]).getValue()); - newComponent->addExecParameter(tmpProp[0]); - } - return newComponent; } From 25711776ec54d7fd0b51b1e17b7d4440c226cb64 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 25 May 2016 15:11:34 -0400 Subject: [PATCH 0298/1644] Calculate allocation context at call time in ComponentDeployment; drop construct properties and specialized methods for checking partial structs from ComponentInfo --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 103 +++++++++--------- redhawk/src/control/sdr/dommgr/Deployment.cpp | 18 ++- .../control/sdr/dommgr/applicationSupport.cpp | 24 ---- .../control/sdr/dommgr/applicationSupport.h | 5 - 4 files changed, 66 insertions(+), 84 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 3c47aaeb5..f010711da 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -2440,60 +2440,57 @@ void createHelper::initializeComponents(const DeploymentList& deployments) // LOG_DEBUG(ApplicationFactory_impl, "Initialize properties for component " << componentId); if (deployment->isResource() && deployment->isConfigurable()) { - CF::Properties partialStruct = component->containsPartialStructConstruct(); - if (partialStruct.length() != 0) { - ostringstream eout; - eout << "Failed to 'configure' Assembly Controller: '"; - eout << softpkg->getName() << "' with component id: '" << deployment->getIdentifier() << " assigned to device: '"<< deployment->getAssignedDevice()->identifier << "' "; - eout << " in waveform '"<< _waveformContextName<<"';"; - eout << "This component contains structure"<getInitializeProperties(); - resource->initializeProperties(initProps); - } catch(CF::PropertySet::InvalidConfiguration& e) { - ostringstream eout; - eout << "Failed to initialize component properties: '"; - eout << softpkg->getName() << "' with component id: '" << deployment->getIdentifier() << " assigned to device: '"<getAssignedDevice()->identifier << "' "; - eout << " in waveform '"<< _waveformContextName<<"';"; - eout << "InvalidConfiguration with this info: <"; - eout << e.msg << "> for these invalid properties: "; - for (unsigned int propIdx = 0; propIdx < e.invalidProperties.length(); propIdx++){ - eout << "(" << e.invalidProperties[propIdx].id << ","; - eout << ossie::any_to_string(e.invalidProperties[propIdx].value) << ")"; + CF::Properties partialStruct = component->iteratePartialStruct(initProps); + if (partialStruct.length() != 0) { + ostringstream eout; + eout << "Failed to 'configure' Assembly Controller: '"; + eout << softpkg->getName() << "' with component id: '" << deployment->getIdentifier() << " assigned to device: '"<< deployment->getAssignedDevice()->identifier << "' "; + eout << " in waveform '"<< _waveformContextName<<"';"; + eout << "This component contains structure"<getName() << "' with component id: '" << deployment->getIdentifier() << " assigned to device: '"<getAssignedDevice()->identifier << "' "; - eout << " in waveform '"<< _waveformContextName<<"';"; - eout << "PartialConfiguration for these invalid properties: "; - for (unsigned int propIdx = 0; propIdx < e.invalidProperties.length(); propIdx++){ - eout << "(" << e.invalidProperties[propIdx].id << ","; - eout << ossie::any_to_string(e.invalidProperties[propIdx].value) << ")"; + try { + // Try to set the initial values for the component's properties + resource->initializeProperties(initProps); + } catch(CF::PropertySet::InvalidConfiguration& e) { + ostringstream eout; + eout << "Failed to initialize component properties: '"; + eout << softpkg->getName() << "' with component id: '" << deployment->getIdentifier() << " assigned to device: '"<getAssignedDevice()->identifier << "' "; + eout << " in waveform '"<< _waveformContextName<<"';"; + eout << "InvalidConfiguration with this info: <"; + eout << e.msg << "> for these invalid properties: "; + for (unsigned int propIdx = 0; propIdx < e.invalidProperties.length(); propIdx++){ + eout << "(" << e.invalidProperties[propIdx].id << ","; + eout << ossie::any_to_string(e.invalidProperties[propIdx].value) << ")"; + } + eout << " error occurred near line:" <<__LINE__ << " in file:" << __FILE__ << ";"; + LOG_ERROR(ApplicationFactory_impl, eout.str()); + throw CF::ApplicationFactory::InvalidInitConfiguration(e.invalidProperties); + } catch(CF::PropertySet::PartialConfiguration& e) { + ostringstream eout; + eout << "Failed to initialize component properties: '"; + eout << softpkg->getName() << "' with component id: '" << deployment->getIdentifier() << " assigned to device: '"<getAssignedDevice()->identifier << "' "; + eout << " in waveform '"<< _waveformContextName<<"';"; + eout << "PartialConfiguration for these invalid properties: "; + for (unsigned int propIdx = 0; propIdx < e.invalidProperties.length(); propIdx++){ + eout << "(" << e.invalidProperties[propIdx].id << ","; + eout << ossie::any_to_string(e.invalidProperties[propIdx].value) << ")"; + } + eout << " error occurred near line:" <<__LINE__ << " in file:" << __FILE__ << ";"; + LOG_ERROR(ApplicationFactory_impl, eout.str()); + throw CF::ApplicationFactory::InvalidInitConfiguration(e.invalidProperties); + } catch( ... ) { + ostringstream eout; + eout << "Failed to initialize component properties: '"; + eout << softpkg->getName() << "' with component id: '" << deployment->getIdentifier() << " assigned to device: '"<getAssignedDevice()->identifier << "' "; + eout << " in waveform '"<< _waveformContextName<<"';"; + eout << "'initializeProperties' failed with Unknown Exception"; + eout << " error occurred near line:" <<__LINE__ << " in file:" << __FILE__ << ";"; + LOG_ERROR(ApplicationFactory_impl, eout.str()); + throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EINVAL, eout.str().c_str()); } - eout << " error occurred near line:" <<__LINE__ << " in file:" << __FILE__ << ";"; - LOG_ERROR(ApplicationFactory_impl, eout.str()); - throw CF::ApplicationFactory::InvalidInitConfiguration(e.invalidProperties); - } catch( ... ) { - ostringstream eout; - std::string component_version(component->spd.getSoftPkgType()); - std::string added_message = this->createVersionMismatchMessage(component_version); - eout << added_message; - eout << "Failed to initialize component properties: '"; - eout << softpkg->getName() << "' with component id: '" << deployment->getIdentifier() << " assigned to device: '"<getAssignedDevice()->identifier << "' "; - eout << " in waveform '"<< _waveformContextName<<"';"; - eout << "'initializeProperties' failed with Unknown Exception"; - eout << " error occurred near line:" <<__LINE__ << " in file:" << __FILE__ << ";"; - LOG_ERROR(ApplicationFactory_impl, eout.str()); - throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EINVAL, eout.str().c_str()); - } } LOG_TRACE(ApplicationFactory_impl, "Initializing component " << componentId); @@ -2580,7 +2577,8 @@ void createHelper::configureComponents(const DeploymentList& deployments) throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EIO, eout.str().c_str()); } - CF::Properties partialStruct = component->containsPartialStructConfig(); + redhawk::PropertyMap config_props = deployment->getInitialConfigureProperties(); + CF::Properties partialStruct = component->iteratePartialStruct(config_props); bool partialWarn = false; if (partialStruct.length() != 0) { ostringstream eout; @@ -2590,7 +2588,6 @@ void createHelper::configureComponents(const DeploymentList& deployments) } try { // try to configure the component - redhawk::PropertyMap config_props = deployment->getInitialConfigureProperties(); _rsc->configure(config_props); } catch(CF::PropertySet::InvalidConfiguration& e) { ostringstream eout; diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index 91e3c8404..e05d8b957 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -352,8 +352,22 @@ float ComponentDeployment::getCpuReservation() const redhawk::PropertyMap ComponentDeployment::getAllocationContext() const { - redhawk::PropertyMap properties(component->getConfigureProperties()); - ossie::corba::extend(properties, component->getConstructProperties()); + redhawk::PropertyMap properties; + if (softpkg->getProperties()) { + BOOST_FOREACH(const Property* property, softpkg->getProperties()->getProperties()) { + // Old logic (2.0): + // * "configure" kind properties that are not read-only + // * "property" kind properties that are not command line (or execparams) + // New logic: + // * all "configure" and "property" kind properties + // Rationale: this is strictly used as context for math statements, + // so it doesn't matter how it gets initialized or whether it's + // writable. + if (property->isConfigure() || property->isProperty()) { + properties.push_back(getPropertyValue(property)); + } + } + } return properties; } diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp index b301f3365..c73512373 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp @@ -123,8 +123,6 @@ ComponentInfo* ComponentInfo::buildComponentInfoFromSPDFile(const SoftPkg* softp if (not cprop[i]->isNone()) { newComponent->addExecParameter(convertPropertyToDataType(cprop[i])); } - } else { - newComponent->addConstructProperty(convertPropertyToDataType(cprop[i])); } } @@ -189,11 +187,6 @@ void ComponentInfo::addConfigureProperty(CF::DataType dt) addProperty(dt, configureProperties); } -void ComponentInfo::addConstructProperty(CF::DataType dt) -{ - addProperty(dt, ctorProperties); -} - void ComponentInfo::overrideProperty(const ossie::ComponentProperty* propref) { std::string propId = propref->getID(); LOG_TRACE(ComponentInfo, "Instantiation property id = " << propId); @@ -221,7 +214,6 @@ void ComponentInfo::overrideProperty(const char* id, const CORBA::Any& value) return; } } - process_overrides(&ctorProperties, id, value); process_overrides(&configureProperties, id, value); process_overrides(&execParameters, id, value); } @@ -298,16 +290,6 @@ CF::Properties ComponentInfo::iteratePartialStruct(const CF::Properties &props) return retval; } -CF::Properties ComponentInfo::containsPartialStructConfig() const -{ - return this->iteratePartialStruct(configureProperties); -} - -CF::Properties ComponentInfo::containsPartialStructConstruct() const -{ - return this->iteratePartialStruct(ctorProperties); -} - CF::Properties ComponentInfo::getAffinityOptions() const { return affinityOptions; @@ -319,12 +301,6 @@ CF::Properties ComponentInfo::getConfigureProperties() const } -CF::Properties ComponentInfo::getConstructProperties() const -{ - return ctorProperties; -} - - CF::Properties ComponentInfo::getExecParameters() { return execParameters; diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.h b/redhawk/src/control/sdr/dommgr/applicationSupport.h index 1b872eefb..e7c5f969b 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.h +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.h @@ -75,18 +75,14 @@ namespace ossie void addExecParameter(CF::DataType dt); void addConfigureProperty(CF::DataType dt); - void addConstructProperty(CF::DataType dt); void overrideProperty(const ossie::ComponentProperty* propref); void overrideProperty(const char* id, const CORBA::Any& value); - CF::Properties containsPartialStructConfig() const; - CF::Properties containsPartialStructConstruct() const; CF::Properties iteratePartialStruct(const CF::Properties &props) const; bool checkStruct(const CF::Properties &props) const; CF::Properties getConfigureProperties() const; - CF::Properties getConstructProperties() const; CF::Properties getAffinityOptions() const; CF::Properties getExecParameters(); @@ -101,7 +97,6 @@ namespace ossie ossie::Properties _affinity_prf; CF::Properties configureProperties; - CF::Properties ctorProperties; CF::Properties execParameters; CF::Properties affinityOptions; From b65191755cc69066c8363c6216c04fef73be1ebb Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 25 May 2016 16:45:49 -0400 Subject: [PATCH 0299/1644] Move checks for partial structs into prop_utils --- redhawk/src/control/framework/prop_utils.cpp | 46 ++++++++++++++- .../src/control/include/ossie/prop_utils.h | 2 + .../sdr/dommgr/ApplicationFactory_impl.cpp | 6 +- .../control/sdr/dommgr/applicationSupport.cpp | 58 ------------------- .../control/sdr/dommgr/applicationSupport.h | 3 - 5 files changed, 49 insertions(+), 66 deletions(-) diff --git a/redhawk/src/control/framework/prop_utils.cpp b/redhawk/src/control/framework/prop_utils.cpp index f6febe25a..75ea1309d 100644 --- a/redhawk/src/control/framework/prop_utils.cpp +++ b/redhawk/src/control/framework/prop_utils.cpp @@ -31,6 +31,7 @@ #include #include #include +#include using namespace ossie; @@ -658,4 +659,47 @@ std::string ossie::retrieveParserErrorLineNumber(std::string message) { ret_message += "."; } return ret_message; -}; +} + +bool ossie::structContainsMixedNilValues(const CF::Properties& properties) +{ + const redhawk::PropertyMap& fields = redhawk::PropertyMap::cast(properties); + bool nils = false; + bool values = false; + for (redhawk::PropertyMap::const_iterator prop = fields.begin(); prop != fields.end(); ++prop) { + if (prop->getValue().isNil()) { + nils = true; + } else { + values = true; + } + if (nils && values) { + return true; + } + } + return false; +} + +CF::Properties ossie::getPartialStructs(const CF::Properties& properties) +{ + CF::Properties partials; + const redhawk::PropertyMap& configProps = redhawk::PropertyMap::cast(properties); + for (redhawk::PropertyMap::const_iterator prop = configProps.begin(); prop != configProps.end(); ++prop) { + CORBA::TypeCode_var type = prop->getValue().type(); + if (CORBA::_tc_AnySeq->equivalent(type)) { + const redhawk::ValueSequence& sequence = prop->getValue().asSequence(); + for (redhawk::ValueSequence::const_iterator item = sequence.begin(); item != sequence.end(); ++item) { + type = item->type(); + if (CF::_tc_Properties->equivalent(type)) { + if (ossie::structContainsMixedNilValues(item->asProperties())) { + ossie::corba::push_back(partials, *prop); + } + } + } + } else if (CF::_tc_Properties->equivalent(type)) { + if (ossie::structContainsMixedNilValues(prop->getValue().asProperties())) { + ossie::corba::push_back(partials, *prop); + } + } + } + return partials; +} diff --git a/redhawk/src/control/include/ossie/prop_utils.h b/redhawk/src/control/include/ossie/prop_utils.h index 05474cd92..f32c90ec6 100644 --- a/redhawk/src/control/include/ossie/prop_utils.h +++ b/redhawk/src/control/include/ossie/prop_utils.h @@ -76,6 +76,8 @@ namespace ossie std::string retrieveParserErrorLineNumber(std::string message); + bool structContainsMixedNilValues(const CF::Properties& properties); + CF::Properties getPartialStructs(const CF::Properties& properties); } #endif diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index f010711da..8fc0e2504 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -2386,7 +2386,6 @@ void createHelper::initializeComponents(const DeploymentList& deployments) for (unsigned int rc_idx = 0; rc_idx < deployments.size (); rc_idx++) { ossie::ComponentDeployment* deployment = deployments[rc_idx]; const ossie::SoftPkg* softpkg = deployment->getSoftPkg(); - const ossie::ComponentInfo* component = deployment->getComponent(); // If the component is non-SCA compliant then we don't expect anything beyond this if (!softpkg->isScaCompliant()) { @@ -2441,7 +2440,7 @@ void createHelper::initializeComponents(const DeploymentList& deployments) LOG_DEBUG(ApplicationFactory_impl, "Initialize properties for component " << componentId); if (deployment->isResource() && deployment->isConfigurable()) { redhawk::PropertyMap initProps = deployment->getInitializeProperties(); - CF::Properties partialStruct = component->iteratePartialStruct(initProps); + CF::Properties partialStruct = ossie::getPartialStructs(initProps); if (partialStruct.length() != 0) { ostringstream eout; eout << "Failed to 'configure' Assembly Controller: '"; @@ -2555,7 +2554,6 @@ void createHelper::configureComponents(const DeploymentList& deployments) for (DeploymentList::iterator depl = configure_list.begin(); depl != configure_list.end(); ++depl) { ossie::ComponentDeployment* deployment = *depl; const ossie::SoftPkg* softpkg = deployment->getSoftPkg(); - const ossie::ComponentInfo* component = deployment->getComponent(); // Assuming 1 instantiation for each componentplacement if (deployment->getInstantiation()->isNamingService()) { @@ -2578,7 +2576,7 @@ void createHelper::configureComponents(const DeploymentList& deployments) } redhawk::PropertyMap config_props = deployment->getInitialConfigureProperties(); - CF::Properties partialStruct = component->iteratePartialStruct(config_props); + CF::Properties partialStruct = ossie::getPartialStructs(config_props); bool partialWarn = false; if (partialStruct.length() != 0) { ostringstream eout; diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp index c73512373..0af541c6e 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp @@ -232,64 +232,6 @@ void ComponentInfo::process_overrides(CF::Properties* props, const char* id, COR return; } -bool ComponentInfo::checkStruct(const CF::Properties &props) const -{ - const redhawk::PropertyMap& tmpProps = redhawk::PropertyMap::cast(props); - int state = 0; // 1 set, -1 nil - for (redhawk::PropertyMap::const_iterator tmpP = tmpProps.begin(); tmpP != tmpProps.end(); tmpP++) { - if (tmpProps[ossie::corba::returnString(tmpP->id)].isNil()) { - if (state == 0) { - state = -1; - } else { - if (state == 1) { - return true; - } - } - } else { - if (state == 0) { - state = 1; - } else { - if (state == -1) { - return true; - } - } - } - } - return false; -} - -CF::Properties ComponentInfo::iteratePartialStruct(const CF::Properties &props) const -{ - CF::Properties retval; - const redhawk::PropertyMap& configProps = redhawk::PropertyMap::cast(props); - for (redhawk::PropertyMap::const_iterator cP = configProps.begin(); cP != configProps.end(); cP++) { - const ossie::Property* prop = spd->getProperties()->getProperty(ossie::corba::returnString(cP->id)); - if (dynamic_cast(prop)) { - CF::Properties* tmp; - if (!(cP->value >>= tmp)) - continue; - if (this->checkStruct(*tmp)) - return *tmp; - } else if (dynamic_cast(prop)) { - CORBA::AnySeq* anySeqPtr; - if (!(cP->value >>= anySeqPtr)) { - continue; - } - CORBA::AnySeq& anySeq = *anySeqPtr; - for (CORBA::ULong ii = 0; ii < anySeq.length(); ++ii) { - CF::Properties* tmp; - if (!(anySeq[ii] >>= tmp)) - continue; - if (this->checkStruct(*tmp)) - return *tmp; - } - } else { - continue; - } - } - return retval; -} - CF::Properties ComponentInfo::getAffinityOptions() const { return affinityOptions; diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.h b/redhawk/src/control/sdr/dommgr/applicationSupport.h index e7c5f969b..6f66da6f2 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.h +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.h @@ -79,9 +79,6 @@ namespace ossie void overrideProperty(const ossie::ComponentProperty* propref); void overrideProperty(const char* id, const CORBA::Any& value); - CF::Properties iteratePartialStruct(const CF::Properties &props) const; - bool checkStruct(const CF::Properties &props) const; - CF::Properties getConfigureProperties() const; CF::Properties getAffinityOptions() const; CF::Properties getExecParameters(); From 69a01a9bf25db7388889f1e4ffddcacd00d3e78c Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 26 May 2016 09:03:26 -0400 Subject: [PATCH 0300/1644] Override assembly controller properties in ComponentDeployment --- redhawk/src/control/sdr/dommgr/Deployment.cpp | 54 +++++++++++++------ redhawk/src/control/sdr/dommgr/Deployment.h | 3 ++ 2 files changed, 41 insertions(+), 16 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index e05d8b957..d1f1724f5 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -629,22 +629,11 @@ ComponentDeployment* ApplicationDeployment::createComponentDeployment(ComponentI ComponentDeployment* deployment = new ComponentDeployment(component, instantiation, component_id); components.push_back(deployment); - // Override external properties from initial configuration - if (!instantiation->isAssemblyController()) { - BOOST_FOREACH(const SoftwareAssembly::Property& property, sad.getExternalProperties()) { - if (property.comprefid == instantiation->getID()) { - std::string property_id = property.externalpropid; - if (property_id.empty()) { - property_id = property.propid; - } - redhawk::PropertyMap::iterator override = initConfiguration.find(property_id); - if (override != initConfiguration.end()) { - RH_NL_TRACE("ApplicationFactory_impl", "Overriding external property " << property_id - << " (" << property.propid << ") = " << override->getValue().toString()); - deployment->overrideProperty(property.propid, override->getValue()); - } - } - } + // Override properties from initial configuration + if (instantiation->isAssemblyController()) { + overrideAssemblyControllerProperties(deployment); + } else { + overrideExternalProperties(deployment); } return deployment; @@ -683,6 +672,39 @@ void ApplicationDeployment::applyCpuReservations(const CpuReservations& reservat } } +void ApplicationDeployment::overrideAssemblyControllerProperties(ComponentDeployment* deployment) +{ + BOOST_FOREACH(const redhawk::PropertyType& override, initConfiguration) { + if (override.getId() == "LOGGING_CONFIG_URI") { + // TODO: Handle logging configuration + } else { + RH_NL_TRACE("ApplicationFactory_impl", "Overriding property " << override.id + << " with " << override.getValue().toString()); + deployment->overrideProperty(override.getId(), override.getValue()); + } + } +} + +void ApplicationDeployment::overrideExternalProperties(ComponentDeployment* deployment) +{ + const std::string& instantiation_id = deployment->getInstantiation()->getID(); + BOOST_FOREACH(const SoftwareAssembly::Property& property, sad.getExternalProperties()) { + if (property.comprefid == instantiation_id) { + std::string property_id = property.externalpropid; + if (property_id.empty()) { + property_id = property.propid; + } + redhawk::PropertyMap::iterator override = initConfiguration.find(property_id); + if (override != initConfiguration.end()) { + RH_NL_TRACE("ApplicationFactory_impl", "Overriding external property " << property_id + << " (" << property.propid << ") = " << override->getValue().toString()); + deployment->overrideProperty(property.propid, override->getValue()); + } + } + } +} + + CF::Resource_ptr ApplicationDeployment::lookupComponentByInstantiationId(const std::string& identifier) { ComponentDeployment* deployment = getComponentDeployment(identifier); diff --git a/redhawk/src/control/sdr/dommgr/Deployment.h b/redhawk/src/control/sdr/dommgr/Deployment.h index acfad437a..304f6b640 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.h +++ b/redhawk/src/control/sdr/dommgr/Deployment.h @@ -253,6 +253,9 @@ namespace ossie { CF::Device_ptr lookupDeviceUsedByApplication(const std::string& usesRefId); protected: + void overrideAssemblyControllerProperties(ComponentDeployment* deployment); + void overrideExternalProperties(ComponentDeployment* deployment); + const SoftwareAssembly& sad; const std::string identifier; const std::string instanceName; From b60a775b04f1c6e9b9094623784be7eca97f7b10 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 26 May 2016 09:16:24 -0400 Subject: [PATCH 0301/1644] Don't override read-only execparams (which raises the question of why bother having one, but that's how it's always worked) --- redhawk/src/control/sdr/dommgr/Deployment.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index d1f1724f5..5861a146c 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -376,11 +376,18 @@ redhawk::PropertyMap ComponentDeployment::getCommandLineParameters() const redhawk::PropertyMap properties; if (softpkg->getProperties()) { BOOST_FOREACH(const Property* property, softpkg->getProperties()->getProperties()) { - if (property->isExecParam() || (property->isProperty() && property->isCommandLine())) { - CF::DataType dt = getPropertyValue(property); - if (!ossie::any::isNull(dt.value)) { - properties.push_back(dt); + if (property->isExecParam()) { + if (property->isReadOnly()) { + RH_NL_WARN("ApplicationFactory_impl", "Ignoring attempt to override readonly property " + << property->getID()); + continue; } + } else if (!(property->isProperty() && property->isCommandLine())) { + continue; + } + CF::DataType dt = getPropertyValue(property); + if (!ossie::any::isNull(dt.value)) { + properties.push_back(dt); } } } From 2e2fed368081fa673c6a77051b4352082d52c5d2 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 26 May 2016 10:19:08 -0400 Subject: [PATCH 0302/1644] Change property parsers to use bools for complex, commandline and optional, since they are notionally boolean --- .../src/control/include/ossie/Properties.h | 68 +++------ redhawk/src/control/parser/Properties.cpp | 142 ++++++------------ .../src/control/parser/internal/prf-pimpl.cpp | 55 ++++--- .../src/control/parser/internal/prf-pimpl.h | 26 ++-- redhawk/src/control/parser/internal/prf.map | 6 +- 5 files changed, 110 insertions(+), 187 deletions(-) diff --git a/redhawk/src/control/include/ossie/Properties.h b/redhawk/src/control/include/ossie/Properties.h index 6da7d8b5b..da9f16d13 100644 --- a/redhawk/src/control/include/ossie/Properties.h +++ b/redhawk/src/control/include/ossie/Properties.h @@ -57,13 +57,6 @@ namespace ossie { const std::string& action, const std::vector& kinds); - Property(const std::string& id, - const std::string& name, - const std::string& mode, - const std::string& action, - const std::vector& kinds, - const std::string& cmdline ); - virtual ~Property(); bool isReadOnly() const; @@ -73,7 +66,7 @@ namespace ossie { bool isConfigure() const; bool isProperty() const; bool isTest() const; - bool isCommandLine() const; + virtual bool isCommandLine() const; bool isExecParam() const; bool isFactoryParam() const; bool isEqual() const; @@ -104,8 +97,6 @@ namespace ossie { std::string mode; std::string action; std::vector kinds; - std::string commandline; - // Pure virtual functions virtual void override(const Property* otherProp) = 0; @@ -124,23 +115,15 @@ namespace ossie { SimpleProperty() {} SimpleProperty(const std::string& id, - const std::string& name, - const std::string& type, - const std::string& mode, - const std::string& action, - const std::vector& kinds, - const optional_value& value, - const std::string& complex_, - const std::string& commandline, - const std::string& optional); - - SimpleProperty(const std::string& id, - const std::string& name, - const std::string& type, - const std::string& mode, - const std::string& action, - const std::vector& kinds, - const optional_value& value); + const std::string& name, + const std::string& type, + const std::string& mode, + const std::string& action, + const std::vector& kinds, + const optional_value& value, + bool complex=false, + bool commandline=false, + bool optional=false); virtual ~SimpleProperty(); @@ -148,13 +131,13 @@ namespace ossie { const char* getValue() const; // Implementation of virtual functions + virtual bool isCommandLine() const; virtual bool isNone() const; virtual const std::string asString() const; virtual const Property* clone() const; const char* getType() const; - const char* getComplex() const; - const char* getCommandLine() const; - const char* getOptional() const; + bool isComplex() const; + bool isOptional() const; protected: virtual void override(const Property* otherProp); @@ -163,8 +146,9 @@ namespace ossie { private: std::string type; optional_value value; - std::string _complex; - std::string optional; + bool complex; + bool commandline; + bool optional; }; /* @@ -185,16 +169,8 @@ namespace ossie { const std::string& action, const std::vector& kinds, const std::vector& values, - const std::string& complex_, - const std::string& optional); - - SimpleSequenceProperty(const std::string& id, - const std::string& name, - const std::string& type, - const std::string& mode, - const std::string& action, - const std::vector& kinds, - const std::vector& values); + bool complex=false, + bool optional=false); virtual ~SimpleSequenceProperty(); @@ -204,8 +180,8 @@ namespace ossie { virtual const std::string asString() const; virtual const Property* clone() const; const char* getType() const; - const char* getComplex() const; - const char* getOptional() const; + bool isComplex() const; + bool isOptional() const; protected: virtual void override(const Property* otherProp); @@ -214,8 +190,8 @@ namespace ossie { private: std::string type; std::vector values; - std::string _complex; - std::string optional; + bool complex; + bool optional; }; /* diff --git a/redhawk/src/control/parser/Properties.cpp b/redhawk/src/control/parser/Properties.cpp index 175abdc0b..81f5e7056 100644 --- a/redhawk/src/control/parser/Properties.cpp +++ b/redhawk/src/control/parser/Properties.cpp @@ -241,24 +241,18 @@ const std::vector& Properties::getFactoryParamProperties() cons * Property class */ -Property::Property(const std::string& id, - const std::string& name, - const std::string& mode, - const std::string& action, - const std::vector& kinds) : - id(id), name(name), mode(mode), action(action), kinds(kinds), - commandline("false") -{}; - Property::Property(const std::string& id, const std::string& name, const std::string& mode, const std::string& action, - const std::vector& kinds, - const std::string& cmdline ): - id(id), name(name), mode(mode), action(action), kinds(kinds), - commandline(cmdline) -{}; + const std::vector& kinds): + id(id), + name(name), + mode(mode), + action(action), + kinds(kinds) +{ +} Property::~Property() { @@ -372,7 +366,7 @@ bool Property::isReadOnly() const bool Property::isCommandLine() const { - return (commandline == "true"); + return false; } bool Property::isReadWrite() const @@ -468,16 +462,16 @@ SimpleProperty::SimpleProperty(const std::string& id, const std::string& action, const std::vector& kinds, const optional_value& value, - const std::string& complex_, - const std::string& commandline_, - const std::string& optional) : - Property(id, name, mode, action, kinds, commandline_ ), + bool complex, + bool commandline, + bool optional) : + Property(id, name, mode, action, kinds), value(value), - _complex(complex_), + complex(complex), + commandline(commandline), optional(optional) { - commandline = commandline_; - if (_complex.compare("true") == 0) { + if (complex) { /* * Downstream processing expects complex types * (e.g., complexLong) rather than primitive @@ -493,27 +487,16 @@ SimpleProperty::SimpleProperty(const std::string& id, } } -/* - * A constructor that does not require the specification of - * whether or not the property is complex. If complexity - * is not specified, the property is assumed to be primitive. - */ -SimpleProperty::SimpleProperty(const std::string& id, - const std::string& name, - const std::string& type, - const std::string& mode, - const std::string& action, - const std::vector& kinds, - const optional_value& value) +SimpleProperty::~SimpleProperty() { - SimpleProperty(id, name, type, mode, action, kinds, value, "false", "false", "false"); } -SimpleProperty::~SimpleProperty() + +bool SimpleProperty::isCommandLine() const { + return commandline; } - bool SimpleProperty::isNone() const { return !value.isSet(); } @@ -541,19 +524,14 @@ const char* SimpleProperty::getType() const return type.c_str(); } -const char* SimpleProperty::getComplex() const -{ - return _complex.c_str(); -} - -const char* SimpleProperty::getCommandLine() const +bool SimpleProperty::isComplex() const { - return commandline.c_str(); + return complex; } -const char* SimpleProperty::getOptional() const +bool SimpleProperty::isOptional() const { - return optional.c_str(); + return optional; } const char* SimpleProperty::getValue() const @@ -580,30 +558,29 @@ const std::string SimpleProperty::asString() const { } const Property* SimpleProperty::clone() const { - return new SimpleProperty(id, name, type, mode, action, kinds, value, _complex, commandline, optional); + return new SimpleProperty(id, name, type, mode, action, kinds, value, complex, commandline, optional); } /* * SimpleSequenceProperty class */ -SimpleSequenceProperty::SimpleSequenceProperty( - const std::string& id, - const std::string& name, - const std::string& type, - const std::string& mode, - const std::string& action, - const std::vector& kinds, - const std::vector& values, - const std::string& complex_, - const std::string& optional) : - Property(id, name, mode, action, kinds), - type(type), - values(values), - _complex(complex_), - optional(optional) -{ - if (_complex.compare("true") == 0) { +SimpleSequenceProperty::SimpleSequenceProperty(const std::string& id, + const std::string& name, + const std::string& type, + const std::string& mode, + const std::string& action, + const std::vector& kinds, + const std::vector& values, + bool complex, + bool optional) : + Property(id, name, mode, action, kinds), + type(type), + values(values), + complex(complex), + optional(optional) +{ + if (complex) { /* * Downstream processing expects complex types * (e.g., complexLong) rather than primitive @@ -615,31 +592,6 @@ SimpleSequenceProperty::SimpleSequenceProperty( } } -/* - * A constructor that does not require the specification of - * whether or not the property is complex. If complexity - * is not specified, the property is assumed to be primitive. - */ -SimpleSequenceProperty::SimpleSequenceProperty( - const std::string& id, - const std::string& name, - const std::string& type, - const std::string& mode, - const std::string& action, - const std::vector& kinds, - const std::vector& values) -{ - SimpleSequenceProperty(id, - name, - type, - mode, - action, - kinds, - values, - "false", - "false"); -} - SimpleSequenceProperty::~SimpleSequenceProperty() { } @@ -672,14 +624,14 @@ const char* SimpleSequenceProperty::getType() const return type.c_str(); } -const char* SimpleSequenceProperty::getComplex() const +bool SimpleSequenceProperty::isComplex() const { - return _complex.c_str(); + return complex; } -const char* SimpleSequenceProperty::getOptional() const +bool SimpleSequenceProperty::isOptional() const { - return optional.c_str(); + return optional; } const std::vector& SimpleSequenceProperty::getValues() const @@ -698,7 +650,7 @@ const std::string SimpleSequenceProperty::asString() const { } const Property* SimpleSequenceProperty::clone() const { - return new SimpleSequenceProperty(id, name, type, mode, action, kinds, values, _complex, optional); + return new SimpleSequenceProperty(id, name, type, mode, action, kinds, values, complex, optional); } /* @@ -719,7 +671,6 @@ StructProperty& StructProperty::operator=(const StructProperty& src) id = src.id; name =src.name; mode=src.mode; - commandline = src.commandline; action=src.action; kinds=src.kinds; /// clean out my old... @@ -803,7 +754,6 @@ StructSequenceProperty& StructSequenceProperty::operator=( const StructSequenceP id = src.id; name =src.name; mode=src.mode; - commandline = src.commandline; action=src.action; kinds=src.kinds; structdef = src.structdef; diff --git a/redhawk/src/control/parser/internal/prf-pimpl.cpp b/redhawk/src/control/parser/internal/prf-pimpl.cpp index 3022a6f86..9ffbe5dd2 100644 --- a/redhawk/src/control/parser/internal/prf-pimpl.cpp +++ b/redhawk/src/control/parser/internal/prf-pimpl.cpp @@ -70,11 +70,10 @@ pre () { } -::std::string IsComplex_pimpl:: +bool IsComplex_pimpl:: post_IsComplex () { - const ::std::string& v (post_string ()); - return v; + return post_string() == "true"; } // IsCommandLine_pimpl @@ -85,11 +84,10 @@ pre () { } -::std::string IsCommandLine_pimpl:: +bool IsCommandLine_pimpl:: post_IsCommandLine () { - const ::std::string& v (post_string ()); - return v; + return post_string() == "true"; } // IsOptional_pimpl @@ -100,11 +98,10 @@ pre () { } -::std::string IsOptional_pimpl:: +bool IsOptional_pimpl:: post_IsOptional () { - const ::std::string& v (post_string ()); - return v; + return post_string() == "true"; } // action_pimpl @@ -401,11 +398,11 @@ pre () _id = ""; _name = ""; _type = ""; - _complex = ""; + _complex = false; _mode = ""; _action = ""; - _optional = ""; - _commandline = ""; + _optional = false; + _commandline = false; _kinds.clear(); _value.reset(); @@ -482,23 +479,23 @@ type (const ::std::string& type) } void simple_pimpl:: -complex (const ::std::string& complex_) +complex (bool complex) { - LOG_TRACE(prf_parser, "simple_pimpl complex " << complex_) - _complex = complex_; + LOG_TRACE(prf_parser, "simple_pimpl complex " << complex) + _complex = complex; } void simple_pimpl:: -optional (const ::std::string& optional) +optional (bool optional) { LOG_TRACE(prf_parser, "simple_pimpl optional " << optional) _optional = optional; } void simple_pimpl:: -commandline (const ::std::string& commandline) +commandline (bool commandline) { - LOG_TRACE(prf_parser, "simple_pimpl _commandline " << _commandline) + LOG_TRACE(prf_parser, "simple_pimpl commandline " << commandline) _commandline = commandline; } @@ -579,10 +576,10 @@ pre () _id = ""; _name = ""; _type = ""; - _complex = ""; + _complex = false; _mode = ""; _action = ""; - _optional = ""; + _optional = false; _kinds.clear(); _values.clear(); @@ -658,14 +655,14 @@ type (const ::std::string& type) } void simpleSequence_pimpl:: -complex (const ::std::string& complex_) +complex (bool complex) { - LOG_TRACE(prf_parser, "simpleSequence_pimpl complex " << complex_) - _complex = complex_; + LOG_TRACE(prf_parser, "simpleSequence_pimpl complex " << complex) + _complex = complex; } void simpleSequence_pimpl:: -optional (const ::std::string& optional) +optional (bool optional) { LOG_TRACE(prf_parser, "simpleSequence_pimpl optional " << optional) _optional = optional; @@ -807,9 +804,9 @@ structvalue (const ossie::ComponentPropertyMap& value) simp->getAction(), simp->getKinds(), val, - simp->getComplex(), - simp->getCommandLine(), - simp->getOptional()); + simp->isComplex(), + simp->isCommandLine(), + simp->isOptional()); rmprops.push_back(p); } else if (dynamic_cast(*prop) != NULL) { @@ -822,8 +819,8 @@ structvalue (const ossie::ComponentPropertyMap& value) simpseq->getAction(), simpseq->getKinds(), vals, - simpseq->getComplex(), - simpseq->getOptional()); + simpseq->isComplex(), + simpseq->isOptional()); rmprops.push_back(p); } else { p = *prop; diff --git a/redhawk/src/control/parser/internal/prf-pimpl.h b/redhawk/src/control/parser/internal/prf-pimpl.h index b3a7d5bab..a794f49ba 100644 --- a/redhawk/src/control/parser/internal/prf-pimpl.h +++ b/redhawk/src/control/parser/internal/prf-pimpl.h @@ -60,7 +60,7 @@ namespace prf virtual void pre (); - virtual ::std::string + virtual bool post_IsComplex (); }; @@ -71,7 +71,7 @@ namespace prf virtual void pre (); - virtual ::std::string + virtual bool post_IsCommandLine (); }; @@ -82,7 +82,7 @@ namespace prf virtual void pre (); - virtual ::std::string + virtual bool post_IsOptional (); }; @@ -322,13 +322,13 @@ namespace prf type (const ::std::string&); virtual void - complex (const ::std::string&); + complex (bool); virtual void - commandline (const ::std::string&); + commandline (bool); virtual void - optional (const ::std::string&); + optional (bool); virtual const ossie::SimpleProperty& post_simple (); @@ -337,11 +337,11 @@ namespace prf std::string _id; std::string _name; std::string _type; - std::string _complex; + bool _complex; std::string _mode; std::string _action; - std::string _commandline; - std::string _optional; + bool _commandline; + bool _optional; std::vector _kinds; std::auto_ptr _value; ossie::SimpleProperty _prop; @@ -422,10 +422,10 @@ namespace prf type (const ::std::string&); virtual void - complex (const ::std::string&); + complex (bool); virtual void - optional (const ::std::string&); + optional (bool); virtual const ossie::SimpleSequenceProperty& post_simpleSequence (); @@ -434,10 +434,10 @@ namespace prf std::string _id; std::string _name; std::string _type; - std::string _complex; + bool _complex; std::string _mode; std::string _action; - std::string _optional; + bool _optional; std::vector _kinds; std::vector _values; ossie::SimpleSequenceProperty _prop; diff --git a/redhawk/src/control/parser/internal/prf.map b/redhawk/src/control/parser/internal/prf.map index 76f077e49..fcfde8a4b 100644 --- a/redhawk/src/control/parser/internal/prf.map +++ b/redhawk/src/control/parser/internal/prf.map @@ -42,9 +42,9 @@ namespace urn:mil:jpeojtrs:sca:prf { PropertyValueType "::std::string"; AccessType "::std::string"; ActionType "::std::string"; - IsComplex "::std::string"; - IsCommandLine "::std::string"; - IsOptional "::std::string"; + IsComplex "bool"; + IsCommandLine "bool"; + IsOptional "bool"; Unit "::std::string"; PropertyConfigurationType "::std::string"; configurationKind "::std::string"; From 37ceda8f3f195ce94f6a95c93e532a5cefca7457 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 26 May 2016 11:00:20 -0400 Subject: [PATCH 0303/1644] Use copy constructor in property clone; defer to base class operator= --- redhawk/src/control/parser/Properties.cpp | 25 ++++++++--------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/redhawk/src/control/parser/Properties.cpp b/redhawk/src/control/parser/Properties.cpp index 81f5e7056..8400c8e19 100644 --- a/redhawk/src/control/parser/Properties.cpp +++ b/redhawk/src/control/parser/Properties.cpp @@ -558,7 +558,7 @@ const std::string SimpleProperty::asString() const { } const Property* SimpleProperty::clone() const { - return new SimpleProperty(id, name, type, mode, action, kinds, value, complex, commandline, optional); + return new SimpleProperty(*this); } @@ -650,7 +650,7 @@ const std::string SimpleSequenceProperty::asString() const { } const Property* SimpleSequenceProperty::clone() const { - return new SimpleSequenceProperty(id, name, type, mode, action, kinds, values, complex, optional); + return new SimpleSequenceProperty(*this); } /* @@ -668,11 +668,8 @@ StructProperty::~StructProperty() StructProperty& StructProperty::operator=(const StructProperty& src) { - id = src.id; - name =src.name; - mode=src.mode; - action=src.action; - kinds=src.kinds; + Property::operator=(src); + /// clean out my old... std::vector::iterator i; for (i = value.begin(); i != value.end(); ++i) { @@ -749,16 +746,12 @@ StructSequenceProperty::~StructSequenceProperty() { } -StructSequenceProperty& StructSequenceProperty::operator=( const StructSequenceProperty &src ) +StructSequenceProperty& StructSequenceProperty::operator=(const StructSequenceProperty& src) { - id = src.id; - name =src.name; - mode=src.mode; - action=src.action; - kinds=src.kinds; - structdef = src.structdef; - values = values; - return *this; + Property::operator=(src); + structdef = src.structdef; + values = values; + return *this; } From 225ed5530dbd4c6073484fa257a1d8708f583274 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 26 May 2016 11:00:48 -0400 Subject: [PATCH 0304/1644] Use new SimpleProperty constructor in nodeBooter --- redhawk/src/control/framework/nodebooter.cpp | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/redhawk/src/control/framework/nodebooter.cpp b/redhawk/src/control/framework/nodebooter.cpp index 1a65b5a38..0a8f30829 100644 --- a/redhawk/src/control/framework/nodebooter.cpp +++ b/redhawk/src/control/framework/nodebooter.cpp @@ -1153,20 +1153,14 @@ int main(int argc, char* argv[]) "readonly", "eq", kinds, - std::string(un.sysname), - "false", - "false", - "false"); + std::string(un.sysname)); ossie::SimpleProperty procProp("DCE:fefb9c66-d14a-438d-ad59-2cfd1adb272b", "processor_name", "string", "readonly", "eq", kinds, - std::string(un.machine), - "false", - "false", - "false"); + std::string(un.machine)); std::vector systemProps; systemProps.push_back(&osProp); systemProps.push_back(&procProp); From 781993d274191a0eef4a061c9d5b5ba0f9a73417 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 26 May 2016 12:50:53 -0400 Subject: [PATCH 0305/1644] Use compiler-generated copy constructor and assignment --- redhawk/src/control/include/ossie/Properties.h | 15 +++------------ redhawk/src/control/parser/Properties.cpp | 9 --------- 2 files changed, 3 insertions(+), 21 deletions(-) diff --git a/redhawk/src/control/include/ossie/Properties.h b/redhawk/src/control/include/ossie/Properties.h index da9f16d13..4947be95b 100644 --- a/redhawk/src/control/include/ossie/Properties.h +++ b/redhawk/src/control/include/ossie/Properties.h @@ -225,14 +225,14 @@ namespace ossie { const ossie::PropertyList & value) : Property(id, name, mode, "external", configurationkinds) { - ossie::PropertyList::const_iterator it; + ossie::PropertyList::const_iterator it; for(it=value.begin(); it != value.end(); ++it) { this->value.push_back(const_cast(it->clone())); } } StructProperty(const StructProperty& other) : - Property(other.id, other.name, other.mode, other.action, other.kinds) + Property(other) { std::vector::const_iterator it; for(it=other.value.begin(); it != other.value.end(); ++it) { @@ -245,7 +245,7 @@ namespace ossie { virtual const std::string asString() const; virtual const Property* clone() const; - StructProperty &operator=(const StructProperty& src); + StructProperty& operator=(const StructProperty& src); const std::vector& getValue() const ; @@ -284,15 +284,6 @@ namespace ossie { virtual ~StructSequenceProperty(); - StructSequenceProperty(const StructSequenceProperty &src ) : - Property(src.id, src.name, src.mode, src.action, src.kinds), - structdef(src.structdef), - values(src.values) - { - } - - StructSequenceProperty & operator=( const StructSequenceProperty &src ); - virtual bool isNone() const; virtual const std::string asString() const; virtual const Property* clone() const; diff --git a/redhawk/src/control/parser/Properties.cpp b/redhawk/src/control/parser/Properties.cpp index 8400c8e19..c5c617b08 100644 --- a/redhawk/src/control/parser/Properties.cpp +++ b/redhawk/src/control/parser/Properties.cpp @@ -746,15 +746,6 @@ StructSequenceProperty::~StructSequenceProperty() { } -StructSequenceProperty& StructSequenceProperty::operator=(const StructSequenceProperty& src) -{ - Property::operator=(src); - structdef = src.structdef; - values = values; - return *this; -} - - bool StructSequenceProperty::isNone() const { return (values.size() == 0); } From 8457140c3292630f2f9b0710093590571e53f4c3 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 26 May 2016 12:58:12 -0400 Subject: [PATCH 0306/1644] Return a non-const pointer from clone() --- redhawk/src/control/include/ossie/Properties.h | 16 ++++++++-------- redhawk/src/control/parser/Properties.cpp | 10 +++++----- .../src/control/parser/internal/prf-pimpl.cpp | 4 ++-- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/redhawk/src/control/include/ossie/Properties.h b/redhawk/src/control/include/ossie/Properties.h index 4947be95b..c6ed67598 100644 --- a/redhawk/src/control/include/ossie/Properties.h +++ b/redhawk/src/control/include/ossie/Properties.h @@ -88,7 +88,7 @@ namespace ossie { // Pure virtual functions virtual bool isNone() const = 0; virtual const std::string asString() const = 0; - virtual const Property* clone() const = 0; + virtual Property* clone() const = 0; protected: // Common across all property types @@ -134,7 +134,7 @@ namespace ossie { virtual bool isCommandLine() const; virtual bool isNone() const; virtual const std::string asString() const; - virtual const Property* clone() const; + virtual Property* clone() const; const char* getType() const; bool isComplex() const; bool isOptional() const; @@ -178,7 +178,7 @@ namespace ossie { virtual bool isNone() const; virtual const std::string asString() const; - virtual const Property* clone() const; + virtual Property* clone() const; const char* getType() const; bool isComplex() const; bool isOptional() const; @@ -214,7 +214,7 @@ namespace ossie { { std::vector::const_iterator it; for(it=value.begin(); it != value.end(); ++it) { - this->value.push_back(const_cast((*it)->clone())); + this->value.push_back((*it)->clone()); } } @@ -227,7 +227,7 @@ namespace ossie { { ossie::PropertyList::const_iterator it; for(it=value.begin(); it != value.end(); ++it) { - this->value.push_back(const_cast(it->clone())); + this->value.push_back(it->clone()); } } @@ -236,14 +236,14 @@ namespace ossie { { std::vector::const_iterator it; for(it=other.value.begin(); it != other.value.end(); ++it) { - this->value.push_back(const_cast((*it)->clone())); + this->value.push_back((*it)->clone()); } } virtual ~StructProperty(); virtual bool isNone() const; virtual const std::string asString() const; - virtual const Property* clone() const; + virtual Property* clone() const; StructProperty& operator=(const StructProperty& src); @@ -286,7 +286,7 @@ namespace ossie { virtual bool isNone() const; virtual const std::string asString() const; - virtual const Property* clone() const; + virtual Property* clone() const; const StructProperty& getStruct() const; const std::vector& getValues() const; diff --git a/redhawk/src/control/parser/Properties.cpp b/redhawk/src/control/parser/Properties.cpp index c5c617b08..4bec2b787 100644 --- a/redhawk/src/control/parser/Properties.cpp +++ b/redhawk/src/control/parser/Properties.cpp @@ -557,7 +557,7 @@ const std::string SimpleProperty::asString() const { return out.str(); } -const Property* SimpleProperty::clone() const { +Property* SimpleProperty::clone() const { return new SimpleProperty(*this); } @@ -649,7 +649,7 @@ const std::string SimpleSequenceProperty::asString() const { return out.str(); } -const Property* SimpleSequenceProperty::clone() const { +Property* SimpleSequenceProperty::clone() const { return new SimpleSequenceProperty(*this); } @@ -680,7 +680,7 @@ StructProperty& StructProperty::operator=(const StructProperty& src) // bring in the new... std::vector::const_iterator it; for(it=src.value.begin(); it != src.value.end(); ++it) { - this->value.push_back(const_cast((*it)->clone())); + this->value.push_back((*it)->clone()); } return *this; @@ -722,7 +722,7 @@ const std::string StructProperty::asString() const { return out.str(); } -const Property* StructProperty::clone() const { +Property* StructProperty::clone() const { return new StructProperty(id, name, mode, kinds, value); }; @@ -778,7 +778,7 @@ const std::string StructSequenceProperty::asString() const { return out.str(); } -const Property* StructSequenceProperty::clone() const { +Property* StructSequenceProperty::clone() const { return new StructSequenceProperty(id, name, mode, structdef, kinds, values); } diff --git a/redhawk/src/control/parser/internal/prf-pimpl.cpp b/redhawk/src/control/parser/internal/prf-pimpl.cpp index 9ffbe5dd2..9a9b03124 100644 --- a/redhawk/src/control/parser/internal/prf-pimpl.cpp +++ b/redhawk/src/control/parser/internal/prf-pimpl.cpp @@ -707,13 +707,13 @@ description (const ::std::string& desciption) void struct_pimpl:: simple (const ossie::SimpleProperty& property) { - _value.push_back(const_cast(property.clone())); + _value.push_back(property.clone()); } void struct_pimpl:: simplesequence (const ossie::SimpleSequenceProperty& property) { - _value.push_back(const_cast(property.clone())); + _value.push_back(property.clone()); } void struct_pimpl:: From 1a3b697f3a6f94d99fef903784c34f70586976eb Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 26 May 2016 12:59:48 -0400 Subject: [PATCH 0307/1644] Compiler-generated operator= is good enough --- redhawk/src/control/include/ossie/Properties.h | 2 -- redhawk/src/control/parser/Properties.cpp | 6 ------ 2 files changed, 8 deletions(-) diff --git a/redhawk/src/control/include/ossie/Properties.h b/redhawk/src/control/include/ossie/Properties.h index c6ed67598..ad29e1d3a 100644 --- a/redhawk/src/control/include/ossie/Properties.h +++ b/redhawk/src/control/include/ossie/Properties.h @@ -372,8 +372,6 @@ namespace ossie { Properties(std::istream& input) throw(ossie::parser_error); - Properties& operator=( const Properties &other); - virtual ~Properties(); const std::vector& getProperties() const; diff --git a/redhawk/src/control/parser/Properties.cpp b/redhawk/src/control/parser/Properties.cpp index 4bec2b787..b124a9a82 100644 --- a/redhawk/src/control/parser/Properties.cpp +++ b/redhawk/src/control/parser/Properties.cpp @@ -88,12 +88,6 @@ Properties::~Properties() LOG_TRACE(Properties, "Destruction for properties") } -Properties& Properties::operator=(const Properties &other) { - _prf = other._prf; - return *this; -} - - void Properties::load(std::istream& input) throw (ossie::parser_error) { std::auto_ptr t = ossie::internalparser::parsePRF(input); _prf.reset(t.release()); From 6975c5889bcb49781573981e10a531eb8c15fad0 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 26 May 2016 13:13:58 -0400 Subject: [PATCH 0308/1644] Reduce excessive use of clone() in PRF parser --- .../src/control/parser/internal/prf-pimpl.cpp | 86 +++++++++---------- .../src/control/parser/internal/prf-pimpl.h | 28 +++--- redhawk/src/control/parser/internal/prf.map | 8 +- 3 files changed, 57 insertions(+), 65 deletions(-) diff --git a/redhawk/src/control/parser/internal/prf-pimpl.cpp b/redhawk/src/control/parser/internal/prf-pimpl.cpp index 9a9b03124..91c5cf4e1 100644 --- a/redhawk/src/control/parser/internal/prf-pimpl.cpp +++ b/redhawk/src/control/parser/internal/prf-pimpl.cpp @@ -286,19 +286,19 @@ description (const ::std::string& description) } void properties_pimpl:: -simple (const ossie::SimpleProperty& simple) +simple (ossie::SimpleProperty* simple) { - LOG_TRACE(prf_parser, "Adding simple property") + LOG_TRACE(prf_parser, "Adding simple property " << simple->getID()) assert(_prf.get() != 0); - _prf->addProperty(simple.clone()); + _prf->addProperty(simple); } void properties_pimpl:: -simplesequence (const ossie::SimpleSequenceProperty& simplesequence) +simplesequence (ossie::SimpleSequenceProperty* simplesequence) { - LOG_TRACE(prf_parser, "Adding simple sequence property " << simplesequence.getID()); + LOG_TRACE(prf_parser, "Adding simple sequence property " << simplesequence->getID()); assert(_prf.get() != 0); - _prf->addProperty(simplesequence.clone()); + _prf->addProperty(simplesequence); } void properties_pimpl:: @@ -307,19 +307,19 @@ test () } void properties_pimpl:: -struct_ (const ossie::StructProperty& struct_) +struct_ (ossie::StructProperty* struct_) { - LOG_TRACE(prf_parser, "Adding struct property " << struct_.getID()); + LOG_TRACE(prf_parser, "Adding struct property " << struct_->getID()); assert(_prf.get() != 0); - _prf->addProperty(struct_.clone()); + _prf->addProperty(struct_); } void properties_pimpl:: -structsequence (const ossie::StructSequenceProperty& structsequence) +structsequence (ossie::StructSequenceProperty* structsequence) { - LOG_TRACE(prf_parser, "Adding struct sequence property " << structsequence.getID()); + LOG_TRACE(prf_parser, "Adding struct sequence property " << structsequence->getID()); assert(_prf.get() != 0); - _prf->addProperty(structsequence.clone()); + _prf->addProperty(structsequence); } std::auto_ptr properties_pimpl:: @@ -499,17 +499,16 @@ commandline (bool commandline) _commandline = commandline; } -const ossie::SimpleProperty& simple_pimpl:: +ossie::SimpleProperty* simple_pimpl:: post_simple () { if (_value.get() != 0) { - LOG_TRACE(prf_parser, "simple_pimpl post " << _id << " " << _name << " " << _value->c_str()); - _prop = ossie::SimpleProperty(_id, _name, _type, _mode, _action, _kinds, _value.get(), _complex, _commandline, _optional); + LOG_TRACE(prf_parser, "simple_pimpl post " << _id << " " << _name << " " << _value->c_str()); + return new ossie::SimpleProperty(_id, _name, _type, _mode, _action, _kinds, _value.get(), _complex, _commandline, _optional); } else { - LOG_TRACE(prf_parser, "simple_pimpl post " << _id << " " << _name << " None"); - _prop = ossie::SimpleProperty(_id, _name, _type, _mode, _action, _kinds, 0, _complex, _commandline, _optional); + LOG_TRACE(prf_parser, "simple_pimpl post " << _id << " " << _name << " None"); + return new ossie::SimpleProperty(_id, _name, _type, _mode, _action, _kinds, 0, _complex, _commandline, _optional); } - return _prop; } // simpleRef_pimpl @@ -668,20 +667,18 @@ optional (bool optional) _optional = optional; } -const ossie::SimpleSequenceProperty& simpleSequence_pimpl:: +ossie::SimpleSequenceProperty* simpleSequence_pimpl:: post_simpleSequence () { - _prop = ossie::SimpleSequenceProperty(_id, - _name, - _type, - _mode, - _action, - _kinds, - _values, - _complex, - _optional); - - return _prop; + return new ossie::SimpleSequenceProperty(_id, + _name, + _type, + _mode, + _action, + _kinds, + _values, + _complex, + _optional); } // struct_pimpl @@ -705,15 +702,15 @@ description (const ::std::string& desciption) } void struct_pimpl:: -simple (const ossie::SimpleProperty& property) +simple (ossie::SimpleProperty* property) { - _value.push_back(property.clone()); + _value.push_back(property); } void struct_pimpl:: -simplesequence (const ossie::SimpleSequenceProperty& property) +simplesequence (ossie::SimpleSequenceProperty* property) { - _value.push_back(property.clone()); + _value.push_back(property); } void struct_pimpl:: @@ -740,7 +737,7 @@ name (const ::std::string& name) _name = name; } -const ossie::StructProperty& struct_pimpl:: +ossie::StructProperty* struct_pimpl:: post_struct () { LOG_TRACE(prf_parser, "struct_pimpl post " << _id << " " << _name); @@ -753,8 +750,7 @@ post_struct () LOG_TRACE(prf_parser, " value " << *i) } - _prop = ossie::StructProperty(_id, _name, _mode, _kinds, _value); - return _prop; + return new ossie::StructProperty(_id, _name, _mode, _kinds, _value); } // structSequence_pimpl @@ -769,7 +765,7 @@ pre () _mode = ""; _kinds.clear(); _values.clear(); - _struct = ossie::StructProperty(); // resets internal values vector + _struct.reset(); // resets internal values vector } void structSequence_pimpl:: @@ -778,17 +774,18 @@ description (const ::std::string& description) } void structSequence_pimpl:: -struct_ (const ossie::StructProperty& structProp) +struct_ (ossie::StructProperty* structProp) { - _struct = structProp; + _struct.reset(structProp); } void structSequence_pimpl:: structvalue (const ossie::ComponentPropertyMap& value) { + assert(_struct.get() != 0); std::vector propValue; std::vector rmprops; - const std::vector& defaults = _struct.getValue(); + const std::vector& defaults = _struct->getValue(); for (std::vector::const_iterator prop = defaults.begin(); prop != defaults.end(); ++prop) { const std::string id = (*prop)->getID(); ossie::ComponentPropertyMap::const_iterator ii = value.find(id); @@ -829,7 +826,7 @@ structvalue (const ossie::ComponentPropertyMap& value) propValue.push_back(p); } } - _values.push_back(ossie::StructProperty(_struct.getID(), _struct.getName(), _struct.getMode(), _struct.getKinds(), propValue)); + _values.push_back(ossie::StructProperty(_struct->getID(), _struct->getName(), _struct->getMode(), _struct->getKinds(), propValue)); // clean up unused properties.. for ( std::vector::iterator i = rmprops.begin(); i != rmprops.end(); ++i) { if ( *i ) delete *i; } } @@ -858,11 +855,10 @@ name (const ::std::string& name) _name = name; } -const ossie::StructSequenceProperty& structSequence_pimpl:: +ossie::StructSequenceProperty* structSequence_pimpl:: post_structSequence () { - _prop = ossie::StructSequenceProperty(_id, _name, _mode, _struct, _kinds, _values); - return _prop; + return new ossie::StructSequenceProperty(_id, _name, _mode, *_struct, _kinds, _values); } // structValue_pimpl diff --git a/redhawk/src/control/parser/internal/prf-pimpl.h b/redhawk/src/control/parser/internal/prf-pimpl.h index a794f49ba..1c990137f 100644 --- a/redhawk/src/control/parser/internal/prf-pimpl.h +++ b/redhawk/src/control/parser/internal/prf-pimpl.h @@ -217,19 +217,19 @@ namespace prf description (const ::std::string&); virtual void - simple (const ossie::SimpleProperty&); + simple (ossie::SimpleProperty*); virtual void - simplesequence (const ossie::SimpleSequenceProperty&); + simplesequence (ossie::SimpleSequenceProperty*); virtual void test (); virtual void - struct_ (const ossie::StructProperty&); + struct_ (ossie::StructProperty*); virtual void - structsequence (const ossie::StructSequenceProperty&); + structsequence (ossie::StructSequenceProperty*); virtual std::auto_ptr post_properties (); @@ -330,7 +330,7 @@ namespace prf virtual void optional (bool); - virtual const ossie::SimpleProperty& + virtual ossie::SimpleProperty* post_simple (); private: @@ -344,7 +344,6 @@ namespace prf bool _optional; std::vector _kinds; std::auto_ptr _value; - ossie::SimpleProperty _prop; }; class simpleRef_pimpl: public virtual simpleRef_pskel @@ -427,7 +426,7 @@ namespace prf virtual void optional (bool); - virtual const ossie::SimpleSequenceProperty& + virtual ossie::SimpleSequenceProperty* post_simpleSequence (); private: @@ -440,7 +439,6 @@ namespace prf bool _optional; std::vector _kinds; std::vector _values; - ossie::SimpleSequenceProperty _prop; }; class struct_pimpl: public virtual struct_pskel @@ -453,10 +451,10 @@ namespace prf description (const ::std::string&); virtual void - simple (const ossie::SimpleProperty&); + simple (ossie::SimpleProperty*); virtual void - simplesequence (const ossie::SimpleSequenceProperty&); + simplesequence (ossie::SimpleSequenceProperty*); virtual void configurationkind (const ::std::string&); @@ -470,7 +468,7 @@ namespace prf virtual void name (const ::std::string&); - virtual const ossie::StructProperty& + virtual ossie::StructProperty* post_struct (); private: @@ -480,7 +478,6 @@ namespace prf std::string _mode; std::vector _kinds; ossie::PropertyList _value; - ossie::StructProperty _prop; }; class structSequence_pimpl: public virtual structSequence_pskel @@ -490,7 +487,7 @@ namespace prf pre (); virtual void - struct_ (const ossie::StructProperty&); + struct_ (ossie::StructProperty*); virtual void description (const ::std::string&); @@ -510,7 +507,7 @@ namespace prf virtual void name (const ::std::string&); - virtual const ossie::StructSequenceProperty& + virtual ossie::StructSequenceProperty* post_structSequence (); private: @@ -519,9 +516,8 @@ namespace prf std::string _type; std::string _mode; std::vector _kinds; - ossie::StructProperty _struct; + std::auto_ptr _struct; std::vector _values; - ossie::StructSequenceProperty _prop; }; class structValue_pimpl: public virtual structValue_pskel diff --git a/redhawk/src/control/parser/internal/prf.map b/redhawk/src/control/parser/internal/prf.map index fcfde8a4b..4c07ec54d 100644 --- a/redhawk/src/control/parser/internal/prf.map +++ b/redhawk/src/control/parser/internal/prf.map @@ -26,10 +26,10 @@ namespace urn:mil:jpeojtrs:sca:prf { include "../../include/ossie/componentProfile.h"; properties "std::auto_ptr"; - simple "const ossie::SimpleProperty&" "const ossie::SimpleProperty&"; - simpleSequence "const ossie::SimpleSequenceProperty&" "const ossie::SimpleSequenceProperty&"; - struct "const ossie::StructProperty&" "const ossie::StructProperty&"; - structSequence "const ossie::StructSequenceProperty&" "const ossie::StructSequenceProperty&"; + simple "ossie::SimpleProperty*"; + simpleSequence "ossie::SimpleSequenceProperty*"; + struct "ossie::StructProperty*"; + structSequence "ossie::StructSequenceProperty*"; description "::std::string"; value "::std::string"; From 969558880040a93ef94e8c00c7e71360d4e17186 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 26 May 2016 16:58:18 -0400 Subject: [PATCH 0309/1644] Use enumerated bit flags for property kinds --- redhawk/src/control/framework/nodebooter.cpp | 6 +- .../src/control/include/ossie/Properties.h | 39 +++++--- redhawk/src/control/parser/Properties.cpp | 98 ++++++++----------- .../src/control/parser/internal/prf-pimpl.cpp | 67 ++++++++----- .../src/control/parser/internal/prf-pimpl.h | 33 ++++--- redhawk/src/control/parser/internal/prf.map | 9 +- 6 files changed, 134 insertions(+), 118 deletions(-) diff --git a/redhawk/src/control/framework/nodebooter.cpp b/redhawk/src/control/framework/nodebooter.cpp index 0a8f30829..f18bd364b 100644 --- a/redhawk/src/control/framework/nodebooter.cpp +++ b/redhawk/src/control/framework/nodebooter.cpp @@ -1145,21 +1145,19 @@ int main(int argc, char* argv[]) LOG_DEBUG(nodebooter, "OS " << un.sysname); // Build a list of properties for this system based on the information from uname. - std::vector kinds; - kinds.push_back("allocation"); ossie::SimpleProperty osProp("DCE:4a23ad60-0b25-4121-a630-68803a498f75", "os_name", "string", "readonly", "eq", - kinds, + ossie::Property::KIND_ALLOCATION, std::string(un.sysname)); ossie::SimpleProperty procProp("DCE:fefb9c66-d14a-438d-ad59-2cfd1adb272b", "processor_name", "string", "readonly", "eq", - kinds, + ossie::Property::KIND_ALLOCATION, std::string(un.machine)); std::vector systemProps; systemProps.push_back(&osProp); diff --git a/redhawk/src/control/include/ossie/Properties.h b/redhawk/src/control/include/ossie/Properties.h index ad29e1d3a..d43f19713 100644 --- a/redhawk/src/control/include/ossie/Properties.h +++ b/redhawk/src/control/include/ossie/Properties.h @@ -49,13 +49,24 @@ namespace ossie { public: friend class Properties; + enum KindType { + KIND_NOTSET = 0, + KIND_ALLOCATION = 1, + KIND_CONFIGURE = 2, + KIND_PROPERTY = 4, + KIND_TEST = 8, + KIND_EXECPARAM = 16, + KIND_FACTORYPARAM = 32, + KIND_DEFAULT = KIND_CONFIGURE + }; + Property() {} Property(const std::string& id, const std::string& name, const std::string& mode, const std::string& action, - const std::vector& kinds); + int kinds); virtual ~Property(); @@ -81,7 +92,7 @@ namespace ossie { const char* getName() const; const char* getMode() const; const char* getAction() const; - const std::vector& getKinds() const; + int getKinds() const; std::string mapPrimitiveToComplex(const std::string& type) const; @@ -96,7 +107,7 @@ namespace ossie { std::string name; std::string mode; std::string action; - std::vector kinds; + int kinds; // Pure virtual functions virtual void override(const Property* otherProp) = 0; @@ -119,7 +130,7 @@ namespace ossie { const std::string& type, const std::string& mode, const std::string& action, - const std::vector& kinds, + int kinds, const optional_value& value, bool complex=false, bool commandline=false, @@ -167,7 +178,7 @@ namespace ossie { const std::string& type, const std::string& mode, const std::string& action, - const std::vector& kinds, + int kinds, const std::vector& values, bool complex=false, bool optional=false); @@ -206,10 +217,10 @@ namespace ossie { StructProperty() {} StructProperty(const std::string& id, - const std::string& name, - const std::string& mode, - const std::vector& configurationkinds, - const std::vector& value) : + const std::string& name, + const std::string& mode, + int configurationkinds, + const std::vector& value) : Property(id, name, mode, "external", configurationkinds) { std::vector::const_iterator it; @@ -219,9 +230,9 @@ namespace ossie { } StructProperty(const std::string& id, - const std::string& name, - const std::string& mode, - const std::vector& configurationkinds, + const std::string& name, + const std::string& mode, + int configurationkinds, const ossie::PropertyList & value) : Property(id, name, mode, "external", configurationkinds) { @@ -274,7 +285,7 @@ namespace ossie { const std::string& name, const std::string& mode, const StructProperty& structdef, - const std::vector& configurationkinds, + int configurationkinds, const std::vector& values) : Property(id, name, mode, "external", configurationkinds), structdef(structdef), @@ -415,5 +426,7 @@ namespace ossie { boost::shared_ptr _prf; }; + std::ostream& operator<<(std::ostream& stream, Property::KindType kind); + } #endif diff --git a/redhawk/src/control/parser/Properties.cpp b/redhawk/src/control/parser/Properties.cpp index b124a9a82..78c31abd9 100644 --- a/redhawk/src/control/parser/Properties.cpp +++ b/redhawk/src/control/parser/Properties.cpp @@ -235,17 +235,45 @@ const std::vector& Properties::getFactoryParamProperties() cons * Property class */ +std::ostream& ossie::operator<<(std::ostream& stream, ossie::Property::KindType kind) +{ + switch (kind) { + case Property::KIND_PROPERTY: + stream << "property"; + break; + case Property::KIND_CONFIGURE: + stream << "configure"; + break; + case Property::KIND_EXECPARAM: + stream << "execparam"; + break; + case Property::KIND_ALLOCATION: + stream << "allocation"; + break; + case Property::KIND_TEST: + stream << "test"; + break; + case Property::KIND_FACTORYPARAM: + stream << "factoryparam"; + break; + default: + break; + } + return stream; +} + Property::Property(const std::string& id, const std::string& name, const std::string& mode, const std::string& action, - const std::vector& kinds): + int kinds): id(id), name(name), mode(mode), action(action), - kinds(kinds) + kinds((kinds == KIND_NOTSET)?KIND_DEFAULT:kinds) { + LOG_TRACE(Property, "Property " << id << " : " << this->kinds); } Property::~Property() @@ -255,77 +283,37 @@ Property::~Property() bool Property::isAllocation() const { TRACE_ENTER(Property); - - for (unsigned int i = 0; i < kinds.size (); i++) { - if (kinds[i] == "allocation") - { return true; } - } - - return false; + return kinds & KIND_ALLOCATION; } bool Property::isConfigure() const { TRACE_ENTER(Property); - if (kinds.size() == 0) { - return true; - } - for (unsigned int i = 0; i < kinds.size (); i++) { - if (kinds[i] == "configure") - { return true; } - } - return false; + return kinds & KIND_CONFIGURE; } bool Property::isProperty() const { TRACE_ENTER(Property); - // RESOLVE, could be default behavior with old style properties - //if (kinds.size() == 0) { - //return true; - //} - for (unsigned int i = 0; i < kinds.size (); i++) { - if (kinds[i] == "property") - { return true; } - } - - return false; + return kinds & KIND_PROPERTY; } bool Property::isTest() const { TRACE_ENTER(Property); - - for (unsigned int i = 0; i < kinds.size (); i++) { - if (kinds[i] == "test") - { return true; } - } - - return false; + return kinds & KIND_TEST; } bool Property::isExecParam() const { TRACE_ENTER(Property); - - for (unsigned int i = 0; i < kinds.size (); i++) { - if (kinds[i] == "execparam") - { return true; } - } - - return false; + return kinds & KIND_EXECPARAM; } bool Property::isFactoryParam() const { TRACE_ENTER(Property); - - for (unsigned int i = 0; i < kinds.size (); i++) { - if (kinds[i] == "factoryparam") - { return true; } - } - - return false; + return kinds & KIND_FACTORYPARAM; } const char* Property::getID() const @@ -348,7 +336,7 @@ const char* Property::getAction() const return action.c_str(); } -const std::vector & Property::getKinds() const +int Property::getKinds() const { return kinds; } @@ -454,7 +442,7 @@ SimpleProperty::SimpleProperty(const std::string& id, const std::string& type, const std::string& mode, const std::string& action, - const std::vector& kinds, + int kinds, const optional_value& value, bool complex, bool commandline, @@ -540,10 +528,10 @@ const char* SimpleProperty::getValue() const const std::string SimpleProperty::asString() const { std::ostringstream out; out << "Simple Property: <'" << this->id << "' '" << this->name << " " << this->mode << " " << this->type << " '"; - std::vector::const_iterator i; - for (i = kinds.begin(); i != kinds.end(); ++i) { - out << *i << ", "; - } + // std::vector::const_iterator i; + // for (i = kinds.begin(); i != kinds.end(); ++i) { + // out << *i << ", "; + // } out << "' "; if (value.isSet()) { out << " = '" << *(this->value) << "'>"; @@ -564,7 +552,7 @@ SimpleSequenceProperty::SimpleSequenceProperty(const std::string& i const std::string& type, const std::string& mode, const std::string& action, - const std::vector& kinds, + int kinds, const std::vector& values, bool complex, bool optional) : diff --git a/redhawk/src/control/parser/internal/prf-pimpl.cpp b/redhawk/src/control/parser/internal/prf-pimpl.cpp index 91c5cf4e1..51876af84 100644 --- a/redhawk/src/control/parser/internal/prf-pimpl.cpp +++ b/redhawk/src/control/parser/internal/prf-pimpl.cpp @@ -145,16 +145,16 @@ post_ActionType () void configurationKind_pimpl:: pre () { - _kindtype = "configure"; + _kindtype = ossie::Property::KIND_DEFAULT; } void configurationKind_pimpl:: -kindtype (const ::std::string& kindtype) +kindtype (ossie::Property::KindType kindtype) { _kindtype = kindtype; } -std::string configurationKind_pimpl:: +ossie::Property::KindType configurationKind_pimpl:: post_configurationKind () { return _kindtype; @@ -227,16 +227,16 @@ post_inputValue () void kind_pimpl:: pre () { - _type = "configure"; // The default is configure + _type = ossie::Property::KIND_DEFAULT; } void kind_pimpl:: -kindtype (const ::std::string& type) +kindtype (ossie::Property::KindType type) { _type = type; } -std::string kind_pimpl:: +ossie::Property::KindType kind_pimpl:: post_kind () { return _type; @@ -250,11 +250,28 @@ pre () { } -std::string PropertyConfigurationType_pimpl:: +ossie::Property::KindType PropertyConfigurationType_pimpl:: post_PropertyConfigurationType () { - const ::std::string& v (post_string ()); - return v; + const std::string& kindtype = post_string(); + LOG_TRACE(prf_parser, "PropertyConfigurationType = " << kindtype); + if (kindtype == "property") { + return ossie::Property::KIND_PROPERTY; + } else if (kindtype == "configure") { + return ossie::Property::KIND_CONFIGURE; + } else if (kindtype == "execparam") { + return ossie::Property::KIND_EXECPARAM; + } else if (kindtype == "allocation") { + return ossie::Property::KIND_ALLOCATION; + } else if (kindtype == "test") { + return ossie::Property::KIND_TEST; + } else if (kindtype == "factoryparam") { + return ossie::Property::KIND_FACTORYPARAM; + } else { + // The generated part of the parser does not validate that the value is + // in the allowed range; just to be safe, treat it as the default + return ossie::Property::KIND_DEFAULT; + } } // StructPropertyConfigurationType_pimpl @@ -265,7 +282,7 @@ pre () { } -::std::string StructPropertyConfigurationType_pimpl:: +ossie::Property::KindType StructPropertyConfigurationType_pimpl:: post_StructPropertyConfigurationType () { return post_PropertyConfigurationType (); @@ -403,7 +420,7 @@ pre () _action = ""; _optional = false; _commandline = false; - _kinds.clear(); + _kinds = ossie::Property::KIND_NOTSET; _value.reset(); } @@ -437,10 +454,10 @@ enumerations (const ::std::map& enumerations) } void simple_pimpl:: -kind (const ::std::string& kind) +kind (ossie::Property::KindType kind) { LOG_TRACE(prf_parser, "simple_pimpl kind " << kind) - _kinds.push_back(kind); + _kinds |= kind; } void simple_pimpl:: @@ -580,7 +597,7 @@ pre () _action = ""; _optional = false; - _kinds.clear(); + _kinds = ossie::Property::KIND_NOTSET; _values.clear(); } @@ -612,10 +629,10 @@ range (const ::std::vector& range) } void simpleSequence_pimpl:: -kind (const ::std::string& kind) +kind (ossie::Property::KindType kind) { LOG_TRACE(prf_parser, "simpleSequence_pimpl kind " << kind) - _kinds.push_back(kind); + _kinds |= kind; } void simpleSequence_pimpl:: @@ -692,7 +709,7 @@ pre () _name = ""; _type = ""; _mode = ""; - _kinds.clear(); + _kinds = ossie::Property::KIND_NOTSET; _value.clear(); } @@ -714,9 +731,9 @@ simplesequence (ossie::SimpleSequenceProperty* property) } void struct_pimpl:: -configurationkind (const ::std::string& kind) +configurationkind (ossie::Property::KindType kind) { - _kinds.push_back(kind); + _kinds |= kind; } void struct_pimpl:: @@ -741,9 +758,9 @@ ossie::StructProperty* struct_pimpl:: post_struct () { LOG_TRACE(prf_parser, "struct_pimpl post " << _id << " " << _name); - for (std::vector::const_iterator ii = _kinds.begin(); ii != _kinds.end(); ++ii) { - LOG_TRACE(prf_parser, " kind " << *ii); - } + // for (std::vector::const_iterator ii = _kinds.begin(); ii != _kinds.end(); ++ii) { + // LOG_TRACE(prf_parser, " kind " << *ii); + // } ossie::PropertyList::const_iterator i; for (i = _value.begin(); i != _value.end(); ++i) { @@ -763,7 +780,7 @@ pre () _name = ""; _type = ""; _mode = ""; - _kinds.clear(); + _kinds = ossie::Property::KIND_NOTSET; _values.clear(); _struct.reset(); // resets internal values vector } @@ -832,9 +849,9 @@ structvalue (const ossie::ComponentPropertyMap& value) } void structSequence_pimpl:: -configurationkind (const ::std::string& kind) +configurationkind (ossie::Property::KindType kind) { - _kinds.push_back(kind); + _kinds |= kind; } void structSequence_pimpl:: diff --git a/redhawk/src/control/parser/internal/prf-pimpl.h b/redhawk/src/control/parser/internal/prf-pimpl.h index 1c990137f..6206d8a17 100644 --- a/redhawk/src/control/parser/internal/prf-pimpl.h +++ b/redhawk/src/control/parser/internal/prf-pimpl.h @@ -119,13 +119,13 @@ namespace prf pre (); virtual void - kindtype (const ::std::string&); + kindtype (ossie::Property::KindType); - virtual ::std::string + virtual ossie::Property::KindType post_configurationKind (); private: - std::string _kindtype; + ossie::Property::KindType _kindtype; }; class enumeration_pimpl: public virtual enumeration_pskel @@ -177,12 +177,13 @@ namespace prf pre (); virtual void - kindtype (const ::std::string&); + kindtype (ossie::Property::KindType); - virtual ::std::string + virtual ossie::Property::KindType post_kind (); + private: - std::string _type; + ossie::Property::KindType _type; }; class PropertyConfigurationType_pimpl: public virtual PropertyConfigurationType_pskel, @@ -192,7 +193,7 @@ namespace prf virtual void pre (); - virtual std::string + virtual ossie::Property::KindType post_PropertyConfigurationType (); }; @@ -203,7 +204,7 @@ namespace prf virtual void pre (); - virtual ::std::string + virtual ossie::Property::KindType post_StructPropertyConfigurationType (); }; @@ -304,7 +305,7 @@ namespace prf enumerations (const ::std::map&); virtual void - kind (const ::std::string&); + kind (ossie::Property::KindType); virtual void action (const ::std::string&); @@ -342,7 +343,7 @@ namespace prf std::string _action; bool _commandline; bool _optional; - std::vector _kinds; + int _kinds; std::auto_ptr _value; }; @@ -403,7 +404,7 @@ namespace prf range (const ::std::vector&); virtual void - kind (const ::std::string&); + kind (ossie::Property::KindType); virtual void action (const ::std::string&); @@ -437,7 +438,7 @@ namespace prf std::string _mode; std::string _action; bool _optional; - std::vector _kinds; + int _kinds; std::vector _values; }; @@ -457,7 +458,7 @@ namespace prf simplesequence (ossie::SimpleSequenceProperty*); virtual void - configurationkind (const ::std::string&); + configurationkind (ossie::Property::KindType); virtual void id (const ::std::string&); @@ -476,7 +477,7 @@ namespace prf std::string _name; std::string _type; std::string _mode; - std::vector _kinds; + int _kinds; ossie::PropertyList _value; }; @@ -496,7 +497,7 @@ namespace prf structvalue (const ossie::ComponentPropertyMap&); virtual void - configurationkind (const ::std::string&); + configurationkind (ossie::Property::KindType); virtual void id (const ::std::string&); @@ -515,7 +516,7 @@ namespace prf std::string _name; std::string _type; std::string _mode; - std::vector _kinds; + int _kinds; std::auto_ptr _struct; std::vector _values; }; diff --git a/redhawk/src/control/parser/internal/prf.map b/redhawk/src/control/parser/internal/prf.map index 4c07ec54d..e6d3847ef 100644 --- a/redhawk/src/control/parser/internal/prf.map +++ b/redhawk/src/control/parser/internal/prf.map @@ -36,9 +36,8 @@ namespace urn:mil:jpeojtrs:sca:prf { values "::std::vector"; units "::std::string"; action "::std::string"; - kind "::std::string"; - kindtype "::std::string"; - StructPropertyConfigurationType "::std::string"; + kind "::ossie::Property::KindType" "::ossie::Property::KindType"; + StructPropertyConfigurationType "::ossie::Property::KindType" "::ossie::Property::KindType"; PropertyValueType "::std::string"; AccessType "::std::string"; ActionType "::std::string"; @@ -46,8 +45,8 @@ namespace urn:mil:jpeojtrs:sca:prf { IsCommandLine "bool"; IsOptional "bool"; Unit "::std::string"; - PropertyConfigurationType "::std::string"; - configurationKind "::std::string"; + PropertyConfigurationType "::ossie::Property::KindType" "::ossie::Property::KindType"; + configurationKind "::ossie::Property::KindType" "::ossie::Property::KindType"; range "::std::pair"; enumerations "::std::map"; enumeration "::std::map::value_type"; From 815048942080e07477eedcabf1079f7eceaa024d Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 27 May 2016 09:32:06 -0400 Subject: [PATCH 0310/1644] PRF parser mapping needs to explicitly declare the argument type for bool, otherwise it uses a const reference --- redhawk/src/control/parser/internal/prf.map | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/redhawk/src/control/parser/internal/prf.map b/redhawk/src/control/parser/internal/prf.map index e6d3847ef..48d26fdf4 100644 --- a/redhawk/src/control/parser/internal/prf.map +++ b/redhawk/src/control/parser/internal/prf.map @@ -41,9 +41,9 @@ namespace urn:mil:jpeojtrs:sca:prf { PropertyValueType "::std::string"; AccessType "::std::string"; ActionType "::std::string"; - IsComplex "bool"; - IsCommandLine "bool"; - IsOptional "bool"; + IsComplex "bool" "bool"; + IsCommandLine "bool" "bool"; + IsOptional "bool" "bool"; Unit "::std::string"; PropertyConfigurationType "::ossie::Property::KindType" "::ossie::Property::KindType"; configurationKind "::ossie::Property::KindType" "::ossie::Property::KindType"; From 6d574e7cad1ca8d97ea0b3622343dcea6a2a159f Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 27 May 2016 10:06:33 -0400 Subject: [PATCH 0311/1644] Make Property::override() public and use that to build struct values, instead of complicated constructors --- .../src/control/include/ossie/Properties.h | 10 ++--- .../src/control/parser/internal/prf-pimpl.cpp | 44 +++---------------- 2 files changed, 10 insertions(+), 44 deletions(-) diff --git a/redhawk/src/control/include/ossie/Properties.h b/redhawk/src/control/include/ossie/Properties.h index d43f19713..faaa09c53 100644 --- a/redhawk/src/control/include/ossie/Properties.h +++ b/redhawk/src/control/include/ossie/Properties.h @@ -101,6 +101,9 @@ namespace ossie { virtual const std::string asString() const = 0; virtual Property* clone() const = 0; + virtual void override(const Property* otherProp) = 0; + virtual void override(const ComponentProperty* newValue) = 0; + protected: // Common across all property types std::string id; @@ -109,9 +112,6 @@ namespace ossie { std::string action; int kinds; - // Pure virtual functions - virtual void override(const Property* otherProp) = 0; - virtual void override(const ComponentProperty* newValue) = 0; }; /* @@ -150,7 +150,6 @@ namespace ossie { bool isComplex() const; bool isOptional() const; - protected: virtual void override(const Property* otherProp); virtual void override(const ComponentProperty* newValue); @@ -194,7 +193,6 @@ namespace ossie { bool isComplex() const; bool isOptional() const; - protected: virtual void override(const Property* otherProp); virtual void override(const ComponentProperty* newValue); @@ -262,7 +260,6 @@ namespace ossie { const Property* getField(const std::string& id) const; - protected: virtual void override(const Property* otherProp); virtual void override(const ComponentProperty* newValue); @@ -302,7 +299,6 @@ namespace ossie { const StructProperty& getStruct() const; const std::vector& getValues() const; - protected: virtual void override(const Property* otherProp); virtual void override(const ComponentProperty* newValue); diff --git a/redhawk/src/control/parser/internal/prf-pimpl.cpp b/redhawk/src/control/parser/internal/prf-pimpl.cpp index 51876af84..7afb5b663 100644 --- a/redhawk/src/control/parser/internal/prf-pimpl.cpp +++ b/redhawk/src/control/parser/internal/prf-pimpl.cpp @@ -801,51 +801,21 @@ structvalue (const ossie::ComponentPropertyMap& value) { assert(_struct.get() != 0); std::vector propValue; - std::vector rmprops; const std::vector& defaults = _struct->getValue(); for (std::vector::const_iterator prop = defaults.begin(); prop != defaults.end(); ++prop) { const std::string id = (*prop)->getID(); ossie::ComponentPropertyMap::const_iterator ii = value.find(id); if (ii != value.end()) { - ossie::Property *p=NULL; - if (dynamic_cast(*prop) != NULL) { - const ossie::SimpleProperty* simp = dynamic_cast(*prop); - std::string val = static_cast(ii->second)->getValue(); - p = new ossie::SimpleProperty(id, - simp->getName(), - simp->getType(), - simp->getMode(), - simp->getAction(), - simp->getKinds(), - val, - simp->isComplex(), - simp->isCommandLine(), - simp->isOptional()); - rmprops.push_back(p); - - } else if (dynamic_cast(*prop) != NULL) { - const ossie::SimpleSequenceProperty* simpseq = dynamic_cast(*prop); - std::vector vals = static_cast(ii->second)->getValues(); - p = new ossie::SimpleSequenceProperty(id, - simpseq->getName(), - simpseq->getType(), - simpseq->getMode(), - simpseq->getAction(), - simpseq->getKinds(), - vals, - simpseq->isComplex(), - simpseq->isOptional()); - rmprops.push_back(p); - } else { - p = *prop; - } - - propValue.push_back(p); + ossie::Property* field = (*prop)->clone(); + propValue.push_back(field); + field->override(ii->second); } } _values.push_back(ossie::StructProperty(_struct->getID(), _struct->getName(), _struct->getMode(), _struct->getKinds(), propValue)); - // clean up unused properties.. - for ( std::vector::iterator i = rmprops.begin(); i != rmprops.end(); ++i) { if ( *i ) delete *i; } + // Clean up cloned properties + for (std::vector::iterator prop = propValue.begin(); prop != propValue.end(); ++prop) { + delete *prop; + } } void structSequence_pimpl:: From 6583532ef32fd6afa4d218bd25b075131798bbed Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 27 May 2016 11:14:49 -0400 Subject: [PATCH 0312/1644] Use an enumeration for property action, with the caveat that it still has to return a string to minimize ripple through prop_utils --- redhawk/src/control/framework/nodebooter.cpp | 4 +- .../src/control/include/ossie/Properties.h | 36 ++++++++---- redhawk/src/control/parser/Properties.cpp | 56 ++++++++++++++----- .../src/control/parser/internal/prf-pimpl.cpp | 35 +++++++++--- .../src/control/parser/internal/prf-pimpl.h | 16 +++--- redhawk/src/control/parser/internal/prf.map | 4 +- 6 files changed, 106 insertions(+), 45 deletions(-) diff --git a/redhawk/src/control/framework/nodebooter.cpp b/redhawk/src/control/framework/nodebooter.cpp index f18bd364b..4650f6848 100644 --- a/redhawk/src/control/framework/nodebooter.cpp +++ b/redhawk/src/control/framework/nodebooter.cpp @@ -1149,14 +1149,14 @@ int main(int argc, char* argv[]) "os_name", "string", "readonly", - "eq", + ossie::Property::ACTION_EQ, ossie::Property::KIND_ALLOCATION, std::string(un.sysname)); ossie::SimpleProperty procProp("DCE:fefb9c66-d14a-438d-ad59-2cfd1adb272b", "processor_name", "string", "readonly", - "eq", + ossie::Property::ACTION_EQ, ossie::Property::KIND_ALLOCATION, std::string(un.machine)); std::vector systemProps; diff --git a/redhawk/src/control/include/ossie/Properties.h b/redhawk/src/control/include/ossie/Properties.h index faaa09c53..c33ff3108 100644 --- a/redhawk/src/control/include/ossie/Properties.h +++ b/redhawk/src/control/include/ossie/Properties.h @@ -57,7 +57,18 @@ namespace ossie { KIND_TEST = 8, KIND_EXECPARAM = 16, KIND_FACTORYPARAM = 32, - KIND_DEFAULT = KIND_CONFIGURE + KIND_DEFAULT = KIND_CONFIGURE + }; + + enum ActionType { + ACTION_EXTERNAL, + ACTION_EQ, + ACTION_NE, + ACTION_GT, + ACTION_LT, + ACTION_GE, + ACTION_LE, + ACTION_DEFAULT = ACTION_EXTERNAL }; Property() {} @@ -65,7 +76,7 @@ namespace ossie { Property(const std::string& id, const std::string& name, const std::string& mode, - const std::string& action, + ActionType action, int kinds); virtual ~Property(); @@ -91,7 +102,11 @@ namespace ossie { const char* getID() const; const char* getName() const; const char* getMode() const; - const char* getAction() const; + // NB: getAction() should return an ActionType; however, there are + // several places that use its return as a string for an argument to + // property helper functions in the base library. Before the parsers + // become "public" API, this should be revisited. + std::string getAction() const; int getKinds() const; std::string mapPrimitiveToComplex(const std::string& type) const; @@ -109,7 +124,7 @@ namespace ossie { std::string id; std::string name; std::string mode; - std::string action; + ActionType action; int kinds; }; @@ -129,7 +144,7 @@ namespace ossie { const std::string& name, const std::string& type, const std::string& mode, - const std::string& action, + ActionType action, int kinds, const optional_value& value, bool complex=false, @@ -176,8 +191,8 @@ namespace ossie { const std::string& name, const std::string& type, const std::string& mode, - const std::string& action, - int kinds, + ActionType action, + int kinds, const std::vector& values, bool complex=false, bool optional=false); @@ -219,7 +234,7 @@ namespace ossie { const std::string& mode, int configurationkinds, const std::vector& value) : - Property(id, name, mode, "external", configurationkinds) + Property(id, name, mode, Property::ACTION_EXTERNAL, configurationkinds) { std::vector::const_iterator it; for(it=value.begin(); it != value.end(); ++it) { @@ -232,7 +247,7 @@ namespace ossie { const std::string& mode, int configurationkinds, const ossie::PropertyList & value) : - Property(id, name, mode, "external", configurationkinds) + Property(id, name, mode, Property::ACTION_EXTERNAL, configurationkinds) { ossie::PropertyList::const_iterator it; for(it=value.begin(); it != value.end(); ++it) { @@ -284,7 +299,7 @@ namespace ossie { const StructProperty& structdef, int configurationkinds, const std::vector& values) : - Property(id, name, mode, "external", configurationkinds), + Property(id, name, mode, Property::ACTION_EXTERNAL, configurationkinds), structdef(structdef), values(values) { @@ -423,6 +438,7 @@ namespace ossie { }; std::ostream& operator<<(std::ostream& stream, Property::KindType kind); + std::ostream& operator<<(std::ostream& stream, Property::ActionType action); } #endif diff --git a/redhawk/src/control/parser/Properties.cpp b/redhawk/src/control/parser/Properties.cpp index 78c31abd9..87ae0d929 100644 --- a/redhawk/src/control/parser/Properties.cpp +++ b/redhawk/src/control/parser/Properties.cpp @@ -262,10 +262,38 @@ std::ostream& ossie::operator<<(std::ostream& stream, ossie::Property::KindType return stream; } +std::ostream& ossie::operator<<(std::ostream& stream, ossie::Property::ActionType action) +{ + switch (action) { + case ossie::Property::ACTION_GE: + stream << "ge"; + break; + case ossie::Property::ACTION_GT: + stream << "gt"; + break; + case ossie::Property::ACTION_LE: + stream << "le"; + break; + case ossie::Property::ACTION_LT: + stream << "lt"; + break; + case ossie::Property::ACTION_NE: + stream << "ne"; + break; + case ossie::Property::ACTION_EQ: + stream << "eq"; + break; + case ossie::Property::ACTION_EXTERNAL: + stream << "external"; + break; + } + return stream; +} + Property::Property(const std::string& id, const std::string& name, const std::string& mode, - const std::string& action, + ActionType action, int kinds): id(id), name(name), @@ -331,9 +359,11 @@ const char* Property::getMode() const return mode.c_str(); } -const char* Property::getAction() const +std::string Property::getAction() const { - return action.c_str(); + std::ostringstream out; + out << action; + return out.str(); } int Property::getKinds() const @@ -363,39 +393,37 @@ bool Property::isWriteOnly() const bool Property::isEqual() const { - return (action == "eq"); + return (action == ACTION_EQ); } bool Property::isNotEqual() const { - return (action == "ne"); + return (action == ACTION_NE); } - bool Property::isGreaterThan() const { - return (action == "gt"); + return (action == ACTION_GT); } bool Property::isLessThan() const { - return (action == "lt"); + return (action == ACTION_LT); } bool Property::isGreaterThanOrEqual() const { - return (action == "ge"); + return (action == ACTION_GE); } - bool Property::isLessThanOrEqual() const { - return (action == "le"); + return (action == ACTION_LE); } bool Property::isExternal() const { - return ((action == "external") || (action == "")); + return (action == ACTION_EXTERNAL); } std::string Property::mapPrimitiveToComplex(const std::string& type) const @@ -441,7 +469,7 @@ SimpleProperty::SimpleProperty(const std::string& id, const std::string& name, const std::string& type, const std::string& mode, - const std::string& action, + ActionType action, int kinds, const optional_value& value, bool complex, @@ -551,7 +579,7 @@ SimpleSequenceProperty::SimpleSequenceProperty(const std::string& i const std::string& name, const std::string& type, const std::string& mode, - const std::string& action, + ActionType action, int kinds, const std::vector& values, bool complex, diff --git a/redhawk/src/control/parser/internal/prf-pimpl.cpp b/redhawk/src/control/parser/internal/prf-pimpl.cpp index 7afb5b663..e71cfc740 100644 --- a/redhawk/src/control/parser/internal/prf-pimpl.cpp +++ b/redhawk/src/control/parser/internal/prf-pimpl.cpp @@ -113,12 +113,12 @@ pre () } void action_pimpl:: -type (const ::std::string& type) +type (ossie::Property::ActionType type) { _type = type; } -::std::string action_pimpl:: +ossie::Property::ActionType action_pimpl:: post_action () { return _type; @@ -132,11 +132,28 @@ pre () { } -std::string ActionType_pimpl:: +ossie::Property::ActionType ActionType_pimpl:: post_ActionType () { - const ::std::string& v (post_string ()); - return v; + const std::string& action = post_string(); + if (action == "ge") { + return ossie::Property::ACTION_GE; + } else if (action == "gt") { + return ossie::Property::ACTION_GT; + } else if (action == "le") { + return ossie::Property::ACTION_LE; + } else if (action == "lt") { + return ossie::Property::ACTION_LT; + } else if (action == "ne") { + return ossie::Property::ACTION_NE; + } else if (action == "eq") { + return ossie::Property::ACTION_EQ; + } else if (action == "external") { + return ossie::Property::ACTION_EXTERNAL; + } else { + LOG_WARN(prf_parser, "Invalid action '" << action << "'"); + return ossie::Property::ACTION_DEFAULT; + } } // configurationKind_pimpl @@ -417,7 +434,7 @@ pre () _type = ""; _complex = false; _mode = ""; - _action = ""; + _action = ossie::Property::ACTION_EXTERNAL; _optional = false; _commandline = false; _kinds = ossie::Property::KIND_NOTSET; @@ -461,7 +478,7 @@ kind (ossie::Property::KindType kind) } void simple_pimpl:: -action (const ::std::string& action) +action (ossie::Property::ActionType action) { LOG_TRACE(prf_parser, "simple_pimpl action " << action) _action = action; @@ -594,7 +611,7 @@ pre () _type = ""; _complex = false; _mode = ""; - _action = ""; + _action = ossie::Property::ACTION_DEFAULT; _optional = false; _kinds = ossie::Property::KIND_NOTSET; @@ -636,7 +653,7 @@ kind (ossie::Property::KindType kind) } void simpleSequence_pimpl:: -action (const ::std::string& action) +action (ossie::Property::ActionType action) { LOG_TRACE(prf_parser, "simpleSequence_pimpl action " << action) _action = action; diff --git a/redhawk/src/control/parser/internal/prf-pimpl.h b/redhawk/src/control/parser/internal/prf-pimpl.h index 6206d8a17..1a4e349a8 100644 --- a/redhawk/src/control/parser/internal/prf-pimpl.h +++ b/redhawk/src/control/parser/internal/prf-pimpl.h @@ -93,12 +93,12 @@ namespace prf pre (); virtual void - type (const std::string&); + type (ossie::Property::ActionType); - virtual ::std::string + virtual ossie::Property::ActionType post_action (); private: - std::string _type; + ossie::Property::ActionType _type; }; class ActionType_pimpl: public virtual ActionType_pskel, @@ -108,7 +108,7 @@ namespace prf virtual void pre (); - virtual std::string + virtual ossie::Property::ActionType post_ActionType (); }; @@ -308,7 +308,7 @@ namespace prf kind (ossie::Property::KindType); virtual void - action (const ::std::string&); + action (ossie::Property::ActionType); virtual void id (const ::std::string&); @@ -340,7 +340,7 @@ namespace prf std::string _type; bool _complex; std::string _mode; - std::string _action; + ossie::Property::ActionType _action; bool _commandline; bool _optional; int _kinds; @@ -407,7 +407,7 @@ namespace prf kind (ossie::Property::KindType); virtual void - action (const ::std::string&); + action (ossie::Property::ActionType); virtual void id (const ::std::string&); @@ -436,7 +436,7 @@ namespace prf std::string _type; bool _complex; std::string _mode; - std::string _action; + ossie::Property::ActionType _action; bool _optional; int _kinds; std::vector _values; diff --git a/redhawk/src/control/parser/internal/prf.map b/redhawk/src/control/parser/internal/prf.map index 48d26fdf4..33f02c78c 100644 --- a/redhawk/src/control/parser/internal/prf.map +++ b/redhawk/src/control/parser/internal/prf.map @@ -35,12 +35,12 @@ namespace urn:mil:jpeojtrs:sca:prf { value "::std::string"; values "::std::vector"; units "::std::string"; - action "::std::string"; + action "::ossie::Property::ActionType" "::ossie::Property::ActionType"; kind "::ossie::Property::KindType" "::ossie::Property::KindType"; StructPropertyConfigurationType "::ossie::Property::KindType" "::ossie::Property::KindType"; PropertyValueType "::std::string"; AccessType "::std::string"; - ActionType "::std::string"; + ActionType "::ossie::Property::ActionType" "::ossie::Property::ActionType"; IsComplex "bool" "bool"; IsCommandLine "bool" "bool"; IsOptional "bool" "bool"; From 419f8dadd4940c240c6b20834eb8dfbbf0f58a88 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 27 May 2016 11:48:59 -0400 Subject: [PATCH 0313/1644] Use an enumeration for property mode --- redhawk/src/control/framework/nodebooter.cpp | 4 +-- .../src/control/include/ossie/Properties.h | 24 +++++++++----- redhawk/src/control/parser/Properties.cpp | 32 ++++++++++++++----- .../src/control/parser/internal/prf-pimpl.cpp | 31 +++++++++++------- .../src/control/parser/internal/prf-pimpl.h | 18 +++++------ redhawk/src/control/parser/internal/prf.map | 2 +- .../control/sdr/devmgr/DeviceManager_impl.cpp | 2 +- redhawk/src/control/sdr/devmgr/spdSupport.cpp | 2 +- .../control/sdr/dommgr/applicationSupport.cpp | 2 +- 9 files changed, 75 insertions(+), 42 deletions(-) diff --git a/redhawk/src/control/framework/nodebooter.cpp b/redhawk/src/control/framework/nodebooter.cpp index 4650f6848..73c5c131f 100644 --- a/redhawk/src/control/framework/nodebooter.cpp +++ b/redhawk/src/control/framework/nodebooter.cpp @@ -1148,14 +1148,14 @@ int main(int argc, char* argv[]) ossie::SimpleProperty osProp("DCE:4a23ad60-0b25-4121-a630-68803a498f75", "os_name", "string", - "readonly", + ossie::Property::MODE_READONLY, ossie::Property::ACTION_EQ, ossie::Property::KIND_ALLOCATION, std::string(un.sysname)); ossie::SimpleProperty procProp("DCE:fefb9c66-d14a-438d-ad59-2cfd1adb272b", "processor_name", "string", - "readonly", + ossie::Property::MODE_READONLY, ossie::Property::ACTION_EQ, ossie::Property::KIND_ALLOCATION, std::string(un.machine)); diff --git a/redhawk/src/control/include/ossie/Properties.h b/redhawk/src/control/include/ossie/Properties.h index c33ff3108..704285577 100644 --- a/redhawk/src/control/include/ossie/Properties.h +++ b/redhawk/src/control/include/ossie/Properties.h @@ -71,11 +71,18 @@ namespace ossie { ACTION_DEFAULT = ACTION_EXTERNAL }; + enum AccessType { + MODE_READWRITE, + MODE_READONLY, + MODE_WRITEONLY, + MODE_DEFAULT = MODE_READWRITE + }; + Property() {} Property(const std::string& id, const std::string& name, - const std::string& mode, + AccessType mode, ActionType action, int kinds); @@ -101,7 +108,7 @@ namespace ossie { const char* getID() const; const char* getName() const; - const char* getMode() const; + AccessType getMode() const; // NB: getAction() should return an ActionType; however, there are // several places that use its return as a string for an argument to // property helper functions in the base library. Before the parsers @@ -123,7 +130,7 @@ namespace ossie { // Common across all property types std::string id; std::string name; - std::string mode; + AccessType mode; ActionType action; int kinds; @@ -143,7 +150,7 @@ namespace ossie { SimpleProperty(const std::string& id, const std::string& name, const std::string& type, - const std::string& mode, + AccessType mode, ActionType action, int kinds, const optional_value& value, @@ -190,7 +197,7 @@ namespace ossie { SimpleSequenceProperty(const std::string& id, const std::string& name, const std::string& type, - const std::string& mode, + AccessType mode, ActionType action, int kinds, const std::vector& values, @@ -231,7 +238,7 @@ namespace ossie { StructProperty(const std::string& id, const std::string& name, - const std::string& mode, + AccessType mode, int configurationkinds, const std::vector& value) : Property(id, name, mode, Property::ACTION_EXTERNAL, configurationkinds) @@ -244,7 +251,7 @@ namespace ossie { StructProperty(const std::string& id, const std::string& name, - const std::string& mode, + AccessType mode, int configurationkinds, const ossie::PropertyList & value) : Property(id, name, mode, Property::ACTION_EXTERNAL, configurationkinds) @@ -295,7 +302,7 @@ namespace ossie { StructSequenceProperty(const std::string& id, const std::string& name, - const std::string& mode, + AccessType mode, const StructProperty& structdef, int configurationkinds, const std::vector& values) : @@ -439,6 +446,7 @@ namespace ossie { std::ostream& operator<<(std::ostream& stream, Property::KindType kind); std::ostream& operator<<(std::ostream& stream, Property::ActionType action); + std::ostream& operator<<(std::ostream& stream, Property::AccessType mode); } #endif diff --git a/redhawk/src/control/parser/Properties.cpp b/redhawk/src/control/parser/Properties.cpp index 87ae0d929..cea262717 100644 --- a/redhawk/src/control/parser/Properties.cpp +++ b/redhawk/src/control/parser/Properties.cpp @@ -290,9 +290,25 @@ std::ostream& ossie::operator<<(std::ostream& stream, ossie::Property::ActionTyp return stream; } +std::ostream& ossie::operator<<(std::ostream& stream, ossie::Property::AccessType mode) +{ + switch (mode) { + case ossie::Property::MODE_READWRITE: + stream << "readwrite"; + break; + case ossie::Property::MODE_READONLY: + stream << "readonly"; + break; + case ossie::Property::MODE_WRITEONLY: + stream << "writeonly"; + break; + } + return stream; +} + Property::Property(const std::string& id, const std::string& name, - const std::string& mode, + AccessType mode, ActionType action, int kinds): id(id), @@ -354,9 +370,9 @@ const char* Property::getName() const return name.c_str(); } -const char* Property::getMode() const +Property::AccessType Property::getMode() const { - return mode.c_str(); + return mode; } std::string Property::getAction() const @@ -373,7 +389,7 @@ int Property::getKinds() const bool Property::isReadOnly() const { - return (mode == "readonly"); + return (mode == MODE_READONLY); } bool Property::isCommandLine() const @@ -383,12 +399,12 @@ bool Property::isCommandLine() const bool Property::isReadWrite() const { - return (mode == "readwrite"); + return (mode == MODE_READWRITE); } bool Property::isWriteOnly() const { - return (mode == "writeonly"); + return (mode == MODE_WRITEONLY); } bool Property::isEqual() const @@ -468,7 +484,7 @@ std::string Property::mapPrimitiveToComplex(const std::string& type) const SimpleProperty::SimpleProperty(const std::string& id, const std::string& name, const std::string& type, - const std::string& mode, + AccessType mode, ActionType action, int kinds, const optional_value& value, @@ -578,7 +594,7 @@ Property* SimpleProperty::clone() const { SimpleSequenceProperty::SimpleSequenceProperty(const std::string& id, const std::string& name, const std::string& type, - const std::string& mode, + AccessType mode, ActionType action, int kinds, const std::vector& values, diff --git a/redhawk/src/control/parser/internal/prf-pimpl.cpp b/redhawk/src/control/parser/internal/prf-pimpl.cpp index e71cfc740..6b9ce6ad8 100644 --- a/redhawk/src/control/parser/internal/prf-pimpl.cpp +++ b/redhawk/src/control/parser/internal/prf-pimpl.cpp @@ -55,11 +55,20 @@ pre () { } -::std::string AccessType_pimpl:: +::ossie::Property::AccessType AccessType_pimpl:: post_AccessType () { - const ::std::string& v (post_string ()); - return v; + const std::string& mode = post_string(); + if (mode == "readwrite") { + return ossie::Property::MODE_READWRITE; + } else if (mode == "readonly") { + return ossie::Property::MODE_READONLY; + } else if (mode == "writeonly") { + return ossie::Property::MODE_WRITEONLY; + } else { + LOG_WARN(prf_parser, "Invalid mode '" << mode << "'"); + return ossie::Property::MODE_DEFAULT; + } } // IsComplex_pimpl @@ -433,7 +442,7 @@ pre () _name = ""; _type = ""; _complex = false; - _mode = ""; + _mode = ossie::Property::MODE_DEFAULT; _action = ossie::Property::ACTION_EXTERNAL; _optional = false; _commandline = false; @@ -492,7 +501,7 @@ id (const ::std::string& id) } void simple_pimpl:: -mode (const ::std::string& mode) +mode (ossie::Property::AccessType mode) { LOG_TRACE(prf_parser, "simple_pimpl mode " << mode) _mode = mode; @@ -610,7 +619,7 @@ pre () _name = ""; _type = ""; _complex = false; - _mode = ""; + _mode = ossie::Property::MODE_DEFAULT; _action = ossie::Property::ACTION_DEFAULT; _optional = false; @@ -667,7 +676,7 @@ id (const ::std::string& id) } void simpleSequence_pimpl:: -mode (const ::std::string& mode) +mode (ossie::Property::AccessType mode) { LOG_TRACE(prf_parser, "simple_pimpl mode " << mode) _mode = mode; @@ -725,7 +734,7 @@ pre () _id = ""; _name = ""; _type = ""; - _mode = ""; + _mode = ossie::Property::MODE_DEFAULT; _kinds = ossie::Property::KIND_NOTSET; _value.clear(); } @@ -760,7 +769,7 @@ id (const ::std::string& id) } void struct_pimpl:: -mode (const ::std::string& mode) +mode (ossie::Property::AccessType mode) { _mode = mode; } @@ -796,7 +805,7 @@ pre () _id = ""; _name = ""; _type = ""; - _mode = ""; + _mode = ossie::Property::MODE_DEFAULT; _kinds = ossie::Property::KIND_NOTSET; _values.clear(); _struct.reset(); // resets internal values vector @@ -848,7 +857,7 @@ id (const ::std::string& id) } void structSequence_pimpl:: -mode (const ::std::string& mode) +mode (ossie::Property::AccessType mode) { _mode = mode; } diff --git a/redhawk/src/control/parser/internal/prf-pimpl.h b/redhawk/src/control/parser/internal/prf-pimpl.h index 1a4e349a8..92ab963b1 100644 --- a/redhawk/src/control/parser/internal/prf-pimpl.h +++ b/redhawk/src/control/parser/internal/prf-pimpl.h @@ -49,7 +49,7 @@ namespace prf virtual void pre (); - virtual ::std::string + virtual ::ossie::Property::AccessType post_AccessType (); }; @@ -314,7 +314,7 @@ namespace prf id (const ::std::string&); virtual void - mode (const ::std::string&); + mode (ossie::Property::AccessType); virtual void name (const ::std::string&); @@ -339,7 +339,7 @@ namespace prf std::string _name; std::string _type; bool _complex; - std::string _mode; + ossie::Property::AccessType _mode; ossie::Property::ActionType _action; bool _commandline; bool _optional; @@ -413,7 +413,7 @@ namespace prf id (const ::std::string&); virtual void - mode (const ::std::string&); + mode (ossie::Property::AccessType); virtual void name (const ::std::string&); @@ -435,7 +435,7 @@ namespace prf std::string _name; std::string _type; bool _complex; - std::string _mode; + ossie::Property::AccessType _mode; ossie::Property::ActionType _action; bool _optional; int _kinds; @@ -464,7 +464,7 @@ namespace prf id (const ::std::string&); virtual void - mode (const ::std::string&); + mode (ossie::Property::AccessType); virtual void name (const ::std::string&); @@ -476,7 +476,7 @@ namespace prf std::string _id; std::string _name; std::string _type; - std::string _mode; + ossie::Property::AccessType _mode; int _kinds; ossie::PropertyList _value; }; @@ -503,7 +503,7 @@ namespace prf id (const ::std::string&); virtual void - mode (const ::std::string&); + mode (ossie::Property::AccessType); virtual void name (const ::std::string&); @@ -515,7 +515,7 @@ namespace prf std::string _id; std::string _name; std::string _type; - std::string _mode; + ossie::Property::AccessType _mode; int _kinds; std::auto_ptr _struct; std::vector _values; diff --git a/redhawk/src/control/parser/internal/prf.map b/redhawk/src/control/parser/internal/prf.map index 33f02c78c..64e2c9921 100644 --- a/redhawk/src/control/parser/internal/prf.map +++ b/redhawk/src/control/parser/internal/prf.map @@ -39,7 +39,7 @@ namespace urn:mil:jpeojtrs:sca:prf { kind "::ossie::Property::KindType" "::ossie::Property::KindType"; StructPropertyConfigurationType "::ossie::Property::KindType" "::ossie::Property::KindType"; PropertyValueType "::std::string"; - AccessType "::std::string"; + AccessType "::ossie::Property::AccessType" "::ossie::Property::AccessType"; ActionType "::ossie::Property::ActionType" "::ossie::Property::ActionType"; IsComplex "bool" "bool"; IsCommandLine "bool" "bool"; diff --git a/redhawk/src/control/sdr/devmgr/DeviceManager_impl.cpp b/redhawk/src/control/sdr/devmgr/DeviceManager_impl.cpp index 1c5328af2..a77fc880b 100644 --- a/redhawk/src/control/sdr/devmgr/DeviceManager_impl.cpp +++ b/redhawk/src/control/sdr/devmgr/DeviceManager_impl.cpp @@ -526,7 +526,7 @@ void DeviceManager_impl::getOverloadprops( } // do not allow readonly execparams to be overloaded (the default from the PRF is passed) - if (std::string((*jprops_iter)->getMode()) == "readonly") { + if ((*jprops_iter)->isReadOnly()) { LOG_WARN(DeviceManager_impl, "DCD requested that readonly execparam " << (*jprops_iter)->getID() << " " << (*jprops_iter)->getName() << " be over-written; ignoring it") continue; } diff --git a/redhawk/src/control/sdr/devmgr/spdSupport.cpp b/redhawk/src/control/sdr/devmgr/spdSupport.cpp index cb998a92f..9cc658313 100644 --- a/redhawk/src/control/sdr/devmgr/spdSupport.cpp +++ b/redhawk/src/control/sdr/devmgr/spdSupport.cpp @@ -472,7 +472,7 @@ void ResourceInfo::load(CF::FileSystem_ptr fileSys) LOG_TRACE(ResourceInfo, "Adding exec params") const std::vector& eprop = prf.getExecParamProperties(); for (unsigned int i = 0; i < eprop.size(); i++) { - if (std::string(eprop[i]->getMode()) != "readonly") { + if (!eprop[i]->isReadOnly()) { LOG_TRACE(ResourceInfo, "Adding exec param " << eprop[i]->getID() << " " << eprop[i]->getName()); addExecParameter(convertPropertyToDataType(eprop[i])); } else { diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp index 0af541c6e..5f0d7f2e3 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp @@ -79,7 +79,7 @@ ComponentInfo* ComponentInfo::buildComponentInfoFromSPDFile(const SoftPkg* softp LOG_TRACE(ComponentInfo, "Adding exec params") const std::vector& eprop = prf.getExecParamProperties(); for (unsigned int i = 0; i < eprop.size(); i++) { - if (std::string(eprop[i]->getMode()) != "readonly") { + if (!eprop[i]->isReadOnly()) { LOG_TRACE(ComponentInfo, "Adding exec param " << eprop[i]->getID() << " " << eprop[i]->getName()); newComponent->addExecParameter(convertPropertyToDataType(eprop[i])); } else { From 6968d8b104e0bc5f133c23f835b9391d0448ccb0 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 27 May 2016 12:22:20 -0400 Subject: [PATCH 0314/1644] Add missing property kinds; some cleanup --- .../src/control/include/ossie/Properties.h | 14 ++-- redhawk/src/control/parser/Properties.cpp | 16 +++-- .../src/control/parser/internal/prf-pimpl.cpp | 70 ++++++++++--------- 3 files changed, 55 insertions(+), 45 deletions(-) diff --git a/redhawk/src/control/include/ossie/Properties.h b/redhawk/src/control/include/ossie/Properties.h index 704285577..a9cc0d37a 100644 --- a/redhawk/src/control/include/ossie/Properties.h +++ b/redhawk/src/control/include/ossie/Properties.h @@ -51,12 +51,14 @@ namespace ossie { enum KindType { KIND_NOTSET = 0, - KIND_ALLOCATION = 1, - KIND_CONFIGURE = 2, - KIND_PROPERTY = 4, - KIND_TEST = 8, - KIND_EXECPARAM = 16, - KIND_FACTORYPARAM = 32, + KIND_CONFIGURE = 1<<1, + KIND_EXECPARAM = 1<<2, + KIND_ALLOCATION = 1<<3, + KIND_FACTORYPARAM = 1<<4, + KIND_TEST = 1<<5, + KIND_EVENT = 1<<6, + KIND_MESSAGE = 1<<7, + KIND_PROPERTY = 1<<8, KIND_DEFAULT = KIND_CONFIGURE }; diff --git a/redhawk/src/control/parser/Properties.cpp b/redhawk/src/control/parser/Properties.cpp index cea262717..2dcec9e67 100644 --- a/redhawk/src/control/parser/Properties.cpp +++ b/redhawk/src/control/parser/Properties.cpp @@ -238,9 +238,6 @@ const std::vector& Properties::getFactoryParamProperties() cons std::ostream& ossie::operator<<(std::ostream& stream, ossie::Property::KindType kind) { switch (kind) { - case Property::KIND_PROPERTY: - stream << "property"; - break; case Property::KIND_CONFIGURE: stream << "configure"; break; @@ -250,11 +247,20 @@ std::ostream& ossie::operator<<(std::ostream& stream, ossie::Property::KindType case Property::KIND_ALLOCATION: stream << "allocation"; break; + case Property::KIND_FACTORYPARAM: + stream << "factoryparam"; + break; case Property::KIND_TEST: stream << "test"; break; - case Property::KIND_FACTORYPARAM: - stream << "factoryparam"; + case Property::KIND_EVENT: + stream << "event"; + break; + case Property::KIND_MESSAGE: + stream << "message"; + break; + case Property::KIND_PROPERTY: + stream << "property"; break; default: break; diff --git a/redhawk/src/control/parser/internal/prf-pimpl.cpp b/redhawk/src/control/parser/internal/prf-pimpl.cpp index 6b9ce6ad8..f5e7b7a7a 100644 --- a/redhawk/src/control/parser/internal/prf-pimpl.cpp +++ b/redhawk/src/control/parser/internal/prf-pimpl.cpp @@ -281,18 +281,22 @@ post_PropertyConfigurationType () { const std::string& kindtype = post_string(); LOG_TRACE(prf_parser, "PropertyConfigurationType = " << kindtype); - if (kindtype == "property") { - return ossie::Property::KIND_PROPERTY; - } else if (kindtype == "configure") { + if (kindtype == "configure") { return ossie::Property::KIND_CONFIGURE; } else if (kindtype == "execparam") { return ossie::Property::KIND_EXECPARAM; } else if (kindtype == "allocation") { return ossie::Property::KIND_ALLOCATION; - } else if (kindtype == "test") { - return ossie::Property::KIND_TEST; } else if (kindtype == "factoryparam") { return ossie::Property::KIND_FACTORYPARAM; + } else if (kindtype == "test") { + return ossie::Property::KIND_TEST; + } else if (kindtype == "event") { + return ossie::Property::KIND_EVENT; + } else if (kindtype == "message") { + return ossie::Property::KIND_MESSAGE; + } else if (kindtype == "property") { + return ossie::Property::KIND_PROPERTY; } else { // The generated part of the parser does not validate that the value is // in the allowed range; just to be safe, treat it as the default @@ -311,7 +315,11 @@ pre () ossie::Property::KindType StructPropertyConfigurationType_pimpl:: post_StructPropertyConfigurationType () { - return post_PropertyConfigurationType (); + ossie::Property::KindType kind = post_PropertyConfigurationType(); + if (kind == ossie::Property::KIND_EXECPARAM) { + LOG_WARN(prf_parser, "Struct properties cannot have kind 'execparam'"); + } + return kind; } // properties_pimpl @@ -438,15 +446,15 @@ post_resultValue () void simple_pimpl:: pre () { - _id = ""; - _name = ""; - _type = ""; + _id.clear(); + _name.clear(); + _type.clear(); + _mode = ossie::Property::MODE_DEFAULT; + _action = ossie::Property::ACTION_DEFAULT; + _kinds = ossie::Property::KIND_NOTSET; _complex = false; - _mode = ossie::Property::MODE_DEFAULT; - _action = ossie::Property::ACTION_EXTERNAL; _optional = false; _commandline = false; - _kinds = ossie::Property::KIND_NOTSET; _value.reset(); } @@ -545,13 +553,12 @@ commandline (bool commandline) ossie::SimpleProperty* simple_pimpl:: post_simple () { - if (_value.get() != 0) { - LOG_TRACE(prf_parser, "simple_pimpl post " << _id << " " << _name << " " << _value->c_str()); - return new ossie::SimpleProperty(_id, _name, _type, _mode, _action, _kinds, _value.get(), _complex, _commandline, _optional); + if (_value.get()) { + LOG_TRACE(prf_parser, "simple_pimpl post " << _id << " " << _name << " " << *_value); } else { LOG_TRACE(prf_parser, "simple_pimpl post " << _id << " " << _name << " None"); - return new ossie::SimpleProperty(_id, _name, _type, _mode, _action, _kinds, 0, _complex, _commandline, _optional); } + return new ossie::SimpleProperty(_id, _name, _type, _mode, _action, _kinds, _value.get(), _complex, _commandline, _optional); } // simpleRef_pimpl @@ -615,15 +622,14 @@ post_simpleSequenceRef () void simpleSequence_pimpl:: pre () { - _id = ""; - _name = ""; - _type = ""; - _complex = false; + _id.clear(); + _name.clear(); + _type.clear(); _mode = ossie::Property::MODE_DEFAULT; _action = ossie::Property::ACTION_DEFAULT; - _optional = false; - _kinds = ossie::Property::KIND_NOTSET; + _complex = false; + _optional = false; _values.clear(); } @@ -639,9 +645,8 @@ values (const ::std::vector& values) for (unsigned i=0; i::const_iterator ii = _kinds.begin(); ii != _kinds.end(); ++ii) { - // LOG_TRACE(prf_parser, " kind " << *ii); - // } ossie::PropertyList::const_iterator i; for (i = _value.begin(); i != _value.end(); ++i) { @@ -802,9 +804,9 @@ post_struct () void structSequence_pimpl:: pre () { - _id = ""; - _name = ""; - _type = ""; + _id.clear(); + _name.clear(); + _type.clear(); _mode = ossie::Property::MODE_DEFAULT; _kinds = ossie::Property::KIND_NOTSET; _values.clear(); From 8e239feb2fe9eba046c93faf437c177dc00a10e0 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 27 May 2016 13:06:38 -0400 Subject: [PATCH 0315/1644] Encapsulate kinds flags in a struct that makes it easier to limit the allowed operations and output to a stream --- .../src/control/include/ossie/Properties.h | 63 ++++++++++++++++--- redhawk/src/control/parser/Properties.cpp | 28 +++++---- .../src/control/parser/internal/prf-pimpl.cpp | 14 ++--- .../src/control/parser/internal/prf-pimpl.h | 8 +-- 4 files changed, 82 insertions(+), 31 deletions(-) diff --git a/redhawk/src/control/include/ossie/Properties.h b/redhawk/src/control/include/ossie/Properties.h index a9cc0d37a..8621edd85 100644 --- a/redhawk/src/control/include/ossie/Properties.h +++ b/redhawk/src/control/include/ossie/Properties.h @@ -50,7 +50,6 @@ namespace ossie { friend class Properties; enum KindType { - KIND_NOTSET = 0, KIND_CONFIGURE = 1<<1, KIND_EXECPARAM = 1<<2, KIND_ALLOCATION = 1<<3, @@ -62,6 +61,46 @@ namespace ossie { KIND_DEFAULT = KIND_CONFIGURE }; + struct Kinds + { + public: + Kinds() : + kinds(0) + { + } + + Kinds(KindType kind) : + kinds(kind) + { + } + + Kinds& operator|= (KindType kind) + { + kinds |= kind; + return *this; + } + + bool operator& (KindType kind) const + { + return (kinds & kind); + } + + Kinds operator| (KindType kind) + { + Kinds result(*this); + result |= kind; + return result; + } + + bool operator! () const + { + return (kinds == 0); + } + + private: + int kinds; + }; + enum ActionType { ACTION_EXTERNAL, ACTION_EQ, @@ -86,7 +125,7 @@ namespace ossie { const std::string& name, AccessType mode, ActionType action, - int kinds); + Kinds kinds); virtual ~Property(); @@ -116,7 +155,7 @@ namespace ossie { // property helper functions in the base library. Before the parsers // become "public" API, this should be revisited. std::string getAction() const; - int getKinds() const; + Kinds getKinds() const; std::string mapPrimitiveToComplex(const std::string& type) const; @@ -134,7 +173,7 @@ namespace ossie { std::string name; AccessType mode; ActionType action; - int kinds; + Kinds kinds; }; @@ -154,7 +193,7 @@ namespace ossie { const std::string& type, AccessType mode, ActionType action, - int kinds, + Kinds kinds, const optional_value& value, bool complex=false, bool commandline=false, @@ -201,7 +240,7 @@ namespace ossie { const std::string& type, AccessType mode, ActionType action, - int kinds, + Kinds kinds, const std::vector& values, bool complex=false, bool optional=false); @@ -241,7 +280,7 @@ namespace ossie { StructProperty(const std::string& id, const std::string& name, AccessType mode, - int configurationkinds, + Kinds configurationkinds, const std::vector& value) : Property(id, name, mode, Property::ACTION_EXTERNAL, configurationkinds) { @@ -254,7 +293,7 @@ namespace ossie { StructProperty(const std::string& id, const std::string& name, AccessType mode, - int configurationkinds, + Kinds configurationkinds, const ossie::PropertyList & value) : Property(id, name, mode, Property::ACTION_EXTERNAL, configurationkinds) { @@ -306,7 +345,7 @@ namespace ossie { const std::string& name, AccessType mode, const StructProperty& structdef, - int configurationkinds, + Kinds configurationkinds, const std::vector& values) : Property(id, name, mode, Property::ACTION_EXTERNAL, configurationkinds), structdef(structdef), @@ -446,7 +485,13 @@ namespace ossie { boost::shared_ptr _prf; }; + inline Property::Kinds operator|(Property::KindType a, Property::KindType b) + { + return Property::Kinds(a) | b; + } + std::ostream& operator<<(std::ostream& stream, Property::KindType kind); + std::ostream& operator<<(std::ostream& stream, Property::Kinds kinds); std::ostream& operator<<(std::ostream& stream, Property::ActionType action); std::ostream& operator<<(std::ostream& stream, Property::AccessType mode); diff --git a/redhawk/src/control/parser/Properties.cpp b/redhawk/src/control/parser/Properties.cpp index 2dcec9e67..8c916df50 100644 --- a/redhawk/src/control/parser/Properties.cpp +++ b/redhawk/src/control/parser/Properties.cpp @@ -268,6 +268,17 @@ std::ostream& ossie::operator<<(std::ostream& stream, ossie::Property::KindType return stream; } +std::ostream& ossie::operator<<(std::ostream& stream, ossie::Property::Kinds kinds) +{ + for (int bit = 1; bit <= Property::KIND_PROPERTY; bit <<= 1) { + Property::KindType flag = static_cast(bit); + if (kinds & flag) { + stream << flag << ","; + } + } + return stream; +} + std::ostream& ossie::operator<<(std::ostream& stream, ossie::Property::ActionType action) { switch (action) { @@ -316,14 +327,13 @@ Property::Property(const std::string& id, const std::string& name, AccessType mode, ActionType action, - int kinds): + Kinds kinds): id(id), name(name), mode(mode), action(action), - kinds((kinds == KIND_NOTSET)?KIND_DEFAULT:kinds) + kinds((!kinds)?KIND_DEFAULT:kinds) { - LOG_TRACE(Property, "Property " << id << " : " << this->kinds); } Property::~Property() @@ -388,7 +398,7 @@ std::string Property::getAction() const return out.str(); } -int Property::getKinds() const +Property::Kinds Property::getKinds() const { return kinds; } @@ -492,7 +502,7 @@ SimpleProperty::SimpleProperty(const std::string& id, const std::string& type, AccessType mode, ActionType action, - int kinds, + Kinds kinds, const optional_value& value, bool complex, bool commandline, @@ -578,11 +588,7 @@ const char* SimpleProperty::getValue() const const std::string SimpleProperty::asString() const { std::ostringstream out; out << "Simple Property: <'" << this->id << "' '" << this->name << " " << this->mode << " " << this->type << " '"; - // std::vector::const_iterator i; - // for (i = kinds.begin(); i != kinds.end(); ++i) { - // out << *i << ", "; - // } - out << "' "; + out << kinds << "' "; if (value.isSet()) { out << " = '" << *(this->value) << "'>"; } @@ -602,7 +608,7 @@ SimpleSequenceProperty::SimpleSequenceProperty(const std::string& i const std::string& type, AccessType mode, ActionType action, - int kinds, + Kinds kinds, const std::vector& values, bool complex, bool optional) : diff --git a/redhawk/src/control/parser/internal/prf-pimpl.cpp b/redhawk/src/control/parser/internal/prf-pimpl.cpp index f5e7b7a7a..37e6811f7 100644 --- a/redhawk/src/control/parser/internal/prf-pimpl.cpp +++ b/redhawk/src/control/parser/internal/prf-pimpl.cpp @@ -451,7 +451,7 @@ pre () _type.clear(); _mode = ossie::Property::MODE_DEFAULT; _action = ossie::Property::ACTION_DEFAULT; - _kinds = ossie::Property::KIND_NOTSET; + _kinds = ossie::Property::Kinds(); _complex = false; _optional = false; _commandline = false; @@ -554,9 +554,9 @@ ossie::SimpleProperty* simple_pimpl:: post_simple () { if (_value.get()) { - LOG_TRACE(prf_parser, "simple_pimpl post " << _id << " " << _name << " " << *_value); + LOG_TRACE(prf_parser, "simple_pimpl post " << _id << " " << _name << " " << _kinds << " " << *_value); } else { - LOG_TRACE(prf_parser, "simple_pimpl post " << _id << " " << _name << " None"); + LOG_TRACE(prf_parser, "simple_pimpl post " << _id << " " << _name << " " << _kinds << " None"); } return new ossie::SimpleProperty(_id, _name, _type, _mode, _action, _kinds, _value.get(), _complex, _commandline, _optional); } @@ -627,7 +627,7 @@ pre () _type.clear(); _mode = ossie::Property::MODE_DEFAULT; _action = ossie::Property::ACTION_DEFAULT; - _kinds = ossie::Property::KIND_NOTSET; + _kinds = ossie::Property::Kinds(); _complex = false; _optional = false; _values.clear(); @@ -740,7 +740,7 @@ pre () _name.clear(); _type.clear(); _mode = ossie::Property::MODE_DEFAULT; - _kinds = ossie::Property::KIND_NOTSET; + _kinds = ossie::Property::Kinds(); _value.clear(); } @@ -788,7 +788,7 @@ name (const ::std::string& name) ossie::StructProperty* struct_pimpl:: post_struct () { - LOG_TRACE(prf_parser, "struct_pimpl post " << _id << " " << _name); + LOG_TRACE(prf_parser, "struct_pimpl post " << _id << " " << _name << " kinds " << _kinds); ossie::PropertyList::const_iterator i; for (i = _value.begin(); i != _value.end(); ++i) { @@ -808,7 +808,7 @@ pre () _name.clear(); _type.clear(); _mode = ossie::Property::MODE_DEFAULT; - _kinds = ossie::Property::KIND_NOTSET; + _kinds = ossie::Property::Kinds(); _values.clear(); _struct.reset(); // resets internal values vector } diff --git a/redhawk/src/control/parser/internal/prf-pimpl.h b/redhawk/src/control/parser/internal/prf-pimpl.h index 92ab963b1..6f5a170a4 100644 --- a/redhawk/src/control/parser/internal/prf-pimpl.h +++ b/redhawk/src/control/parser/internal/prf-pimpl.h @@ -343,7 +343,7 @@ namespace prf ossie::Property::ActionType _action; bool _commandline; bool _optional; - int _kinds; + ossie::Property::Kinds _kinds; std::auto_ptr _value; }; @@ -438,7 +438,7 @@ namespace prf ossie::Property::AccessType _mode; ossie::Property::ActionType _action; bool _optional; - int _kinds; + ossie::Property::Kinds _kinds; std::vector _values; }; @@ -477,7 +477,7 @@ namespace prf std::string _name; std::string _type; ossie::Property::AccessType _mode; - int _kinds; + ossie::Property::Kinds _kinds; ossie::PropertyList _value; }; @@ -516,7 +516,7 @@ namespace prf std::string _name; std::string _type; ossie::Property::AccessType _mode; - int _kinds; + ossie::Property::Kinds _kinds; std::auto_ptr _struct; std::vector _values; }; From 09866df72ba5200b381ddd8f92b98e893b48307e Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 27 May 2016 13:32:30 -0400 Subject: [PATCH 0316/1644] Struct and structsequence properties don't have a type --- redhawk/src/control/parser/internal/prf-pimpl.cpp | 2 -- redhawk/src/control/parser/internal/prf-pimpl.h | 4 +--- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/redhawk/src/control/parser/internal/prf-pimpl.cpp b/redhawk/src/control/parser/internal/prf-pimpl.cpp index 37e6811f7..a11f6941a 100644 --- a/redhawk/src/control/parser/internal/prf-pimpl.cpp +++ b/redhawk/src/control/parser/internal/prf-pimpl.cpp @@ -738,7 +738,6 @@ pre () _id.clear(); _name.clear(); - _type.clear(); _mode = ossie::Property::MODE_DEFAULT; _kinds = ossie::Property::Kinds(); _value.clear(); @@ -806,7 +805,6 @@ pre () { _id.clear(); _name.clear(); - _type.clear(); _mode = ossie::Property::MODE_DEFAULT; _kinds = ossie::Property::Kinds(); _values.clear(); diff --git a/redhawk/src/control/parser/internal/prf-pimpl.h b/redhawk/src/control/parser/internal/prf-pimpl.h index 6f5a170a4..6f3bfce5b 100644 --- a/redhawk/src/control/parser/internal/prf-pimpl.h +++ b/redhawk/src/control/parser/internal/prf-pimpl.h @@ -475,10 +475,9 @@ namespace prf private: std::string _id; std::string _name; - std::string _type; ossie::Property::AccessType _mode; ossie::Property::Kinds _kinds; - ossie::PropertyList _value; + ossie::PropertyList _value; }; class structSequence_pimpl: public virtual structSequence_pskel @@ -514,7 +513,6 @@ namespace prf private: std::string _id; std::string _name; - std::string _type; ossie::Property::AccessType _mode; ossie::Property::Kinds _kinds; std::auto_ptr _struct; From b7cb0899fc73ed97145c1776ee5360b788e1f32f Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 27 May 2016 13:47:45 -0400 Subject: [PATCH 0317/1644] Use PropertyList for automatic cleanup in parser; use copy constructor in clone; remove extra constructor for struct property --- redhawk/src/control/include/ossie/Properties.h | 13 ------------- redhawk/src/control/parser/Properties.cpp | 2 +- redhawk/src/control/parser/internal/prf-pimpl.cpp | 6 +----- 3 files changed, 2 insertions(+), 19 deletions(-) diff --git a/redhawk/src/control/include/ossie/Properties.h b/redhawk/src/control/include/ossie/Properties.h index 8621edd85..70367d44c 100644 --- a/redhawk/src/control/include/ossie/Properties.h +++ b/redhawk/src/control/include/ossie/Properties.h @@ -277,19 +277,6 @@ namespace ossie { public: StructProperty() {} - StructProperty(const std::string& id, - const std::string& name, - AccessType mode, - Kinds configurationkinds, - const std::vector& value) : - Property(id, name, mode, Property::ACTION_EXTERNAL, configurationkinds) - { - std::vector::const_iterator it; - for(it=value.begin(); it != value.end(); ++it) { - this->value.push_back((*it)->clone()); - } - } - StructProperty(const std::string& id, const std::string& name, AccessType mode, diff --git a/redhawk/src/control/parser/Properties.cpp b/redhawk/src/control/parser/Properties.cpp index 8c916df50..824525a39 100644 --- a/redhawk/src/control/parser/Properties.cpp +++ b/redhawk/src/control/parser/Properties.cpp @@ -761,7 +761,7 @@ const std::string StructProperty::asString() const { } Property* StructProperty::clone() const { - return new StructProperty(id, name, mode, kinds, value); + return new StructProperty(*this); }; const std::vector& StructProperty::getValue() const { diff --git a/redhawk/src/control/parser/internal/prf-pimpl.cpp b/redhawk/src/control/parser/internal/prf-pimpl.cpp index a11f6941a..b355af0e3 100644 --- a/redhawk/src/control/parser/internal/prf-pimpl.cpp +++ b/redhawk/src/control/parser/internal/prf-pimpl.cpp @@ -826,7 +826,7 @@ void structSequence_pimpl:: structvalue (const ossie::ComponentPropertyMap& value) { assert(_struct.get() != 0); - std::vector propValue; + ossie::PropertyList propValue; const std::vector& defaults = _struct->getValue(); for (std::vector::const_iterator prop = defaults.begin(); prop != defaults.end(); ++prop) { const std::string id = (*prop)->getID(); @@ -838,10 +838,6 @@ structvalue (const ossie::ComponentPropertyMap& value) } } _values.push_back(ossie::StructProperty(_struct->getID(), _struct->getName(), _struct->getMode(), _struct->getKinds(), propValue)); - // Clean up cloned properties - for (std::vector::iterator prop = propValue.begin(); prop != propValue.end(); ++prop) { - delete *prop; - } } void structSequence_pimpl:: From 4ce6bf3b17bac0b8efc021c97fab74573a9245a2 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 27 May 2016 14:04:36 -0400 Subject: [PATCH 0318/1644] Use a managed container for struct property fields to reduce management of pointers --- redhawk/src/control/framework/prop_utils.cpp | 16 +++---- .../src/control/include/ossie/Properties.h | 29 ++++-------- redhawk/src/control/parser/Properties.cpp | 44 ++++--------------- .../src/control/parser/internal/prf-pimpl.cpp | 8 ++-- 4 files changed, 28 insertions(+), 69 deletions(-) diff --git a/redhawk/src/control/framework/prop_utils.cpp b/redhawk/src/control/framework/prop_utils.cpp index 75ea1309d..367a25b53 100644 --- a/redhawk/src/control/framework/prop_utils.cpp +++ b/redhawk/src/control/framework/prop_utils.cpp @@ -131,11 +131,10 @@ CF::DataType ossie::convertPropertyToDataType(const StructProperty* prop) { } CF::Properties structval_; - const std::vector& propValue = prop->getValue(); - std::vector::const_iterator i; - for (i = propValue.begin(); i != propValue.end(); ++i) { + const PropertyList& propValue = prop->getValue(); + for (ossie::PropertyList::const_iterator i = propValue.begin(); i != propValue.end(); ++i) { CF::DataType dt; - dt = convertPropertyToDataType(*i); + dt = convertPropertyToDataType(&(*i)); structval_.length(structval_.length() + 1); structval_[structval_.length() - 1] = dt; } @@ -206,12 +205,12 @@ CF::DataType ossie::overridePropertyValue(const SimpleSequenceProperty* prop, co static CF::Properties overrideStructValues(const StructProperty* prop, const ossie::ComponentPropertyMap & values) { - const std::vector& props = prop->getValue(); + const PropertyList& props = prop->getValue(); LOG_TRACE(prop_utils, "structure has " << props.size() << " elements"); CF::Properties structval; structval.length(props.size()); for (CORBA::ULong ii = 0; ii < structval.length(); ++ii) { - const Property* property = props[ii]; + const Property* property = &props[ii]; const std::string id = property->getID(); ossie::ComponentPropertyMap::const_iterator itemoverride = values.find(id); if (itemoverride == values.end()) { @@ -233,12 +232,12 @@ static CF::Properties overrideStructValues(const StructProperty* prop, const oss static CF::Properties overrideStructValues(const StructProperty* prop, const ossie::ComponentPropertyMap & values, const CF::Properties& configureProperties) { - const std::vector& props = prop->getValue(); + const PropertyList& props = prop->getValue(); LOG_TRACE(prop_utils, "structure has " << props.size() << " elements"); CF::Properties structval; structval.length(props.size()); for (CORBA::ULong ii = 0; ii < structval.length(); ++ii) { - const Property* property = props[ii]; + const Property* property = &props[ii]; const std::string id = property->getID(); ossie::ComponentPropertyMap::const_iterator itemoverride = values.find(id); if (dynamic_cast(itemoverride->second) != NULL) { @@ -614,7 +613,6 @@ CORBA::Any ossie::convertAnyToPropertyType(const CORBA::Any& value, const Struct const CF::Properties *depProps; if (value >>= depProps) { CF::Properties tmp_props; - std::vector structval = property->getValue(); for (unsigned int index = 0; index < depProps->length(); ++index) { const CF::DataType& item = (*depProps)[index]; const std::string propid(item.id); diff --git a/redhawk/src/control/include/ossie/Properties.h b/redhawk/src/control/include/ossie/Properties.h index 70367d44c..e2a658a83 100644 --- a/redhawk/src/control/include/ossie/Properties.h +++ b/redhawk/src/control/include/ossie/Properties.h @@ -174,9 +174,12 @@ namespace ossie { AccessType mode; ActionType action; Kinds kinds; - }; + inline Property* new_clone(const Property& property) { + return property.clone(); + } + /* * */ @@ -281,32 +284,18 @@ namespace ossie { const std::string& name, AccessType mode, Kinds configurationkinds, - const ossie::PropertyList & value) : - Property(id, name, mode, Property::ACTION_EXTERNAL, configurationkinds) + const ossie::PropertyList& value) : + Property(id, name, mode, Property::ACTION_EXTERNAL, configurationkinds), + value(value) { - ossie::PropertyList::const_iterator it; - for(it=value.begin(); it != value.end(); ++it) { - this->value.push_back(it->clone()); - } } - StructProperty(const StructProperty& other) : - Property(other) - { - std::vector::const_iterator it; - for(it=other.value.begin(); it != other.value.end(); ++it) { - this->value.push_back((*it)->clone()); - } - } - virtual ~StructProperty(); virtual bool isNone() const; virtual const std::string asString() const; virtual Property* clone() const; - StructProperty& operator=(const StructProperty& src); - - const std::vector& getValue() const ; + const PropertyList& getValue() const; const Property* getField(const std::string& id) const; @@ -314,7 +303,7 @@ namespace ossie { virtual void override(const ComponentProperty* newValue); private: - std::vector value; + PropertyList value; }; /* diff --git a/redhawk/src/control/parser/Properties.cpp b/redhawk/src/control/parser/Properties.cpp index 824525a39..818ec137f 100644 --- a/redhawk/src/control/parser/Properties.cpp +++ b/redhawk/src/control/parser/Properties.cpp @@ -696,38 +696,12 @@ Property* SimpleSequenceProperty::clone() const { */ StructProperty::~StructProperty() { - std::vector::iterator i; - for (i = value.begin(); i != value.end(); ++i) { - if ( *i ) delete *i; - } - value.clear(); -} - - -StructProperty& StructProperty::operator=(const StructProperty& src) -{ - Property::operator=(src); - - /// clean out my old... - std::vector::iterator i; - for (i = value.begin(); i != value.end(); ++i) { - if ( *i ) delete *i; - } - value.clear(); - - // bring in the new... - std::vector::const_iterator it; - for(it=src.value.begin(); it != src.value.end(); ++it) { - this->value.push_back((*it)->clone()); - } - - return *this; } bool StructProperty::isNone() const { // it is not possible to set only one of the structure values if (value.size() > 0) - return (value[0]->isNone()); + return (value[0].isNone()); else return true; } @@ -735,8 +709,7 @@ bool StructProperty::isNone() const { void StructProperty::override(const Property* otherProp) { const StructProperty* otherStructProp = dynamic_cast(otherProp); if (otherStructProp != NULL) { - value.clear(); - std::copy(otherStructProp->value.begin(), otherStructProp->value.end(), std::back_inserter(value)); + value = otherStructProp->getValue(); } else { LOG_WARN(StructProperty, "Ignoring override request") } @@ -753,9 +726,8 @@ void StructProperty::override(const ComponentProperty* newValue) { const std::string StructProperty::asString() const { std::ostringstream out; out << "'" << this->id << "' '" << this->name; - std::vector::const_iterator i; - for (i = value.begin(); i != value.end(); ++i) { - out << " " << **i << std::endl; + for (PropertyList::const_iterator i = value.begin(); i != value.end(); ++i) { + out << " " << *i << std::endl; } return out.str(); } @@ -764,14 +736,14 @@ Property* StructProperty::clone() const { return new StructProperty(*this); }; -const std::vector& StructProperty::getValue() const { +const ossie::PropertyList& StructProperty::getValue() const { return value; } const Property* StructProperty::getField(const std::string& fieldId) const { - for (std::vector::const_iterator field = value.begin(); field !=value.end(); ++field) { - if (fieldId == (*field)->getID()) { - return *field; + for (PropertyList::const_iterator field = value.begin(); field !=value.end(); ++field) { + if (fieldId == field->getID()) { + return &(*field); } } return 0; diff --git a/redhawk/src/control/parser/internal/prf-pimpl.cpp b/redhawk/src/control/parser/internal/prf-pimpl.cpp index b355af0e3..e6a4301cf 100644 --- a/redhawk/src/control/parser/internal/prf-pimpl.cpp +++ b/redhawk/src/control/parser/internal/prf-pimpl.cpp @@ -827,12 +827,12 @@ structvalue (const ossie::ComponentPropertyMap& value) { assert(_struct.get() != 0); ossie::PropertyList propValue; - const std::vector& defaults = _struct->getValue(); - for (std::vector::const_iterator prop = defaults.begin(); prop != defaults.end(); ++prop) { - const std::string id = (*prop)->getID(); + const ossie::PropertyList& defaults = _struct->getValue(); + for (ossie::PropertyList::const_iterator prop = defaults.begin(); prop != defaults.end(); ++prop) { + const std::string id = prop->getID(); ossie::ComponentPropertyMap::const_iterator ii = value.find(id); if (ii != value.end()) { - ossie::Property* field = (*prop)->clone(); + ossie::Property* field = prop->clone(); propValue.push_back(field); field->override(ii->second); } From 235a278caf4c04e7057438d87573a6ccc502ec9c Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 27 May 2016 14:34:11 -0400 Subject: [PATCH 0319/1644] Return const string references for simple and simple sequence types --- redhawk/src/control/include/ossie/Properties.h | 12 ++++++------ redhawk/src/control/parser/Properties.cpp | 8 ++++---- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/redhawk/src/control/include/ossie/Properties.h b/redhawk/src/control/include/ossie/Properties.h index e2a658a83..1f7c17d5e 100644 --- a/redhawk/src/control/include/ossie/Properties.h +++ b/redhawk/src/control/include/ossie/Properties.h @@ -206,15 +206,15 @@ namespace ossie { // SimpleProperty specific functions const char* getValue() const; + const std::string& getType() const; + bool isComplex() const; + bool isOptional() const; // Implementation of virtual functions virtual bool isCommandLine() const; virtual bool isNone() const; virtual const std::string asString() const; virtual Property* clone() const; - const char* getType() const; - bool isComplex() const; - bool isOptional() const; virtual void override(const Property* otherProp); virtual void override(const ComponentProperty* newValue); @@ -251,13 +251,13 @@ namespace ossie { virtual ~SimpleSequenceProperty(); const std::vector& getValues() const; + const std::string& getType() const; + bool isComplex() const; + bool isOptional() const; virtual bool isNone() const; virtual const std::string asString() const; virtual Property* clone() const; - const char* getType() const; - bool isComplex() const; - bool isOptional() const; virtual void override(const Property* otherProp); virtual void override(const ComponentProperty* newValue); diff --git a/redhawk/src/control/parser/Properties.cpp b/redhawk/src/control/parser/Properties.cpp index 818ec137f..a9d70c39e 100644 --- a/redhawk/src/control/parser/Properties.cpp +++ b/redhawk/src/control/parser/Properties.cpp @@ -561,9 +561,9 @@ void SimpleProperty::override(const ComponentProperty* newValue) { } } -const char* SimpleProperty::getType() const +const std::string& SimpleProperty::getType() const { - return type.c_str(); + return type; } bool SimpleProperty::isComplex() const @@ -657,9 +657,9 @@ void SimpleSequenceProperty::override(const ComponentProperty* newValue) { } } -const char* SimpleSequenceProperty::getType() const +const std::string& SimpleSequenceProperty::getType() const { - return type.c_str(); + return type; } bool SimpleSequenceProperty::isComplex() const From 53bd125fb21a22261e7249db423202cc08501ab1 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 27 May 2016 14:54:03 -0400 Subject: [PATCH 0320/1644] Use base std::ostream for Property stream operator; group stream operators --- .../src/control/include/ossie/Properties.h | 26 +++++++------------ redhawk/src/control/parser/Properties.cpp | 6 +++++ 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/redhawk/src/control/include/ossie/Properties.h b/redhawk/src/control/include/ossie/Properties.h index 1f7c17d5e..667c20a1e 100644 --- a/redhawk/src/control/include/ossie/Properties.h +++ b/redhawk/src/control/include/ossie/Properties.h @@ -180,6 +180,11 @@ namespace ossie { return property.clone(); } + inline Property::Kinds operator|(Property::KindType a, Property::KindType b) + { + return Property::Kinds(a) | b; + } + /* * */ @@ -346,12 +351,11 @@ namespace ossie { std::vector values; }; - template< typename charT, typename Traits> - std::basic_ostream& operator<<(std::basic_ostream &out, const Property& prop) - { - out << prop.asString(); - return out; - } + std::ostream& operator<<(std::ostream& out, const Property& prop); + std::ostream& operator<<(std::ostream& stream, Property::KindType kind); + std::ostream& operator<<(std::ostream& stream, Property::Kinds kinds); + std::ostream& operator<<(std::ostream& stream, Property::ActionType action); + std::ostream& operator<<(std::ostream& stream, Property::AccessType mode); /* * @@ -461,15 +465,5 @@ namespace ossie { boost::shared_ptr _prf; }; - inline Property::Kinds operator|(Property::KindType a, Property::KindType b) - { - return Property::Kinds(a) | b; - } - - std::ostream& operator<<(std::ostream& stream, Property::KindType kind); - std::ostream& operator<<(std::ostream& stream, Property::Kinds kinds); - std::ostream& operator<<(std::ostream& stream, Property::ActionType action); - std::ostream& operator<<(std::ostream& stream, Property::AccessType mode); - } #endif diff --git a/redhawk/src/control/parser/Properties.cpp b/redhawk/src/control/parser/Properties.cpp index a9d70c39e..6da95b097 100644 --- a/redhawk/src/control/parser/Properties.cpp +++ b/redhawk/src/control/parser/Properties.cpp @@ -235,6 +235,12 @@ const std::vector& Properties::getFactoryParamProperties() cons * Property class */ +std::ostream& ossie::operator<<(std::ostream& stream, const ossie::Property& property) +{ + stream << property.asString(); + return stream; +} + std::ostream& ossie::operator<<(std::ostream& stream, ossie::Property::KindType kind) { switch (kind) { From 7c997dc350af9e468e59bada4956174e1932784e Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 27 May 2016 15:50:30 -0400 Subject: [PATCH 0321/1644] Use an enumeration for SPD code type --- redhawk/src/control/include/ossie/SoftPkg.h | 28 +++++++++---------- redhawk/src/control/parser/SoftPkg.cpp | 27 ++++++++++++++++++ .../src/control/parser/internal/spd-pimpl.cpp | 25 ++++++++++------- .../src/control/parser/internal/spd-pimpl.h | 4 +-- redhawk/src/control/parser/internal/spd.map | 2 +- .../control/sdr/devmgr/DeviceManager_impl.cpp | 4 +-- redhawk/src/control/sdr/devmgr/spdSupport.cpp | 16 +++++------ redhawk/src/control/sdr/devmgr/spdSupport.h | 2 +- redhawk/src/control/sdr/dommgr/Deployment.cpp | 12 ++++---- 9 files changed, 76 insertions(+), 44 deletions(-) diff --git a/redhawk/src/control/include/ossie/SoftPkg.h b/redhawk/src/control/include/ossie/SoftPkg.h index 7f8b4996d..7b5ecbba7 100644 --- a/redhawk/src/control/include/ossie/SoftPkg.h +++ b/redhawk/src/control/include/ossie/SoftPkg.h @@ -67,17 +67,25 @@ namespace ossie { class Code { public: + enum CodeType { + NONE, + EXECUTABLE, + KERNEL_MODULE, + SHARED_LIBRARY, + DRIVER + }; + // Required std::string localfile; // Optional - optional_value type; + CodeType type; optional_value entrypoint; optional_value stacksize; optional_value priority; Code() : localfile(""), - type(""), + type(NONE), entrypoint(), stacksize(), priority() @@ -132,12 +140,8 @@ namespace ossie { return code.localfile; } - const char * getCodeType() const { - if (code.type.isSet()) { - return code.type->c_str(); - } else { - return 0; - } + Code::CodeType getCodeType() const { + return code.type; } const char * getEntryPoint() const { @@ -316,12 +320,8 @@ namespace ossie { std::string _spdPath; }; - template< typename charT, typename Traits> - std::basic_ostream& operator<<(std::basic_ostream &out, const SPD::Code& code) - { - out << "localfile: " << code.localfile << " type: " << code.type << " entrypoint: " << code.entrypoint; - return out; - } + std::ostream& operator<<(std::ostream& out, SPD::Code::CodeType type); + std::ostream& operator<<(std::ostream& out, const SPD::Code& code); } #endif diff --git a/redhawk/src/control/parser/SoftPkg.cpp b/redhawk/src/control/parser/SoftPkg.cpp index 4ee9f9365..32d034ba7 100644 --- a/redhawk/src/control/parser/SoftPkg.cpp +++ b/redhawk/src/control/parser/SoftPkg.cpp @@ -58,3 +58,30 @@ const std::string SPD::SoftPkgRef::asString() const { out << "SoftPkgRef localfile: " << this->localfile << " implref: " << this->implref; return out.str(); } + +std::ostream& ossie::operator<<(std::ostream& out, SPD::Code::CodeType type) +{ + switch (type) { + case SPD::Code::EXECUTABLE: + out << "Executable"; + break; + case SPD::Code::KERNEL_MODULE: + out << "KernelModule"; + break; + case SPD::Code::SHARED_LIBRARY: + out << "SharedLibrary"; + break; + case SPD::Code::DRIVER: + out << "Driver"; + break; + default: + break; + } + return out; +} + +std::ostream& ossie::operator<<(std::ostream& out, const SPD::Code& code) +{ + out << "localfile: " << code.localfile << " type: " << code.type << " entrypoint: " << code.entrypoint; + return out; +} diff --git a/redhawk/src/control/parser/internal/spd-pimpl.cpp b/redhawk/src/control/parser/internal/spd-pimpl.cpp index deab39764..a5b214dbc 100644 --- a/redhawk/src/control/parser/internal/spd-pimpl.cpp +++ b/redhawk/src/control/parser/internal/spd-pimpl.cpp @@ -371,7 +371,7 @@ priority (unsigned long long priority) } void code_pimpl:: -type (const ::std::string& type1) +type (ossie::SPD::Code::CodeType type1) { LOG_TRACE(spd_parser, "code type " << type1) code->type = type1; @@ -758,17 +758,22 @@ pre () { } -::std::string codeFileType_pimpl:: +ossie::SPD::Code::CodeType codeFileType_pimpl:: post_codeFileType () { - const ::std::string& v (post_nmtoken ()); - if ((v != "Executable") - || (v != "SharedLibrary") - || (v != "KernelModule") - || (v != "Driver")) { - // TODO throw invalid_value(this, v - } - return v; + const std::string& type = post_nmtoken(); + if (type == "Executable") { + return ossie::SPD::Code::EXECUTABLE; + } else if (type == "SharedLibrary") { + return ossie::SPD::Code::SHARED_LIBRARY; + } else if (type == "KernelModule") { + return ossie::SPD::Code::KERNEL_MODULE; + } else if (type == "Driver") { + return ossie::SPD::Code::DRIVER; + } else { + LOG_WARN(spd_parser, "Invalid code type '" << type << "'"); + return ossie::SPD::Code::NONE; + } } // simpleref_pimpl diff --git a/redhawk/src/control/parser/internal/spd-pimpl.h b/redhawk/src/control/parser/internal/spd-pimpl.h index 680af1ed9..9ed0e6ea4 100644 --- a/redhawk/src/control/parser/internal/spd-pimpl.h +++ b/redhawk/src/control/parser/internal/spd-pimpl.h @@ -224,7 +224,7 @@ namespace spd priority (unsigned long long); virtual void - type (const ::std::string&); + type (ossie::SPD::Code::CodeType); virtual ossie::SPD::Code post_code (); @@ -477,7 +477,7 @@ namespace spd virtual void pre (); - virtual ::std::string + virtual ossie::SPD::Code::CodeType post_codeFileType (); }; diff --git a/redhawk/src/control/parser/internal/spd.map b/redhawk/src/control/parser/internal/spd.map index 9ac79e375..2045621da 100644 --- a/redhawk/src/control/parser/internal/spd.map +++ b/redhawk/src/control/parser/internal/spd.map @@ -35,7 +35,7 @@ author "ossie::SPD::Author"; usesDevice "ossie::UsesDevice"; implementation "ossie::SPD::Implementation"; dependency "ossie::DependencyRef*"; -codeFileType "::std::string"; +codeFileType "::ossie::SPD::Code::CodeType" "::ossie::SPD::Code::CodeType"; code "ossie::SPD::Code"; compiler "ossie::SPD::NameVersionPair"; humanlangauge "::std::string"; diff --git a/redhawk/src/control/sdr/devmgr/DeviceManager_impl.cpp b/redhawk/src/control/sdr/devmgr/DeviceManager_impl.cpp index a77fc880b..543694a3d 100644 --- a/redhawk/src/control/sdr/devmgr/DeviceManager_impl.cpp +++ b/redhawk/src/control/sdr/devmgr/DeviceManager_impl.cpp @@ -1014,7 +1014,7 @@ void DeviceManager_impl::createDeviceThread( if (!matchedDeviceImpl) { throw std::runtime_error("unable to find matching device implementation"); } - bool isSharedLibrary = (std::string(matchedDeviceImpl->getCodeType()) == "SharedLibrary"); + bool isSharedLibrary = matchedDeviceImpl->getCodeType() == ossie::SPD::Code::SHARED_LIBRARY; // Logic for persona devices // check is parent exists and if the code type is "SharedLibrary" @@ -1396,7 +1396,7 @@ void DeviceManager_impl::postConstructor ( << "no available device implementations match device manager properties for deployOnDevice") continue; } - bool isSharedLibrary = (std::string(matchedDeviceImpl->getCodeType()) == "SharedLibrary"); + bool isSharedLibrary = matchedDeviceImpl->getCodeType() == ossie::SPD::Code::SHARED_LIBRARY; bool isCompositePartOf = constCompPlaceIter->isCompositePartOf(); if (isCompositePartOf && isSharedLibrary) { diff --git a/redhawk/src/control/sdr/devmgr/spdSupport.cpp b/redhawk/src/control/sdr/devmgr/spdSupport.cpp index 9cc658313..2a2a3b52d 100644 --- a/redhawk/src/control/sdr/devmgr/spdSupport.cpp +++ b/redhawk/src/control/sdr/devmgr/spdSupport.cpp @@ -203,19 +203,19 @@ const std::vector& ImplementationInfo::getDependencyProperti return dependencyProperties; } -void ImplementationInfo::setCodeType(const char* _type) +void ImplementationInfo::setCodeType(const SPD::Code::CodeType _type) { - std::string type(_type); - if (type == "KernelModule") { + switch (_type) { + case SPD::Code::KERNEL_MODULE: codeType = CF::LoadableDevice::KERNEL_MODULE; - } else if (type == "SharedLibrary") { + case SPD::Code::SHARED_LIBRARY: codeType = CF::LoadableDevice::SHARED_LIBRARY; - } else if (type == "Executable") { + case SPD::Code::EXECUTABLE: codeType = CF::LoadableDevice::EXECUTABLE; - } else if (type == "Driver") { + case SPD::Code::DRIVER: codeType = CF::LoadableDevice::DRIVER; - } else { - LOG_WARN(ImplementationInfo, "Bad code type " << type); + default: + LOG_WARN(ImplementationInfo, "Bad code type " << _type); } } diff --git a/redhawk/src/control/sdr/devmgr/spdSupport.h b/redhawk/src/control/sdr/devmgr/spdSupport.h index 4bd751c1b..3d7fddced 100644 --- a/redhawk/src/control/sdr/devmgr/spdSupport.h +++ b/redhawk/src/control/sdr/devmgr/spdSupport.h @@ -104,7 +104,7 @@ namespace ossie protected: void setLocalFileName(const char* fileName); void setEntryPoint(const char* fileName); - void setCodeType(const char* _type); + void setCodeType(ossie::SPD::Code::CodeType _type); void setStackSize(const unsigned long long *_stackSize); void setPriority(const unsigned long long *_priority); void addDependencyProperty(const ossie::PropertyRef& property); diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index 5861a146c..333904bfa 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -204,16 +204,16 @@ std::string SoftpkgDeployment::getLocalFile() CF::LoadableDevice::LoadType SoftpkgDeployment::getCodeType() const { - const std::string type = implementation->getCodeType(); - if (type == "KernelModule") { + switch (implementation->getCodeType()) { + case SPD::Code::KERNEL_MODULE: return CF::LoadableDevice::KERNEL_MODULE; - } else if (type == "SharedLibrary") { + case SPD::Code::SHARED_LIBRARY: return CF::LoadableDevice::SHARED_LIBRARY; - } else if (type == "Executable") { + case SPD::Code::EXECUTABLE: return CF::LoadableDevice::EXECUTABLE; - } else if (type == "Driver") { + case SPD::Code::DRIVER: return CF::LoadableDevice::DRIVER; - } else { + default: return CF::LoadableDevice::LoadType(); } } From 2e0ccd954ba28ef633fcdfe9b7ee979a90f3ca66 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 27 May 2016 16:03:37 -0400 Subject: [PATCH 0322/1644] Honor implref in softpkgref --- redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 8fc0e2504..28f8e98b9 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -1778,11 +1778,16 @@ bool createHelper::resolveSoftpkgDependencies(ossie::SoftpkgDeployment* deployme ossie::SoftpkgDeployment* createHelper::resolveDependencyImplementation(const ossie::SPD::SoftPkgRef& ref, ossie::DeviceNode& device) { + LOG_TRACE(ApplicationFactory_impl, "Resolving dependency " << ref); const SoftPkg* softpkg = _appProfile.getSoftPkg(ref.localfile); const SPD::Implementations& spd_list = softpkg->getImplementations(); for (size_t implCount = 0; implCount < spd_list.size(); implCount++) { const ossie::SPD::Implementation& implementation = spd_list[implCount]; + if (ref.implref.isSet() && (implementation.getID() != *ref.implref)) { + continue; + } + // Check that this implementation can run on the device if (!checkProcessor(implementation.getProcessors(), device.prf.getAllocationProperties())) { continue; From b592cf0f8390418f1347eb4201edcb598f17a24a Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 31 May 2016 10:04:16 -0400 Subject: [PATCH 0323/1644] Handle SAD uses devices after deployments are assigned, so that we can use the assembly controller's deployment for allocation context --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 50 +++++++------------ redhawk/src/control/sdr/dommgr/Deployment.cpp | 19 +++---- redhawk/src/control/sdr/dommgr/Deployment.h | 2 +- redhawk/src/control/sdr/dommgr/createHelper.h | 3 -- 4 files changed, 26 insertions(+), 48 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 28f8e98b9..2d43929ab 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -598,25 +598,6 @@ ApplicationFactory_impl::~ApplicationFactory_impl () } -/* - * Check to make sure assemblyController was initialized if it was SCA compliant - */ -void createHelper::_checkAssemblyController( - CF::Resource_ptr assemblyController, - ossie::ComponentInfo* assemblyControllerComponent) const -{ - if (CORBA::is_nil(assemblyController)) { - if ((assemblyControllerComponent==NULL) || - (assemblyControllerComponent->spd->isScaCompliant()) - ) { - LOG_DEBUG(ApplicationFactory_impl, "assembly controller is not Sca Compliant or has not been assigned"); - throw (CF::ApplicationFactory::CreateApplicationError( - CF::CF_NOTSET, - "assembly controller is not Sca Compliant or has not been assigned")); - } - } -} - void createHelper::_connectComponents(ossie::ApplicationDeployment& appDeployment, std::vector& connections){ try{ @@ -1181,24 +1162,21 @@ CF::Application_ptr createHelper::create ( ossie::ApplicationDeployment app_deployment(_appFact._sadParser, _waveformContextName, modifiedInitConfiguration); getRequiredComponents(_appFact._fileMgr, _appFact._sadParser, app_deployment); - ossie::ComponentInfo* assemblyControllerComponent = app_deployment.getAssemblyController(); - if (assemblyControllerComponent) { - overrideProperties(modifiedInitConfiguration, assemblyControllerComponent); - } - //////////////////////////////////////////////// // Assign components to devices //////////////////////////////////////////////// - // Allocate any usesdevice capacities specified in the SAD file - _handleUsesDevices(app_deployment, name); - // Catch invalid device assignments _validateDAS(app_deployment, deviceAssignments); // Assign all components to devices assignPlacementsToDevices(app_deployment, deviceAssignments); + // Allocate any usesdevice capacities specified in the SAD file; at this + // point, the complete set of component deployments is known, including any + // property overrides for allocation context + _handleUsesDevices(app_deployment, name); + // Assign CPU reservations to components app_deployment.applyCpuReservations(specialized_reservations); @@ -1225,13 +1203,19 @@ CF::Application_ptr createHelper::create ( initializeComponents(app_deployment.getComponentDeployments()); // Check that the assembly controller is valid - CF::Resource_var assemblyController; - if (assemblyControllerComponent) { - const std::string& assemblyControllerId = assemblyControllerComponent->getInstantiation()->getID(); - ossie::ComponentDeployment* deployment = app_deployment.getComponentDeployment(assemblyControllerId); - assemblyController = deployment->getResourcePtr(); + LOG_TRACE(ApplicationFactory_impl, "Checking assembly controller"); + ossie::ComponentDeployment* ac_deployment = app_deployment.getAssemblyController(); + if (!ac_deployment) { + const char* message = "Assembly controller has not been assigned"; + LOG_ERROR(ApplicationFactory_impl, message); + throw CF::ApplicationFactory::CreateApplicationError(CF::CF_NOTSET, message); + } + CF::Resource_var assemblyController = assemblyController = ac_deployment->getResourcePtr(); + if (CORBA::is_nil(assemblyController) && ac_deployment->getSoftPkg()->isScaCompliant()) { + const char* message = "Assembly controller has not registered with the application"; + LOG_ERROR(ApplicationFactory_impl, message); + throw CF::ApplicationFactory::CreateApplicationError(CF::CF_NOTSET, message); } - _checkAssemblyController(assemblyController, assemblyControllerComponent); _connectComponents(app_deployment, connections); _configureComponents(app_deployment.getComponentDeployments()); diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index 333904bfa..fbffc087d 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -602,26 +602,23 @@ ComponentInfo* ApplicationDeployment::getComponent(const std::string& instantiat return 0; } -ComponentInfo* ApplicationDeployment::getAssemblyController() const +ComponentDeployment* ApplicationDeployment::getAssemblyController() { - for (PlacementList::const_iterator placement = placements.begin(); placement != placements.end(); ++placement) { - const std::vector& components = (*placement)->getComponents(); - for (std::vector::const_iterator comp = components.begin(); comp != components.end(); ++comp) { - if ((*comp)->getInstantiation()->isAssemblyController()) { - return *comp; - } + BOOST_FOREACH(ComponentDeployment* deployment, components) { + if (deployment->getInstantiation()->isAssemblyController()) { + return deployment; } } - return 0; } redhawk::PropertyMap ApplicationDeployment::getAllocationContext() const { redhawk::PropertyMap properties; - const ossie::ComponentInfo* assembly_controller = getAssemblyController(); - if (assembly_controller) { - properties = assembly_controller->getConfigureProperties(); + BOOST_FOREACH(ComponentDeployment* deployment, components) { + if (deployment->getInstantiation()->isAssemblyController()) { + properties = deployment->getAllocationContext(); + } } return properties; } diff --git a/redhawk/src/control/sdr/dommgr/Deployment.h b/redhawk/src/control/sdr/dommgr/Deployment.h index 304f6b640..55cd8e549 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.h +++ b/redhawk/src/control/sdr/dommgr/Deployment.h @@ -230,7 +230,7 @@ namespace ossie { */ redhawk::PropertyMap getAllocationContext() const; - ComponentInfo* getAssemblyController() const; + ComponentDeployment* getAssemblyController(); ComponentInfo* getComponent(const std::string& instantiationId); diff --git a/redhawk/src/control/sdr/dommgr/createHelper.h b/redhawk/src/control/sdr/dommgr/createHelper.h index d272131dc..a908f82c6 100644 --- a/redhawk/src/control/sdr/dommgr/createHelper.h +++ b/redhawk/src/control/sdr/dommgr/createHelper.h @@ -111,9 +111,6 @@ class createHelper void _connectComponents(ossie::ApplicationDeployment& appDeployment, std::vector& connections); void _configureComponents(const DeploymentList& deployments); - void _checkAssemblyController( - CF::Resource_ptr assemblyController, - ossie::ComponentInfo* assemblyControllerComponent) const; void setUpExternalPorts(ossie::ApplicationDeployment& appDeployment, Application_impl* application); void setUpExternalProperties(ossie::ApplicationDeployment& appDeployment, Application_impl* application); void _placeHostCollocation(ossie::ApplicationDeployment& appDeployment, From b866e22f3cd32171b153942a92f904d114cf98a1 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 31 May 2016 13:02:57 -0400 Subject: [PATCH 0324/1644] Fix conversion of SPD::Code::CodeType to CF::LoadableDevice::LoadType --- redhawk/src/control/sdr/devmgr/spdSupport.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/redhawk/src/control/sdr/devmgr/spdSupport.cpp b/redhawk/src/control/sdr/devmgr/spdSupport.cpp index 2a2a3b52d..bdc8151cb 100644 --- a/redhawk/src/control/sdr/devmgr/spdSupport.cpp +++ b/redhawk/src/control/sdr/devmgr/spdSupport.cpp @@ -208,12 +208,16 @@ void ImplementationInfo::setCodeType(const SPD::Code::CodeType _type) switch (_type) { case SPD::Code::KERNEL_MODULE: codeType = CF::LoadableDevice::KERNEL_MODULE; + break; case SPD::Code::SHARED_LIBRARY: codeType = CF::LoadableDevice::SHARED_LIBRARY; + break; case SPD::Code::EXECUTABLE: codeType = CF::LoadableDevice::EXECUTABLE; + break; case SPD::Code::DRIVER: codeType = CF::LoadableDevice::DRIVER; + break; default: LOG_WARN(ImplementationInfo, "Bad code type " << _type); } From 0e30620a5532c53ee4f471ea4e2d2a1fa27bc396 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 31 May 2016 15:24:26 -0400 Subject: [PATCH 0325/1644] Handle logging configuration URI resolution within execution --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 171 ++++++------------ redhawk/src/control/sdr/dommgr/Deployment.cpp | 65 +++++-- redhawk/src/control/sdr/dommgr/Deployment.h | 2 + redhawk/src/control/sdr/dommgr/createHelper.h | 2 +- 4 files changed, 113 insertions(+), 127 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 2d43929ab..a62a8fc3a 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -1306,40 +1306,6 @@ CF::Application_ptr createHelper::create ( return appObj._retn(); } -void createHelper::overrideProperties(const CF::Properties& initConfiguration, - ossie::ComponentInfo* component) { - // Override properties - for (unsigned int initCount = 0; initCount < initConfiguration.length(); initCount++) { - const std::string init_id(initConfiguration[initCount].id); - if (init_id == "LOGGING_CONFIG_URI"){ - // See if the LOGGING_CONFIG_URI has already been set - // via or initParams - bool alreadyHasLoggingConfigURI = false; - CF::Properties execParameters = component->getExecParameters(); - for (unsigned int i = 0; i < execParameters.length(); ++i) { - const std::string propid(execParameters[i].id); - if (propid == "LOGGING_CONFIG_URI") { - alreadyHasLoggingConfigURI = true; - break; - } - } - // If LOGGING_CONFIG_URI isn't already an exec param, add it - // Otherwise, don't override component exec param value - if (!alreadyHasLoggingConfigURI) { - // Add LOGGING_CONFIG_URI as an exec param now so that it can be set to the overridden value - CF::DataType lcuri = initConfiguration[initCount]; - component->addExecParameter(lcuri); - LOG_TRACE(ApplicationFactory_impl, "Adding LOGGING_CONFIG_URI as exec param with value " - << ossie::any_to_string(lcuri.value)); - } - } else { - LOG_TRACE(ApplicationFactory_impl, "Overriding property " << init_id - << " with " << ossie::any_to_string(initConfiguration[initCount].value)); - component->overrideProperty(init_id.c_str(), initConfiguration[initCount].value); - } - } -} - CF::AllocationManager::AllocationResponseSequence* createHelper::allocateUsesDeviceProperties(const std::vector& usesDevices, const CF::Properties& configureProperties) { CF::AllocationManager::AllocationRequestSequence request; @@ -1951,7 +1917,6 @@ void createHelper::loadAndExecuteComponents(const DeploymentList& deployments, for (unsigned int rc_idx = 0; rc_idx < deployments.size (); rc_idx++) { ossie::ComponentDeployment* deployment = deployments[rc_idx]; - ossie::ComponentInfo* component = deployment->getComponent(); const ossie::SoftPkg* softpkg = deployment->getSoftPkg(); const ossie::ComponentInstantiation* instantiation = deployment->getInstantiation(); const ossie::SPD::Implementation* implementation = deployment->getImplementation(); @@ -2031,92 +1996,47 @@ void createHelper::loadAndExecuteComponents(const DeploymentList& deployments, // 5. A (SharedLibrary) With a code entrypoint element means load and CF Device::execute. if (((deployment->getCodeType() == CF::LoadableDevice::EXECUTABLE) || (deployment->getCodeType() == CF::LoadableDevice::SHARED_LIBRARY)) && (deployment->getEntryPoint().size() != 0)) { + attemptComponentExecution(_appReg, deployment); + } + } +} - // See if the LOGGING_CONFIG_URI has already been set - // via or initParams - bool alreadyHasLoggingConfigURI = false; - std::string logging_uri(""); - CF::DataType* logcfg_prop = NULL; - CF::Properties execParameters = component->getExecParameters(); - const ossie::ComponentInstantiation* instantiation = deployment->getInstantiation(); - for (unsigned int i = 0; i < execParameters.length(); ++i) { - std::string propid = static_cast(execParameters[i].id); - if (propid == "LOGGING_CONFIG_URI") { - logcfg_prop = &execParameters[i]; - const char* tmpstr; - if ( ossie::any::isNull(logcfg_prop->value) == true ) { - LOG_WARN(ApplicationFactory_impl, "Missing value for LOGGING_CONFIG_URI, component: " - << _baseNamingContext << "/" - << instantiation->getFindByNamingServiceName()); - } - else { - logcfg_prop->value >>= tmpstr; - LOG_TRACE(ApplicationFactory_impl, "Resource logging configuration provided, logcfg:" << tmpstr); - logging_uri = string(tmpstr); - alreadyHasLoggingConfigURI = true; - } - break; - } - } - - ossie::logging::LogConfigUriResolverPtr logcfg_resolver = ossie::logging::GetLogConfigUriResolver(); +std::string createHelper::resolveLoggingConfiguration(ossie::ComponentDeployment* deployment) +{ + // Use the log config resolver (if enabled) + const ossie::ComponentInstantiation* instantiation = deployment->getInstantiation(); + if (_appFact._domainManager->getUseLogConfigResolver()) { + ossie::logging::LogConfigUriResolverPtr logcfg_resolver = ossie::logging::GetLogConfigUriResolver(); + if (logcfg_resolver) { std::string logcfg_path = ossie::logging::GetComponentPath(_appFact._domainName, _waveformContextName, instantiation->getFindByNamingServiceName()); - if ( _appFact._domainManager->getUseLogConfigResolver() && logcfg_resolver ) { - std::string t_uri = logcfg_resolver->get_uri( logcfg_path ); - LOG_DEBUG(ApplicationFactory_impl, "Using LogConfigResolver plugin: path " << logcfg_path << " logcfg:" << t_uri ); - if ( !t_uri.empty() ) logging_uri = t_uri; - } - - if (!alreadyHasLoggingConfigURI && logging_uri.empty() ) { - // Query the DomainManager for the logging configuration - LOG_TRACE(ApplicationFactory_impl, "Checking DomainManager for LOGGING_CONFIG_URI"); - PropertyInterface *log_prop = _appFact._domainManager->getPropertyFromId("LOGGING_CONFIG_URI"); - StringProperty *logProperty = (StringProperty *)log_prop; - if (!logProperty->isNil()) { - logging_uri = logProperty->getValue(); - } else { - LOG_TRACE(ApplicationFactory_impl, "DomainManager LOGGING_CONFIG_URI is not set"); - } - - rh_logger::LoggerPtr dom_logger = _appFact._domainManager->getLogger(); - if ( dom_logger ) { - rh_logger::LevelPtr dlevel = dom_logger->getLevel(); - if ( !dlevel ) dlevel = rh_logger::Logger::getRootLogger()->getLevel(); - CF::DataType prop; - prop.id = "DEBUG_LEVEL"; - prop.value <<= static_cast(ossie::logging::ConvertRHLevelToDebug( dlevel )); - component->addExecParameter(prop); - } - } - - // if we have a uri but no property, add property to component's exec param list - if ( logcfg_prop == NULL && !logging_uri.empty() ) { - CF::DataType prop; - prop.id = "LOGGING_CONFIG_URI"; - prop.value <<= logging_uri.c_str(); - LOG_DEBUG(ApplicationFactory_impl, "logcfg_prop == NULL " << prop.id << " / " << logging_uri ); - component->addExecParameter(prop); + std::string uri = logcfg_resolver->get_uri(logcfg_path); + LOG_DEBUG(ApplicationFactory_impl, "Using LogConfigResolver plugin: path " << logcfg_path + << " logcfg:" << uri ); + if (!uri.empty()) { + return uri; } + } + } - if (!logging_uri.empty()) { - if (logging_uri.substr(0, 4) == "sca:") { - string fileSysIOR = ossie::corba::objectToString(_appFact._domainManager->_fileMgr); - logging_uri += ("?fs=" + fileSysIOR); - LOG_TRACE(ApplicationFactory_impl, "Adding file system IOR " << logging_uri); - } + // Ask the component for its configuration + std::string logging_uri = deployment->getLoggingConfiguration(); + if (!logging_uri.empty()) { + LOG_TRACE(ApplicationFactory_impl, "Resource logging configuration provided, logcfg:" << logging_uri); + return logging_uri; + } - LOG_DEBUG(ApplicationFactory_impl, " LOGGING_CONFIG_URI :" << logging_uri); - CORBA::Any loguri; - loguri <<= logging_uri.c_str(); - // this overrides all instances of the property called LOGGING_CONFIG_URI - LOG_TRACE(ApplicationFactory_impl, "override ....... uri " << logging_uri ); - component->overrideProperty("LOGGING_CONFIG_URI", loguri); - } - - attemptComponentExecution(_appReg, deployment); - } + // Query the DomainManager for the logging configuration + LOG_TRACE(ApplicationFactory_impl, "Checking DomainManager for LOGGING_CONFIG_URI"); + PropertyInterface* log_prop = _appFact._domainManager->getPropertyFromId("LOGGING_CONFIG_URI"); + StringProperty* logProperty = dynamic_cast(log_prop); + if (!logProperty->isNil()) { + logging_uri = logProperty->getValue(); + } else { + LOG_TRACE(ApplicationFactory_impl, "DomainManager LOGGING_CONFIG_URI is not set"); } + + return logging_uri; } void createHelper::attemptComponentExecution (CF::ApplicationRegistrar_ptr registrar, @@ -2156,6 +2076,29 @@ void createHelper::attemptComponentExecution (CF::ApplicationRegistrar_ptr regis execParameters["DOM_PATH"] = _baseNamingContext; execParameters["PROFILE_NAME"] = softpkg->getSPDFile(); + // Pass logging configuration + std::string logging_uri = resolveLoggingConfiguration(deployment); + if (!logging_uri.empty()) { + // Check for sca: URI type, and append the IOR for the file system + if (logging_uri.find("sca:/") == 0) { + string ior = ossie::corba::objectToString(_appFact._domainManager->_fileMgr); + logging_uri += ("?fs=" + ior); + LOG_TRACE(ApplicationFactory_impl, "Adding file system IOR " << logging_uri); + } + LOG_DEBUG(ApplicationFactory_impl, " LOGGING_CONFIG_URI: " << logging_uri); + execParameters["LOGGING_CONFIG_URI"] = logging_uri; + } else { + // No LOGGING_CONFIG_URI can be found, pass DEBUG_LEVEL + rh_logger::LoggerPtr dom_logger = _appFact._domainManager->getLogger(); + if (dom_logger) { + rh_logger::LevelPtr dlevel = dom_logger->getLevel(); + if (!dlevel) { + dlevel = rh_logger::Logger::getRootLogger()->getLevel(); + } + execParameters["DEBUG_LEVEL"] = static_cast(ossie::logging::ConvertRHLevelToDebug(dlevel)); + } + } + // Add the Naming Context IOR last to make it easier to parse the command line execParameters["NAMING_CONTEXT_IOR"] = ossie::corba::objectToString(registrar); diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index fbffc087d..76685fb33 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -390,8 +390,15 @@ redhawk::PropertyMap ComponentDeployment::getCommandLineParameters() const properties.push_back(dt); } } - } - return properties; + } + + // Handle special Docker image property if set in component instantiation + const ComponentProperty* docker = getPropertyOverride("__DOCKER_IMAGE__"); + if (docker) { + properties["__DOCKER_IMAGE__"] = dynamic_cast(docker)->getValue(); + } + + return properties; } redhawk::PropertyMap ComponentDeployment::getInitialConfigureProperties() const @@ -407,12 +414,6 @@ redhawk::PropertyMap ComponentDeployment::getInitialConfigureProperties() const } } } - - // Handle special Docker image property if set in component instantiation - const ComponentProperty* docker = getPropertyOverride("__DOCKER_IMAGE__"); - if (docker) { - properties["__DOCKER_IMAGE__"] = dynamic_cast(docker)->getValue(); - } return properties; } @@ -501,6 +502,42 @@ void ComponentDeployment::load(Application_impl* application, CF::FileSystem_ptr SoftpkgDeployment::load(application, fileSystem, device, identifier); } +std::string ComponentDeployment::getLoggingConfiguration() const +{ + // Check for a runtime override first + redhawk::PropertyMap::const_iterator override = overrides.find("LOGGING_CONFIG_URI"); + if (override != overrides.end()) { + if (override->getValue().isNil()) { + return std::string(); + } else { + return override->getValue().toString(); + } + } + + // Then, check for an override in the component instantiation + const ComponentProperty* propref = getPropertyOverride("LOGGING_CONFIG_URI"); + if (propref) { + const SimplePropertyRef* simple = dynamic_cast(propref); + if (!simple) { + return std::string(); + } else { + return simple->getValue(); + } + } + + // Finally, check for a PRF value + if (softpkg->getProperties()) { + const Property* property = softpkg->getProperties()->getProperty("LOGGING_CONFIG_URI"); + if (property) { + const SimpleProperty* simple = dynamic_cast(property); + if (simple && simple->getValue()) { + return simple->getValue(); + } + } + } + + return std::string(); +} PlacementPlan::PlacementPlan() { @@ -679,12 +716,16 @@ void ApplicationDeployment::applyCpuReservations(const CpuReservations& reservat void ApplicationDeployment::overrideAssemblyControllerProperties(ComponentDeployment* deployment) { BOOST_FOREACH(const redhawk::PropertyType& override, initConfiguration) { - if (override.getId() == "LOGGING_CONFIG_URI") { - // TODO: Handle logging configuration + const std::string propid = override.getId(); + if (propid == "LOGGING_CONFIG_URI") { + if (deployment->getLoggingConfiguration().empty()) { + RH_NL_TRACE("ApplicationFactory_impl", "Adding LOGGING_CONFIG_URI as a command line parameter with value " << override.getValue().toString()); + deployment->overrideProperty(propid, override.getValue()); + } } else { - RH_NL_TRACE("ApplicationFactory_impl", "Overriding property " << override.id + RH_NL_TRACE("ApplicationFactory_impl", "Overriding property " << propid << " with " << override.getValue().toString()); - deployment->overrideProperty(override.getId(), override.getValue()); + deployment->overrideProperty(propid, override.getValue()); } } } diff --git a/redhawk/src/control/sdr/dommgr/Deployment.h b/redhawk/src/control/sdr/dommgr/Deployment.h index 55cd8e549..cc4ae900a 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.h +++ b/redhawk/src/control/sdr/dommgr/Deployment.h @@ -165,6 +165,8 @@ namespace ossie { void load(Application_impl* application, CF::FileSystem_ptr fileSystem, CF::LoadableDevice_ptr device); + std::string getLoggingConfiguration() const; + protected: CF::DataType getPropertyValue(const Property* property) const; const ComponentProperty* getPropertyOverride(const std::string& id) const; diff --git a/redhawk/src/control/sdr/dommgr/createHelper.h b/redhawk/src/control/sdr/dommgr/createHelper.h index a908f82c6..41883fb66 100644 --- a/redhawk/src/control/sdr/dommgr/createHelper.h +++ b/redhawk/src/control/sdr/dommgr/createHelper.h @@ -104,7 +104,6 @@ class createHelper typedef std::vector OSList; // createHelper helper methods - void overrideProperties(const CF::Properties& initConfiguration, ossie::ComponentInfo* component); void assignPlacementsToDevices(ossie::ApplicationDeployment& appDeployment, const DeviceAssignmentMap& devices); void _validateDAS(ossie::ApplicationDeployment& appDeployment, const DeviceAssignmentMap& deviceAssignments); @@ -178,6 +177,7 @@ class createHelper std::vector& connections, std::string base_naming_context); + std::string resolveLoggingConfiguration(ossie::ComponentDeployment* deployment); std::vector getStartOrder(const DeploymentList& deployments); // Cleanup - used when create fails/doesn't succeed for some reason From 6a8c9f28b516d6fbfdf612d79588ee021d3cf0d2 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 31 May 2016 16:54:07 -0400 Subject: [PATCH 0326/1644] Remove all properties except for affinity options from ComponentInfo --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 10 -- redhawk/src/control/sdr/dommgr/Deployment.cpp | 50 +++++-- .../control/sdr/dommgr/applicationSupport.cpp | 125 ------------------ .../control/sdr/dommgr/applicationSupport.h | 12 -- 4 files changed, 36 insertions(+), 161 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index a62a8fc3a..34df068bd 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -1793,16 +1793,6 @@ ossie::ComponentInfo* createHelper::buildComponentInfo(CF::FileSystem_ptr fileSy } newComponent->setAffinity( instance.getAffinity() ); - - const ossie::ComponentPropertyList & ins_prop = instance.getProperties(); - - for (unsigned int i = 0; i < ins_prop.size(); ++i) { - if (ins_prop[i]._id == "__DOCKER_IMAGE__") { - continue; - } - newComponent->overrideProperty(&ins_prop[i]); - } - return newComponent; } diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index 76685fb33..fbf00bb59 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -227,6 +227,26 @@ ComponentDeployment::ComponentDeployment(ComponentInfo* component, identifier(identifier), affinityOptions(component->getAffinityOptions()) { + // If the SoftPkg has an associated Properties, check the overrides for + // validity + if (softpkg->getProperties()) { + BOOST_FOREACH(const ComponentProperty& override, instantiation->getProperties()) { + const Property* property = softpkg->getProperties()->getProperty(override.getID()); + if (!property) { + if (override.getID() == "LOGGING_CONFIG_URI") { + // It's legal to override the logging configuration, even + // if it isn't defined in the PRF + } else { + RH_NL_WARN("ApplicationFactory_impl", "Ignoring attempt to override property " + << override.getID() << " that does not exist in component"); + } + } else if (property->isReadOnly() && !property->isProperty()) { + // Only 'property' kind supports overrides if it's read-only + RH_NL_WARN("ApplicationFactory_impl", "Ignoring attempt to override read-only property " + << property->getID()); + } + } + } } ComponentInfo* ComponentDeployment::getComponent() @@ -378,8 +398,8 @@ redhawk::PropertyMap ComponentDeployment::getCommandLineParameters() const BOOST_FOREACH(const Property* property, softpkg->getProperties()->getProperties()) { if (property->isExecParam()) { if (property->isReadOnly()) { - RH_NL_WARN("ApplicationFactory_impl", "Ignoring attempt to override readonly property " - << property->getID()); + // NB: Not only can read-only execparams not be overridden, + // they are not included in the command line continue; } } else if (!(property->isProperty() && property->isCommandLine())) { @@ -440,19 +460,21 @@ void ComponentDeployment::overrideProperty(const std::string& id, const CORBA::A CF::DataType ComponentDeployment::getPropertyValue(const Property* property) const { - // Check for a runtime override first - redhawk::PropertyMap::const_iterator override = overrides.find(property->getID()); - if (override != overrides.end()) { - return *override; - } - // Then, check for an override in the component instantiation - const ComponentProperty* propref = getPropertyOverride(property->getID()); - if (propref) { - return ossie::overridePropertyValue(property, propref); - } else { - // Default to the PRF value - return ossie::convertPropertyToDataType(property); + // Only allow overrides for writable or 'property' kind properties + if (!property->isReadOnly() || property->isProperty()) { + // Check for a runtime override first + redhawk::PropertyMap::const_iterator override = overrides.find(property->getID()); + if (override != overrides.end()) { + return *override; + } + // Then, check for an override in the component instantiation + const ComponentProperty* propref = getPropertyOverride(property->getID()); + if (propref) { + return ossie::overridePropertyValue(property, propref); + } } + // Default to the PRF value + return ossie::convertPropertyToDataType(property); } const ComponentProperty* ComponentDeployment::getPropertyOverride(const std::string& id) const diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp index 5f0d7f2e3..a8c72fe80 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp @@ -69,65 +69,6 @@ ComponentInfo* ComponentInfo::buildComponentInfoFromSPDFile(const SoftPkg* softp LOG_TRACE(ComponentInfo, "Building component info from softpkg " << softpkg->getName()); ossie::ComponentInfo* newComponent = new ossie::ComponentInfo(softpkg, instantiation); - - // Extract Properties from the implementation-agnostic PRF file - // once we match the component to a device we can grab the implementation - // specific PRF file - if (softpkg->getProperties()) { - // Handle component properties - Properties& prf = *softpkg->getProperties(); - LOG_TRACE(ComponentInfo, "Adding exec params") - const std::vector& eprop = prf.getExecParamProperties(); - for (unsigned int i = 0; i < eprop.size(); i++) { - if (!eprop[i]->isReadOnly()) { - LOG_TRACE(ComponentInfo, "Adding exec param " << eprop[i]->getID() << " " << eprop[i]->getName()); - newComponent->addExecParameter(convertPropertyToDataType(eprop[i])); - } else { - LOG_TRACE(ComponentInfo, "Ignoring readonly exec param " << eprop[i]->getID() << " " << eprop[i]->getName()); - } - } - - // According to SCA 2.2.2 Appendix D 4.1.1.6 the only properties - // that are to be sent to allocateCapacity are device - // properties that are external. Furthermore, the SPD list's its - // needs, not in the PRF file, but in the SPD file - // element - // prop = prf->getMatchingProperties(); - //for (unsigned int i=0; i < prop->size(); i++) { - // newComponent->addAllocationCapacity((*prop)[i]->getDataType()); - //} - - const std::vector& prop = prf.getConfigureProperties(); - for (unsigned int i = 0; i < prop.size(); i++) { - if (!prop[i]->isReadOnly()) { - LOG_TRACE(ComponentInfo, "Adding configure prop " << prop[i]->getID() << " " << prop[i]->getName() << " " << prop[i]->isReadOnly()) - newComponent->addConfigureProperty(convertPropertyToDataType(prop[i])); - } - } - - const std::vector& cprop = prf.getConstructProperties(); - for (unsigned int i = 0; i < cprop.size(); i++) { - LOG_TRACE(ComponentInfo, "Adding construct prop " << cprop[i]->getID() << " " << cprop[i]->getName() << " " << cprop[i]->isReadOnly()); - bool isExec = false; - std::string cprop_id(cprop[i]->getID()); - for (unsigned int ei = 0; ei < eprop.size(); ei++) { - std::string eprop_id(eprop[ei]->getID()); - if (eprop_id == cprop_id) { - isExec = true; - break; - } - } - if (isExec) - continue; - if (cprop[i]->isCommandLine()) { - if (not cprop[i]->isNone()) { - newComponent->addExecParameter(convertPropertyToDataType(cprop[i])); - } - } - } - - } - LOG_TRACE(ComponentInfo, "Done building component info from soft package " << softpkg->getName()); return newComponent; } @@ -177,73 +118,7 @@ void ComponentInfo::setAffinity( const AffinityProperties &affinity_props ) } -void ComponentInfo::addExecParameter(CF::DataType dt) -{ - addProperty(dt, execParameters); -} - -void ComponentInfo::addConfigureProperty(CF::DataType dt) -{ - addProperty(dt, configureProperties); -} - -void ComponentInfo::overrideProperty(const ossie::ComponentProperty* propref) { - std::string propId = propref->getID(); - LOG_TRACE(ComponentInfo, "Instantiation property id = " << propId); - const Property* prop = 0; - if (spd->getProperties()) { - prop = spd->getProperties()->getProperty(propId); - } - // Without a prop, we don't know how to convert the strings to the property any type - if (!prop) { - LOG_WARN(ComponentInfo, "ignoring attempt to override property " << propId << " that does not exist in component") - return; - } - - CF::DataType dt = overridePropertyValue(prop, propref); - overrideProperty(dt.id, dt.value); -} - -void ComponentInfo::overrideProperty(const char* id, const CORBA::Any& value) -{ - const Property* prop = 0; - if (spd->getProperties()) { - prop = spd->getProperties()->getProperty(id); - if (prop && prop->isReadOnly()) { - LOG_WARN(ComponentInfo, "ignoring attempt to override readonly property " << id); - return; - } - } - process_overrides(&configureProperties, id, value); - process_overrides(&execParameters, id, value); -} - - - -void ComponentInfo::process_overrides(CF::Properties* props, const char* id, CORBA::Any value) -{ - LOG_DEBUG(ComponentInfo, "Attempting to override property " << id); - for (unsigned int i = 0; i < (*props).length(); ++i ) { - if (strcmp(id, (*props)[i].id) == 0) { - LOG_DEBUG(ComponentInfo, "Overriding property " << id << " with value " << ossie::any_to_string(value)); - (*props)[i].value = value; - } - } - return; -} - CF::Properties ComponentInfo::getAffinityOptions() const { return affinityOptions; } - -CF::Properties ComponentInfo::getConfigureProperties() const -{ - return configureProperties; -} - - -CF::Properties ComponentInfo::getExecParameters() -{ - return execParameters; -} diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.h b/redhawk/src/control/sdr/dommgr/applicationSupport.h index 6f66da6f2..5ec43b758 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.h +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.h @@ -73,15 +73,7 @@ namespace ossie void setAffinity( const AffinityProperties &affinity ); - void addExecParameter(CF::DataType dt); - void addConfigureProperty(CF::DataType dt); - - void overrideProperty(const ossie::ComponentProperty* propref); - void overrideProperty(const char* id, const CORBA::Any& value); - - CF::Properties getConfigureProperties() const; CF::Properties getAffinityOptions() const; - CF::Properties getExecParameters(); static ComponentInfo* buildComponentInfoFromSPDFile(const SoftPkg* softpkg, const ComponentInstantiation* instantiation); @@ -89,12 +81,8 @@ namespace ossie private: ComponentInfo (const ComponentInfo&); - void process_overrides(CF::Properties* props, const char* id, CORBA::Any value); - ossie::Properties _affinity_prf; - CF::Properties configureProperties; - CF::Properties execParameters; CF::Properties affinityOptions; const ComponentInstantiation* instantiation; From d08514ba49e68e17d1baa1ceded45348ccfdd823 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 1 Jun 2016 09:32:06 -0400 Subject: [PATCH 0327/1644] Move ApplicationComponent to PersistenceStore.h --- .../src/control/sdr/dommgr/Application_impl.h | 2 +- .../src/control/sdr/dommgr/PersistenceStore.h | 16 +++++++++++++++- .../src/control/sdr/dommgr/applicationSupport.h | 12 ------------ 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/Application_impl.h b/redhawk/src/control/sdr/dommgr/Application_impl.h index 6a98489cb..807cb9020 100644 --- a/redhawk/src/control/sdr/dommgr/Application_impl.h +++ b/redhawk/src/control/sdr/dommgr/Application_impl.h @@ -32,7 +32,7 @@ #include #include -#include "applicationSupport.h" +#include "PersistenceStore.h" #include "connectionSupport.h" diff --git a/redhawk/src/control/sdr/dommgr/PersistenceStore.h b/redhawk/src/control/sdr/dommgr/PersistenceStore.h index 9a7702660..e2888719c 100644 --- a/redhawk/src/control/sdr/dommgr/PersistenceStore.h +++ b/redhawk/src/control/sdr/dommgr/PersistenceStore.h @@ -25,7 +25,9 @@ #include #include -#include "applicationSupport.h" +#include +#include + #include "connectionSupport.h" @@ -93,6 +95,18 @@ namespace ossie { typedef std::map AllocationTable; typedef std::map RemoteAllocationTable; + struct ApplicationComponent { + std::string identifier; + std::string softwareProfile; + std::string namingContext; + std::string implementationId; + std::vector loadedFiles; + unsigned long processId; + CORBA::Object_var componentObject; + CF::Device_var assignedDevice; + }; + typedef std::list ComponentList; + struct ApplicationNode { std::string name; std::string profile; diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.h b/redhawk/src/control/sdr/dommgr/applicationSupport.h index 5ec43b758..26a2c1367 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.h +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.h @@ -42,18 +42,6 @@ namespace ossie { - struct ApplicationComponent { - std::string identifier; - std::string softwareProfile; - std::string namingContext; - std::string implementationId; - std::vector loadedFiles; - unsigned long processId; - CORBA::Object_var componentObject; - CF::Device_var assignedDevice; - }; - typedef std::list ComponentList; - /* Base class to contain data for components * - Used to store information about about components */ From 8a7f50e067a91314d805dba353d91fbea6740167 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 1 Jun 2016 10:25:21 -0400 Subject: [PATCH 0328/1644] Move affinity property handling to a utility function --- redhawk/src/control/framework/prop_utils.cpp | 39 +++++++++++++++++++ .../src/control/include/ossie/prop_utils.h | 2 + .../sdr/dommgr/ApplicationFactory_impl.cpp | 1 - redhawk/src/control/sdr/dommgr/Deployment.cpp | 17 ++++---- redhawk/src/control/sdr/dommgr/Deployment.h | 5 +-- .../control/sdr/dommgr/applicationSupport.cpp | 35 ----------------- .../control/sdr/dommgr/applicationSupport.h | 11 ------ 7 files changed, 50 insertions(+), 60 deletions(-) diff --git a/redhawk/src/control/framework/prop_utils.cpp b/redhawk/src/control/framework/prop_utils.cpp index 367a25b53..59bcff84f 100644 --- a/redhawk/src/control/framework/prop_utils.cpp +++ b/redhawk/src/control/framework/prop_utils.cpp @@ -28,9 +28,13 @@ #include "omniORB4/CORBA.h" #endif +#include +#include + #include #include #include +#include #include using namespace ossie; @@ -701,3 +705,38 @@ CF::Properties ossie::getPartialStructs(const CF::Properties& properties) } return partials; } + +CF::Properties ossie::getAffinityOptions(const ComponentInstantiation::AffinityProperties& affinityProps) +{ + // Store parsed affinity properties as a static singleton, protecting the + // load with a mutex; if the definitions are not set + static boost::scoped_ptr definitions; + static boost::mutex mutex; + if (!definitions) { + boost::mutex::scoped_lock lock(mutex); + if (!definitions) { + // Set the singleton first, under the assumption that if load fails + // once it will always fail, so that it doesn't re-try every time + definitions.reset(new ossie::Properties()); + try { + std::stringstream xml(redhawk::affinity::get_property_definitions()); + LOG_TRACE(prop_utils, "Loading affinity definitions: " << xml.str()); + definitions->load(xml); + } catch (...) { + LOG_WARN(prop_utils, "Error loading affinity defintions from library"); + } + } + } + + CF::Properties options; + BOOST_FOREACH(const ossie::ComponentProperty& propref, affinityProps) { + const Property* prop = definitions->getProperty(propref.getID()); + if (prop) { + CF::DataType dt = overridePropertyValue(prop, &propref); + ossie::corba::push_back(options, dt); + } else { + LOG_WARN(prop_utils, "Ignoring unknown affinity property " << propref.getID()); + } + } + return options; +} diff --git a/redhawk/src/control/include/ossie/prop_utils.h b/redhawk/src/control/include/ossie/prop_utils.h index f32c90ec6..6360de7f3 100644 --- a/redhawk/src/control/include/ossie/prop_utils.h +++ b/redhawk/src/control/include/ossie/prop_utils.h @@ -78,6 +78,8 @@ namespace ossie bool structContainsMixedNilValues(const CF::Properties& properties); CF::Properties getPartialStructs(const CF::Properties& properties); + + CF::Properties getAffinityOptions(const ComponentInstantiation::AffinityProperties& affinityProps); } #endif diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 34df068bd..0a751585b 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -1792,7 +1792,6 @@ ossie::ComponentInfo* createHelper::buildComponentInfo(CF::FileSystem_ptr fileSy LOG_WARN(ApplicationFactory_impl, "component instantiation is sca compliant but does not provide a 'findcomponent' name...this is probably an error"); } - newComponent->setAffinity( instance.getAffinity() ); return newComponent; } diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index fbf00bb59..5ecac2e47 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -218,14 +218,13 @@ CF::LoadableDevice::LoadType SoftpkgDeployment::getCodeType() const } } -ComponentDeployment::ComponentDeployment(ComponentInfo* component, +ComponentDeployment::ComponentDeployment(const SoftPkg* softpkg, const ComponentInstantiation* instantiation, const std::string& identifier) : - SoftpkgDeployment(component->spd), - component(component), + SoftpkgDeployment(softpkg), instantiation(instantiation), identifier(identifier), - affinityOptions(component->getAffinityOptions()) + affinityOptions() { // If the SoftPkg has an associated Properties, check the overrides for // validity @@ -247,11 +246,11 @@ ComponentDeployment::ComponentDeployment(ComponentInfo* component, } } } -} -ComponentInfo* ComponentDeployment::getComponent() -{ - return component; + if (!instantiation->getAffinity().empty()) { + RH_NL_TRACE("ApplicationFactory_impl", "Setting affinity options"); + affinityOptions = ossie::getAffinityOptions(instantiation->getAffinity()); + } } const std::string& ComponentDeployment::getIdentifier() const @@ -689,7 +688,7 @@ ComponentDeployment* ApplicationDeployment::createComponentDeployment(ComponentI const ComponentInstantiation* instantiation = component->getInstantiation(); std::string component_id = instantiation->getID() + ":" + instanceName; - ComponentDeployment* deployment = new ComponentDeployment(component, instantiation, component_id); + ComponentDeployment* deployment = new ComponentDeployment(component->spd, instantiation, component_id); components.push_back(deployment); // Override properties from initial configuration diff --git a/redhawk/src/control/sdr/dommgr/Deployment.h b/redhawk/src/control/sdr/dommgr/Deployment.h index cc4ae900a..efdd52b6b 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.h +++ b/redhawk/src/control/sdr/dommgr/Deployment.h @@ -100,11 +100,9 @@ namespace ossie { class ComponentDeployment : public SoftpkgDeployment, public UsesDeviceDeployment { public: - ComponentDeployment(ComponentInfo* component, const ComponentInstantiation* instantiation, + ComponentDeployment(const SoftPkg* softpkg, const ComponentInstantiation* instantiation, const std::string& identifier); - ComponentInfo* getComponent(); - /** * @brief Returns the component's runtime identifier */ @@ -171,7 +169,6 @@ namespace ossie { CF::DataType getPropertyValue(const Property* property) const; const ComponentProperty* getPropertyOverride(const std::string& id) const; - ComponentInfo* component; const ComponentInstantiation* instantiation; const std::string identifier; diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp index a8c72fe80..d0b92ba26 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp @@ -77,15 +77,6 @@ ComponentInfo::ComponentInfo(const SoftPkg* softpkg, const ComponentInstantiatio spd(softpkg), instantiation(instantiation) { - // load common affinity property definitions - try { - std::stringstream os(redhawk::affinity::get_property_definitions()); - LOG_TRACE(ComponentInfo, "affinity definitions: " << os.str()); - _affinity_prf.load(os); - } - catch(...){ - LOG_WARN(ComponentInfo, "Error loading affinity definitions from library." ); - } } ComponentInfo::~ComponentInfo () @@ -96,29 +87,3 @@ const ComponentInstantiation* ComponentInfo::getInstantiation() const { return instantiation; } - -void ComponentInfo::setAffinity( const AffinityProperties &affinity_props ) -{ - - for (unsigned int i = 0; i < affinity_props.size(); ++i) { - const ossie::ComponentProperty* propref = &(affinity_props[i]); - std::string propId = propref->getID(); - LOG_DEBUG(ComponentInfo, "Affinity property id = " << propId); - const Property* prop = _affinity_prf.getProperty(propId); - // Without a prop, we don't know how to convert the strings to the property any type - if (prop == NULL) { - LOG_WARN(ComponentInfo, "ignoring attempt to override property " << propId << " that does not exist in component"); - continue; - } - - // add property - CF::DataType dt = overridePropertyValue(prop, propref); - addProperty( dt, affinityOptions ); - } - -} - -CF::Properties ComponentInfo::getAffinityOptions() const -{ - return affinityOptions; -} diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.h b/redhawk/src/control/sdr/dommgr/applicationSupport.h index 26a2c1367..3ff60f712 100644 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.h +++ b/redhawk/src/control/sdr/dommgr/applicationSupport.h @@ -50,8 +50,6 @@ namespace ossie ENABLE_LOGGING public: - typedef ossie::ComponentInstantiation::AffinityProperties AffinityProperties; - ComponentInfo (const SoftPkg* softpkg, const ComponentInstantiation* instantiation); ~ComponentInfo (); @@ -59,20 +57,11 @@ namespace ossie const ComponentInstantiation* getInstantiation() const; - void setAffinity( const AffinityProperties &affinity ); - - CF::Properties getAffinityOptions() const; - static ComponentInfo* buildComponentInfoFromSPDFile(const SoftPkg* softpkg, const ComponentInstantiation* instantiation); private: ComponentInfo (const ComponentInfo&); - - ossie::Properties _affinity_prf; - - CF::Properties affinityOptions; - const ComponentInstantiation* instantiation; }; From ddcf0042ff1960740ff68597367c1d4cdca8e829 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 1 Jun 2016 10:40:13 -0400 Subject: [PATCH 0329/1644] Remove all use of ComponentInfo from the deployment classes --- .../control/sdr/dommgr/ApplicationFactory_impl.cpp | 14 +++++++++----- redhawk/src/control/sdr/dommgr/Deployment.cpp | 6 +++--- redhawk/src/control/sdr/dommgr/Deployment.h | 3 ++- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 0a751585b..2b1723a65 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -638,15 +638,17 @@ void createHelper::assignPlacementsToDevices(ossie::ApplicationDeployment& appDe LOG_TRACE(ApplicationFactory_impl, "-- Completed placement for Collocation ID:" << (*plan)->getId() << " Components Placed: " << components.size()); } else { - ComponentInfo* component = components[0]; + const SoftPkg* softpkg = components[0]->spd; + const ComponentInstantiation* instantiation = components[0]->getInstantiation(); std::string assigned_device; - DeviceAssignmentMap::const_iterator device = devices.find(component->getInstantiation()->getID()); + DeviceAssignmentMap::const_iterator device = devices.find(instantiation->getID()); if (device != devices.end()) { assigned_device = device->second; - LOG_TRACE(ApplicationFactory_impl, "Component " << component->getInstantiation()->getID() + LOG_TRACE(ApplicationFactory_impl, "Component " << instantiation->getID() << " is assigned to device " << assigned_device); } - ossie::ComponentDeployment* deployment = appDeployment.createComponentDeployment(component); + ossie::ComponentDeployment* deployment = appDeployment.createComponentDeployment(softpkg, + instantiation); allocateComponent(deployment, assigned_device, appDeployment.getIdentifier()); } } @@ -825,7 +827,9 @@ void createHelper::_placeHostCollocation(ossie::ApplicationDeployment& appDeploy DeploymentList deployments; for (PlacementList::const_iterator comp = components.begin(); comp != components.end(); ++comp) { - ossie::ComponentDeployment* deployment = appDeployment.createComponentDeployment(*comp); + const SoftPkg* softpkg = (*comp)->spd; + const ComponentInstantiation* instantiation = (*comp)->getInstantiation(); + ossie::ComponentDeployment* deployment = appDeployment.createComponentDeployment(softpkg, instantiation); deployments.push_back(deployment); } diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index 5ecac2e47..ebee335cd 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -681,14 +681,14 @@ redhawk::PropertyMap ApplicationDeployment::getAllocationContext() const return properties; } -ComponentDeployment* ApplicationDeployment::createComponentDeployment(ComponentInfo* component) +ComponentDeployment* ApplicationDeployment::createComponentDeployment(const SoftPkg* softpkg, + const ComponentInstantiation* instantiation) { // Create a unique identifier for this component instance by appending the // application instance's unique name - const ComponentInstantiation* instantiation = component->getInstantiation(); std::string component_id = instantiation->getID() + ":" + instanceName; - ComponentDeployment* deployment = new ComponentDeployment(component->spd, instantiation, component_id); + ComponentDeployment* deployment = new ComponentDeployment(softpkg, instantiation, component_id); components.push_back(deployment); // Override properties from initial configuration diff --git a/redhawk/src/control/sdr/dommgr/Deployment.h b/redhawk/src/control/sdr/dommgr/Deployment.h index efdd52b6b..8f77cf1e0 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.h +++ b/redhawk/src/control/sdr/dommgr/Deployment.h @@ -233,7 +233,8 @@ namespace ossie { ComponentInfo* getComponent(const std::string& instantiationId); - ComponentDeployment* createComponentDeployment(ComponentInfo* component); + ComponentDeployment* createComponentDeployment(const SoftPkg* softpkg, + const ComponentInstantiation* instantiation); const ComponentList& getComponentDeployments(); ComponentDeployment* getComponentDeployment(const std::string& instantiationId); From e030e4f18f95bde5a41badd42c453b1163ecd392 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 1 Jun 2016 11:10:41 -0400 Subject: [PATCH 0330/1644] Place components from the basic SoftwareAssembly data structures instead of PlacementPlan/ComponentInfo --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 81 ++++++++++--------- redhawk/src/control/sdr/dommgr/createHelper.h | 2 +- 2 files changed, 42 insertions(+), 41 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 2b1723a65..922cf8083 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -29,6 +29,7 @@ #include #include +#include #include #include @@ -627,30 +628,31 @@ void createHelper::_configureComponents(const DeploymentList& deployments) void createHelper::assignPlacementsToDevices(ossie::ApplicationDeployment& appDeployment, const DeviceAssignmentMap& devices) { - typedef ossie::ApplicationDeployment::PlacementList PlacementPlanList; - const PlacementPlanList& placements = appDeployment.getPlacements(); - for (PlacementPlanList::const_iterator plan = placements.begin(); plan != placements.end(); ++plan) { - const std::vector& components = (*plan)->getComponents(); - if (components.size() > 1) { - LOG_TRACE(ApplicationFactory_impl, "Placing host collocation " << (*plan)->getId() - << " " << (*plan)->getName()); - _placeHostCollocation(appDeployment, components, devices); - LOG_TRACE(ApplicationFactory_impl, "-- Completed placement for Collocation ID:" - << (*plan)->getId() << " Components Placed: " << components.size()); - } else { - const SoftPkg* softpkg = components[0]->spd; - const ComponentInstantiation* instantiation = components[0]->getInstantiation(); - std::string assigned_device; - DeviceAssignmentMap::const_iterator device = devices.find(instantiation->getID()); - if (device != devices.end()) { - assigned_device = device->second; - LOG_TRACE(ApplicationFactory_impl, "Component " << instantiation->getID() - << " is assigned to device " << assigned_device); - } - ossie::ComponentDeployment* deployment = appDeployment.createComponentDeployment(softpkg, - instantiation); - allocateComponent(deployment, assigned_device, appDeployment.getIdentifier()); + // Try to place all of the collocations first, since they naturally have + // more restrictive placement constraints + BOOST_FOREACH(const SoftwareAssembly::HostCollocation& collocation, _appFact._sadParser.getHostCollocations()) { + _placeHostCollocation(appDeployment, collocation, devices); + } + + // Place the remaining components one-by-one + BOOST_FOREACH(const ComponentPlacement& placement, _appFact._sadParser.getComponentPlacements()) { + const SoftPkg* softpkg = _appProfile.getSoftPkg(placement.componentFile->getFileName()); + // Even though it is possible for there to be more than one instantiation + // per component, the tooling doesn't support that, so supporting this at a + // framework level would add substantial complexity without providing any + // appreciable improvements. It is far easier to have multiple placements + // rather than multiple instantiations. + const ComponentInstantiation* instantiation = &(placement.getInstantiations()[0]); + std::string assigned_device; + DeviceAssignmentMap::const_iterator device = devices.find(instantiation->getID()); + if (device != devices.end()) { + assigned_device = device->second; + LOG_TRACE(ApplicationFactory_impl, "Component " << instantiation->getID() + << " is assigned to device " << assigned_device); } + ossie::ComponentDeployment* deployment = appDeployment.createComponentDeployment(softpkg, + instantiation); + allocateComponent(deployment, assigned_device, appDeployment.getIdentifier()); } } @@ -797,16 +799,23 @@ CF::Properties createHelper::_consolidateAllocations(const DeploymentList& deplo } void createHelper::_placeHostCollocation(ossie::ApplicationDeployment& appDeployment, - const PlacementList& components, + const ossie::SoftwareAssembly::HostCollocation& collocation, const DeviceAssignmentMap& devices) { + LOG_TRACE(ApplicationFactory_impl, "Placing host collocation " << collocation.getID() + << " " << collocation.getName()); + // Keep track of devices to which some of the components have // been assigned. DeviceIDList assignedDevices; - for (PlacementList::const_iterator placement = components.begin(); - placement != components.end(); - ++placement) { - DeviceAssignmentMap::const_iterator device = devices.find((*placement)->getInstantiation()->getID()); + DeploymentList deployments; + BOOST_FOREACH(const ComponentPlacement& placement, collocation.getComponents()) { + const SoftPkg* softpkg = _appProfile.getSoftPkg(placement.componentFile->getFileName()); + const ComponentInstantiation* instantiation = &(placement.getInstantiations()[0]); + ossie::ComponentDeployment* deployment = appDeployment.createComponentDeployment(softpkg, instantiation); + deployments.push_back(deployment); + + DeviceAssignmentMap::const_iterator device = devices.find(instantiation->getID()); if (device != devices.end()) { assignedDevices.push_back(device->second); } @@ -823,23 +832,15 @@ void createHelper::_placeHostCollocation(ossie::ApplicationDeployment& appDeploy } } - LOG_TRACE(ApplicationFactory_impl, "Placing " << components.size() << " components"); - - DeploymentList deployments; - for (PlacementList::const_iterator comp = components.begin(); comp != components.end(); ++comp) { - const SoftPkg* softpkg = (*comp)->spd; - const ComponentInstantiation* instantiation = (*comp)->getInstantiation(); - ossie::ComponentDeployment* deployment = appDeployment.createComponentDeployment(softpkg, instantiation); - deployments.push_back(deployment); - } - + LOG_TRACE(ApplicationFactory_impl, "Placing " << deployments.size() << " components"); if (!placeHostCollocation(appDeployment, deployments, deployments.begin(), deploymentDevices)) { std::ostringstream eout; - //eout << "Could not collocate components for collocation NAME: " << collocation.getName() << " ID:" << collocation.id; - eout << "Could not collocate components for collocation"; + eout << "Could not collocate components for collocation NAME: " << collocation.getName() << " ID:" << collocation.id; LOG_ERROR(ApplicationFactory_impl, eout.str()); throw CF::ApplicationFactory::CreateApplicationRequestError(); } + LOG_TRACE(ApplicationFactory_impl, "-- Completed placement for Collocation ID:" + << collocation.getID() << " Components Placed: " << deployments.size()); } void createHelper::_handleUsesDevices(ossie::ApplicationDeployment& appDeployment, diff --git a/redhawk/src/control/sdr/dommgr/createHelper.h b/redhawk/src/control/sdr/dommgr/createHelper.h index 41883fb66..419d58acf 100644 --- a/redhawk/src/control/sdr/dommgr/createHelper.h +++ b/redhawk/src/control/sdr/dommgr/createHelper.h @@ -113,7 +113,7 @@ class createHelper void setUpExternalPorts(ossie::ApplicationDeployment& appDeployment, Application_impl* application); void setUpExternalProperties(ossie::ApplicationDeployment& appDeployment, Application_impl* application); void _placeHostCollocation(ossie::ApplicationDeployment& appDeployment, - const PlacementList& collocatedComponents, + const ossie::SoftwareAssembly::HostCollocation& collocation, const DeviceAssignmentMap& devices); bool placeHostCollocation(ossie::ApplicationDeployment& appDeployment, const DeploymentList& components, From a4fdcaf00a4005146d8de9ba753dbe00bcedf00a Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 1 Jun 2016 11:53:07 -0400 Subject: [PATCH 0331/1644] Drop ComponentInfo structure entirely --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 33 +------ .../control/sdr/dommgr/ApplicationProfile.cpp | 97 ++----------------- .../control/sdr/dommgr/ApplicationProfile.h | 54 +---------- redhawk/src/control/sdr/dommgr/Deployment.cpp | 75 +------------- redhawk/src/control/sdr/dommgr/Deployment.h | 35 +------ redhawk/src/control/sdr/dommgr/Makefile.am | 3 +- .../control/sdr/dommgr/applicationSupport.h | 69 ------------- redhawk/src/control/sdr/dommgr/createHelper.h | 11 +-- 8 files changed, 24 insertions(+), 353 deletions(-) delete mode 100644 redhawk/src/control/sdr/dommgr/applicationSupport.h diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 922cf8083..585051232 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -1761,9 +1761,8 @@ ossie::SoftpkgDeployment* createHelper::resolveDependencyImplementation(const os return 0; } -ossie::ComponentInfo* createHelper::buildComponentInfo(CF::FileSystem_ptr fileSys, - const SoftwareAssembly& sadParser, - const ComponentPlacement& component) +void createHelper::checkComponentInfo(CF::FileSystem_ptr fileSys, + const ComponentPlacement& component) { // Even though it is possible for there to be more than one instantiation per component, // the tooling doesn't support that, so supporting this at a framework level would add @@ -1773,7 +1772,6 @@ ossie::ComponentInfo* createHelper::buildComponentInfo(CF::FileSystem_ptr fileSy const ComponentInstantiation& instance = instantiations[0]; // Extract required data from SPD file - ossie::ComponentInfo* newComponent = 0; LOG_TRACE(ApplicationFactory_impl, "Getting the SPD Filename"); const ComponentFile* componentfile = component.componentFile; if (!componentfile) { @@ -1783,21 +1781,9 @@ ossie::ComponentInfo* createHelper::buildComponentInfo(CF::FileSystem_ptr fileSy } LOG_TRACE(ApplicationFactory_impl, "Building Component Info From SPD File"); const SoftPkg* softpkg = _appProfile.getSoftPkg(componentfile->getFileName()); - newComponent = ossie::ComponentInfo::buildComponentInfoFromSPDFile(softpkg, &instance); - if (newComponent == 0) { - ostringstream eout; - eout << "Error loading component information for file ref " << component.getFileRefId(); - LOG_ERROR(ApplicationFactory_impl, eout.str()); - throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EINVAL, eout.str().c_str()); - } - - LOG_TRACE(ApplicationFactory_impl, "Done building Component Info From SPD File") - - if (newComponent->spd->isScaCompliant() && !instance.isNamingService()) { + if (softpkg->isScaCompliant() && !instance.isNamingService()) { LOG_WARN(ApplicationFactory_impl, "component instantiation is sca compliant but does not provide a 'findcomponent' name...this is probably an error"); } - - return newComponent; } /* Create a vector of all the components for the SAD associated with this App Factory @@ -1810,31 +1796,22 @@ void createHelper::getRequiredComponents(CF::FileSystem_ptr fileSys, { TRACE_ENTER(ApplicationFactory_impl); - const std::string assemblyControllerRefId = sadParser.getAssemblyControllerRefId(); - // Walk through the host collocations first const std::vector& collocations = sadParser.getHostCollocations(); for (size_t index = 0; index < collocations.size(); ++index) { const SoftwareAssembly::HostCollocation& collocation = collocations[index]; LOG_TRACE(ApplicationFactory_impl, "Building component info for host collocation " << collocation.getID()); - ossie::PlacementPlan* plan = new ossie::PlacementPlan(collocation.getID(), collocation.getName()); - appDeployment.addPlacement(plan); - const std::vector& placements = collocations[index].getComponents(); for (unsigned int i = 0; i < placements.size(); i++) { - ossie::ComponentInfo* component = buildComponentInfo(fileSys, sadParser, placements[i]); - plan->addComponent(component); + checkComponentInfo(fileSys, placements[i]); } } // Then, walk through the remaining non-collocated components const std::vector& componentsFromSAD = sadParser.getComponentPlacements(); for (unsigned int i = 0; i < componentsFromSAD.size(); i++) { - ossie::PlacementPlan* plan = new ossie::PlacementPlan(); - appDeployment.addPlacement(plan); - ossie::ComponentInfo* component = buildComponentInfo(fileSys, sadParser, componentsFromSAD[i]); - plan->addComponent(component); + checkComponentInfo(fileSys, componentsFromSAD[i]); } TRACE_EXIT(ApplicationFactory_impl); diff --git a/redhawk/src/control/sdr/dommgr/ApplicationProfile.cpp b/redhawk/src/control/sdr/dommgr/ApplicationProfile.cpp index 0c731934a..7beb9972a 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationProfile.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationProfile.cpp @@ -20,61 +20,15 @@ #include #include -#include #include +#include +#include #include "ApplicationProfile.h" using namespace ossie; -/** - * SinglePlacement - */ -SinglePlacement::SinglePlacement(const ComponentInstantiation* instantiation, - const SoftPkg* softpkg) : - instantiation(instantiation), - softpkg(softpkg) -{ -} - -const ComponentInstantiation* SinglePlacement::getComponentInstantiation() const -{ - return instantiation; -} - -const SoftPkg* SinglePlacement::getComponentProfile() -{ - return softpkg; -} - - -CollocationPlacement::CollocationPlacement(const std::string& id, const std::string& name) : - id(id), - name(name) -{ -} - -const std::string& CollocationPlacement::getId() const -{ - return id; -} - -const std::string& CollocationPlacement::getName() const -{ - return name; -} - -const CollocationPlacement::PlacementList& CollocationPlacement::getPlacements() const -{ - return placements; -} - -void CollocationPlacement::addPlacement(SinglePlacement* placement) -{ - placements.push_back(placement); -} - //////////////////////////////////////////////////// /* * ApplicationProfile member function definitions @@ -87,9 +41,6 @@ ApplicationProfile::ApplicationProfile() ApplicationProfile::~ApplicationProfile() { - for (PlacementList::iterator placement = placements.begin(); placement != placements.end(); ++placement) { - delete *placement; - } } const std::string& ApplicationProfile::getIdentifier() const @@ -102,26 +53,20 @@ void ApplicationProfile::load(CF::FileSystem_ptr fileSystem, const SoftwareAssem identifier = sad.getID(); // Walk through the host collocations first - const std::vector& collocations = sad.getHostCollocations(); - for (size_t index = 0; index < collocations.size(); ++index) { - const SoftwareAssembly::HostCollocation& collocation = collocations[index]; + BOOST_FOREACH(const SoftwareAssembly::HostCollocation& collocation, sad.getHostCollocations()) { LOG_TRACE(ApplicationProfile, "Building component info for host collocation " << collocation.getID()); - CollocationPlacement* placement = new CollocationPlacement(collocation.getID(), collocation.getName()); - placements.push_back(placement); - const std::vector& components = collocations[index].getComponents(); - for (unsigned int i = 0; i < components.size(); i++) { - SinglePlacement* component = buildComponentPlacement(fileSystem, sad, components[i]); - placement->addPlacement(component); + BOOST_FOREACH(const ComponentPlacement& placement, collocation.getComponents()) { + assert(placement.componentFile); + loadProfile(fileSystem, placement.componentFile->getFileName()); } } // Then, walk through the remaining non-collocated components - const std::vector& components = sad.getComponentPlacements(); - for (unsigned int i = 0; i < components.size(); i++) { - SinglePlacement* placement = buildComponentPlacement(fileSystem, sad, components[i]); - placements.push_back(placement); + BOOST_FOREACH(const ComponentPlacement& placement, sad.getComponentPlacements()) { + assert(placement.componentFile); + loadProfile(fileSystem, placement.componentFile->getFileName()); } } @@ -186,27 +131,3 @@ const SoftPkg* ApplicationProfile::loadProfile(CF::FileSystem_ptr fileSystem, return spd; } - -SinglePlacement* ApplicationProfile::buildComponentPlacement(CF::FileSystem_ptr fileSystem, - const SoftwareAssembly& sad, - const ComponentPlacement& placement) -{ - assert(placement.componentFile); - ComponentFile* componentFile = const_cast(placement.componentFile); - const SoftPkg* softpkg = loadProfile(fileSystem, componentFile->getFileName()); - - // Even though it is possible for there to be more than one instantiation - // per component, the tooling doesn't support that, so supporting this at a - // framework level would add substantial complexity without providing any - // appreciable improvements. It is far easier to have multiple placements - // rather than multiple instantiations. - const std::vector& instantiations = placement.getInstantiations(); - const ComponentInstantiation& instance = instantiations[0]; - - return new SinglePlacement(&instance, softpkg); -} - -const ApplicationProfile::PlacementList& ApplicationProfile::getPlacements() const -{ - return placements; -} diff --git a/redhawk/src/control/sdr/dommgr/ApplicationProfile.h b/redhawk/src/control/sdr/dommgr/ApplicationProfile.h index 4dba4ce81..99a306d15 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationProfile.h +++ b/redhawk/src/control/sdr/dommgr/ApplicationProfile.h @@ -27,51 +27,12 @@ #include -#include "applicationSupport.h" +#include +#include +#include namespace ossie { - class Placement - { - public: - virtual ~Placement() { } - }; - - class SinglePlacement : public Placement - { - public: - SinglePlacement(const ComponentInstantiation* instantiation, - const SoftPkg* softpkg); - - const ComponentInstantiation* getComponentInstantiation() const; - - const SoftPkg* getComponentProfile(); - - protected: - const ComponentInstantiation* instantiation; - const SoftPkg* softpkg; - }; - - class CollocationPlacement : public Placement - { - public: - typedef std::vector PlacementList; - - CollocationPlacement(const std::string& id, const std::string& name); - - const std::string& getId() const; - const std::string& getName() const; - - const PlacementList& getPlacements() const; - - void addPlacement(SinglePlacement* placement); - - protected: - const std::string id; - const std::string name; - PlacementList placements; - }; - /* Base class to contain data for applications * - Used to store information about about: * -> ExternalPorts @@ -83,8 +44,6 @@ namespace ossie { ENABLE_LOGGING; public: - typedef std::vector PlacementList; - ApplicationProfile(); ~ApplicationProfile(); @@ -92,8 +51,6 @@ namespace ossie { void load(CF::FileSystem_ptr fileSystem, const SoftwareAssembly& sad); - const PlacementList& getPlacements() const; - const SoftPkg* getSoftPkg(const std::string& filename) const; protected: @@ -101,13 +58,8 @@ namespace ossie { const SoftPkg* loadProfile(CF::FileSystem_ptr fileSystem, const std::string& filename); - SinglePlacement* buildComponentPlacement(CF::FileSystem_ptr fileSystem, - const SoftwareAssembly& sad, - const ComponentPlacement& placement); - std::string identifier; ProfileList profiles; - PlacementList placements; }; } diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index ebee335cd..f22508a7e 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -22,6 +22,7 @@ #include #include +#include #include "Application_impl.h" #include "PersistenceStore.h" @@ -560,55 +561,6 @@ std::string ComponentDeployment::getLoggingConfiguration() const return std::string(); } -PlacementPlan::PlacementPlan() -{ -} - -PlacementPlan::~PlacementPlan() -{ - for (ComponentList::iterator comp = components.begin(); comp != components.end(); ++comp) { - delete *comp; - } -} - -PlacementPlan::PlacementPlan(const std::string& id, const std::string& name) : - id(id), - name(name) -{ -} - -const std::string& PlacementPlan::getId() const -{ - return id; -} - -const std::string& PlacementPlan::getName() const -{ - return name; -} - -const PlacementPlan::ComponentList& PlacementPlan::getComponents() const -{ - return components; -} - -void PlacementPlan::addComponent(ComponentInfo* component) -{ - components.push_back(component); -} - -ComponentInfo* PlacementPlan::getComponent(const std::string& instantiationId) -{ - for (ComponentList::iterator comp = components.begin(); comp != components.end(); ++comp) { - if (instantiationId == (*comp)->getInstantiation()->getID()) { - return *comp; - } - } - - return 0; -} - - ApplicationDeployment::ApplicationDeployment(const SoftwareAssembly& sad, const std::string& instanceName, const CF::Properties& initConfiguration) : @@ -628,9 +580,6 @@ ApplicationDeployment::~ApplicationDeployment() for (ComponentList::iterator comp = components.begin(); comp != components.end(); ++comp) { delete *comp; } - for (std::vector::iterator place = placements.begin(); place != placements.end(); ++place) { - delete (*place); - } } const std::string& ApplicationDeployment::getIdentifier() const @@ -638,28 +587,6 @@ const std::string& ApplicationDeployment::getIdentifier() const return identifier; } -void ApplicationDeployment::addPlacement(PlacementPlan* placement) -{ - placements.push_back(placement); -} - -const std::vector& ApplicationDeployment::getPlacements() const -{ - return placements; -} - -ComponentInfo* ApplicationDeployment::getComponent(const std::string& instantiationId) -{ - for (PlacementList::iterator placement = placements.begin(); placement != placements.end(); ++placement) { - ComponentInfo* component = (*placement)->getComponent(instantiationId); - if (component) { - return component; - } - } - - return 0; -} - ComponentDeployment* ApplicationDeployment::getAssemblyController() { BOOST_FOREACH(ComponentDeployment* deployment, components) { diff --git a/redhawk/src/control/sdr/dommgr/Deployment.h b/redhawk/src/control/sdr/dommgr/Deployment.h index 8f77cf1e0..edbcc1823 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.h +++ b/redhawk/src/control/sdr/dommgr/Deployment.h @@ -27,7 +27,8 @@ #include #include -#include "applicationSupport.h" +#include + #include "connectionSupport.h" class Application_impl; @@ -181,34 +182,9 @@ namespace ossie { redhawk::PropertyMap affinityOptions; }; - class PlacementPlan - { - public: - typedef std::vector ComponentList; - - PlacementPlan(); - PlacementPlan(const std::string& id, const std::string& name); - ~PlacementPlan(); - - const std::string& getId() const; - const std::string& getName() const; - - const ComponentList& getComponents() const; - - void addComponent(ComponentInfo* component); - - ComponentInfo* getComponent(const std::string& instantiationId); - - protected: - std::string id; - std::string name; - ComponentList components; - }; - class ApplicationDeployment : public ComponentLookup, public DeviceLookup, public UsesDeviceDeployment { public: - typedef std::vector PlacementList; typedef std::vector ComponentList; typedef std::map CpuReservations; @@ -219,10 +195,6 @@ namespace ossie { const std::string& getIdentifier() const; - void addPlacement(PlacementPlan* placement); - - const PlacementList& getPlacements() const; - /** * Returns the properties used for evaluating math statements in * allocation @@ -231,8 +203,6 @@ namespace ossie { ComponentDeployment* getAssemblyController(); - ComponentInfo* getComponent(const std::string& instantiationId); - ComponentDeployment* createComponentDeployment(const SoftPkg* softpkg, const ComponentInstantiation* instantiation); @@ -260,7 +230,6 @@ namespace ossie { const std::string identifier; const std::string instanceName; redhawk::PropertyMap initConfiguration; - PlacementList placements; ComponentList components; }; } diff --git a/redhawk/src/control/sdr/dommgr/Makefile.am b/redhawk/src/control/sdr/dommgr/Makefile.am index f52ba4ce7..bcb261ebb 100644 --- a/redhawk/src/control/sdr/dommgr/Makefile.am +++ b/redhawk/src/control/sdr/dommgr/Makefile.am @@ -22,8 +22,7 @@ domainmgrdir = $(SDR_ROOT)/dom/mgr dist_domainmgr_DATA = DomainManager.spd.xml DomainManager.scd.xml DomainManager.prf.xml domainmgr_PROGRAMS = DomainManager -DomainManager_SOURCES = applicationSupport.cpp \ - connectionSupport.cpp \ +DomainManager_SOURCES = connectionSupport.cpp \ AllocationManager_impl.cpp \ EventChannelManager.cpp \ Application_impl.cpp \ diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.h b/redhawk/src/control/sdr/dommgr/applicationSupport.h deleted file mode 100644 index 3ff60f712..000000000 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * This file is protected by Copyright. Please refer to the COPYRIGHT file - * distributed with this source distribution. - * - * This file is part of REDHAWK core. - * - * REDHAWK core is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see http://www.gnu.org/licenses/. - */ - - -#ifndef APPLICATIONSUPPORT_H -#define APPLICATIONSUPPORT_H - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -// Application support routines - -// Base class to contain data for the components required to -// create an application -// Application support routines - -namespace ossie -{ - /* Base class to contain data for components - * - Used to store information about about components - */ - class ComponentInfo - { - ENABLE_LOGGING - - public: - ComponentInfo (const SoftPkg* softpkg, const ComponentInstantiation* instantiation); - ~ComponentInfo (); - - const SoftPkg* spd; - - const ComponentInstantiation* getInstantiation() const; - - static ComponentInfo* buildComponentInfoFromSPDFile(const SoftPkg* softpkg, - const ComponentInstantiation* instantiation); - - private: - ComponentInfo (const ComponentInfo&); - const ComponentInstantiation* instantiation; - }; - -} -#endif diff --git a/redhawk/src/control/sdr/dommgr/createHelper.h b/redhawk/src/control/sdr/dommgr/createHelper.h index 419d58acf..28595361f 100644 --- a/redhawk/src/control/sdr/dommgr/createHelper.h +++ b/redhawk/src/control/sdr/dommgr/createHelper.h @@ -25,8 +25,9 @@ #include #include +#include + #include "PersistenceStore.h" -#include "applicationSupport.h" #include "ApplicationProfile.h" #include "Deployment.h" @@ -70,10 +71,6 @@ class createHelper const DeviceAssignmentMap& deviceAssignments); private: - - // list of components that are part of a collocation - typedef std::vector PlacementList; - // Used for storing the current state of the OE & create process const ApplicationFactory_impl& _appFact; @@ -132,9 +129,7 @@ class createHelper void getRequiredComponents(CF::FileSystem_ptr fileSys, const ossie::SoftwareAssembly& sadParser, ossie::ApplicationDeployment& appDeployment); - ossie::ComponentInfo* buildComponentInfo(CF::FileSystem_ptr fileSys, - const ossie::SoftwareAssembly& sadParser, - const ossie::ComponentPlacement& component); + void checkComponentInfo(CF::FileSystem_ptr fileSys, const ossie::ComponentPlacement& component); // Supports allocation bool allocateUsesDevices(const std::vector& usesDevices, From 005899a1031986dbf5eb375242e79d82e0cf0e4b Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 1 Jun 2016 12:23:24 -0400 Subject: [PATCH 0332/1644] Merge ApplicationProfile's remaining functionality--loading profiles--into ApplicationDeployment --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 91 +++--------- .../control/sdr/dommgr/ApplicationProfile.cpp | 133 ------------------ .../control/sdr/dommgr/ApplicationProfile.h | 67 --------- redhawk/src/control/sdr/dommgr/Deployment.cpp | 92 ++++++++++++ redhawk/src/control/sdr/dommgr/Deployment.h | 10 ++ redhawk/src/control/sdr/dommgr/Makefile.am | 1 - redhawk/src/control/sdr/dommgr/createHelper.h | 22 ++- 7 files changed, 129 insertions(+), 287 deletions(-) delete mode 100644 redhawk/src/control/sdr/dommgr/ApplicationProfile.cpp delete mode 100644 redhawk/src/control/sdr/dommgr/ApplicationProfile.h diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 585051232..03a3c9d31 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -636,7 +636,7 @@ void createHelper::assignPlacementsToDevices(ossie::ApplicationDeployment& appDe // Place the remaining components one-by-one BOOST_FOREACH(const ComponentPlacement& placement, _appFact._sadParser.getComponentPlacements()) { - const SoftPkg* softpkg = _appProfile.getSoftPkg(placement.componentFile->getFileName()); + const SoftPkg* softpkg = appDeployment.getSoftPkg(placement.componentFile->getFileName()); // Even though it is possible for there to be more than one instantiation // per component, the tooling doesn't support that, so supporting this at a // framework level would add substantial complexity without providing any @@ -652,7 +652,7 @@ void createHelper::assignPlacementsToDevices(ossie::ApplicationDeployment& appDe } ossie::ComponentDeployment* deployment = appDeployment.createComponentDeployment(softpkg, instantiation); - allocateComponent(deployment, assigned_device, appDeployment.getIdentifier()); + allocateComponent(appDeployment, deployment, assigned_device); } } @@ -762,7 +762,7 @@ bool createHelper::allocateHostCollocation(ossie::ApplicationDeployment& appDepl for (DeploymentList::const_iterator depl = components.begin(); depl != components.end(); ++depl) { // Reset any dependencies that may have been resolved in a prior attempt (*depl)->clearDependencies(); - if (!resolveSoftpkgDependencies(*depl, *node)) { + if (!resolveSoftpkgDependencies(appDeployment, *depl, *node)) { LOG_TRACE(ApplicationFactory_impl, "Unable to resolve softpackage dependencies for component " << (*depl)->getIdentifier() << " implementation " << (*depl)->getImplementation()->getID()); @@ -810,7 +810,7 @@ void createHelper::_placeHostCollocation(ossie::ApplicationDeployment& appDeploy DeviceIDList assignedDevices; DeploymentList deployments; BOOST_FOREACH(const ComponentPlacement& placement, collocation.getComponents()) { - const SoftPkg* softpkg = _appProfile.getSoftPkg(placement.componentFile->getFileName()); + const SoftPkg* softpkg = appDeployment.getSoftPkg(placement.componentFile->getFileName()); const ComponentInstantiation* instantiation = &(placement.getInstantiations()[0]); ossie::ComponentDeployment* deployment = appDeployment.createComponentDeployment(softpkg, instantiation); deployments.push_back(deployment); @@ -1163,9 +1163,8 @@ CF::Application_ptr createHelper::create ( ////////////////////////////////////////////////// // Load the components to instantiate from the SAD - _appProfile.load(_appFact._fileMgr, _appFact._sadParser); ossie::ApplicationDeployment app_deployment(_appFact._sadParser, _waveformContextName, modifiedInitConfiguration); - getRequiredComponents(_appFact._fileMgr, _appFact._sadParser, app_deployment); + app_deployment.loadProfiles(_appFact._fileMgr); //////////////////////////////////////////////// // Assign components to devices @@ -1342,9 +1341,9 @@ CF::AllocationManager::AllocationResponseSequence* createHelper::allocateUsesDev collocation request. This requires that we know and cleanup only those allocations that we made.. */ -void createHelper::allocateComponent(ossie::ComponentDeployment* deployment, - const std::string& assignedDeviceId, - const std::string& appIdentifier) +void createHelper::allocateComponent(ossie::ApplicationDeployment& appDeployment, + ossie::ComponentDeployment* deployment, + const std::string& assignedDeviceId) { redhawk::PropertyMap alloc_context = deployment->getAllocationContext(); @@ -1395,7 +1394,8 @@ void createHelper::allocateComponent(ossie::ComponentDeployment* deployment, // Found an implementation which has its 'usesdevice' dependencies // satisfied, now perform assignment/allocation of component to device LOG_DEBUG(ApplicationFactory_impl, "Trying to find the device"); - ossie::AllocationResult response = allocateComponentToDevice(deployment, assignedDeviceId, appIdentifier); + ossie::AllocationResult response = allocateComponentToDevice(deployment, assignedDeviceId, + appDeployment.getIdentifier()); if (response.first.empty()) { LOG_DEBUG(ApplicationFactory_impl, "Unable to allocate device for component " @@ -1411,7 +1411,7 @@ void createHelper::allocateComponent(ossie::ComponentDeployment* deployment, DeviceNode& node = *(response.second); const std::string& deviceId = node.identifier; - if (!resolveSoftpkgDependencies(deployment, node)) { + if (!resolveSoftpkgDependencies(appDeployment, deployment, node)) { LOG_DEBUG(ApplicationFactory_impl, "Unable to resolve softpackage dependencies for component " << deployment->getIdentifier() << " implementation " << implementation->getID()); continue; @@ -1710,7 +1710,9 @@ void createHelper::_castRequestProperties(CF::Properties& allocationProperties, } } -bool createHelper::resolveSoftpkgDependencies(ossie::SoftpkgDeployment* deployment, ossie::DeviceNode& device) +bool createHelper::resolveSoftpkgDependencies(ossie::ApplicationDeployment& appDeployment, + ossie::SoftpkgDeployment* deployment, + ossie::DeviceNode& device) { const ossie::SPD::Implementation* implementation = deployment->getImplementation(); const SPD::SoftPkgDependencies& deps = implementation->getSoftPkgDependencies(); @@ -1718,7 +1720,7 @@ bool createHelper::resolveSoftpkgDependencies(ossie::SoftpkgDeployment* deployme for (iterSoftpkg = deps.begin(); iterSoftpkg != deps.end(); ++iterSoftpkg) { // Find an implementation whose dependencies match - ossie::SoftpkgDeployment* dependency = resolveDependencyImplementation(*iterSoftpkg, device); + ossie::SoftpkgDeployment* dependency = resolveDependencyImplementation(appDeployment, *iterSoftpkg, device); if (dependency) { deployment->addDependency(dependency); } else { @@ -1730,11 +1732,12 @@ bool createHelper::resolveSoftpkgDependencies(ossie::SoftpkgDeployment* deployme return true; } -ossie::SoftpkgDeployment* createHelper::resolveDependencyImplementation(const ossie::SPD::SoftPkgRef& ref, +ossie::SoftpkgDeployment* createHelper::resolveDependencyImplementation(ossie::ApplicationDeployment& appDeployment, + const ossie::SPD::SoftPkgRef& ref, ossie::DeviceNode& device) { LOG_TRACE(ApplicationFactory_impl, "Resolving dependency " << ref); - const SoftPkg* softpkg = _appProfile.getSoftPkg(ref.localfile); + const SoftPkg* softpkg = appDeployment.getSoftPkg(ref.localfile); const SPD::Implementations& spd_list = softpkg->getImplementations(); for (size_t implCount = 0; implCount < spd_list.size(); implCount++) { @@ -1752,7 +1755,7 @@ ossie::SoftpkgDeployment* createHelper::resolveDependencyImplementation(const os ossie::SoftpkgDeployment* dependency = new ossie::SoftpkgDeployment(softpkg, &implementation); // Recursively check any softpkg dependencies - if (resolveSoftpkgDependencies(dependency, device)) { + if (resolveSoftpkgDependencies(appDeployment, dependency, device)) { return dependency; } delete dependency; @@ -1761,62 +1764,6 @@ ossie::SoftpkgDeployment* createHelper::resolveDependencyImplementation(const os return 0; } -void createHelper::checkComponentInfo(CF::FileSystem_ptr fileSys, - const ComponentPlacement& component) -{ - // Even though it is possible for there to be more than one instantiation per component, - // the tooling doesn't support that, so supporting this at a framework level would add - // substantial complexity without providing any appreciable improvements. It is far - // easier to have multiple placements rather than multiple instantiations. - const vector& instantiations = component.getInstantiations(); - const ComponentInstantiation& instance = instantiations[0]; - - // Extract required data from SPD file - LOG_TRACE(ApplicationFactory_impl, "Getting the SPD Filename"); - const ComponentFile* componentfile = component.componentFile; - if (!componentfile) { - ostringstream eout; - eout << "The SPD file reference for componentfile "<getFileName()); - if (softpkg->isScaCompliant() && !instance.isNamingService()) { - LOG_WARN(ApplicationFactory_impl, "component instantiation is sca compliant but does not provide a 'findcomponent' name...this is probably an error"); - } -} - -/* Create a vector of all the components for the SAD associated with this App Factory - * - Get component information from the SAD and store in _requiredComponents vector - */ -void createHelper::getRequiredComponents(CF::FileSystem_ptr fileSys, - const SoftwareAssembly& sadParser, - ossie::ApplicationDeployment& appDeployment) - -{ - TRACE_ENTER(ApplicationFactory_impl); - - // Walk through the host collocations first - const std::vector& collocations = sadParser.getHostCollocations(); - for (size_t index = 0; index < collocations.size(); ++index) { - const SoftwareAssembly::HostCollocation& collocation = collocations[index]; - LOG_TRACE(ApplicationFactory_impl, "Building component info for host collocation " - << collocation.getID()); - const std::vector& placements = collocations[index].getComponents(); - for (unsigned int i = 0; i < placements.size(); i++) { - checkComponentInfo(fileSys, placements[i]); - } - } - - // Then, walk through the remaining non-collocated components - const std::vector& componentsFromSAD = sadParser.getComponentPlacements(); - for (unsigned int i = 0; i < componentsFromSAD.size(); i++) { - checkComponentInfo(fileSys, componentsFromSAD[i]); - } - - TRACE_EXIT(ApplicationFactory_impl); -} - /* Given a waveform/application name, return a unique waveform naming context * - Returns a unique waveform naming context * THIS FUNCTION IS NOT THREAD SAFE diff --git a/redhawk/src/control/sdr/dommgr/ApplicationProfile.cpp b/redhawk/src/control/sdr/dommgr/ApplicationProfile.cpp deleted file mode 100644 index 7beb9972a..000000000 --- a/redhawk/src/control/sdr/dommgr/ApplicationProfile.cpp +++ /dev/null @@ -1,133 +0,0 @@ -/* - * This file is protected by Copyright. Please refer to the COPYRIGHT file - * distributed with this source distribution. - * - * This file is part of REDHAWK core. - * - * REDHAWK core is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see http://www.gnu.org/licenses/. - */ - -#include -#include - -#include -#include -#include - -#include "ApplicationProfile.h" - -using namespace ossie; - -//////////////////////////////////////////////////// -/* - * ApplicationProfile member function definitions - */ -PREPARE_LOGGING(ApplicationProfile); - -ApplicationProfile::ApplicationProfile() -{ -} - -ApplicationProfile::~ApplicationProfile() -{ -} - -const std::string& ApplicationProfile::getIdentifier() const -{ - return identifier; -} - -void ApplicationProfile::load(CF::FileSystem_ptr fileSystem, const SoftwareAssembly& sad) -{ - identifier = sad.getID(); - - // Walk through the host collocations first - BOOST_FOREACH(const SoftwareAssembly::HostCollocation& collocation, sad.getHostCollocations()) { - LOG_TRACE(ApplicationProfile, "Building component info for host collocation " - << collocation.getID()); - - BOOST_FOREACH(const ComponentPlacement& placement, collocation.getComponents()) { - assert(placement.componentFile); - loadProfile(fileSystem, placement.componentFile->getFileName()); - } - } - - // Then, walk through the remaining non-collocated components - BOOST_FOREACH(const ComponentPlacement& placement, sad.getComponentPlacements()) { - assert(placement.componentFile); - loadProfile(fileSystem, placement.componentFile->getFileName()); - } -} - -const SoftPkg* ApplicationProfile::getSoftPkg(const std::string& filename) const -{ - BOOST_FOREACH(const SoftPkg& softpkg, profiles) { - if (softpkg.getSPDFile() == filename) { - return &softpkg; - } - } - - throw std::logic_error(filename + " was never loaded"); -} - -const SoftPkg* ApplicationProfile::loadProfile(CF::FileSystem_ptr fileSystem, - const std::string& filename) -{ - BOOST_FOREACH(const SoftPkg& profile, profiles) { - if (profile.getSPDFile() == filename) { - LOG_TRACE(ApplicationProfile, "Found existing profile " << filename); - return &profile; - } - } - - LOG_TRACE(ApplicationProfile, "Loading SPD file " << filename); - File_stream spd_stream(fileSystem, filename.c_str()); - SoftPkg* spd = new SoftPkg(spd_stream, filename); - profiles.push_back(spd); - spd_stream.close(); - - const SPD::Implementations& spd_impls = spd->getImplementations(); - for (SPD::Implementations::const_iterator impl = spd_impls.begin(); impl != spd_impls.end(); ++impl) { - const SPD::SoftPkgDependencies& deps = impl->getSoftPkgDependencies(); - for (SPD::SoftPkgDependencies::const_iterator dep = deps.begin(); dep != deps.end(); ++dep) { - SPD::SoftPkgRef& ref = const_cast(*dep); - LOG_TRACE(ApplicationProfile, "Resolving soft package reference " << ref.localfile); - loadProfile(fileSystem, ref.localfile); - } - } - - if (spd->getPRFFile()) { - LOG_TRACE(ApplicationProfile, "Loading PRF file " << spd->getPRFFile()); - try { - spd->setProperties(boost::make_shared()); - File_stream prf_stream(fileSystem, spd->getPRFFile()); - spd->getProperties()->load(prf_stream); - } catch (const std::exception& exc) { - LOG_ERROR(ApplicationProfile, "Invalid PRF file " << spd->getPRFFile() << ": " << exc.what()); - } - } - - if (spd->getSCDFile()) { - LOG_TRACE(ApplicationProfile, "Loading SCD file " << spd->getSCDFile()); - try { - spd->setDescriptor(boost::make_shared()); - File_stream scd_stream(fileSystem, spd->getSCDFile()); - spd->getDescriptor()->load(scd_stream); - } catch (const std::exception& exc) { - LOG_ERROR(ApplicationProfile, "Invalid SCD file " << spd->getSCDFile() << ": " << exc.what()); - } - } - - return spd; -} diff --git a/redhawk/src/control/sdr/dommgr/ApplicationProfile.h b/redhawk/src/control/sdr/dommgr/ApplicationProfile.h deleted file mode 100644 index 99a306d15..000000000 --- a/redhawk/src/control/sdr/dommgr/ApplicationProfile.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * This file is protected by Copyright. Please refer to the COPYRIGHT file - * distributed with this source distribution. - * - * This file is part of REDHAWK core. - * - * REDHAWK core is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see http://www.gnu.org/licenses/. - */ - - -#ifndef APPLICATIONPROFILE_H -#define APPLICATIONPROFILE_H - -#include -#include - -#include - -#include -#include -#include - -namespace ossie { - - /* Base class to contain data for applications - * - Used to store information about about: - * -> ExternalPorts - * -> External Properties - * -> UsesDevice relationships - */ - class ApplicationProfile - { - ENABLE_LOGGING; - - public: - ApplicationProfile(); - ~ApplicationProfile(); - - const std::string& getIdentifier() const; - - void load(CF::FileSystem_ptr fileSystem, const SoftwareAssembly& sad); - - const SoftPkg* getSoftPkg(const std::string& filename) const; - - protected: - typedef boost::ptr_vector ProfileList; - - const SoftPkg* loadProfile(CF::FileSystem_ptr fileSystem, const std::string& filename); - - std::string identifier; - ProfileList profiles; - }; - -} - -#endif // APPLICATIONPROFILE_H diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index f22508a7e..58c807c0a 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -21,6 +21,7 @@ #include #include +#include #include #include @@ -587,6 +588,35 @@ const std::string& ApplicationDeployment::getIdentifier() const return identifier; } +void ApplicationDeployment::loadProfiles(CF::FileSystem_ptr fileSystem) +{ + // Walk through the host collocations first + BOOST_FOREACH(const SoftwareAssembly::HostCollocation& collocation, sad.getHostCollocations()) { + BOOST_FOREACH(const ComponentPlacement& placement, collocation.getComponents()) { + assert(placement.componentFile); + const SoftPkg* softpkg = loadProfile(fileSystem, placement.componentFile->getFileName()); + const ComponentInstantiation* instantiation = &(placement.getInstantiations()[0]); + if (softpkg->isScaCompliant() && !instantiation->isNamingService()) { + RH_NL_WARN("ApplicationFactory_impl", "Component instantiation " + << instantiation->getID() << " does not provide a 'findcomponent' name but " + << softpkg->getName() << " is SCA-compliant"); + } + } + } + + // Then, walk through the remaining non-collocated components + BOOST_FOREACH(const ComponentPlacement& placement, sad.getComponentPlacements()) { + assert(placement.componentFile); + const SoftPkg* softpkg = loadProfile(fileSystem, placement.componentFile->getFileName()); + const ComponentInstantiation* instantiation = &(placement.getInstantiations()[0]); + if (softpkg->isScaCompliant() && !instantiation->isNamingService()) { + RH_NL_WARN("ApplicationFactory_impl", "Component instantiation " + << instantiation->getID() << " does not provide a 'findcomponent' name but " + << softpkg->getName() << " is SCA-compliant"); + } + } +} + ComponentDeployment* ApplicationDeployment::getAssemblyController() { BOOST_FOREACH(ComponentDeployment* deployment, components) { @@ -698,6 +728,68 @@ void ApplicationDeployment::overrideExternalProperties(ComponentDeployment* depl } +const SoftPkg* ApplicationDeployment::getSoftPkg(const std::string& filename) const +{ + BOOST_FOREACH(const SoftPkg& softpkg, profiles) { + if (softpkg.getSPDFile() == filename) { + return &softpkg; + } + } + + throw std::logic_error(filename + " was never loaded"); +} + +const SoftPkg* ApplicationDeployment::loadProfile(CF::FileSystem_ptr fileSystem, + const std::string& filename) +{ + BOOST_FOREACH(const SoftPkg& profile, profiles) { + if (profile.getSPDFile() == filename) { + RH_NL_TRACE("ApplicationFactory_impl", "Found existing profile " << filename); + return &profile; + } + } + + RH_NL_TRACE("ApplicationFactory_impl", "Loading SPD file " << filename); + File_stream spd_stream(fileSystem, filename.c_str()); + SoftPkg* spd = new SoftPkg(spd_stream, filename); + profiles.push_back(spd); + spd_stream.close(); + + const SPD::Implementations& spd_impls = spd->getImplementations(); + for (SPD::Implementations::const_iterator impl = spd_impls.begin(); impl != spd_impls.end(); ++impl) { + const SPD::SoftPkgDependencies& deps = impl->getSoftPkgDependencies(); + for (SPD::SoftPkgDependencies::const_iterator dep = deps.begin(); dep != deps.end(); ++dep) { + SPD::SoftPkgRef& ref = const_cast(*dep); + RH_NL_TRACE("ApplicationFactory_impl", "Resolving soft package reference " << ref.localfile); + loadProfile(fileSystem, ref.localfile); + } + } + + if (spd->getPRFFile()) { + RH_NL_TRACE("ApplicationFactory_impl", "Loading PRF file " << spd->getPRFFile()); + try { + spd->setProperties(boost::make_shared()); + File_stream prf_stream(fileSystem, spd->getPRFFile()); + spd->getProperties()->load(prf_stream); + } catch (const std::exception& exc) { + RH_NL_ERROR("ApplicationFactory_impl", "Invalid PRF file " << spd->getPRFFile() << ": " << exc.what()); + } + } + + if (spd->getSCDFile()) { + RH_NL_TRACE("ApplicationFactory_impl", "Loading SCD file " << spd->getSCDFile()); + try { + spd->setDescriptor(boost::make_shared()); + File_stream scd_stream(fileSystem, spd->getSCDFile()); + spd->getDescriptor()->load(scd_stream); + } catch (const std::exception& exc) { + RH_NL_ERROR("ApplicationFactory_impl", "Invalid SCD file " << spd->getSCDFile() << ": " << exc.what()); + } + } + + return spd; +} + CF::Resource_ptr ApplicationDeployment::lookupComponentByInstantiationId(const std::string& identifier) { ComponentDeployment* deployment = getComponentDeployment(identifier); diff --git a/redhawk/src/control/sdr/dommgr/Deployment.h b/redhawk/src/control/sdr/dommgr/Deployment.h index edbcc1823..80cb54bd2 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.h +++ b/redhawk/src/control/sdr/dommgr/Deployment.h @@ -25,6 +25,7 @@ #include #include +#include #include #include @@ -193,8 +194,12 @@ namespace ossie { const CF::Properties& initConfiguration); ~ApplicationDeployment(); + void loadProfiles(CF::FileSystem_ptr fileSystem); + const std::string& getIdentifier() const; + const SoftPkg* getSoftPkg(const std::string& filename) const; + /** * Returns the properties used for evaluating math statements in * allocation @@ -223,6 +228,10 @@ namespace ossie { CF::Device_ptr lookupDeviceUsedByApplication(const std::string& usesRefId); protected: + typedef boost::ptr_vector ProfileList; + + const SoftPkg* loadProfile(CF::FileSystem_ptr fileSystem, const std::string& filename); + void overrideAssemblyControllerProperties(ComponentDeployment* deployment); void overrideExternalProperties(ComponentDeployment* deployment); @@ -230,6 +239,7 @@ namespace ossie { const std::string identifier; const std::string instanceName; redhawk::PropertyMap initConfiguration; + ProfileList profiles; ComponentList components; }; } diff --git a/redhawk/src/control/sdr/dommgr/Makefile.am b/redhawk/src/control/sdr/dommgr/Makefile.am index bcb261ebb..823881545 100644 --- a/redhawk/src/control/sdr/dommgr/Makefile.am +++ b/redhawk/src/control/sdr/dommgr/Makefile.am @@ -34,7 +34,6 @@ DomainManager_SOURCES = connectionSupport.cpp \ DomainManager_impl.cpp \ FakeApplication.cpp \ Deployment.cpp \ - ApplicationProfile.cpp \ main.cpp DomainManager_CPPFLAGS = -I../../include -I../../parser -I$(top_srcdir)/base/include -I$(top_srcdir)/base $(BOOST_CPPFLAGS) $(OMNIORB_CFLAGS) $(LOG4CXX_FLAGS) DomainManager_CXXFLAGS = -Wall diff --git a/redhawk/src/control/sdr/dommgr/createHelper.h b/redhawk/src/control/sdr/dommgr/createHelper.h index 28595361f..a9f0d6244 100644 --- a/redhawk/src/control/sdr/dommgr/createHelper.h +++ b/redhawk/src/control/sdr/dommgr/createHelper.h @@ -28,7 +28,6 @@ #include #include "PersistenceStore.h" -#include "ApplicationProfile.h" #include "Deployment.h" class Application_impl; @@ -94,8 +93,6 @@ class createHelper CosNaming::NamingContext_var _waveformContext; CosNaming::NamingContext_ptr _domainContext; - ossie::ApplicationProfile _appProfile; - typedef std::vector DeploymentList; typedef std::vector ProcessorList; typedef std::vector OSList; @@ -125,12 +122,6 @@ class createHelper void _evaluateMATHinRequest(CF::Properties &request, const CF::Properties &configureProperties); void _castRequestProperties(CF::Properties& allocationProperties, const std::vector &prop_refs, unsigned int offset=0); - // Populate _requiredComponents vector - void getRequiredComponents(CF::FileSystem_ptr fileSys, - const ossie::SoftwareAssembly& sadParser, - ossie::ApplicationDeployment& appDeployment); - void checkComponentInfo(CF::FileSystem_ptr fileSys, const ossie::ComponentPlacement& component); - // Supports allocation bool allocateUsesDevices(const std::vector& usesDevices, const CF::Properties& configureProperties, @@ -139,9 +130,9 @@ class createHelper CF::AllocationManager::AllocationResponseSequence* allocateUsesDeviceProperties( const std::vector& component, const CF::Properties& configureProperties); - void allocateComponent(ossie::ComponentDeployment* deployment, - const std::string& assignedDeviceId, - const std::string& appIdentifier); + void allocateComponent(ossie::ApplicationDeployment& appDeployment, + ossie::ComponentDeployment* deployment, + const std::string& assignedDeviceId); ossie::AllocationResult allocateComponentToDevice(ossie::ComponentDeployment* deployment, const std::string& assignedDeviceId, @@ -153,8 +144,11 @@ class createHelper const ProcessorList& processorDeps, const OSList& osDeps); - bool resolveSoftpkgDependencies(ossie::SoftpkgDeployment* deployment, ossie::DeviceNode& device); - ossie::SoftpkgDeployment* resolveDependencyImplementation(const ossie::SPD::SoftPkgRef& ref, + bool resolveSoftpkgDependencies(ossie::ApplicationDeployment& appDeployment, + ossie::SoftpkgDeployment* deployment, + ossie::DeviceNode& device); + ossie::SoftpkgDeployment* resolveDependencyImplementation(ossie::ApplicationDeployment& appDeployment, + const ossie::SPD::SoftPkgRef& ref, ossie::DeviceNode& device); // Supports loading, executing, initializing, configuring, & connecting From 7c40932d9ec737ddbc0fdb65db41a62bf23b1260 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 1 Jun 2016 12:43:23 -0400 Subject: [PATCH 0333/1644] Split ApplicationDeployment into its own files, with its own logger --- .../sdr/dommgr/ApplicationDeployment.cpp | 325 ++++++++++++++++++ .../sdr/dommgr/ApplicationDeployment.h | 102 ++++++ redhawk/src/control/sdr/dommgr/Deployment.cpp | 293 ---------------- redhawk/src/control/sdr/dommgr/Deployment.h | 64 +--- redhawk/src/control/sdr/dommgr/Makefile.am | 1 + redhawk/src/control/sdr/dommgr/createHelper.h | 2 +- 6 files changed, 430 insertions(+), 357 deletions(-) create mode 100644 redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp create mode 100644 redhawk/src/control/sdr/dommgr/ApplicationDeployment.h diff --git a/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp b/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp new file mode 100644 index 000000000..6338f9611 --- /dev/null +++ b/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp @@ -0,0 +1,325 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK core. + * + * REDHAWK core is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +#include + +#include +#include +#include + +#include "PersistenceStore.h" +#include "ApplicationDeployment.h" + +using namespace ossie; + +PREPARE_LOGGING(ApplicationDeployment); + +ApplicationDeployment::ApplicationDeployment(const SoftwareAssembly& sad, + const std::string& instanceName, + const CF::Properties& initConfiguration) : + sad(sad), + // Give the application a unique identifier of the form + // "softwareassemblyid:ApplicationName", where the application name + // includes the serial number generated for the naming context + // (e.g. "Application_1"). + identifier(sad.getID() + ":" + instanceName), + instanceName(instanceName), + initConfiguration(initConfiguration) +{ +} + +ApplicationDeployment::~ApplicationDeployment() +{ + for (ComponentList::iterator comp = components.begin(); comp != components.end(); ++comp) { + delete *comp; + } +} + +const std::string& ApplicationDeployment::getIdentifier() const +{ + return identifier; +} + +void ApplicationDeployment::loadProfiles(CF::FileSystem_ptr fileSystem) +{ + // Walk through the host collocations first + BOOST_FOREACH(const SoftwareAssembly::HostCollocation& collocation, sad.getHostCollocations()) { + BOOST_FOREACH(const ComponentPlacement& placement, collocation.getComponents()) { + assert(placement.componentFile); + const SoftPkg* softpkg = loadProfile(fileSystem, placement.componentFile->getFileName()); + const ComponentInstantiation* instantiation = &(placement.getInstantiations()[0]); + if (softpkg->isScaCompliant() && !instantiation->isNamingService()) { + LOG_WARN(ApplicationDeployment, "Component instantiation " + << instantiation->getID() << " does not provide a 'findcomponent' name but " + << softpkg->getName() << " is SCA-compliant"); + } + } + } + + // Then, walk through the remaining non-collocated components + BOOST_FOREACH(const ComponentPlacement& placement, sad.getComponentPlacements()) { + assert(placement.componentFile); + const SoftPkg* softpkg = loadProfile(fileSystem, placement.componentFile->getFileName()); + const ComponentInstantiation* instantiation = &(placement.getInstantiations()[0]); + if (softpkg->isScaCompliant() && !instantiation->isNamingService()) { + LOG_WARN(ApplicationDeployment, "Component instantiation " + << instantiation->getID() << " does not provide a 'findcomponent' name but " + << softpkg->getName() << " is SCA-compliant"); + } + } +} + +ComponentDeployment* ApplicationDeployment::getAssemblyController() +{ + BOOST_FOREACH(ComponentDeployment* deployment, components) { + if (deployment->getInstantiation()->isAssemblyController()) { + return deployment; + } + } + return 0; +} + +redhawk::PropertyMap ApplicationDeployment::getAllocationContext() const +{ + redhawk::PropertyMap properties; + BOOST_FOREACH(ComponentDeployment* deployment, components) { + if (deployment->getInstantiation()->isAssemblyController()) { + properties = deployment->getAllocationContext(); + } + } + return properties; +} + +ComponentDeployment* ApplicationDeployment::createComponentDeployment(const SoftPkg* softpkg, + const ComponentInstantiation* instantiation) +{ + // Create a unique identifier for this component instance by appending the + // application instance's unique name + std::string component_id = instantiation->getID() + ":" + instanceName; + + ComponentDeployment* deployment = new ComponentDeployment(softpkg, instantiation, component_id); + components.push_back(deployment); + + // Override properties from initial configuration + if (instantiation->isAssemblyController()) { + overrideAssemblyControllerProperties(deployment); + } else { + overrideExternalProperties(deployment); + } + + return deployment; +} + +const ApplicationDeployment::ComponentList& ApplicationDeployment::getComponentDeployments() +{ + return components; +} + +ComponentDeployment* ApplicationDeployment::getComponentDeployment(const std::string& instantiationId) +{ + for (ComponentList::iterator comp = components.begin(); comp != components.end(); ++comp) { + if (instantiationId == (*comp)->getInstantiation()->getID()) { + return *comp; + } + } + + return 0; +} + +void ApplicationDeployment::applyCpuReservations(const CpuReservations& reservations) +{ + BOOST_FOREACH(ComponentDeployment* deployment, components) { + CpuReservations::const_iterator reserved = reservations.find(deployment->getIdentifier()); + if (reserved == reservations.end()) { + // NB: Check for the usage name for consistency with 2.0, although + // the instantiation ID would make more sense. In most cases, this + // is probably a moot point, since the IDE uses the same value for + // both. + reserved = reservations.find(deployment->getInstantiation()->getUsageName()); + } + if (reserved != reservations.end()) { + deployment->setCpuReservation(reserved->second); + } + } +} + +void ApplicationDeployment::overrideAssemblyControllerProperties(ComponentDeployment* deployment) +{ + BOOST_FOREACH(const redhawk::PropertyType& override, initConfiguration) { + const std::string propid = override.getId(); + if (propid == "LOGGING_CONFIG_URI") { + if (deployment->getLoggingConfiguration().empty()) { + LOG_TRACE(ApplicationDeployment, "Adding LOGGING_CONFIG_URI as a command line parameter with value " + << override.getValue().toString()); + deployment->overrideProperty(propid, override.getValue()); + } + } else { + LOG_TRACE(ApplicationDeployment, "Overriding property " << propid + << " with " << override.getValue().toString()); + deployment->overrideProperty(propid, override.getValue()); + } + } +} + +void ApplicationDeployment::overrideExternalProperties(ComponentDeployment* deployment) +{ + const std::string& instantiation_id = deployment->getInstantiation()->getID(); + BOOST_FOREACH(const SoftwareAssembly::Property& property, sad.getExternalProperties()) { + if (property.comprefid == instantiation_id) { + std::string property_id = property.externalpropid; + if (property_id.empty()) { + property_id = property.propid; + } + redhawk::PropertyMap::iterator override = initConfiguration.find(property_id); + if (override != initConfiguration.end()) { + LOG_TRACE(ApplicationDeployment, "Overriding external property " << property_id + << " (" << property.propid << ") = " << override->getValue().toString()); + deployment->overrideProperty(property.propid, override->getValue()); + } + } + } +} + + +const SoftPkg* ApplicationDeployment::getSoftPkg(const std::string& filename) const +{ + BOOST_FOREACH(const SoftPkg& softpkg, profiles) { + if (softpkg.getSPDFile() == filename) { + return &softpkg; + } + } + + throw std::logic_error(filename + " was never loaded"); +} + +const SoftPkg* ApplicationDeployment::loadProfile(CF::FileSystem_ptr fileSystem, + const std::string& filename) +{ + BOOST_FOREACH(const SoftPkg& profile, profiles) { + if (profile.getSPDFile() == filename) { + LOG_TRACE(ApplicationDeployment, "Found existing profile " << filename); + return &profile; + } + } + + LOG_TRACE(ApplicationDeployment, "Loading SPD file " << filename); + File_stream spd_stream(fileSystem, filename.c_str()); + SoftPkg* spd = new SoftPkg(spd_stream, filename); + profiles.push_back(spd); + spd_stream.close(); + + const SPD::Implementations& spd_impls = spd->getImplementations(); + for (SPD::Implementations::const_iterator impl = spd_impls.begin(); impl != spd_impls.end(); ++impl) { + const SPD::SoftPkgDependencies& deps = impl->getSoftPkgDependencies(); + for (SPD::SoftPkgDependencies::const_iterator dep = deps.begin(); dep != deps.end(); ++dep) { + SPD::SoftPkgRef& ref = const_cast(*dep); + LOG_TRACE(ApplicationDeployment, "Resolving soft package reference " << ref.localfile); + loadProfile(fileSystem, ref.localfile); + } + } + + if (spd->getPRFFile()) { + LOG_TRACE(ApplicationDeployment, "Loading PRF file " << spd->getPRFFile()); + try { + spd->setProperties(boost::make_shared()); + File_stream prf_stream(fileSystem, spd->getPRFFile()); + spd->getProperties()->load(prf_stream); + } catch (const std::exception& exc) { + LOG_ERROR(ApplicationDeployment, "Invalid PRF file " << spd->getPRFFile() << ": " << exc.what()); + } + } + + if (spd->getSCDFile()) { + LOG_TRACE(ApplicationDeployment, "Loading SCD file " << spd->getSCDFile()); + try { + spd->setDescriptor(boost::make_shared()); + File_stream scd_stream(fileSystem, spd->getSCDFile()); + spd->getDescriptor()->load(scd_stream); + } catch (const std::exception& exc) { + LOG_ERROR(ApplicationDeployment, "Invalid SCD file " << spd->getSCDFile() << ": " << exc.what()); + } + } + + return spd; +} + +CF::Resource_ptr ApplicationDeployment::lookupComponentByInstantiationId(const std::string& identifier) +{ + ComponentDeployment* deployment = getComponentDeployment(identifier); + if (deployment) { + return deployment->getResourcePtr(); + } + return CF::Resource::_nil(); +} + +CF::Device_ptr ApplicationDeployment::lookupDeviceThatLoadedComponentInstantiationId(const std::string& componentId) +{ + LOG_TRACE(ApplicationDeployment, "[DeviceLookup] Lookup device that loaded component " << componentId); + + ComponentDeployment* deployment = getComponentDeployment(componentId); + if (!deployment) { + LOG_WARN(ApplicationDeployment, "[DeviceLookup] Component not found"); + return CF::Device::_nil(); + } + + boost::shared_ptr device = deployment->getAssignedDevice(); + if (!device) { + LOG_WARN(ApplicationDeployment, "[DeviceLookup] Component not assigned to device"); + return CF::Device::_nil(); + } + + LOG_TRACE(ApplicationDeployment, "[DeviceLookup] Assigned device id " << device->identifier); + return CF::Device::_duplicate(device->device); +} + +CF::Device_ptr ApplicationDeployment::lookupDeviceUsedByComponentInstantiationId(const std::string& componentId, + const std::string& usesId) +{ + LOG_TRACE(ApplicationDeployment, "[DeviceLookup] Lookup device used by component " << componentId); + + ComponentDeployment* deployment = getComponentDeployment(componentId); + if (!deployment) { + LOG_WARN(ApplicationDeployment, "[DeviceLookup] Component not found"); + return CF::Device::_nil(); + } + + UsesDeviceAssignment* uses = deployment->getUsesDeviceAssignment(usesId); + if (!uses) { + LOG_WARN(ApplicationDeployment, "[DeviceLookup] UsesDevice not found"); + return CF::Device::_nil(); + } + + //LOG_TRACE(ApplicationDeployment, "[DeviceLookup] Assigned device id " << deviceId); + return uses->getAssignedDevice(); +} + +CF::Device_ptr ApplicationDeployment::lookupDeviceUsedByApplication(const std::string& usesRefId) +{ + LOG_TRACE(ApplicationDeployment, "[DeviceLookup] Lookup device used by application, Uses Id: " << usesRefId); + + UsesDeviceAssignment* uses = getUsesDeviceAssignment(usesRefId); + if (!uses) { + LOG_WARN(ApplicationDeployment, "[DeviceLookup] UsesDevice not found"); + return CF::Device::_nil(); + } + + //LOG_TRACE(ApplicationDeployment, "[DeviceLookup] Assigned device id " << deviceId); + return uses->getAssignedDevice(); +} diff --git a/redhawk/src/control/sdr/dommgr/ApplicationDeployment.h b/redhawk/src/control/sdr/dommgr/ApplicationDeployment.h new file mode 100644 index 000000000..6a0f9d7fc --- /dev/null +++ b/redhawk/src/control/sdr/dommgr/ApplicationDeployment.h @@ -0,0 +1,102 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK core. + * + * REDHAWK core is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +#ifndef APPLICATIONDEPLOYMENT_H +#define APPLICATIONDEPLOYMENT_H + +#include +#include + +#include +#include + +#include +#include +#include + +#include "connectionSupport.h" +#include "Deployment.h" + +namespace ossie { + + class ApplicationDeployment : public ComponentLookup, public DeviceLookup, public UsesDeviceDeployment + { + ENABLE_LOGGING; + + public: + typedef std::vector ComponentList; + typedef std::map CpuReservations; + + ApplicationDeployment(const SoftwareAssembly& sad, + const std::string& instanceName, + const CF::Properties& initConfiguration); + ~ApplicationDeployment(); + + void loadProfiles(CF::FileSystem_ptr fileSystem); + + const std::string& getIdentifier() const; + + const SoftPkg* getSoftPkg(const std::string& filename) const; + + /** + * Returns the properties used for evaluating math statements in + * allocation + */ + redhawk::PropertyMap getAllocationContext() const; + + ComponentDeployment* getAssemblyController(); + + ComponentDeployment* createComponentDeployment(const SoftPkg* softpkg, + const ComponentInstantiation* instantiation); + + const ComponentList& getComponentDeployments(); + ComponentDeployment* getComponentDeployment(const std::string& instantiationId); + + void applyCpuReservations(const CpuReservations& reservations); + + // Adapt interfaces for component and device search to support + // ConnectionManager + // ComponentLookup interface + virtual CF::Resource_ptr lookupComponentByInstantiationId(const std::string& identifier); + + // DeviceLookup interface + CF::Device_ptr lookupDeviceThatLoadedComponentInstantiationId(const std::string& componentId); + CF::Device_ptr lookupDeviceUsedByComponentInstantiationId(const std::string& componentId, + const std::string& usesId); + CF::Device_ptr lookupDeviceUsedByApplication(const std::string& usesRefId); + + protected: + typedef boost::ptr_vector ProfileList; + + const SoftPkg* loadProfile(CF::FileSystem_ptr fileSystem, const std::string& filename); + + void overrideAssemblyControllerProperties(ComponentDeployment* deployment); + void overrideExternalProperties(ComponentDeployment* deployment); + + const SoftwareAssembly& sad; + const std::string identifier; + const std::string instanceName; + redhawk::PropertyMap initConfiguration; + ProfileList profiles; + ComponentList components; + }; +} + +#endif // APPLICATIONDEPLOYMENT_H diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index 58c807c0a..6fcc949be 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -21,7 +21,6 @@ #include #include -#include #include #include @@ -561,295 +560,3 @@ std::string ComponentDeployment::getLoggingConfiguration() const return std::string(); } - -ApplicationDeployment::ApplicationDeployment(const SoftwareAssembly& sad, - const std::string& instanceName, - const CF::Properties& initConfiguration) : - sad(sad), - // Give the application a unique identifier of the form - // "softwareassemblyid:ApplicationName", where the application name - // includes the serial number generated for the naming context - // (e.g. "Application_1"). - identifier(sad.getID() + ":" + instanceName), - instanceName(instanceName), - initConfiguration(initConfiguration) -{ -} - -ApplicationDeployment::~ApplicationDeployment() -{ - for (ComponentList::iterator comp = components.begin(); comp != components.end(); ++comp) { - delete *comp; - } -} - -const std::string& ApplicationDeployment::getIdentifier() const -{ - return identifier; -} - -void ApplicationDeployment::loadProfiles(CF::FileSystem_ptr fileSystem) -{ - // Walk through the host collocations first - BOOST_FOREACH(const SoftwareAssembly::HostCollocation& collocation, sad.getHostCollocations()) { - BOOST_FOREACH(const ComponentPlacement& placement, collocation.getComponents()) { - assert(placement.componentFile); - const SoftPkg* softpkg = loadProfile(fileSystem, placement.componentFile->getFileName()); - const ComponentInstantiation* instantiation = &(placement.getInstantiations()[0]); - if (softpkg->isScaCompliant() && !instantiation->isNamingService()) { - RH_NL_WARN("ApplicationFactory_impl", "Component instantiation " - << instantiation->getID() << " does not provide a 'findcomponent' name but " - << softpkg->getName() << " is SCA-compliant"); - } - } - } - - // Then, walk through the remaining non-collocated components - BOOST_FOREACH(const ComponentPlacement& placement, sad.getComponentPlacements()) { - assert(placement.componentFile); - const SoftPkg* softpkg = loadProfile(fileSystem, placement.componentFile->getFileName()); - const ComponentInstantiation* instantiation = &(placement.getInstantiations()[0]); - if (softpkg->isScaCompliant() && !instantiation->isNamingService()) { - RH_NL_WARN("ApplicationFactory_impl", "Component instantiation " - << instantiation->getID() << " does not provide a 'findcomponent' name but " - << softpkg->getName() << " is SCA-compliant"); - } - } -} - -ComponentDeployment* ApplicationDeployment::getAssemblyController() -{ - BOOST_FOREACH(ComponentDeployment* deployment, components) { - if (deployment->getInstantiation()->isAssemblyController()) { - return deployment; - } - } - return 0; -} - -redhawk::PropertyMap ApplicationDeployment::getAllocationContext() const -{ - redhawk::PropertyMap properties; - BOOST_FOREACH(ComponentDeployment* deployment, components) { - if (deployment->getInstantiation()->isAssemblyController()) { - properties = deployment->getAllocationContext(); - } - } - return properties; -} - -ComponentDeployment* ApplicationDeployment::createComponentDeployment(const SoftPkg* softpkg, - const ComponentInstantiation* instantiation) -{ - // Create a unique identifier for this component instance by appending the - // application instance's unique name - std::string component_id = instantiation->getID() + ":" + instanceName; - - ComponentDeployment* deployment = new ComponentDeployment(softpkg, instantiation, component_id); - components.push_back(deployment); - - // Override properties from initial configuration - if (instantiation->isAssemblyController()) { - overrideAssemblyControllerProperties(deployment); - } else { - overrideExternalProperties(deployment); - } - - return deployment; -} - -const ApplicationDeployment::ComponentList& ApplicationDeployment::getComponentDeployments() -{ - return components; -} - -ComponentDeployment* ApplicationDeployment::getComponentDeployment(const std::string& instantiationId) -{ - for (ComponentList::iterator comp = components.begin(); comp != components.end(); ++comp) { - if (instantiationId == (*comp)->getInstantiation()->getID()) { - return *comp; - } - } - - return 0; -} - -void ApplicationDeployment::applyCpuReservations(const CpuReservations& reservations) -{ - BOOST_FOREACH(ComponentDeployment* deployment, components) { - CpuReservations::const_iterator reserved = reservations.find(deployment->getIdentifier()); - if (reserved == reservations.end()) { - // NB: Check for the usage name for consistency with 2.0, although - // the instantiation ID would make more sense. In most cases, this - // is probably a moot point, since the IDE uses the same value for - // both. - reserved = reservations.find(deployment->getInstantiation()->getUsageName()); - } - if (reserved != reservations.end()) { - deployment->setCpuReservation(reserved->second); - } - } -} - -void ApplicationDeployment::overrideAssemblyControllerProperties(ComponentDeployment* deployment) -{ - BOOST_FOREACH(const redhawk::PropertyType& override, initConfiguration) { - const std::string propid = override.getId(); - if (propid == "LOGGING_CONFIG_URI") { - if (deployment->getLoggingConfiguration().empty()) { - RH_NL_TRACE("ApplicationFactory_impl", "Adding LOGGING_CONFIG_URI as a command line parameter with value " << override.getValue().toString()); - deployment->overrideProperty(propid, override.getValue()); - } - } else { - RH_NL_TRACE("ApplicationFactory_impl", "Overriding property " << propid - << " with " << override.getValue().toString()); - deployment->overrideProperty(propid, override.getValue()); - } - } -} - -void ApplicationDeployment::overrideExternalProperties(ComponentDeployment* deployment) -{ - const std::string& instantiation_id = deployment->getInstantiation()->getID(); - BOOST_FOREACH(const SoftwareAssembly::Property& property, sad.getExternalProperties()) { - if (property.comprefid == instantiation_id) { - std::string property_id = property.externalpropid; - if (property_id.empty()) { - property_id = property.propid; - } - redhawk::PropertyMap::iterator override = initConfiguration.find(property_id); - if (override != initConfiguration.end()) { - RH_NL_TRACE("ApplicationFactory_impl", "Overriding external property " << property_id - << " (" << property.propid << ") = " << override->getValue().toString()); - deployment->overrideProperty(property.propid, override->getValue()); - } - } - } -} - - -const SoftPkg* ApplicationDeployment::getSoftPkg(const std::string& filename) const -{ - BOOST_FOREACH(const SoftPkg& softpkg, profiles) { - if (softpkg.getSPDFile() == filename) { - return &softpkg; - } - } - - throw std::logic_error(filename + " was never loaded"); -} - -const SoftPkg* ApplicationDeployment::loadProfile(CF::FileSystem_ptr fileSystem, - const std::string& filename) -{ - BOOST_FOREACH(const SoftPkg& profile, profiles) { - if (profile.getSPDFile() == filename) { - RH_NL_TRACE("ApplicationFactory_impl", "Found existing profile " << filename); - return &profile; - } - } - - RH_NL_TRACE("ApplicationFactory_impl", "Loading SPD file " << filename); - File_stream spd_stream(fileSystem, filename.c_str()); - SoftPkg* spd = new SoftPkg(spd_stream, filename); - profiles.push_back(spd); - spd_stream.close(); - - const SPD::Implementations& spd_impls = spd->getImplementations(); - for (SPD::Implementations::const_iterator impl = spd_impls.begin(); impl != spd_impls.end(); ++impl) { - const SPD::SoftPkgDependencies& deps = impl->getSoftPkgDependencies(); - for (SPD::SoftPkgDependencies::const_iterator dep = deps.begin(); dep != deps.end(); ++dep) { - SPD::SoftPkgRef& ref = const_cast(*dep); - RH_NL_TRACE("ApplicationFactory_impl", "Resolving soft package reference " << ref.localfile); - loadProfile(fileSystem, ref.localfile); - } - } - - if (spd->getPRFFile()) { - RH_NL_TRACE("ApplicationFactory_impl", "Loading PRF file " << spd->getPRFFile()); - try { - spd->setProperties(boost::make_shared()); - File_stream prf_stream(fileSystem, spd->getPRFFile()); - spd->getProperties()->load(prf_stream); - } catch (const std::exception& exc) { - RH_NL_ERROR("ApplicationFactory_impl", "Invalid PRF file " << spd->getPRFFile() << ": " << exc.what()); - } - } - - if (spd->getSCDFile()) { - RH_NL_TRACE("ApplicationFactory_impl", "Loading SCD file " << spd->getSCDFile()); - try { - spd->setDescriptor(boost::make_shared()); - File_stream scd_stream(fileSystem, spd->getSCDFile()); - spd->getDescriptor()->load(scd_stream); - } catch (const std::exception& exc) { - RH_NL_ERROR("ApplicationFactory_impl", "Invalid SCD file " << spd->getSCDFile() << ": " << exc.what()); - } - } - - return spd; -} - -CF::Resource_ptr ApplicationDeployment::lookupComponentByInstantiationId(const std::string& identifier) -{ - ComponentDeployment* deployment = getComponentDeployment(identifier); - if (deployment) { - return deployment->getResourcePtr(); - } - return CF::Resource::_nil(); -} - -CF::Device_ptr ApplicationDeployment::lookupDeviceThatLoadedComponentInstantiationId(const std::string& componentId) -{ - RH_NL_TRACE("ApplicationFactory_impl", "[DeviceLookup] Lookup device that loaded component " << componentId); - - ComponentDeployment* deployment = getComponentDeployment(componentId); - if (!deployment) { - RH_NL_WARN("ApplicationFactory_impl", "[DeviceLookup] Component not found"); - return CF::Device::_nil(); - } - - boost::shared_ptr device = deployment->getAssignedDevice(); - if (!device) { - RH_NL_WARN("ApplicationFactory_impl", "[DeviceLookup] Component not assigned to device"); - return CF::Device::_nil(); - } - - RH_NL_TRACE("ApplicationFactory_impl", "[DeviceLookup] Assigned device id " << device->identifier); - return CF::Device::_duplicate(device->device); -} - -CF::Device_ptr ApplicationDeployment::lookupDeviceUsedByComponentInstantiationId(const std::string& componentId, - const std::string& usesId) -{ - RH_NL_TRACE("ApplicationFactory_impl", "[DeviceLookup] Lookup device used by component " << componentId); - - ComponentDeployment* deployment = getComponentDeployment(componentId); - if (!deployment) { - RH_NL_WARN("ApplicationFactory_impl", "[DeviceLookup] Component not found"); - return CF::Device::_nil(); - } - - UsesDeviceAssignment* uses = deployment->getUsesDeviceAssignment(usesId); - if (!uses) { - RH_NL_WARN("ApplicationFactory_impl", "[DeviceLookup] UsesDevice not found"); - return CF::Device::_nil(); - } - - //RH_NL_TRACE("ApplicationFactory_impl", "[DeviceLookup] Assigned device id " << deviceId); - return uses->getAssignedDevice(); -} - -CF::Device_ptr ApplicationDeployment::lookupDeviceUsedByApplication(const std::string& usesRefId) -{ - RH_NL_TRACE("ApplicationFactory_impl", "[DeviceLookup] Lookup device used by application, Uses Id: " << usesRefId); - - UsesDeviceAssignment* uses = getUsesDeviceAssignment(usesRefId); - if (!uses) { - RH_NL_WARN("ApplicationFactory_impl", "[DeviceLookup] UsesDevice not found"); - return CF::Device::_nil(); - } - - //RH_NL_TRACE("ApplicationFactory_impl", "[DeviceLookup] Assigned device id " << deviceId); - return uses->getAssignedDevice(); -} diff --git a/redhawk/src/control/sdr/dommgr/Deployment.h b/redhawk/src/control/sdr/dommgr/Deployment.h index 80cb54bd2..cd8fb52a5 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.h +++ b/redhawk/src/control/sdr/dommgr/Deployment.h @@ -25,12 +25,9 @@ #include #include -#include #include -#include - -#include "connectionSupport.h" +#include "PersistenceStore.h" class Application_impl; @@ -183,65 +180,6 @@ namespace ossie { redhawk::PropertyMap affinityOptions; }; - class ApplicationDeployment : public ComponentLookup, public DeviceLookup, public UsesDeviceDeployment - { - public: - typedef std::vector ComponentList; - typedef std::map CpuReservations; - - ApplicationDeployment(const SoftwareAssembly& sad, - const std::string& instanceName, - const CF::Properties& initConfiguration); - ~ApplicationDeployment(); - - void loadProfiles(CF::FileSystem_ptr fileSystem); - - const std::string& getIdentifier() const; - - const SoftPkg* getSoftPkg(const std::string& filename) const; - - /** - * Returns the properties used for evaluating math statements in - * allocation - */ - redhawk::PropertyMap getAllocationContext() const; - - ComponentDeployment* getAssemblyController(); - - ComponentDeployment* createComponentDeployment(const SoftPkg* softpkg, - const ComponentInstantiation* instantiation); - - const ComponentList& getComponentDeployments(); - ComponentDeployment* getComponentDeployment(const std::string& instantiationId); - - void applyCpuReservations(const CpuReservations& reservations); - - // Adapt interfaces for component and device search to support - // ConnectionManager - // ComponentLookup interface - virtual CF::Resource_ptr lookupComponentByInstantiationId(const std::string& identifier); - - // DeviceLookup interface - CF::Device_ptr lookupDeviceThatLoadedComponentInstantiationId(const std::string& componentId); - CF::Device_ptr lookupDeviceUsedByComponentInstantiationId(const std::string& componentId, - const std::string& usesId); - CF::Device_ptr lookupDeviceUsedByApplication(const std::string& usesRefId); - - protected: - typedef boost::ptr_vector ProfileList; - - const SoftPkg* loadProfile(CF::FileSystem_ptr fileSystem, const std::string& filename); - - void overrideAssemblyControllerProperties(ComponentDeployment* deployment); - void overrideExternalProperties(ComponentDeployment* deployment); - - const SoftwareAssembly& sad; - const std::string identifier; - const std::string instanceName; - redhawk::PropertyMap initConfiguration; - ProfileList profiles; - ComponentList components; - }; } #endif // DEPLOYMENT_H diff --git a/redhawk/src/control/sdr/dommgr/Makefile.am b/redhawk/src/control/sdr/dommgr/Makefile.am index 823881545..b6ea82725 100644 --- a/redhawk/src/control/sdr/dommgr/Makefile.am +++ b/redhawk/src/control/sdr/dommgr/Makefile.am @@ -34,6 +34,7 @@ DomainManager_SOURCES = connectionSupport.cpp \ DomainManager_impl.cpp \ FakeApplication.cpp \ Deployment.cpp \ + ApplicationDeployment.cpp \ main.cpp DomainManager_CPPFLAGS = -I../../include -I../../parser -I$(top_srcdir)/base/include -I$(top_srcdir)/base $(BOOST_CPPFLAGS) $(OMNIORB_CFLAGS) $(LOG4CXX_FLAGS) DomainManager_CXXFLAGS = -Wall diff --git a/redhawk/src/control/sdr/dommgr/createHelper.h b/redhawk/src/control/sdr/dommgr/createHelper.h index a9f0d6244..631fe926e 100644 --- a/redhawk/src/control/sdr/dommgr/createHelper.h +++ b/redhawk/src/control/sdr/dommgr/createHelper.h @@ -28,7 +28,7 @@ #include #include "PersistenceStore.h" -#include "Deployment.h" +#include "ApplicationDeployment.h" class Application_impl; class AllocationManager_impl; From 82b0e772a538f9e6f06576f4d2fd55ca577b9e1b Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 1 Jun 2016 13:06:02 -0400 Subject: [PATCH 0334/1644] Add canOverride() method to parser properties, instead of having to know the rules at point-of-use --- redhawk/src/control/include/ossie/Properties.h | 1 + redhawk/src/control/parser/Properties.cpp | 10 ++++++++++ redhawk/src/control/sdr/dommgr/Deployment.cpp | 6 ++---- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/redhawk/src/control/include/ossie/Properties.h b/redhawk/src/control/include/ossie/Properties.h index 667c20a1e..c505f77b1 100644 --- a/redhawk/src/control/include/ossie/Properties.h +++ b/redhawk/src/control/include/ossie/Properties.h @@ -132,6 +132,7 @@ namespace ossie { bool isReadOnly() const; bool isReadWrite() const; bool isWriteOnly() const; + bool canOverride() const; bool isAllocation() const; bool isConfigure() const; bool isProperty() const; diff --git a/redhawk/src/control/parser/Properties.cpp b/redhawk/src/control/parser/Properties.cpp index 6da95b097..903861859 100644 --- a/redhawk/src/control/parser/Properties.cpp +++ b/redhawk/src/control/parser/Properties.cpp @@ -429,6 +429,16 @@ bool Property::isWriteOnly() const return (mode == MODE_WRITEONLY); } +bool Property::canOverride() const +{ + // Only allow overrides for writable or 'property' kind properties + if (isProperty()) { + return true; + } else { + return !isReadOnly(); + } +} + bool Property::isEqual() const { return (action == ACTION_EQ); diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index 6fcc949be..960a7e119 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -240,8 +240,7 @@ ComponentDeployment::ComponentDeployment(const SoftPkg* softpkg, RH_NL_WARN("ApplicationFactory_impl", "Ignoring attempt to override property " << override.getID() << " that does not exist in component"); } - } else if (property->isReadOnly() && !property->isProperty()) { - // Only 'property' kind supports overrides if it's read-only + } else if (!property->canOverride()) { RH_NL_WARN("ApplicationFactory_impl", "Ignoring attempt to override read-only property " << property->getID()); } @@ -460,8 +459,7 @@ void ComponentDeployment::overrideProperty(const std::string& id, const CORBA::A CF::DataType ComponentDeployment::getPropertyValue(const Property* property) const { - // Only allow overrides for writable or 'property' kind properties - if (!property->isReadOnly() || property->isProperty()) { + if (property->canOverride()) { // Check for a runtime override first redhawk::PropertyMap::const_iterator override = overrides.find(property->getID()); if (override != overrides.end()) { From 8479db07100605f7d8e5a7ff7c986d68c963c3fb Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 1 Jun 2016 13:45:01 -0400 Subject: [PATCH 0335/1644] Change loading of profiles slightly to avoid displaying warnings for softpkg dependencies with invalid PRF/SCD references (at least one of the test libraries) and give consistent checking of component instantiations --- .../sdr/dommgr/ApplicationDeployment.cpp | 81 +++++++++---------- .../sdr/dommgr/ApplicationDeployment.h | 5 +- 2 files changed, 44 insertions(+), 42 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp b/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp index 6338f9611..3dd9ca542 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp @@ -62,27 +62,13 @@ void ApplicationDeployment::loadProfiles(CF::FileSystem_ptr fileSystem) // Walk through the host collocations first BOOST_FOREACH(const SoftwareAssembly::HostCollocation& collocation, sad.getHostCollocations()) { BOOST_FOREACH(const ComponentPlacement& placement, collocation.getComponents()) { - assert(placement.componentFile); - const SoftPkg* softpkg = loadProfile(fileSystem, placement.componentFile->getFileName()); - const ComponentInstantiation* instantiation = &(placement.getInstantiations()[0]); - if (softpkg->isScaCompliant() && !instantiation->isNamingService()) { - LOG_WARN(ApplicationDeployment, "Component instantiation " - << instantiation->getID() << " does not provide a 'findcomponent' name but " - << softpkg->getName() << " is SCA-compliant"); - } + loadComponentProfile(fileSystem, placement); } } // Then, walk through the remaining non-collocated components BOOST_FOREACH(const ComponentPlacement& placement, sad.getComponentPlacements()) { - assert(placement.componentFile); - const SoftPkg* softpkg = loadProfile(fileSystem, placement.componentFile->getFileName()); - const ComponentInstantiation* instantiation = &(placement.getInstantiations()[0]); - if (softpkg->isScaCompliant() && !instantiation->isNamingService()) { - LOG_WARN(ApplicationDeployment, "Component instantiation " - << instantiation->getID() << " does not provide a 'findcomponent' name but " - << softpkg->getName() << " is SCA-compliant"); - } + loadComponentProfile(fileSystem, placement); } } @@ -209,10 +195,45 @@ const SoftPkg* ApplicationDeployment::getSoftPkg(const std::string& filename) co throw std::logic_error(filename + " was never loaded"); } -const SoftPkg* ApplicationDeployment::loadProfile(CF::FileSystem_ptr fileSystem, - const std::string& filename) +void ApplicationDeployment::loadComponentProfile(CF::FileSystem_ptr fileSystem, + const ComponentPlacement& placement) +{ + assert(placement.componentFile); + SoftPkg* softpkg = loadProfile(fileSystem, placement.componentFile->getFileName()); + const ComponentInstantiation* instantiation = &(placement.getInstantiations()[0]); + if (softpkg->isScaCompliant() && !instantiation->isNamingService()) { + LOG_WARN(ApplicationDeployment, "Component instantiation " + << instantiation->getID() << " does not provide a 'findcomponent' name but " + << softpkg->getName() << " is SCA-compliant"); + } + + if (softpkg->getPRFFile()) { + LOG_TRACE(ApplicationDeployment, "Loading PRF file " << softpkg->getPRFFile()); + try { + softpkg->setProperties(boost::make_shared()); + File_stream prf_stream(fileSystem, softpkg->getPRFFile()); + softpkg->getProperties()->load(prf_stream); + } catch (const std::exception& exc) { + LOG_ERROR(ApplicationDeployment, "Invalid PRF file " << softpkg->getPRFFile() << ": " << exc.what()); + } + } + + if (softpkg->getSCDFile()) { + LOG_TRACE(ApplicationDeployment, "Loading SCD file " << softpkg->getSCDFile()); + try { + softpkg->setDescriptor(boost::make_shared()); + File_stream scd_stream(fileSystem, softpkg->getSCDFile()); + softpkg->getDescriptor()->load(scd_stream); + } catch (const std::exception& exc) { + LOG_ERROR(ApplicationDeployment, "Invalid SCD file " << softpkg->getSCDFile() << ": " << exc.what()); + } + } +} + +SoftPkg* ApplicationDeployment::loadProfile(CF::FileSystem_ptr fileSystem, + const std::string& filename) { - BOOST_FOREACH(const SoftPkg& profile, profiles) { + BOOST_FOREACH(SoftPkg& profile, profiles) { if (profile.getSPDFile() == filename) { LOG_TRACE(ApplicationDeployment, "Found existing profile " << filename); return &profile; @@ -235,28 +256,6 @@ const SoftPkg* ApplicationDeployment::loadProfile(CF::FileSystem_ptr fileSystem, } } - if (spd->getPRFFile()) { - LOG_TRACE(ApplicationDeployment, "Loading PRF file " << spd->getPRFFile()); - try { - spd->setProperties(boost::make_shared()); - File_stream prf_stream(fileSystem, spd->getPRFFile()); - spd->getProperties()->load(prf_stream); - } catch (const std::exception& exc) { - LOG_ERROR(ApplicationDeployment, "Invalid PRF file " << spd->getPRFFile() << ": " << exc.what()); - } - } - - if (spd->getSCDFile()) { - LOG_TRACE(ApplicationDeployment, "Loading SCD file " << spd->getSCDFile()); - try { - spd->setDescriptor(boost::make_shared()); - File_stream scd_stream(fileSystem, spd->getSCDFile()); - spd->getDescriptor()->load(scd_stream); - } catch (const std::exception& exc) { - LOG_ERROR(ApplicationDeployment, "Invalid SCD file " << spd->getSCDFile() << ": " << exc.what()); - } - } - return spd; } diff --git a/redhawk/src/control/sdr/dommgr/ApplicationDeployment.h b/redhawk/src/control/sdr/dommgr/ApplicationDeployment.h index 6a0f9d7fc..c6c34c18a 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationDeployment.h +++ b/redhawk/src/control/sdr/dommgr/ApplicationDeployment.h @@ -85,7 +85,10 @@ namespace ossie { protected: typedef boost::ptr_vector ProfileList; - const SoftPkg* loadProfile(CF::FileSystem_ptr fileSystem, const std::string& filename); + void loadComponentProfile(CF::FileSystem_ptr fileSystem, + const ComponentPlacement& placement); + + SoftPkg* loadProfile(CF::FileSystem_ptr fileSystem, const std::string& filename); void overrideAssemblyControllerProperties(ComponentDeployment* deployment); void overrideExternalProperties(ComponentDeployment* deployment); From 1b4cb13acdcb9d36f9bca38f39bb672ada0474a1 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 1 Jun 2016 14:02:39 -0400 Subject: [PATCH 0336/1644] Move management of the Properties and ComponentDescriptor instances into SoftPkg --- redhawk/src/control/include/ossie/SoftPkg.h | 28 +++++-------------- redhawk/src/control/parser/SoftPkg.cpp | 26 ++++++++++++++++- .../sdr/dommgr/ApplicationDeployment.cpp | 6 ++-- 3 files changed, 34 insertions(+), 26 deletions(-) diff --git a/redhawk/src/control/include/ossie/SoftPkg.h b/redhawk/src/control/include/ossie/SoftPkg.h index 7b5ecbba7..85fd7ca39 100644 --- a/redhawk/src/control/include/ossie/SoftPkg.h +++ b/redhawk/src/control/include/ossie/SoftPkg.h @@ -190,17 +190,9 @@ namespace ossie { class SoftPkg { public: - SoftPkg() : _spd(0), _spdFile("") {} - + SoftPkg(); SoftPkg(std::istream& input, const std::string& _spdFile) throw (ossie::parser_error); - SoftPkg& operator=(SoftPkg other) - { - _spd = other._spd; - _spdFile = other._spdFile; - return *this; - } - public: void load(std::istream& input, const std::string& _spdFile) throw (ossie::parser_error); @@ -292,25 +284,19 @@ namespace ossie { return _spd->type != "sca_non_compliant"; } - const boost::shared_ptr& getProperties() const + const Properties* getProperties() const { - return _properties; + return _properties.get(); } - void setProperties(const boost::shared_ptr& properties) - { - _properties = properties; - } + void loadProperties(std::istream& file); - const boost::shared_ptr& getDescriptor() const + const ComponentDescriptor* getDescriptor() const { - return _descriptor; + return _descriptor.get(); } - void setDescriptor(const boost::shared_ptr& descriptor) - { - _descriptor = descriptor; - } + void loadDescriptor(std::istream& file); protected: std::auto_ptr _spd; diff --git a/redhawk/src/control/parser/SoftPkg.cpp b/redhawk/src/control/parser/SoftPkg.cpp index 32d034ba7..30a722a8b 100644 --- a/redhawk/src/control/parser/SoftPkg.cpp +++ b/redhawk/src/control/parser/SoftPkg.cpp @@ -19,11 +19,23 @@ */ #include -#include "ossie/SoftPkg.h" + +#include + +#include +#include +#include + #include "internal/spd-parser.h" using namespace ossie; +SoftPkg::SoftPkg() : + _spd(0), + _spdFile() +{ +} + SoftPkg::SoftPkg(std::istream& input, const std::string& spdFile) throw (ossie::parser_error) { this->load(input, spdFile); } @@ -53,6 +65,18 @@ void SoftPkg::load(std::istream& input, const std::string& spdFile) throw (ossie } } +void SoftPkg::loadProperties(std::istream& input) +{ + _properties = boost::make_shared(); + _properties->load(input); +} + +void SoftPkg::loadDescriptor(std::istream& input) +{ + _descriptor = boost::make_shared(); + _descriptor->load(input); +} + const std::string SPD::SoftPkgRef::asString() const { std::ostringstream out; out << "SoftPkgRef localfile: " << this->localfile << " implref: " << this->implref; diff --git a/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp b/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp index 3dd9ca542..a29a84f6f 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp @@ -210,9 +210,8 @@ void ApplicationDeployment::loadComponentProfile(CF::FileSystem_ptr fileSystem, if (softpkg->getPRFFile()) { LOG_TRACE(ApplicationDeployment, "Loading PRF file " << softpkg->getPRFFile()); try { - softpkg->setProperties(boost::make_shared()); File_stream prf_stream(fileSystem, softpkg->getPRFFile()); - softpkg->getProperties()->load(prf_stream); + softpkg->loadProperties(prf_stream); } catch (const std::exception& exc) { LOG_ERROR(ApplicationDeployment, "Invalid PRF file " << softpkg->getPRFFile() << ": " << exc.what()); } @@ -221,9 +220,8 @@ void ApplicationDeployment::loadComponentProfile(CF::FileSystem_ptr fileSystem, if (softpkg->getSCDFile()) { LOG_TRACE(ApplicationDeployment, "Loading SCD file " << softpkg->getSCDFile()); try { - softpkg->setDescriptor(boost::make_shared()); File_stream scd_stream(fileSystem, softpkg->getSCDFile()); - softpkg->getDescriptor()->load(scd_stream); + softpkg->loadDescriptor(scd_stream); } catch (const std::exception& exc) { LOG_ERROR(ApplicationDeployment, "Invalid SCD file " << softpkg->getSCDFile() << ": " << exc.what()); } From 005a42f22ac5c08a5aafc504c2bee2c248ae1332 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 1 Jun 2016 14:25:20 -0400 Subject: [PATCH 0337/1644] Provide methods to get external ID/name for application ports and properties --- .../control/include/ossie/SoftwareAssembly.h | 42 +++++++++++++------ .../sdr/dommgr/ApplicationFactory_impl.cpp | 26 ++---------- 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/redhawk/src/control/include/ossie/SoftwareAssembly.h b/redhawk/src/control/include/ossie/SoftwareAssembly.h index c7330c8ee..de75db8ad 100644 --- a/redhawk/src/control/include/ossie/SoftwareAssembly.h +++ b/redhawk/src/control/include/ossie/SoftwareAssembly.h @@ -61,18 +61,27 @@ namespace ossie { }; class Port { - public: - typedef enum { - NONE = 0, - USESIDENTIFIER, - PROVIDESIDENTIFIER, - SUPPORTEDIDENTIFIER - } port_type; - - std::string componentrefid; - std::string identifier; - std::string externalname; - port_type type; + public: + typedef enum { + NONE = 0, + USESIDENTIFIER, + PROVIDESIDENTIFIER, + SUPPORTEDIDENTIFIER + } port_type; + + std::string componentrefid; + std::string identifier; + std::string externalname; + port_type type; + + const std::string& getExternalName() const + { + if (externalname.empty()) { + return identifier; + } else { + return externalname; + } + } }; class Property { @@ -80,6 +89,15 @@ namespace ossie { std::string comprefid; std::string propid; std::string externalpropid; + + const std::string& getExternalID() const + { + if (externalpropid.empty()) { + return propid; + } else { + return externalpropid; + } + } }; class SAD { diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 03a3c9d31..63ca89a7b 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -458,12 +458,7 @@ ApplicationFactory_impl::ApplicationFactory_impl (const std::string& softwarePro std::vector extPorts; for (std::vector::const_iterator port = ports.begin(); port != ports.end(); ++port) { // Gets name to use - std::string extName; - if (port->externalname != "") { - extName = port->externalname; - } else { - extName = port->identifier; - } + const std::string& extName = port->getExternalName(); // Check for duplicate if (std::find(extPorts.begin(), extPorts.end(), extName) == extPorts.end()) { extPorts.push_back(extName); @@ -550,12 +545,7 @@ ApplicationFactory_impl::ApplicationFactory_impl (const std::string& softwarePro std::vector extProps; for (std::vector::const_iterator prop = properties.begin(); prop != properties.end(); ++prop) { // Gets name to use - std::string extName; - if (prop->externalpropid != "") { - extName = prop->externalpropid; - } else { - extName = prop->propid; - } + const std::string& extName = prop->getExternalID(); // Check for duplicate if (std::find(extProps.begin(), extProps.end(), extName) == extProps.end()) { extProps.push_back(extName); @@ -935,11 +925,7 @@ void createHelper::setUpExternalPorts(ossie::ApplicationDeployment& appDeploymen } // Add it to the list of external ports on the application object. - std::string name = port->externalname; - if (name.empty()) { - name = port->identifier; - } - application->addExternalPort(name, obj); + application->addExternalPort(port->getExternalName(), obj); } } @@ -966,11 +952,7 @@ void createHelper::setUpExternalProperties(ossie::ApplicationDeployment& appDepl } CF::Resource_var comp = deployment->getResourcePtr(); - std::string external_id = prop->externalpropid; - if (external_id.empty()) { - external_id = prop->propid; - } - application->addExternalProperty(prop->propid, external_id, comp); + application->addExternalProperty(prop->propid, prop->getExternalID(), comp); } } From 7596611a02bd76bd1cc0e82afbaa0393f08d9d35 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 1 Jun 2016 14:40:51 -0400 Subject: [PATCH 0338/1644] Remove unneeded member --- redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp | 6 ++---- redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h | 1 - 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 63ca89a7b..21365aebe 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -393,10 +393,8 @@ ApplicationFactory_impl::ApplicationFactory_impl (const std::string& softwarePro throw; } - _dmnMgr = domainManager->_this(); - try { - _fileMgr = _dmnMgr->fileMgr(); + _fileMgr = _domainManager->fileMgr(); } catch ( std::exception& ex ) { ostringstream eout; eout << "The following standard exception occurred: "<_fileMgr failed with Unknown Exception"); + LOG_ERROR(ApplicationFactory_impl, "domainManager->_fileMgr failed with Unknown Exception"); throw CF::DomainManager::ApplicationInstallationError(CF::CF_EBADF, "Could not get File Manager from Domain Manager"); } diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h index 36ef043cc..faee2cec0 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h @@ -46,7 +46,6 @@ class ApplicationFactory_impl: public virtual POA_CF::ApplicationFactory ossie::SoftwareAssembly _sadParser; CF::FileManager_var _fileMgr; - CF::DomainManager_var _dmnMgr; boost::mutex _pendingCreateLock; From 13ff6511e9c753c288ce40bcbfbf00f8397c2ca8 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 1 Jun 2016 16:09:59 -0400 Subject: [PATCH 0339/1644] Separate component profile validation from basic SoftPkg validation --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 176 ++++++++---------- .../sdr/dommgr/ApplicationFactory_impl.h | 5 +- 2 files changed, 76 insertions(+), 105 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 21365aebe..283c296a2 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -151,33 +151,89 @@ ApplicationFactory_impl::ValidateFileLocation( CF::FileManager_ptr fileMgr, cons void ApplicationFactory_impl::ValidateSoftPkgDep (CF::FileManager_ptr fileMgr, DomainManager_impl *domMgr, const std::string& sfw_profile ) { SoftPkg pkg; - ValidateSPD(fileMgr, domMgr, pkg, sfw_profile, false, false ); + ValidateSPD(fileMgr, pkg, sfw_profile); } -std::string ApplicationFactory_impl::xmlParsingVersionMismatch(DomainManager_impl *domMgr, std::string &component_version) +void ApplicationFactory_impl::ValidateComponent(CF::FileManager_ptr fileMgr, + SoftPkg &spdParser, + const std::string& sfw_profile) { - std::string added_message; - if (!component_version.empty()) { + ValidateSPD(fileMgr, spdParser, sfw_profile); + + // query SPD for PRF + if (spdParser.getPRFFile() != 0) { + LOG_TRACE(ApplicationFactory_impl, "validating " << spdParser.getPRFFile()); try { - static std::string version = domMgr->getRedhawkVersion(); - if (redhawk::compareVersions(component_version, version) < 0) { - added_message = "Attempting to run a component from version "; - added_message += component_version; - added_message += " on REDHAWK version "; - added_message += version; - added_message += ". "; + ValidateFileLocation(fileMgr, spdParser.getPRFFile()); + + // check the file name ends with the extension given in the spec + if (spdParser.getPRFFile() && (strstr (spdParser.getPRFFile (), ".prf.xml")) == NULL) { + LOG_ERROR(ApplicationFactory_impl, "File " << spdParser.getPRFFile() << " should end in .prf.xml."); } - } catch ( ... ) {} + + LOG_TRACE(ApplicationFactory_impl, "Creating file stream"); + File_stream prfStream(fileMgr, spdParser.getPRFFile()); + LOG_TRACE(ApplicationFactory_impl, "Loading parser"); + Properties prfParser(prfStream); + LOG_TRACE(ApplicationFactory_impl, "Closing stream"); + prfStream.close(); + } catch (ossie::parser_error& ex ) { + std::string parser_error_line = ossie::retrieveParserErrorLineNumber(ex.what()); + LOG_ERROR(ApplicationFactory_impl, "Error validating PRF " << spdParser.getPRFFile() << ". " << parser_error_line << "The XML parser returned the following error: " << ex.what()); + throw CF::DomainManager::ApplicationInstallationError (CF::CF_EBADF, ex.what()); + } catch (CF::InvalidFileName ex) { + LOG_ERROR(ApplicationFactory_impl, "Failed to validate PRF due to invalid file name " << ex.msg); + throw CF::DomainManager::ApplicationInstallationError (CF::CF_EBADF, ex.msg); + } catch (CF::FileException ex) { + LOG_ERROR(ApplicationFactory_impl, "Failed to validate PRF due to file exception" << ex.msg); + throw CF::DomainManager::ApplicationInstallationError (CF::CF_EBADF, ex.msg); + } catch ( ... ) { + LOG_ERROR(ApplicationFactory_impl, "Unexpected error validating PRF " << spdParser.getPRFFile()); + throw CF::DomainManager::ApplicationInstallationError (CF::CF_EBADF, ""); + } + } else { + LOG_TRACE(ApplicationFactory_impl, "No PRF file to validate"); + } + + if (spdParser.getSCDFile() != 0) { + try { + // query SPD for SCD + LOG_TRACE(ApplicationFactory_impl, "validating " << spdParser.getSCDFile()); + ValidateFileLocation ( fileMgr, spdParser.getSCDFile ()); + + // Check the filename ends with the extension given in the spec + if ((strstr (spdParser.getSCDFile (), ".scd.xml")) == NULL) + { LOG_ERROR(ApplicationFactory_impl, "File " << spdParser.getSCDFile() << " should end with .scd.xml."); } + + File_stream _scd(fileMgr, spdParser.getSCDFile()); + ComponentDescriptor scdParser (_scd); + _scd.close(); + } catch (ossie::parser_error& ex) { + std::string parser_error_line = ossie::retrieveParserErrorLineNumber(ex.what()); + LOG_ERROR(ApplicationFactory_impl, "SCD file failed validation; parser error on file " << spdParser.getSCDFile() << ". " << parser_error_line << "The XML parser returned the following error: " << ex.what()); + throw CF::DomainManager::ApplicationInstallationError (CF::CF_EBADF, ex.what()); + } catch (CF::InvalidFileName ex) { + LOG_ERROR(ApplicationFactory_impl, "Failed to validate SCD due to invalid file name " << ex.msg); + throw CF::DomainManager::ApplicationInstallationError (CF::CF_EBADF, ex.msg); + } catch (CF::FileException ex) { + LOG_ERROR(ApplicationFactory_impl, "Failed to validate SCD due to file exception" << ex.msg); + throw CF::DomainManager::ApplicationInstallationError (CF::CF_EBADF, ex.msg); + } catch ( ... ) { + LOG_ERROR(ApplicationFactory_impl, "Unexpected error validating PRF " << spdParser.getSCDFile()); + throw CF::DomainManager::ApplicationInstallationError (CF::CF_EBADF, ""); + } + } else if (spdParser.isScaCompliant()) { + LOG_ERROR(ApplicationFactory_impl, "SCA compliant component is missing SCD file reference"); + throw CF::DomainManager::ApplicationInstallationError(CF::CF_EBADF, "SCA compliant components require SCD file"); + } else { + LOG_TRACE(ApplicationFactory_impl, "No SCD file to validate") } - return added_message; } void ApplicationFactory_impl::ValidateSPD(CF::FileManager_ptr fileMgr, DomainManager_impl *domMgr, SoftPkg &spdParser, - const std::string& sfw_profile, - const bool require_prf, - const bool require_scd) { + const std::string& sfw_profile) { TRACE_ENTER(ApplicationFactory_impl) if ( sfw_profile == "" ) { @@ -275,92 +331,6 @@ void ApplicationFactory_impl::ValidateSPD(CF::FileManager_ptr fileMgr, } } - - // query SPD for PRF - if (spdParser.getPRFFile() != 0) { - LOG_TRACE(ApplicationFactory_impl, "validating " << spdParser.getPRFFile()); - try { - ValidateFileLocation ( fileMgr, spdParser.getPRFFile ()); - - // check the file name ends with the extension given in the spec - if (spdParser.getPRFFile() && (strstr (spdParser.getPRFFile (), ".prf.xml")) == NULL) { - LOG_ERROR(ApplicationFactory_impl, "File " << spdParser.getPRFFile() << " should end in .prf.xml."); - } - - LOG_TRACE(ApplicationFactory_impl, "Creating file stream") - File_stream prfStream(fileMgr, spdParser.getPRFFile()); - LOG_TRACE(ApplicationFactory_impl, "Loading parser") - Properties prfParser(prfStream); - LOG_TRACE(ApplicationFactory_impl, "Closing stream") - prfStream.close(); - } catch (ossie::parser_error& ex ) { - ostringstream eout; - std::string component_version(spdParser.getSoftPkgType()); - eout << xmlParsingVersionMismatch(domMgr, component_version); - std::string parser_error_line = ossie::retrieveParserErrorLineNumber(ex.what()); - eout << "Failed to parse PRF: " << spdParser.getPRFFile() << ". " << parser_error_line << " The XML parser returned the following error: " << ex.what(); - LOG_ERROR(ApplicationFactory_impl, eout.str() ); - throw CF::DomainManager::ApplicationInstallationError (CF::CF_EBADF, eout.str().c_str()); - } catch (CF::InvalidFileName ex) { - if ( require_prf ) { - LOG_ERROR(ApplicationFactory_impl, "Failed to validate PRF: " << spdParser.getPRFFile() << " Invalid file name exception: " << ex.msg); - throw CF::DomainManager::ApplicationInstallationError (CF::CF_EBADF, ex.msg); - } - } catch (CF::FileException ex) { - if ( require_prf ) { - LOG_ERROR(ApplicationFactory_impl, "Failed to validate PRF: " << spdParser.getPRFFile() << " File exception: " << ex.msg); - throw CF::DomainManager::ApplicationInstallationError (CF::CF_EBADF, ex.msg); - } - } catch ( ... ) { - LOG_ERROR(ApplicationFactory_impl, "Unexpected error validating PRF: " << spdParser.getPRFFile()); - throw CF::DomainManager::ApplicationInstallationError (CF::CF_EBADF, ""); - } - } else { - LOG_TRACE(ApplicationFactory_impl, "No PRF file to validate") - } - - if (spdParser.getSCDFile() != 0) { - try { - // query SPD for SCD - LOG_TRACE(ApplicationFactory_impl, "validating " << spdParser.getSCDFile()); - ValidateFileLocation ( fileMgr, spdParser.getSCDFile ()); - - // Check the filename ends with the extension given in the spec - if ((strstr (spdParser.getSCDFile (), ".scd.xml")) == NULL) - { LOG_ERROR(ApplicationFactory_impl, "File " << spdParser.getSCDFile() << " should end with .scd.xml."); } - - File_stream _scd(fileMgr, spdParser.getSCDFile()); - ComponentDescriptor scdParser (_scd); - _scd.close(); - } catch (ossie::parser_error& ex) { - ostringstream eout; - std::string component_version(spdParser.getSoftPkgType()); - eout << xmlParsingVersionMismatch(domMgr, component_version); - std::string parser_error_line = ossie::retrieveParserErrorLineNumber(ex.what()); - eout << "Failed to parse SCD: " << spdParser.getSCDFile() << ". " << parser_error_line << " The XML parser returned the following error: " << ex.what(); - LOG_ERROR(ApplicationFactory_impl, eout.str() ); - throw CF::DomainManager::ApplicationInstallationError (CF::CF_EBADF, eout.str().c_str()); - } catch (CF::InvalidFileName ex) { - if ( require_scd ){ - LOG_ERROR(ApplicationFactory_impl, "Failed to validate SCD: " << spdParser.getSCDFile() << " Invalid file name exception: " << ex.msg); - throw CF::DomainManager::ApplicationInstallationError (CF::CF_EBADF, ex.msg); - } - } catch (CF::FileException ex) { - if ( require_scd ) { - LOG_ERROR(ApplicationFactory_impl, "Failed to validate SCD: " << spdParser.getSCDFile() << " File exception: " << ex.msg); - throw CF::DomainManager::ApplicationInstallationError (CF::CF_EBADF, ex.msg); - } - } catch ( ... ) { - LOG_ERROR(ApplicationFactory_impl, "Unexpected error validating SCD: " << spdParser.getSCDFile()); - throw CF::DomainManager::ApplicationInstallationError (CF::CF_EBADF, ""); - } - } else if (spdParser.isScaCompliant() and require_scd ) { - LOG_ERROR(ApplicationFactory_impl, "SCA compliant component is missing SCD file reference"); - throw CF::DomainManager::ApplicationInstallationError(CF::CF_EBADF, "SCA compliant components require SCD file"); - } else { - LOG_TRACE(ApplicationFactory_impl, "No SCD file to validate") - } - } catch (CF::InvalidFileName& ex) { LOG_ERROR(ApplicationFactory_impl, "Failed to validate SPD: " << sfw_profile << ", exception: " << ex.msg); throw CF::DomainManager::ApplicationInstallationError (CF::CF_EBADF, ex.msg); @@ -481,7 +451,7 @@ ApplicationFactory_impl::ApplicationFactory_impl (const std::string& softwarePro const std::string& p_name = comp->componentFile->filename; try { LOG_DEBUG(ApplicationFactory_impl, "Validating... COMP profile: " << p_name); - ValidateSPD( _fileMgr, comp_pkg, p_name.c_str() ) ; + ValidateComponent(_fileMgr, comp_pkg, p_name); } catch (CF::FileException& ex) { LOG_ERROR(ApplicationFactory_impl, "installApplication: While validating the SAD profile: " << ex.msg); throw CF::DomainManager::ApplicationInstallationError (CF::CF_EBADF, ex.msg); diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h index faee2cec0..33e3f60a8 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h @@ -58,8 +58,9 @@ class ApplicationFactory_impl: public virtual POA_CF::ApplicationFactory std::string getBaseWaveformContext(std::string waveform_context); static void ValidateFileLocation ( CF::FileManager_ptr fileMgr, const std::string &profile ); - static void ValidateSoftPkgDep( CF::FileManager_ptr fileMgr, DomainManager_impl *domMgr, const std::string &profile ); - static void ValidateSPD (CF::FileManager_ptr fileMgr, DomainManager_impl *domMgr, ossie::SoftPkg &spd, const std::string &profile, const bool require_prf=true, const bool require_scd=true ); + static void ValidateSoftPkgDep( CF::FileManager_ptr fileMgr, const std::string &profile ); + static void ValidateSPD (CF::FileManager_ptr fileMgr, ossie::SoftPkg& spd, const std::string& profile); + static void ValidateComponent (CF::FileManager_ptr fileMgr, ossie::SoftPkg& spd, const std::string& profile); protected: static std::string xmlParsingVersionMismatch(DomainManager_impl *domMgr, std::string &component_version); From a2aac666c601ec251f7196a0c090955d6c38bd65 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 1 Jun 2016 16:29:30 -0400 Subject: [PATCH 0340/1644] Iterate through all component instantiations within a placement, just in case --- .../sdr/dommgr/ApplicationDeployment.cpp | 13 ++++-- .../sdr/dommgr/ApplicationFactory_impl.cpp | 46 ++++++++++--------- 2 files changed, 32 insertions(+), 27 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp b/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp index a29a84f6f..66470bdca 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp @@ -200,11 +200,14 @@ void ApplicationDeployment::loadComponentProfile(CF::FileSystem_ptr fileSystem, { assert(placement.componentFile); SoftPkg* softpkg = loadProfile(fileSystem, placement.componentFile->getFileName()); - const ComponentInstantiation* instantiation = &(placement.getInstantiations()[0]); - if (softpkg->isScaCompliant() && !instantiation->isNamingService()) { - LOG_WARN(ApplicationDeployment, "Component instantiation " - << instantiation->getID() << " does not provide a 'findcomponent' name but " - << softpkg->getName() << " is SCA-compliant"); + if (softpkg->isScaCompliant()){ + BOOST_FOREACH(const ComponentInstantiation& instantiation, placement.getInstantiations()) { + if (!instantiation.isNamingService()) { + LOG_WARN(ApplicationDeployment, "Component instantiation " + << instantiation.getID() << " does not provide a 'findcomponent' name but " + << softpkg->getName() << " is SCA-compliant"); + } + } } if (softpkg->getPRFFile()) { diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 283c296a2..1b2c0150c 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -595,22 +595,20 @@ void createHelper::assignPlacementsToDevices(ossie::ApplicationDeployment& appDe // Place the remaining components one-by-one BOOST_FOREACH(const ComponentPlacement& placement, _appFact._sadParser.getComponentPlacements()) { const SoftPkg* softpkg = appDeployment.getSoftPkg(placement.componentFile->getFileName()); - // Even though it is possible for there to be more than one instantiation - // per component, the tooling doesn't support that, so supporting this at a - // framework level would add substantial complexity without providing any - // appreciable improvements. It is far easier to have multiple placements - // rather than multiple instantiations. - const ComponentInstantiation* instantiation = &(placement.getInstantiations()[0]); - std::string assigned_device; - DeviceAssignmentMap::const_iterator device = devices.find(instantiation->getID()); - if (device != devices.end()) { - assigned_device = device->second; - LOG_TRACE(ApplicationFactory_impl, "Component " << instantiation->getID() - << " is assigned to device " << assigned_device); + BOOST_FOREACH(const ComponentInstantiation& instantiation, placement.getInstantiations()) { + // Even though the XML supports more than one instantiation per + // component placement, the tooling doesn't support that, so this + // loop may be strictly academic + std::string assigned_device; + DeviceAssignmentMap::const_iterator device = devices.find(instantiation.getID()); + if (device != devices.end()) { + assigned_device = device->second; + LOG_TRACE(ApplicationFactory_impl, "Component " << instantiation.getID() + << " is assigned to device " << assigned_device); + } + ComponentDeployment* deployment = appDeployment.createComponentDeployment(softpkg, &instantiation); + allocateComponent(appDeployment, deployment, assigned_device); } - ossie::ComponentDeployment* deployment = appDeployment.createComponentDeployment(softpkg, - instantiation); - allocateComponent(appDeployment, deployment, assigned_device); } } @@ -769,13 +767,17 @@ void createHelper::_placeHostCollocation(ossie::ApplicationDeployment& appDeploy DeploymentList deployments; BOOST_FOREACH(const ComponentPlacement& placement, collocation.getComponents()) { const SoftPkg* softpkg = appDeployment.getSoftPkg(placement.componentFile->getFileName()); - const ComponentInstantiation* instantiation = &(placement.getInstantiations()[0]); - ossie::ComponentDeployment* deployment = appDeployment.createComponentDeployment(softpkg, instantiation); - deployments.push_back(deployment); - - DeviceAssignmentMap::const_iterator device = devices.find(instantiation->getID()); - if (device != devices.end()) { - assignedDevices.push_back(device->second); + BOOST_FOREACH(const ComponentInstantiation& instantiation, placement.getInstantiations()) { + // Even though the XML supports more than one instantiation per + // component placement, the tooling doesn't support that, so this + // loop may be strictly academic + ComponentDeployment* deployment = appDeployment.createComponentDeployment(softpkg, &instantiation); + deployments.push_back(deployment); + + DeviceAssignmentMap::const_iterator device = devices.find(instantiation.getID()); + if (device != devices.end()) { + assignedDevices.push_back(device->second); + } } } From 7d2fe34d0e0845227331867f0937262ed66cd7aa Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 1 Jun 2016 16:53:57 -0400 Subject: [PATCH 0341/1644] Make determination of whether a deployment is executable simpler --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 12 +--------- redhawk/src/control/sdr/dommgr/Deployment.cpp | 22 +++++++++++++++++++ redhawk/src/control/sdr/dommgr/Deployment.h | 1 + 3 files changed, 24 insertions(+), 11 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 1b2c0150c..b758905f8 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -1855,17 +1855,7 @@ void createHelper::loadAndExecuteComponents(const DeploymentList& deployments, throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EIO, message.str().c_str()); } - // OSSIE extends section D.2.1.6.3 to support loading a directory - // and execute a file in that directory using a entrypoint - // 1. Executable means to use CF LoadableDevice::load and CF ExecutableDevice::execute operations. This is a "main" process. - // - A Executable that references a directory instead of a file means to recursively load the contents of the directory - // and then execute the program specified via entrypoint - // 2. Driver and Kernel Module means load only. - // 3. SharedLibrary means dynamic linking. - // 4. A (SharedLibrary) Without a code entrypoint element means load only. - // 5. A (SharedLibrary) With a code entrypoint element means load and CF Device::execute. - if (((deployment->getCodeType() == CF::LoadableDevice::EXECUTABLE) || - (deployment->getCodeType() == CF::LoadableDevice::SHARED_LIBRARY)) && (deployment->getEntryPoint().size() != 0)) { + if (deployment->isExecutable()) { attemptComponentExecution(_appReg, deployment); } } diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index 960a7e119..2c26f23e2 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -219,6 +219,28 @@ CF::LoadableDevice::LoadType SoftpkgDeployment::getCodeType() const } } +bool SoftpkgDeployment::isExecutable() const +{ + // REDHAWK extends section D.2.1.6.3 to support loading a directory + // and execute a file in that directory using a entrypoint + // 1. Executable means to use CF LoadableDevice::load and CF ExecutableDevice::execute operations. This is a "main" process. + // - A Executable that references a directory instead of a file means to recursively load the contents of the directory + // and then execute the program specified via entrypoint + // 2. Driver and Kernel Module means load only. + // 3. SharedLibrary means dynamic linking. + // 4. A (SharedLibrary) Without a code entrypoint element means load only. + // 5. A (SharedLibrary) With a code entrypoint element means load and CF Device::execute. + switch (implementation->getCodeType()) { + case SPD::Code::EXECUTABLE: + // Returns true if the entry point is non-null + return bool(implementation->getEntryPoint()); + case SPD::Code::SHARED_LIBRARY: + return true; + default: + return false; + } +} + ComponentDeployment::ComponentDeployment(const SoftPkg* softpkg, const ComponentInstantiation* instantiation, const std::string& identifier) : diff --git a/redhawk/src/control/sdr/dommgr/Deployment.h b/redhawk/src/control/sdr/dommgr/Deployment.h index cd8fb52a5..cde8ea009 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.h +++ b/redhawk/src/control/sdr/dommgr/Deployment.h @@ -80,6 +80,7 @@ namespace ossie { std::string getLocalFile(); CF::LoadableDevice::LoadType getCodeType() const; + bool isExecutable() const; void addDependency(SoftpkgDeployment* dependency); const DeploymentList& getDependencies(); From ebb15f6cfb4b6eacb21e658ddaf1a03f2611839f Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 1 Jun 2016 16:59:43 -0400 Subject: [PATCH 0342/1644] Copy the string from the componentfileref, instead of linking via pointer --- redhawk/src/control/include/ossie/componentProfile.h | 3 ++- redhawk/src/control/parser/SoftwareAssembly.cpp | 2 +- redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp | 3 +-- .../src/control/sdr/dommgr/ApplicationFactory_impl.cpp | 8 ++++---- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/redhawk/src/control/include/ossie/componentProfile.h b/redhawk/src/control/include/ossie/componentProfile.h index 87df93a1d..af3e70698 100644 --- a/redhawk/src/control/include/ossie/componentProfile.h +++ b/redhawk/src/control/include/ossie/componentProfile.h @@ -219,7 +219,8 @@ namespace ossie { std::vector instantiations; - const ComponentFile* componentFile; + // Resolved after parsing is complete + std::string filename; public: const std::vector& getInstantiations() const; diff --git a/redhawk/src/control/parser/SoftwareAssembly.cpp b/redhawk/src/control/parser/SoftwareAssembly.cpp index 3b854f399..35c47e72c 100644 --- a/redhawk/src/control/parser/SoftwareAssembly.cpp +++ b/redhawk/src/control/parser/SoftwareAssembly.cpp @@ -76,7 +76,7 @@ void SoftwareAssembly::validateComponentPlacements(std::vectorfilename; BOOST_FOREACH(ComponentInstantiation& instance, placement.instantiations) { if (!_sad->assemblycontroller.empty() && _sad->assemblycontroller == instance.instantiationId) { diff --git a/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp b/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp index 66470bdca..2cd4b3eec 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp @@ -198,8 +198,7 @@ const SoftPkg* ApplicationDeployment::getSoftPkg(const std::string& filename) co void ApplicationDeployment::loadComponentProfile(CF::FileSystem_ptr fileSystem, const ComponentPlacement& placement) { - assert(placement.componentFile); - SoftPkg* softpkg = loadProfile(fileSystem, placement.componentFile->getFileName()); + SoftPkg* softpkg = loadProfile(fileSystem, placement.filename); if (softpkg->isScaCompliant()){ BOOST_FOREACH(const ComponentInstantiation& instantiation, placement.getInstantiations()) { if (!instantiation.isNamingService()) { diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index b758905f8..1cd650fd8 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -448,7 +448,7 @@ ApplicationFactory_impl::ApplicationFactory_impl (const std::string& softwarePro for (std::vector::const_iterator comp = components.begin(); comp != components.end(); ++comp) { SoftPkg comp_pkg; - const std::string& p_name = comp->componentFile->filename; + const std::string& p_name = comp->filename; try { LOG_DEBUG(ApplicationFactory_impl, "Validating... COMP profile: " << p_name); ValidateComponent(_fileMgr, comp_pkg, p_name); @@ -479,7 +479,7 @@ ApplicationFactory_impl::ApplicationFactory_impl (const std::string& softwarePro compInst != compInstantiations.end(); ++compInst){ if (assemblyControllerId == compInst->instantiationId) { ac_spd = comp_pkg; - ac_profile = comp->componentFile->filename; + ac_profile = comp->filename; ac_found = true; break; } @@ -594,7 +594,7 @@ void createHelper::assignPlacementsToDevices(ossie::ApplicationDeployment& appDe // Place the remaining components one-by-one BOOST_FOREACH(const ComponentPlacement& placement, _appFact._sadParser.getComponentPlacements()) { - const SoftPkg* softpkg = appDeployment.getSoftPkg(placement.componentFile->getFileName()); + const SoftPkg* softpkg = appDeployment.getSoftPkg(placement.filename); BOOST_FOREACH(const ComponentInstantiation& instantiation, placement.getInstantiations()) { // Even though the XML supports more than one instantiation per // component placement, the tooling doesn't support that, so this @@ -766,7 +766,7 @@ void createHelper::_placeHostCollocation(ossie::ApplicationDeployment& appDeploy DeviceIDList assignedDevices; DeploymentList deployments; BOOST_FOREACH(const ComponentPlacement& placement, collocation.getComponents()) { - const SoftPkg* softpkg = appDeployment.getSoftPkg(placement.componentFile->getFileName()); + const SoftPkg* softpkg = appDeployment.getSoftPkg(placement.filename); BOOST_FOREACH(const ComponentInstantiation& instantiation, placement.getInstantiations()) { // Even though the XML supports more than one instantiation per // component placement, the tooling doesn't support that, so this From de695444d17f0e2cfb0d98c80905cf5a80eb167b Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 2 Jun 2016 12:34:07 -0400 Subject: [PATCH 0343/1644] Relay more detailed exception messages from File_stream --- redhawk/src/base/framework/FileStream.cpp | 32 +++++++++++++++++++-- redhawk/src/base/include/ossie/FileStream.h | 20 ++----------- 2 files changed, 32 insertions(+), 20 deletions(-) diff --git a/redhawk/src/base/framework/FileStream.cpp b/redhawk/src/base/framework/FileStream.cpp index 8027ae415..399d5a45a 100644 --- a/redhawk/src/base/framework/FileStream.cpp +++ b/redhawk/src/base/framework/FileStream.cpp @@ -84,9 +84,37 @@ void File_buffer::close() throw(std::ios_base::failure) } } catch (CORBA::SystemException& se) { - throw std::ios_base::failure("CORBA SystemException while opening file"); + throw std::ios_base::failure("CORBA SystemException while closing file"); } catch (...) { - throw std::ios_base::failure("Unexpected error while opening file"); + throw std::ios_base::failure("Unexpected error while closing file"); + } +} + +File_stream::File_stream(CF::FileSystem_ptr fsysptr, const char* path) throw(std::ios_base::failure) : + std::ios(0), + needsClose(true) +{ + try { + sb = new File_buffer((CF::File_var)fsysptr->open(path, true)); + this->init(sb); + } catch (const CF::InvalidFileName& ifn) { + throw std::ios_base::failure(std::string(ifn.msg)); + } catch (const CF::FileException& fe) { + throw std::ios_base::failure(std::string(fe.msg)); + } catch( ... ) { + throw std::ios_base::failure("exception while opening file"); + } +} + +File_stream::File_stream(CF::File_ptr fptr) : + std::ios(0), + needsClose(false) +{ + try { + sb = new File_buffer(fptr); + this->init(sb); + } catch( ... ) { + throw std::ios_base::failure("exception while opening file"); } } diff --git a/redhawk/src/base/include/ossie/FileStream.h b/redhawk/src/base/include/ossie/FileStream.h index 165e6ea9d..ca887515a 100644 --- a/redhawk/src/base/include/ossie/FileStream.h +++ b/redhawk/src/base/include/ossie/FileStream.h @@ -56,30 +56,14 @@ class File_stream : public std::istream * Opening a stream using this constructor will ensure that the SCA file get's closed automatically * when the file stream is destroyed. */ - explicit File_stream(CF::FileSystem_ptr fsysptr, const char* path) throw(std::ios_base::failure) : std::ios(0), needsClose(true) - { - try { - sb = new File_buffer((CF::File_var)fsysptr->open(path, true)); - this->init(sb); - } catch( ... ) { - throw std::ios_base::failure("exception while opening file"); - } - } + File_stream(CF::FileSystem_ptr fsysptr, const char* path) throw(std::ios_base::failure); /* * Open a stream given a SCA File. * * Note: the caller is responsible for closing the provided file. */ - explicit File_stream(CF::File_ptr fptr) : std::ios(0), needsClose(false) - { - try { - sb = new File_buffer(fptr); - this->init(sb); - } catch( ... ) { - throw std::ios_base::failure("exception while opening file"); - } - } + explicit File_stream(CF::File_ptr fptr); virtual ~File_stream(); From 3107a88b2869f67229ee620f5699704905b4a187 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 3 Jun 2016 09:56:42 -0400 Subject: [PATCH 0344/1644] Add a method to find a specified implementation from a SoftPkg --- redhawk/src/control/include/ossie/SoftPkg.h | 2 ++ redhawk/src/control/parser/SoftPkg.cpp | 13 +++++++++++++ 2 files changed, 15 insertions(+) diff --git a/redhawk/src/control/include/ossie/SoftPkg.h b/redhawk/src/control/include/ossie/SoftPkg.h index 85fd7ca39..fdc6be9f8 100644 --- a/redhawk/src/control/include/ossie/SoftPkg.h +++ b/redhawk/src/control/include/ossie/SoftPkg.h @@ -273,6 +273,8 @@ namespace ossie { return _spd->implementations; } + const ossie::SPD::Implementation* getImplementation(const std::string& id) const; + const std::vector& getUsesDevices() const { assert(_spd.get() != 0); return _spd->usesDevice; diff --git a/redhawk/src/control/parser/SoftPkg.cpp b/redhawk/src/control/parser/SoftPkg.cpp index 30a722a8b..d1946ef30 100644 --- a/redhawk/src/control/parser/SoftPkg.cpp +++ b/redhawk/src/control/parser/SoftPkg.cpp @@ -20,6 +20,7 @@ #include +#include #include #include @@ -77,6 +78,18 @@ void SoftPkg::loadDescriptor(std::istream& input) _descriptor->load(input); } +const SPD::Implementation* SoftPkg::getImplementation(const std::string& id) const +{ + assert(_spd.get() != 0); + BOOST_FOREACH(const SPD::Implementation& implementation, _spd->implementations) { + if (id == implementation.getID()) { + return &implementation; + } + } + + return 0; +} + const std::string SPD::SoftPkgRef::asString() const { std::ostringstream out; out << "SoftPkgRef localfile: " << this->localfile << " implref: " << this->implref; From 7e55079d1b46e2f321d9037c9a9f4bcc43274c83 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 3 Jun 2016 10:01:22 -0400 Subject: [PATCH 0345/1644] Add a ProfileCache class to handle loading of SoftPkg objects from the FileSystem --- redhawk/src/control/sdr/dommgr/Makefile.am | 1 + .../src/control/sdr/dommgr/ProfileCache.cpp | 95 ++++++++++++++ redhawk/src/control/sdr/dommgr/ProfileCache.h | 120 ++++++++++++++++++ 3 files changed, 216 insertions(+) create mode 100644 redhawk/src/control/sdr/dommgr/ProfileCache.cpp create mode 100644 redhawk/src/control/sdr/dommgr/ProfileCache.h diff --git a/redhawk/src/control/sdr/dommgr/Makefile.am b/redhawk/src/control/sdr/dommgr/Makefile.am index b6ea82725..40c4737f3 100644 --- a/redhawk/src/control/sdr/dommgr/Makefile.am +++ b/redhawk/src/control/sdr/dommgr/Makefile.am @@ -35,6 +35,7 @@ DomainManager_SOURCES = connectionSupport.cpp \ FakeApplication.cpp \ Deployment.cpp \ ApplicationDeployment.cpp \ + ProfileCache.cpp \ main.cpp DomainManager_CPPFLAGS = -I../../include -I../../parser -I$(top_srcdir)/base/include -I$(top_srcdir)/base $(BOOST_CPPFLAGS) $(OMNIORB_CFLAGS) $(LOG4CXX_FLAGS) DomainManager_CXXFLAGS = -Wall diff --git a/redhawk/src/control/sdr/dommgr/ProfileCache.cpp b/redhawk/src/control/sdr/dommgr/ProfileCache.cpp new file mode 100644 index 000000000..7c68c6f55 --- /dev/null +++ b/redhawk/src/control/sdr/dommgr/ProfileCache.cpp @@ -0,0 +1,95 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK core. + * + * REDHAWK core is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +#include + +#include +#include + +#include "ProfileCache.h" + +using namespace redhawk; +using namespace ossie; + +PREPARE_LOGGING(ProfileCache); + +ProfileCache::ProfileCache(CF::FileSystem_ptr fileSystem) : + fileSystem(CF::FileSystem::_duplicate(fileSystem)) +{ +} + +const SoftPkg* ProfileCache::loadProfile(const std::string& spdFilename) +{ + // Use basic load to find or load the SPD, then cast the const away so that + // the PRF and SCD can be loaded if needed + SoftPkg* softpkg = const_cast(loadSoftPkg(spdFilename)); + + // If the SPD has a PRF reference, and it hasn't already been loaded, try + // to load it + if (softpkg->getPRFFile() && !softpkg->getProperties()) { + const std::string prf_file = softpkg->getPRFFile(); + LOG_TRACE(ProfileCache, "Loading PRF file " << prf_file); + try { + File_stream prf_stream(fileSystem, prf_file.c_str()); + softpkg->loadProperties(prf_stream); + } catch (const std::exception& exc) { + std::string message = spdFilename + " has invalid PRF file " + prf_file + ": " + exc.what(); + throw invalid_profile(spdFilename, message); + } + } + + // If the SPD has an SCD reference, and it hasn't already been loaded, try + // to load it + if (softpkg->getSCDFile() && !softpkg->getDescriptor()) { + const std::string scd_file = softpkg->getSCDFile(); + LOG_TRACE(ProfileCache, "Loading SCD file " << scd_file); + try { + File_stream scd_stream(fileSystem, scd_file.c_str()); + softpkg->loadDescriptor(scd_stream); + } catch (const std::exception& exc) { + std::string message = spdFilename + " has invalid SCD file " + scd_file + ": " + exc.what(); + throw invalid_profile(spdFilename, message); + } + } + + return softpkg; +} + +const SoftPkg* ProfileCache::loadSoftPkg(const std::string& filename) +{ + // Check the cache first + BOOST_FOREACH(SoftPkg& softpkg, profiles) { + if (softpkg.getSPDFile() == filename) { + LOG_TRACE(ProfileCache, "Found existing SPD " << filename); + return &softpkg; + } + } + + LOG_TRACE(ProfileCache, "Loading SPD file " << filename); + try { + File_stream spd_stream(fileSystem, filename.c_str()); + SoftPkg* softpkg = new SoftPkg(spd_stream, filename); + profiles.push_back(softpkg); + return softpkg; + } catch (const std::exception& exc) { + std::string message = filename + " is invalid: " + exc.what(); + throw invalid_profile(filename, message); + } +} diff --git a/redhawk/src/control/sdr/dommgr/ProfileCache.h b/redhawk/src/control/sdr/dommgr/ProfileCache.h new file mode 100644 index 000000000..cd60fe9a4 --- /dev/null +++ b/redhawk/src/control/sdr/dommgr/ProfileCache.h @@ -0,0 +1,120 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK core. + * + * REDHAWK core is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +#ifndef PROFILECACHE_H +#define PROFILECACHE_H + +#include +#include + +#include + +#include +#include +#include + +namespace redhawk { + + /** + * @brief An exception raised when a SoftPkg profile is invalid + */ + class invalid_profile : public std::runtime_error + { + public: + invalid_profile(const std::string& filename, const std::string& message) : + std::runtime_error(message), + filename(filename) + { + } + + virtual ~invalid_profile() throw() + { + // Only defined because the compiler-generated destructor has a + // looser throw specification than runtime_error's destructor + } + + /** + * @brief Returns the filename of the invalid SoftPkg profile + */ + const std::string& get_filename() const + { + return filename; + } + + private: + const std::string filename; + }; + + /** + * @brief Caching softpkg profile loader + */ + class ProfileCache + { + ENABLE_LOGGING; + + public: + /** + * @brief Creates a new cache + * @param fileSystem the CF::FileSystem used to load files + * + * Creates a new empty cache. When this cache is destroyed, all loaded + * profiles are deleted. + */ + ProfileCache(CF::FileSystem_ptr fileSystem); + + /** + * @brief Loads an SPD file and its PRF and SCD, if available + * @param spdFilename the path to the SPD file + * @return a pointer to the loaded SoftPkg + * @exception redhawk::invalid_profile a file is invalid or cannot be + * parsed + * + * Reads and parses the SPD file @a spdFilename and its referenced PRF + * and SCD files (if any), caching the result. Subsequent calls with + * the same filename will return the cached object. + * + * The returned SoftPkg is owned by this object, not the caller. + */ + const ossie::SoftPkg* loadProfile(const std::string& spdFilename); + + /** + * @brief Loads an SPD file + * @param spdFilename the path to the SPD file + * @return a pointer to the loaded SoftPkg + * @exception redhawk::invalid_profile file is invalid or cannot be + * parsed + * + * Reads and parses the SPD file @a spdFilename and its referenced PRF + * and SCD files (if any), caching the result. Subsequent calls with + * the same filename will return the cached object. + + * The returned SoftPkg is owned by this object, not the caller. + */ + const ossie::SoftPkg* loadSoftPkg(const std::string& filename); + + protected: + ossie::SoftPkg* findSoftPkg(const std::string& filename); + + CF::FileSystem_var fileSystem; + boost::ptr_vector profiles; + }; +} + +#endif // PROFILECACHE_H From a972da8251f5a2e581e0a5c7c5f14a58ac65ec73 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 3 Jun 2016 10:20:46 -0400 Subject: [PATCH 0346/1644] Break application validation out into its own class --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 363 +----------------- .../sdr/dommgr/ApplicationFactory_impl.h | 8 - .../sdr/dommgr/ApplicationValidator.cpp | 253 ++++++++++++ .../control/sdr/dommgr/ApplicationValidator.h | 90 +++++ redhawk/src/control/sdr/dommgr/Makefile.am | 1 + 5 files changed, 365 insertions(+), 350 deletions(-) create mode 100644 redhawk/src/control/sdr/dommgr/ApplicationValidator.cpp create mode 100644 redhawk/src/control/sdr/dommgr/ApplicationValidator.h diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 1cd650fd8..a5ceef0f4 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -43,6 +43,7 @@ #include "DomainManager_impl.h" #include "AllocationManager_impl.h" #include "RH_NamingContext.h" +#include "ApplicationValidator.h" namespace fs = boost::filesystem; using namespace ossie; @@ -128,226 +129,6 @@ namespace { PREPARE_LOGGING(ApplicationFactory_impl); -void -ApplicationFactory_impl::ValidateFileLocation( CF::FileManager_ptr fileMgr, const std::string &profile_file) -{ - TRACE_ENTER(ApplicationFactory_impl) - - if (profile_file == "") { - TRACE_EXIT(ApplicationFactory_impl) - return; - } - - // Verify file within the provided FileMgr - LOG_TRACE(ApplicationFactory_impl, "Validating that profile " << profile_file << " exists"); - if (!fileMgr->exists (profile_file.c_str())) { - string msg = "File "; - msg += profile_file; - msg += " does not exist."; - throw CF::FileException (CF::CF_ENOENT, msg.c_str()); - } -} - - -void ApplicationFactory_impl::ValidateSoftPkgDep (CF::FileManager_ptr fileMgr, DomainManager_impl *domMgr, const std::string& sfw_profile ) { - SoftPkg pkg; - ValidateSPD(fileMgr, pkg, sfw_profile); -} - -void ApplicationFactory_impl::ValidateComponent(CF::FileManager_ptr fileMgr, - SoftPkg &spdParser, - const std::string& sfw_profile) -{ - ValidateSPD(fileMgr, spdParser, sfw_profile); - - // query SPD for PRF - if (spdParser.getPRFFile() != 0) { - LOG_TRACE(ApplicationFactory_impl, "validating " << spdParser.getPRFFile()); - try { - ValidateFileLocation(fileMgr, spdParser.getPRFFile()); - - // check the file name ends with the extension given in the spec - if (spdParser.getPRFFile() && (strstr (spdParser.getPRFFile (), ".prf.xml")) == NULL) { - LOG_ERROR(ApplicationFactory_impl, "File " << spdParser.getPRFFile() << " should end in .prf.xml."); - } - - LOG_TRACE(ApplicationFactory_impl, "Creating file stream"); - File_stream prfStream(fileMgr, spdParser.getPRFFile()); - LOG_TRACE(ApplicationFactory_impl, "Loading parser"); - Properties prfParser(prfStream); - LOG_TRACE(ApplicationFactory_impl, "Closing stream"); - prfStream.close(); - } catch (ossie::parser_error& ex ) { - std::string parser_error_line = ossie::retrieveParserErrorLineNumber(ex.what()); - LOG_ERROR(ApplicationFactory_impl, "Error validating PRF " << spdParser.getPRFFile() << ". " << parser_error_line << "The XML parser returned the following error: " << ex.what()); - throw CF::DomainManager::ApplicationInstallationError (CF::CF_EBADF, ex.what()); - } catch (CF::InvalidFileName ex) { - LOG_ERROR(ApplicationFactory_impl, "Failed to validate PRF due to invalid file name " << ex.msg); - throw CF::DomainManager::ApplicationInstallationError (CF::CF_EBADF, ex.msg); - } catch (CF::FileException ex) { - LOG_ERROR(ApplicationFactory_impl, "Failed to validate PRF due to file exception" << ex.msg); - throw CF::DomainManager::ApplicationInstallationError (CF::CF_EBADF, ex.msg); - } catch ( ... ) { - LOG_ERROR(ApplicationFactory_impl, "Unexpected error validating PRF " << spdParser.getPRFFile()); - throw CF::DomainManager::ApplicationInstallationError (CF::CF_EBADF, ""); - } - } else { - LOG_TRACE(ApplicationFactory_impl, "No PRF file to validate"); - } - - if (spdParser.getSCDFile() != 0) { - try { - // query SPD for SCD - LOG_TRACE(ApplicationFactory_impl, "validating " << spdParser.getSCDFile()); - ValidateFileLocation ( fileMgr, spdParser.getSCDFile ()); - - // Check the filename ends with the extension given in the spec - if ((strstr (spdParser.getSCDFile (), ".scd.xml")) == NULL) - { LOG_ERROR(ApplicationFactory_impl, "File " << spdParser.getSCDFile() << " should end with .scd.xml."); } - - File_stream _scd(fileMgr, spdParser.getSCDFile()); - ComponentDescriptor scdParser (_scd); - _scd.close(); - } catch (ossie::parser_error& ex) { - std::string parser_error_line = ossie::retrieveParserErrorLineNumber(ex.what()); - LOG_ERROR(ApplicationFactory_impl, "SCD file failed validation; parser error on file " << spdParser.getSCDFile() << ". " << parser_error_line << "The XML parser returned the following error: " << ex.what()); - throw CF::DomainManager::ApplicationInstallationError (CF::CF_EBADF, ex.what()); - } catch (CF::InvalidFileName ex) { - LOG_ERROR(ApplicationFactory_impl, "Failed to validate SCD due to invalid file name " << ex.msg); - throw CF::DomainManager::ApplicationInstallationError (CF::CF_EBADF, ex.msg); - } catch (CF::FileException ex) { - LOG_ERROR(ApplicationFactory_impl, "Failed to validate SCD due to file exception" << ex.msg); - throw CF::DomainManager::ApplicationInstallationError (CF::CF_EBADF, ex.msg); - } catch ( ... ) { - LOG_ERROR(ApplicationFactory_impl, "Unexpected error validating PRF " << spdParser.getSCDFile()); - throw CF::DomainManager::ApplicationInstallationError (CF::CF_EBADF, ""); - } - } else if (spdParser.isScaCompliant()) { - LOG_ERROR(ApplicationFactory_impl, "SCA compliant component is missing SCD file reference"); - throw CF::DomainManager::ApplicationInstallationError(CF::CF_EBADF, "SCA compliant components require SCD file"); - } else { - LOG_TRACE(ApplicationFactory_impl, "No SCD file to validate") - } -} - -void ApplicationFactory_impl::ValidateSPD(CF::FileManager_ptr fileMgr, - DomainManager_impl *domMgr, - SoftPkg &spdParser, - const std::string& sfw_profile) { - TRACE_ENTER(ApplicationFactory_impl) - - if ( sfw_profile == "" ) { - LOG_WARN( ApplicationFactory_impl, "No Software Profile Provided."); - throw CF::DomainManager::ApplicationInstallationError (CF::CF_EBADF, "No software profile provided"); - TRACE_EXIT(ApplicationFactory_impl); - } - - try { - LOG_TRACE(ApplicationFactory_impl, "Validating SPD " << sfw_profile); - ValidateFileLocation(fileMgr, sfw_profile); - - // check the filename ends with the extension given in the spec - if ((strstr (sfw_profile.c_str(), ".spd.xml")) == NULL) - { LOG_ERROR(ApplicationFactory_impl, "File " << sfw_profile << " should end with .spd.xml"); } - LOG_TRACE(ApplicationFactory_impl, "validating " << sfw_profile); - - try { - File_stream _spd(fileMgr, sfw_profile.c_str()); - spdParser.load( _spd, sfw_profile.c_str() ); - _spd.close(); - } catch (ossie::parser_error& ex) { - File_stream _spd(fileMgr, sfw_profile.c_str()); - std::string line; - std::string component_version; - while (std::getline(_spd, line)) { - size_t type_idx = line.find("type"); - if (type_idx != std::string::npos) { - size_t first_quote = line.find('"', type_idx); - if (first_quote == std::string::npos) - continue; - size_t second_quote = line.find('"', first_quote + 1); - if (second_quote == std::string::npos) - continue; - component_version = line.substr(first_quote + 1, second_quote-(first_quote+1)); - break; - } - } - ostringstream eout; - eout << xmlParsingVersionMismatch(domMgr, component_version); - std::string parser_error_line = ossie::retrieveParserErrorLineNumber(ex.what()); - eout << "Failed to parse SPD: " << sfw_profile << ". " << parser_error_line << " The XML parser returned the following error: " << ex.what(); - LOG_ERROR(ApplicationFactory_impl, eout.str() ); - throw CF::DomainManager::ApplicationInstallationError (CF::CF_EBADF, eout.str().c_str()); - } catch (CF::InvalidFileName ex) { - LOG_ERROR(ApplicationFactory_impl, "Failed to validate SPD: " << sfw_profile << ". Invalid file name exception: " << ex.msg); - throw CF::DomainManager::ApplicationInstallationError (CF::CF_EBADF, ex.msg); - } catch (CF::FileException ex) { - LOG_ERROR(ApplicationFactory_impl, "Failed to validate SPD: " << sfw_profile << ". File exception: " << ex.msg); - throw CF::DomainManager::ApplicationInstallationError (CF::CF_EBADF, ex.msg); - } catch ( ... ) { - LOG_ERROR(ApplicationFactory_impl, "Unexpected error validating SPD: " << sfw_profile ); - throw CF::DomainManager::ApplicationInstallationError (CF::CF_EBADF, ""); - } - - // - // validate each implementation - // - const ossie::SPD::Implementations& impls = spdParser.getImplementations(); - ossie::SPD::Implementations::const_iterator impl = impls.begin(); - for( ; impl != impls.end(); impl++ ) { - - - // validate code file exists - try { - boost::filesystem::path implPath = boost::filesystem::path( spdParser.getSPDPath()) / impl->getCodeFile(); - LOG_TRACE(ApplicationFactory_impl, "Validating Implmentation existance: " << implPath.string() ); - ValidateFileLocation( fileMgr, implPath.string().c_str() ); - } catch (CF::InvalidFileName ex) { - LOG_ERROR(ApplicationFactory_impl, "Invalid Code File, PROFILE:" << sfw_profile << " CODE:" << impl->getCodeFile()); - throw CF::DomainManager::ApplicationInstallationError (CF::CF_EBADF, ex.msg); - } catch (CF::FileException ex) { - LOG_ERROR(ApplicationFactory_impl, "Invalid Code File, PROFILE:" << sfw_profile << " CODE:" << impl->getCodeFile()); - throw CF::DomainManager::ApplicationInstallationError (CF::CF_EBADF, ex.msg); - } catch ( ... ) { - LOG_ERROR(ApplicationFactory_impl, "Unexpected error validating PRF " << spdParser.getPRFFile()); - throw CF::DomainManager::ApplicationInstallationError (CF::CF_EBADF, ""); - } - - // validate all the soft package dependencies.... - const ossie::SPD::SoftPkgDependencies& deps = impl->getSoftPkgDependencies(); - ossie::SPD::SoftPkgDependencies::const_iterator dep = deps.begin(); - for(; dep != deps.end(); dep++ ) { - try { - LOG_TRACE(ApplicationFactory_impl, "Validating Dependency: " << dep->localfile); - ValidateSoftPkgDep(fileMgr, domMgr, dep->localfile); - } catch (CF::InvalidFileName ex) { - LOG_ERROR(ApplicationFactory_impl, "Invalid Code File, PROFILE:" << sfw_profile << " CODE:" << impl->getCodeFile()); - throw CF::DomainManager::ApplicationInstallationError (CF::CF_EBADF, ex.msg); - } catch (CF::FileException ex) { - LOG_ERROR(ApplicationFactory_impl, "Invalid Code File, PROFILE:" << sfw_profile << " CODE:" << impl->getCodeFile()); - throw CF::DomainManager::ApplicationInstallationError (CF::CF_EBADF, ex.msg); - } - - } - - } - } catch (CF::InvalidFileName& ex) { - LOG_ERROR(ApplicationFactory_impl, "Failed to validate SPD: " << sfw_profile << ", exception: " << ex.msg); - throw CF::DomainManager::ApplicationInstallationError (CF::CF_EBADF, ex.msg); - } catch (CF::FileException& ex) { - LOG_ERROR(ApplicationFactory_impl, "Failed to validate SPD: " << sfw_profile << ", exception: " << ex.msg); - throw CF::DomainManager::ApplicationInstallationError (CF::CF_EBADF, ex.msg); - } catch (CF::DomainManager::ApplicationInstallationError& ex) { - throw; - } catch ( ... ) { - LOG_ERROR(ApplicationFactory_impl, "Unexpected error validating SPD: " << sfw_profile); - throw CF::DomainManager::ApplicationInstallationError (); - } - - -} - - ApplicationFactory_impl::ApplicationFactory_impl (const std::string& softwareProfile, const std::string& domainName, DomainManager_impl* domainManager) : @@ -380,14 +161,18 @@ ApplicationFactory_impl::ApplicationFactory_impl (const std::string& softwarePro throw CF::DomainManager::ApplicationInstallationError(CF::CF_EBADF, "Could not get File Manager from Domain Manager"); } + LOG_INFO(ApplicationFactory_impl, "Installing application " << _softwareProfile); try { + if (!_fileMgr->exists(_softwareProfile.c_str())) { + std::string msg = "File "; + msg += _softwareProfile; + msg += " does not exist."; + throw CF::FileException (CF::CF_ENOENT, msg.c_str()); + } - LOG_INFO(ApplicationFactory_impl, "Installing application " << _softwareProfile.c_str()); - ValidateFileLocation ( _fileMgr, _softwareProfile ); - - File_stream _sad(_fileMgr, _softwareProfile.c_str()); - _sadParser.load(_sad); - _sad.close(); + File_stream _sad(_fileMgr, _softwareProfile.c_str()); + _sadParser.load(_sad); + _sad.close(); } catch (const ossie::parser_error& ex) { ostringstream eout; std::string parser_error_line = ossie::retrieveParserErrorLineNumber(ex.what()); @@ -421,122 +206,16 @@ ApplicationFactory_impl::ApplicationFactory_impl (const std::string& softwarePro throw CF::DomainManager::ApplicationInstallationError(CF::CF_ENOENT, eout.str().c_str()); } - // Makes sure all external port names are unique - const std::vector& ports = _sadParser.getExternalPorts(); - std::vector extPorts; - for (std::vector::const_iterator port = ports.begin(); port != ports.end(); ++port) { - // Gets name to use - const std::string& extName = port->getExternalName(); - // Check for duplicate - if (std::find(extPorts.begin(), extPorts.end(), extName) == extPorts.end()) { - extPorts.push_back(extName); - } else { - ostringstream eout; - eout << "Duplicate External Port name: " << extName; - LOG_ERROR(ApplicationFactory_impl, eout.str()); - throw CF::DomainManager::ApplicationInstallationError(CF::CF_NOTSET, eout.str().c_str()); - } - } - - // Gets the assembly controller software profile by looping through each - // component instantiation to find a matching ID to the AC's - std::string assemblyControllerId = _sadParser.getAssemblyControllerRefId(); - SoftPkg ac_spd; - std::string ac_profile; - bool ac_found = false; - std::vector components = _sadParser.getAllComponents(); - for (std::vector::const_iterator comp = components.begin(); - comp != components.end(); ++comp) { - SoftPkg comp_pkg; - const std::string& p_name = comp->filename; - try { - LOG_DEBUG(ApplicationFactory_impl, "Validating... COMP profile: " << p_name); - ValidateComponent(_fileMgr, comp_pkg, p_name); - } catch (CF::FileException& ex) { - LOG_ERROR(ApplicationFactory_impl, "installApplication: While validating the SAD profile: " << ex.msg); - throw CF::DomainManager::ApplicationInstallationError (CF::CF_EBADF, ex.msg); - } catch( CF::InvalidFileName& ex ) { - std::ostringstream eout; - eout << "Invalid file name: " << p_name; - LOG_ERROR(ApplicationFactory_impl, "installApplication: Invalid file name: " << p_name); - throw CF::DomainManager::ApplicationInstallationError (CF::CF_EBADF, eout.str().c_str()); - } catch (CF::DomainManager::ApplicationInstallationError& e) { - LOG_TRACE(ApplicationFactory_impl, "rethrowing ApplicationInstallationError" << e.msg); - throw; - } catch ( std::exception& ex ) { - std::ostringstream eout; - eout << "The following standard exception occurred: "< compInstantiations = comp->instantiations; - for (std::vector::const_iterator compInst = compInstantiations.begin(); - compInst != compInstantiations.end(); ++compInst){ - if (assemblyControllerId == compInst->instantiationId) { - ac_spd = comp_pkg; - ac_profile = comp->filename; - ac_found = true; - break; - } - } - } - } - - // Gets the assembly controllers properties - Properties prf; - if (ac_found) { - if ( ac_spd.getPRFFile() ) { - std::string prf_file(ac_spd.getPRFFile()); - try { - File_stream _prf(_fileMgr, prf_file.c_str()); - prf.load(_prf); - _prf.close(); - } catch(ossie::parser_error& ex ) { - std::ostringstream os; - std::string parser_error_line = ossie::retrieveParserErrorLineNumber(ex.what()); - os << "Invalid PRF file: " << prf_file << ". " << parser_error_line << " The XML parser returned the following error: " << ex.what(); - LOG_ERROR(ApplicationFactory_impl, os.str() ); - throw CF::DomainManager::ApplicationInstallationError(CF::CF_NOTSET, os.str().c_str()); - } catch( ... ) { - // Errors are reported at create time - } - } - } - - // Makes sure all external property names are unique - const std::vector& properties = _sadParser.getExternalProperties(); - std::vector extProps; - for (std::vector::const_iterator prop = properties.begin(); prop != properties.end(); ++prop) { - // Gets name to use - const std::string& extName = prop->getExternalID(); - // Check for duplicate - if (std::find(extProps.begin(), extProps.end(), extName) == extProps.end()) { - extProps.push_back(extName); - } else { - ostringstream eout; - eout << "Duplicate External Property name: " << extName; - LOG_ERROR(ApplicationFactory_impl, eout.str()); - throw CF::DomainManager::ApplicationInstallationError(CF::CF_NOTSET, eout.str().c_str()); - } - } - - // Make sure AC prop ID's aren't in conflict with external ones - const std::vector& acProps = prf.getProperties(); - for (unsigned int i = 0; i < acProps.size(); ++i) { - // Check for duplicate - if (std::find(extProps.begin(), extProps.end(), acProps[i]->getID()) == extProps.end()) { - extProps.push_back(acProps[i]->getID()); - } else { - ostringstream eout; - eout << "Assembly controller property in use as External Property: " << acProps[i]->getID(); - LOG_ERROR(ApplicationFactory_impl, eout.str()); - throw CF::DomainManager::ApplicationInstallationError(CF::CF_NOTSET, eout.str().c_str()); - } + // Validate the application using the current domain state; however, we + // cannot assume that the component SPDs will not change between now and a + // subsequent create call, so the parsed profiles are not saved + redhawk::ApplicationValidator validator(_fileMgr); + try { + validator.validate(_sadParser); + } catch (const std::runtime_error& exc) { + LOG_ERROR(ApplicationFactory_impl, "SAD " << softwareProfile + << " failed validation: " << exc.what()); + throw CF::DomainManager::ApplicationInstallationError(CF::CF_EBADF, exc.what()); } _name = _sadParser.getName(); diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h index 33e3f60a8..36c036e40 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h @@ -57,14 +57,6 @@ class ApplicationFactory_impl: public virtual POA_CF::ApplicationFactory std::string getWaveformContextName(std::string name); std::string getBaseWaveformContext(std::string waveform_context); - static void ValidateFileLocation ( CF::FileManager_ptr fileMgr, const std::string &profile ); - static void ValidateSoftPkgDep( CF::FileManager_ptr fileMgr, const std::string &profile ); - static void ValidateSPD (CF::FileManager_ptr fileMgr, ossie::SoftPkg& spd, const std::string& profile); - static void ValidateComponent (CF::FileManager_ptr fileMgr, ossie::SoftPkg& spd, const std::string& profile); - -protected: - static std::string xmlParsingVersionMismatch(DomainManager_impl *domMgr, std::string &component_version); - public: ApplicationFactory_impl (const std::string& softwareProfile, const std::string& domainName, diff --git a/redhawk/src/control/sdr/dommgr/ApplicationValidator.cpp b/redhawk/src/control/sdr/dommgr/ApplicationValidator.cpp new file mode 100644 index 000000000..13b880ae8 --- /dev/null +++ b/redhawk/src/control/sdr/dommgr/ApplicationValidator.cpp @@ -0,0 +1,253 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK core. + * + * REDHAWK core is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +#include + +#include +#include + +#include + +#include "ApplicationValidator.h" + +using namespace redhawk; +using namespace ossie; +namespace fs = boost::filesystem; + +class bad_implementation : public redhawk::validation_error +{ +public: + bad_implementation(const SoftPkg* softpkg, const SPD::Implementation& impl, const std::string& message) : + redhawk::validation_error("Soft package " + softpkg->getSPDFile() + " has invalid implementation " + impl.getID() + ": " + message) + { + } +}; + +PREPARE_LOGGING(ApplicationValidator); + +ApplicationValidator::ApplicationValidator(CF::FileSystem_ptr fileSystem) : + fileSystem(CF::FileSystem::_duplicate(fileSystem)), + cache(fileSystem) +{ +} + +void ApplicationValidator::validate(const SoftwareAssembly& sad) +{ + // Check partitioning + BOOST_FOREACH(const SoftwareAssembly::HostCollocation& collocation, sad.getHostCollocations()) { + validateHostCollocation(collocation); + } + BOOST_FOREACH(const ComponentPlacement& placement, sad.getComponentPlacements()) { + validateComponentPlacement(placement); + } + + // Check externally-promoted ports and properties + validateExternalPorts(sad.getExternalPorts()); + + const Properties* ac_props = getAssemblyControllerProperties(sad); + validateExternalProperties(ac_props, sad.getExternalProperties()); +} + +void ApplicationValidator::validateExternalPorts(const std::vector& ports) +{ + // Make sure all external port names are unique + // NB: Should check component references are valid as well + std::set port_names; + BOOST_FOREACH(const SoftwareAssembly::Port& port, ports) { + const std::string& name = port.getExternalName(); + if (port_names.count(name) == 0) { + port_names.insert(name); + } else { + throw validation_error("Duplicate external port name " + name); + } + } +} + +void ApplicationValidator::validateExternalProperties(const Properties* acProperties, + const std::vector& properties) +{ + // Makes sure all external property names are unique + // NB: Should check component references are valid as well + std::set property_names; + BOOST_FOREACH(const SoftwareAssembly::Property& property, properties) { + const std::string& name = property.getExternalID(); + if (property_names.count(name) == 0) { + property_names.insert(name); + } else { + throw validation_error("Duplicate external property name " + name); + } + } + + // Make sure AC property IDs aren't in conflict with external ones + if (acProperties) { + BOOST_FOREACH(const Property* property, acProperties->getProperties()) { + const std::string& name = property->getID(); + if (property_names.count(name) == 0) { + property_names.insert(name); + } else { + throw validation_error("Assembly controller property " + name + " in use as external property"); + } + } + } +} + +void ApplicationValidator::validateSoftPkgRef(const SPD::SoftPkgRef& softpkgref) +{ + const std::string& spd_file = softpkgref.localfile; + if (spd_file.empty()) { + throw std::runtime_error("empty softpkgref"); + } + + // Basic checking for valid, existing filename + LOG_TRACE(ApplicationValidator, "Validating SPD " << spd_file); + checkFilename(spd_file); + if (!fileExists(spd_file)) { + throw std::runtime_error("softpkgref " + spd_file + " does not exist"); + } + + // If this fails, it will throw redhawk::invalid_profile + const SoftPkg* softpkg = cache.loadSoftPkg(spd_file); + + // Check implementation(s) + if (softpkgref.implref.isSet()) { + // A specific implementation is given; make sure it exists and is valid + const std::string& impl_id = *(softpkgref.implref); + const SPD::Implementation* implementation = softpkg->getImplementation(impl_id); + if (!implementation) { + throw std::runtime_error("softpkgref " + spd_file + " has no implementation " + impl_id); + } + + validateImplementation(softpkg, *implementation, false); + } else { + // Validate all implementations + BOOST_FOREACH(const SPD::Implementation& implementation, softpkg->getImplementations()) { + validateImplementation(softpkg, implementation, false); + } + } +} + +void ApplicationValidator::validateImplementation(const SoftPkg* softpkg, + const SPD::Implementation& implementation, + bool executable) +{ + LOG_TRACE(ApplicationValidator, "Validating SPD implementation " << implementation.getID()); + + // Always ensure that the localfile exists + fs::path code = fs::path(softpkg->getSPDPath()) / implementation.getCodeFile(); + LOG_TRACE(ApplicationValidator, "Validating code localfile " << code.string()); + if (!fileExists(code.string())) { + throw bad_implementation(softpkg, implementation, "missing localfile " + code.string()); + } + + // If the implementation needs to be executable (i.e., would be used for a + // component instantiation), make sure it has a valid entry point + if (executable) { + if (!implementation.getEntryPoint()) { + throw bad_implementation(softpkg, implementation, "has no entry point"); + } + fs::path entry_point = fs::path(softpkg->getSPDPath()) / implementation.getEntryPoint(); + LOG_TRACE(ApplicationValidator, "Validating code entry point " << entry_point.string()); + if (!fileExists(entry_point.string())) { + throw bad_implementation(softpkg, implementation, "missing entrypoint " + entry_point.string()); + } + } + + // Check all softpkg references + BOOST_FOREACH(const SPD::SoftPkgRef& spdref, implementation.getSoftPkgDependencies()) { + try { + validateSoftPkgRef(spdref); + } catch (const std::runtime_error& exc) { + // Turn the exception into a more detailed bad_implementation that + // includes enough context to debug the XML + throw bad_implementation(softpkg, implementation, exc.what()); + } + } +} + +void ApplicationValidator::validateHostCollocation(const SoftwareAssembly::HostCollocation& collocation) +{ + BOOST_FOREACH(const ComponentPlacement& placement, collocation.getComponents()) { + validateComponentPlacement(placement); + } +} + +void ApplicationValidator::validateComponentPlacement(const ComponentPlacement& placement) +{ + const std::string& spd_file = placement.filename; + if (spd_file.empty()) { + throw validation_error("componentfile " + placement._componentFileRef + " filename is empty"); + } + + // Basic checking for valid, existing filename + LOG_TRACE(ApplicationValidator, "Validating SPD " << spd_file); + checkFilename(spd_file); + if (!fileExists(spd_file)) { + throw validation_error("componentfile " + placement._componentFileRef + " points to non-existent file " + spd_file); + } + + // If this fails, it will throw redhawk::invalid_profile + const SoftPkg* softpkg = cache.loadProfile(spd_file); + + BOOST_FOREACH(const SPD::Implementation& implementation, softpkg->getImplementations()) { + validateImplementation(softpkg, implementation, true); + } + + // If the softpkg is SCA-compliant, make sure it has a descriptor + if (softpkg->isScaCompliant() && !softpkg->getDescriptor()) { + std::string message = spd_file + " is SCA-compliant but does not have an SCD"; + throw validation_error(message); + } +} + +const Properties* ApplicationValidator::getAssemblyControllerProperties(const SoftwareAssembly& sad) +{ + // Search through all placements for the instantiation that is the assembly + // controller, then get the SoftPkg (which has already been loaded) and + // return its Properties + BOOST_FOREACH(const ComponentPlacement& placement, sad.getAllComponents()) { + BOOST_FOREACH(const ComponentInstantiation& instantiation, placement.getInstantiations()) { + if (instantiation.isAssemblyController()) { + const SoftPkg* softpkg = cache.loadProfile(placement.filename); + return softpkg->getProperties(); + } + } + } + + return 0; +} + +bool ApplicationValidator::fileExists(const std::string& filename) +{ + LOG_TRACE(ApplicationValidator, "Checking existence of file '" << filename << "'"); + try { + return fileSystem->exists(filename.c_str()); + } catch (...) { + // Turn all exceptions into negative result; in this context, at least, + // CORBA errors mean the same thing--the file is not usable + return false; + } +} + +void ApplicationValidator::checkFilename(const std::string& filename) +{ + if (filename.find(".spd.xml") == std::string::npos) { + LOG_WARN(ApplicationValidator, "SPD file " << filename << " should end with .spd.xml"); + } +} diff --git a/redhawk/src/control/sdr/dommgr/ApplicationValidator.h b/redhawk/src/control/sdr/dommgr/ApplicationValidator.h new file mode 100644 index 000000000..3866f8858 --- /dev/null +++ b/redhawk/src/control/sdr/dommgr/ApplicationValidator.h @@ -0,0 +1,90 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK core. + * + * REDHAWK core is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +#ifndef APPLICATIONVALIDATOR_H +#define APPLICATIONVALIDATOR_H + +#include + +#include +#include +#include + +#include "ProfileCache.h" + +namespace redhawk { + + /** + * @brief An exception raised when a SoftwareAssembly is invalid + */ + class validation_error : public std::runtime_error { + public: + validation_error(const std::string& what_arg) : std::runtime_error(what_arg) + {} + }; + + class ApplicationValidator { + + ENABLE_LOGGING; + + public: + ApplicationValidator(CF::FileSystem_ptr fileSystem); + + /** + * @brief Validates a SoftwareAssembly + * @param sad a parsed SoftwareAssembly + * @exception redhawk::validation_error the SAD is invalid + * @exception redhawk::invalid_profile a SoftPkg profile used by this + * SAD is invalid + * + * Performs validation of a SoftwareAssembly, making sure that it is + * semantically valid (at least, enough to attempt deployment). All + * SoftPkgs that could potentially be used to deploy components are + * checked to make sure that they are valid. + */ + void validate(const ossie::SoftwareAssembly& sad); + + private: + void validateExternalPorts(const std::vector& ports); + + void validateExternalProperties(const ossie::Properties* acProperties, + const std::vector& properties); + + void validateHostCollocation(const ossie::SoftwareAssembly::HostCollocation& collocation); + + void validateComponentPlacement(const ossie::ComponentPlacement& placement); + + void validateSoftPkgRef(const ossie::SPD::SoftPkgRef& softpkgref); + + void validateImplementation(const ossie::SoftPkg* softpkg, + const ossie::SPD::Implementation& implementation, + bool executable); + + const ossie::Properties* getAssemblyControllerProperties(const ossie::SoftwareAssembly& sad); + + void checkFilename(const std::string& filename); + bool fileExists(const std::string& filename); + + CF::FileSystem_var fileSystem; + redhawk::ProfileCache cache; + }; +} + +#endif // APPLICATIONVALIDATOR_H diff --git a/redhawk/src/control/sdr/dommgr/Makefile.am b/redhawk/src/control/sdr/dommgr/Makefile.am index 40c4737f3..3b35714b5 100644 --- a/redhawk/src/control/sdr/dommgr/Makefile.am +++ b/redhawk/src/control/sdr/dommgr/Makefile.am @@ -35,6 +35,7 @@ DomainManager_SOURCES = connectionSupport.cpp \ FakeApplication.cpp \ Deployment.cpp \ ApplicationDeployment.cpp \ + ApplicationValidator.cpp \ ProfileCache.cpp \ main.cpp DomainManager_CPPFLAGS = -I../../include -I../../parser -I$(top_srcdir)/base/include -I$(top_srcdir)/base $(BOOST_CPPFLAGS) $(OMNIORB_CFLAGS) $(LOG4CXX_FLAGS) From fe5f6e1c577d27e927ff12f0d5628a558c0f03a6 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 3 Jun 2016 12:00:21 -0400 Subject: [PATCH 0347/1644] Move internal parser implementations into their own .cpp files to better insulate the code that uses them from the implementation details --- .../control/parser/ComponentDescriptor.cpp | 1 - .../parser/DomainManagerConfiguration.cpp | 1 - redhawk/src/control/parser/Makefile.am | 6 + .../control/parser/internal/dcd-parser.cpp | 210 +++++++++++++++ .../src/control/parser/internal/dcd-parser.h | 192 +------------ .../control/parser/internal/dmd-parser.cpp | 85 ++++++ .../src/control/parser/internal/dmd-parser.h | 67 +---- .../control/parser/internal/prf-parser.cpp | 163 +++++++++++ .../src/control/parser/internal/prf-parser.h | 144 +--------- .../control/parser/internal/sad-parser.cpp | 253 ++++++++++++++++++ .../src/control/parser/internal/sad-parser.h | 236 +--------------- .../control/parser/internal/scd-parser.cpp | 107 ++++++++ .../src/control/parser/internal/scd-parser.h | 88 +----- .../control/parser/internal/spd-parser.cpp | 182 +++++++++++++ .../src/control/parser/internal/spd-parser.h | 168 +----------- 15 files changed, 1034 insertions(+), 869 deletions(-) create mode 100644 redhawk/src/control/parser/internal/dcd-parser.cpp create mode 100644 redhawk/src/control/parser/internal/dmd-parser.cpp create mode 100644 redhawk/src/control/parser/internal/prf-parser.cpp create mode 100644 redhawk/src/control/parser/internal/sad-parser.cpp create mode 100644 redhawk/src/control/parser/internal/scd-parser.cpp create mode 100644 redhawk/src/control/parser/internal/spd-parser.cpp diff --git a/redhawk/src/control/parser/ComponentDescriptor.cpp b/redhawk/src/control/parser/ComponentDescriptor.cpp index 0089c7cb8..bbe30edd5 100644 --- a/redhawk/src/control/parser/ComponentDescriptor.cpp +++ b/redhawk/src/control/parser/ComponentDescriptor.cpp @@ -26,7 +26,6 @@ #include "ossie/ComponentDescriptor.h" #include "internal/scd-parser.h" -using namespace scd; using namespace ossie; ComponentDescriptor::ComponentDescriptor(std::istream& input) throw (ossie::parser_error) { diff --git a/redhawk/src/control/parser/DomainManagerConfiguration.cpp b/redhawk/src/control/parser/DomainManagerConfiguration.cpp index fa8966128..b351c4fc9 100644 --- a/redhawk/src/control/parser/DomainManagerConfiguration.cpp +++ b/redhawk/src/control/parser/DomainManagerConfiguration.cpp @@ -23,7 +23,6 @@ #include"internal/dmd-parser.h" using namespace ossie; -using namespace dmd; // The implementation of these functions should come from the XSD produced drivers // When the XSD changes you will need to update these functions. diff --git a/redhawk/src/control/parser/Makefile.am b/redhawk/src/control/parser/Makefile.am index fa20c53d3..3327f50f0 100644 --- a/redhawk/src/control/parser/Makefile.am +++ b/redhawk/src/control/parser/Makefile.am @@ -30,6 +30,12 @@ libossieparser_la_SOURCES = Properties.cpp \ DeviceManagerConfiguration.cpp \ SoftwareAssembly.cpp \ componentProfile.cpp \ + internal/prf-parser.cpp \ + internal/dmd-parser.cpp \ + internal/dcd-parser.cpp \ + internal/sad-parser.cpp \ + internal/scd-parser.cpp \ + internal/spd-parser.cpp \ internal/prf-pskel.cpp \ internal/dmd-pskel.cpp \ internal/dcd-pskel.cpp \ diff --git a/redhawk/src/control/parser/internal/dcd-parser.cpp b/redhawk/src/control/parser/internal/dcd-parser.cpp new file mode 100644 index 000000000..28e8252fe --- /dev/null +++ b/redhawk/src/control/parser/internal/dcd-parser.cpp @@ -0,0 +1,210 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK core. + * + * REDHAWK core is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +#include + +#include "dcd-parser.h" +#include "dcd-pimpl.h" + +std::auto_ptr +ossie::internalparser::parseDCD(std::istream& input) throw (ossie::parser_error) +{ + try { + // Instantiate individual parsers. + // + ::dcd::deviceconfiguration_pimpl deviceconfiguration_p; + ::xml_schema::string_pimpl string_p; + ::dcd::devicemanagersoftpkg_pimpl devicemanagersoftpkg_p; + ::dcd::localfile_pimpl localfile_p; + ::dcd::componentfiles_pimpl componentfiles_p; + ::dcd::componentfile_pimpl componentfile_p; + ::dcd::partitioning_pimpl partitioning_p; + ::dcd::componentplacement_pimpl componentplacement_p; + ::dcd::componentfileref_pimpl componentfileref_p; + ::dcd::deployondevice_pimpl deployondevice_p; + ::dcd::compositepartofdevice_pimpl compositepartofdevice_p; + ::dcd::devicepkgfile_pimpl devicepkgfile_p; + ::dcd::componentinstantiation_pimpl componentinstantiation_p; + ::dcd::componentproperties_pimpl componentproperties_p; + ::dcd::simpleref_pimpl simpleref_p; + ::dcd::simplesequenceref_pimpl simplesequenceref_p; + ::dcd::values_pimpl values_p; + ::dcd::structref_pimpl structref_p; + ::dcd::structsequenceref_pimpl structsequenceref_p; + ::dcd::structvalue_pimpl structvalue_p; + ::dcd::domainmanager_pimpl domainmanager_p; + ::dcd::namingservice_pimpl namingservice_p; + ::dcd::connections_pimpl connections_p; + ::dcd::connectinterface_pimpl connectinterface_p; + ::dcd::usesport_pimpl usesport_p; + ::dcd::componentinstantiationref_pimpl componentinstantiationref_p; + ::dcd::devicethatloadedthiscomponentref_pimpl devicethatloadedthiscomponentref_p; + ::dcd::deviceusedbythiscomponentref_pimpl deviceusedbythiscomponentref_p; + ::dcd::findby_pimpl findby_p; + ::dcd::domainfinder_pimpl domainfinder_p; + ::dcd::providesport_pimpl providesport_p; + ::dcd::componentsupportedinterface_pimpl componentsupportedinterface_p; + ::dcd::filesystemnames_pimpl filesystemnames_p; + ::dcd::filesystemname_pimpl filesystemname_p; + ::dcd::affinity_pimpl affinity_p; + ::dcd::loggingconfig_pimpl loggingconfig_p; + + + // Connect the parsers together. + // + deviceconfiguration_p.parsers (string_p, + devicemanagersoftpkg_p, + componentfiles_p, + partitioning_p, + connections_p, + domainmanager_p, + filesystemnames_p, + string_p, + string_p); + + devicemanagersoftpkg_p.parsers (localfile_p); + + localfile_p.parsers (string_p); + + componentfiles_p.parsers (componentfile_p); + + componentfile_p.parsers (localfile_p, + string_p, + string_p); + + partitioning_p.parsers (componentplacement_p); + + componentplacement_p.parsers (componentfileref_p, + deployondevice_p, + compositepartofdevice_p, + devicepkgfile_p, + componentinstantiation_p); + + componentfileref_p.parsers (string_p); + + deployondevice_p.parsers (string_p); + + compositepartofdevice_p.parsers (string_p); + + devicepkgfile_p.parsers (localfile_p, + string_p); + + componentinstantiation_p.parsers (string_p, + componentproperties_p, + affinity_p, + loggingconfig_p, + string_p); + + affinity_p.parsers (simpleref_p, + simplesequenceref_p, + structref_p, + structsequenceref_p); + + loggingconfig_p.parsers(string_p); + + componentproperties_p.parsers (simpleref_p, + simplesequenceref_p, + structref_p, + structsequenceref_p); + + simpleref_p.parsers (string_p, + string_p); + + simplesequenceref_p.parsers (values_p, + string_p); + + values_p.parsers (string_p); + + structref_p.parsers (simpleref_p, + simplesequenceref_p, + string_p); + + structsequenceref_p.parsers (structvalue_p, + string_p); + + structvalue_p.parsers (simpleref_p, + simplesequenceref_p); + + domainmanager_p.parsers (namingservice_p, + string_p); + + namingservice_p.parsers (string_p); + + connections_p.parsers (connectinterface_p); + + connectinterface_p.parsers (usesport_p, + providesport_p, + componentsupportedinterface_p, + findby_p, + string_p); + + usesport_p.parsers (string_p, + componentinstantiationref_p, + devicethatloadedthiscomponentref_p, + deviceusedbythiscomponentref_p, + findby_p); + + componentinstantiationref_p.parsers (string_p); + + devicethatloadedthiscomponentref_p.parsers (string_p); + + deviceusedbythiscomponentref_p.parsers (string_p, + string_p); + + findby_p.parsers (namingservice_p, + string_p, + domainfinder_p); + + domainfinder_p.parsers (string_p, + string_p); + + providesport_p.parsers (string_p, + componentinstantiationref_p, + devicethatloadedthiscomponentref_p, + deviceusedbythiscomponentref_p, + findby_p); + + componentsupportedinterface_p.parsers (string_p, + componentinstantiationref_p, + findby_p); + + filesystemnames_p.parsers (filesystemname_p); + + filesystemname_p.parsers (string_p, + string_p); + + // Parse the XML document. + // + ::xml_schema::document doc_p ( + deviceconfiguration_p, + "", + "deviceconfiguration"); + + deviceconfiguration_p.pre (); + doc_p.parse (input); + return (deviceconfiguration_p.post_deviceconfiguration ()); + } catch (const ::xml_schema::exception& e) { + std::ostringstream err; + err << e; + throw ossie::parser_error(err.str()); + } catch (const std::ios_base::failure& e) { + throw ossie::parser_error(e.what()); + } +} diff --git a/redhawk/src/control/parser/internal/dcd-parser.h b/redhawk/src/control/parser/internal/dcd-parser.h index 134f86a84..b7a775a7c 100644 --- a/redhawk/src/control/parser/internal/dcd-parser.h +++ b/redhawk/src/control/parser/internal/dcd-parser.h @@ -21,198 +21,14 @@ #ifndef __DCD_PARSER_H__ #define __DCD_PARSER_H__ -#include -#include -#include"ossie/exceptions.h" -#include "dcd-pimpl.h" +#include -#include +#include +#include namespace ossie { namespace internalparser { - inline std::auto_ptr parseDCD(std::istream& input) throw (ossie::parser_error) { - try { - // Instantiate individual parsers. - // - ::dcd::deviceconfiguration_pimpl deviceconfiguration_p; - ::xml_schema::string_pimpl string_p; - ::dcd::devicemanagersoftpkg_pimpl devicemanagersoftpkg_p; - ::dcd::localfile_pimpl localfile_p; - ::dcd::componentfiles_pimpl componentfiles_p; - ::dcd::componentfile_pimpl componentfile_p; - ::dcd::partitioning_pimpl partitioning_p; - ::dcd::componentplacement_pimpl componentplacement_p; - ::dcd::componentfileref_pimpl componentfileref_p; - ::dcd::deployondevice_pimpl deployondevice_p; - ::dcd::compositepartofdevice_pimpl compositepartofdevice_p; - ::dcd::devicepkgfile_pimpl devicepkgfile_p; - ::dcd::componentinstantiation_pimpl componentinstantiation_p; - ::dcd::componentproperties_pimpl componentproperties_p; - ::dcd::simpleref_pimpl simpleref_p; - ::dcd::simplesequenceref_pimpl simplesequenceref_p; - ::dcd::values_pimpl values_p; - ::dcd::structref_pimpl structref_p; - ::dcd::structsequenceref_pimpl structsequenceref_p; - ::dcd::structvalue_pimpl structvalue_p; - ::dcd::domainmanager_pimpl domainmanager_p; - ::dcd::namingservice_pimpl namingservice_p; - ::dcd::connections_pimpl connections_p; - ::dcd::connectinterface_pimpl connectinterface_p; - ::dcd::usesport_pimpl usesport_p; - ::dcd::componentinstantiationref_pimpl componentinstantiationref_p; - ::dcd::devicethatloadedthiscomponentref_pimpl devicethatloadedthiscomponentref_p; - ::dcd::deviceusedbythiscomponentref_pimpl deviceusedbythiscomponentref_p; - ::dcd::findby_pimpl findby_p; - ::dcd::domainfinder_pimpl domainfinder_p; - ::dcd::providesport_pimpl providesport_p; - ::dcd::componentsupportedinterface_pimpl componentsupportedinterface_p; - ::dcd::filesystemnames_pimpl filesystemnames_p; - ::dcd::filesystemname_pimpl filesystemname_p; - ::dcd::affinity_pimpl affinity_p; - ::dcd::loggingconfig_pimpl loggingconfig_p; - - - // Connect the parsers together. - // - deviceconfiguration_p.parsers (string_p, - devicemanagersoftpkg_p, - componentfiles_p, - partitioning_p, - connections_p, - domainmanager_p, - filesystemnames_p, - string_p, - string_p); - - devicemanagersoftpkg_p.parsers (localfile_p); - - localfile_p.parsers (string_p); - - componentfiles_p.parsers (componentfile_p); - - componentfile_p.parsers (localfile_p, - string_p, - string_p); - - partitioning_p.parsers (componentplacement_p); - - componentplacement_p.parsers (componentfileref_p, - deployondevice_p, - compositepartofdevice_p, - devicepkgfile_p, - componentinstantiation_p); - - componentfileref_p.parsers (string_p); - - deployondevice_p.parsers (string_p); - - compositepartofdevice_p.parsers (string_p); - - devicepkgfile_p.parsers (localfile_p, - string_p); - - componentinstantiation_p.parsers (string_p, - componentproperties_p, - affinity_p, - loggingconfig_p, - string_p); - - affinity_p.parsers (simpleref_p, - simplesequenceref_p, - structref_p, - structsequenceref_p); - - loggingconfig_p.parsers(string_p); - - componentproperties_p.parsers (simpleref_p, - simplesequenceref_p, - structref_p, - structsequenceref_p); - - simpleref_p.parsers (string_p, - string_p); - - simplesequenceref_p.parsers (values_p, - string_p); - - values_p.parsers (string_p); - - structref_p.parsers (simpleref_p, - simplesequenceref_p, - string_p); - - structsequenceref_p.parsers (structvalue_p, - string_p); - - structvalue_p.parsers (simpleref_p, - simplesequenceref_p); - - domainmanager_p.parsers (namingservice_p, - string_p); - - namingservice_p.parsers (string_p); - - connections_p.parsers (connectinterface_p); - - connectinterface_p.parsers (usesport_p, - providesport_p, - componentsupportedinterface_p, - findby_p, - string_p); - - usesport_p.parsers (string_p, - componentinstantiationref_p, - devicethatloadedthiscomponentref_p, - deviceusedbythiscomponentref_p, - findby_p); - - componentinstantiationref_p.parsers (string_p); - - devicethatloadedthiscomponentref_p.parsers (string_p); - - deviceusedbythiscomponentref_p.parsers (string_p, - string_p); - - findby_p.parsers (namingservice_p, - string_p, - domainfinder_p); - - domainfinder_p.parsers (string_p, - string_p); - - providesport_p.parsers (string_p, - componentinstantiationref_p, - devicethatloadedthiscomponentref_p, - deviceusedbythiscomponentref_p, - findby_p); - - componentsupportedinterface_p.parsers (string_p, - componentinstantiationref_p, - findby_p); - - filesystemnames_p.parsers (filesystemname_p); - - filesystemname_p.parsers (string_p, - string_p); - - // Parse the XML document. - // - ::xml_schema::document doc_p ( - deviceconfiguration_p, - "", - "deviceconfiguration"); - - deviceconfiguration_p.pre (); - doc_p.parse (input); - return (deviceconfiguration_p.post_deviceconfiguration ()); - } catch (const ::xml_schema::exception& e) { - std::ostringstream err; - err << e; - throw ossie::parser_error(err.str()); - } catch (const std::ios_base::failure& e) { - throw ossie::parser_error(e.what()); - } - } + std::auto_ptr parseDCD(std::istream& input) throw (ossie::parser_error); } } diff --git a/redhawk/src/control/parser/internal/dmd-parser.cpp b/redhawk/src/control/parser/internal/dmd-parser.cpp new file mode 100644 index 000000000..84550ee1a --- /dev/null +++ b/redhawk/src/control/parser/internal/dmd-parser.cpp @@ -0,0 +1,85 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK core. + * + * REDHAWK core is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +#include + +#include "dmd-parser.h" +#include "dmd-pimpl.h" + +std::auto_ptr +ossie::internalparser::parseDMD(std::istream& input) throw (ossie::parser_error) +{ + using namespace dmd; + + try { + // Instantiate individual parsers. + // + domainmanagerconfiguration_pimpl domainmanagerconfiguration_p; + ::xml_schema::string_pimpl string_p; + domainmanagersoftpkg_pimpl domainmanagersoftpkg_p; + localfile_pimpl localfile_p; + services_pimpl services_p; + service_pimpl service_p; + findby_pimpl findby_p; + namingservice_pimpl namingservice_p; + ::xml_schema::any_simple_type_pimpl any_simple_type_p; + domainfinder_pimpl domainfinder_p; + + // Connect the parsers together. + // + domainmanagerconfiguration_p.parsers (string_p, + domainmanagersoftpkg_p, + services_p, + string_p, + string_p); + + domainmanagersoftpkg_p.parsers (localfile_p); + + localfile_p.parsers (string_p); + + services_p.parsers (service_p); + + service_p.parsers (string_p, + findby_p); + + findby_p.parsers (namingservice_p, + string_p, + domainfinder_p); + + namingservice_p.parsers (any_simple_type_p); + + domainfinder_p.parsers (string_p, + string_p); + + // Parse the XML document. + // + ::xml_schema::document doc_p (domainmanagerconfiguration_p, "", "domainmanagerconfiguration"); + + domainmanagerconfiguration_p.pre (); + doc_p.parse (input); + return (domainmanagerconfiguration_p.post_domainmanagerconfiguration ()); + } catch (const ::xml_schema::exception& e) { + std::ostringstream err; + err << e; + throw ossie::parser_error(err.str()); + } catch (const std::ios_base::failure& e) { + throw ossie::parser_error(e.what()); + } +} diff --git a/redhawk/src/control/parser/internal/dmd-parser.h b/redhawk/src/control/parser/internal/dmd-parser.h index 16d34d188..638762430 100644 --- a/redhawk/src/control/parser/internal/dmd-parser.h +++ b/redhawk/src/control/parser/internal/dmd-parser.h @@ -21,71 +21,14 @@ #ifndef __DMD_PARSER_H__ #define __DMD_PARSER_H__ -#include -#include -#include "dmd-pimpl.h" -#include"ossie/exceptions.h" +#include + +#include +#include namespace ossie { namespace internalparser { - inline std::auto_ptr parseDMD(std::istream& input) throw (ossie::parser_error) { - using namespace dmd; - - try { - // Instantiate individual parsers. - // - domainmanagerconfiguration_pimpl domainmanagerconfiguration_p; - ::xml_schema::string_pimpl string_p; - domainmanagersoftpkg_pimpl domainmanagersoftpkg_p; - localfile_pimpl localfile_p; - services_pimpl services_p; - service_pimpl service_p; - findby_pimpl findby_p; - namingservice_pimpl namingservice_p; - ::xml_schema::any_simple_type_pimpl any_simple_type_p; - domainfinder_pimpl domainfinder_p; - - // Connect the parsers together. - // - domainmanagerconfiguration_p.parsers (string_p, - domainmanagersoftpkg_p, - services_p, - string_p, - string_p); - - domainmanagersoftpkg_p.parsers (localfile_p); - - localfile_p.parsers (string_p); - - services_p.parsers (service_p); - - service_p.parsers (string_p, - findby_p); - - findby_p.parsers (namingservice_p, - string_p, - domainfinder_p); - - namingservice_p.parsers (any_simple_type_p); - - domainfinder_p.parsers (string_p, - string_p); - - // Parse the XML document. - // - ::xml_schema::document doc_p (domainmanagerconfiguration_p, "", "domainmanagerconfiguration"); - - domainmanagerconfiguration_p.pre (); - doc_p.parse (input); - return (domainmanagerconfiguration_p.post_domainmanagerconfiguration ()); - } catch (const ::xml_schema::exception& e) { - std::ostringstream err; - err << e; - throw ossie::parser_error(err.str()); - } catch (const std::ios_base::failure& e) { - throw ossie::parser_error(e.what()); - } - } + std::auto_ptr parseDMD(std::istream& input) throw (ossie::parser_error); } } diff --git a/redhawk/src/control/parser/internal/prf-parser.cpp b/redhawk/src/control/parser/internal/prf-parser.cpp new file mode 100644 index 000000000..6cab4018f --- /dev/null +++ b/redhawk/src/control/parser/internal/prf-parser.cpp @@ -0,0 +1,163 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK core. + * + * REDHAWK core is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +#include + +#include "prf-parser.h" +#include "prf-pimpl.h" + +std::auto_ptr ossie::internalparser::parsePRF(std::istream& input) throw (ossie::parser_error) +{ + using namespace prf; + + try { + // Instantiate individual parsers. + // + properties_pimpl properties_p; + ::xml_schema::string_pimpl string_p; + simple_pimpl simple_p; + Unit_pimpl Unit_p; + range_pimpl range_p; + enumerations_pimpl enumerations_p; + enumeration_pimpl enumeration_p; + kind_pimpl kind_p; + PropertyConfigurationType_pimpl PropertyConfigurationType_p; + action_pimpl action_p; + ActionType_pimpl ActionType_p; + AccessType_pimpl AccessType_p; + PropertyValueType_pimpl PropertyValueType_p; + simpleSequence_pimpl simpleSequence_p; + values_pimpl values_p; + test_pimpl test_p; + inputValue_pimpl inputValue_p; + resultValue_pimpl resultValue_p; + struct_pimpl struct_p; + configurationKind_pimpl configurationKind_p; + StructPropertyConfigurationType_pimpl StructPropertyConfigurationType_p; + structSequence_pimpl structSequence_p; + structValue_pimpl structValue_p; + IsComplex_pimpl IsComplex_p; + IsCommandLine_pimpl IsCommandLine_p; + IsOptional_pimpl IsOptional_p; + simpleRef_pimpl simpleRef_p; + simpleSequenceRef_pimpl simpleSequenceRef_p; + + // Connect the parsers together. + // + properties_p.parsers (string_p, + simple_p, + simpleSequence_p, + test_p, + struct_p, + structSequence_p); + + simple_p.parsers (string_p, + string_p, + Unit_p, + range_p, + enumerations_p, + kind_p, + action_p, + string_p, + AccessType_p, + string_p, + IsComplex_p, + IsCommandLine_p, + IsOptional_p, + PropertyValueType_p); + + range_p.parsers (string_p, + string_p); + + enumerations_p.parsers (enumeration_p); + + enumeration_p.parsers (string_p, + string_p); + + kind_p.parsers (PropertyConfigurationType_p); + + action_p.parsers (ActionType_p); + + simpleSequence_p.parsers (string_p, + values_p, + Unit_p, + range_p, + kind_p, + action_p, + string_p, + AccessType_p, + string_p, + PropertyValueType_p, + IsComplex_p, + IsOptional_p); + + values_p.parsers (string_p); + + test_p.parsers (string_p, + inputValue_p, + resultValue_p, + string_p); + + inputValue_p.parsers (simple_p); + + resultValue_p.parsers (simple_p); + + struct_p.parsers (string_p, + simple_p, + simpleSequence_p, + configurationKind_p, + string_p, + AccessType_p, + string_p); + + configurationKind_p.parsers (StructPropertyConfigurationType_p); + + structSequence_p.parsers (string_p, + struct_p, + structValue_p, + configurationKind_p, + string_p, + AccessType_p, + string_p); + + structValue_p.parsers (simpleRef_p, + simpleSequenceRef_p); + + simpleRef_p.parsers (string_p, + string_p); + + simpleSequenceRef_p.parsers (values_p, + string_p); + + // Parse the XML document. + // + ::xml_schema::document doc_p (properties_p, "properties"); + + properties_p.pre (); + doc_p.parse (input); + return properties_p.post_properties (); + } catch (const ::xml_schema::exception& e) { + std::ostringstream message; + message << e; + throw ossie::parser_error(message.str()); + } catch (const std::ios_base::failure& e) { + throw ossie::parser_error(e.what()); + } +} diff --git a/redhawk/src/control/parser/internal/prf-parser.h b/redhawk/src/control/parser/internal/prf-parser.h index dbfb49807..ff7492163 100644 --- a/redhawk/src/control/parser/internal/prf-parser.h +++ b/redhawk/src/control/parser/internal/prf-parser.h @@ -21,148 +21,14 @@ #ifndef __PRF_PARSER_H__ #define __PRF_PARSER_H__ -#include"prf-pimpl.h" -#include"ossie/exceptions.h" -#include"ossie/Properties.h" +#include + +#include +#include namespace ossie { namespace internalparser { - inline std::auto_ptr parsePRF(std::istream& input) throw (ossie::parser_error) { - using namespace prf; - try { - // Instantiate individual parsers. - // - properties_pimpl properties_p; - ::xml_schema::string_pimpl string_p; - simple_pimpl simple_p; - Unit_pimpl Unit_p; - range_pimpl range_p; - enumerations_pimpl enumerations_p; - enumeration_pimpl enumeration_p; - kind_pimpl kind_p; - PropertyConfigurationType_pimpl PropertyConfigurationType_p; - action_pimpl action_p; - ActionType_pimpl ActionType_p; - AccessType_pimpl AccessType_p; - PropertyValueType_pimpl PropertyValueType_p; - simpleSequence_pimpl simpleSequence_p; - values_pimpl values_p; - test_pimpl test_p; - inputValue_pimpl inputValue_p; - resultValue_pimpl resultValue_p; - struct_pimpl struct_p; - configurationKind_pimpl configurationKind_p; - StructPropertyConfigurationType_pimpl StructPropertyConfigurationType_p; - structSequence_pimpl structSequence_p; - structValue_pimpl structValue_p; - IsComplex_pimpl IsComplex_p; - IsCommandLine_pimpl IsCommandLine_p; - IsOptional_pimpl IsOptional_p; - simpleRef_pimpl simpleRef_p; - simpleSequenceRef_pimpl simpleSequenceRef_p; - - // Connect the parsers together. - // - properties_p.parsers (string_p, - simple_p, - simpleSequence_p, - test_p, - struct_p, - structSequence_p); - - simple_p.parsers (string_p, - string_p, - Unit_p, - range_p, - enumerations_p, - kind_p, - action_p, - string_p, - AccessType_p, - string_p, - IsComplex_p, - IsCommandLine_p, - IsOptional_p, - PropertyValueType_p); - - range_p.parsers (string_p, - string_p); - - enumerations_p.parsers (enumeration_p); - - enumeration_p.parsers (string_p, - string_p); - - kind_p.parsers (PropertyConfigurationType_p); - - action_p.parsers (ActionType_p); - - simpleSequence_p.parsers (string_p, - values_p, - Unit_p, - range_p, - kind_p, - action_p, - string_p, - AccessType_p, - string_p, - PropertyValueType_p, - IsComplex_p, - IsOptional_p); - - values_p.parsers (string_p); - - test_p.parsers (string_p, - inputValue_p, - resultValue_p, - string_p); - - inputValue_p.parsers (simple_p); - - resultValue_p.parsers (simple_p); - - struct_p.parsers (string_p, - simple_p, - simpleSequence_p, - configurationKind_p, - string_p, - AccessType_p, - string_p); - - configurationKind_p.parsers (StructPropertyConfigurationType_p); - - structSequence_p.parsers (string_p, - struct_p, - structValue_p, - configurationKind_p, - string_p, - AccessType_p, - string_p); - - structValue_p.parsers (simpleRef_p, - simpleSequenceRef_p); - - simpleRef_p.parsers (string_p, - string_p); - - simpleSequenceRef_p.parsers (values_p, - string_p); - - // Parse the XML document. - // - ::xml_schema::document doc_p (properties_p, "properties"); - - properties_p.pre (); - doc_p.parse (input); - return properties_p.post_properties (); - } catch (const ::xml_schema::exception& e) { - std::ostringstream message; - message << e; - throw ossie::parser_error(message.str()); - } catch (const std::ios_base::failure& e) { - throw ossie::parser_error(e.what()); - } - } + std::auto_ptr parsePRF(std::istream& input) throw (ossie::parser_error); } } #endif diff --git a/redhawk/src/control/parser/internal/sad-parser.cpp b/redhawk/src/control/parser/internal/sad-parser.cpp new file mode 100644 index 000000000..63a356274 --- /dev/null +++ b/redhawk/src/control/parser/internal/sad-parser.cpp @@ -0,0 +1,253 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK core. + * + * REDHAWK core is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +#include + +#include "sad-parser.h" +#include "sad-pimpl.h" + +std::auto_ptr +ossie::internalparser::parseSAD(std::istream& input) throw (ossie::parser_error) +{ + try { + // Instantiate individual parsers. + // + ::sad::softwareassembly_pimpl softwareassembly_p; + ::xml_schema::string_pimpl string_p; + ::sad::componentfiles_pimpl componentfiles_p; + ::sad::componentfile_pimpl componentfile_p; + ::sad::localfile_pimpl localfile_p; + ::sad::partitioning_pimpl partitioning_p; + ::sad::componentplacement_pimpl componentplacement_p; + ::sad::componentfileref_pimpl componentfileref_p; + ::sad::componentinstantiation_pimpl componentinstantiation_p; + ::sad::componentproperties_pimpl componentproperties_p; + ::sad::simpleref_pimpl simpleref_p; + ::sad::simplesequenceref_pimpl simplesequenceref_p; + ::sad::values_pimpl values_p; + ::sad::structref_pimpl structref_p; + ::sad::structsequenceref_pimpl structsequenceref_p; + ::sad::structvalue_pimpl structvalue_p; + ::sad::findcomponent_pimpl findcomponent_p; + ::sad::componentresourcefactoryref_pimpl componentresourcefactoryref_p; + ::sad::resourcefactoryproperties_pimpl resourcefactoryproperties_p; + ::sad::namingservice_pimpl namingservice_p; + ::sad::hostcollocation_pimpl hostcollocation_p; + ::sad::assemblycontroller_pimpl assemblycontroller_p; + ::sad::componentinstantiationref_pimpl componentinstantiationref_p; + ::sad::connections_pimpl connections_p; + ::sad::connectinterface_pimpl connectinterface_p; + ::sad::usesport_pimpl usesport_p; + ::sad::devicethatloadedthiscomponentref_pimpl devicethatloadedthiscomponentref_p; + ::sad::deviceusedbythiscomponentref_pimpl deviceusedbythiscomponentref_p; + ::sad::deviceusedbyapplication_pimpl deviceusedbyapplication_p; + ::sad::findby_pimpl findby_p; + ::sad::domainfinder_pimpl domainfinder_p; + ::sad::providesport_pimpl providesport_p; + ::sad::componentsupportedinterface_pimpl componentsupportedinterface_p; + ::sad::externalports_pimpl externalports_p; + ::sad::port_pimpl port_p; + ::sad::externalproperties_pimpl externalproperties_p; + ::sad::property_pimpl property_p; + ::sad::usesdevicedependencies_pimpl usesdevicedependencies_p; + ::sad::usesdevice_pimpl usesdevice_p; + ::sad::propertyref_pimpl propertyref_p; + ::sad::affinity_pimpl affinity_p; + ::sad::loggingconfig_pimpl loggingconfig_p; + + + // Connect the parsers together. + // + softwareassembly_p.parsers (string_p, + componentfiles_p, + partitioning_p, + assemblycontroller_p, + connections_p, + externalports_p, + externalproperties_p, + usesdevicedependencies_p, + string_p, + string_p, + string_p); + + componentfiles_p.parsers (componentfile_p); + + componentfile_p.parsers (localfile_p, + string_p, + string_p); + + localfile_p.parsers (string_p); + + partitioning_p.parsers (componentplacement_p, + hostcollocation_p); + + componentplacement_p.parsers (componentfileref_p, + componentinstantiation_p); + + componentfileref_p.parsers (string_p); + + componentinstantiation_p.parsers (string_p, + componentproperties_p, + affinity_p, + loggingconfig_p, + findcomponent_p, + string_p, + string_p); + + affinity_p.parsers(simpleref_p, + simplesequenceref_p, + structref_p, + structsequenceref_p); + + loggingconfig_p.parsers(string_p); + + componentproperties_p.parsers (simpleref_p, + simplesequenceref_p, + structref_p, + structsequenceref_p); + + simpleref_p.parsers (string_p, + string_p); + + simplesequenceref_p.parsers (values_p, + string_p); + + values_p.parsers (string_p); + + structref_p.parsers (simpleref_p, + simplesequenceref_p, + string_p); + + structsequenceref_p.parsers (structvalue_p, + string_p); + + structvalue_p.parsers (simpleref_p, + simplesequenceref_p); + + findcomponent_p.parsers (componentresourcefactoryref_p, + namingservice_p); + + componentresourcefactoryref_p.parsers (resourcefactoryproperties_p, + string_p); + + resourcefactoryproperties_p.parsers (simpleref_p, + simplesequenceref_p, + structref_p, + structsequenceref_p); + + namingservice_p.parsers (string_p); + + hostcollocation_p.parsers (componentplacement_p, + string_p, + string_p); + + assemblycontroller_p.parsers (componentinstantiationref_p); + + componentinstantiationref_p.parsers (string_p); + + connections_p.parsers (connectinterface_p); + + connectinterface_p.parsers (usesport_p, + providesport_p, + componentsupportedinterface_p, + findby_p, + string_p); + + usesport_p.parsers (string_p, + componentinstantiationref_p, + devicethatloadedthiscomponentref_p, + deviceusedbythiscomponentref_p, + deviceusedbyapplication_p, + findby_p); + + devicethatloadedthiscomponentref_p.parsers (string_p); + + deviceusedbythiscomponentref_p.parsers (string_p, + string_p); + + deviceusedbyapplication_p.parsers(string_p); + + findby_p.parsers (namingservice_p, + string_p, + domainfinder_p); + + domainfinder_p.parsers (string_p, + string_p); + + providesport_p.parsers (string_p, + componentinstantiationref_p, + devicethatloadedthiscomponentref_p, + deviceusedbythiscomponentref_p, + deviceusedbyapplication_p, + findby_p); + + componentsupportedinterface_p.parsers (string_p, + componentinstantiationref_p, + devicethatloadedthiscomponentref_p, + deviceusedbythiscomponentref_p, + deviceusedbyapplication_p, + findby_p); + + externalports_p.parsers (port_p); + + port_p.parsers (string_p, + string_p, + string_p, + string_p, + componentinstantiationref_p, + string_p); + + externalproperties_p.parsers (property_p); + + property_p.parsers (string_p, + string_p, + string_p); + + usesdevicedependencies_p.parsers (usesdevice_p); + + usesdevice_p.parsers (propertyref_p, + simpleref_p, + simplesequenceref_p, + structref_p, + structsequenceref_p, + string_p, + string_p); + + propertyref_p.parsers (string_p, + string_p); + + // Parse the XML document. + // + ::xml_schema::document doc_p ( + softwareassembly_p, + "", + "softwareassembly"); + + softwareassembly_p.pre (); + doc_p.parse (input); + return (softwareassembly_p.post_softwareassembly ()); + } catch (const ::xml_schema::exception& e) { + std::ostringstream err; + err << e; + throw ossie::parser_error(err.str()); + } catch (const std::ios_base::failure& e) { + throw ossie::parser_error(e.what()); + } +} diff --git a/redhawk/src/control/parser/internal/sad-parser.h b/redhawk/src/control/parser/internal/sad-parser.h index be402e194..563242e18 100644 --- a/redhawk/src/control/parser/internal/sad-parser.h +++ b/redhawk/src/control/parser/internal/sad-parser.h @@ -21,241 +21,15 @@ #ifndef __SAD_PARSER_H__ #define __SAD_PARSER_H__ -#include -#include -#include"ossie/exceptions.h" -#include "sad-pimpl.h" +#include +#include -#include +#include +#include namespace ossie { namespace internalparser { - inline std::auto_ptr parseSAD(std::istream& input) throw (ossie::parser_error) { - try { - // Instantiate individual parsers. - // - ::sad::softwareassembly_pimpl softwareassembly_p; - ::xml_schema::string_pimpl string_p; - ::sad::componentfiles_pimpl componentfiles_p; - ::sad::componentfile_pimpl componentfile_p; - ::sad::localfile_pimpl localfile_p; - ::sad::partitioning_pimpl partitioning_p; - ::sad::componentplacement_pimpl componentplacement_p; - ::sad::componentfileref_pimpl componentfileref_p; - ::sad::componentinstantiation_pimpl componentinstantiation_p; - ::sad::componentproperties_pimpl componentproperties_p; - ::sad::simpleref_pimpl simpleref_p; - ::sad::simplesequenceref_pimpl simplesequenceref_p; - ::sad::values_pimpl values_p; - ::sad::structref_pimpl structref_p; - ::sad::structsequenceref_pimpl structsequenceref_p; - ::sad::structvalue_pimpl structvalue_p; - ::sad::findcomponent_pimpl findcomponent_p; - ::sad::componentresourcefactoryref_pimpl componentresourcefactoryref_p; - ::sad::resourcefactoryproperties_pimpl resourcefactoryproperties_p; - ::sad::namingservice_pimpl namingservice_p; - ::sad::hostcollocation_pimpl hostcollocation_p; - ::sad::assemblycontroller_pimpl assemblycontroller_p; - ::sad::componentinstantiationref_pimpl componentinstantiationref_p; - ::sad::connections_pimpl connections_p; - ::sad::connectinterface_pimpl connectinterface_p; - ::sad::usesport_pimpl usesport_p; - ::sad::devicethatloadedthiscomponentref_pimpl devicethatloadedthiscomponentref_p; - ::sad::deviceusedbythiscomponentref_pimpl deviceusedbythiscomponentref_p; - ::sad::deviceusedbyapplication_pimpl deviceusedbyapplication_p; - ::sad::findby_pimpl findby_p; - ::sad::domainfinder_pimpl domainfinder_p; - ::sad::providesport_pimpl providesport_p; - ::sad::componentsupportedinterface_pimpl componentsupportedinterface_p; - ::sad::externalports_pimpl externalports_p; - ::sad::port_pimpl port_p; - ::sad::externalproperties_pimpl externalproperties_p; - ::sad::property_pimpl property_p; - ::sad::usesdevicedependencies_pimpl usesdevicedependencies_p; - ::sad::usesdevice_pimpl usesdevice_p; - ::sad::propertyref_pimpl propertyref_p; - ::sad::affinity_pimpl affinity_p; - ::sad::loggingconfig_pimpl loggingconfig_p; - - - // Connect the parsers together. - // - softwareassembly_p.parsers (string_p, - componentfiles_p, - partitioning_p, - assemblycontroller_p, - connections_p, - externalports_p, - externalproperties_p, - usesdevicedependencies_p, - string_p, - string_p, - string_p); - - componentfiles_p.parsers (componentfile_p); - - componentfile_p.parsers (localfile_p, - string_p, - string_p); - - localfile_p.parsers (string_p); - - partitioning_p.parsers (componentplacement_p, - hostcollocation_p); - - componentplacement_p.parsers (componentfileref_p, - componentinstantiation_p); - - componentfileref_p.parsers (string_p); - - componentinstantiation_p.parsers (string_p, - componentproperties_p, - affinity_p, - loggingconfig_p, - findcomponent_p, - string_p, - string_p); - - affinity_p.parsers(simpleref_p, - simplesequenceref_p, - structref_p, - structsequenceref_p); - - loggingconfig_p.parsers(string_p); - - componentproperties_p.parsers (simpleref_p, - simplesequenceref_p, - structref_p, - structsequenceref_p); - - simpleref_p.parsers (string_p, - string_p); - - simplesequenceref_p.parsers (values_p, - string_p); - - values_p.parsers (string_p); - - structref_p.parsers (simpleref_p, - simplesequenceref_p, - string_p); - - structsequenceref_p.parsers (structvalue_p, - string_p); - - structvalue_p.parsers (simpleref_p, - simplesequenceref_p); - - findcomponent_p.parsers (componentresourcefactoryref_p, - namingservice_p); - - componentresourcefactoryref_p.parsers (resourcefactoryproperties_p, - string_p); - - resourcefactoryproperties_p.parsers (simpleref_p, - simplesequenceref_p, - structref_p, - structsequenceref_p); - - namingservice_p.parsers (string_p); - - hostcollocation_p.parsers (componentplacement_p, - string_p, - string_p); - - assemblycontroller_p.parsers (componentinstantiationref_p); - - componentinstantiationref_p.parsers (string_p); - - connections_p.parsers (connectinterface_p); - - connectinterface_p.parsers (usesport_p, - providesport_p, - componentsupportedinterface_p, - findby_p, - string_p); - - usesport_p.parsers (string_p, - componentinstantiationref_p, - devicethatloadedthiscomponentref_p, - deviceusedbythiscomponentref_p, - deviceusedbyapplication_p, - findby_p); - - devicethatloadedthiscomponentref_p.parsers (string_p); - - deviceusedbythiscomponentref_p.parsers (string_p, - string_p); - - deviceusedbyapplication_p.parsers(string_p); - - findby_p.parsers (namingservice_p, - string_p, - domainfinder_p); - - domainfinder_p.parsers (string_p, - string_p); - - providesport_p.parsers (string_p, - componentinstantiationref_p, - devicethatloadedthiscomponentref_p, - deviceusedbythiscomponentref_p, - deviceusedbyapplication_p, - findby_p); - - componentsupportedinterface_p.parsers (string_p, - componentinstantiationref_p, - devicethatloadedthiscomponentref_p, - deviceusedbythiscomponentref_p, - deviceusedbyapplication_p, - findby_p); - - externalports_p.parsers (port_p); - - port_p.parsers (string_p, - string_p, - string_p, - string_p, - componentinstantiationref_p, - string_p); - - externalproperties_p.parsers (property_p); - - property_p.parsers (string_p, - string_p, - string_p); - - usesdevicedependencies_p.parsers (usesdevice_p); - - usesdevice_p.parsers (propertyref_p, - simpleref_p, - simplesequenceref_p, - structref_p, - structsequenceref_p, - string_p, - string_p); - - propertyref_p.parsers (string_p, - string_p); - - // Parse the XML document. - // - ::xml_schema::document doc_p ( - softwareassembly_p, - "", - "softwareassembly"); - - softwareassembly_p.pre (); - doc_p.parse (input); - return (softwareassembly_p.post_softwareassembly ()); - } catch (const ::xml_schema::exception& e) { - std::ostringstream err; - err << e; - throw ossie::parser_error(err.str()); - } catch (const std::ios_base::failure& e) { - throw ossie::parser_error(e.what()); - } - } + std::auto_ptr parseSAD(std::istream& input) throw (ossie::parser_error); } } diff --git a/redhawk/src/control/parser/internal/scd-parser.cpp b/redhawk/src/control/parser/internal/scd-parser.cpp new file mode 100644 index 000000000..5cbd5e699 --- /dev/null +++ b/redhawk/src/control/parser/internal/scd-parser.cpp @@ -0,0 +1,107 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK core. + * + * REDHAWK core is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +#include + +#include "scd-parser.h" +#include "scd-pimpl.h" + +std::auto_ptr +ossie::internalparser::parseSCD(std::istream& input) throw (ossie::parser_error) +{ + using namespace scd; + + try { + // Instantiate individual parsers. + // + softwarecomponent_pimpl softwarecomponent_p; + ::xml_schema::string_pimpl string_p; + componentRepId_pimpl componentRepId_p; + componentFeatures_pimpl componentFeatures_p; + supportsInterface_pimpl supportsInterface_p; + ports_pimpl ports_p; + provides_pimpl provides_p; + portType_pimpl portType_p; + type_pimpl type_p; + uses_pimpl uses_p; + interfaces_pimpl interfaces_p; + interface_pimpl interface_p; + inheritsInterface_pimpl inheritsInterface_p; + propertyFile_pimpl propertyFile_p; + localFile_pimpl localFile_p; + + // Connect the parsers together. + // + softwarecomponent_p.parsers (string_p, + componentRepId_p, + string_p, + componentFeatures_p, + interfaces_p, + propertyFile_p); + + componentRepId_p.parsers (string_p); + + componentFeatures_p.parsers (supportsInterface_p, + ports_p); + + supportsInterface_p.parsers (string_p, + string_p); + + ports_p.parsers (provides_p, + uses_p); + + provides_p.parsers (string_p, + portType_p, + string_p, + string_p); + + portType_p.parsers (type_p); + + uses_p.parsers (string_p, + portType_p, + string_p, + string_p); + + interfaces_p.parsers (interface_p); + + interface_p.parsers (inheritsInterface_p, + string_p, + string_p); + + inheritsInterface_p.parsers (string_p); + + propertyFile_p.parsers (localFile_p, + string_p); + + localFile_p.parsers (string_p); + + // Parse the XML document. + // + ::xml_schema::document doc_p (softwarecomponent_p, "softwarecomponent"); + + softwarecomponent_p.pre (); + doc_p.parse (input); + return (softwarecomponent_p.post_softwarecomponent ()); + } catch (const ::xml_schema::exception& e) { + throw ossie::parser_error(e.what()); + } catch (const std::ios_base::failure& e) { + throw ossie::parser_error(e.what()); + } +} diff --git a/redhawk/src/control/parser/internal/scd-parser.h b/redhawk/src/control/parser/internal/scd-parser.h index 477b0f50d..6fc4d0354 100644 --- a/redhawk/src/control/parser/internal/scd-parser.h +++ b/redhawk/src/control/parser/internal/scd-parser.h @@ -21,92 +21,14 @@ #ifndef __SCD_PARSER_H__ #define __SCD_PARSER_H__ -#include "scd-pimpl.h" -#include "ossie/exceptions.h" +#include + +#include +#include namespace ossie { namespace internalparser { - inline std::auto_ptr parseSCD(std::istream& input) throw (ossie::parser_error) - { - using namespace scd; - - try { - // Instantiate individual parsers. - // - softwarecomponent_pimpl softwarecomponent_p; - ::xml_schema::string_pimpl string_p; - componentRepId_pimpl componentRepId_p; - componentFeatures_pimpl componentFeatures_p; - supportsInterface_pimpl supportsInterface_p; - ports_pimpl ports_p; - provides_pimpl provides_p; - portType_pimpl portType_p; - type_pimpl type_p; - uses_pimpl uses_p; - interfaces_pimpl interfaces_p; - interface_pimpl interface_p; - inheritsInterface_pimpl inheritsInterface_p; - propertyFile_pimpl propertyFile_p; - localFile_pimpl localFile_p; - - // Connect the parsers together. - // - softwarecomponent_p.parsers (string_p, - componentRepId_p, - string_p, - componentFeatures_p, - interfaces_p, - propertyFile_p); - - componentRepId_p.parsers (string_p); - - componentFeatures_p.parsers (supportsInterface_p, - ports_p); - - supportsInterface_p.parsers (string_p, - string_p); - - ports_p.parsers (provides_p, - uses_p); - - provides_p.parsers (string_p, - portType_p, - string_p, - string_p); - - portType_p.parsers (type_p); - - uses_p.parsers (string_p, - portType_p, - string_p, - string_p); - - interfaces_p.parsers (interface_p); - - interface_p.parsers (inheritsInterface_p, - string_p, - string_p); - - inheritsInterface_p.parsers (string_p); - - propertyFile_p.parsers (localFile_p, - string_p); - - localFile_p.parsers (string_p); - - // Parse the XML document. - // - ::xml_schema::document doc_p (softwarecomponent_p, "softwarecomponent"); - - softwarecomponent_p.pre (); - doc_p.parse (input); - return (softwarecomponent_p.post_softwarecomponent ()); - } catch (const ::xml_schema::exception& e) { - throw ossie::parser_error(e.what()); - } catch (const std::ios_base::failure& e) { - throw ossie::parser_error(e.what()); - } - } + std::auto_ptr parseSCD(std::istream& input) throw (ossie::parser_error); } } #endif diff --git a/redhawk/src/control/parser/internal/spd-parser.cpp b/redhawk/src/control/parser/internal/spd-parser.cpp new file mode 100644 index 000000000..6b93c3610 --- /dev/null +++ b/redhawk/src/control/parser/internal/spd-parser.cpp @@ -0,0 +1,182 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK core. + * + * REDHAWK core is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +#include + +#include "spd-parser.h" +#include "spd-pimpl.h" + +std::auto_ptr ossie::internalparser::parseSPD(std::istream& input) throw (ossie::parser_error) +{ + try { + // Instantiate individual parsers. + // + ::spd::softPkg_pimpl softPkg_p; + ::xml_schema::string_pimpl string_p; + ::spd::author_pimpl author_p; + ::xml_schema::uri_pimpl uri_p; + ::spd::propertyFile_pimpl propertyFile_p; + ::spd::localFile_pimpl localFile_p; + ::spd::descriptor_pimpl descriptor_p; + ::spd::implementation_pimpl implementation_p; + ::spd::code_pimpl code_p; + ::xml_schema::unsigned_long_pimpl unsigned_long_p; + ::spd::codeFileType_pimpl codeFileType_p; + ::spd::compiler_pimpl compiler_p; + ::spd::programmingLanguage_pimpl programmingLanguage_p; + ::spd::humanLanguage_pimpl humanLanguage_p; + ::spd::runtime_pimpl runtime_p; + ::spd::os_pimpl os_p; + ::spd::processor_pimpl processor_p; + ::spd::dependency_pimpl dependency_p; + ::spd::softPkgRef_pimpl softPkgRef_p; + ::spd::implRef_pimpl implRef_p; + ::spd::propertyRef_pimpl propertyRef_p; + ::spd::usesDevice_pimpl usesDevice_p; + ::spd::aepcompliance_pimpl aepcompliance_p; + ::spd::simpleref_pimpl simpleref_p; + ::spd::simplesequenceref_pimpl simplesequenceref_p; + ::spd::structref_pimpl structref_p; + ::spd::structsequenceref_pimpl structsequenceref_p; + ::spd::values_pimpl values_p; + ::spd::structvalue_pimpl structvalue_p; + + // Connect the parsers together. + // + softPkg_p.parsers (string_p, + author_p, + string_p, + propertyFile_p, + descriptor_p, + implementation_p, + usesDevice_p, + string_p, + string_p, + string_p, + string_p); + + author_p.parsers (string_p, + string_p, + uri_p); + + propertyFile_p.parsers (localFile_p, + string_p); + + localFile_p.parsers (string_p); + + descriptor_p.parsers (localFile_p, + string_p); + + implementation_p.parsers (string_p, + propertyFile_p, + code_p, + compiler_p, + programmingLanguage_p, + humanLanguage_p, + runtime_p, + os_p, + processor_p, + dependency_p, + usesDevice_p, + string_p, + aepcompliance_p); + + code_p.parsers (localFile_p, + string_p, + unsigned_long_p, + unsigned_long_p, + codeFileType_p); + + compiler_p.parsers (string_p, + string_p); + + programmingLanguage_p.parsers (string_p, + string_p); + + humanLanguage_p.parsers (string_p); + + runtime_p.parsers (string_p, + string_p); + + os_p.parsers (string_p, + string_p); + + processor_p.parsers (string_p); + + dependency_p.parsers (softPkgRef_p, + propertyRef_p, + simpleref_p, + simplesequenceref_p, + structref_p, + structsequenceref_p, + string_p); + + softPkgRef_p.parsers (localFile_p, + implRef_p); + + implRef_p.parsers (string_p); + + propertyRef_p.parsers (string_p, + string_p); + + usesDevice_p.parsers (propertyRef_p, + simpleref_p, + simplesequenceref_p, + structref_p, + structsequenceref_p, + string_p, + string_p); + + simpleref_p.parsers (string_p, + string_p); + + simplesequenceref_p.parsers (values_p, + string_p); + + values_p.parsers (string_p); + + structref_p.parsers (simpleref_p, + simplesequenceref_p, + string_p); + + structsequenceref_p.parsers (structvalue_p, + string_p); + + structvalue_p.parsers (simpleref_p, + simplesequenceref_p); + + // Parse the XML document. + // + ::xml_schema::document doc_p ( + softPkg_p, + "", + "softpkg"); + + softPkg_p.pre (); + doc_p.parse (input); + return (softPkg_p.post_softPkg ()); + } catch (const ::xml_schema::exception& e) { + std::ostringstream err; + err << e; + throw ossie::parser_error(err.str()); + } catch (const std::ios_base::failure& e) { + throw ossie::parser_error(e.what()); + } +} diff --git a/redhawk/src/control/parser/internal/spd-parser.h b/redhawk/src/control/parser/internal/spd-parser.h index 618030cbb..3559b1fc1 100644 --- a/redhawk/src/control/parser/internal/spd-parser.h +++ b/redhawk/src/control/parser/internal/spd-parser.h @@ -21,173 +21,13 @@ #ifndef __SPD_PARSER_H__ #define __SPD_PARSER_H__ -#include -#include -#include"ossie/exceptions.h" -#include "spd-pimpl.h" - -#include +#include +#include +#include namespace ossie { namespace internalparser { - inline std::auto_ptr parseSPD(std::istream& input) throw (ossie::parser_error) { - using namespace spd; - - try { - // Instantiate individual parsers. - // - ::spd::softPkg_pimpl softPkg_p; - ::xml_schema::string_pimpl string_p; - ::spd::author_pimpl author_p; - ::xml_schema::uri_pimpl uri_p; - ::spd::propertyFile_pimpl propertyFile_p; - ::spd::localFile_pimpl localFile_p; - ::spd::descriptor_pimpl descriptor_p; - ::spd::implementation_pimpl implementation_p; - ::spd::code_pimpl code_p; - ::xml_schema::unsigned_long_pimpl unsigned_long_p; - ::spd::codeFileType_pimpl codeFileType_p; - ::spd::compiler_pimpl compiler_p; - ::spd::programmingLanguage_pimpl programmingLanguage_p; - ::spd::humanLanguage_pimpl humanLanguage_p; - ::spd::runtime_pimpl runtime_p; - ::spd::os_pimpl os_p; - ::spd::processor_pimpl processor_p; - ::spd::dependency_pimpl dependency_p; - ::spd::softPkgRef_pimpl softPkgRef_p; - ::spd::implRef_pimpl implRef_p; - ::spd::propertyRef_pimpl propertyRef_p; - ::spd::usesDevice_pimpl usesDevice_p; - ::spd::aepcompliance_pimpl aepcompliance_p; - ::spd::simpleref_pimpl simpleref_p; - ::spd::simplesequenceref_pimpl simplesequenceref_p; - ::spd::structref_pimpl structref_p; - ::spd::structsequenceref_pimpl structsequenceref_p; - ::spd::values_pimpl values_p; - ::spd::structvalue_pimpl structvalue_p; - - // Connect the parsers together. - // - softPkg_p.parsers (string_p, - author_p, - string_p, - propertyFile_p, - descriptor_p, - implementation_p, - usesDevice_p, - string_p, - string_p, - string_p, - string_p); - - author_p.parsers (string_p, - string_p, - uri_p); - - propertyFile_p.parsers (localFile_p, - string_p); - - localFile_p.parsers (string_p); - - descriptor_p.parsers (localFile_p, - string_p); - - implementation_p.parsers (string_p, - propertyFile_p, - code_p, - compiler_p, - programmingLanguage_p, - humanLanguage_p, - runtime_p, - os_p, - processor_p, - dependency_p, - usesDevice_p, - string_p, - aepcompliance_p); - - code_p.parsers (localFile_p, - string_p, - unsigned_long_p, - unsigned_long_p, - codeFileType_p); - - compiler_p.parsers (string_p, - string_p); - - programmingLanguage_p.parsers (string_p, - string_p); - - humanLanguage_p.parsers (string_p); - - runtime_p.parsers (string_p, - string_p); - - os_p.parsers (string_p, - string_p); - - processor_p.parsers (string_p); - - dependency_p.parsers (softPkgRef_p, - propertyRef_p, - simpleref_p, - simplesequenceref_p, - structref_p, - structsequenceref_p, - string_p); - - softPkgRef_p.parsers (localFile_p, - implRef_p); - - implRef_p.parsers (string_p); - - propertyRef_p.parsers (string_p, - string_p); - - usesDevice_p.parsers (propertyRef_p, - simpleref_p, - simplesequenceref_p, - structref_p, - structsequenceref_p, - string_p, - string_p); - - simpleref_p.parsers (string_p, - string_p); - - simplesequenceref_p.parsers (values_p, - string_p); - - values_p.parsers (string_p); - - structref_p.parsers (simpleref_p, - simplesequenceref_p, - string_p); - - structsequenceref_p.parsers (structvalue_p, - string_p); - - structvalue_p.parsers (simpleref_p, - simplesequenceref_p); - - // Parse the XML document. - // - ::xml_schema::document doc_p ( - softPkg_p, - "", - "softpkg"); - - softPkg_p.pre (); - doc_p.parse (input); - return (softPkg_p.post_softPkg ()); - } catch (const ::xml_schema::exception& e) { - std::ostringstream err; - err << e; - throw ossie::parser_error(err.str()); - } catch (const std::ios_base::failure& e) { - throw ossie::parser_error(e.what()); - } - } + std::auto_ptr parseSPD(std::istream& input) throw (ossie::parser_error); } } #endif From 4aab12b401c7dc40c0fb7ccf336a67a75e70dcde Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 3 Jun 2016 12:30:26 -0400 Subject: [PATCH 0348/1644] Remove empty file --- redhawk/src/control/parser/Makefile.am | 1 - redhawk/src/control/parser/debug.cpp | 19 ------------------- 2 files changed, 20 deletions(-) delete mode 100644 redhawk/src/control/parser/debug.cpp diff --git a/redhawk/src/control/parser/Makefile.am b/redhawk/src/control/parser/Makefile.am index 3327f50f0..8bc18f479 100644 --- a/redhawk/src/control/parser/Makefile.am +++ b/redhawk/src/control/parser/Makefile.am @@ -22,7 +22,6 @@ noinst_LTLIBRARIES = libossieparser.la libossieparser_la_SOURCES = Properties.cpp \ - debug.cpp \ SoftPkg.cpp \ PropertyRef.cpp \ DomainManagerConfiguration.cpp \ diff --git a/redhawk/src/control/parser/debug.cpp b/redhawk/src/control/parser/debug.cpp deleted file mode 100644 index cf682e8e5..000000000 --- a/redhawk/src/control/parser/debug.cpp +++ /dev/null @@ -1,19 +0,0 @@ -/* - * This file is protected by Copyright. Please refer to the COPYRIGHT file - * distributed with this source distribution. - * - * This file is part of REDHAWK core. - * - * REDHAWK core is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see http://www.gnu.org/licenses/. - */ From 4222b0254dba0a5e08f53e5c3a69e5b1276ef041 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 3 Jun 2016 12:56:47 -0400 Subject: [PATCH 0349/1644] Move assembly controller flag from ComponentInstantiation to ComponentDeployment --- .../src/control/include/ossie/componentProfile.h | 5 ----- redhawk/src/control/parser/SoftwareAssembly.cpp | 1 - redhawk/src/control/parser/componentProfile.cpp | 13 +------------ .../control/sdr/dommgr/ApplicationDeployment.cpp | 7 ++++--- .../control/sdr/dommgr/ApplicationFactory_impl.cpp | 4 ++-- .../src/control/sdr/dommgr/ApplicationValidator.cpp | 2 +- redhawk/src/control/sdr/dommgr/Deployment.cpp | 12 +++++++++++- redhawk/src/control/sdr/dommgr/Deployment.h | 4 ++++ 8 files changed, 23 insertions(+), 25 deletions(-) diff --git a/redhawk/src/control/include/ossie/componentProfile.h b/redhawk/src/control/include/ossie/componentProfile.h index af3e70698..bc3edef0b 100644 --- a/redhawk/src/control/include/ossie/componentProfile.h +++ b/redhawk/src/control/include/ossie/componentProfile.h @@ -203,11 +203,6 @@ namespace ossie { const std::string& getFindByNamingServiceName() const; - bool isAssemblyController() const; - void setIsAssemblyController(bool state); - - private: - bool _isAssemblyController; }; /* diff --git a/redhawk/src/control/parser/SoftwareAssembly.cpp b/redhawk/src/control/parser/SoftwareAssembly.cpp index 35c47e72c..5f045394a 100644 --- a/redhawk/src/control/parser/SoftwareAssembly.cpp +++ b/redhawk/src/control/parser/SoftwareAssembly.cpp @@ -80,7 +80,6 @@ void SoftwareAssembly::validateComponentPlacements(std::vectorassemblycontroller.empty() && _sad->assemblycontroller == instance.instantiationId) { - instance.setIsAssemblyController(true); _assemblyController = &instance; } } diff --git a/redhawk/src/control/parser/componentProfile.cpp b/redhawk/src/control/parser/componentProfile.cpp index c10bb62a7..0cda1a547 100644 --- a/redhawk/src/control/parser/componentProfile.cpp +++ b/redhawk/src/control/parser/componentProfile.cpp @@ -124,8 +124,7 @@ const std::string StructSequencePropertyRef::_asString() const { // // ComponentInstantiation // -ComponentInstantiation::ComponentInstantiation() : - _isAssemblyController(false) +ComponentInstantiation::ComponentInstantiation() { } @@ -169,16 +168,6 @@ const ComponentInstantiation::LoggingConfig &ComponentInstantiation::getLoggingC return loggingConfig; } -bool ComponentInstantiation::isAssemblyController() const -{ - return _isAssemblyController; -} - -void ComponentInstantiation::setIsAssemblyController(bool state) -{ - _isAssemblyController = state; -} - // // ComponentPlacement // diff --git a/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp b/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp index 2cd4b3eec..88f440f32 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp @@ -75,7 +75,7 @@ void ApplicationDeployment::loadProfiles(CF::FileSystem_ptr fileSystem) ComponentDeployment* ApplicationDeployment::getAssemblyController() { BOOST_FOREACH(ComponentDeployment* deployment, components) { - if (deployment->getInstantiation()->isAssemblyController()) { + if (deployment->isAssemblyController()) { return deployment; } } @@ -86,7 +86,7 @@ redhawk::PropertyMap ApplicationDeployment::getAllocationContext() const { redhawk::PropertyMap properties; BOOST_FOREACH(ComponentDeployment* deployment, components) { - if (deployment->getInstantiation()->isAssemblyController()) { + if (deployment->isAssemblyController()) { properties = deployment->getAllocationContext(); } } @@ -104,7 +104,8 @@ ComponentDeployment* ApplicationDeployment::createComponentDeployment(const Soft components.push_back(deployment); // Override properties from initial configuration - if (instantiation->isAssemblyController()) { + if (instantiation->getID() == sad.getAssemblyControllerRefId()) { + deployment->setIsAssemblyController(true); overrideAssemblyControllerProperties(deployment); } else { overrideExternalProperties(deployment); diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index a5ceef0f4..b70713a57 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -2010,7 +2010,7 @@ void createHelper::configureComponents(const DeploymentList& deployments) } else { // The component is configurable; if it's the assembly controller, // save it for the end - if (deployment->getInstantiation()->isAssemblyController()) { + if (deployment->isAssemblyController()) { ac_deployment = deployment; } else { configure_list.push_back(deployment); @@ -2157,7 +2157,7 @@ std::vector createHelper::getStartOrder(const DeploymentList& for (size_t index = 0; index < deployments.size(); ++index) { ossie::ComponentDeployment* deployment = deployments[index]; const ossie::ComponentInstantiation* instantiation = deployment->getInstantiation(); - if (instantiation->isAssemblyController()) { + if (deployment->isAssemblyController()) { LOG_TRACE(ApplicationFactory_impl, "Component " << instantiation->getID() << " is the assembly controller"); } else if (instantiation->hasStartOrder()) { diff --git a/redhawk/src/control/sdr/dommgr/ApplicationValidator.cpp b/redhawk/src/control/sdr/dommgr/ApplicationValidator.cpp index 13b880ae8..6f83ce3c0 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationValidator.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationValidator.cpp @@ -223,7 +223,7 @@ const Properties* ApplicationValidator::getAssemblyControllerProperties(const So // return its Properties BOOST_FOREACH(const ComponentPlacement& placement, sad.getAllComponents()) { BOOST_FOREACH(const ComponentInstantiation& instantiation, placement.getInstantiations()) { - if (instantiation.isAssemblyController()) { + if (instantiation.getID() == sad.getAssemblyControllerRefId()) { const SoftPkg* softpkg = cache.loadProfile(placement.filename); return softpkg->getProperties(); } diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index 2c26f23e2..a79065fdb 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -247,7 +247,7 @@ ComponentDeployment::ComponentDeployment(const SoftPkg* softpkg, SoftpkgDeployment(softpkg), instantiation(instantiation), identifier(identifier), - affinityOptions() + assemblyController(false) { // If the SoftPkg has an associated Properties, check the overrides for // validity @@ -295,6 +295,16 @@ bool ComponentDeployment::isConfigurable() const return softpkg->getDescriptor()->isConfigurable(); } +bool ComponentDeployment::isAssemblyController() const +{ + return assemblyController; +} + +void ComponentDeployment::setIsAssemblyController(bool state) +{ + assemblyController = state; +} + void ComponentDeployment::setAssignedDevice(const boost::shared_ptr& device) { assignedDevice = device; diff --git a/redhawk/src/control/sdr/dommgr/Deployment.h b/redhawk/src/control/sdr/dommgr/Deployment.h index cde8ea009..8544ae6cf 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.h +++ b/redhawk/src/control/sdr/dommgr/Deployment.h @@ -113,6 +113,9 @@ namespace ossie { bool isResource() const; bool isConfigurable() const; + bool isAssemblyController() const; + void setIsAssemblyController(bool state); + std::string getEntryPoint(); redhawk::PropertyMap getOptions(); @@ -171,6 +174,7 @@ namespace ossie { const ComponentInstantiation* instantiation; const std::string identifier; + bool assemblyController; boost::shared_ptr assignedDevice; CF::Resource_var resource; From d55017a52195694cf8413c8815bf1d1cbc93b91a Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 3 Jun 2016 15:07:47 -0400 Subject: [PATCH 0350/1644] Clean up parser makefile and use a pattern rule instead of cut-and-paste --- redhawk/src/control/parser/Makefile.am | 40 +++++++++----------------- 1 file changed, 13 insertions(+), 27 deletions(-) diff --git a/redhawk/src/control/parser/Makefile.am b/redhawk/src/control/parser/Makefile.am index 8bc18f479..8c9d1ccc4 100644 --- a/redhawk/src/control/parser/Makefile.am +++ b/redhawk/src/control/parser/Makefile.am @@ -70,42 +70,28 @@ CLEANFILES = internal/dcd-pskel.h internal/dcd-pskel.cpp \ internal/scd-pskel.h internal/scd-pskel.cpp \ internal/spd-pskel.h internal/spd-pskel.cpp -libossieparser_la_CXXFLAGS = -Wall $(STDINTF_CFLAGS) $(EXPAT_CFLAGS) $(BOOST_CPPFLAGS) -libossieparser_la_LIBADD = $(STDINTF_LIBS) $(EXPAT_LIBS) -libossieparser_la_LDFLAGS = -Wall $(EXPAT_LDFLAGS) +libossieparser_la_CXXFLAGS = -Wall $(EXPAT_CFLAGS) $(BOOST_CPPFLAGS) +libossieparser_la_LIBADD = $(EXPAT_LIBS) +libossieparser_la_LDFLAGS = $(EXPAT_LDFLAGS) AM_CPPFLAGS = -I../include -I. -I$(top_srcdir)/base/include XSDFLAGS = --hxx-suffix .h --cxx-suffix .cpp --xml-parser expat --output-dir internal $(OSSIE_XSDFLAGS) -internal/dmd-pskel.cpp: $(top_srcdir)/xml/xsd/dmd.xsd internal/dmd.map -# We need to keep xmlns items in the XSD, but we have to remove them from validation - -$(XSD) cxx-parser --root-element domainmanagerconfiguration --type-map internal/dmd.map $(XSDFLAGS) $<; sed -i 's/ns == "urn:mil:jpeojtrs:sca:dmd"/ns.empty()/g' internal/dmd-pskel.cpp; sed -i 's/"urn:mil:jpeojtrs:sca:dmd"/""/g' internal/dmd-pskel.cpp - -internal/dcd-pskel.cpp: $(top_srcdir)/xml/xsd/dcd.xsd internal/dcd.map -# We need to keep xmlns items in the XSD, but we have to remove them from validation - -$(XSD) cxx-parser --root-element deviceconfiguration --type-map internal/dcd.map $(XSDFLAGS) $<; sed -i 's/ns == "urn:mil:jpeojtrs:sca:dcd"/ns.empty()/g' internal/dcd-pskel.cpp; sed -i 's/"urn:mil:jpeojtrs:sca:dcd"/""/g' internal/dcd-pskel.cpp - -internal/spd-pskel.cpp: $(top_srcdir)/xml/xsd/spd.xsd internal/spd.map -# We need to keep xmlns items in the XSD, but we have to remove them from validation - -$(XSD) cxx-parser --root-element softpkg --type-map internal/spd.map $(XSDFLAGS) $<; sed -i 's/ns == "urn:mil:jpeojtrs:sca:spd"/ns.empty()/g' internal/spd-pskel.cpp; sed -i 's/"urn:mil:jpeojtrs:sca:spd"/""/g' internal/spd-pskel.cpp - -internal/scd-pskel.cpp: $(top_srcdir)/xml/xsd/scd.xsd internal/scd.map - -$(XSD) cxx-parser --root-element softwarecomponent --type-map internal/scd.map $(XSDFLAGS) $<; sed -i 's/ns == "urn:mil:jpeojtrs:sca:scd"/ns.empty()/g' internal/scd-pskel.cpp; sed -i 's/"urn:mil:jpeojtrs:sca:scd"/""/g' internal/scd-pskel.cpp - -internal/sad-pskel.cpp: $(top_srcdir)/xml/xsd/sad.xsd internal/sad.map -# We need to keep xmlns items in the XSD, but we have to remove them from validation - -$(XSD) cxx-parser --root-element softwareassembly --type-map internal/sad.map $(XSDFLAGS) $<; sed -i 's/ns == "urn:mil:jpeojtrs:sca:sad"/ns.empty()/g' internal/sad-pskel.cpp; sed -i 's/"urn:mil:jpeojtrs:sca:sad"/""/g' internal/sad-pskel.cpp - -internal/prf-pskel.cpp: $(top_srcdir)/xml/xsd/prf.xsd internal/prf.map -# We need to keep xmlns items in the XSD, but we have to remove them from validation - -$(XSD) cxx-parser --root-element properties --type-map internal/prf.map $(XSDFLAGS) $<; sed -i 's/ns == "urn:mil:jpeojtrs:sca:prf"/ns.empty()/g' internal/prf-pskel.cpp; sed -i 's/"urn:mil:jpeojtrs:sca:prf"/""/g' internal/prf-pskel.cpp +# Pattern rule to generate *-pskel files using the corresponding .xsd and .map +# files. We need to keep xmlns items in the XSD, but we have to remove them +# from the generated parser's validation (this is what the sed command is for). +internal/%-pskel.cpp: $(top_srcdir)/xml/xsd/%.xsd internal/%.map + $(AM_V_GEN)$(XSD) cxx-parser --type-map internal/$*.map $(XSDFLAGS) $< + $(AM_V_at)$(SED) -i 's/ns == "urn:mil:jpeojtrs:sca:$*"/ns.empty()/g' $@ + $(AM_V_at)$(SED) -i 's/"urn:mil:jpeojtrs:sca:$*"/""/g' $@ +# The DPD and profile parsers aren't used by the framework internal/dpd-pskel.cpp: $(top_srcdir)/xml/xsd/dpd.xsd - -$(XSD) cxx-parser --root-element devicepkg $(XSDFLAGS) $< + $(AM_V_GEN)$(XSD) cxx-parser --root-element devicepkg $(XSDFLAGS) $< internal/profile-pskel.cpp: $(top_srcdir)/xml/xsd/profile.xsd - -$(XSD) cxx-parser --root-element profile $(XSDFLAGS) $< + $(AM_V_GEN)$(XSD) cxx-parser --root-element profile $(XSDFLAGS) $< .PHONY: generate_noop_impl generate_test_driver From cbe0a4612ea5e8b0ddcd8b115f2810a5f1eaf780 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 3 Jun 2016 15:49:35 -0400 Subject: [PATCH 0351/1644] More exact checking of profile filenames in validation, now including PRF and SCD --- .../sdr/dommgr/ApplicationValidator.cpp | 31 ++++++++++++++++--- .../control/sdr/dommgr/ApplicationValidator.h | 2 +- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationValidator.cpp b/redhawk/src/control/sdr/dommgr/ApplicationValidator.cpp index 6f83ce3c0..17b0b7e34 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationValidator.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationValidator.cpp @@ -117,10 +117,12 @@ void ApplicationValidator::validateSoftPkgRef(const SPD::SoftPkgRef& softpkgref) // Basic checking for valid, existing filename LOG_TRACE(ApplicationValidator, "Validating SPD " << spd_file); - checkFilename(spd_file); if (!fileExists(spd_file)) { throw std::runtime_error("softpkgref " + spd_file + " does not exist"); } + if (!endsWith(spd_file, ".spd.xml")) { + LOG_WARN(ApplicationValidator, "SPD file " << spd_file << " should end with .spd.xml"); + } // If this fails, it will throw redhawk::invalid_profile const SoftPkg* softpkg = cache.loadSoftPkg(spd_file); @@ -197,14 +199,30 @@ void ApplicationValidator::validateComponentPlacement(const ComponentPlacement& // Basic checking for valid, existing filename LOG_TRACE(ApplicationValidator, "Validating SPD " << spd_file); - checkFilename(spd_file); if (!fileExists(spd_file)) { throw validation_error("componentfile " + placement._componentFileRef + " points to non-existent file " + spd_file); } + if (!endsWith(spd_file, ".spd.xml")) { + LOG_WARN(ApplicationValidator, "SPD file " << spd_file << " should end with .spd.xml"); + } // If this fails, it will throw redhawk::invalid_profile const SoftPkg* softpkg = cache.loadProfile(spd_file); + // Check the PRF and SCD filenames + if (softpkg->getPRFFile()) { + std::string prf_file = softpkg->getPRFFile(); + if (!endsWith(prf_file, ".prf.xml")) { + LOG_WARN(ApplicationValidator, "PRF file " << prf_file << " should end with .prf.xml"); + } + } + if (softpkg->getSCDFile()) { + std::string scd_file = softpkg->getSCDFile(); + if (!endsWith(scd_file, ".scd.xml")) { + LOG_WARN(ApplicationValidator, "SCD file " << scd_file << " should end with .scd.xml"); + } + } + BOOST_FOREACH(const SPD::Implementation& implementation, softpkg->getImplementations()) { validateImplementation(softpkg, implementation, true); } @@ -245,9 +263,12 @@ bool ApplicationValidator::fileExists(const std::string& filename) } } -void ApplicationValidator::checkFilename(const std::string& filename) +bool ApplicationValidator::endsWith(const std::string& filename, const std::string& suffix) { - if (filename.find(".spd.xml") == std::string::npos) { - LOG_WARN(ApplicationValidator, "SPD file " << filename << " should end with .spd.xml"); + if (filename.size() < suffix.size()) { + return false; } + // Compare the end of the filename to the entirety of the suffix + std::string::size_type start = filename.size() - suffix.size(); + return filename.compare(start, suffix.size(), suffix) == 0; } diff --git a/redhawk/src/control/sdr/dommgr/ApplicationValidator.h b/redhawk/src/control/sdr/dommgr/ApplicationValidator.h index 3866f8858..549d6bedd 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationValidator.h +++ b/redhawk/src/control/sdr/dommgr/ApplicationValidator.h @@ -79,7 +79,7 @@ namespace redhawk { const ossie::Properties* getAssemblyControllerProperties(const ossie::SoftwareAssembly& sad); - void checkFilename(const std::string& filename); + bool endsWith(const std::string& filename, const std::string& suffix); bool fileExists(const std::string& filename); CF::FileSystem_var fileSystem; From 8738e477e5af0ab6b44a354b083c6f78b3951b60 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 3 Jun 2016 16:01:10 -0400 Subject: [PATCH 0352/1644] Restore old logging statements for uses device lookup --- .../src/control/sdr/dommgr/ApplicationDeployment.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp b/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp index 88f440f32..468c6d3ca 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp @@ -306,8 +306,10 @@ CF::Device_ptr ApplicationDeployment::lookupDeviceUsedByComponentInstantiationId return CF::Device::_nil(); } - //LOG_TRACE(ApplicationDeployment, "[DeviceLookup] Assigned device id " << deviceId); - return uses->getAssignedDevice(); + CF::Device_var device = uses->getAssignedDevice(); + LOG_TRACE(ApplicationDeployment, "[DeviceLookup] Assigned device id " + << ossie::corba::returnString(device->identifier())); + return device._retn(); } CF::Device_ptr ApplicationDeployment::lookupDeviceUsedByApplication(const std::string& usesRefId) @@ -320,6 +322,8 @@ CF::Device_ptr ApplicationDeployment::lookupDeviceUsedByApplication(const std::s return CF::Device::_nil(); } - //LOG_TRACE(ApplicationDeployment, "[DeviceLookup] Assigned device id " << deviceId); - return uses->getAssignedDevice(); + CF::Device_var device = uses->getAssignedDevice(); + LOG_TRACE(ApplicationDeployment, "[DeviceLookup] Assigned device id " + << ossie::corba::returnString(device->identifier())); + return device._retn(); } From 96896bbc137eda91c51226526ae3d8426857f0ae Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 3 Jun 2016 16:14:24 -0400 Subject: [PATCH 0353/1644] Use ProfileCache class instead of similar code in ApplicationDeployment --- .../sdr/dommgr/ApplicationDeployment.cpp | 97 ++----------------- .../sdr/dommgr/ApplicationDeployment.h | 13 --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 8 +- redhawk/src/control/sdr/dommgr/createHelper.h | 3 + 4 files changed, 13 insertions(+), 108 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp b/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp index 468c6d3ca..83f9697ce 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp @@ -57,21 +57,6 @@ const std::string& ApplicationDeployment::getIdentifier() const return identifier; } -void ApplicationDeployment::loadProfiles(CF::FileSystem_ptr fileSystem) -{ - // Walk through the host collocations first - BOOST_FOREACH(const SoftwareAssembly::HostCollocation& collocation, sad.getHostCollocations()) { - BOOST_FOREACH(const ComponentPlacement& placement, collocation.getComponents()) { - loadComponentProfile(fileSystem, placement); - } - } - - // Then, walk through the remaining non-collocated components - BOOST_FOREACH(const ComponentPlacement& placement, sad.getComponentPlacements()) { - loadComponentProfile(fileSystem, placement); - } -} - ComponentDeployment* ApplicationDeployment::getAssemblyController() { BOOST_FOREACH(ComponentDeployment* deployment, components) { @@ -100,6 +85,12 @@ ComponentDeployment* ApplicationDeployment::createComponentDeployment(const Soft // application instance's unique name std::string component_id = instantiation->getID() + ":" + instanceName; + if (softpkg->isScaCompliant() && !instantiation->isNamingService()) { + LOG_WARN(ApplicationDeployment, "Component instantiation " + << instantiation->getID() << " does not provide a 'findcomponent' name but " + << softpkg->getName() << " is SCA-compliant"); + } + ComponentDeployment* deployment = new ComponentDeployment(softpkg, instantiation, component_id); components.push_back(deployment); @@ -184,82 +175,6 @@ void ApplicationDeployment::overrideExternalProperties(ComponentDeployment* depl } } - -const SoftPkg* ApplicationDeployment::getSoftPkg(const std::string& filename) const -{ - BOOST_FOREACH(const SoftPkg& softpkg, profiles) { - if (softpkg.getSPDFile() == filename) { - return &softpkg; - } - } - - throw std::logic_error(filename + " was never loaded"); -} - -void ApplicationDeployment::loadComponentProfile(CF::FileSystem_ptr fileSystem, - const ComponentPlacement& placement) -{ - SoftPkg* softpkg = loadProfile(fileSystem, placement.filename); - if (softpkg->isScaCompliant()){ - BOOST_FOREACH(const ComponentInstantiation& instantiation, placement.getInstantiations()) { - if (!instantiation.isNamingService()) { - LOG_WARN(ApplicationDeployment, "Component instantiation " - << instantiation.getID() << " does not provide a 'findcomponent' name but " - << softpkg->getName() << " is SCA-compliant"); - } - } - } - - if (softpkg->getPRFFile()) { - LOG_TRACE(ApplicationDeployment, "Loading PRF file " << softpkg->getPRFFile()); - try { - File_stream prf_stream(fileSystem, softpkg->getPRFFile()); - softpkg->loadProperties(prf_stream); - } catch (const std::exception& exc) { - LOG_ERROR(ApplicationDeployment, "Invalid PRF file " << softpkg->getPRFFile() << ": " << exc.what()); - } - } - - if (softpkg->getSCDFile()) { - LOG_TRACE(ApplicationDeployment, "Loading SCD file " << softpkg->getSCDFile()); - try { - File_stream scd_stream(fileSystem, softpkg->getSCDFile()); - softpkg->loadDescriptor(scd_stream); - } catch (const std::exception& exc) { - LOG_ERROR(ApplicationDeployment, "Invalid SCD file " << softpkg->getSCDFile() << ": " << exc.what()); - } - } -} - -SoftPkg* ApplicationDeployment::loadProfile(CF::FileSystem_ptr fileSystem, - const std::string& filename) -{ - BOOST_FOREACH(SoftPkg& profile, profiles) { - if (profile.getSPDFile() == filename) { - LOG_TRACE(ApplicationDeployment, "Found existing profile " << filename); - return &profile; - } - } - - LOG_TRACE(ApplicationDeployment, "Loading SPD file " << filename); - File_stream spd_stream(fileSystem, filename.c_str()); - SoftPkg* spd = new SoftPkg(spd_stream, filename); - profiles.push_back(spd); - spd_stream.close(); - - const SPD::Implementations& spd_impls = spd->getImplementations(); - for (SPD::Implementations::const_iterator impl = spd_impls.begin(); impl != spd_impls.end(); ++impl) { - const SPD::SoftPkgDependencies& deps = impl->getSoftPkgDependencies(); - for (SPD::SoftPkgDependencies::const_iterator dep = deps.begin(); dep != deps.end(); ++dep) { - SPD::SoftPkgRef& ref = const_cast(*dep); - LOG_TRACE(ApplicationDeployment, "Resolving soft package reference " << ref.localfile); - loadProfile(fileSystem, ref.localfile); - } - } - - return spd; -} - CF::Resource_ptr ApplicationDeployment::lookupComponentByInstantiationId(const std::string& identifier) { ComponentDeployment* deployment = getComponentDeployment(identifier); diff --git a/redhawk/src/control/sdr/dommgr/ApplicationDeployment.h b/redhawk/src/control/sdr/dommgr/ApplicationDeployment.h index c6c34c18a..78d7eeab6 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationDeployment.h +++ b/redhawk/src/control/sdr/dommgr/ApplicationDeployment.h @@ -25,7 +25,6 @@ #include #include -#include #include #include @@ -49,12 +48,8 @@ namespace ossie { const CF::Properties& initConfiguration); ~ApplicationDeployment(); - void loadProfiles(CF::FileSystem_ptr fileSystem); - const std::string& getIdentifier() const; - const SoftPkg* getSoftPkg(const std::string& filename) const; - /** * Returns the properties used for evaluating math statements in * allocation @@ -83,13 +78,6 @@ namespace ossie { CF::Device_ptr lookupDeviceUsedByApplication(const std::string& usesRefId); protected: - typedef boost::ptr_vector ProfileList; - - void loadComponentProfile(CF::FileSystem_ptr fileSystem, - const ComponentPlacement& placement); - - SoftPkg* loadProfile(CF::FileSystem_ptr fileSystem, const std::string& filename); - void overrideAssemblyControllerProperties(ComponentDeployment* deployment); void overrideExternalProperties(ComponentDeployment* deployment); @@ -97,7 +85,6 @@ namespace ossie { const std::string identifier; const std::string instanceName; redhawk::PropertyMap initConfiguration; - ProfileList profiles; ComponentList components; }; } diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index b70713a57..cb3c01a31 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -273,7 +273,7 @@ void createHelper::assignPlacementsToDevices(ossie::ApplicationDeployment& appDe // Place the remaining components one-by-one BOOST_FOREACH(const ComponentPlacement& placement, _appFact._sadParser.getComponentPlacements()) { - const SoftPkg* softpkg = appDeployment.getSoftPkg(placement.filename); + const SoftPkg* softpkg = _profileCache.loadProfile(placement.filename); BOOST_FOREACH(const ComponentInstantiation& instantiation, placement.getInstantiations()) { // Even though the XML supports more than one instantiation per // component placement, the tooling doesn't support that, so this @@ -445,7 +445,7 @@ void createHelper::_placeHostCollocation(ossie::ApplicationDeployment& appDeploy DeviceIDList assignedDevices; DeploymentList deployments; BOOST_FOREACH(const ComponentPlacement& placement, collocation.getComponents()) { - const SoftPkg* softpkg = appDeployment.getSoftPkg(placement.filename); + const SoftPkg* softpkg = _profileCache.loadProfile(placement.filename); BOOST_FOREACH(const ComponentInstantiation& instantiation, placement.getInstantiations()) { // Even though the XML supports more than one instantiation per // component placement, the tooling doesn't support that, so this @@ -795,7 +795,6 @@ CF::Application_ptr createHelper::create ( ////////////////////////////////////////////////// // Load the components to instantiate from the SAD ossie::ApplicationDeployment app_deployment(_appFact._sadParser, _waveformContextName, modifiedInitConfiguration); - app_deployment.loadProfiles(_appFact._fileMgr); //////////////////////////////////////////////// // Assign components to devices @@ -1368,7 +1367,7 @@ ossie::SoftpkgDeployment* createHelper::resolveDependencyImplementation(ossie::A ossie::DeviceNode& device) { LOG_TRACE(ApplicationFactory_impl, "Resolving dependency " << ref); - const SoftPkg* softpkg = appDeployment.getSoftPkg(ref.localfile); + const SoftPkg* softpkg = _profileCache.loadSoftPkg(ref.localfile); const SPD::Implementations& spd_list = softpkg->getImplementations(); for (size_t implCount = 0; implCount < spd_list.size(); implCount++) { @@ -2192,6 +2191,7 @@ createHelper::createHelper ( _baseNamingContext(baseNamingContext), _waveformContext(CosNaming::NamingContext::_duplicate(waveformContext)), _domainContext(domainContext), + _profileCache(_appFact._fileMgr), _isComplete(false), _application(0) { diff --git a/redhawk/src/control/sdr/dommgr/createHelper.h b/redhawk/src/control/sdr/dommgr/createHelper.h index 631fe926e..feb6fbdcb 100644 --- a/redhawk/src/control/sdr/dommgr/createHelper.h +++ b/redhawk/src/control/sdr/dommgr/createHelper.h @@ -29,6 +29,7 @@ #include "PersistenceStore.h" #include "ApplicationDeployment.h" +#include "ProfileCache.h" class Application_impl; class AllocationManager_impl; @@ -93,6 +94,8 @@ class createHelper CosNaming::NamingContext_var _waveformContext; CosNaming::NamingContext_ptr _domainContext; + redhawk::ProfileCache _profileCache; + typedef std::vector DeploymentList; typedef std::vector ProcessorList; typedef std::vector OSList; From 5cd6b8d0ab8530b271924aba2be46c23f3f878d9 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 6 Jun 2016 11:01:48 -0400 Subject: [PATCH 0354/1644] Add stream output operator for PropertyMap, implementing toString() in terms of that --- redhawk/src/base/framework/PropertyMap.cpp | 10 ++++++++-- redhawk/src/base/include/ossie/PropertyMap.h | 1 + 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/redhawk/src/base/framework/PropertyMap.cpp b/redhawk/src/base/framework/PropertyMap.cpp index 14d318471..817e0de84 100644 --- a/redhawk/src/base/framework/PropertyMap.cpp +++ b/redhawk/src/base/framework/PropertyMap.cpp @@ -185,9 +185,15 @@ void PropertyMap::erase(iterator first, iterator last) std::string PropertyMap::toString() const { std::ostringstream out; + out << *this; + return out.str(); +} + +std::ostream& redhawk::operator<<(std::ostream& out, const redhawk::PropertyMap& properties) +{ out << "{"; bool first = true; - for (const_iterator prop = begin(); prop != end(); ++prop) { + for (PropertyMap::const_iterator prop = properties.begin(); prop != properties.end(); ++prop) { if (!first) { out << ", "; } @@ -195,5 +201,5 @@ std::string PropertyMap::toString() const out << prop->getId() << "=" << prop->getValue().toString(); } out << "}"; - return out.str(); + return out; } diff --git a/redhawk/src/base/include/ossie/PropertyMap.h b/redhawk/src/base/include/ossie/PropertyMap.h index 8261609c1..195928495 100644 --- a/redhawk/src/base/include/ossie/PropertyMap.h +++ b/redhawk/src/base/include/ossie/PropertyMap.h @@ -82,6 +82,7 @@ namespace redhawk { std::string toString() const; }; + std::ostream& operator<<(std::ostream& out, const PropertyMap& properties); } #endif // REDHAWK_PROPERTYMAP_H From 1672ac12a5607f8acbe829b8d82288cfe93e3d5d Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 6 Jun 2016 11:29:41 -0400 Subject: [PATCH 0355/1644] Move responsibility for initial configure call to ComponentDeployment, and streamline exception handling --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 131 +++--------------- redhawk/src/control/sdr/dommgr/Deployment.cpp | 57 ++++++++ redhawk/src/control/sdr/dommgr/Deployment.h | 48 +++++++ redhawk/src/control/sdr/dommgr/createHelper.h | 1 - 4 files changed, 122 insertions(+), 115 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index cb3c01a31..c5062d98a 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -250,18 +250,6 @@ void createHelper::_connectComponents(ossie::ApplicationDeployment& appDeploymen "Connecting components failed (unclear where this occurred)")); } -void createHelper::_configureComponents(const DeploymentList& deployments) -{ - try{ - configureComponents(deployments); - } catch (CF::ApplicationFactory::CreateApplicationError& ex) { - throw; - } CATCH_THROW_LOG_TRACE( - ApplicationFactory_impl, - "Configure on component failed (unclear where in the process this occurred)", - CF::ApplicationFactory::CreateApplicationError(CF::CF_EINVAL, "Configure of component failed (unclear where in the process this occurred)")) -} - void createHelper::assignPlacementsToDevices(ossie::ApplicationDeployment& appDeployment, const DeviceAssignmentMap& devices) { @@ -852,7 +840,18 @@ CF::Application_ptr createHelper::create ( } _connectComponents(app_deployment, connections); - _configureComponents(app_deployment.getComponentDeployments()); + try { + configureComponents(app_deployment.getComponentDeployments()); + } catch (const ossie::configure_error& exc) { + // Unfortunately, InvalidInitConfiguration does not include an error + // message, so log the error here to give more details + std::ostringstream eout; + LOG_ERROR(ApplicationFactory_impl, "Configure of component " << exc.deployment()->getIdentifier() + << " failed with " << exc.what() << " " << exc.properties()); + throw CF::ApplicationFactory::InvalidInitConfiguration(exc.properties()); + } catch (const std::exception& exc) { + throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EINVAL, exc.what()); + } setUpExternalPorts(app_deployment, _application); setUpExternalProperties(app_deployment, _application); @@ -1995,115 +1994,19 @@ void createHelper::initializeComponents(const DeploymentList& deployments) void createHelper::configureComponents(const DeploymentList& deployments) { - DeploymentList configure_list; ossie::ComponentDeployment* ac_deployment = 0; for (DeploymentList::const_iterator depl = deployments.begin(); depl != deployments.end(); ++depl) { ossie::ComponentDeployment* deployment = (*depl); - if (!deployment->getSoftPkg()->isScaCompliant()) { - // If the component is non-SCA compliant then we don't expect anything beyond this - LOG_TRACE(ApplicationFactory_impl, "Skipping configure of non SCA-compliant component " - << deployment->getIdentifier()); - } else if (!deployment->isResource()) { - LOG_TRACE(ApplicationFactory_impl, "Skipping configure of non-resource component " - << deployment->getIdentifier()); + if (deployment->isAssemblyController()) { + ac_deployment = deployment; } else { - // The component is configurable; if it's the assembly controller, - // save it for the end - if (deployment->isAssemblyController()) { - ac_deployment = deployment; - } else { - configure_list.push_back(deployment); - } + deployment->configure(); } } + // Configure the assembly controller last, if it's configurable if (ac_deployment) { - configure_list.push_back(ac_deployment); - } - - for (DeploymentList::iterator depl = configure_list.begin(); depl != configure_list.end(); ++depl) { - ossie::ComponentDeployment* deployment = *depl; - const ossie::SoftPkg* softpkg = deployment->getSoftPkg(); - - // Assuming 1 instantiation for each componentplacement - if (deployment->getInstantiation()->isNamingService()) { - - CF::Resource_var _rsc = deployment->getResourcePtr(); - - if (CORBA::is_nil(_rsc)) { - LOG_ERROR(ApplicationFactory_impl, "Could not get component reference"); - ostringstream eout; - std::string component_version(component->spd.getSoftPkgType()); - std::string added_message = this->createVersionMismatchMessage(component_version); - eout << added_message; - eout << "Could not get component reference for component: '" - << softpkg->getName() << "' with component id: '" - << deployment->getIdentifier() << " assigned to device: '" - << deployment->getAssignedDevice()->identifier<<"'"; - eout << " in waveform '" << _waveformContextName<<"';"; - eout << " error occurred near line:" <<__LINE__ << " in file:" << __FILE__ << ";"; - throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EIO, eout.str().c_str()); - } - - redhawk::PropertyMap config_props = deployment->getInitialConfigureProperties(); - CF::Properties partialStruct = ossie::getPartialStructs(config_props); - bool partialWarn = false; - if (partialStruct.length() != 0) { - ostringstream eout; - eout << "Component " << deployment->getIdentifier() << " contains structure"<< partialStruct[0].id <<" with a mix of defined and nil values. The behavior for the component is undefined"; - LOG_WARN(ApplicationFactory_impl, eout.str()); - partialWarn = true; - } - try { - // try to configure the component - _rsc->configure(config_props); - } catch(CF::PropertySet::InvalidConfiguration& e) { - ostringstream eout; - eout << "Failed to 'configure' component: '"; - eout << softpkg->getName() << "' with component id: '" << deployment->getIdentifier() << " assigned to device: '"<getAssignedDevice()->identifier << "' "; - eout << " in waveform '"<< _waveformContextName<<"';"; - eout << "InvalidConfiguration with this info: <"; - eout << e.msg << "> for these invalid properties: "; - for (unsigned int propIdx = 0; propIdx < e.invalidProperties.length(); propIdx++){ - eout << "(" << e.invalidProperties[propIdx].id << ","; - eout << ossie::any_to_string(e.invalidProperties[propIdx].value) << ")"; - } - if (partialWarn) { - eout << ". Note that this component contains a property with a mix of defined and nil values."; - } - eout << " error occurred near line:" <<__LINE__ << " in file:" << __FILE__ << ";"; - LOG_ERROR(ApplicationFactory_impl, eout.str()); - throw CF::ApplicationFactory::InvalidInitConfiguration(e.invalidProperties); - } catch(CF::PropertySet::PartialConfiguration& e) { - ostringstream eout; - eout << "Failed to instantiate component: '"; - eout << softpkg->getName() << "' with component id: '" << deployment->getIdentifier() << " assigned to device: '"<getAssignedDevice()->identifier << "' "; - eout << " in waveform '"<< _waveformContextName<<"';"; - eout << "Failed to 'configure' component; PartialConfiguration for these invalid properties: "; - for (unsigned int propIdx = 0; propIdx < e.invalidProperties.length(); propIdx++){ - eout << "(" << e.invalidProperties[propIdx].id << ","; - eout << ossie::any_to_string(e.invalidProperties[propIdx].value) << ")"; - } - if (partialWarn) { - eout << ". Note that this component contains a property with a mix of defined and nil values."; - } - eout << " error occurred near line:" <<__LINE__ << " in file:" << __FILE__ << ";"; - LOG_ERROR(ApplicationFactory_impl, eout.str()); - throw CF::ApplicationFactory::InvalidInitConfiguration(e.invalidProperties); - } catch( ... ) { - ostringstream eout; - eout << "Failed to instantiate component: '"; - eout << softpkg->getName() << "' with component id: '" << deployment->getIdentifier() << " assigned to device: '"<< deployment->getAssignedDevice()->identifier << "' "; - eout << " in waveform '"<< _waveformContextName<<"';"; - eout << "'configure' failed with Unknown Exception"; - if (partialWarn) { - eout << ". Note that this component contains a property with a mix of defined and nil values."; - } - eout << " error occurred near line:" <<__LINE__ << " in file:" << __FILE__ << ";"; - LOG_ERROR(ApplicationFactory_impl, eout.str()); - throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EINVAL, eout.str().c_str()); - } - } + ac_deployment->configure(); } } diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index a79065fdb..d78e20aa1 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -590,3 +590,60 @@ std::string ComponentDeployment::getLoggingConfiguration() const return std::string(); } + +void ComponentDeployment::configure() +{ + if (!softpkg->isScaCompliant()) { + // If the component is non-SCA compliant then we don't expect anything beyond this + RH_NL_TRACE("ApplicationFactory_impl", "Skipping configure of non SCA-compliant component " + << identifier); + return; + } else if (!isResource()) { + RH_NL_TRACE("ApplicationFactory_impl", "Skipping configure of non-resource component " + << identifier); + return; + } + + if (!instantiation->isNamingService()) { + // Per the old code, we only configure if the instantiation uses naming + // service to locate the component + return; + } + + if (CORBA::is_nil(resource)) { + // NB: I think having a valid CORBA reference is a pre-condition of + // getting to this point in the first place + RH_NL_ERROR("ApplicationFactory_impl", "Could not get component reference"); + throw std::runtime_error("Could not get component reference for component " + identifier); + } + + redhawk::PropertyMap config_props = getInitialConfigureProperties(); + + // Check and warn for partial structs + CF::Properties partials = ossie::getPartialStructs(config_props); + if (partials.length() > 0) { + std::ostringstream eout; + eout << "Component " << identifier << " contains " << partials.length() + << "structure(s) with a mix of defined and nil values: "; + bool first = true; + for (int index = 0; index < partials.length(); ++index) { + if (!first) { + eout << ", "; + } + eout << partials[index].id; + } + eout << ". The behavior for the component is undefined"; + RH_NL_WARN("ApplicationFactory_impl", eout.str()); + } + + try { + RH_NL_TRACE("ApplicationFactory_impl", "Configuring component " << identifier); + resource->configure(config_props); + } catch (const CF::PropertySet::InvalidConfiguration& ic) { + throw configure_error(this, ic.invalidProperties, "invalid configuration"); + } catch (const CF::PropertySet::PartialConfiguration& pc) { + throw configure_error(this, pc.invalidProperties, "partial configuration"); + } catch (...) { + throw std::runtime_error("unable to configure component " + identifier); + } +} diff --git a/redhawk/src/control/sdr/dommgr/Deployment.h b/redhawk/src/control/sdr/dommgr/Deployment.h index 8544ae6cf..52c8e6685 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.h +++ b/redhawk/src/control/sdr/dommgr/Deployment.h @@ -33,6 +33,52 @@ class Application_impl; namespace ossie { + class ComponentDeployment; + + class deployment_error : public std::runtime_error { + public: + deployment_error(const ComponentDeployment* deployment, const std::string& message) : + std::runtime_error(message), + _deployment(deployment) + { + } + + virtual ~deployment_error() throw () + { + } + + const ComponentDeployment* deployment() const + { + return _deployment; + } + + private: + const ComponentDeployment* _deployment; + }; + + class configure_error : public deployment_error { + public: + configure_error(const ComponentDeployment* deployment, + const CF::Properties& properties, + const std::string& message) : + deployment_error(deployment, message), + _properties(properties) + { + } + + virtual ~configure_error() throw () + { + } + + const redhawk::PropertyMap& properties() const + { + return _properties; + } + + private: + const redhawk::PropertyMap _properties; + }; + class UsesDeviceAssignment { public: @@ -168,6 +214,8 @@ namespace ossie { std::string getLoggingConfiguration() const; + void configure(); + protected: CF::DataType getPropertyValue(const Property* property) const; const ComponentProperty* getPropertyOverride(const std::string& id) const; diff --git a/redhawk/src/control/sdr/dommgr/createHelper.h b/redhawk/src/control/sdr/dommgr/createHelper.h index feb6fbdcb..3257fcf7d 100644 --- a/redhawk/src/control/sdr/dommgr/createHelper.h +++ b/redhawk/src/control/sdr/dommgr/createHelper.h @@ -106,7 +106,6 @@ class createHelper void _validateDAS(ossie::ApplicationDeployment& appDeployment, const DeviceAssignmentMap& deviceAssignments); void _connectComponents(ossie::ApplicationDeployment& appDeployment, std::vector& connections); - void _configureComponents(const DeploymentList& deployments); void setUpExternalPorts(ossie::ApplicationDeployment& appDeployment, Application_impl* application); void setUpExternalProperties(ossie::ApplicationDeployment& appDeployment, Application_impl* application); void _placeHostCollocation(ossie::ApplicationDeployment& appDeployment, From b21a2ff1cdd8ef9b0dd73a0849f2d4b56a2338e8 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 6 Jun 2016 11:58:54 -0400 Subject: [PATCH 0356/1644] Move responsibility for property initialization and initialize call to ComponentDeployment, and streamline exception handling --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 103 +++--------------- redhawk/src/control/sdr/dommgr/Deployment.cpp | 68 +++++++++++- redhawk/src/control/sdr/dommgr/Deployment.h | 4 + 3 files changed, 85 insertions(+), 90 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index c5062d98a..c5bdac078 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -822,7 +822,20 @@ CF::Application_ptr createHelper::create ( CF::ApplicationRegistrar_var app_reg = _application->appReg(); loadAndExecuteComponents(app_deployment.getComponentDeployments(), app_reg); waitForComponentRegistration(app_deployment.getComponentDeployments()); - initializeComponents(app_deployment.getComponentDeployments()); + + try { + initializeComponents(app_deployment.getComponentDeployments()); + } catch (const ossie::configure_error& exc) { + // Unfortunately, InvalidInitConfiguration does not include an error + // message, so log the error here to give more details + std::ostringstream eout; + LOG_ERROR(ApplicationFactory_impl, "Property initialization of component " + << exc.deployment()->getIdentifier() + << " failed with " << exc.what() << " " << exc.properties()); + throw CF::ApplicationFactory::InvalidInitConfiguration(exc.properties()); + } catch (const std::exception& exc) { + throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EINVAL, exc.what()); + } // Check that the assembly controller is valid LOG_TRACE(ApplicationFactory_impl, "Checking assembly controller"); @@ -1902,93 +1915,7 @@ void createHelper::initializeComponents(const DeploymentList& deployments) usleep(1000); } - - // - // call resource's initializeProperties method to handle any properties required for construction - // - LOG_DEBUG(ApplicationFactory_impl, "Initialize properties for component " << componentId); - if (deployment->isResource() && deployment->isConfigurable()) { - redhawk::PropertyMap initProps = deployment->getInitializeProperties(); - CF::Properties partialStruct = ossie::getPartialStructs(initProps); - if (partialStruct.length() != 0) { - ostringstream eout; - eout << "Failed to 'configure' Assembly Controller: '"; - eout << softpkg->getName() << "' with component id: '" << deployment->getIdentifier() << " assigned to device: '"<< deployment->getAssignedDevice()->identifier << "' "; - eout << " in waveform '"<< _waveformContextName<<"';"; - eout << "This component contains structure"<initializeProperties(initProps); - } catch(CF::PropertySet::InvalidConfiguration& e) { - ostringstream eout; - eout << "Failed to initialize component properties: '"; - eout << softpkg->getName() << "' with component id: '" << deployment->getIdentifier() << " assigned to device: '"<getAssignedDevice()->identifier << "' "; - eout << " in waveform '"<< _waveformContextName<<"';"; - eout << "InvalidConfiguration with this info: <"; - eout << e.msg << "> for these invalid properties: "; - for (unsigned int propIdx = 0; propIdx < e.invalidProperties.length(); propIdx++){ - eout << "(" << e.invalidProperties[propIdx].id << ","; - eout << ossie::any_to_string(e.invalidProperties[propIdx].value) << ")"; - } - eout << " error occurred near line:" <<__LINE__ << " in file:" << __FILE__ << ";"; - LOG_ERROR(ApplicationFactory_impl, eout.str()); - throw CF::ApplicationFactory::InvalidInitConfiguration(e.invalidProperties); - } catch(CF::PropertySet::PartialConfiguration& e) { - ostringstream eout; - eout << "Failed to initialize component properties: '"; - eout << softpkg->getName() << "' with component id: '" << deployment->getIdentifier() << " assigned to device: '"<getAssignedDevice()->identifier << "' "; - eout << " in waveform '"<< _waveformContextName<<"';"; - eout << "PartialConfiguration for these invalid properties: "; - for (unsigned int propIdx = 0; propIdx < e.invalidProperties.length(); propIdx++){ - eout << "(" << e.invalidProperties[propIdx].id << ","; - eout << ossie::any_to_string(e.invalidProperties[propIdx].value) << ")"; - } - eout << " error occurred near line:" <<__LINE__ << " in file:" << __FILE__ << ";"; - LOG_ERROR(ApplicationFactory_impl, eout.str()); - throw CF::ApplicationFactory::InvalidInitConfiguration(e.invalidProperties); - } catch( ... ) { - ostringstream eout; - eout << "Failed to initialize component properties: '"; - eout << softpkg->getName() << "' with component id: '" << deployment->getIdentifier() << " assigned to device: '"<getAssignedDevice()->identifier << "' "; - eout << " in waveform '"<< _waveformContextName<<"';"; - eout << "'initializeProperties' failed with Unknown Exception"; - eout << " error occurred near line:" <<__LINE__ << " in file:" << __FILE__ << ";"; - LOG_ERROR(ApplicationFactory_impl, eout.str()); - throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EINVAL, eout.str().c_str()); - } - } - - LOG_TRACE(ApplicationFactory_impl, "Initializing component " << componentId); - try { - resource->initialize(); - } catch (const CF::LifeCycle::InitializeError& error) { - // Dump the detailed initialization failure to the log - ostringstream logmsg; - std::string component_version(component->spd.getSoftPkgType()); - std::string added_message = this->createVersionMismatchMessage(component_version); - logmsg << added_message; - logmsg << "Initializing component " << componentId << " failed"; - for (CORBA::ULong index = 0; index < error.errorMessages.length(); ++index) { - logmsg << std::endl << error.errorMessages[index]; - } - LOG_ERROR(ApplicationFactory_impl, logmsg.str()); - - ostringstream eout; - eout << added_message; - eout << "Unable to initialize component " << componentId; - throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EIO, eout.str().c_str()); - } catch (const CORBA::SystemException& exc) { - ostringstream eout; - std::string component_version(component->spd.getSoftPkgType()); - std::string added_message = this->createVersionMismatchMessage(component_version); - eout << added_message; - eout << "CORBA " << exc._name() << " exception initializing component " << componentId; - LOG_ERROR(ApplicationFactory_impl, eout.str()); - throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EIO, eout.str().c_str()); - } + deployment->initialize(); } } diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index d78e20aa1..045c2fc3a 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -591,6 +591,70 @@ std::string ComponentDeployment::getLoggingConfiguration() const return std::string(); } +void ComponentDeployment::initializeProperties() +{ + redhawk::PropertyMap init_props = getInitializeProperties(); + + CF::Properties partials = ossie::getPartialStructs(init_props); + if (partials.length() > 0) { + std::ostringstream eout; + eout << "cannot be initialized due to " << partials.length(); + eout << " structure(s) with a mix of defined and nil values: "; + bool first = true; + for (size_t index = 0; index < partials.length(); ++index) { + if (!first) { + eout << ", "; + } + eout << partials[index].id; + } + throw deployment_error(this, eout.str()); + } + + RH_NL_DEBUG("ApplicationFactory_impl", "Initializing properties for component " << identifier); + try { + resource->initializeProperties(init_props); + } catch (const CF::PropertySet::InvalidConfiguration& ic) { + throw configure_error(this, ic.invalidProperties, "invalid configuration"); + } catch (const CF::PropertySet::PartialConfiguration& pc) { + throw configure_error(this, pc.invalidProperties, "partial configuration"); + } catch (const CF::PropertyEmitter::AlreadyInitialized& ai) { + // The component should never be initialized twice, at least not by the + // ApplicationFactory + throw std::runtime_error("component " + identifier + " was already initialized"); + } catch (...) { + throw std::runtime_error("unable to initialize properties for component " + identifier); + } +} + +void ComponentDeployment::initialize() +{ + if (isConfigurable()) { + initializeProperties(); + } + + RH_NL_TRACE("ApplicationFactory_impl", "Initializing component " << identifier); + try { + resource->initialize(); + } catch (const CF::LifeCycle::InitializeError& error) { + // Dump the detailed initialization failure to the log + std::ostringstream logmsg; + logmsg << "Initializing component " << identifier << " failed"; + for (CORBA::ULong index = 0; index < error.errorMessages.length(); ++index) { + logmsg << std::endl << error.errorMessages[index]; + } + RH_NL_ERROR("ApplicationFactory_impl", logmsg.str()); + + const std::string errmsg = "Unable to initialize component " + identifier; + throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EIO, errmsg.c_str()); + } catch (const CORBA::SystemException& exc) { + std::ostringstream eout; + eout << "CORBA " << exc._name() << " exception initializing component " << identifier; + RH_NL_ERROR("ApplicationFactory_impl", eout.str()); + throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EIO, eout.str().c_str()); + } + +} + void ComponentDeployment::configure() { if (!softpkg->isScaCompliant()) { @@ -626,7 +690,7 @@ void ComponentDeployment::configure() eout << "Component " << identifier << " contains " << partials.length() << "structure(s) with a mix of defined and nil values: "; bool first = true; - for (int index = 0; index < partials.length(); ++index) { + for (size_t index = 0; index < partials.length(); ++index) { if (!first) { eout << ", "; } @@ -636,8 +700,8 @@ void ComponentDeployment::configure() RH_NL_WARN("ApplicationFactory_impl", eout.str()); } + RH_NL_TRACE("ApplicationFactory_impl", "Configuring component " << identifier); try { - RH_NL_TRACE("ApplicationFactory_impl", "Configuring component " << identifier); resource->configure(config_props); } catch (const CF::PropertySet::InvalidConfiguration& ic) { throw configure_error(this, ic.invalidProperties, "invalid configuration"); diff --git a/redhawk/src/control/sdr/dommgr/Deployment.h b/redhawk/src/control/sdr/dommgr/Deployment.h index 52c8e6685..8248ecf4c 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.h +++ b/redhawk/src/control/sdr/dommgr/Deployment.h @@ -214,12 +214,16 @@ namespace ossie { std::string getLoggingConfiguration() const; + void initialize(); + void configure(); protected: CF::DataType getPropertyValue(const Property* property) const; const ComponentProperty* getPropertyOverride(const std::string& id) const; + void initializeProperties(); + const ComponentInstantiation* instantiation; const std::string identifier; bool assemblyController; From 5ebb6cd575ca55659b0d8cffcdd5153a20f72811 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 6 Jun 2016 14:07:02 -0400 Subject: [PATCH 0357/1644] Use a specific exception to handle execute errors and reduce boilerplate message code --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 148 ++++++------------ redhawk/src/control/sdr/dommgr/Deployment.h | 23 +++ 2 files changed, 69 insertions(+), 102 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index c5bdac078..ed323a0cb 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -819,8 +819,18 @@ CF::Application_ptr createHelper::create ( std::vector connections; std::vector allocationIDs; - CF::ApplicationRegistrar_var app_reg = _application->appReg(); - loadAndExecuteComponents(app_deployment.getComponentDeployments(), app_reg); + try { + CF::ApplicationRegistrar_var app_reg = _application->appReg(); + loadAndExecuteComponents(app_deployment.getComponentDeployments(), app_reg); + } catch (const ossie::execute_error& exc) { + std::ostringstream eout; + eout << "Executing component " << exc.deployment()->getIdentifier(); + eout << " implementation " << exc.deployment()->getImplementation()->getID(); + eout << " failed on device " << exc.device()->identifier; + eout << ": " << exc.what(); + throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EIO, eout.str().c_str()); + } + waitForComponentRegistration(app_deployment.getComponentDeployments()); try { @@ -1592,9 +1602,6 @@ std::string createHelper::resolveLoggingConfiguration(ossie::ComponentDeployment void createHelper::attemptComponentExecution (CF::ApplicationRegistrar_ptr registrar, ossie::ComponentDeployment* deployment) { - const ossie::SPD::Implementation* implementation = deployment->getImplementation(); - const ossie::SoftPkg* softpkg = deployment->getSoftPkg(); - // Get executable device reference boost::shared_ptr device = deployment->getAssignedDevice(); CF::ExecutableDevice_var execdev = ossie::corba::_narrowSafe(device->device); @@ -1624,7 +1631,7 @@ void createHelper::attemptComponentExecution (CF::ApplicationRegistrar_ptr regis execParameters["NAME_BINDING"] = deployment->getInstantiation()->getFindByNamingServiceName(); } execParameters["DOM_PATH"] = _baseNamingContext; - execParameters["PROFILE_NAME"] = softpkg->getSPDFile(); + execParameters["PROFILE_NAME"] = deployment->getSoftPkg()->getSPDFile(); // Pass logging configuration std::string logging_uri = resolveLoggingConfiguration(deployment); @@ -1667,109 +1674,46 @@ void createHelper::attemptComponentExecution (CF::ApplicationRegistrar_ptr regis dep_seq[p]=CORBA::string_dup(resolved_softpkg_deps[p].c_str()); } - CF::ExecutableDevice::ProcessID_Type tempPid = -1; - // attempt to execute the component - try { - LOG_TRACE(ApplicationFactory_impl, "executing " << entryPoint << " on device " << device->label); - for (redhawk::PropertyMap::iterator prop = execParameters.begin(); prop != execParameters.end(); ++prop) { - LOG_TRACE(ApplicationFactory_impl, " exec param " << prop->getId() << " " << prop->getValue().toString()); - } + LOG_TRACE(ApplicationFactory_impl, "Executing " << entryPoint << " on device " << device->label); + for (redhawk::PropertyMap::iterator prop = execParameters.begin(); prop != execParameters.end(); ++prop) { + LOG_TRACE(ApplicationFactory_impl, " exec param " << prop->getId() << " " << prop->getValue().toString()); + } - // Get options list - redhawk::PropertyMap options = deployment->getOptions(); - for (redhawk::PropertyMap::iterator opt = options.begin(); opt != options.end(); ++opt) { - LOG_TRACE(ApplicationFactory_impl, " RESOURCE OPTION: " << opt->getId() - << " " << opt->getValue().toString()); - } + // Get options list + redhawk::PropertyMap options = deployment->getOptions(); + for (redhawk::PropertyMap::iterator opt = options.begin(); opt != options.end(); ++opt) { + LOG_TRACE(ApplicationFactory_impl, " RESOURCE OPTION: " << opt->getId() + << " " << opt->getValue().toString()); + } + CF::ExecutableDevice::ProcessID_Type pid = -1; + try { // call 'execute' on the ExecutableDevice to execute the component - tempPid = execdev->executeLinked(entryPoint.c_str(), options, execParameters, dep_seq); - } catch( CF::InvalidFileName& _ex ) { - std::string added_message = this->createVersionMismatchMessage(component_version); - ostringstream eout; - eout << "InvalidFileName when calling 'execute' on device with device id: '" << device->identifier << "' for component: '"; - eout << softpkg->getName() << "' with component id: '" << deployment->getIdentifier() << "' "; - eout << " with implementation id: '" << implementation->getID() << "'"; - eout << " in waveform '" << _waveformContextName<<"'"; - eout << " with error: <" << _ex.msg << ">;"; - eout << " error occurred near line:" <<__LINE__ << " in file:" << __FILE__ << ";"; - LOG_TRACE(ApplicationFactory_impl, eout.str()) - throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EIO, eout.str().c_str()); - } catch( CF::Device::InvalidState& _ex ) { - std::string added_message = this->createVersionMismatchMessage(component_version); - ostringstream eout; - eout << "InvalidState when calling 'execute' on device with device id: '" << device->identifier << "' for component: '"; - eout << softpkg->getName() << "' with component id: '" << deployment->getIdentifier() << "' "; - eout << " with implementation id: '" << implementation->getID() << "'"; - eout << " in waveform '" << _waveformContextName<<"'"; - eout << " with error: <" << _ex.msg << ">;"; - eout << " error occurred near line:" <<__LINE__ << " in file:" << __FILE__ << ";"; - LOG_TRACE(ApplicationFactory_impl, eout.str()) - throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EIO, eout.str().c_str()); - } catch( CF::ExecutableDevice::InvalidParameters& _ex ) { - std::string added_message = this->createVersionMismatchMessage(component_version); - ostringstream eout; - eout << "InvalidParameters when calling 'execute' on device with device id: '" << device->identifier << "' for component: '"; - eout << softpkg->getName() << "' with component id: '" << deployment->getIdentifier() << "' "; - eout << " with implementation id: '" << implementation->getID() << "'"; - eout << " in waveform '" << _waveformContextName<<"'"; - eout << " with invalid params: <"; - for (unsigned int propIdx = 0; propIdx < _ex.invalidParms.length(); propIdx++){ - eout << "(" << _ex.invalidParms[propIdx].id << "," << ossie::any_to_string(_ex.invalidParms[propIdx].value) << ")"; - } - eout << " > error occurred near line:" <<__LINE__ << " in file:" << __FILE__ << ";"; - LOG_TRACE(ApplicationFactory_impl, eout.str()) - throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EIO, eout.str().c_str()); - } catch( CF::ExecutableDevice::InvalidOptions& _ex ) { - std::string component_version(component->spd.getSoftPkgType()); - std::string added_message = this->createVersionMismatchMessage(component_version); - ostringstream eout; - eout << "InvalidOptions when calling 'execute' on device with device id: '" << device->identifier << "' for component: '"; - eout << softpkg->getName() << "' with component id: '" << deployment->getIdentifier() << "' "; - eout << " with implementation id: '" << implementation->getID() << "'"; - eout << " in waveform '" << _waveformContextName<<"'"; - eout << " with invalid options: <"; - for (unsigned int propIdx = 0; propIdx < _ex.invalidOpts.length(); propIdx++){ - eout << "(" << _ex.invalidOpts[propIdx].id << "," << ossie::any_to_string(_ex.invalidOpts[propIdx].value) << ")"; - } - eout << " > error occurred near line:" <<__LINE__ << " in file:" << __FILE__ << ";"; - LOG_TRACE(ApplicationFactory_impl, eout.str()) - throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EIO, eout.str().c_str()); - } catch (CF::ExecutableDevice::ExecuteFail& ex) { - std::string added_message = this->createVersionMismatchMessage(component_version); - ostringstream eout; - eout << "ExecuteFail when calling 'execute' on device with device id: '" << device->identifier << "' for component: '"; - eout << softpkg->getName() << "' with component id: '" << deployment->getIdentifier() << "' "; - eout << " with implementation id: '" << implementation->getID() << "'"; - eout << " in waveform '" << _waveformContextName<<"'"; - eout << " with message: '" << ex.msg << "'"; - eout << " error occurred near line:" <<__LINE__ << " in file:" << __FILE__ << ";"; - LOG_TRACE(ApplicationFactory_impl, eout.str()) - throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EIO, eout.str().c_str()); - } CATCH_THROW_LOG_ERROR( - ApplicationFactory_impl, "Caught an unexpected error when calling 'execute' on device with device id: '" - << device->identifier << "' for component: '" << softpkg->getName() - << "' with component id: '" << deployment->getIdentifier() << "' " - << " with implementation id: '" << implementation->getID() << "'" - << " in waveform '" << _waveformContextName<<"'" - << " error occurred near line:" <<__LINE__ << " in file:" << __FILE__, - CF::ApplicationFactory::CreateApplicationError(CF::CF_EINVAL, "Caught an unexpected error when calling 'execute' on device")); + pid = execdev->executeLinked(entryPoint.c_str(), options, execParameters, dep_seq); + } catch (const CF::InvalidFileName&) { + throw ossie::execute_error(deployment, device, "invalid filename"); + } catch (const CF::Device::InvalidState& exc) { + std::string message = "invalid device state " + std::string(exc.msg); + throw ossie::execute_error(deployment, device, message); + } catch (const CF::ExecutableDevice::InvalidParameters& exc) { + std::string message = "invalid parameters " + redhawk::PropertyMap::cast(exc.invalidParms).toString(); + throw ossie::execute_error(deployment, device, message); + } catch (const CF::ExecutableDevice::InvalidOptions& exc) { + std::string message = "invalid options " + redhawk::PropertyMap::cast(exc.invalidOpts).toString(); + throw ossie::execute_error(deployment, device, message); + } catch (const CF::ExecutableDevice::ExecuteFail& exc) { + std::string message = "execute failure " + std::string(exc.msg); + throw ossie::execute_error(deployment, device, message); + } catch (...) { + throw ossie::execute_error(deployment, device, "unexpected error"); + } // handle pid output - if (tempPid < 0) { - std::string added_message = this->createVersionMismatchMessage(component_version); - ostringstream eout; - eout << added_message; - eout << "Failed to 'execute' component for component: '"; - eout << softpkg->getName() << "' with component id: '" << deployment->getIdentifier() << "' "; - eout << " with implementation id: '" << implementation->getID() << "'"; - eout << " in waveform '" << _waveformContextName<<"'"; - eout << " error occurred near line:" <<__LINE__ << " in file:" << __FILE__ << ";"; - LOG_TRACE(ApplicationFactory_impl, eout.str()) - throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EAGAIN, eout.str().c_str()); + if (pid < 0) { + throw ossie::execute_error(deployment, device, "execute returned invalid process ID"); } else { - _application->setComponentPid(deployment->getIdentifier(), tempPid); + _application->setComponentPid(deployment->getIdentifier(), pid); } } diff --git a/redhawk/src/control/sdr/dommgr/Deployment.h b/redhawk/src/control/sdr/dommgr/Deployment.h index 8248ecf4c..66276a2c3 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.h +++ b/redhawk/src/control/sdr/dommgr/Deployment.h @@ -56,6 +56,29 @@ namespace ossie { const ComponentDeployment* _deployment; }; + class execute_error : public deployment_error { + public: + execute_error(const ComponentDeployment* deployment, + const boost::shared_ptr& device, + const std::string& message) : + deployment_error(deployment, message), + _device(device) + { + } + + const boost::shared_ptr& device() const + { + return _device; + } + + virtual ~execute_error() throw () + { + } + + private: + boost::shared_ptr _device; + }; + class configure_error : public deployment_error { public: configure_error(const ComponentDeployment* deployment, From 49cd4ddeaaf74fabf7f02391d6dae22947fa35ef Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 6 Jun 2016 14:27:55 -0400 Subject: [PATCH 0358/1644] New utility functions to give better string descriptions of CORBA exceptions --- redhawk/src/base/framework/CorbaUtils.cpp | 35 +++++++++++++++++++++ redhawk/src/base/include/ossie/CorbaUtils.h | 3 ++ 2 files changed, 38 insertions(+) diff --git a/redhawk/src/base/framework/CorbaUtils.cpp b/redhawk/src/base/framework/CorbaUtils.cpp index 2b249f2a5..211040f08 100644 --- a/redhawk/src/base/framework/CorbaUtils.cpp +++ b/redhawk/src/base/framework/CorbaUtils.cpp @@ -29,6 +29,12 @@ #include "ossie/CorbaUtils.h" +#ifdef minor +// Depending on g++ settings, the C stdlib defines a minor() macro that breaks +// CORBA::SystemException's minor() methods +#undef minor +#endif + static CORBA::ORB_var orb = CORBA::ORB::_nil(); static PortableServer::POA_var root_poa = PortableServer::POA::_nil(); static CosNaming::NamingContext_var inc = CosNaming::NamingContext::_nil(); @@ -380,6 +386,35 @@ PortableServer::ServantBase* internal::getLocalServant(CORBA::Object_ptr object) return 0; } +std::string describeException(const CORBA::SystemException& exc) +{ + std::ostringstream out; + out << "CORBA::" << exc._name() << " (minor: " << exc.minor() << " completed: "; + switch (exc.completed()) { + case CORBA::COMPLETED_YES: + out << "YES"; + break; + case CORBA::COMPLETED_NO: + out << "NO"; + break; + case CORBA::COMPLETED_MAYBE: + out << "MAYBE"; + break; + } + out << ")"; + return out.str(); +} + +std::string describeException(const CORBA::Exception& exc) { + const CORBA::SystemException* sys = dynamic_cast(&exc); + if (sys) { + return describeException(*sys); + } + std::ostringstream out; + out << exc._name() << " (" << exc._rep_id() << ")"; + return out.str(); +} + #define LNTRACE( lname, expression ) RH_TRACE( rh_logger::Logger::getLogger(lname), expression ) #define LNDEBUG( lname, expression ) RH_DEBUG( rh_logger::Logger::getLogger(lname), expression ) #define LNINFO( lname, expression ) RH_INFO( rh_logger::Logger::getLogger(lname), expression ) diff --git a/redhawk/src/base/include/ossie/CorbaUtils.h b/redhawk/src/base/include/ossie/CorbaUtils.h index 78459564d..b1fcddc02 100644 --- a/redhawk/src/base/include/ossie/CorbaUtils.h +++ b/redhawk/src/base/include/ossie/CorbaUtils.h @@ -239,6 +239,9 @@ namespace ossie { return 0; } + std::string describeException(const CORBA::SystemException& exc); + std::string describeException(const CORBA::Exception& exc); + // Mapping of C++ types to type codes. template static CORBA::TypeCode_ptr TypeCode (void) From 2b20523fbcd7ad3ac42b724aae8d0f45dfd87731 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 6 Jun 2016 15:31:10 -0400 Subject: [PATCH 0359/1644] Consolidate more deployment error handling at the outer level; a little more consistency and "just in case" exception handling --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 68 +++++++++---------- redhawk/src/control/sdr/dommgr/Deployment.cpp | 51 +++++++------- redhawk/src/control/sdr/dommgr/Deployment.h | 50 +++++++++----- 3 files changed, 91 insertions(+), 78 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index ed323a0cb..bd3910005 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -682,6 +682,30 @@ throw (CORBA::SystemException, CF::ApplicationFactory::CreateApplicationError, } catch (CF::ApplicationFactory::CreateApplicationRequestError& ex) { LOG_ERROR(ApplicationFactory_impl, "Error in application creation") throw; + } catch (const ossie::execute_error& exc) { + // A component failed execution, report details + std::ostringstream eout; + eout << "Executing component " << exc.deployment()->getIdentifier(); + eout << " implementation " << exc.deployment()->getImplementation()->getID(); + eout << " failed on device " << exc.device()->identifier; + eout << ": " << exc.what(); + LOG_ERROR(ApplicationFactory_impl, eout.str()); + throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EIO, eout.str().c_str()); + } catch (const ossie::properties_error& exc) { + // Unfortunately, InvalidInitConfiguration does not include an error + // message, so log the error here to give more details + std::ostringstream eout; + LOG_ERROR(ApplicationFactory_impl, "Component " << exc.deployment()->getIdentifier() + << " failed with " << exc.what() << " " << exc.properties()); + throw CF::ApplicationFactory::InvalidInitConfiguration(exc.properties()); + } catch (const ossie::deployment_error& exc) { + // A component failed deployment in some other way, report details + std::stringstream eout; + eout << "Component " << exc.deployment()->getIdentifier(); + eout << " implementation " << exc.deployment()->getImplementation()->getID(); + eout << " failed: " << exc.what(); + LOG_ERROR(ApplicationFactory_impl, eout.str()); + throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EINVAL, eout.str().c_str()); } catch (const std::exception& ex) { std::ostringstream eout; eout << "The following standard exception occurred: "< connections; std::vector allocationIDs; - try { - CF::ApplicationRegistrar_var app_reg = _application->appReg(); - loadAndExecuteComponents(app_deployment.getComponentDeployments(), app_reg); - } catch (const ossie::execute_error& exc) { - std::ostringstream eout; - eout << "Executing component " << exc.deployment()->getIdentifier(); - eout << " implementation " << exc.deployment()->getImplementation()->getID(); - eout << " failed on device " << exc.device()->identifier; - eout << ": " << exc.what(); - throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EIO, eout.str().c_str()); - } + CF::ApplicationRegistrar_var app_reg = _application->appReg(); + loadAndExecuteComponents(app_deployment.getComponentDeployments(), app_reg); waitForComponentRegistration(app_deployment.getComponentDeployments()); - try { - initializeComponents(app_deployment.getComponentDeployments()); - } catch (const ossie::configure_error& exc) { - // Unfortunately, InvalidInitConfiguration does not include an error - // message, so log the error here to give more details - std::ostringstream eout; - LOG_ERROR(ApplicationFactory_impl, "Property initialization of component " - << exc.deployment()->getIdentifier() - << " failed with " << exc.what() << " " << exc.properties()); - throw CF::ApplicationFactory::InvalidInitConfiguration(exc.properties()); - } catch (const std::exception& exc) { - throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EINVAL, exc.what()); - } + initializeComponents(app_deployment.getComponentDeployments()); // Check that the assembly controller is valid LOG_TRACE(ApplicationFactory_impl, "Checking assembly controller"); @@ -863,18 +866,7 @@ CF::Application_ptr createHelper::create ( } _connectComponents(app_deployment, connections); - try { - configureComponents(app_deployment.getComponentDeployments()); - } catch (const ossie::configure_error& exc) { - // Unfortunately, InvalidInitConfiguration does not include an error - // message, so log the error here to give more details - std::ostringstream eout; - LOG_ERROR(ApplicationFactory_impl, "Configure of component " << exc.deployment()->getIdentifier() - << " failed with " << exc.what() << " " << exc.properties()); - throw CF::ApplicationFactory::InvalidInitConfiguration(exc.properties()); - } catch (const std::exception& exc) { - throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EINVAL, exc.what()); - } + configureComponents(app_deployment.getComponentDeployments()); setUpExternalPorts(app_deployment, _application); setUpExternalProperties(app_deployment, _application); @@ -1705,7 +1697,11 @@ void createHelper::attemptComponentExecution (CF::ApplicationRegistrar_ptr regis } catch (const CF::ExecutableDevice::ExecuteFail& exc) { std::string message = "execute failure " + std::string(exc.msg); throw ossie::execute_error(deployment, device, message); + } catch (const CORBA::SystemException& exc) { + throw ossie::execute_error(deployment, device, ossie::corba::describeException(exc)); } catch (...) { + // Should never happen, but turn anything else into an execute_error + // just in case throw ossie::execute_error(deployment, device, "unexpected error"); } diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index 045c2fc3a..ecf92a3b6 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -179,8 +179,7 @@ void SoftpkgDeployment::load(Application_impl* application, CF::FileSystem_ptr f message += exc.msg; throw std::runtime_error(message); } catch (const CORBA::SystemException& exc) { - std::string message = "CORBA system exception "; - message += exc._name(); + std::string message = ossie::corba::describeException(exc); message += " loading " + fileName; throw std::runtime_error(message); } @@ -613,16 +612,20 @@ void ComponentDeployment::initializeProperties() RH_NL_DEBUG("ApplicationFactory_impl", "Initializing properties for component " << identifier); try { resource->initializeProperties(init_props); - } catch (const CF::PropertySet::InvalidConfiguration& ic) { - throw configure_error(this, ic.invalidProperties, "invalid configuration"); - } catch (const CF::PropertySet::PartialConfiguration& pc) { - throw configure_error(this, pc.invalidProperties, "partial configuration"); - } catch (const CF::PropertyEmitter::AlreadyInitialized& ai) { + } catch (const CF::PropertySet::InvalidConfiguration& exc) { + throw properties_error(this, exc.invalidProperties, "invalid configuration in property initialization"); + } catch (const CF::PropertySet::PartialConfiguration& exc) { + throw properties_error(this, exc.invalidProperties, "partial configuration in property initialization"); + } catch (const CF::PropertyEmitter::AlreadyInitialized&) { // The component should never be initialized twice, at least not by the // ApplicationFactory - throw std::runtime_error("component " + identifier + " was already initialized"); + throw deployment_error(this, "already initialized"); + } catch (const CORBA::SystemException& exc) { + throw deployment_error(this, "initializing properties raised " + ossie::corba::describeException(exc)); } catch (...) { - throw std::runtime_error("unable to initialize properties for component " + identifier); + // Should never happen, but turn anything else into a deployment_error + // just in case + throw deployment_error(this, "unexpected error initializing properties"); } } @@ -638,21 +641,17 @@ void ComponentDeployment::initialize() } catch (const CF::LifeCycle::InitializeError& error) { // Dump the detailed initialization failure to the log std::ostringstream logmsg; - logmsg << "Initializing component " << identifier << " failed"; for (CORBA::ULong index = 0; index < error.errorMessages.length(); ++index) { logmsg << std::endl << error.errorMessages[index]; } - RH_NL_ERROR("ApplicationFactory_impl", logmsg.str()); - - const std::string errmsg = "Unable to initialize component " + identifier; - throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EIO, errmsg.c_str()); + throw deployment_error(this, logmsg.str()); } catch (const CORBA::SystemException& exc) { - std::ostringstream eout; - eout << "CORBA " << exc._name() << " exception initializing component " << identifier; - RH_NL_ERROR("ApplicationFactory_impl", eout.str()); - throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EIO, eout.str().c_str()); + throw deployment_error(this, "initialize raised " + ossie::corba::describeException(exc)); + } catch (...) { + // Should never happen, but turn anything else into a deployment_error + // just in case + throw deployment_error(this, "unexpected error in initialize"); } - } void ComponentDeployment::configure() @@ -678,7 +677,7 @@ void ComponentDeployment::configure() // NB: I think having a valid CORBA reference is a pre-condition of // getting to this point in the first place RH_NL_ERROR("ApplicationFactory_impl", "Could not get component reference"); - throw std::runtime_error("Could not get component reference for component " + identifier); + throw ossie::deployment_error(this, "no CORBA reference"); } redhawk::PropertyMap config_props = getInitialConfigureProperties(); @@ -703,11 +702,13 @@ void ComponentDeployment::configure() RH_NL_TRACE("ApplicationFactory_impl", "Configuring component " << identifier); try { resource->configure(config_props); - } catch (const CF::PropertySet::InvalidConfiguration& ic) { - throw configure_error(this, ic.invalidProperties, "invalid configuration"); - } catch (const CF::PropertySet::PartialConfiguration& pc) { - throw configure_error(this, pc.invalidProperties, "partial configuration"); + } catch (const CF::PropertySet::InvalidConfiguration& exc) { + throw properties_error(this, exc.invalidProperties, "invalid configuration in configure"); + } catch (const CF::PropertySet::PartialConfiguration& exc) { + throw properties_error(this, exc.invalidProperties, "partial configuration in configure"); + } catch (const CORBA::SystemException& exc) { + throw deployment_error(this, "configure raised " + ossie::corba::describeException(exc)); } catch (...) { - throw std::runtime_error("unable to configure component " + identifier); + throw deployment_error(this, "unexpected error configuring component"); } } diff --git a/redhawk/src/control/sdr/dommgr/Deployment.h b/redhawk/src/control/sdr/dommgr/Deployment.h index 66276a2c3..c0dd0c7fb 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.h +++ b/redhawk/src/control/sdr/dommgr/Deployment.h @@ -79,17 +79,17 @@ namespace ossie { boost::shared_ptr _device; }; - class configure_error : public deployment_error { + class properties_error : public deployment_error { public: - configure_error(const ComponentDeployment* deployment, - const CF::Properties& properties, - const std::string& message) : + properties_error(const ComponentDeployment* deployment, + const CF::Properties& properties, + const std::string& message) : deployment_error(deployment, message), _properties(properties) { } - virtual ~configure_error() throw () + virtual ~properties_error() throw () { } @@ -212,18 +212,6 @@ namespace ossie { */ redhawk::PropertyMap getCommandLineParameters() const; - /** - * Returns the properties used for the initial call to configure() - * during deployment - */ - redhawk::PropertyMap getInitialConfigureProperties() const; - - /** - * Returns the properties used for initializePropertes() during - * deployment - */ - redhawk::PropertyMap getInitializeProperties() const; - void overrideProperty(const std::string& id, const CORBA::Any& value); void setAssignedDevice(const boost::shared_ptr& device); @@ -237,11 +225,39 @@ namespace ossie { std::string getLoggingConfiguration() const; + /** + * @brief Initializes the deployed component + * @exception ossie::properties_error invalid properties in property + * initialization + * @exception ossie::deployment_error initialization failed + * + * Handles initialization of new-style 'property' kind properties and + * calls initialize on the component. + */ void initialize(); + /** + * @brief Configures legacy properties to initial values + * @exception ossie::properties_error invalid properties + * @exception ossie::deployment_error configure failed + * + * Handles configuration of legacy 'configure' kind properties. + */ void configure(); protected: + /** + * Returns the properties used for the initial call to configure() + * during deployment + */ + redhawk::PropertyMap getInitialConfigureProperties() const; + + /** + * Returns the properties used for initializePropertes() during + * deployment + */ + redhawk::PropertyMap getInitializeProperties() const; + CF::DataType getPropertyValue(const Property* property) const; const ComponentProperty* getPropertyOverride(const std::string& id) const; From 7060fcc11d493d4c6af572cc5ba0f7dcf886bc2a Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 6 Jun 2016 15:58:19 -0400 Subject: [PATCH 0360/1644] Move deployment structures to the redhawk namespace (might as well take credit for REDHAWK-developed code) --- .../sdr/dommgr/ApplicationDeployment.cpp | 1 + .../sdr/dommgr/ApplicationDeployment.h | 12 +- .../sdr/dommgr/ApplicationFactory_impl.cpp | 115 +++++++++--------- redhawk/src/control/sdr/dommgr/Deployment.cpp | 3 +- redhawk/src/control/sdr/dommgr/Deployment.h | 43 +++---- redhawk/src/control/sdr/dommgr/createHelper.h | 44 +++---- 6 files changed, 111 insertions(+), 107 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp b/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp index 83f9697ce..dfa6fd0a1 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp @@ -27,6 +27,7 @@ #include "PersistenceStore.h" #include "ApplicationDeployment.h" +using namespace redhawk; using namespace ossie; PREPARE_LOGGING(ApplicationDeployment); diff --git a/redhawk/src/control/sdr/dommgr/ApplicationDeployment.h b/redhawk/src/control/sdr/dommgr/ApplicationDeployment.h index 78d7eeab6..5ecf2f040 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationDeployment.h +++ b/redhawk/src/control/sdr/dommgr/ApplicationDeployment.h @@ -33,9 +33,9 @@ #include "connectionSupport.h" #include "Deployment.h" -namespace ossie { +namespace redhawk { - class ApplicationDeployment : public ComponentLookup, public DeviceLookup, public UsesDeviceDeployment + class ApplicationDeployment : public ossie::ComponentLookup, public ossie::DeviceLookup, public UsesDeviceDeployment { ENABLE_LOGGING; @@ -43,7 +43,7 @@ namespace ossie { typedef std::vector ComponentList; typedef std::map CpuReservations; - ApplicationDeployment(const SoftwareAssembly& sad, + ApplicationDeployment(const ossie::SoftwareAssembly& sad, const std::string& instanceName, const CF::Properties& initConfiguration); ~ApplicationDeployment(); @@ -58,8 +58,8 @@ namespace ossie { ComponentDeployment* getAssemblyController(); - ComponentDeployment* createComponentDeployment(const SoftPkg* softpkg, - const ComponentInstantiation* instantiation); + ComponentDeployment* createComponentDeployment(const ossie::SoftPkg* softpkg, + const ossie::ComponentInstantiation* instantiation); const ComponentList& getComponentDeployments(); ComponentDeployment* getComponentDeployment(const std::string& instantiationId); @@ -81,7 +81,7 @@ namespace ossie { void overrideAssemblyControllerProperties(ComponentDeployment* deployment); void overrideExternalProperties(ComponentDeployment* deployment); - const SoftwareAssembly& sad; + const ossie::SoftwareAssembly& sad; const std::string identifier; const std::string instanceName; redhawk::PropertyMap initConfiguration; diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index bd3910005..0f1412633 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -236,7 +236,7 @@ ApplicationFactory_impl::~ApplicationFactory_impl () } -void createHelper::_connectComponents(ossie::ApplicationDeployment& appDeployment, +void createHelper::_connectComponents(redhawk::ApplicationDeployment& appDeployment, std::vector& connections){ try{ connectComponents(appDeployment, connections, _baseNamingContext); @@ -250,7 +250,7 @@ void createHelper::_connectComponents(ossie::ApplicationDeployment& appDeploymen "Connecting components failed (unclear where this occurred)")); } -void createHelper::assignPlacementsToDevices(ossie::ApplicationDeployment& appDeployment, +void createHelper::assignPlacementsToDevices(redhawk::ApplicationDeployment& appDeployment, const DeviceAssignmentMap& devices) { // Try to place all of the collocations first, since they naturally have @@ -273,13 +273,13 @@ void createHelper::assignPlacementsToDevices(ossie::ApplicationDeployment& appDe LOG_TRACE(ApplicationFactory_impl, "Component " << instantiation.getID() << " is assigned to device " << assigned_device); } - ComponentDeployment* deployment = appDeployment.createComponentDeployment(softpkg, &instantiation); + redhawk::ComponentDeployment* deployment = appDeployment.createComponentDeployment(softpkg, &instantiation); allocateComponent(appDeployment, deployment, assigned_device); } } } -void createHelper::_validateDAS(ossie::ApplicationDeployment& appDeployment, +void createHelper::_validateDAS(redhawk::ApplicationDeployment& appDeployment, const DeviceAssignmentMap& deviceAssignments) { LOG_TRACE(ApplicationFactory_impl, "Validating device assignment sequence (length " @@ -301,7 +301,7 @@ void createHelper::_validateDAS(ossie::ApplicationDeployment& appDeployment, } } -bool createHelper::placeHostCollocation(ossie::ApplicationDeployment& appDeployment, +bool createHelper::placeHostCollocation(redhawk::ApplicationDeployment& appDeployment, const DeploymentList& components, DeploymentList::const_iterator current, ossie::DeviceList& deploymentDevices, @@ -316,7 +316,7 @@ bool createHelper::placeHostCollocation(ossie::ApplicationDeployment& appDeploym // Try all of the implementations from the current component for matches // with the processor and OS dependencies - ossie::ComponentDeployment* deployment = *current; + redhawk::ComponentDeployment* deployment = *current; const SPD::Implementations& comp_impls = deployment->getSoftPkg()->getImplementations(); LOG_TRACE(ApplicationFactory_impl, "Finding collocation-compatible implementations for component " << deployment->getInstantiation()->getID()); @@ -353,7 +353,7 @@ bool createHelper::placeHostCollocation(ossie::ApplicationDeployment& appDeploym return false; } -bool createHelper::allocateHostCollocation(ossie::ApplicationDeployment& appDeployment, +bool createHelper::allocateHostCollocation(redhawk::ApplicationDeployment& appDeployment, const DeploymentList& components, ossie::DeviceList& deploymentDevices, const ProcessorList& processorDeps, @@ -421,7 +421,7 @@ CF::Properties createHelper::_consolidateAllocations(const DeploymentList& deplo return allocs; } -void createHelper::_placeHostCollocation(ossie::ApplicationDeployment& appDeployment, +void createHelper::_placeHostCollocation(redhawk::ApplicationDeployment& appDeployment, const ossie::SoftwareAssembly::HostCollocation& collocation, const DeviceAssignmentMap& devices) { @@ -438,7 +438,7 @@ void createHelper::_placeHostCollocation(ossie::ApplicationDeployment& appDeploy // Even though the XML supports more than one instantiation per // component placement, the tooling doesn't support that, so this // loop may be strictly academic - ComponentDeployment* deployment = appDeployment.createComponentDeployment(softpkg, &instantiation); + redhawk::ComponentDeployment* deployment = appDeployment.createComponentDeployment(softpkg, &instantiation); deployments.push_back(deployment); DeviceAssignmentMap::const_iterator device = devices.find(instantiation.getID()); @@ -470,7 +470,7 @@ void createHelper::_placeHostCollocation(ossie::ApplicationDeployment& appDeploy << collocation.getID() << " Components Placed: " << deployments.size()); } -void createHelper::_handleUsesDevices(ossie::ApplicationDeployment& appDeployment, +void createHelper::_handleUsesDevices(redhawk::ApplicationDeployment& appDeployment, const std::string& appName) { // Gets all uses device info from the SAD file @@ -482,7 +482,7 @@ void createHelper::_handleUsesDevices(ossie::ApplicationDeployment& appDeploymen CF::Properties appProperties = appDeployment.getAllocationContext(); // The device assignments for SAD-level usesdevices are never stored - ossie::UsesDeviceDeployment assignedDevices; + redhawk::UsesDeviceDeployment assignedDevices; if (!allocateUsesDevices(usesDevices, appProperties, assignedDevices, this->_allocations)) { // There were unsatisfied usesdevices for the application ostringstream eout; @@ -506,7 +506,7 @@ void createHelper::_handleUsesDevices(ossie::ApplicationDeployment& appDeploymen assignedDevices.transferUsesDeviceAssignments(appDeployment); } -void createHelper::setUpExternalPorts(ossie::ApplicationDeployment& appDeployment, +void createHelper::setUpExternalPorts(redhawk::ApplicationDeployment& appDeployment, Application_impl* application) { typedef std::vector PortList; @@ -520,7 +520,7 @@ void createHelper::setUpExternalPorts(ossie::ApplicationDeployment& appDeploymen << " Port identifier: " << port->identifier); // Get the component from the instantiation identifier. - ossie::ComponentDeployment* deployment = appDeployment.getComponentDeployment(port->componentrefid); + redhawk::ComponentDeployment* deployment = appDeployment.getComponentDeployment(port->componentrefid); if (!deployment) { LOG_ERROR(ApplicationFactory_impl, "Invalid componentinstantiationref (" @@ -566,7 +566,7 @@ void createHelper::setUpExternalPorts(ossie::ApplicationDeployment& appDeploymen } } -void createHelper::setUpExternalProperties(ossie::ApplicationDeployment& appDeployment, +void createHelper::setUpExternalProperties(redhawk::ApplicationDeployment& appDeployment, Application_impl* application) { const std::vector& props = _appFact._sadParser.getExternalProperties(); @@ -575,7 +575,7 @@ void createHelper::setUpExternalProperties(ossie::ApplicationDeployment& appDepl LOG_TRACE(ApplicationFactory_impl, "Property component: " << prop->comprefid << " Property identifier: " << prop->propid); // Get the component from the compref identifier. - ossie::ComponentDeployment* deployment = appDeployment.getComponentDeployment(prop->comprefid); + redhawk::ComponentDeployment* deployment = appDeployment.getComponentDeployment(prop->comprefid); if (!deployment) { LOG_ERROR(ApplicationFactory_impl, "Unable to find component for comprefid " << prop->comprefid); throw CF::ApplicationFactory::CreateApplicationError(CF::CF_NOTSET, "Unable to find component for given comprefid"); @@ -682,7 +682,7 @@ throw (CORBA::SystemException, CF::ApplicationFactory::CreateApplicationError, } catch (CF::ApplicationFactory::CreateApplicationRequestError& ex) { LOG_ERROR(ApplicationFactory_impl, "Error in application creation") throw; - } catch (const ossie::execute_error& exc) { + } catch (const redhawk::execute_error& exc) { // A component failed execution, report details std::ostringstream eout; eout << "Executing component " << exc.deployment()->getIdentifier(); @@ -691,14 +691,14 @@ throw (CORBA::SystemException, CF::ApplicationFactory::CreateApplicationError, eout << ": " << exc.what(); LOG_ERROR(ApplicationFactory_impl, eout.str()); throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EIO, eout.str().c_str()); - } catch (const ossie::properties_error& exc) { + } catch (const redhawk::properties_error& exc) { // Unfortunately, InvalidInitConfiguration does not include an error // message, so log the error here to give more details std::ostringstream eout; LOG_ERROR(ApplicationFactory_impl, "Component " << exc.deployment()->getIdentifier() << " failed with " << exc.what() << " " << exc.properties()); throw CF::ApplicationFactory::InvalidInitConfiguration(exc.properties()); - } catch (const ossie::deployment_error& exc) { + } catch (const redhawk::deployment_error& exc) { // A component failed deployment in some other way, report details std::stringstream eout; eout << "Component " << exc.deployment()->getIdentifier(); @@ -806,7 +806,7 @@ CF::Application_ptr createHelper::create ( ////////////////////////////////////////////////// // Load the components to instantiate from the SAD - ossie::ApplicationDeployment app_deployment(_appFact._sadParser, _waveformContextName, modifiedInitConfiguration); + redhawk::ApplicationDeployment app_deployment(_appFact._sadParser, _waveformContextName, modifiedInitConfiguration); //////////////////////////////////////////////// // Assign components to devices @@ -852,7 +852,7 @@ CF::Application_ptr createHelper::create ( // Check that the assembly controller is valid LOG_TRACE(ApplicationFactory_impl, "Checking assembly controller"); - ossie::ComponentDeployment* ac_deployment = app_deployment.getAssemblyController(); + redhawk::ComponentDeployment* ac_deployment = app_deployment.getAssemblyController(); if (!ac_deployment) { const char* message = "Assembly controller has not been assigned"; LOG_ERROR(ApplicationFactory_impl, message); @@ -882,7 +882,7 @@ CF::Application_ptr createHelper::create ( // Fill in the uses devices for the application CF::DeviceAssignmentSequence app_devices; - typedef std::vector UsesList; + typedef std::vector UsesList; const UsesList& app_uses = app_deployment.getUsesDeviceAssignments(); for (UsesList::const_iterator uses = app_uses.begin(); uses != app_uses.end(); ++uses) { CF::DeviceAssignmentType assignment; @@ -985,15 +985,15 @@ CF::AllocationManager::AllocationResponseSequence* createHelper::allocateUsesDev collocation request. This requires that we know and cleanup only those allocations that we made.. */ -void createHelper::allocateComponent(ossie::ApplicationDeployment& appDeployment, - ossie::ComponentDeployment* deployment, +void createHelper::allocateComponent(redhawk::ApplicationDeployment& appDeployment, + redhawk::ComponentDeployment* deployment, const std::string& assignedDeviceId) { redhawk::PropertyMap alloc_context = deployment->getAllocationContext(); // Find the devices that allocate the SPD's minimum required usesdevices properties const std::vector& usesDevVec = deployment->getSoftPkg()->getUsesDevices(); - ossie::UsesDeviceDeployment assignedDevices; + redhawk::UsesDeviceDeployment assignedDevices; if (!allocateUsesDevices(usesDevVec, alloc_context, assignedDevices, this->_allocations)) { // There were unsatisfied usesdevices for the component ostringstream eout; @@ -1020,7 +1020,7 @@ void createHelper::allocateComponent(ossie::ApplicationDeployment& appDeployment const ossie::SPD::Implementation* implementation = &implementations[implCount]; // Handle 'usesdevice' dependencies for the particular implementation - UsesDeviceDeployment implAssignedDevices; + redhawk::UsesDeviceDeployment implAssignedDevices; ScopedAllocations implAllocations(*this->_allocationMgr); const std::vector& implUsesDevVec = implementation->getUsesDevices(); @@ -1109,7 +1109,7 @@ void createHelper::allocateComponent(ossie::ApplicationDeployment& appDeployment bool createHelper::allocateUsesDevices(const std::vector& usesDevices, const CF::Properties& configureProperties, - ossie::UsesDeviceDeployment& deviceAssignments, + redhawk::UsesDeviceDeployment& deviceAssignments, ScopedAllocations& allocations) { // Create a temporary lookup table for reconciling allocation requests with @@ -1146,7 +1146,7 @@ bool createHelper::allocateUsesDevices(const std::vector& usesDevice const std::string deviceId = ossie::corba::returnString(response[resp].allocatedDevice->identifier()); usesDeviceMap.erase(uses); - ossie::UsesDeviceAssignment* assignment = new ossie::UsesDeviceAssignment(uses->second); + redhawk::UsesDeviceAssignment* assignment = new redhawk::UsesDeviceAssignment(uses->second); assignment->setAssignedDevice(response[resp].allocatedDevice); deviceAssignments.addUsesDeviceAssignment(assignment); } @@ -1265,9 +1265,9 @@ void createHelper::_evaluateMATHinRequest(CF::Properties &request, const CF::Pro * - If not specified in DAS, then iterate through devices looking for a device that satisfies * the allocation properties */ -ossie::AllocationResult createHelper::allocateComponentToDevice(ossie::ComponentDeployment* deployment, - const std::string& assignedDeviceId, - const std::string& appIdentifier) +ossie::AllocationResult createHelper::allocateComponentToDevice(redhawk::ComponentDeployment* deployment, + const std::string& assignedDeviceId, + const std::string& appIdentifier) { const ossie::SPD::Implementation* implementation = deployment->getImplementation(); ossie::DeviceList devices = _registeredDevices; @@ -1354,8 +1354,8 @@ void createHelper::_castRequestProperties(CF::Properties& allocationProperties, } } -bool createHelper::resolveSoftpkgDependencies(ossie::ApplicationDeployment& appDeployment, - ossie::SoftpkgDeployment* deployment, +bool createHelper::resolveSoftpkgDependencies(redhawk::ApplicationDeployment& appDeployment, + redhawk::SoftpkgDeployment* deployment, ossie::DeviceNode& device) { const ossie::SPD::Implementation* implementation = deployment->getImplementation(); @@ -1364,7 +1364,7 @@ bool createHelper::resolveSoftpkgDependencies(ossie::ApplicationDeployment& appD for (iterSoftpkg = deps.begin(); iterSoftpkg != deps.end(); ++iterSoftpkg) { // Find an implementation whose dependencies match - ossie::SoftpkgDeployment* dependency = resolveDependencyImplementation(appDeployment, *iterSoftpkg, device); + redhawk::SoftpkgDeployment* dependency = resolveDependencyImplementation(appDeployment, *iterSoftpkg, device); if (dependency) { deployment->addDependency(dependency); } else { @@ -1376,9 +1376,10 @@ bool createHelper::resolveSoftpkgDependencies(ossie::ApplicationDeployment& appD return true; } -ossie::SoftpkgDeployment* createHelper::resolveDependencyImplementation(ossie::ApplicationDeployment& appDeployment, - const ossie::SPD::SoftPkgRef& ref, - ossie::DeviceNode& device) +redhawk::SoftpkgDeployment* +createHelper::resolveDependencyImplementation(redhawk::ApplicationDeployment& appDeployment, + const ossie::SPD::SoftPkgRef& ref, + ossie::DeviceNode& device) { LOG_TRACE(ApplicationFactory_impl, "Resolving dependency " << ref); const SoftPkg* softpkg = _profileCache.loadSoftPkg(ref.localfile); @@ -1397,7 +1398,7 @@ ossie::SoftpkgDeployment* createHelper::resolveDependencyImplementation(ossie::A continue; } - ossie::SoftpkgDeployment* dependency = new ossie::SoftpkgDeployment(softpkg, &implementation); + redhawk::SoftpkgDeployment* dependency = new redhawk::SoftpkgDeployment(softpkg, &implementation); // Recursively check any softpkg dependencies if (resolveSoftpkgDependencies(appDeployment, dependency, device)) { return dependency; @@ -1478,7 +1479,7 @@ void createHelper::loadAndExecuteComponents(const DeploymentList& deployments, applyApplicationAffinityOptions(deployments); for (unsigned int rc_idx = 0; rc_idx < deployments.size (); rc_idx++) { - ossie::ComponentDeployment* deployment = deployments[rc_idx]; + redhawk::ComponentDeployment* deployment = deployments[rc_idx]; const ossie::SoftPkg* softpkg = deployment->getSoftPkg(); const ossie::ComponentInstantiation* instantiation = deployment->getInstantiation(); const ossie::SPD::Implementation* implementation = deployment->getImplementation(); @@ -1553,7 +1554,7 @@ void createHelper::loadAndExecuteComponents(const DeploymentList& deployments, } } -std::string createHelper::resolveLoggingConfiguration(ossie::ComponentDeployment* deployment) +std::string createHelper::resolveLoggingConfiguration(redhawk::ComponentDeployment* deployment) { // Use the log config resolver (if enabled) const ossie::ComponentInstantiation* instantiation = deployment->getInstantiation(); @@ -1592,7 +1593,7 @@ std::string createHelper::resolveLoggingConfiguration(ossie::ComponentDeployment } void createHelper::attemptComponentExecution (CF::ApplicationRegistrar_ptr registrar, - ossie::ComponentDeployment* deployment) + redhawk::ComponentDeployment* deployment) { // Get executable device reference boost::shared_ptr device = deployment->getAssignedDevice(); @@ -1684,30 +1685,30 @@ void createHelper::attemptComponentExecution (CF::ApplicationRegistrar_ptr regis // call 'execute' on the ExecutableDevice to execute the component pid = execdev->executeLinked(entryPoint.c_str(), options, execParameters, dep_seq); } catch (const CF::InvalidFileName&) { - throw ossie::execute_error(deployment, device, "invalid filename"); + throw redhawk::execute_error(deployment, device, "invalid filename"); } catch (const CF::Device::InvalidState& exc) { std::string message = "invalid device state " + std::string(exc.msg); - throw ossie::execute_error(deployment, device, message); + throw redhawk::execute_error(deployment, device, message); } catch (const CF::ExecutableDevice::InvalidParameters& exc) { std::string message = "invalid parameters " + redhawk::PropertyMap::cast(exc.invalidParms).toString(); - throw ossie::execute_error(deployment, device, message); + throw redhawk::execute_error(deployment, device, message); } catch (const CF::ExecutableDevice::InvalidOptions& exc) { std::string message = "invalid options " + redhawk::PropertyMap::cast(exc.invalidOpts).toString(); - throw ossie::execute_error(deployment, device, message); + throw redhawk::execute_error(deployment, device, message); } catch (const CF::ExecutableDevice::ExecuteFail& exc) { std::string message = "execute failure " + std::string(exc.msg); - throw ossie::execute_error(deployment, device, message); + throw redhawk::execute_error(deployment, device, message); } catch (const CORBA::SystemException& exc) { - throw ossie::execute_error(deployment, device, ossie::corba::describeException(exc)); + throw redhawk::execute_error(deployment, device, ossie::corba::describeException(exc)); } catch (...) { // Should never happen, but turn anything else into an execute_error // just in case - throw ossie::execute_error(deployment, device, "unexpected error"); + throw redhawk::execute_error(deployment, device, "unexpected error"); } // handle pid output if (pid < 0) { - throw ossie::execute_error(deployment, device, "execute returned invalid process ID"); + throw redhawk::execute_error(deployment, device, "execute returned invalid process ID"); } else { _application->setComponentPid(deployment->getIdentifier(), pid); } @@ -1737,7 +1738,7 @@ void createHelper::applyApplicationAffinityOptions(const DeploymentList& deploym // boost::shared_ptr deploy_on_device; for (unsigned int rc_idx = 0; rc_idx < deployments.size(); rc_idx++) { - ossie::ComponentDeployment* deployment = deployments[rc_idx]; + redhawk::ComponentDeployment* deployment = deployments[rc_idx]; if (!(deployment->getNicAssignment().empty())) { deploy_on_device = deployment->getAssignedDevice(); } @@ -1745,7 +1746,7 @@ void createHelper::applyApplicationAffinityOptions(const DeploymentList& deploym if (deploy_on_device) { for (unsigned int rc_idx = 0; rc_idx < deployments.size (); rc_idx++) { - ossie::ComponentDeployment* deployment = deployments[rc_idx]; + redhawk::ComponentDeployment* deployment = deployments[rc_idx]; boost::shared_ptr dev = deployment->getAssignedDevice(); // for matching device deployments then apply nic affinity settings if (dev->identifier == deploy_on_device->identifier) { @@ -1781,7 +1782,7 @@ void createHelper::waitForComponentRegistration(const DeploymentList& deployment LOG_ERROR(ApplicationFactory_impl, "Timed out waiting for component to bind to naming context (" << elapsed << "s elapsed)"); ostringstream eout; for (unsigned int req_idx = 0; req_idx < deployments.size(); req_idx++) { - ossie::ComponentDeployment* deployment = deployments[req_idx]; + redhawk::ComponentDeployment* deployment = deployments[req_idx]; if (expected_components.count(deployment->getIdentifier())) { eout << "Timed out waiting for component to register: '" << deployment->getSoftPkg()->getName() << "' with component id: '" << deployment->getIdentifier() @@ -1806,7 +1807,7 @@ void createHelper::initializeComponents(const DeploymentList& deployments) LOG_TRACE(ApplicationFactory_impl, "initializing " << deployments.size() << " waveform components"); for (unsigned int rc_idx = 0; rc_idx < deployments.size (); rc_idx++) { - ossie::ComponentDeployment* deployment = deployments[rc_idx]; + redhawk::ComponentDeployment* deployment = deployments[rc_idx]; const ossie::SoftPkg* softpkg = deployment->getSoftPkg(); // If the component is non-SCA compliant then we don't expect anything beyond this @@ -1861,9 +1862,9 @@ void createHelper::initializeComponents(const DeploymentList& deployments) void createHelper::configureComponents(const DeploymentList& deployments) { - ossie::ComponentDeployment* ac_deployment = 0; + redhawk::ComponentDeployment* ac_deployment = 0; for (DeploymentList::const_iterator depl = deployments.begin(); depl != deployments.end(); ++depl) { - ossie::ComponentDeployment* deployment = (*depl); + redhawk::ComponentDeployment* deployment = (*depl); if (deployment->isAssemblyController()) { ac_deployment = deployment; } else { @@ -1880,7 +1881,7 @@ void createHelper::configureComponents(const DeploymentList& deployments) /* Connect the components * - Connect the components */ -void createHelper::connectComponents(ossie::ApplicationDeployment& appDeployment, +void createHelper::connectComponents(redhawk::ApplicationDeployment& appDeployment, std::vector& connections, string base_naming_context) { @@ -1921,10 +1922,10 @@ std::vector createHelper::getStartOrder(const DeploymentList& // the values in the SAD. Using a multimap, keyed on the start order value, // accounts for duplicate keys and allows assigning the effective order // easily by iterating through all entries. - typedef std::multimap StartOrderMap; + typedef std::multimap StartOrderMap; StartOrderMap start_map; for (size_t index = 0; index < deployments.size(); ++index) { - ossie::ComponentDeployment* deployment = deployments[index]; + redhawk::ComponentDeployment* deployment = deployments[index]; const ossie::ComponentInstantiation* instantiation = deployment->getInstantiation(); if (deployment->isAssemblyController()) { LOG_TRACE(ApplicationFactory_impl, "Component " << instantiation->getID() diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index ecf92a3b6..09af72bbb 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -28,6 +28,7 @@ #include "PersistenceStore.h" #include "Deployment.h" +using namespace redhawk; using namespace ossie; namespace fs = boost::filesystem; @@ -677,7 +678,7 @@ void ComponentDeployment::configure() // NB: I think having a valid CORBA reference is a pre-condition of // getting to this point in the first place RH_NL_ERROR("ApplicationFactory_impl", "Could not get component reference"); - throw ossie::deployment_error(this, "no CORBA reference"); + throw redhawk::deployment_error(this, "no CORBA reference"); } redhawk::PropertyMap config_props = getInitialConfigureProperties(); diff --git a/redhawk/src/control/sdr/dommgr/Deployment.h b/redhawk/src/control/sdr/dommgr/Deployment.h index c0dd0c7fb..6027b8758 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.h +++ b/redhawk/src/control/sdr/dommgr/Deployment.h @@ -31,7 +31,7 @@ class Application_impl; -namespace ossie { +namespace redhawk { class ComponentDeployment; @@ -59,14 +59,14 @@ namespace ossie { class execute_error : public deployment_error { public: execute_error(const ComponentDeployment* deployment, - const boost::shared_ptr& device, + const boost::shared_ptr& device, const std::string& message) : deployment_error(deployment, message), _device(device) { } - const boost::shared_ptr& device() const + const boost::shared_ptr& device() const { return _device; } @@ -76,7 +76,7 @@ namespace ossie { } private: - boost::shared_ptr _device; + boost::shared_ptr _device; }; class properties_error : public deployment_error { @@ -105,15 +105,15 @@ namespace ossie { class UsesDeviceAssignment { public: - UsesDeviceAssignment(const UsesDevice* usesDevice); + UsesDeviceAssignment(const ossie::UsesDevice* usesDevice); - const UsesDevice* getUsesDevice() const; + const ossie::UsesDevice* getUsesDevice() const; void setAssignedDevice(CF::Device_ptr device); CF::Device_ptr getAssignedDevice() const; private: - const UsesDevice* usesDevice; + const ossie::UsesDevice* usesDevice; CF::Device_var assignedDevice; }; @@ -139,13 +139,13 @@ namespace ossie { public: typedef std::vector DeploymentList; - SoftpkgDeployment(const SoftPkg* softpkg, const SPD::Implementation* implementation=0); + SoftpkgDeployment(const ossie::SoftPkg* softpkg, const ossie::SPD::Implementation* implementation=0); ~SoftpkgDeployment(); - const SoftPkg* getSoftPkg() const; + const ossie::SoftPkg* getSoftPkg() const; - void setImplementation(const SPD::Implementation* implementation); - const SPD::Implementation* getImplementation() const; + void setImplementation(const ossie::SPD::Implementation* implementation); + const ossie::SPD::Implementation* getImplementation() const; std::string getLocalFile(); CF::LoadableDevice::LoadType getCodeType() const; @@ -161,15 +161,16 @@ namespace ossie { void load(Application_impl* application, CF::FileSystem_ptr fileSystem, CF::LoadableDevice_ptr device, const std::string& componentId); - const SoftPkg* softpkg; - const SPD::Implementation* implementation; + const ossie::SoftPkg* softpkg; + const ossie::SPD::Implementation* implementation; DeploymentList dependencies; }; class ComponentDeployment : public SoftpkgDeployment, public UsesDeviceDeployment { public: - ComponentDeployment(const SoftPkg* softpkg, const ComponentInstantiation* instantiation, + ComponentDeployment(const ossie::SoftPkg* softpkg, + const ossie::ComponentInstantiation* instantiation, const std::string& identifier); /** @@ -177,7 +178,7 @@ namespace ossie { */ const std::string& getIdentifier() const; - const ComponentInstantiation* getInstantiation() const; + const ossie::ComponentInstantiation* getInstantiation() const; bool isResource() const; bool isConfigurable() const; @@ -214,8 +215,8 @@ namespace ossie { void overrideProperty(const std::string& id, const CORBA::Any& value); - void setAssignedDevice(const boost::shared_ptr& device); - boost::shared_ptr getAssignedDevice(); + void setAssignedDevice(const boost::shared_ptr& device); + boost::shared_ptr getAssignedDevice(); void setResourcePtr(CF::Resource_ptr resource); CF::Resource_ptr getResourcePtr() const; @@ -258,16 +259,16 @@ namespace ossie { */ redhawk::PropertyMap getInitializeProperties() const; - CF::DataType getPropertyValue(const Property* property) const; - const ComponentProperty* getPropertyOverride(const std::string& id) const; + CF::DataType getPropertyValue(const ossie::Property* property) const; + const ossie::ComponentProperty* getPropertyOverride(const std::string& id) const; void initializeProperties(); - const ComponentInstantiation* instantiation; + const ossie::ComponentInstantiation* instantiation; const std::string identifier; bool assemblyController; - boost::shared_ptr assignedDevice; + boost::shared_ptr assignedDevice; CF::Resource_var resource; redhawk::PropertyMap overrides; diff --git a/redhawk/src/control/sdr/dommgr/createHelper.h b/redhawk/src/control/sdr/dommgr/createHelper.h index 3257fcf7d..57daf8a99 100644 --- a/redhawk/src/control/sdr/dommgr/createHelper.h +++ b/redhawk/src/control/sdr/dommgr/createHelper.h @@ -96,28 +96,28 @@ class createHelper redhawk::ProfileCache _profileCache; - typedef std::vector DeploymentList; + typedef std::vector DeploymentList; typedef std::vector ProcessorList; typedef std::vector OSList; // createHelper helper methods - void assignPlacementsToDevices(ossie::ApplicationDeployment& appDeployment, + void assignPlacementsToDevices(redhawk::ApplicationDeployment& appDeployment, const DeviceAssignmentMap& devices); - void _validateDAS(ossie::ApplicationDeployment& appDeployment, const DeviceAssignmentMap& deviceAssignments); - void _connectComponents(ossie::ApplicationDeployment& appDeployment, + void _validateDAS(redhawk::ApplicationDeployment& appDeployment, const DeviceAssignmentMap& deviceAssignments); + void _connectComponents(redhawk::ApplicationDeployment& appDeployment, std::vector& connections); - void setUpExternalPorts(ossie::ApplicationDeployment& appDeployment, Application_impl* application); - void setUpExternalProperties(ossie::ApplicationDeployment& appDeployment, Application_impl* application); - void _placeHostCollocation(ossie::ApplicationDeployment& appDeployment, + void setUpExternalPorts(redhawk::ApplicationDeployment& appDeployment, Application_impl* application); + void setUpExternalProperties(redhawk::ApplicationDeployment& appDeployment, Application_impl* application); + void _placeHostCollocation(redhawk::ApplicationDeployment& appDeployment, const ossie::SoftwareAssembly::HostCollocation& collocation, const DeviceAssignmentMap& devices); - bool placeHostCollocation(ossie::ApplicationDeployment& appDeployment, + bool placeHostCollocation(redhawk::ApplicationDeployment& appDeployment, const DeploymentList& components, DeploymentList::const_iterator current, ossie::DeviceList& deploymentDevices, const ProcessorList& processorDeps=ProcessorList(), const OSList& osDeps=OSList()); - void _handleUsesDevices(ossie::ApplicationDeployment& appDeployment, + void _handleUsesDevices(redhawk::ApplicationDeployment& appDeployment, const std::string& appName); CF::Properties _consolidateAllocations(const DeploymentList& implementations); @@ -127,48 +127,48 @@ class createHelper // Supports allocation bool allocateUsesDevices(const std::vector& usesDevices, const CF::Properties& configureProperties, - ossie::UsesDeviceDeployment& assignedDevices, + redhawk::UsesDeviceDeployment& assignedDevices, ScopedAllocations& allocations); CF::AllocationManager::AllocationResponseSequence* allocateUsesDeviceProperties( const std::vector& component, const CF::Properties& configureProperties); - void allocateComponent(ossie::ApplicationDeployment& appDeployment, - ossie::ComponentDeployment* deployment, + void allocateComponent(redhawk::ApplicationDeployment& appDeployment, + redhawk::ComponentDeployment* deployment, const std::string& assignedDeviceId); - ossie::AllocationResult allocateComponentToDevice(ossie::ComponentDeployment* deployment, + ossie::AllocationResult allocateComponentToDevice(redhawk::ComponentDeployment* deployment, const std::string& assignedDeviceId, const std::string& appIdentifier); - bool allocateHostCollocation(ossie::ApplicationDeployment& appDeployment, + bool allocateHostCollocation(redhawk::ApplicationDeployment& appDeployment, const DeploymentList& components, ossie::DeviceList& deploymentDevices, const ProcessorList& processorDeps, const OSList& osDeps); - bool resolveSoftpkgDependencies(ossie::ApplicationDeployment& appDeployment, - ossie::SoftpkgDeployment* deployment, + bool resolveSoftpkgDependencies(redhawk::ApplicationDeployment& appDeployment, + redhawk::SoftpkgDeployment* deployment, ossie::DeviceNode& device); - ossie::SoftpkgDeployment* resolveDependencyImplementation(ossie::ApplicationDeployment& appDeployment, - const ossie::SPD::SoftPkgRef& ref, - ossie::DeviceNode& device); + redhawk::SoftpkgDeployment* resolveDependencyImplementation(redhawk::ApplicationDeployment& appDeployment, + const ossie::SPD::SoftPkgRef& ref, + ossie::DeviceNode& device); // Supports loading, executing, initializing, configuring, & connecting void loadAndExecuteComponents(const DeploymentList& deployments, CF::ApplicationRegistrar_ptr _appReg); void applyApplicationAffinityOptions(const DeploymentList& deployments); - void attemptComponentExecution(CF::ApplicationRegistrar_ptr registrar, ossie::ComponentDeployment* deployment); + void attemptComponentExecution(CF::ApplicationRegistrar_ptr registrar, redhawk::ComponentDeployment* deployment); void waitForComponentRegistration(const DeploymentList& deployments); void initializeComponents(const DeploymentList& deployments); void configureComponents(const DeploymentList& deployments); - void connectComponents(ossie::ApplicationDeployment& appDeployment, + void connectComponents(redhawk::ApplicationDeployment& appDeployment, std::vector& connections, std::string base_naming_context); - std::string resolveLoggingConfiguration(ossie::ComponentDeployment* deployment); + std::string resolveLoggingConfiguration(redhawk::ComponentDeployment* deployment); std::vector getStartOrder(const DeploymentList& deployments); // Cleanup - used when create fails/doesn't succeed for some reason From a95929eb20bbdd9ec3ceffaa827007c907bf182b Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 6 Jun 2016 16:00:49 -0400 Subject: [PATCH 0361/1644] Match case of profile object name for SoftPkgDeployment class --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 8 ++--- redhawk/src/control/sdr/dommgr/Deployment.cpp | 30 +++++++++---------- redhawk/src/control/sdr/dommgr/Deployment.h | 12 ++++---- redhawk/src/control/sdr/dommgr/createHelper.h | 4 +-- 4 files changed, 27 insertions(+), 27 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 0f1412633..37d727f8f 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -1355,7 +1355,7 @@ void createHelper::_castRequestProperties(CF::Properties& allocationProperties, } bool createHelper::resolveSoftpkgDependencies(redhawk::ApplicationDeployment& appDeployment, - redhawk::SoftpkgDeployment* deployment, + redhawk::SoftPkgDeployment* deployment, ossie::DeviceNode& device) { const ossie::SPD::Implementation* implementation = deployment->getImplementation(); @@ -1364,7 +1364,7 @@ bool createHelper::resolveSoftpkgDependencies(redhawk::ApplicationDeployment& ap for (iterSoftpkg = deps.begin(); iterSoftpkg != deps.end(); ++iterSoftpkg) { // Find an implementation whose dependencies match - redhawk::SoftpkgDeployment* dependency = resolveDependencyImplementation(appDeployment, *iterSoftpkg, device); + redhawk::SoftPkgDeployment* dependency = resolveDependencyImplementation(appDeployment, *iterSoftpkg, device); if (dependency) { deployment->addDependency(dependency); } else { @@ -1376,7 +1376,7 @@ bool createHelper::resolveSoftpkgDependencies(redhawk::ApplicationDeployment& ap return true; } -redhawk::SoftpkgDeployment* +redhawk::SoftPkgDeployment* createHelper::resolveDependencyImplementation(redhawk::ApplicationDeployment& appDeployment, const ossie::SPD::SoftPkgRef& ref, ossie::DeviceNode& device) @@ -1398,7 +1398,7 @@ createHelper::resolveDependencyImplementation(redhawk::ApplicationDeployment& ap continue; } - redhawk::SoftpkgDeployment* dependency = new redhawk::SoftpkgDeployment(softpkg, &implementation); + redhawk::SoftPkgDeployment* dependency = new redhawk::SoftPkgDeployment(softpkg, &implementation); // Recursively check any softpkg dependencies if (resolveSoftpkgDependencies(appDeployment, dependency, device)) { return dependency; diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index 09af72bbb..fc762f54e 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -86,44 +86,44 @@ CF::Device_ptr UsesDeviceAssignment::getAssignedDevice() const return CF::Device::_duplicate(assignedDevice); } -SoftpkgDeployment::SoftpkgDeployment(const SoftPkg* softpkg, +SoftPkgDeployment::SoftPkgDeployment(const SoftPkg* softpkg, const SPD::Implementation* implementation) : softpkg(softpkg), implementation(implementation) { } -SoftpkgDeployment::~SoftpkgDeployment() +SoftPkgDeployment::~SoftPkgDeployment() { clearDependencies(); } -const SoftPkg* SoftpkgDeployment::getSoftPkg() const +const SoftPkg* SoftPkgDeployment::getSoftPkg() const { return &(*softpkg); } -void SoftpkgDeployment::setImplementation(const SPD::Implementation* implementation) +void SoftPkgDeployment::setImplementation(const SPD::Implementation* implementation) { this->implementation = implementation; } -const SPD::Implementation* SoftpkgDeployment::getImplementation() const +const SPD::Implementation* SoftPkgDeployment::getImplementation() const { return implementation; } -void SoftpkgDeployment::addDependency(SoftpkgDeployment* dependency) +void SoftPkgDeployment::addDependency(SoftPkgDeployment* dependency) { dependencies.push_back(dependency); } -const std::vector& SoftpkgDeployment::getDependencies() +const std::vector& SoftPkgDeployment::getDependencies() { return dependencies; } -void SoftpkgDeployment::clearDependencies() +void SoftPkgDeployment::clearDependencies() { for (DeploymentList::iterator dependency = dependencies.begin(); dependency != dependencies.end(); ++dependency) { delete (*dependency); @@ -131,7 +131,7 @@ void SoftpkgDeployment::clearDependencies() dependencies.clear(); } -std::vector SoftpkgDeployment::getDependencyLocalFiles() +std::vector SoftPkgDeployment::getDependencyLocalFiles() { std::vector files; for (DeploymentList::iterator dependency = dependencies.begin(); dependency != dependencies.end(); ++dependency) { @@ -142,7 +142,7 @@ std::vector SoftpkgDeployment::getDependencyLocalFiles() return files; } -void SoftpkgDeployment::load(Application_impl* application, CF::FileSystem_ptr fileSystem, +void SoftPkgDeployment::load(Application_impl* application, CF::FileSystem_ptr fileSystem, CF::LoadableDevice_ptr device, const std::string& componentId) { if (!implementation) { @@ -187,7 +187,7 @@ void SoftpkgDeployment::load(Application_impl* application, CF::FileSystem_ptr f application->addComponentLoadedFile(componentId, fileName); } -std::string SoftpkgDeployment::getLocalFile() +std::string SoftPkgDeployment::getLocalFile() { fs::path codeLocalFile = fs::path(implementation->getCodeFile()); if (!codeLocalFile.has_root_directory()) { @@ -203,7 +203,7 @@ std::string SoftpkgDeployment::getLocalFile() return codeLocalFile.string(); } -CF::LoadableDevice::LoadType SoftpkgDeployment::getCodeType() const +CF::LoadableDevice::LoadType SoftPkgDeployment::getCodeType() const { switch (implementation->getCodeType()) { case SPD::Code::KERNEL_MODULE: @@ -219,7 +219,7 @@ CF::LoadableDevice::LoadType SoftpkgDeployment::getCodeType() const } } -bool SoftpkgDeployment::isExecutable() const +bool SoftPkgDeployment::isExecutable() const { // REDHAWK extends section D.2.1.6.3 to support loading a directory // and execute a file in that directory using a entrypoint @@ -244,7 +244,7 @@ bool SoftpkgDeployment::isExecutable() const ComponentDeployment::ComponentDeployment(const SoftPkg* softpkg, const ComponentInstantiation* instantiation, const std::string& identifier) : - SoftpkgDeployment(softpkg), + SoftPkgDeployment(softpkg), instantiation(instantiation), identifier(identifier), assemblyController(false) @@ -551,7 +551,7 @@ CF::Resource_ptr ComponentDeployment::getResourcePtr() const void ComponentDeployment::load(Application_impl* application, CF::FileSystem_ptr fileSystem, CF::LoadableDevice_ptr device) { - SoftpkgDeployment::load(application, fileSystem, device, identifier); + SoftPkgDeployment::load(application, fileSystem, device, identifier); } std::string ComponentDeployment::getLoggingConfiguration() const diff --git a/redhawk/src/control/sdr/dommgr/Deployment.h b/redhawk/src/control/sdr/dommgr/Deployment.h index 6027b8758..92bb59b32 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.h +++ b/redhawk/src/control/sdr/dommgr/Deployment.h @@ -134,13 +134,13 @@ namespace redhawk { AssignmentList assignments; }; - class SoftpkgDeployment + class SoftPkgDeployment { public: - typedef std::vector DeploymentList; + typedef std::vector DeploymentList; - SoftpkgDeployment(const ossie::SoftPkg* softpkg, const ossie::SPD::Implementation* implementation=0); - ~SoftpkgDeployment(); + SoftPkgDeployment(const ossie::SoftPkg* softpkg, const ossie::SPD::Implementation* implementation=0); + ~SoftPkgDeployment(); const ossie::SoftPkg* getSoftPkg() const; @@ -151,7 +151,7 @@ namespace redhawk { CF::LoadableDevice::LoadType getCodeType() const; bool isExecutable() const; - void addDependency(SoftpkgDeployment* dependency); + void addDependency(SoftPkgDeployment* dependency); const DeploymentList& getDependencies(); void clearDependencies(); @@ -166,7 +166,7 @@ namespace redhawk { DeploymentList dependencies; }; - class ComponentDeployment : public SoftpkgDeployment, public UsesDeviceDeployment + class ComponentDeployment : public SoftPkgDeployment, public UsesDeviceDeployment { public: ComponentDeployment(const ossie::SoftPkg* softpkg, diff --git a/redhawk/src/control/sdr/dommgr/createHelper.h b/redhawk/src/control/sdr/dommgr/createHelper.h index 57daf8a99..6612f06fa 100644 --- a/redhawk/src/control/sdr/dommgr/createHelper.h +++ b/redhawk/src/control/sdr/dommgr/createHelper.h @@ -147,9 +147,9 @@ class createHelper const OSList& osDeps); bool resolveSoftpkgDependencies(redhawk::ApplicationDeployment& appDeployment, - redhawk::SoftpkgDeployment* deployment, + redhawk::SoftPkgDeployment* deployment, ossie::DeviceNode& device); - redhawk::SoftpkgDeployment* resolveDependencyImplementation(redhawk::ApplicationDeployment& appDeployment, + redhawk::SoftPkgDeployment* resolveDependencyImplementation(redhawk::ApplicationDeployment& appDeployment, const ossie::SPD::SoftPkgRef& ref, ossie::DeviceNode& device); From dac46f0aaef66d615b356a18612c44bbf13c740d Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 7 Jun 2016 09:37:28 -0400 Subject: [PATCH 0362/1644] Fix spacing in log message --- redhawk/src/control/sdr/dommgr/Deployment.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index fc762f54e..f92342304 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -688,7 +688,7 @@ void ComponentDeployment::configure() if (partials.length() > 0) { std::ostringstream eout; eout << "Component " << identifier << " contains " << partials.length() - << "structure(s) with a mix of defined and nil values: "; + << " structure(s) with a mix of defined and nil values: "; bool first = true; for (size_t index = 0; index < partials.length(); ++index) { if (!first) { From ae2dc22d346f84f3cd0f6c83184190d9a8278653 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 7 Jun 2016 11:05:27 -0400 Subject: [PATCH 0363/1644] Move deployment exceptions to their own header and implementation files; store relevant information from component deployments in the exception, instead of counting on the deployment object to outlive the exception; handle placement errors using the same pattern --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 59 +++----- redhawk/src/control/sdr/dommgr/Deployment.cpp | 7 +- redhawk/src/control/sdr/dommgr/Deployment.h | 69 --------- .../sdr/dommgr/DeploymentExceptions.cpp | 49 +++++++ .../control/sdr/dommgr/DeploymentExceptions.h | 131 ++++++++++++++++++ redhawk/src/control/sdr/dommgr/Makefile.am | 1 + 6 files changed, 209 insertions(+), 107 deletions(-) create mode 100644 redhawk/src/control/sdr/dommgr/DeploymentExceptions.cpp create mode 100644 redhawk/src/control/sdr/dommgr/DeploymentExceptions.h diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 37d727f8f..e182889ad 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -44,6 +44,7 @@ #include "AllocationManager_impl.h" #include "RH_NamingContext.h" #include "ApplicationValidator.h" +#include "DeploymentExceptions.h" namespace fs = boost::filesystem; using namespace ossie; @@ -461,10 +462,7 @@ void createHelper::_placeHostCollocation(redhawk::ApplicationDeployment& appDepl LOG_TRACE(ApplicationFactory_impl, "Placing " << deployments.size() << " components"); if (!placeHostCollocation(appDeployment, deployments, deployments.begin(), deploymentDevices)) { - std::ostringstream eout; - eout << "Could not collocate components for collocation NAME: " << collocation.getName() << " ID:" << collocation.id; - LOG_ERROR(ApplicationFactory_impl, eout.str()); - throw CF::ApplicationFactory::CreateApplicationRequestError(); + throw redhawk::placement_failure(collocation, "failed to satisfy device dependencies"); } LOG_TRACE(ApplicationFactory_impl, "-- Completed placement for Collocation ID:" << collocation.getID() << " Components Placed: " << deployments.size()); @@ -682,11 +680,17 @@ throw (CORBA::SystemException, CF::ApplicationFactory::CreateApplicationError, } catch (CF::ApplicationFactory::CreateApplicationRequestError& ex) { LOG_ERROR(ApplicationFactory_impl, "Error in application creation") throw; + } catch (const redhawk::placement_failure& exc) { + // Unable to place a component or host collocation, report details + std::ostringstream eout; + eout << "Failed to place " << exc.name() << ": " << exc.what(); + LOG_ERROR(ApplicationFactory_impl, eout.str()); + throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EIO, eout.str().c_str()); } catch (const redhawk::execute_error& exc) { // A component failed execution, report details std::ostringstream eout; - eout << "Executing component " << exc.deployment()->getIdentifier(); - eout << " implementation " << exc.deployment()->getImplementation()->getID(); + eout << "Executing component " << exc.identifier(); + eout << " implementation " << exc.implementation(); eout << " failed on device " << exc.device()->identifier; eout << ": " << exc.what(); LOG_ERROR(ApplicationFactory_impl, eout.str()); @@ -695,14 +699,14 @@ throw (CORBA::SystemException, CF::ApplicationFactory::CreateApplicationError, // Unfortunately, InvalidInitConfiguration does not include an error // message, so log the error here to give more details std::ostringstream eout; - LOG_ERROR(ApplicationFactory_impl, "Component " << exc.deployment()->getIdentifier() - << " failed with " << exc.what() << " " << exc.properties()); + LOG_ERROR(ApplicationFactory_impl, "Component " << exc.identifier() + << " failed due to " << exc.what() << " " << exc.properties()); throw CF::ApplicationFactory::InvalidInitConfiguration(exc.properties()); } catch (const redhawk::deployment_error& exc) { // A component failed deployment in some other way, report details std::stringstream eout; - eout << "Component " << exc.deployment()->getIdentifier(); - eout << " implementation " << exc.deployment()->getImplementation()->getID(); + eout << "Deploying component " << exc.identifier(); + eout << " implementation " << exc.implementation(); eout << " failed: " << exc.what(); LOG_ERROR(ApplicationFactory_impl, eout.str()); throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EINVAL, eout.str().c_str()); @@ -1077,6 +1081,10 @@ void createHelper::allocateComponent(redhawk::ApplicationDeployment& appDeployme return; } + // Report failure, checking if the problem was that all executable devices + // were busy; this can yield false negatives (or positives) since it's not + // atomic with the allocation, but should provide a little extra insight in + // most cases bool allBusy = true; for (ossie::DeviceList::iterator dev = _executableDevices.begin(); dev != _executableDevices.end(); ++dev) { CF::Device::UsageType state; @@ -1092,19 +1100,9 @@ void createHelper::allocateComponent(redhawk::ApplicationDeployment& appDeployme } } if (allBusy) { - // Report failure - std::ostringstream eout; - eout << "Unable to launch component '"<getSoftPkg()->getName()<<"'. All executable devices (i.e.: GPP) in the Domain are busy"; - LOG_DEBUG(ApplicationFactory_impl, eout.str()); - throw CF::ApplicationFactory::CreateApplicationError(CF::CF_ENOSPC, eout.str().c_str()); + throw redhawk::placement_failure(deployment->getInstantiation(), "all executable devices (GPPs) in the Domain are busy"); } - - // Report failure - std::ostringstream eout; - eout << "Failed to satisfy device dependencies for component: '"; - eout << deployment->getSoftPkg()->getName() << "' with component id: '" << deployment->getIdentifier() << "'"; - LOG_DEBUG(ApplicationFactory_impl, eout.str()); - throw CF::ApplicationFactory::CreateApplicationError(CF::CF_ENOSPC, eout.str().c_str()); + throw redhawk::placement_failure(deployment->getInstantiation(), "failed to satisfy device dependencies"); } bool createHelper::allocateUsesDevices(const std::vector& usesDevices, @@ -1825,25 +1823,12 @@ void createHelper::initializeComponents(const DeploymentList& deployments) const std::string componentId = deployment->getIdentifier(); CORBA::Object_var objref = _application->getComponentObject(componentId); if (CORBA::is_nil(objref)) { - ostringstream eout; - eout << "No object found for component: '" << softpkg->getName() - << "' with component id: '" << componentId - << " assigned to device: '"<getAssignedDevice()->identifier<<"'"; - eout << " in waveform '" << _waveformContextName<<"';"; - eout << " error occurred near line:" <<__LINE__ << " in file:" << __FILE__ << ";"; - throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EIO, eout.str().c_str()); + throw redhawk::deployment_error(deployment, "component did not register with application"); } CF::Resource_var resource = ossie::corba::_narrowSafe(objref); if (CORBA::is_nil(resource)) { - ostringstream eout; - eout << "CF::Resource::_narrow failed with Unknown Exception for component: '" - << softpkg->getName() - << "' with component id: '" << componentId - << " assigned to device: '"<getAssignedDevice()->identifier<<"'"; - eout << " in waveform '" << _waveformContextName<<"';"; - eout << " error occurred near line:" <<__LINE__ << " in file:" << __FILE__ << ";"; - throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EIO, eout.str().c_str()); + throw redhawk::deployment_error(deployment, "component object is not a CF::Resource"); } deployment->setResourcePtr(resource); diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index f92342304..a60d095ce 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -27,6 +27,7 @@ #include "Application_impl.h" #include "PersistenceStore.h" #include "Deployment.h" +#include "DeploymentExceptions.h" using namespace redhawk; using namespace ossie; @@ -642,8 +643,12 @@ void ComponentDeployment::initialize() } catch (const CF::LifeCycle::InitializeError& error) { // Dump the detailed initialization failure to the log std::ostringstream logmsg; + logmsg << "initialize error"; for (CORBA::ULong index = 0; index < error.errorMessages.length(); ++index) { - logmsg << std::endl << error.errorMessages[index]; + if (index > 0) { + logmsg << ","; + } + logmsg << " '" << error.errorMessages[index] << "'"; } throw deployment_error(this, logmsg.str()); } catch (const CORBA::SystemException& exc) { diff --git a/redhawk/src/control/sdr/dommgr/Deployment.h b/redhawk/src/control/sdr/dommgr/Deployment.h index 92bb59b32..8c79a31a9 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.h +++ b/redhawk/src/control/sdr/dommgr/Deployment.h @@ -33,75 +33,6 @@ class Application_impl; namespace redhawk { - class ComponentDeployment; - - class deployment_error : public std::runtime_error { - public: - deployment_error(const ComponentDeployment* deployment, const std::string& message) : - std::runtime_error(message), - _deployment(deployment) - { - } - - virtual ~deployment_error() throw () - { - } - - const ComponentDeployment* deployment() const - { - return _deployment; - } - - private: - const ComponentDeployment* _deployment; - }; - - class execute_error : public deployment_error { - public: - execute_error(const ComponentDeployment* deployment, - const boost::shared_ptr& device, - const std::string& message) : - deployment_error(deployment, message), - _device(device) - { - } - - const boost::shared_ptr& device() const - { - return _device; - } - - virtual ~execute_error() throw () - { - } - - private: - boost::shared_ptr _device; - }; - - class properties_error : public deployment_error { - public: - properties_error(const ComponentDeployment* deployment, - const CF::Properties& properties, - const std::string& message) : - deployment_error(deployment, message), - _properties(properties) - { - } - - virtual ~properties_error() throw () - { - } - - const redhawk::PropertyMap& properties() const - { - return _properties; - } - - private: - const redhawk::PropertyMap _properties; - }; - class UsesDeviceAssignment { public: diff --git a/redhawk/src/control/sdr/dommgr/DeploymentExceptions.cpp b/redhawk/src/control/sdr/dommgr/DeploymentExceptions.cpp new file mode 100644 index 000000000..45cb8f143 --- /dev/null +++ b/redhawk/src/control/sdr/dommgr/DeploymentExceptions.cpp @@ -0,0 +1,49 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK core. + * + * REDHAWK core is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +#include + +#include "DeploymentExceptions.h" +#include "Deployment.h" + +using namespace redhawk; + +deployment_error::deployment_error(const ComponentDeployment* deployment, const std::string& message) : + std::runtime_error(message), + _identifier(deployment->getIdentifier()) +{ + if (deployment->getImplementation()) { + _implementation = deployment->getImplementation()->getID(); + } +} + +placement_failure::placement_failure(const ossie::ComponentInstantiation* instantiation, + const std::string& message) : + std::runtime_error(message), + _name("component " + instantiation->getID()) +{ +} + +placement_failure::placement_failure(const ossie::SoftwareAssembly::HostCollocation& collocation, + const std::string& message) : + std::runtime_error(message), + _name("host collocation " + collocation.getID() + " (" + collocation.getName() + ")") +{ +} diff --git a/redhawk/src/control/sdr/dommgr/DeploymentExceptions.h b/redhawk/src/control/sdr/dommgr/DeploymentExceptions.h new file mode 100644 index 000000000..2191d91fb --- /dev/null +++ b/redhawk/src/control/sdr/dommgr/DeploymentExceptions.h @@ -0,0 +1,131 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK core. + * + * REDHAWK core is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +#ifndef DEPLOYMENTEXCEPTIONS_H +#define DEPLOYMENTEXCEPTIONS_H + +#include +#include + +#include + +#include +#include + +namespace ossie { + class ComponentInstantiation; + class DeviceNode; +} + +namespace redhawk { + + class ComponentDeployment; + + class deployment_error : public std::runtime_error { + public: + deployment_error(const ComponentDeployment* deployment, const std::string& message); + + virtual ~deployment_error() throw () + { + } + + const std::string& identifier() const + { + return _identifier; + } + + const std::string& implementation() const + { + return _implementation; + } + + private: + std::string _identifier; + std::string _implementation; + }; + + class placement_failure : public std::runtime_error { + public: + placement_failure(const ossie::ComponentInstantiation* instantiation, const std::string& message); + + placement_failure(const ossie::SoftwareAssembly::HostCollocation& collocation, const std::string& message); + + virtual ~placement_failure() throw () + { + } + + const std::string& name() const + { + return _name; + } + + private: + std::string _name; + }; + + class execute_error : public deployment_error { + public: + execute_error(const ComponentDeployment* deployment, + const boost::shared_ptr& device, + const std::string& message) : + deployment_error(deployment, message), + _device(device) + { + } + + const boost::shared_ptr& device() const + { + return _device; + } + + virtual ~execute_error() throw () + { + } + + private: + boost::shared_ptr _device; + }; + + class properties_error : public deployment_error { + public: + properties_error(const ComponentDeployment* deployment, + const CF::Properties& properties, + const std::string& message) : + deployment_error(deployment, message), + _properties(properties) + { + } + + virtual ~properties_error() throw () + { + } + + const redhawk::PropertyMap& properties() const + { + return _properties; + } + + private: + const redhawk::PropertyMap _properties; + }; + +} + +#endif // DEPLOYMENTEXCEPTIONS_H diff --git a/redhawk/src/control/sdr/dommgr/Makefile.am b/redhawk/src/control/sdr/dommgr/Makefile.am index 3b35714b5..a0c733ae2 100644 --- a/redhawk/src/control/sdr/dommgr/Makefile.am +++ b/redhawk/src/control/sdr/dommgr/Makefile.am @@ -34,6 +34,7 @@ DomainManager_SOURCES = connectionSupport.cpp \ DomainManager_impl.cpp \ FakeApplication.cpp \ Deployment.cpp \ + DeploymentExceptions.cpp \ ApplicationDeployment.cpp \ ApplicationValidator.cpp \ ProfileCache.cpp \ From fbe7b615151ddedd6225c7e72df75b539e7f4fe5 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 7 Jun 2016 11:14:37 -0400 Subject: [PATCH 0364/1644] Check if all execute devices are busy in the failed collocation placement case --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 29 ++++++++++++------- redhawk/src/control/sdr/dommgr/createHelper.h | 1 + 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index e182889ad..9f1f6b0cb 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -462,6 +462,9 @@ void createHelper::_placeHostCollocation(redhawk::ApplicationDeployment& appDepl LOG_TRACE(ApplicationFactory_impl, "Placing " << deployments.size() << " components"); if (!placeHostCollocation(appDeployment, deployments, deployments.begin(), deploymentDevices)) { + if (_allDevicesBusy(deploymentDevices)) { + throw redhawk::placement_failure(collocation, "all executable devices (GPPs) in the Domain are busy"); + } throw redhawk::placement_failure(collocation, "failed to satisfy device dependencies"); } LOG_TRACE(ApplicationFactory_impl, "-- Completed placement for Collocation ID:" @@ -1082,11 +1085,19 @@ void createHelper::allocateComponent(redhawk::ApplicationDeployment& appDeployme } // Report failure, checking if the problem was that all executable devices - // were busy; this can yield false negatives (or positives) since it's not - // atomic with the allocation, but should provide a little extra insight in - // most cases - bool allBusy = true; - for (ossie::DeviceList::iterator dev = _executableDevices.begin(); dev != _executableDevices.end(); ++dev) { + // were busy + if (_allDevicesBusy(_executableDevices)) { + throw redhawk::placement_failure(deployment->getInstantiation(), "all executable devices (GPPs) in the Domain are busy"); + } + throw redhawk::placement_failure(deployment->getInstantiation(), "failed to satisfy device dependencies"); +} + +bool createHelper::_allDevicesBusy(ossie::DeviceList& devices) +{ + // While this can yield false negatives (or positives) since it's not + // atomic with component allocation, it should provide a little extra + // insight in most cases + for (ossie::DeviceList::iterator dev = devices.begin(); dev != devices.end(); ++dev) { CF::Device::UsageType state; try { state = (*dev)->device->usageState(); @@ -1095,14 +1106,10 @@ void createHelper::allocateComponent(redhawk::ApplicationDeployment& appDeployme continue; } if (state != CF::Device::BUSY) { - allBusy = false; - break; + return false; } } - if (allBusy) { - throw redhawk::placement_failure(deployment->getInstantiation(), "all executable devices (GPPs) in the Domain are busy"); - } - throw redhawk::placement_failure(deployment->getInstantiation(), "failed to satisfy device dependencies"); + return true; } bool createHelper::allocateUsesDevices(const std::vector& usesDevices, diff --git a/redhawk/src/control/sdr/dommgr/createHelper.h b/redhawk/src/control/sdr/dommgr/createHelper.h index 6612f06fa..4b44047ba 100644 --- a/redhawk/src/control/sdr/dommgr/createHelper.h +++ b/redhawk/src/control/sdr/dommgr/createHelper.h @@ -119,6 +119,7 @@ class createHelper const OSList& osDeps=OSList()); void _handleUsesDevices(redhawk::ApplicationDeployment& appDeployment, const std::string& appName); + bool _allDevicesBusy(ossie::DeviceList& devices); CF::Properties _consolidateAllocations(const DeploymentList& implementations); void _evaluateMATHinRequest(CF::Properties &request, const CF::Properties &configureProperties); From 0a6bab8ccf1d089d08977640e26a5f63d2abff73 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 7 Jun 2016 11:15:17 -0400 Subject: [PATCH 0365/1644] Remove inaccurate comment --- redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 9f1f6b0cb..7471bc156 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -986,11 +986,6 @@ CF::AllocationManager::AllocationResponseSequence* createHelper::allocateUsesDev * - Allocate capacity on usesdevice(s) * - Find and implementation that has it's implementation-specific usesdevice dependencies satisfied * - Allocate the component to a particular device - - Current implementation takes advantage of single failure then clean up everything..... To support collocation - allocation failover for mulitple devices, then we need to clean up only the allocations that we made during a failed - collocation request. This requires that we know and cleanup only those allocations that we made.. - */ void createHelper::allocateComponent(redhawk::ApplicationDeployment& appDeployment, redhawk::ComponentDeployment* deployment, From b485c04a4dc1053bf16840360250a9828dcb773d Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 7 Jun 2016 11:25:20 -0400 Subject: [PATCH 0366/1644] Convert a couple more exceptions into deployment errors --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 20 +++---------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 7471bc156..bf22c2340 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -1512,16 +1512,8 @@ void createHelper::loadAndExecuteComponents(const DeploymentList& deployments, // Get file name, load if it is not empty std::string codeLocalFile = deployment->getLocalFile(); if (codeLocalFile.empty()) { - ostringstream eout; - eout << "code.localfile is empty for component: '"; - eout << softpkg->getName(); - eout << "' with component id: '" << deployment->getIdentifier() << "' "; - eout << " with implementation id: '" << implementation->getID() << "'"; - eout << " on device id: '" << device->identifier << "'"; - eout << " in waveform '" << _waveformContextName<<"'"; - eout << " error occurred near line:" <<__LINE__ << " in file:" << __FILE__ << ";"; - LOG_TRACE(ApplicationFactory_impl, eout.str()) - throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EBADF, eout.str().c_str()); + // This should be caught by validation, but just in case + throw redhawk::deployment_error(deployment, "empty localfile"); } // narrow to LoadableDevice interface @@ -1539,13 +1531,7 @@ void createHelper::loadAndExecuteComponents(const DeploymentList& deployments, try { deployment->load(_application, _appFact._fileMgr, loadabledev); } catch (const std::exception& exc) { - std::ostringstream message; - message << "Unable to load component " << softpkg->getName() - << " implementation " << implementation->getID() - << " on device " << device->identifier - << ": " << exc.what(); - LOG_ERROR(ApplicationFactory_impl, message.str()); - throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EIO, message.str().c_str()); + throw redhawk::deployment_error(deployment, exc.what()); } if (deployment->isExecutable()) { From 09f9d64a3776881280072c51f543c8b7c2b6ca97 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 7 Jun 2016 13:39:51 -0400 Subject: [PATCH 0367/1644] Create a common base for deployment exceptions and rename the old deployment_exception component_exception --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 10 ++-- redhawk/src/control/sdr/dommgr/Deployment.cpp | 24 ++++----- redhawk/src/control/sdr/dommgr/Deployment.h | 4 +- .../sdr/dommgr/DeploymentExceptions.cpp | 8 +-- .../control/sdr/dommgr/DeploymentExceptions.h | 50 +++++++++++-------- 5 files changed, 53 insertions(+), 43 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index bf22c2340..2d77fb8ee 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -705,7 +705,7 @@ throw (CORBA::SystemException, CF::ApplicationFactory::CreateApplicationError, LOG_ERROR(ApplicationFactory_impl, "Component " << exc.identifier() << " failed due to " << exc.what() << " " << exc.properties()); throw CF::ApplicationFactory::InvalidInitConfiguration(exc.properties()); - } catch (const redhawk::deployment_error& exc) { + } catch (const redhawk::component_error& exc) { // A component failed deployment in some other way, report details std::stringstream eout; eout << "Deploying component " << exc.identifier(); @@ -1513,7 +1513,7 @@ void createHelper::loadAndExecuteComponents(const DeploymentList& deployments, std::string codeLocalFile = deployment->getLocalFile(); if (codeLocalFile.empty()) { // This should be caught by validation, but just in case - throw redhawk::deployment_error(deployment, "empty localfile"); + throw redhawk::component_error(deployment, "empty localfile"); } // narrow to LoadableDevice interface @@ -1531,7 +1531,7 @@ void createHelper::loadAndExecuteComponents(const DeploymentList& deployments, try { deployment->load(_application, _appFact._fileMgr, loadabledev); } catch (const std::exception& exc) { - throw redhawk::deployment_error(deployment, exc.what()); + throw redhawk::component_error(deployment, exc.what()); } if (deployment->isExecutable()) { @@ -1811,12 +1811,12 @@ void createHelper::initializeComponents(const DeploymentList& deployments) const std::string componentId = deployment->getIdentifier(); CORBA::Object_var objref = _application->getComponentObject(componentId); if (CORBA::is_nil(objref)) { - throw redhawk::deployment_error(deployment, "component did not register with application"); + throw redhawk::component_error(deployment, "component did not register with application"); } CF::Resource_var resource = ossie::corba::_narrowSafe(objref); if (CORBA::is_nil(resource)) { - throw redhawk::deployment_error(deployment, "component object is not a CF::Resource"); + throw redhawk::component_error(deployment, "component object is not a CF::Resource"); } deployment->setResourcePtr(resource); diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index a60d095ce..5ab5d5b7c 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -608,7 +608,7 @@ void ComponentDeployment::initializeProperties() } eout << partials[index].id; } - throw deployment_error(this, eout.str()); + throw component_error(this, eout.str()); } RH_NL_DEBUG("ApplicationFactory_impl", "Initializing properties for component " << identifier); @@ -621,13 +621,13 @@ void ComponentDeployment::initializeProperties() } catch (const CF::PropertyEmitter::AlreadyInitialized&) { // The component should never be initialized twice, at least not by the // ApplicationFactory - throw deployment_error(this, "already initialized"); + throw component_error(this, "already initialized"); } catch (const CORBA::SystemException& exc) { - throw deployment_error(this, "initializing properties raised " + ossie::corba::describeException(exc)); + throw component_error(this, "initializing properties raised " + ossie::corba::describeException(exc)); } catch (...) { - // Should never happen, but turn anything else into a deployment_error + // Should never happen, but turn anything else into a component_error // just in case - throw deployment_error(this, "unexpected error initializing properties"); + throw component_error(this, "unexpected error initializing properties"); } } @@ -650,13 +650,13 @@ void ComponentDeployment::initialize() } logmsg << " '" << error.errorMessages[index] << "'"; } - throw deployment_error(this, logmsg.str()); + throw component_error(this, logmsg.str()); } catch (const CORBA::SystemException& exc) { - throw deployment_error(this, "initialize raised " + ossie::corba::describeException(exc)); + throw component_error(this, "initialize raised " + ossie::corba::describeException(exc)); } catch (...) { - // Should never happen, but turn anything else into a deployment_error + // Should never happen, but turn anything else into a component_error // just in case - throw deployment_error(this, "unexpected error in initialize"); + throw component_error(this, "unexpected error in initialize"); } } @@ -683,7 +683,7 @@ void ComponentDeployment::configure() // NB: I think having a valid CORBA reference is a pre-condition of // getting to this point in the first place RH_NL_ERROR("ApplicationFactory_impl", "Could not get component reference"); - throw redhawk::deployment_error(this, "no CORBA reference"); + throw redhawk::component_error(this, "no CORBA reference"); } redhawk::PropertyMap config_props = getInitialConfigureProperties(); @@ -713,8 +713,8 @@ void ComponentDeployment::configure() } catch (const CF::PropertySet::PartialConfiguration& exc) { throw properties_error(this, exc.invalidProperties, "partial configuration in configure"); } catch (const CORBA::SystemException& exc) { - throw deployment_error(this, "configure raised " + ossie::corba::describeException(exc)); + throw component_error(this, "configure raised " + ossie::corba::describeException(exc)); } catch (...) { - throw deployment_error(this, "unexpected error configuring component"); + throw component_error(this, "unexpected error configuring component"); } } diff --git a/redhawk/src/control/sdr/dommgr/Deployment.h b/redhawk/src/control/sdr/dommgr/Deployment.h index 8c79a31a9..c21dd0d1b 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.h +++ b/redhawk/src/control/sdr/dommgr/Deployment.h @@ -161,7 +161,7 @@ namespace redhawk { * @brief Initializes the deployed component * @exception ossie::properties_error invalid properties in property * initialization - * @exception ossie::deployment_error initialization failed + * @exception ossie::component_error initialization failed * * Handles initialization of new-style 'property' kind properties and * calls initialize on the component. @@ -171,7 +171,7 @@ namespace redhawk { /** * @brief Configures legacy properties to initial values * @exception ossie::properties_error invalid properties - * @exception ossie::deployment_error configure failed + * @exception ossie::component_error configure failed * * Handles configuration of legacy 'configure' kind properties. */ diff --git a/redhawk/src/control/sdr/dommgr/DeploymentExceptions.cpp b/redhawk/src/control/sdr/dommgr/DeploymentExceptions.cpp index 45cb8f143..e417b7afd 100644 --- a/redhawk/src/control/sdr/dommgr/DeploymentExceptions.cpp +++ b/redhawk/src/control/sdr/dommgr/DeploymentExceptions.cpp @@ -25,8 +25,8 @@ using namespace redhawk; -deployment_error::deployment_error(const ComponentDeployment* deployment, const std::string& message) : - std::runtime_error(message), +component_error::component_error(const ComponentDeployment* deployment, const std::string& message) : + deployment_error(message), _identifier(deployment->getIdentifier()) { if (deployment->getImplementation()) { @@ -36,14 +36,14 @@ deployment_error::deployment_error(const ComponentDeployment* deployment, const placement_failure::placement_failure(const ossie::ComponentInstantiation* instantiation, const std::string& message) : - std::runtime_error(message), + deployment_error(message), _name("component " + instantiation->getID()) { } placement_failure::placement_failure(const ossie::SoftwareAssembly::HostCollocation& collocation, const std::string& message) : - std::runtime_error(message), + deployment_error(message), _name("host collocation " + collocation.getID() + " (" + collocation.getName() + ")") { } diff --git a/redhawk/src/control/sdr/dommgr/DeploymentExceptions.h b/redhawk/src/control/sdr/dommgr/DeploymentExceptions.h index 2191d91fb..6430d3acf 100644 --- a/redhawk/src/control/sdr/dommgr/DeploymentExceptions.h +++ b/redhawk/src/control/sdr/dommgr/DeploymentExceptions.h @@ -22,6 +22,7 @@ #define DEPLOYMENTEXCEPTIONS_H #include +#include #include #include @@ -36,56 +37,65 @@ namespace ossie { namespace redhawk { + class ApplicationDeployment; class ComponentDeployment; class deployment_error : public std::runtime_error { public: - deployment_error(const ComponentDeployment* deployment, const std::string& message); - - virtual ~deployment_error() throw () + deployment_error(const std::string& message) : + std::runtime_error(message) { } + }; - const std::string& identifier() const + class placement_failure : public deployment_error { + public: + placement_failure(const ossie::ComponentInstantiation* instantiation, const std::string& message); + + placement_failure(const ossie::SoftwareAssembly::HostCollocation& collocation, const std::string& message); + + virtual ~placement_failure() throw () { - return _identifier; } - const std::string& implementation() const + const std::string& name() const { - return _implementation; + return _name; } private: - std::string _identifier; - std::string _implementation; + std::string _name; }; - class placement_failure : public std::runtime_error { + class component_error : public deployment_error { public: - placement_failure(const ossie::ComponentInstantiation* instantiation, const std::string& message); + component_error(const ComponentDeployment* deployment, const std::string& message); - placement_failure(const ossie::SoftwareAssembly::HostCollocation& collocation, const std::string& message); + virtual ~component_error() throw () + { + } - virtual ~placement_failure() throw () + const std::string& identifier() const { + return _identifier; } - const std::string& name() const + const std::string& implementation() const { - return _name; + return _implementation; } private: - std::string _name; + std::string _identifier; + std::string _implementation; }; - class execute_error : public deployment_error { + class execute_error : public component_error { public: execute_error(const ComponentDeployment* deployment, const boost::shared_ptr& device, const std::string& message) : - deployment_error(deployment, message), + component_error(deployment, message), _device(device) { } @@ -103,12 +113,12 @@ namespace redhawk { boost::shared_ptr _device; }; - class properties_error : public deployment_error { + class properties_error : public component_error { public: properties_error(const ComponentDeployment* deployment, const CF::Properties& properties, const std::string& message) : - deployment_error(deployment, message), + component_error(deployment, message), _properties(properties) { } From a65fac751044d68f2e98656a94fe3a86872ccce4 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 7 Jun 2016 14:37:51 -0400 Subject: [PATCH 0368/1644] Improve error handling for application connections to pass through as much contextual information as possible --- .../sdr/dommgr/ApplicationDeployment.cpp | 17 +++---- .../sdr/dommgr/ApplicationFactory_impl.cpp | 38 +++++++-------- .../control/sdr/dommgr/DeploymentExceptions.h | 21 +++++++++ .../control/sdr/dommgr/connectionSupport.cpp | 47 ++++++++++--------- .../control/sdr/dommgr/connectionSupport.h | 20 ++++++-- redhawk/src/control/sdr/dommgr/createHelper.h | 2 - 6 files changed, 84 insertions(+), 61 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp b/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp index dfa6fd0a1..c01177c57 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp @@ -182,7 +182,7 @@ CF::Resource_ptr ApplicationDeployment::lookupComponentByInstantiationId(const s if (deployment) { return deployment->getResourcePtr(); } - return CF::Resource::_nil(); + throw ossie::LookupError("component '" + identifier + "' not found"); } CF::Device_ptr ApplicationDeployment::lookupDeviceThatLoadedComponentInstantiationId(const std::string& componentId) @@ -191,14 +191,12 @@ CF::Device_ptr ApplicationDeployment::lookupDeviceThatLoadedComponentInstantiati ComponentDeployment* deployment = getComponentDeployment(componentId); if (!deployment) { - LOG_WARN(ApplicationDeployment, "[DeviceLookup] Component not found"); - return CF::Device::_nil(); + throw ossie::LookupError("component '" + componentId + "' not found"); } boost::shared_ptr device = deployment->getAssignedDevice(); if (!device) { - LOG_WARN(ApplicationDeployment, "[DeviceLookup] Component not assigned to device"); - return CF::Device::_nil(); + throw ossie::LookupError("component '" + componentId + "' is not assigned to a device"); } LOG_TRACE(ApplicationDeployment, "[DeviceLookup] Assigned device id " << device->identifier); @@ -212,14 +210,12 @@ CF::Device_ptr ApplicationDeployment::lookupDeviceUsedByComponentInstantiationId ComponentDeployment* deployment = getComponentDeployment(componentId); if (!deployment) { - LOG_WARN(ApplicationDeployment, "[DeviceLookup] Component not found"); - return CF::Device::_nil(); + throw ossie::LookupError("component '" + componentId + "' not found"); } UsesDeviceAssignment* uses = deployment->getUsesDeviceAssignment(usesId); if (!uses) { - LOG_WARN(ApplicationDeployment, "[DeviceLookup] UsesDevice not found"); - return CF::Device::_nil(); + throw ossie::LookupError("component '" + componentId + "' has no usesdevice '" + usesId + "'"); } CF::Device_var device = uses->getAssignedDevice(); @@ -234,8 +230,7 @@ CF::Device_ptr ApplicationDeployment::lookupDeviceUsedByApplication(const std::s UsesDeviceAssignment* uses = getUsesDeviceAssignment(usesRefId); if (!uses) { - LOG_WARN(ApplicationDeployment, "[DeviceLookup] UsesDevice not found"); - return CF::Device::_nil(); + throw ossie::LookupError("application has no usesdevice '" + usesRefId + "'"); } CF::Device_var device = uses->getAssignedDevice(); diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 2d77fb8ee..3e4cf1cfc 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -237,20 +237,6 @@ ApplicationFactory_impl::~ApplicationFactory_impl () } -void createHelper::_connectComponents(redhawk::ApplicationDeployment& appDeployment, - std::vector& connections){ - try{ - connectComponents(appDeployment, connections, _baseNamingContext); - } catch (CF::ApplicationFactory::CreateApplicationError& ex) { - throw; - } CATCH_THROW_LOG_TRACE( - ApplicationFactory_impl, - "Connecting components failed (unclear where this occurred)", - CF::ApplicationFactory::CreateApplicationError( - CF::CF_EINVAL, - "Connecting components failed (unclear where this occurred)")); -} - void createHelper::assignPlacementsToDevices(redhawk::ApplicationDeployment& appDeployment, const DeviceAssignmentMap& devices) { @@ -713,6 +699,13 @@ throw (CORBA::SystemException, CF::ApplicationFactory::CreateApplicationError, eout << " failed: " << exc.what(); LOG_ERROR(ApplicationFactory_impl, eout.str()); throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EINVAL, eout.str().c_str()); + } catch (const redhawk::connection_error& exc) { + // A connection defined in the SAD could not be made, either because an + // endpoint could not be resolved, or connectPort failed + std::ostringstream eout; + eout << "Unable to make connection '" << exc.identifier() << "': " << exc.what(); + LOG_ERROR(ApplicationFactory_impl, eout.str()); + throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EIO, eout.str().c_str()); } catch (const std::exception& ex) { std::ostringstream eout; eout << "The following standard exception occurred: "<lookupDeviceThatLoadedComponentInstantiationId(refid); - if (CORBA::is_nil(device)) { - LOG_ERROR(AppConnectionManager, "devicethatloadedthiscomponentref not found"); - } - return device; + return _deviceLookup->lookupDeviceThatLoadedComponentInstantiationId(refid); } CF::Device_ptr AppConnectionManager::resolveDeviceUsedByThisComponentRef(const std::string& refid, const std::string& usesrefid) { - CF::Device_ptr device = _deviceLookup->lookupDeviceUsedByComponentInstantiationId(refid, usesrefid); - if (CORBA::is_nil(device)) { - LOG_ERROR(AppConnectionManager, "deviceusedbythiscomponentref not found"); - } - return device; + return _deviceLookup->lookupDeviceUsedByComponentInstantiationId(refid, usesrefid); } CF::Device_ptr AppConnectionManager::resolveDeviceUsedByApplication(const std::string& usesrefid) { - CF::Device_ptr device = _deviceLookup->lookupDeviceUsedByApplication(usesrefid); - if (CORBA::is_nil(device)) { - LOG_ERROR(AppConnectionManager, "deviceusedbyapplication not found"); - } - return device; + return _deviceLookup->lookupDeviceUsedByApplication(usesrefid); } const std::vector& AppConnectionManager::getConnections() { @@ -207,7 +202,7 @@ PREPARE_CF_LOGGING(DomainConnectionManager); DomainConnectionManager::DomainConnectionManager(DomainLookup* domainLookup, ComponentLookup* componentLookup, const std::string& domainName) : - ConnectionManager(domainLookup, componentLookup, domainName), + ConnectionManager(domainLookup, componentLookup, domainName, false), _connectionsByRequester() { } @@ -692,12 +687,20 @@ bool ConnectionNode::connect(ConnectionManager& manager) try { usesObject = uses->resolve(manager); } catch ( ... ) { - LOG_TRACE(ConnectionNode, "Unable to resolve the uses object"); + if (manager.exceptionsEnabled()) { + throw; + } else { + LOG_TRACE(ConnectionNode, "Unable to resolve the uses object"); + } } try { providesPort = provides->resolve(manager); } catch ( ... ) { - LOG_TRACE(ConnectionNode, "Unable to resolve the provides object"); + if (manager.exceptionsEnabled()) { + throw; + } else { + LOG_TRACE(ConnectionNode, "Unable to resolve the provides object"); + } } if (CORBA::is_nil(usesObject) || CORBA::is_nil(providesPort)) { diff --git a/redhawk/src/control/sdr/dommgr/connectionSupport.h b/redhawk/src/control/sdr/dommgr/connectionSupport.h index a5b508ab6..3a7edb51b 100644 --- a/redhawk/src/control/sdr/dommgr/connectionSupport.h +++ b/redhawk/src/control/sdr/dommgr/connectionSupport.h @@ -50,6 +50,14 @@ namespace ossie } }; + class LookupError : public std::runtime_error { + public: + LookupError(const std::string& message) : + std::runtime_error(message) + { + } + }; + // Interface to look up components by their identifier. class ComponentLookup { @@ -207,9 +215,6 @@ namespace ossie ENABLE_LOGGING; public: - ConnectionManager(DomainLookup* domainLookup, - ComponentLookup* componentLookup, - const std::string& namingContext); virtual ~ConnectionManager(); static void disconnectAll(ConnectionList& connections, ossie::DomainLookup* domainLookup); @@ -227,11 +232,18 @@ namespace ossie virtual CF::Device_ptr resolveDeviceUsedByThisComponentRef(const std::string& refid, const std::string& usesid) = 0; virtual CF::Device_ptr resolveDeviceUsedByApplication(const std::string& usesrefid) = 0; + bool exceptionsEnabled(); + protected: + ConnectionManager(DomainLookup* domainLookup, + ComponentLookup* componentLookup, + const std::string& namingContext, + bool enableExceptions); + ossie::DomainLookup* _domainLookup; ossie::ComponentLookup* _componentLookup; std::string _namingContext; - + bool _enableExceptions; }; class AppConnectionManager : public ConnectionManager diff --git a/redhawk/src/control/sdr/dommgr/createHelper.h b/redhawk/src/control/sdr/dommgr/createHelper.h index 4b44047ba..8a5341ce7 100644 --- a/redhawk/src/control/sdr/dommgr/createHelper.h +++ b/redhawk/src/control/sdr/dommgr/createHelper.h @@ -104,8 +104,6 @@ class createHelper void assignPlacementsToDevices(redhawk::ApplicationDeployment& appDeployment, const DeviceAssignmentMap& devices); void _validateDAS(redhawk::ApplicationDeployment& appDeployment, const DeviceAssignmentMap& deviceAssignments); - void _connectComponents(redhawk::ApplicationDeployment& appDeployment, - std::vector& connections); void setUpExternalPorts(redhawk::ApplicationDeployment& appDeployment, Application_impl* application); void setUpExternalProperties(redhawk::ApplicationDeployment& appDeployment, Application_impl* application); void _placeHostCollocation(redhawk::ApplicationDeployment& appDeployment, From bd05d03cad35dc96ba029d8d687cb6a7835d7af2 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 7 Jun 2016 15:30:43 -0400 Subject: [PATCH 0369/1644] Throw LookupErrors from DomainManager for additional context for application connection failures --- .../src/control/sdr/dommgr/DomainManager_impl.cpp | 11 +++++++---- redhawk/src/control/sdr/dommgr/connectionSupport.cpp | 12 +++++++++++- redhawk/src/control/sdr/dommgr/connectionSupport.h | 2 ++ 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp b/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp index 2d645f6b6..ef0496415 100644 --- a/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp @@ -2226,21 +2226,24 @@ CORBA::Object_ptr DomainManager_impl::lookupDomainObject (const std::string& typ LOG_TRACE(DomainManager_impl, "Found service " << name); return CORBA::Object::_duplicate(serviceNode->service); } - LOG_WARN(DomainManager_impl, "No service found for servicename '" << name << "'"); + throw ossie::LookupError("no service '" + name + "' found"); } else if (type == "servicetype") { ServiceList::iterator serviceNode = findServiceByType(name); if (serviceNode != _registeredServices.end()) { LOG_TRACE(DomainManager_impl, "Found service " << serviceNode->name << " supporting '" << name << "'"); return CORBA::Object::_duplicate(serviceNode->service); } - LOG_WARN(DomainManager_impl, "No service found for servicetype '" << name << "'"); + throw ossie::LookupError("no service found for type '" + name + "'"); } else if (type == "domainmanager") { return _this(); } else if (type == "application") { Application_impl* application = findApplicationById(name); - if (application) { - return application->_this(); + if (!application) { + throw ossie::LookupError("no application '" + name + "' found"); } + return application->_this(); + } else { + throw ossie::LookupError("invalid domainfinder type '" + type + "'"); } return CORBA::Object::_nil(); } diff --git a/redhawk/src/control/sdr/dommgr/connectionSupport.cpp b/redhawk/src/control/sdr/dommgr/connectionSupport.cpp index 3bef0b5d9..2f514b398 100644 --- a/redhawk/src/control/sdr/dommgr/connectionSupport.cpp +++ b/redhawk/src/control/sdr/dommgr/connectionSupport.cpp @@ -85,7 +85,17 @@ CORBA::Object_ptr ConnectionManager::resolveComponent(const std::string& identif CORBA::Object_ptr ConnectionManager::resolveDomainObject(const std::string& type, const std::string& name) { - return _domainLookup->lookupDomainObject(type, name); + try { + return _domainLookup->lookupDomainObject(type, name); + } catch (const LookupError& error) { + if (exceptionsEnabled()) { + // Pass the exception on to the caller + throw; + } else { + LOG_WARN(ConnectionManager, "Failed to resolve domain object: " << error.what()); + } + } + return CORBA::Object::_nil(); } CORBA::Object_ptr ConnectionManager::resolveFindByNamingService(const std::string& name) diff --git a/redhawk/src/control/sdr/dommgr/connectionSupport.h b/redhawk/src/control/sdr/dommgr/connectionSupport.h index 3a7edb51b..0b2ef49fd 100644 --- a/redhawk/src/control/sdr/dommgr/connectionSupport.h +++ b/redhawk/src/control/sdr/dommgr/connectionSupport.h @@ -50,6 +50,8 @@ namespace ossie } }; + // Exception type that may be thrown when an implementation of one of the + // lookup interfaces cannot find the requested object. class LookupError : public std::runtime_error { public: LookupError(const std::string& message) : From b6192cb163efc67a43a33cebcc4cd56994942c0e Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 7 Jun 2016 16:11:14 -0400 Subject: [PATCH 0370/1644] Switch deployment exception names to mixed-case for more consistency with other exceptions (like InvalidConnection, LookupError, etc.) --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 48 +++++++++---------- redhawk/src/control/sdr/dommgr/Deployment.cpp | 42 ++++++++-------- .../sdr/dommgr/DeploymentExceptions.cpp | 16 +++---- .../control/sdr/dommgr/DeploymentExceptions.h | 46 +++++++++--------- 4 files changed, 76 insertions(+), 76 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 3e4cf1cfc..d2c87156f 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -449,9 +449,9 @@ void createHelper::_placeHostCollocation(redhawk::ApplicationDeployment& appDepl LOG_TRACE(ApplicationFactory_impl, "Placing " << deployments.size() << " components"); if (!placeHostCollocation(appDeployment, deployments, deployments.begin(), deploymentDevices)) { if (_allDevicesBusy(deploymentDevices)) { - throw redhawk::placement_failure(collocation, "all executable devices (GPPs) in the Domain are busy"); + throw redhawk::PlacementFailure(collocation, "all executable devices (GPPs) in the Domain are busy"); } - throw redhawk::placement_failure(collocation, "failed to satisfy device dependencies"); + throw redhawk::PlacementFailure(collocation, "failed to satisfy device dependencies"); } LOG_TRACE(ApplicationFactory_impl, "-- Completed placement for Collocation ID:" << collocation.getID() << " Components Placed: " << deployments.size()); @@ -669,13 +669,13 @@ throw (CORBA::SystemException, CF::ApplicationFactory::CreateApplicationError, } catch (CF::ApplicationFactory::CreateApplicationRequestError& ex) { LOG_ERROR(ApplicationFactory_impl, "Error in application creation") throw; - } catch (const redhawk::placement_failure& exc) { + } catch (const redhawk::PlacementFailure& exc) { // Unable to place a component or host collocation, report details std::ostringstream eout; eout << "Failed to place " << exc.name() << ": " << exc.what(); LOG_ERROR(ApplicationFactory_impl, eout.str()); throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EIO, eout.str().c_str()); - } catch (const redhawk::execute_error& exc) { + } catch (const redhawk::ExecuteError& exc) { // A component failed execution, report details std::ostringstream eout; eout << "Executing component " << exc.identifier(); @@ -684,14 +684,14 @@ throw (CORBA::SystemException, CF::ApplicationFactory::CreateApplicationError, eout << ": " << exc.what(); LOG_ERROR(ApplicationFactory_impl, eout.str()); throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EIO, eout.str().c_str()); - } catch (const redhawk::properties_error& exc) { + } catch (const redhawk::PropertiesError& exc) { // Unfortunately, InvalidInitConfiguration does not include an error // message, so log the error here to give more details std::ostringstream eout; LOG_ERROR(ApplicationFactory_impl, "Component " << exc.identifier() << " failed due to " << exc.what() << " " << exc.properties()); throw CF::ApplicationFactory::InvalidInitConfiguration(exc.properties()); - } catch (const redhawk::component_error& exc) { + } catch (const redhawk::ComponentError& exc) { // A component failed deployment in some other way, report details std::stringstream eout; eout << "Deploying component " << exc.identifier(); @@ -699,7 +699,7 @@ throw (CORBA::SystemException, CF::ApplicationFactory::CreateApplicationError, eout << " failed: " << exc.what(); LOG_ERROR(ApplicationFactory_impl, eout.str()); throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EINVAL, eout.str().c_str()); - } catch (const redhawk::connection_error& exc) { + } catch (const redhawk::ConnectionError& exc) { // A connection defined in the SAD could not be made, either because an // endpoint could not be resolved, or connectPort failed std::ostringstream eout; @@ -1075,9 +1075,9 @@ void createHelper::allocateComponent(redhawk::ApplicationDeployment& appDeployme // Report failure, checking if the problem was that all executable devices // were busy if (_allDevicesBusy(_executableDevices)) { - throw redhawk::placement_failure(deployment->getInstantiation(), "all executable devices (GPPs) in the Domain are busy"); + throw redhawk::PlacementFailure(deployment->getInstantiation(), "all executable devices (GPPs) in the Domain are busy"); } - throw redhawk::placement_failure(deployment->getInstantiation(), "failed to satisfy device dependencies"); + throw redhawk::PlacementFailure(deployment->getInstantiation(), "failed to satisfy device dependencies"); } bool createHelper::_allDevicesBusy(ossie::DeviceList& devices) @@ -1506,7 +1506,7 @@ void createHelper::loadAndExecuteComponents(const DeploymentList& deployments, std::string codeLocalFile = deployment->getLocalFile(); if (codeLocalFile.empty()) { // This should be caught by validation, but just in case - throw redhawk::component_error(deployment, "empty localfile"); + throw redhawk::ComponentError(deployment, "empty localfile"); } // narrow to LoadableDevice interface @@ -1524,7 +1524,7 @@ void createHelper::loadAndExecuteComponents(const DeploymentList& deployments, try { deployment->load(_application, _appFact._fileMgr, loadabledev); } catch (const std::exception& exc) { - throw redhawk::component_error(deployment, exc.what()); + throw redhawk::ComponentError(deployment, exc.what()); } if (deployment->isExecutable()) { @@ -1664,30 +1664,30 @@ void createHelper::attemptComponentExecution (CF::ApplicationRegistrar_ptr regis // call 'execute' on the ExecutableDevice to execute the component pid = execdev->executeLinked(entryPoint.c_str(), options, execParameters, dep_seq); } catch (const CF::InvalidFileName&) { - throw redhawk::execute_error(deployment, device, "invalid filename"); + throw redhawk::ExecuteError(deployment, device, "invalid filename"); } catch (const CF::Device::InvalidState& exc) { std::string message = "invalid device state " + std::string(exc.msg); - throw redhawk::execute_error(deployment, device, message); + throw redhawk::ExecuteError(deployment, device, message); } catch (const CF::ExecutableDevice::InvalidParameters& exc) { std::string message = "invalid parameters " + redhawk::PropertyMap::cast(exc.invalidParms).toString(); - throw redhawk::execute_error(deployment, device, message); + throw redhawk::ExecuteError(deployment, device, message); } catch (const CF::ExecutableDevice::InvalidOptions& exc) { std::string message = "invalid options " + redhawk::PropertyMap::cast(exc.invalidOpts).toString(); - throw redhawk::execute_error(deployment, device, message); + throw redhawk::ExecuteError(deployment, device, message); } catch (const CF::ExecutableDevice::ExecuteFail& exc) { std::string message = "execute failure " + std::string(exc.msg); - throw redhawk::execute_error(deployment, device, message); + throw redhawk::ExecuteError(deployment, device, message); } catch (const CORBA::SystemException& exc) { - throw redhawk::execute_error(deployment, device, ossie::corba::describeException(exc)); + throw redhawk::ExecuteError(deployment, device, ossie::corba::describeException(exc)); } catch (...) { - // Should never happen, but turn anything else into an execute_error + // Should never happen, but turn anything else into an ExecuteError // just in case - throw redhawk::execute_error(deployment, device, "unexpected error"); + throw redhawk::ExecuteError(deployment, device, "unexpected error"); } // handle pid output if (pid < 0) { - throw redhawk::execute_error(deployment, device, "execute returned invalid process ID"); + throw redhawk::ExecuteError(deployment, device, "execute returned invalid process ID"); } else { _application->setComponentPid(deployment->getIdentifier(), pid); } @@ -1804,12 +1804,12 @@ void createHelper::initializeComponents(const DeploymentList& deployments) const std::string componentId = deployment->getIdentifier(); CORBA::Object_var objref = _application->getComponentObject(componentId); if (CORBA::is_nil(objref)) { - throw redhawk::component_error(deployment, "component did not register with application"); + throw redhawk::ComponentError(deployment, "component did not register with application"); } CF::Resource_var resource = ossie::corba::_narrowSafe(objref); if (CORBA::is_nil(resource)) { - throw redhawk::component_error(deployment, "component object is not a CF::Resource"); + throw redhawk::ComponentError(deployment, "component object is not a CF::Resource"); } deployment->setResourcePtr(resource); @@ -1869,10 +1869,10 @@ void createHelper::connectComponents(redhawk::ApplicationDeployment& appDeployme try { resolved = connectionManager.resolveConnection(connection); } catch (const std::exception& exc) { - throw redhawk::connection_error(connection.getID(), exc.what()); + throw redhawk::ConnectionError(connection.getID(), exc.what()); } if (!resolved) { - throw redhawk::connection_error(connection.getID(), "connection failed"); + throw redhawk::ConnectionError(connection.getID(), "connection failed"); } } diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index 5ab5d5b7c..07be25888 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -169,21 +169,21 @@ void SoftPkgDeployment::load(Application_impl* application, CF::FileSystem_ptr f } catch (const CF::Device::InvalidState& exc) { std::string message = "device is in invalid state: "; message += exc.msg; - throw std::runtime_error(message); + throw DeploymentError(message); } catch (const CF::LoadableDevice::InvalidLoadKind& exc) { - throw std::runtime_error("invalid load kind for file " + fileName); + throw DeploymentError("invalid load kind for file " + fileName); } catch (const CF::InvalidFileName& exc) { std::string message = "file name '" + fileName + "' is invalid: "; message += exc.msg; - throw std::runtime_error(message); + throw DeploymentError(message); } catch (const CF::LoadableDevice::LoadFail& exc) { std::string message = "failure loading file '" + fileName + "': "; message += exc.msg; - throw std::runtime_error(message); + throw DeploymentError(message); } catch (const CORBA::SystemException& exc) { std::string message = ossie::corba::describeException(exc); message += " loading " + fileName; - throw std::runtime_error(message); + throw DeploymentError(message); } application->addComponentLoadedFile(componentId, fileName); } @@ -608,26 +608,26 @@ void ComponentDeployment::initializeProperties() } eout << partials[index].id; } - throw component_error(this, eout.str()); + throw ComponentError(this, eout.str()); } RH_NL_DEBUG("ApplicationFactory_impl", "Initializing properties for component " << identifier); try { resource->initializeProperties(init_props); } catch (const CF::PropertySet::InvalidConfiguration& exc) { - throw properties_error(this, exc.invalidProperties, "invalid configuration in property initialization"); + throw PropertiesError(this, exc.invalidProperties, "invalid configuration in property initialization"); } catch (const CF::PropertySet::PartialConfiguration& exc) { - throw properties_error(this, exc.invalidProperties, "partial configuration in property initialization"); + throw PropertiesError(this, exc.invalidProperties, "partial configuration in property initialization"); } catch (const CF::PropertyEmitter::AlreadyInitialized&) { // The component should never be initialized twice, at least not by the // ApplicationFactory - throw component_error(this, "already initialized"); + throw ComponentError(this, "already initialized"); } catch (const CORBA::SystemException& exc) { - throw component_error(this, "initializing properties raised " + ossie::corba::describeException(exc)); + throw ComponentError(this, "initializing properties raised " + ossie::corba::describeException(exc)); } catch (...) { - // Should never happen, but turn anything else into a component_error + // Should never happen, but turn anything else into a ComponentError // just in case - throw component_error(this, "unexpected error initializing properties"); + throw ComponentError(this, "unexpected error initializing properties"); } } @@ -650,13 +650,13 @@ void ComponentDeployment::initialize() } logmsg << " '" << error.errorMessages[index] << "'"; } - throw component_error(this, logmsg.str()); + throw ComponentError(this, logmsg.str()); } catch (const CORBA::SystemException& exc) { - throw component_error(this, "initialize raised " + ossie::corba::describeException(exc)); + throw ComponentError(this, "initialize raised " + ossie::corba::describeException(exc)); } catch (...) { - // Should never happen, but turn anything else into a component_error + // Should never happen, but turn anything else into a ComponentError // just in case - throw component_error(this, "unexpected error in initialize"); + throw ComponentError(this, "unexpected error in initialize"); } } @@ -683,7 +683,7 @@ void ComponentDeployment::configure() // NB: I think having a valid CORBA reference is a pre-condition of // getting to this point in the first place RH_NL_ERROR("ApplicationFactory_impl", "Could not get component reference"); - throw redhawk::component_error(this, "no CORBA reference"); + throw redhawk::ComponentError(this, "no CORBA reference"); } redhawk::PropertyMap config_props = getInitialConfigureProperties(); @@ -709,12 +709,12 @@ void ComponentDeployment::configure() try { resource->configure(config_props); } catch (const CF::PropertySet::InvalidConfiguration& exc) { - throw properties_error(this, exc.invalidProperties, "invalid configuration in configure"); + throw PropertiesError(this, exc.invalidProperties, "invalid configuration in configure"); } catch (const CF::PropertySet::PartialConfiguration& exc) { - throw properties_error(this, exc.invalidProperties, "partial configuration in configure"); + throw PropertiesError(this, exc.invalidProperties, "partial configuration in configure"); } catch (const CORBA::SystemException& exc) { - throw component_error(this, "configure raised " + ossie::corba::describeException(exc)); + throw ComponentError(this, "configure raised " + ossie::corba::describeException(exc)); } catch (...) { - throw component_error(this, "unexpected error configuring component"); + throw ComponentError(this, "unexpected error configuring component"); } } diff --git a/redhawk/src/control/sdr/dommgr/DeploymentExceptions.cpp b/redhawk/src/control/sdr/dommgr/DeploymentExceptions.cpp index e417b7afd..3ec3a8ff0 100644 --- a/redhawk/src/control/sdr/dommgr/DeploymentExceptions.cpp +++ b/redhawk/src/control/sdr/dommgr/DeploymentExceptions.cpp @@ -25,8 +25,8 @@ using namespace redhawk; -component_error::component_error(const ComponentDeployment* deployment, const std::string& message) : - deployment_error(message), +ComponentError::ComponentError(const ComponentDeployment* deployment, const std::string& message) : + DeploymentError(message), _identifier(deployment->getIdentifier()) { if (deployment->getImplementation()) { @@ -34,16 +34,16 @@ component_error::component_error(const ComponentDeployment* deployment, const st } } -placement_failure::placement_failure(const ossie::ComponentInstantiation* instantiation, - const std::string& message) : - deployment_error(message), +PlacementFailure::PlacementFailure(const ossie::ComponentInstantiation* instantiation, + const std::string& message) : + DeploymentError(message), _name("component " + instantiation->getID()) { } -placement_failure::placement_failure(const ossie::SoftwareAssembly::HostCollocation& collocation, - const std::string& message) : - deployment_error(message), +PlacementFailure::PlacementFailure(const ossie::SoftwareAssembly::HostCollocation& collocation, + const std::string& message) : + DeploymentError(message), _name("host collocation " + collocation.getID() + " (" + collocation.getName() + ")") { } diff --git a/redhawk/src/control/sdr/dommgr/DeploymentExceptions.h b/redhawk/src/control/sdr/dommgr/DeploymentExceptions.h index 8022ea4c7..a69435439 100644 --- a/redhawk/src/control/sdr/dommgr/DeploymentExceptions.h +++ b/redhawk/src/control/sdr/dommgr/DeploymentExceptions.h @@ -40,23 +40,23 @@ namespace redhawk { class ApplicationDeployment; class ComponentDeployment; - class deployment_error : public std::runtime_error { + class DeploymentError : public std::runtime_error { public: - deployment_error(const std::string& message) : + DeploymentError(const std::string& message) : std::runtime_error(message) { } }; - class connection_error : public deployment_error { + class ConnectionError : public DeploymentError { public: - connection_error(const std::string& identifier, const std::string& message) : - deployment_error(message), + ConnectionError(const std::string& identifier, const std::string& message) : + DeploymentError(message), _identifier(identifier) { } - virtual ~connection_error() throw() + virtual ~ConnectionError() throw() { } @@ -69,13 +69,13 @@ namespace redhawk { const std::string _identifier; }; - class placement_failure : public deployment_error { + class PlacementFailure : public DeploymentError { public: - placement_failure(const ossie::ComponentInstantiation* instantiation, const std::string& message); + PlacementFailure(const ossie::ComponentInstantiation* instantiation, const std::string& message); - placement_failure(const ossie::SoftwareAssembly::HostCollocation& collocation, const std::string& message); + PlacementFailure(const ossie::SoftwareAssembly::HostCollocation& collocation, const std::string& message); - virtual ~placement_failure() throw () + virtual ~PlacementFailure() throw () { } @@ -88,11 +88,11 @@ namespace redhawk { std::string _name; }; - class component_error : public deployment_error { + class ComponentError : public DeploymentError { public: - component_error(const ComponentDeployment* deployment, const std::string& message); + ComponentError(const ComponentDeployment* deployment, const std::string& message); - virtual ~component_error() throw () + virtual ~ComponentError() throw () { } @@ -111,12 +111,12 @@ namespace redhawk { std::string _implementation; }; - class execute_error : public component_error { + class ExecuteError : public ComponentError { public: - execute_error(const ComponentDeployment* deployment, - const boost::shared_ptr& device, - const std::string& message) : - component_error(deployment, message), + ExecuteError(const ComponentDeployment* deployment, + const boost::shared_ptr& device, + const std::string& message) : + ComponentError(deployment, message), _device(device) { } @@ -126,7 +126,7 @@ namespace redhawk { return _device; } - virtual ~execute_error() throw () + virtual ~ExecuteError() throw () { } @@ -134,17 +134,17 @@ namespace redhawk { boost::shared_ptr _device; }; - class properties_error : public component_error { + class PropertiesError : public ComponentError { public: - properties_error(const ComponentDeployment* deployment, + PropertiesError(const ComponentDeployment* deployment, const CF::Properties& properties, const std::string& message) : - component_error(deployment, message), + ComponentError(deployment, message), _properties(properties) { } - virtual ~properties_error() throw () + virtual ~PropertiesError() throw () { } From 5cf584224f18f3ac5ecfbaf8a5bab36a17d89ed7 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 7 Jun 2016 16:43:49 -0400 Subject: [PATCH 0371/1644] Handle fetching of component objects after waiting for registration, dropping some redundant checks --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 76 +++++++++---------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index d2c87156f..1db7ce8bf 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -1741,7 +1741,7 @@ void createHelper::waitForComponentRegistration(const DeploymentList& deployment { // Wait for all components to be registered before continuing int componentBindingTimeout = _appFact._domainManager->getComponentBindingTimeout(); - LOG_TRACE(ApplicationFactory_impl, "Waiting " << componentBindingTimeout << "s for all components register"); + LOG_TRACE(ApplicationFactory_impl, "Waiting " << componentBindingTimeout << "s for all components to register"); // Track only SCA-compliant components; non-compliant components will never // register with the application, nor do they need to be initialized @@ -1758,20 +1758,44 @@ void createHelper::waitForComponentRegistration(const DeploymentList& deployment if (!_application->waitForComponents(expected_components, componentBindingTimeout)) { // For reference, determine much time has really elapsed. time_t elapsed = time(NULL)-start; - LOG_ERROR(ApplicationFactory_impl, "Timed out waiting for component to bind to naming context (" << elapsed << "s elapsed)"); - ostringstream eout; - for (unsigned int req_idx = 0; req_idx < deployments.size(); req_idx++) { - redhawk::ComponentDeployment* deployment = deployments[req_idx]; - if (expected_components.count(deployment->getIdentifier())) { - eout << "Timed out waiting for component to register: '" << deployment->getSoftPkg()->getName() - << "' with component id: '" << deployment->getIdentifier() - << " assigned to device: '" << deployment->getAssignedDevice()->identifier; - break; + LOG_ERROR(ApplicationFactory_impl, "Timed out waiting for components to register (" << elapsed << "s elapsed)"); + } + + // Fetch the objects, finding any components that did not register + BOOST_FOREACH(redhawk::ComponentDeployment* deployment, deployments) { + if (deployment->getSoftPkg()->isScaCompliant()) { + // Find the component on the Application + const std::string componentId = deployment->getIdentifier(); + CORBA::Object_var objref = _application->getComponentObject(componentId); + if (CORBA::is_nil(objref)) { + throw redhawk::ComponentError(deployment, "component did not register with application"); + } + + // Occasionally, omniORB may have a cached connection where the + // other end has terminated (this is particularly a problem with + // Java, because the Sun ORB never closes connections on shutdown). + // If the new component just happens to have the same TCP/IP + // address and port, the first time we try to reach the component, + // it will get a CORBA.COMM_FAILURE exception even though the + // reference is valid. In this case, a call to _non_existent() + // should cause omniORB to clean up the stale socket, and any + // subsequent calls behave normally. + try { + objref->_non_existent(); + } catch (...) { + LOG_DEBUG(ApplicationFactory_impl, "Component object did not respond to initial ping"); + } + + // Convert to a CF::Resource object + if (deployment->isResource()) { + CF::Resource_var resource = ossie::corba::_narrowSafe(objref); + if (CORBA::is_nil(resource)) { + throw redhawk::ComponentError(deployment, "component object is not a CF::Resource"); + } + + deployment->setResourcePtr(resource); } } - eout << " in waveform '" << _waveformContextName<<"';"; - eout << " error occurred near line:" <<__LINE__ << " in file:" << __FILE__ << ";"; - throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EIO, eout.str().c_str()); } } @@ -1793,35 +1817,11 @@ void createHelper::initializeComponents(const DeploymentList& deployments) if (!softpkg->isScaCompliant()) { LOG_TRACE(ApplicationFactory_impl, "Component is non SCA-compliant, continuing to next component"); continue; - } - - if (!deployment->isResource()) { + } else if (!deployment->isResource()) { LOG_TRACE(ApplicationFactory_impl, "Component is not a resource, continuing to next component"); continue; } - // Find the component on the Application - const std::string componentId = deployment->getIdentifier(); - CORBA::Object_var objref = _application->getComponentObject(componentId); - if (CORBA::is_nil(objref)) { - throw redhawk::ComponentError(deployment, "component did not register with application"); - } - - CF::Resource_var resource = ossie::corba::_narrowSafe(objref); - if (CORBA::is_nil(resource)) { - throw redhawk::ComponentError(deployment, "component object is not a CF::Resource"); - } - - deployment->setResourcePtr(resource); - - int initAttempts=3; - while ( initAttempts > 0 ) { - initAttempts--; - if ( ossie::corba::objectExists(resource) == true ) { initAttempts = 0; continue; } - LOG_DEBUG(ApplicationFactory_impl, "Retrying component ping............ comp:" << deployment->getIdentifier() << " waveform: " << _waveformContextName); - usleep(1000); - } - deployment->initialize(); } } From a8c18e62edfca681b2ed40b965d2ff6c05c83f42 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 8 Jun 2016 09:17:57 -0400 Subject: [PATCH 0372/1644] Update exception handling for usesdevice failures --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 68 +++++++++---------- .../sdr/dommgr/DeploymentExceptions.cpp | 14 ++++ .../control/sdr/dommgr/DeploymentExceptions.h | 24 +++++++ redhawk/src/control/sdr/dommgr/createHelper.h | 2 + 4 files changed, 74 insertions(+), 34 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 1db7ce8bf..df5313ff8 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -472,27 +472,25 @@ void createHelper::_handleUsesDevices(redhawk::ApplicationDeployment& appDeploym redhawk::UsesDeviceDeployment assignedDevices; if (!allocateUsesDevices(usesDevices, appProperties, assignedDevices, this->_allocations)) { // There were unsatisfied usesdevices for the application - ostringstream eout; - eout << "Failed to satisfy 'usesdevice' dependencies "; - bool first = true; - for (std::vector::const_iterator uses = usesDevices.begin(); uses != usesDevices.end(); ++uses) { - if (!assignedDevices.getUsesDeviceAssignment(uses->getID())) { - if (!first) { - eout << ", "; - } else { - first = false; - } - eout << uses->getID(); - } - } - eout << "for application '" << appName << "'"; - LOG_DEBUG(ApplicationFactory_impl, eout.str()); - throw CF::ApplicationFactory::CreateApplicationError(CF::CF_ENOSPC, eout.str().c_str()); + std::vector failed_ids = _getFailedUsesDevices(usesDevices, assignedDevices); + throw redhawk::UsesDeviceFailure(appDeployment, failed_ids); } assignedDevices.transferUsesDeviceAssignments(appDeployment); } +std::vector createHelper::_getFailedUsesDevices(const std::vector& usesDevices, + redhawk::UsesDeviceDeployment& assignedDevices) +{ + std::vector failed_ids; + BOOST_FOREACH(const ossie::UsesDevice& uses, usesDevices) { + if (!assignedDevices.getUsesDeviceAssignment(uses.getID())) { + failed_ids.push_back(uses.getID()); + } + } + return failed_ids; +} + void createHelper::setUpExternalPorts(redhawk::ApplicationDeployment& appDeployment, Application_impl* application) { @@ -675,6 +673,22 @@ throw (CORBA::SystemException, CF::ApplicationFactory::CreateApplicationError, eout << "Failed to place " << exc.name() << ": " << exc.what(); LOG_ERROR(ApplicationFactory_impl, eout.str()); throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EIO, eout.str().c_str()); + } catch (const redhawk::UsesDeviceFailure& exc) { + // One or more usesdevice(s) could not be allocated + std::ostringstream eout; + eout << "Failed to satisfy 'usesdevice' dependencies "; + bool first = true; + BOOST_FOREACH(const std::string& id, exc.ids()) { + if (!first) { + eout << ", "; + } else { + first = false; + } + eout << id; + } + eout << " for " << exc.context(); + LOG_ERROR(ApplicationFactory_impl, eout.str()); + throw CF::ApplicationFactory::CreateApplicationError(CF::CF_ENOSPC, eout.str().c_str()); } catch (const redhawk::ExecuteError& exc) { // A component failed execution, report details std::ostringstream eout; @@ -987,26 +1001,12 @@ void createHelper::allocateComponent(redhawk::ApplicationDeployment& appDeployme redhawk::PropertyMap alloc_context = deployment->getAllocationContext(); // Find the devices that allocate the SPD's minimum required usesdevices properties - const std::vector& usesDevVec = deployment->getSoftPkg()->getUsesDevices(); + const std::vector& usesDevices = deployment->getSoftPkg()->getUsesDevices(); redhawk::UsesDeviceDeployment assignedDevices; - if (!allocateUsesDevices(usesDevVec, alloc_context, assignedDevices, this->_allocations)) { + if (!allocateUsesDevices(usesDevices, alloc_context, assignedDevices, this->_allocations)) { // There were unsatisfied usesdevices for the component - ostringstream eout; - eout << "Failed to satisfy 'usesdevice' dependencies "; - bool first = true; - for (std::vector::const_iterator uses = usesDevVec.begin(); uses != usesDevVec.end(); ++uses) { - if (!assignedDevices.getUsesDeviceAssignment(uses->getID())) { - if (!first) { - eout << ", "; - } else { - first = false; - } - eout << uses->getID(); - } - } - eout << "for component '" << deployment->getIdentifier() << "'"; - LOG_DEBUG(ApplicationFactory_impl, eout.str()); - throw CF::ApplicationFactory::CreateApplicationError(CF::CF_ENOSPC, eout.str().c_str()); + std::vector failed_ids = _getFailedUsesDevices(usesDevices, assignedDevices); + throw redhawk::UsesDeviceFailure(deployment, failed_ids); } // now attempt to find an implementation that can have it's allocation requirements met diff --git a/redhawk/src/control/sdr/dommgr/DeploymentExceptions.cpp b/redhawk/src/control/sdr/dommgr/DeploymentExceptions.cpp index 3ec3a8ff0..f38811a4e 100644 --- a/redhawk/src/control/sdr/dommgr/DeploymentExceptions.cpp +++ b/redhawk/src/control/sdr/dommgr/DeploymentExceptions.cpp @@ -25,6 +25,20 @@ using namespace redhawk; +UsesDeviceFailure::UsesDeviceFailure(const ApplicationDeployment&, const std::vector& ids) : + DeploymentError("failed to satisfy usesdevice dependencies"), + _context("application"), + _ids(ids) +{ +} + +UsesDeviceFailure::UsesDeviceFailure(const ComponentDeployment* component, const std::vector& ids) : + DeploymentError("failed to satisfy usesdevice dependencies"), + _context("component '" + component->getInstantiation()->getID() + "'"), + _ids(ids) +{ +} + ComponentError::ComponentError(const ComponentDeployment* deployment, const std::string& message) : DeploymentError(message), _identifier(deployment->getIdentifier()) diff --git a/redhawk/src/control/sdr/dommgr/DeploymentExceptions.h b/redhawk/src/control/sdr/dommgr/DeploymentExceptions.h index a69435439..b1c0e38a0 100644 --- a/redhawk/src/control/sdr/dommgr/DeploymentExceptions.h +++ b/redhawk/src/control/sdr/dommgr/DeploymentExceptions.h @@ -48,6 +48,30 @@ namespace redhawk { } }; + class UsesDeviceFailure : public DeploymentError { + public: + UsesDeviceFailure(const ApplicationDeployment& application, const std::vector& ids); + UsesDeviceFailure(const ComponentDeployment* component, const std::vector& ids); + + virtual ~UsesDeviceFailure() throw() + { + } + + const std::string& context() const + { + return _context; + } + + const std::vector& ids() const + { + return _ids; + } + + private: + std::string _context; + std::vector _ids; + }; + class ConnectionError : public DeploymentError { public: ConnectionError(const std::string& identifier, const std::string& message) : diff --git a/redhawk/src/control/sdr/dommgr/createHelper.h b/redhawk/src/control/sdr/dommgr/createHelper.h index 8a5341ce7..9c0c8a620 100644 --- a/redhawk/src/control/sdr/dommgr/createHelper.h +++ b/redhawk/src/control/sdr/dommgr/createHelper.h @@ -117,6 +117,8 @@ class createHelper const OSList& osDeps=OSList()); void _handleUsesDevices(redhawk::ApplicationDeployment& appDeployment, const std::string& appName); + std::vector _getFailedUsesDevices(const std::vector& usesDevices, + redhawk::UsesDeviceDeployment& assignedDevices); bool _allDevicesBusy(ossie::DeviceList& devices); CF::Properties _consolidateAllocations(const DeploymentList& implementations); From 9e5080dac68c1847efe07dcd0d58a3d86762534e Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 8 Jun 2016 09:50:06 -0400 Subject: [PATCH 0373/1644] Turn any exception in qtbrowse's application creation into a dialog box with the error text, instead of dumping to the console --- .../base/framework/python/ossie/apps/qtbrowse/browsewindow.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/redhawk/src/base/framework/python/ossie/apps/qtbrowse/browsewindow.py b/redhawk/src/base/framework/python/ossie/apps/qtbrowse/browsewindow.py index 0004cb93c..f12cf3d71 100644 --- a/redhawk/src/base/framework/python/ossie/apps/qtbrowse/browsewindow.py +++ b/redhawk/src/base/framework/python/ossie/apps/qtbrowse/browsewindow.py @@ -365,6 +365,9 @@ def createSelected (self): except CF.ApplicationFactory.CreateApplicationError, e: QMessageBox.critical(self, 'Creation of waveform failed.', e.msg, QMessageBox.Ok) return + except: + QMessageBox.critical(self, 'Creation of waveform failed', str(sys.exc_info()[1]), QMessageBox.Ok) + return if app_inst == None: QMessageBox.critical(self, 'Creation of waveform failed.', 'Unable to create Application instance for $SDRROOT'+app, QMessageBox.Ok) From 7c026f4c8cc9592413c4f2881731421508c4a251 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 8 Jun 2016 10:08:42 -0400 Subject: [PATCH 0374/1644] Reject empty or invalid assembly controller in SAD parsing, instead of waiting until application creation --- .../control/include/ossie/SoftwareAssembly.h | 1 - .../src/control/parser/SoftwareAssembly.cpp | 24 +++++++------------ .../sdr/dommgr/ApplicationFactory_impl.cpp | 15 ++++++------ 3 files changed, 16 insertions(+), 24 deletions(-) diff --git a/redhawk/src/control/include/ossie/SoftwareAssembly.h b/redhawk/src/control/include/ossie/SoftwareAssembly.h index de75db8ad..e329f3b72 100644 --- a/redhawk/src/control/include/ossie/SoftwareAssembly.h +++ b/redhawk/src/control/include/ossie/SoftwareAssembly.h @@ -149,7 +149,6 @@ namespace ossie { void validateComponentPlacements(std::vector& placements); std::auto_ptr _sad; - ComponentInstantiation* _assemblyController; }; } #endif diff --git a/redhawk/src/control/parser/SoftwareAssembly.cpp b/redhawk/src/control/parser/SoftwareAssembly.cpp index 5f045394a..3e6e79702 100644 --- a/redhawk/src/control/parser/SoftwareAssembly.cpp +++ b/redhawk/src/control/parser/SoftwareAssembly.cpp @@ -37,14 +37,12 @@ const ComponentInstantiation* SoftwareAssembly::HostCollocation::getInstantiatio } SoftwareAssembly::SoftwareAssembly() : - _sad(0), - _assemblyController(0) + _sad(0) { } SoftwareAssembly::SoftwareAssembly(std::istream& input) throw (ossie::parser_error) : - _sad(0), - _assemblyController(0) + _sad(0) { this->load(input); } @@ -61,10 +59,12 @@ void SoftwareAssembly::load(std::istream& input) throw (ossie::parser_error) } validateComponentPlacements(_sad->partitioning.placements); - // If assemblycontroller is set, make sure it was found during component - // validation - if (!_sad->assemblycontroller.empty() && !_assemblyController) { - throw ossie::parser_error("assemblycontroller has invalid componentinstantiationref " + _sad->assemblycontroller); + // Make sure assemblycontroller is set, and references a real component + if (_sad->assemblycontroller.empty()) { + throw ossie::parser_error("assemblycontroller is not set"); + } + if (!getComponentInstantiation(_sad->assemblycontroller)) { + throw ossie::parser_error("assemblycontroller has invalid componentinstantiationref '" + _sad->assemblycontroller + "'"); } } @@ -74,15 +74,9 @@ void SoftwareAssembly::validateComponentPlacements(std::vectorfilename; - - BOOST_FOREACH(ComponentInstantiation& instance, placement.instantiations) { - if (!_sad->assemblycontroller.empty() && _sad->assemblycontroller == instance.instantiationId) { - _assemblyController = &instance; - } - } } } diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index df5313ff8..3cb21967b 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -862,23 +862,22 @@ CF::Application_ptr createHelper::create ( waitForComponentRegistration(app_deployment.getComponentDeployments()); - initializeComponents(app_deployment.getComponentDeployments()); - // Check that the assembly controller is valid LOG_TRACE(ApplicationFactory_impl, "Checking assembly controller"); redhawk::ComponentDeployment* ac_deployment = app_deployment.getAssemblyController(); if (!ac_deployment) { - const char* message = "Assembly controller has not been assigned"; - LOG_ERROR(ApplicationFactory_impl, message); - throw CF::ApplicationFactory::CreateApplicationError(CF::CF_NOTSET, message); + // This condition should have been prevented by parser validation + throw std::logic_error("Assembly controller has not been assigned"); } CF::Resource_var assemblyController = assemblyController = ac_deployment->getResourcePtr(); if (CORBA::is_nil(assemblyController) && ac_deployment->getSoftPkg()->isScaCompliant()) { - const char* message = "Assembly controller has not registered with the application"; - LOG_ERROR(ApplicationFactory_impl, message); - throw CF::ApplicationFactory::CreateApplicationError(CF::CF_NOTSET, message); + // Likewise, component registration should have already thrown an + // exception if an SCA-compliant component did not register + throw std::logic_error("Assembly controller has not registered with the application"); } + initializeComponents(app_deployment.getComponentDeployments()); + connectComponents(app_deployment, connections, _baseNamingContext); configureComponents(app_deployment.getComponentDeployments()); From 4d14eabbc1de3b9f76cf56786c6b1b6389212f20 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 8 Jun 2016 11:29:21 -0400 Subject: [PATCH 0375/1644] Reject invalid component references for external ports and proerties in SAD parsing, instead of waiting until application creation --- .../control/include/ossie/SoftwareAssembly.h | 2 ++ .../src/control/parser/SoftwareAssembly.cpp | 21 +++++++++++++++++++ .../sdr/dommgr/ApplicationFactory_impl.cpp | 13 ++++-------- 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/redhawk/src/control/include/ossie/SoftwareAssembly.h b/redhawk/src/control/include/ossie/SoftwareAssembly.h index e329f3b72..d377d2e2c 100644 --- a/redhawk/src/control/include/ossie/SoftwareAssembly.h +++ b/redhawk/src/control/include/ossie/SoftwareAssembly.h @@ -147,6 +147,8 @@ namespace ossie { protected: void validateComponentPlacements(std::vector& placements); + void validateExternalPorts(std::vector& ports); + void validateExternalProperties(std::vector& properties); std::auto_ptr _sad; }; diff --git a/redhawk/src/control/parser/SoftwareAssembly.cpp b/redhawk/src/control/parser/SoftwareAssembly.cpp index 3e6e79702..410157c4a 100644 --- a/redhawk/src/control/parser/SoftwareAssembly.cpp +++ b/redhawk/src/control/parser/SoftwareAssembly.cpp @@ -66,6 +66,9 @@ void SoftwareAssembly::load(std::istream& input) throw (ossie::parser_error) if (!getComponentInstantiation(_sad->assemblycontroller)) { throw ossie::parser_error("assemblycontroller has invalid componentinstantiationref '" + _sad->assemblycontroller + "'"); } + + validateExternalPorts(_sad->externalports); + validateExternalProperties(_sad->externalproperties); } void SoftwareAssembly::validateComponentPlacements(std::vector& placements) @@ -80,6 +83,24 @@ void SoftwareAssembly::validateComponentPlacements(std::vector& ports) +{ + BOOST_FOREACH(SoftwareAssembly::Port& port, ports) { + if (!getComponentInstantiation(port.componentrefid)) { + throw ossie::parser_error("external port '" + port.getExternalName() + "' has invalid componentrefid '" + port.componentrefid + "'"); + } + } +} + +void SoftwareAssembly::validateExternalProperties(std::vector& properties) +{ + BOOST_FOREACH(SoftwareAssembly::Property& property, properties) { + if (!getComponentInstantiation(property.comprefid)) { + throw ossie::parser_error("external property '" + property.getExternalID() + "' has invalid comprefid '" + property.comprefid + "'"); + } + } +} + const std::string& SoftwareAssembly::getID() const { assert(_sad.get() != 0); return _sad->id; diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 3cb21967b..662c1940f 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -507,13 +507,8 @@ void createHelper::setUpExternalPorts(redhawk::ApplicationDeployment& appDeploym // Get the component from the instantiation identifier. redhawk::ComponentDeployment* deployment = appDeployment.getComponentDeployment(port->componentrefid); if (!deployment) { - LOG_ERROR(ApplicationFactory_impl, - "Invalid componentinstantiationref (" - <componentrefid - <<") given for an external port "); - throw(CF::ApplicationFactory::CreateApplicationError( - CF::CF_NOTSET, - "Invalid componentinstantiationref given for external port")); + // The SAD parser should have rejected invalid component references + throw std::logic_error("component not found for external port '" + port->getExternalName() + "'"); } CF::Resource_var resource = deployment->getResourcePtr(); @@ -562,8 +557,8 @@ void createHelper::setUpExternalProperties(redhawk::ApplicationDeployment& appDe // Get the component from the compref identifier. redhawk::ComponentDeployment* deployment = appDeployment.getComponentDeployment(prop->comprefid); if (!deployment) { - LOG_ERROR(ApplicationFactory_impl, "Unable to find component for comprefid " << prop->comprefid); - throw CF::ApplicationFactory::CreateApplicationError(CF::CF_NOTSET, "Unable to find component for given comprefid"); + // The SAD parser should have rejected invalid component references + throw std::logic_error("component not found for external property '" + prop->getExternalID() + "'"); } const Property* property = deployment->getSoftPkg()->getProperties()->getProperty(prop->propid); if (!property){ From 98ac1368cecffac7bd8ad0a9b347d41c4012bffc Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 8 Jun 2016 13:41:28 -0400 Subject: [PATCH 0376/1644] Delay throwing a LookupError on component lookup until the ConnectionManager has had a chance to check the domain for a DeviceManager --- redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp | 2 +- redhawk/src/control/sdr/dommgr/connectionSupport.cpp | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp b/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp index c01177c57..50142e0a2 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp @@ -182,7 +182,7 @@ CF::Resource_ptr ApplicationDeployment::lookupComponentByInstantiationId(const s if (deployment) { return deployment->getResourcePtr(); } - throw ossie::LookupError("component '" + identifier + "' not found"); + return CF::Resource::_nil(); } CF::Device_ptr ApplicationDeployment::lookupDeviceThatLoadedComponentInstantiationId(const std::string& componentId) diff --git a/redhawk/src/control/sdr/dommgr/connectionSupport.cpp b/redhawk/src/control/sdr/dommgr/connectionSupport.cpp index 2f514b398..3aa68d2c9 100644 --- a/redhawk/src/control/sdr/dommgr/connectionSupport.cpp +++ b/redhawk/src/control/sdr/dommgr/connectionSupport.cpp @@ -78,7 +78,11 @@ CORBA::Object_ptr ConnectionManager::resolveComponent(const std::string& identif target = _domainLookup->lookupDeviceManagerByInstantiationId(identifier); } if (CORBA::is_nil(target)) { - LOG_DEBUG(ConnectionManager, "Could not locate component with instantiation id " << identifier); + if (exceptionsEnabled()) { + throw ossie::LookupError("component '" + identifier + "' not found"); + } else { + LOG_DEBUG(ConnectionManager, "Could not locate component with instantiation id " << identifier); + } } return target._retn(); } From 9ef05930d4f4e3c499532d1e4e922c9d25e0bce3 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 8 Jun 2016 13:42:12 -0400 Subject: [PATCH 0377/1644] Update test to account for earlier failure with applications that have invalid component references in external properties; this shouldn't really affect anyone, because create() was always going to fail --- redhawk/src/testing/tests/test_08_SADProperties.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/redhawk/src/testing/tests/test_08_SADProperties.py b/redhawk/src/testing/tests/test_08_SADProperties.py index 88d37aca8..3fed269a0 100644 --- a/redhawk/src/testing/tests/test_08_SADProperties.py +++ b/redhawk/src/testing/tests/test_08_SADProperties.py @@ -225,15 +225,9 @@ def test_badCompRef(self): sadpath = '/waveforms/ExternalProperties/ExternalProperties'+extra+'.sad.xml' else: sadpath = '/waveforms/ExternalProperties/ExternalProperties'+extra+'NoJava.sad.xml' - self._domMgr.installApplication(sadpath) - self.assertEqual(len(self._domMgr._get_applicationFactories()), 1) - appFact = self._domMgr._get_applicationFactories()[0] # Bad compref tag in externalproperties should throw appropriate error - self.assertRaises(CF.ApplicationFactory.CreateApplicationError, appFact.create, appFact._get_name(), [], []) - - self.assertNotEqual(self._domMgr, None) - self.assertNotEqual(self._devMgr, None) + self.assertRaises(CF.DomainManager.ApplicationInstallationError, self._domMgr.installApplication, sadpath) def test_ExternalPropOverride(self): self.assertNotEqual(self._domMgr, None) From 4c04b328b9eae57715ba431410127595b8af0757 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 8 Jun 2016 14:03:45 -0400 Subject: [PATCH 0378/1644] Use deployment error to report invalid external property --- .../src/control/sdr/dommgr/ApplicationFactory_impl.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 662c1940f..49b00847c 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -562,10 +562,7 @@ void createHelper::setUpExternalProperties(redhawk::ApplicationDeployment& appDe } const Property* property = deployment->getSoftPkg()->getProperties()->getProperty(prop->propid); if (!property){ - LOG_ERROR(ApplicationFactory_impl, "Attempting to promote property: '" << - prop->propid << "' that does not exist in component: '" << prop->comprefid << "'"); - throw CF::ApplicationFactory::CreateApplicationError(CF::CF_NOTSET, - "Attempting to promote property that does not exist in component"); + throw redhawk::DeploymentError("Attempting to promote property '" + prop->propid + "' that does not exist in component '" + prop->comprefid + "'"); } CF::Resource_var comp = deployment->getResourcePtr(); @@ -715,6 +712,11 @@ throw (CORBA::SystemException, CF::ApplicationFactory::CreateApplicationError, eout << "Unable to make connection '" << exc.identifier() << "': " << exc.what(); LOG_ERROR(ApplicationFactory_impl, eout.str()); throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EIO, eout.str().c_str()); + } catch (const redhawk::DeploymentError& exc) { + // Some other problem occurred in deployment, just log and throw CORBA + // exception + LOG_ERROR(ApplicationFactory_impl, exc.what()); + throw CF::ApplicationFactory::CreateApplicationError(CF::CF_NOTSET, exc.what()); } catch (const std::exception& ex) { std::ostringstream eout; eout << "The following standard exception occurred: "< Date: Wed, 8 Jun 2016 14:18:57 -0400 Subject: [PATCH 0379/1644] Change failure to register to an ExecuteError; don't make the caller explicitly provide a device for ExecuteError --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 18 +++++++++--------- redhawk/src/control/sdr/dommgr/Deployment.cpp | 2 +- redhawk/src/control/sdr/dommgr/Deployment.h | 2 +- .../sdr/dommgr/DeploymentExceptions.cpp | 6 ++++++ .../control/sdr/dommgr/DeploymentExceptions.h | 8 +------- 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 49b00847c..9e2264629 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -1660,30 +1660,30 @@ void createHelper::attemptComponentExecution (CF::ApplicationRegistrar_ptr regis // call 'execute' on the ExecutableDevice to execute the component pid = execdev->executeLinked(entryPoint.c_str(), options, execParameters, dep_seq); } catch (const CF::InvalidFileName&) { - throw redhawk::ExecuteError(deployment, device, "invalid filename"); + throw redhawk::ExecuteError(deployment, "invalid filename"); } catch (const CF::Device::InvalidState& exc) { std::string message = "invalid device state " + std::string(exc.msg); - throw redhawk::ExecuteError(deployment, device, message); + throw redhawk::ExecuteError(deployment, message); } catch (const CF::ExecutableDevice::InvalidParameters& exc) { std::string message = "invalid parameters " + redhawk::PropertyMap::cast(exc.invalidParms).toString(); - throw redhawk::ExecuteError(deployment, device, message); + throw redhawk::ExecuteError(deployment, message); } catch (const CF::ExecutableDevice::InvalidOptions& exc) { std::string message = "invalid options " + redhawk::PropertyMap::cast(exc.invalidOpts).toString(); - throw redhawk::ExecuteError(deployment, device, message); + throw redhawk::ExecuteError(deployment, message); } catch (const CF::ExecutableDevice::ExecuteFail& exc) { std::string message = "execute failure " + std::string(exc.msg); - throw redhawk::ExecuteError(deployment, device, message); + throw redhawk::ExecuteError(deployment, message); } catch (const CORBA::SystemException& exc) { - throw redhawk::ExecuteError(deployment, device, ossie::corba::describeException(exc)); + throw redhawk::ExecuteError(deployment, ossie::corba::describeException(exc)); } catch (...) { // Should never happen, but turn anything else into an ExecuteError // just in case - throw redhawk::ExecuteError(deployment, device, "unexpected error"); + throw redhawk::ExecuteError(deployment, "unexpected error"); } // handle pid output if (pid < 0) { - throw redhawk::ExecuteError(deployment, device, "execute returned invalid process ID"); + throw redhawk::ExecuteError(deployment, "execute returned invalid process ID"); } else { _application->setComponentPid(deployment->getIdentifier(), pid); } @@ -1764,7 +1764,7 @@ void createHelper::waitForComponentRegistration(const DeploymentList& deployment const std::string componentId = deployment->getIdentifier(); CORBA::Object_var objref = _application->getComponentObject(componentId); if (CORBA::is_nil(objref)) { - throw redhawk::ComponentError(deployment, "component did not register with application"); + throw redhawk::ExecuteError(deployment, "component did not register with application"); } // Occasionally, omniORB may have a cached connection where the diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index 07be25888..31e22aefc 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -311,7 +311,7 @@ void ComponentDeployment::setAssignedDevice(const boost::shared_ptr& assignedDevice = device; } -boost::shared_ptr ComponentDeployment::getAssignedDevice() +const boost::shared_ptr& ComponentDeployment::getAssignedDevice() const { return assignedDevice; } diff --git a/redhawk/src/control/sdr/dommgr/Deployment.h b/redhawk/src/control/sdr/dommgr/Deployment.h index c21dd0d1b..ec44c5850 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.h +++ b/redhawk/src/control/sdr/dommgr/Deployment.h @@ -147,7 +147,7 @@ namespace redhawk { void overrideProperty(const std::string& id, const CORBA::Any& value); void setAssignedDevice(const boost::shared_ptr& device); - boost::shared_ptr getAssignedDevice(); + const boost::shared_ptr& getAssignedDevice() const; void setResourcePtr(CF::Resource_ptr resource); CF::Resource_ptr getResourcePtr() const; diff --git a/redhawk/src/control/sdr/dommgr/DeploymentExceptions.cpp b/redhawk/src/control/sdr/dommgr/DeploymentExceptions.cpp index f38811a4e..090278b0f 100644 --- a/redhawk/src/control/sdr/dommgr/DeploymentExceptions.cpp +++ b/redhawk/src/control/sdr/dommgr/DeploymentExceptions.cpp @@ -48,6 +48,12 @@ ComponentError::ComponentError(const ComponentDeployment* deployment, const std: } } +ExecuteError::ExecuteError(const ComponentDeployment* deployment, const std::string& message) : + ComponentError(deployment, message), + _device(deployment->getAssignedDevice()) +{ +} + PlacementFailure::PlacementFailure(const ossie::ComponentInstantiation* instantiation, const std::string& message) : DeploymentError(message), diff --git a/redhawk/src/control/sdr/dommgr/DeploymentExceptions.h b/redhawk/src/control/sdr/dommgr/DeploymentExceptions.h index b1c0e38a0..9edfc7aee 100644 --- a/redhawk/src/control/sdr/dommgr/DeploymentExceptions.h +++ b/redhawk/src/control/sdr/dommgr/DeploymentExceptions.h @@ -137,13 +137,7 @@ namespace redhawk { class ExecuteError : public ComponentError { public: - ExecuteError(const ComponentDeployment* deployment, - const boost::shared_ptr& device, - const std::string& message) : - ComponentError(deployment, message), - _device(device) - { - } + ExecuteError(const ComponentDeployment* deployment, const std::string& message); const boost::shared_ptr& device() const { From 52d35806a1cf03e7ee087bdc5af9d6c385f20617 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 8 Jun 2016 14:24:53 -0400 Subject: [PATCH 0380/1644] Use the instantiation ID, not the mangled identifier, for exceptions --- redhawk/src/control/sdr/dommgr/DeploymentExceptions.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/redhawk/src/control/sdr/dommgr/DeploymentExceptions.cpp b/redhawk/src/control/sdr/dommgr/DeploymentExceptions.cpp index 090278b0f..7e4021e19 100644 --- a/redhawk/src/control/sdr/dommgr/DeploymentExceptions.cpp +++ b/redhawk/src/control/sdr/dommgr/DeploymentExceptions.cpp @@ -41,7 +41,7 @@ UsesDeviceFailure::UsesDeviceFailure(const ComponentDeployment* component, const ComponentError::ComponentError(const ComponentDeployment* deployment, const std::string& message) : DeploymentError(message), - _identifier(deployment->getIdentifier()) + _identifier(deployment->getInstantiation()->getID()) { if (deployment->getImplementation()) { _implementation = deployment->getImplementation()->getID(); From 3d21df19ab5048fbc27c61469a0f561de50e4163 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 8 Jun 2016 14:36:30 -0400 Subject: [PATCH 0381/1644] Change expected exception in collocation failure (it used to throw the wrong exception, in that it doesn't have anything to do with a DeviceAssignmentSequence) --- .../testing/tests/test_05_CollocationApplicationFactory.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/redhawk/src/testing/tests/test_05_CollocationApplicationFactory.py b/redhawk/src/testing/tests/test_05_CollocationApplicationFactory.py index 3fcee65b3..c692226f9 100644 --- a/redhawk/src/testing/tests/test_05_CollocationApplicationFactory.py +++ b/redhawk/src/testing/tests/test_05_CollocationApplicationFactory.py @@ -424,11 +424,12 @@ def test_collocationFailFast(self): allocations_pre = self._getProperty(device, 'allocation_attempts') try: app = appFact.create(appFact._get_name(), [], []) - app.releaseObject() - self.fail("Expected app creation to fail") - except CF.ApplicationFactory.CreateApplicationRequestError: + except CF.ApplicationFactory.CreateApplicationError: # This is expected pass + else: + app.releaseObject() + self.fail("Expected app creation to fail") # Clean up a little domMgr.uninstallApplication(appFact._get_identifier()) From 90bd78f6c52e530c0dc3b8bfef591c94e25c1706 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 9 Jun 2016 09:29:50 -0400 Subject: [PATCH 0382/1644] Add a deployment exception specifically for bad external ports --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 54 ++++++++++--------- .../sdr/dommgr/DeploymentExceptions.cpp | 7 +++ .../control/sdr/dommgr/DeploymentExceptions.h | 22 ++++++++ 3 files changed, 57 insertions(+), 26 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 9e2264629..a6a295708 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -494,35 +494,27 @@ std::vector createHelper::_getFailedUsesDevices(const std::vector PortList; - const PortList& ports = _appFact._sadParser.getExternalPorts(); LOG_TRACE(ApplicationFactory_impl, - "Mapping " << ports.size() << " external port(s)"); + "Mapping " << _appFact._sadParser.getExternalPorts().size() << " external port(s)"); - for (PortList::const_iterator port = ports.begin(); port != ports.end(); ++port) { - LOG_TRACE(ApplicationFactory_impl, - "Port component: " << port->componentrefid - << " Port identifier: " << port->identifier); + BOOST_FOREACH(const SoftwareAssembly::Port& port, _appFact._sadParser.getExternalPorts()) { + LOG_TRACE(ApplicationFactory_impl, "External port '" << port.getExternalName() + << "' from component '" << port.componentrefid + << "' identifier '" << port.identifier << "'"); // Get the component from the instantiation identifier. - redhawk::ComponentDeployment* deployment = appDeployment.getComponentDeployment(port->componentrefid); + redhawk::ComponentDeployment* deployment = appDeployment.getComponentDeployment(port.componentrefid); if (!deployment) { // The SAD parser should have rejected invalid component references - throw std::logic_error("component not found for external port '" + port->getExternalName() + "'"); + throw std::logic_error("component not found for external port '" + port.getExternalName() + "'"); } CF::Resource_var resource = deployment->getResourcePtr(); CORBA::Object_var obj; - if (port->type == SoftwareAssembly::Port::SUPPORTEDIDENTIFIER) { - if (!resource->_is_a(port->identifier.c_str())) { - LOG_ERROR( - ApplicationFactory_impl, - "Component does not support requested interface: " - << port->identifier); - throw(CF::ApplicationFactory::CreateApplicationError( - CF::CF_NOTSET, - "Component does not support requested interface")); + if (port.type == SoftwareAssembly::Port::SUPPORTEDIDENTIFIER) { + if (!resource->_is_a(port.identifier.c_str())) { + throw redhawk::BadExternalPort(port, "component does not support interface " + port.identifier); } obj = CORBA::Object::_duplicate(resource); } else { @@ -532,17 +524,20 @@ void createHelper::setUpExternalPorts(redhawk::ApplicationDeployment& appDeploym // component's SCD. // Try to look up the port. try { - obj = resource->getPort(port->identifier.c_str()); - } CATCH_THROW_LOG_ERROR( - ApplicationFactory_impl, - "Invalid port id", - CF::ApplicationFactory::CreateApplicationError( - CF::CF_NOTSET, - "Invalid port identifier")) + obj = resource->getPort(port.identifier.c_str()); + } catch (const CF::PortSupplier::UnknownPort& exc) { + throw redhawk::BadExternalPort(port, "component has no port '" + port.identifier + "'"); + } catch (const CORBA::SystemException& exc) { + throw redhawk::BadExternalPort(port, ossie::corba::describeException(exc)); + } catch (...) { + // Should never happen, but turn anything else into a + // BadExternalPort just in case + throw redhawk::BadExternalPort(port, "unexpected error"); + } } // Add it to the list of external ports on the application object. - application->addExternalPort(port->getExternalName(), obj); + application->addExternalPort(port.getExternalName(), obj); } } @@ -712,6 +707,13 @@ throw (CORBA::SystemException, CF::ApplicationFactory::CreateApplicationError, eout << "Unable to make connection '" << exc.identifier() << "': " << exc.what(); LOG_ERROR(ApplicationFactory_impl, eout.str()); throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EIO, eout.str().c_str()); + } catch (const redhawk::BadExternalPort& exc) { + std::stringstream eout; + eout << "Could not create external port '" << exc.name(); + eout << "' from component '" << exc.component(); + eout << "': " << exc.what(); + LOG_ERROR(ApplicationFactory_impl, eout.str()); + throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EINVAL, eout.str().c_str()); } catch (const redhawk::DeploymentError& exc) { // Some other problem occurred in deployment, just log and throw CORBA // exception diff --git a/redhawk/src/control/sdr/dommgr/DeploymentExceptions.cpp b/redhawk/src/control/sdr/dommgr/DeploymentExceptions.cpp index 7e4021e19..e1964e6f8 100644 --- a/redhawk/src/control/sdr/dommgr/DeploymentExceptions.cpp +++ b/redhawk/src/control/sdr/dommgr/DeploymentExceptions.cpp @@ -67,3 +67,10 @@ PlacementFailure::PlacementFailure(const ossie::SoftwareAssembly::HostCollocatio _name("host collocation " + collocation.getID() + " (" + collocation.getName() + ")") { } + +BadExternalPort::BadExternalPort(const ossie::SoftwareAssembly::Port& port, const std::string& message) : + DeploymentError(message), + _name(port.getExternalName()), + _component(port.componentrefid) +{ +} diff --git a/redhawk/src/control/sdr/dommgr/DeploymentExceptions.h b/redhawk/src/control/sdr/dommgr/DeploymentExceptions.h index 9edfc7aee..ef3ab264a 100644 --- a/redhawk/src/control/sdr/dommgr/DeploymentExceptions.h +++ b/redhawk/src/control/sdr/dommgr/DeploymentExceptions.h @@ -175,6 +175,28 @@ namespace redhawk { const redhawk::PropertyMap _properties; }; + class BadExternalPort : public DeploymentError { + public: + BadExternalPort(const ossie::SoftwareAssembly::Port& port, const std::string& message); + + virtual ~BadExternalPort() throw () + { + } + + const std::string& name() const + { + return _name; + } + + const std::string& component() const + { + return _component; + } + + private: + const std::string _name; + const std::string _component; + }; } #endif // DEPLOYMENTEXCEPTIONS_H From fde890f2082e910331fd0c2101da53d3b89a0805 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 9 Jun 2016 10:09:40 -0400 Subject: [PATCH 0383/1644] Make translation from internal DeploymentError to CORBA exception easier by providing the error number and full message text from the specific error, making the catch/throw much more concise --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 65 ++-------------- .../sdr/dommgr/DeploymentExceptions.cpp | 78 +++++++++++++++++-- .../control/sdr/dommgr/DeploymentExceptions.h | 50 +++++++++++- 3 files changed, 125 insertions(+), 68 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index a6a295708..7c66a852b 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -654,37 +654,6 @@ throw (CORBA::SystemException, CF::ApplicationFactory::CreateApplicationError, } catch (CF::ApplicationFactory::CreateApplicationRequestError& ex) { LOG_ERROR(ApplicationFactory_impl, "Error in application creation") throw; - } catch (const redhawk::PlacementFailure& exc) { - // Unable to place a component or host collocation, report details - std::ostringstream eout; - eout << "Failed to place " << exc.name() << ": " << exc.what(); - LOG_ERROR(ApplicationFactory_impl, eout.str()); - throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EIO, eout.str().c_str()); - } catch (const redhawk::UsesDeviceFailure& exc) { - // One or more usesdevice(s) could not be allocated - std::ostringstream eout; - eout << "Failed to satisfy 'usesdevice' dependencies "; - bool first = true; - BOOST_FOREACH(const std::string& id, exc.ids()) { - if (!first) { - eout << ", "; - } else { - first = false; - } - eout << id; - } - eout << " for " << exc.context(); - LOG_ERROR(ApplicationFactory_impl, eout.str()); - throw CF::ApplicationFactory::CreateApplicationError(CF::CF_ENOSPC, eout.str().c_str()); - } catch (const redhawk::ExecuteError& exc) { - // A component failed execution, report details - std::ostringstream eout; - eout << "Executing component " << exc.identifier(); - eout << " implementation " << exc.implementation(); - eout << " failed on device " << exc.device()->identifier; - eout << ": " << exc.what(); - LOG_ERROR(ApplicationFactory_impl, eout.str()); - throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EIO, eout.str().c_str()); } catch (const redhawk::PropertiesError& exc) { // Unfortunately, InvalidInitConfiguration does not include an error // message, so log the error here to give more details @@ -692,33 +661,11 @@ throw (CORBA::SystemException, CF::ApplicationFactory::CreateApplicationError, LOG_ERROR(ApplicationFactory_impl, "Component " << exc.identifier() << " failed due to " << exc.what() << " " << exc.properties()); throw CF::ApplicationFactory::InvalidInitConfiguration(exc.properties()); - } catch (const redhawk::ComponentError& exc) { - // A component failed deployment in some other way, report details - std::stringstream eout; - eout << "Deploying component " << exc.identifier(); - eout << " implementation " << exc.implementation(); - eout << " failed: " << exc.what(); - LOG_ERROR(ApplicationFactory_impl, eout.str()); - throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EINVAL, eout.str().c_str()); - } catch (const redhawk::ConnectionError& exc) { - // A connection defined in the SAD could not be made, either because an - // endpoint could not be resolved, or connectPort failed - std::ostringstream eout; - eout << "Unable to make connection '" << exc.identifier() << "': " << exc.what(); - LOG_ERROR(ApplicationFactory_impl, eout.str()); - throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EIO, eout.str().c_str()); - } catch (const redhawk::BadExternalPort& exc) { - std::stringstream eout; - eout << "Could not create external port '" << exc.name(); - eout << "' from component '" << exc.component(); - eout << "': " << exc.what(); - LOG_ERROR(ApplicationFactory_impl, eout.str()); - throw CF::ApplicationFactory::CreateApplicationError(CF::CF_EINVAL, eout.str().c_str()); } catch (const redhawk::DeploymentError& exc) { - // Some other problem occurred in deployment, just log and throw CORBA - // exception - LOG_ERROR(ApplicationFactory_impl, exc.what()); - throw CF::ApplicationFactory::CreateApplicationError(CF::CF_NOTSET, exc.what()); + // Convert from internal error to CORBA exception and report the error + const std::string message = exc.message(); + LOG_ERROR(ApplicationFactory_impl, "Failed to create application '" << name << "': " << message); + throw CF::ApplicationFactory::CreateApplicationError(exc.errorNumber(), message.c_str()); } catch (const std::exception& ex) { std::ostringstream eout; eout << "The following standard exception occurred: "<getLastDeviceUsedForDeployment(); diff --git a/redhawk/src/control/sdr/dommgr/DeploymentExceptions.cpp b/redhawk/src/control/sdr/dommgr/DeploymentExceptions.cpp index e1964e6f8..134a7b445 100644 --- a/redhawk/src/control/sdr/dommgr/DeploymentExceptions.cpp +++ b/redhawk/src/control/sdr/dommgr/DeploymentExceptions.cpp @@ -18,6 +18,10 @@ * along with this program. If not, see http://www.gnu.org/licenses/. */ +#include + +#include + #include #include "DeploymentExceptions.h" @@ -26,21 +30,45 @@ using namespace redhawk; UsesDeviceFailure::UsesDeviceFailure(const ApplicationDeployment&, const std::vector& ids) : - DeploymentError("failed to satisfy usesdevice dependencies"), + DeploymentError(CF::CF_ENOSPC, "failed to satisfy usesdevice dependencies"), _context("application"), _ids(ids) { } UsesDeviceFailure::UsesDeviceFailure(const ComponentDeployment* component, const std::vector& ids) : - DeploymentError("failed to satisfy usesdevice dependencies"), + DeploymentError(CF::CF_ENOSPC, "failed to satisfy usesdevice dependencies"), _context("component '" + component->getInstantiation()->getID() + "'"), _ids(ids) { } +std::string UsesDeviceFailure::message() const +{ + std::ostringstream msg; + msg << "Failed to satisfy 'usesdevice' dependencies "; + bool first = true; + BOOST_FOREACH(const std::string& id, ids()) { + if (!first) { + msg << ", "; + } else { + first = false; + } + msg << id; + } + msg << " for " << context(); + return msg.str(); +} + +std::string ConnectionError::message() const +{ + std::ostringstream msg; + msg << "Unable to make connection '" << identifier() << "': " << what(); + return msg.str(); +} + ComponentError::ComponentError(const ComponentDeployment* deployment, const std::string& message) : - DeploymentError(message), + DeploymentError(CF::CF_EINVAL, message), _identifier(deployment->getInstantiation()->getID()) { if (deployment->getImplementation()) { @@ -48,29 +76,67 @@ ComponentError::ComponentError(const ComponentDeployment* deployment, const std: } } +std::string ComponentError::message() const +{ + std::ostringstream msg; + msg << "Deploying component " << identifier(); + msg << " implementation " << implementation(); + msg << " failed: " << what(); + return msg.str(); +} + ExecuteError::ExecuteError(const ComponentDeployment* deployment, const std::string& message) : ComponentError(deployment, message), _device(deployment->getAssignedDevice()) { + // Override the default ComponentError errorNumber; this is simpler than + // having an extra ComponentError constructor + errorNumber(CF::CF_EIO); +} + +std::string ExecuteError::message() const +{ + std::ostringstream msg; + msg << "Executing component " << identifier(); + msg << " implementation " << implementation(); + msg << " failed on device " << device()->identifier; + msg << ": " << what(); + return msg.str(); } PlacementFailure::PlacementFailure(const ossie::ComponentInstantiation* instantiation, const std::string& message) : - DeploymentError(message), + DeploymentError(CF::CF_EIO, message), _name("component " + instantiation->getID()) { } PlacementFailure::PlacementFailure(const ossie::SoftwareAssembly::HostCollocation& collocation, const std::string& message) : - DeploymentError(message), + DeploymentError(CF::CF_EIO, message), _name("host collocation " + collocation.getID() + " (" + collocation.getName() + ")") { } +std::string PlacementFailure::message() const +{ + std::ostringstream msg; + msg << "Failed to place " << name() << ": " << what(); + return msg.str(); +} + BadExternalPort::BadExternalPort(const ossie::SoftwareAssembly::Port& port, const std::string& message) : - DeploymentError(message), + DeploymentError(CF::CF_EINVAL, message), _name(port.getExternalName()), _component(port.componentrefid) { } + +std::string BadExternalPort::message() const +{ + std::ostringstream msg; + msg << "Could not create external port '" << name(); + msg << "' from component '" << component(); + msg << "': " << what(); + return msg.str(); +} diff --git a/redhawk/src/control/sdr/dommgr/DeploymentExceptions.h b/redhawk/src/control/sdr/dommgr/DeploymentExceptions.h index ef3ab264a..f1f612e11 100644 --- a/redhawk/src/control/sdr/dommgr/DeploymentExceptions.h +++ b/redhawk/src/control/sdr/dommgr/DeploymentExceptions.h @@ -43,7 +43,41 @@ namespace redhawk { class DeploymentError : public std::runtime_error { public: DeploymentError(const std::string& message) : - std::runtime_error(message) + std::runtime_error(message), + _errorNumber(CF::CF_NOTSET) + { + } + + DeploymentError(CF::ErrorNumberType errorNum, const std::string& message) : + std::runtime_error(message), + _errorNumber(errorNum) + { + } + + virtual std::string message() const + { + return std::string(what()); + } + + CF::ErrorNumberType errorNumber() const + { + return _errorNumber; + } + + protected: + void errorNumber(CF::ErrorNumberType errorNum) + { + _errorNumber = errorNum; + } + + private: + CF::ErrorNumberType _errorNumber; + }; + + class NoExecutableDevices : public DeploymentError { + public: + NoExecutableDevices() : + DeploymentError(CF::CF_ENODEV, "Domain has no executable devices (GPPs) to run components") { } }; @@ -57,6 +91,8 @@ namespace redhawk { { } + virtual std::string message() const; + const std::string& context() const { return _context; @@ -75,7 +111,7 @@ namespace redhawk { class ConnectionError : public DeploymentError { public: ConnectionError(const std::string& identifier, const std::string& message) : - DeploymentError(message), + DeploymentError(CF::CF_EIO, message), _identifier(identifier) { } @@ -84,6 +120,8 @@ namespace redhawk { { } + virtual std::string message() const; + const std::string& identifier() const { return _identifier; @@ -103,6 +141,8 @@ namespace redhawk { { } + virtual std::string message() const; + const std::string& name() const { return _name; @@ -120,6 +160,8 @@ namespace redhawk { { } + virtual std::string message() const; + const std::string& identifier() const { return _identifier; @@ -148,6 +190,8 @@ namespace redhawk { { } + virtual std::string message() const; + private: boost::shared_ptr _device; }; @@ -183,6 +227,8 @@ namespace redhawk { { } + virtual std::string message() const; + const std::string& name() const { return _name; From a85529bf08a2fadeda86622d1336b3a65f13ea5e Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 9 Jun 2016 12:03:57 -0400 Subject: [PATCH 0384/1644] Provide a description from Endpoint classes to allow the exception on failed resolution to be more helpful --- redhawk/src/control/sdr/dommgr/Endpoints.h | 59 +++++++++++++++++++ .../control/sdr/dommgr/connectionSupport.cpp | 4 +- .../control/sdr/dommgr/connectionSupport.h | 4 +- 3 files changed, 64 insertions(+), 3 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/Endpoints.h b/redhawk/src/control/sdr/dommgr/Endpoints.h index 13c03e8c4..5e991a58e 100644 --- a/redhawk/src/control/sdr/dommgr/Endpoints.h +++ b/redhawk/src/control/sdr/dommgr/Endpoints.h @@ -50,6 +50,11 @@ namespace ossie { return ((type == APPLICATION) && (identifier == identifier_)); } + virtual std::string description() const + { + return "application '" + identifier_ + "'"; + } + virtual ApplicationEndpoint* clone() const { return new ApplicationEndpoint(*this); @@ -96,6 +101,11 @@ namespace ossie { return ((type == COMPONENT) && (identifier == identifier_)); } + virtual std::string description() const + { + return "component '" + identifier_ + "'"; + } + virtual ComponentEndpoint* clone() const { return new ComponentEndpoint(*this); @@ -146,6 +156,11 @@ namespace ossie { return false; } + virtual std::string description() const + { + return "device that loaded component '" + identifier_ + "'"; + } + virtual DeviceLoadedEndpoint* clone() const { return new DeviceLoadedEndpoint(*this); @@ -203,6 +218,11 @@ namespace ossie { return new DeviceUsedEndpoint(*this); } + virtual std::string description() const + { + return "usesdevice '" + usesIdentifier_ + "' for component '" + componentIdentifier_ + "'"; + } + private: virtual CORBA::Object_ptr resolve_(ConnectionManager& manager) { @@ -249,6 +269,11 @@ namespace ossie { return false; } + virtual std::string description() const + { + return "application usesdevice '" + usesIdentifier_ + "'"; + } + virtual ApplicationUsesDeviceEndpoint* clone() const { return new ApplicationUsesDeviceEndpoint(*this); @@ -298,6 +323,11 @@ namespace ossie { return false; } + virtual std::string description() const + { + return "find by naming service '" + name_ + "'"; + } + virtual FindByNamingServiceEndpoint* clone() const { return new FindByNamingServiceEndpoint(*this); @@ -347,6 +377,15 @@ namespace ossie { return ((type == Endpoint::SERVICENAME) && (identifier == name_)); } + virtual std::string description() const + { + std::string desc = "domain object type " + type_; + if (!name_.empty()) { + desc += " '" + name_ + "'"; + } + return desc; + } + virtual FindByDomainFinderEndpoint* clone() const { return new FindByDomainFinderEndpoint(*this); @@ -405,6 +444,11 @@ namespace ossie { return ((type == Endpoint::SERVICENAME) && (identifier == name_)); } + virtual std::string description() const + { + return "service '" + name_ + "'"; + } + virtual ServiceEndpoint* clone() const { return new ServiceEndpoint(*this); @@ -457,6 +501,11 @@ namespace ossie { return false; } + virtual std::string description() const + { + return "event channel '" + name_ + "'"; + } + virtual EventChannelEndpoint* clone() const { return new EventChannelEndpoint(*this); @@ -509,6 +558,11 @@ namespace ossie { return false; } + virtual std::string description() const + { + return "object reference"; + } + virtual ObjectrefEndpoint* clone() const { return new ObjectrefEndpoint(*this); @@ -583,6 +637,11 @@ namespace ossie { return supplier_->checkDependency(type, identifier); } + virtual std::string description() const + { + return supplier_->description() + " port '" + name_ + "'"; + } + virtual PortEndpoint* clone() const { return new PortEndpoint(*this); diff --git a/redhawk/src/control/sdr/dommgr/connectionSupport.cpp b/redhawk/src/control/sdr/dommgr/connectionSupport.cpp index 3aa68d2c9..5135d29ac 100644 --- a/redhawk/src/control/sdr/dommgr/connectionSupport.cpp +++ b/redhawk/src/control/sdr/dommgr/connectionSupport.cpp @@ -724,9 +724,9 @@ bool ConnectionNode::connect(ConnectionManager& manager) return false; } else { if (!uses->isResolved() && !uses->allowDeferral()) { - throw InvalidConnection("Uses endpoint for "+identifier+" cannot be resolved or deferred"); + throw InvalidConnection(uses->description() + " cannot be resolved or deferred"); } else { - throw InvalidConnection("Provides endpoint for "+identifier+" cannot be resolved or deferred"); + throw InvalidConnection(provides->description() + " cannot be resolved or deferred"); } } } diff --git a/redhawk/src/control/sdr/dommgr/connectionSupport.h b/redhawk/src/control/sdr/dommgr/connectionSupport.h index 0b2ef49fd..072d1ea33 100644 --- a/redhawk/src/control/sdr/dommgr/connectionSupport.h +++ b/redhawk/src/control/sdr/dommgr/connectionSupport.h @@ -130,7 +130,9 @@ namespace ossie void release(); - // Virtual copy contstructor + virtual std::string description() const = 0; + + // Virtual copy constructor virtual Endpoint* clone() const = 0; static Endpoint* ParsePortSupplier(const Port* port); From 01fa5e4c49b0fcd5fc0d1f6b7f1d0377a47eeb52 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 9 Jun 2016 12:43:34 -0400 Subject: [PATCH 0385/1644] If enabled, throw an exception in port resolution when the object is not a port supplier --- redhawk/src/control/sdr/dommgr/Endpoints.h | 27 ++++++++++++++-------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/Endpoints.h b/redhawk/src/control/sdr/dommgr/Endpoints.h index 5e991a58e..561854696 100644 --- a/redhawk/src/control/sdr/dommgr/Endpoints.h +++ b/redhawk/src/control/sdr/dommgr/Endpoints.h @@ -651,17 +651,24 @@ namespace ossie { virtual CORBA::Object_ptr resolve_(ConnectionManager& manager) { CORBA::Object_var supplierObject = supplier_->resolve(manager); - CF::PortSupplier_var portSupplier = ossie::corba::_narrowSafe(supplierObject); - if (!CORBA::is_nil(portSupplier)) { - try { - return portSupplier->getPort(name_.c_str()); - } catch (const CF::PortSupplier::UnknownPort&) { - LOG_ERROR(PortEndpoint, "Port supplier reports no port with name " << name_); - } CATCH_LOG_ERROR(PortEndpoint, "Failure in getPort"); - - invalidPort_ = true; - } else { + if (CORBA::is_nil(supplierObject)) { LOG_DEBUG(PortEndpoint, "Unable to resolve port supplier"); + } else { + CF::PortSupplier_var portSupplier = ossie::corba::_narrowSafe(supplierObject); + if (!CORBA::is_nil(portSupplier)) { + try { + return portSupplier->getPort(name_.c_str()); + } catch (const CF::PortSupplier::UnknownPort&) { + LOG_ERROR(PortEndpoint, "Port supplier reports no port with name " << name_); + } CATCH_LOG_ERROR(PortEndpoint, "Failure in getPort"); + } else { + if (manager.exceptionsEnabled()) { + throw LookupError(supplier_->description() + " is not a port supplier"); + } else { + LOG_ERROR(PortEndpoint, "Object " << supplier_->description() << " is not a port supplier"); + } + } + invalidPort_ = true; } return CORBA::Object::_nil(); } From b0f4b12bbf0685500b53bc6974829d2fff4e24e9 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 9 Jun 2016 14:10:48 -0400 Subject: [PATCH 0386/1644] Turn property initialization errors back into CreateApplicationError exceptions (the old code used to throw InvalidInitConfiguration but turn it into CreateApplicationError at the outer try/catch) --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 17 +++++------------ .../control/sdr/dommgr/DeploymentExceptions.cpp | 13 ++++++++++++- .../control/sdr/dommgr/DeploymentExceptions.h | 2 ++ 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 7c66a852b..9d6e8d7c2 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -648,24 +648,17 @@ throw (CORBA::SystemException, CF::ApplicationFactory::CreateApplicationError, CF::Application_ptr new_app; try { new_app = new_createhelper.create(name, initConfiguration, deviceAssignmentMap); + } catch (const redhawk::DeploymentError& exc) { + // Convert from internal error to CORBA exception and report the error + const std::string message = exc.message(); + LOG_ERROR(ApplicationFactory_impl, "Failed to create application '" << name << "': " << message); + throw CF::ApplicationFactory::CreateApplicationError(exc.errorNumber(), message.c_str()); } catch (CF::ApplicationFactory::CreateApplicationError& ex) { LOG_ERROR(ApplicationFactory_impl, "Error in application creation; " << ex.msg); throw; } catch (CF::ApplicationFactory::CreateApplicationRequestError& ex) { LOG_ERROR(ApplicationFactory_impl, "Error in application creation") throw; - } catch (const redhawk::PropertiesError& exc) { - // Unfortunately, InvalidInitConfiguration does not include an error - // message, so log the error here to give more details - std::ostringstream eout; - LOG_ERROR(ApplicationFactory_impl, "Component " << exc.identifier() - << " failed due to " << exc.what() << " " << exc.properties()); - throw CF::ApplicationFactory::InvalidInitConfiguration(exc.properties()); - } catch (const redhawk::DeploymentError& exc) { - // Convert from internal error to CORBA exception and report the error - const std::string message = exc.message(); - LOG_ERROR(ApplicationFactory_impl, "Failed to create application '" << name << "': " << message); - throw CF::ApplicationFactory::CreateApplicationError(exc.errorNumber(), message.c_str()); } catch (const std::exception& ex) { std::ostringstream eout; eout << "The following standard exception occurred: "< Date: Thu, 9 Jun 2016 14:13:32 -0400 Subject: [PATCH 0387/1644] Update test now that a missing or invalid assembly controller is caught at install time --- .../tests/test_04_ApplicationFactory.py | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/redhawk/src/testing/tests/test_04_ApplicationFactory.py b/redhawk/src/testing/tests/test_04_ApplicationFactory.py index 1c3b013a3..1a4e25501 100644 --- a/redhawk/src/testing/tests/test_04_ApplicationFactory.py +++ b/redhawk/src/testing/tests/test_04_ApplicationFactory.py @@ -1452,27 +1452,14 @@ def test_hostCollocationFail(self): self.fail('Application creation should fail') def test_NoAssemblyController(self): - # Test that creating an application that uses host collocation fails - # if all the components cannot be allocated on the same device. + # Test that installing an application without an assembly controller fails nodebooter, domMgr = self.launchDomainManager() self.assertNotEqual(domMgr, None) nodebooter, devMgr = self.launchDeviceManager("/nodes/test_BasicTestDevice_node/DeviceManager.dcd.xml") self.assertNotEqual(devMgr, None) - domMgr.installApplication("/waveforms/CommandWrapperNoAssembly/CommandWrapper.sad.xml") - self.assertEqual(len(domMgr._get_applicationFactories()), 1) - - appFact = domMgr._get_applicationFactories()[0] - - try: - app = appFact.create(appFact._get_name(), [], []) - except: - pass - else: - app.stop() - app.releaseObject() - self.fail('Application creation should fail') - domMgr._get_identifier() + sadFile = "/waveforms/CommandWrapperNoAssembly/CommandWrapper.sad.xml" + self.assertRaises(CF.DomainManager.ApplicationInstallationError, domMgr.installApplication, sadFile) def test_hostCollocationDAS(self): # Test that creating an application that uses host collocation with From 1e2ddc48f0d9171ebc27ae13424c2c2d1897200f Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 10 Jun 2016 14:00:43 -0400 Subject: [PATCH 0388/1644] Pass along abnormal component termination messages to the owning application; track pending applications in addition to active ones, so that the application doesn't have to keep waiting on registrations --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 4 +- .../control/sdr/dommgr/Application_impl.cpp | 23 ++++++++++- .../src/control/sdr/dommgr/Application_impl.h | 4 ++ .../sdr/dommgr/DomainManager_EventSupport.cpp | 32 ++++++++------- .../control/sdr/dommgr/DomainManager_impl.cpp | 41 ++++++++++++++++++- .../control/sdr/dommgr/DomainManager_impl.h | 6 ++- 6 files changed, 91 insertions(+), 19 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 9d6e8d7c2..ae55671ee 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -787,6 +787,7 @@ CF::Application_ptr createHelper::create ( _waveformContext, aware_application, _domainContext); + _appFact._domainManager->addPendingApplication(_application); // Activate the new Application servant PortableServer::ObjectId_var oid = Application_impl::Activate(_application); @@ -879,7 +880,7 @@ CF::Application_ptr createHelper::create ( // ApplicationSequence in DomainManager CF::Application_var appObj = _application->_this(); try { - _appFact._domainManager->addApplication(_application); + _appFact._domainManager->completePendingApplication(_application); } catch (CF::DomainManager::ApplicationInstallationError& ex) { // something bad happened - clean up LOG_ERROR(ApplicationFactory_impl, ex.msg); @@ -1884,6 +1885,7 @@ createHelper::~createHelper() void createHelper::_cleanupFailedCreate() { if (_application) { + _appFact._domainManager->cancelPendingApplication(_application); _application->releaseComponents(); _application->terminateComponents(); _application->unloadComponents(); diff --git a/redhawk/src/control/sdr/dommgr/Application_impl.cpp b/redhawk/src/control/sdr/dommgr/Application_impl.cpp index 04ea0d0b5..38422190d 100644 --- a/redhawk/src/control/sdr/dommgr/Application_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/Application_impl.cpp @@ -72,6 +72,11 @@ namespace { return !CORBA::is_nil(component.componentObject); } + bool is_terminated(const ossie::ApplicationComponent& component) + { + return (component.processId == 0); + } + CF::ComponentType to_component_type(const ossie::ApplicationComponent& component) { CF::ComponentType result; @@ -1154,6 +1159,10 @@ throw (CORBA::SystemException) return new CF::DeviceAssignmentSequence(_componentDevices); } +const std::string& Application_impl::getIdentifier() const +{ + return _identifier; +} void Application_impl::addExternalPort (const std::string& identifier, CORBA::Object_ptr port) { @@ -1187,7 +1196,7 @@ bool Application_impl::checkConnectionDependency (Endpoint::DependencyType type, bool Application_impl::_checkRegistrations (std::set& identifiers) { for (ossie::ComponentList::iterator ii = _components.begin(); ii != _components.end(); ++ii) { - if (is_registered(*ii)) { + if (is_registered(*ii) || is_terminated(*ii)) { identifiers.erase(ii->identifier); } } @@ -1360,3 +1369,15 @@ CORBA::Object_ptr Application_impl::getComponentObject(const std::string& identi return CORBA::Object::_duplicate(component->componentObject); } } + +void Application_impl::componentTerminated(const std::string& componentId, const std::string& deviceId) +{ + LOG_WARN(Application_impl, "Component '" << componentId << "' from application '" << _identifier + << "' terminated abnormally on device '" << deviceId << "'"); + ossie::ApplicationComponent* component = findComponent(componentId); + if (component) { + boost::mutex::scoped_lock lock(_registrationMutex); + component->processId = 0; + _registrationCondition.notify_all(); + } +} diff --git a/redhawk/src/control/sdr/dommgr/Application_impl.h b/redhawk/src/control/sdr/dommgr/Application_impl.h index 807cb9020..15b65455b 100644 --- a/redhawk/src/control/sdr/dommgr/Application_impl.h +++ b/redhawk/src/control/sdr/dommgr/Application_impl.h @@ -130,6 +130,8 @@ class Application_impl : public virtual POA_CF::Application, public Logging_impl CF::ApplicationRegistrar_ptr appReg (void); + const std::string& getIdentifier() const; + void addExternalPort (const std::string&, CORBA::Object_ptr); void addExternalProperty (const std::string&, const std::string&, CF::Resource_ptr); @@ -152,6 +154,8 @@ class Application_impl : public virtual POA_CF::Application, public Logging_impl void terminateComponents(); void unloadComponents(); + void componentTerminated(const std::string& componentId, const std::string& deviceId); + bool waitForComponents(std::set& identifiers, int timeout); CF::Application_ptr getComponentApplication(); diff --git a/redhawk/src/control/sdr/dommgr/DomainManager_EventSupport.cpp b/redhawk/src/control/sdr/dommgr/DomainManager_EventSupport.cpp index c360bf272..88754b609 100644 --- a/redhawk/src/control/sdr/dommgr/DomainManager_EventSupport.cpp +++ b/redhawk/src/control/sdr/dommgr/DomainManager_EventSupport.cpp @@ -26,6 +26,7 @@ #include #include "DomainManager_EventSupport.h" #include "DomainManager_impl.h" +#include "Application_impl.h" using namespace ossie; @@ -171,22 +172,23 @@ void DomainManager_impl::sendResourceStateChange( const std::string &source_id, ewriter.sendResourceStateChange( evt ); } +void DomainManager_impl::idmTerminationMessages(const redhawk::events::ComponentTerminationEvent& termMsg) +{ + boost::recursive_mutex::scoped_lock lock(stateAccess); + Application_impl* application = findApplicationById(termMsg.application_id); + if (!application) { + ApplicationTable::iterator iter = _pendingApplications.find(termMsg.application_id); + if (iter != _pendingApplications.end()) { + application = iter->second; + } + } - -void DomainManager_impl::handleIDMChannelMessages( const CORBA::Any &msg ) { - - const StandardEvent::AbnormalComponentTerminationEventType *termMsg; - if ( msg >>= termMsg ) { - LOG_WARN(DomainManager_impl, "Abnormal Component Termination, Reporting Device: " << termMsg->deviceId << " Application/Component " << - termMsg->applicationId << "/" << termMsg->componentId ); - } - -} - - -void DomainManager_impl::idmTerminationMessages( const redhawk::events::ComponentTerminationEvent &termMsg ) { - LOG_WARN(DomainManager_impl, "Abnormal Component Termination, Reporting Device: " << termMsg.device_id << " Application/Component " << - termMsg.application_id << "/" << termMsg.component_id ); + if (application) { + application->componentTerminated(termMsg.component_id, termMsg.device_id); + } else { + LOG_WARN(DomainManager_impl, "Abormal Component Termination, Reporting Device: " << termMsg.device_id + << " Application/Component " << termMsg.application_id << "/" << termMsg.component_id); + } } diff --git a/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp b/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp index ef0496415..1796ed031 100644 --- a/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp @@ -1783,7 +1783,7 @@ DomainManager_impl::addApplication(Application_impl* new_app) ApplicationNode appNode; appNode.name = ossie::corba::returnString(new_app->name()); - appNode.identifier = ossie::corba::returnString(new_app->identifier()); + appNode.identifier = new_app->getIdentifier(); appNode.profile = ossie::corba::returnString(new_app->profile()); appNode.contextName = new_app->_waveformContextName; appNode.context = CosNaming::NamingContext::_duplicate(new_app->_waveformContext); @@ -1832,6 +1832,45 @@ DomainManager_impl::addApplication(Application_impl* new_app) TRACE_EXIT(DomainManager_impl) } +void DomainManager_impl::addPendingApplication(Application_impl* application) +{ + TRACE_ENTER(DomainManager_impl); + boost::recursive_mutex::scoped_lock lock(stateAccess); + application->_add_ref(); + _pendingApplications[application->getIdentifier()] = application; + TRACE_EXIT(DomainManager_impl); +} + +void DomainManager_impl::cancelPendingApplication(Application_impl* application) +{ + TRACE_ENTER(DomainManager_impl); + boost::recursive_mutex::scoped_lock lock(stateAccess); + ApplicationTable::iterator iter = _pendingApplications.find(application->getIdentifier()); + if (iter == _pendingApplications.end()) { + LOG_ERROR(DomainManager_impl, "No pending application '" << application->getIdentifier() << "' to cancel"); + } else { + _pendingApplications.erase(iter); + application->_remove_ref(); + } + TRACE_EXIT(DomainManager_impl); +} + +void DomainManager_impl::completePendingApplication(Application_impl* application) +{ + TRACE_ENTER(DomainManager_impl); + boost::recursive_mutex::scoped_lock lock(stateAccess); + ApplicationTable::iterator iter = _pendingApplications.find(application->getIdentifier()); + if (iter == _pendingApplications.end()) { + LOG_ERROR(DomainManager_impl, "No pending application '" << application->getIdentifier() + << "' to move to active state"); + } else { + addApplication(application); + application->_remove_ref(); + _pendingApplications.erase(iter); + } + TRACE_EXIT(DomainManager_impl); +} + void DomainManager_impl::removeApplication(std::string app_id) { diff --git a/redhawk/src/control/sdr/dommgr/DomainManager_impl.h b/redhawk/src/control/sdr/dommgr/DomainManager_impl.h index eedc97fd2..cd47136c5 100644 --- a/redhawk/src/control/sdr/dommgr/DomainManager_impl.h +++ b/redhawk/src/control/sdr/dommgr/DomainManager_impl.h @@ -155,6 +155,10 @@ class DomainManager_impl: public virtual POA_CF::DomainManager, public PropertyS void restoreEventChannels(const std::string& _db_uri); void addApplication(Application_impl* new_app); + + void addPendingApplication(Application_impl* application); + void cancelPendingApplication(Application_impl* application); + void completePendingApplication(Application_impl* application); void releaseAllApplications(); @@ -280,7 +284,6 @@ class DomainManager_impl: public virtual POA_CF::DomainManager, public PropertyS // void establishDomainManagementChannels( const std::string &db_uri ); void disconnectDomainManagementChannels(); - void handleIDMChannelMessages( const CORBA::Any &msg ); void idmTerminationMessages( const redhawk::events::ComponentTerminationEvent &msg ); void destroyEventChannels (void); @@ -341,6 +344,7 @@ class DomainManager_impl: public virtual POA_CF::DomainManager, public PropertyS typedef std::map ApplicationTable; ApplicationTable _applications; + ApplicationTable _pendingApplications; typedef std::map ApplicationFactoryTable; ApplicationFactoryTable _applicationFactories; From 15e0279b7854e0fc0886f61baf5ceb1a967124e2 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 13 Jun 2016 11:04:18 -0400 Subject: [PATCH 0389/1644] Turn abnormal component termination during deployment into an immediate failure, with its own exception type --- .../sdr/dommgr/ApplicationDeployment.cpp | 11 +++++++ .../sdr/dommgr/ApplicationDeployment.h | 1 + .../sdr/dommgr/ApplicationFactory_impl.cpp | 29 +++++++++++++++---- .../control/sdr/dommgr/Application_impl.cpp | 5 +++- .../sdr/dommgr/DeploymentExceptions.cpp | 7 +++++ .../control/sdr/dommgr/DeploymentExceptions.h | 23 +++++++++++++++ redhawk/src/control/sdr/dommgr/createHelper.h | 2 +- 7 files changed, 71 insertions(+), 7 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp b/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp index 50142e0a2..824091e11 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp @@ -122,6 +122,17 @@ ComponentDeployment* ApplicationDeployment::getComponentDeployment(const std::st return 0; } +ComponentDeployment* ApplicationDeployment::getComponentDeploymentByUniqueId(const std::string& identifier) +{ + BOOST_FOREACH(ComponentDeployment* deployment, components) { + if (identifier == deployment->getIdentifier()) { + return deployment; + } + } + + return 0; +} + void ApplicationDeployment::applyCpuReservations(const CpuReservations& reservations) { BOOST_FOREACH(ComponentDeployment* deployment, components) { diff --git a/redhawk/src/control/sdr/dommgr/ApplicationDeployment.h b/redhawk/src/control/sdr/dommgr/ApplicationDeployment.h index 5ecf2f040..52c2623d4 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationDeployment.h +++ b/redhawk/src/control/sdr/dommgr/ApplicationDeployment.h @@ -63,6 +63,7 @@ namespace redhawk { const ComponentList& getComponentDeployments(); ComponentDeployment* getComponentDeployment(const std::string& instantiationId); + ComponentDeployment* getComponentDeploymentByUniqueId(const std::string& identifier); void applyCpuReservations(const CpuReservations& reservations); diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index ae55671ee..66c931c59 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -798,7 +798,7 @@ CF::Application_ptr createHelper::create ( CF::ApplicationRegistrar_var app_reg = _application->appReg(); loadAndExecuteComponents(app_deployment.getComponentDeployments(), app_reg); - waitForComponentRegistration(app_deployment.getComponentDeployments()); + waitForComponentRegistration(app_deployment); // Check that the assembly controller is valid LOG_TRACE(ApplicationFactory_impl, "Checking assembly controller"); @@ -1674,7 +1674,7 @@ void createHelper::applyApplicationAffinityOptions(const DeploymentList& deploym } -void createHelper::waitForComponentRegistration(const DeploymentList& deployments) +void createHelper::waitForComponentRegistration(redhawk::ApplicationDeployment& appDeployment) { // Wait for all components to be registered before continuing int componentBindingTimeout = _appFact._domainManager->getComponentBindingTimeout(); @@ -1683,6 +1683,7 @@ void createHelper::waitForComponentRegistration(const DeploymentList& deployment // Track only SCA-compliant components; non-compliant components will never // register with the application, nor do they need to be initialized std::set expected_components; + const DeploymentList& deployments = appDeployment.getComponentDeployments(); for (DeploymentList::const_iterator dep = deployments.begin(); dep != deployments.end(); ++dep) { if ((*dep)->getSoftPkg()->isScaCompliant()) { expected_components.insert((*dep)->getIdentifier()); @@ -1692,10 +1693,28 @@ void createHelper::waitForComponentRegistration(const DeploymentList& deployment // Record current time, to measure elapsed time in the event of a failure time_t start = time(NULL); - if (!_application->waitForComponents(expected_components, componentBindingTimeout)) { - // For reference, determine much time has really elapsed. - time_t elapsed = time(NULL)-start; + // Wait for all required components to register, adding additional context + // to any termination exceptions that may be raised + bool complete; + try { + complete = _application->waitForComponents(expected_components, componentBindingTimeout); + } catch (const redhawk::ComponentTerminated& exc) { + redhawk::ComponentDeployment* deployment = appDeployment.getComponentDeploymentByUniqueId(exc.identifier()); + if (!deployment) { + // The deployment should always be found, but in the event that it + // isn't, rethrow the original exception just in case; the outer + // create() exception handler will turn it into a CF exception + throw; + } + throw redhawk::ExecuteError(deployment, "component terminated before registering with application"); + } + + // For reference, determine much time has really elapsed. + time_t elapsed = time(NULL)-start; + if (!complete) { LOG_ERROR(ApplicationFactory_impl, "Timed out waiting for components to register (" << elapsed << "s elapsed)"); + } else { + LOG_DEBUG(ApplicationFactory_impl, "Component registration completed in " << elapsed << "s"); } // Fetch the objects, finding any components that did not register diff --git a/redhawk/src/control/sdr/dommgr/Application_impl.cpp b/redhawk/src/control/sdr/dommgr/Application_impl.cpp index 38422190d..d1ffaab3b 100644 --- a/redhawk/src/control/sdr/dommgr/Application_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/Application_impl.cpp @@ -32,6 +32,7 @@ #include "ApplicationRegistrar.h" #include "connectionSupport.h" #include "FakeApplication.h" +#include "DeploymentExceptions.h" PREPARE_CF_LOGGING(Application_impl); @@ -1196,8 +1197,10 @@ bool Application_impl::checkConnectionDependency (Endpoint::DependencyType type, bool Application_impl::_checkRegistrations (std::set& identifiers) { for (ossie::ComponentList::iterator ii = _components.begin(); ii != _components.end(); ++ii) { - if (is_registered(*ii) || is_terminated(*ii)) { + if (is_registered(*ii)) { identifiers.erase(ii->identifier); + } else if (is_terminated(*ii)) { + throw redhawk::ComponentTerminated(ii->identifier); } } return identifiers.empty(); diff --git a/redhawk/src/control/sdr/dommgr/DeploymentExceptions.cpp b/redhawk/src/control/sdr/dommgr/DeploymentExceptions.cpp index 23429dc7f..d6a10101e 100644 --- a/redhawk/src/control/sdr/dommgr/DeploymentExceptions.cpp +++ b/redhawk/src/control/sdr/dommgr/DeploymentExceptions.cpp @@ -151,3 +151,10 @@ std::string BadExternalPort::message() const msg << "': " << what(); return msg.str(); } + +std::string ComponentTerminated::message() const +{ + std::ostringstream msg; + msg << "Component '" << identifier() << "' terminated abnormally"; + return msg.str(); +} diff --git a/redhawk/src/control/sdr/dommgr/DeploymentExceptions.h b/redhawk/src/control/sdr/dommgr/DeploymentExceptions.h index 8991c12a4..8e52521aa 100644 --- a/redhawk/src/control/sdr/dommgr/DeploymentExceptions.h +++ b/redhawk/src/control/sdr/dommgr/DeploymentExceptions.h @@ -245,6 +245,29 @@ namespace redhawk { const std::string _name; const std::string _component; }; + + class ComponentTerminated : public DeploymentError { + public: + ComponentTerminated(const std::string& identifier) : + DeploymentError("component terminated abnormally"), + _identifier(identifier) + { + } + + virtual ~ComponentTerminated() throw () + { + } + + virtual std::string message() const; + + const std::string& identifier() const + { + return _identifier; + } + + private: + const std::string _identifier; + }; } #endif // DEPLOYMENTEXCEPTIONS_H diff --git a/redhawk/src/control/sdr/dommgr/createHelper.h b/redhawk/src/control/sdr/dommgr/createHelper.h index 9c0c8a620..593d571a4 100644 --- a/redhawk/src/control/sdr/dommgr/createHelper.h +++ b/redhawk/src/control/sdr/dommgr/createHelper.h @@ -161,7 +161,7 @@ class createHelper void attemptComponentExecution(CF::ApplicationRegistrar_ptr registrar, redhawk::ComponentDeployment* deployment); - void waitForComponentRegistration(const DeploymentList& deployments); + void waitForComponentRegistration(redhawk::ApplicationDeployment& appDeployment); void initializeComponents(const DeploymentList& deployments); void configureComponents(const DeploymentList& deployments); From 893a169ca0ac30bf061de30907ec3a6a24f6b2c0 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 13 Jun 2016 16:49:20 -0400 Subject: [PATCH 0390/1644] Initial working ApplicationFactory support for launching shared library components in a container (currently in an external repository) --- .../sdr/dommgr/ApplicationDeployment.cpp | 48 +++++++ .../sdr/dommgr/ApplicationDeployment.h | 22 +++ .../sdr/dommgr/ApplicationFactory_impl.cpp | 136 +++++++++++++++++- redhawk/src/control/sdr/dommgr/Deployment.cpp | 13 +- redhawk/src/control/sdr/dommgr/Deployment.h | 4 + redhawk/src/control/sdr/dommgr/createHelper.h | 5 + 6 files changed, 221 insertions(+), 7 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp b/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp index 824091e11..87a454d3f 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp @@ -26,12 +26,21 @@ #include "PersistenceStore.h" #include "ApplicationDeployment.h" +#include "ProfileCache.h" using namespace redhawk; using namespace ossie; PREPARE_LOGGING(ApplicationDeployment); +ContainerDeployment::ContainerDeployment(const ossie::SoftPkg* softpkg, + ossie::ComponentInstantiation* instantiation, + const std::string& identifier) : + ComponentDeployment(softpkg, instantiation, identifier), + instance(instantiation) +{ +} + ApplicationDeployment::ApplicationDeployment(const SoftwareAssembly& sad, const std::string& instanceName, const CF::Properties& initConfiguration) : @@ -106,11 +115,40 @@ ComponentDeployment* ApplicationDeployment::createComponentDeployment(const Soft return deployment; } +ContainerDeployment* ApplicationDeployment::createContainer(redhawk::ProfileCache& cache, + const boost::shared_ptr& device) +{ + ContainerDeployment* container = getContainer(device->identifier); + if (container) { + LOG_DEBUG(ApplicationDeployment, "Using existing container " << container->getIdentifier()); + return container; + } + + const ossie::SoftPkg* softpkg = cache.loadSoftPkg("/components/rh/AppContainer/AppContainer.spd.xml"); + + // Create an instantiation with the ID based on the device label; the + // deployment will own this object + ossie::ComponentInstantiation* instantiation = new ossie::ComponentInstantiation; + instantiation->instantiationId = "Container_" + device->label; + + LOG_DEBUG(ApplicationDeployment, "Creating container " << instantiation->getID()); + std::string container_id = identifier + ":" + instantiation->getID(); + + container = new ContainerDeployment(softpkg, instantiation, container_id); + containers.push_back(container); + return container; +} + const ApplicationDeployment::ComponentList& ApplicationDeployment::getComponentDeployments() { return components; } +const ApplicationDeployment::ContainerList& ApplicationDeployment::getContainerDeployments() +{ + return containers; +} + ComponentDeployment* ApplicationDeployment::getComponentDeployment(const std::string& instantiationId) { for (ComponentList::iterator comp = components.begin(); comp != components.end(); ++comp) { @@ -187,6 +225,16 @@ void ApplicationDeployment::overrideExternalProperties(ComponentDeployment* depl } } +ContainerDeployment* ApplicationDeployment::getContainer(const std::string& deviceId) +{ + BOOST_FOREACH(ContainerDeployment* container, containers) { + if (container->getAssignedDevice() && container->getAssignedDevice()->identifier == deviceId) { + return container; + } + } + return 0; +} + CF::Resource_ptr ApplicationDeployment::lookupComponentByInstantiationId(const std::string& identifier) { ComponentDeployment* deployment = getComponentDeployment(identifier); diff --git a/redhawk/src/control/sdr/dommgr/ApplicationDeployment.h b/redhawk/src/control/sdr/dommgr/ApplicationDeployment.h index 52c2623d4..92bf20c72 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationDeployment.h +++ b/redhawk/src/control/sdr/dommgr/ApplicationDeployment.h @@ -35,12 +35,27 @@ namespace redhawk { + class ProfileCache; + + class ContainerDeployment : public ComponentDeployment + { + public: + ContainerDeployment(const ossie::SoftPkg* softpkg, + ossie::ComponentInstantiation* instantiation, + const std::string& identifier); + + protected: + // The instantiation does not appear in a SAD; take ownership here + boost::scoped_ptr instance; + }; + class ApplicationDeployment : public ossie::ComponentLookup, public ossie::DeviceLookup, public UsesDeviceDeployment { ENABLE_LOGGING; public: typedef std::vector ComponentList; + typedef std::vector ContainerList; typedef std::map CpuReservations; ApplicationDeployment(const ossie::SoftwareAssembly& sad, @@ -67,6 +82,10 @@ namespace redhawk { void applyCpuReservations(const CpuReservations& reservations); + const ContainerList& getContainerDeployments(); + ContainerDeployment* createContainer(redhawk::ProfileCache& cache, + const boost::shared_ptr& device); + // Adapt interfaces for component and device search to support // ConnectionManager // ComponentLookup interface @@ -82,11 +101,14 @@ namespace redhawk { void overrideAssemblyControllerProperties(ComponentDeployment* deployment); void overrideExternalProperties(ComponentDeployment* deployment); + ContainerDeployment* getContainer(const std::string& deviceId); + const ossie::SoftwareAssembly& sad; const std::string identifier; const std::string instanceName; redhawk::PropertyMap initConfiguration; ComponentList components; + ContainerList containers; }; } diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 66c931c59..9029238ed 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -262,6 +262,23 @@ void createHelper::assignPlacementsToDevices(redhawk::ApplicationDeployment& app } redhawk::ComponentDeployment* deployment = appDeployment.createComponentDeployment(softpkg, &instantiation); allocateComponent(appDeployment, deployment, assigned_device); + + // For components that run as shared libraries, create or reuse a + // matching container deployment + if (deployment->getImplementation()->getCodeType() == SPD::Code::SHARED_LIBRARY) { + LOG_DEBUG(ApplicationFactory_impl, "Component " << deployment->getInstantiation()->getID() + << "' implementation " << deployment->getImplementation()->getID() + << " is a shared library"); + redhawk::ContainerDeployment* container = appDeployment.createContainer(_profileCache, deployment->getAssignedDevice()); + if (!container->getAssignedDevice()) { + // Use whether the device is assigned as a sentinel to check + // whether the container was already created, and if not, + // allocate it to the device + allocateComponent(appDeployment, container, deployment->getAssignedDevice()->identifier); + } + deployment->setContainer(container); + } + } } } @@ -792,12 +809,11 @@ CF::Application_ptr createHelper::create ( // Activate the new Application servant PortableServer::ObjectId_var oid = Application_impl::Activate(_application); - std::vector connections; - std::vector allocationIDs; - CF::ApplicationRegistrar_var app_reg = _application->appReg(); - loadAndExecuteComponents(app_deployment.getComponentDeployments(), app_reg); + loadAndExecuteContainers(app_deployment.getContainerDeployments(), app_reg); + waitForContainerRegistration(app_deployment); + loadAndExecuteComponents(app_deployment.getComponentDeployments(), app_reg); waitForComponentRegistration(app_deployment); // Check that the assembly controller is valid @@ -816,6 +832,7 @@ CF::Application_ptr createHelper::create ( initializeComponents(app_deployment.getComponentDeployments()); + std::vector connections; connectComponents(app_deployment, connections, _baseNamingContext); configureComponents(app_deployment.getComponentDeployments()); @@ -829,6 +846,7 @@ CF::Application_ptr createHelper::create ( // collocated. This means that we assume the SAD // element contains the element. NB: Ownership // of the ConnectionManager is passed to the application. + std::vector allocationIDs; _allocations.transfer(allocationIDs); // Fill in the uses devices for the application @@ -1398,6 +1416,61 @@ string ApplicationFactory_impl::getBaseWaveformContext(string waveform_context) return base_naming_context; } +void createHelper::loadAndExecuteContainers(const ContainerList& containers, + CF::ApplicationRegistrar_ptr _appReg) +{ + LOG_TRACE(ApplicationFactory_impl, "Loading and Executing " << containers.size() << " containers"); + // TODO: Promote contained component affinity values + + BOOST_FOREACH(redhawk::ContainerDeployment* container, containers) { + const ossie::SoftPkg* softpkg = container->getSoftPkg(); + const ossie::SPD::Implementation* implementation = container->getImplementation(); + + boost::shared_ptr device = container->getAssignedDevice(); + if (!device) { + std::ostringstream message; + message << "component " << container->getIdentifier() << " was not assigned to a device"; + throw std::logic_error(message.str()); + } + + // Let the application know to expect the given component + _application->addComponent(container->getIdentifier(), softpkg->getSPDFile()); + _application->setComponentImplementation(container->getIdentifier(), implementation->getID()); + _application->setComponentDevice(container->getIdentifier(), device->device); + + // get the code.localfile + LOG_TRACE(ApplicationFactory_impl, "Host is " << device->label << " Local file name is " + << container->getLocalFile()); + + // Get file name, load if it is not empty + std::string codeLocalFile = container->getLocalFile(); + if (codeLocalFile.empty()) { + // This should be caught by validation, but just in case + throw redhawk::ComponentError(container, "empty localfile"); + } + + // narrow to LoadableDevice interface + CF::LoadableDevice_var loadabledev = ossie::corba::_narrowSafe(device->device); + if (CORBA::is_nil(loadabledev)) { + std::ostringstream message; + message << "container " << container->getIdentifier() << " was assigned to non-loadable device " + << device->identifier; + LOG_ERROR(ApplicationFactory_impl, message); + throw std::logic_error(message.str()); + } + + LOG_TRACE(ApplicationFactory_impl, "Loading " << codeLocalFile << " and dependencies on device " + << device->label); + try { + container->load(_application, _appFact._fileMgr, loadabledev); + } catch (const std::exception& exc) { + throw redhawk::ComponentError(container, exc.what()); + } + + attemptComponentExecution(_appReg, container); + } +} + /* Perform 'load' and 'execute' operations to launch component on the assigned device * - Actually loads and executes the component on the given device */ @@ -1583,8 +1656,15 @@ void createHelper::attemptComponentExecution (CF::ApplicationRegistrar_ptr regis dep_seq[p]=CORBA::string_dup(resolved_softpkg_deps[p].c_str()); } - // attempt to execute the component - LOG_TRACE(ApplicationFactory_impl, "Executing " << entryPoint << " on device " << device->label); + // Attempt to execute the component + if (deployment->getContainer()) { + LOG_TRACE(ApplicationFactory_impl, "Executing " << entryPoint << " via container on device " << device->label); + redhawk::ComponentDeployment* container = deployment->getContainer(); + CF::Resource_var resource = container->getResourcePtr(); + execdev = CF::ExecutableDevice::_narrow(resource); + } else { + LOG_TRACE(ApplicationFactory_impl, "Executing " << entryPoint << " on device " << device->label); + } for (redhawk::PropertyMap::iterator prop = execParameters.begin(); prop != execParameters.end(); ++prop) { LOG_TRACE(ApplicationFactory_impl, " exec param " << prop->getId() << " " << prop->getValue().toString()); } @@ -1674,6 +1754,50 @@ void createHelper::applyApplicationAffinityOptions(const DeploymentList& deploym } +void createHelper::waitForContainerRegistration(redhawk::ApplicationDeployment& appDeployment) +{ + // Wait for any containers to be registered before continuing + int timeout = _appFact._domainManager->getComponentBindingTimeout(); + LOG_TRACE(ApplicationFactory_impl, "Waiting " << timeout << "s for containers to register"); + std::set expected_components; + BOOST_FOREACH(redhawk::ContainerDeployment* container, appDeployment.getContainerDeployments()) { + expected_components.insert(container->getIdentifier()); + } + + // Record current time, to measure elapsed time in the event of a failure + time_t start = time(NULL); + + // Wait for all required components to register, adding additional context + // to any termination exceptions that may be raised + bool complete = _application->waitForComponents(expected_components, timeout); + // TODO: convert into ExecuteError + + // For reference, determine much time has really elapsed. + time_t elapsed = time(NULL)-start; + if (!complete) { + LOG_ERROR(ApplicationFactory_impl, "Timed out waiting for container to register (" << elapsed << "s elapsed)"); + } else { + LOG_DEBUG(ApplicationFactory_impl, "Container registration completed in " << elapsed << "s"); + } + + // Fetch the objects, finding any components that did not register + BOOST_FOREACH(redhawk::ContainerDeployment* container, appDeployment.getContainerDeployments()) { + // Find the component on the Application + const std::string component_id = container->getIdentifier(); + CORBA::Object_var objref = _application->getComponentObject(component_id); + if (CORBA::is_nil(objref)) { + throw redhawk::ExecuteError(container, "container did not register with application"); + } + + CF::Resource_var resource = ossie::corba::_narrowSafe(objref); + if (CORBA::is_nil(resource)) { + throw redhawk::ComponentError(container, "component object is not a CF::Resource"); + } + + container->setResourcePtr(resource); + } +} + void createHelper::waitForComponentRegistration(redhawk::ApplicationDeployment& appDeployment) { // Wait for all components to be registered before continuing diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index 31e22aefc..0d9314f97 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -248,7 +248,8 @@ ComponentDeployment::ComponentDeployment(const SoftPkg* softpkg, SoftPkgDeployment(softpkg), instantiation(instantiation), identifier(identifier), - assemblyController(false) + assemblyController(false), + container(0) { // If the SoftPkg has an associated Properties, check the overrides for // validity @@ -286,6 +287,16 @@ const ComponentInstantiation* ComponentDeployment::getInstantiation() const return instantiation; } +void ComponentDeployment::setContainer(ComponentDeployment* container) +{ + this->container = container; +} + +ComponentDeployment* ComponentDeployment::getContainer() +{ + return container; +} + bool ComponentDeployment::isResource() const { return softpkg->getDescriptor()->isResource(); diff --git a/redhawk/src/control/sdr/dommgr/Deployment.h b/redhawk/src/control/sdr/dommgr/Deployment.h index ec44c5850..fa4144ae6 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.h +++ b/redhawk/src/control/sdr/dommgr/Deployment.h @@ -111,6 +111,9 @@ namespace redhawk { const ossie::ComponentInstantiation* getInstantiation() const; + void setContainer(ComponentDeployment* container); + ComponentDeployment* getContainer(); + bool isResource() const; bool isConfigurable() const; @@ -200,6 +203,7 @@ namespace redhawk { bool assemblyController; boost::shared_ptr assignedDevice; + ComponentDeployment* container; CF::Resource_var resource; redhawk::PropertyMap overrides; diff --git a/redhawk/src/control/sdr/dommgr/createHelper.h b/redhawk/src/control/sdr/dommgr/createHelper.h index 593d571a4..50cd13a2a 100644 --- a/redhawk/src/control/sdr/dommgr/createHelper.h +++ b/redhawk/src/control/sdr/dommgr/createHelper.h @@ -97,6 +97,7 @@ class createHelper redhawk::ProfileCache _profileCache; typedef std::vector DeploymentList; + typedef std::vector ContainerList; typedef std::vector ProcessorList; typedef std::vector OSList; @@ -155,6 +156,10 @@ class createHelper ossie::DeviceNode& device); // Supports loading, executing, initializing, configuring, & connecting + void loadAndExecuteContainers(const ContainerList& containers, + CF::ApplicationRegistrar_ptr _appReg); + void waitForContainerRegistration(redhawk::ApplicationDeployment& appDeployment); + void loadAndExecuteComponents(const DeploymentList& deployments, CF::ApplicationRegistrar_ptr _appReg); void applyApplicationAffinityOptions(const DeploymentList& deployments); From a58703bea8e572eafb86fcffce8223cb222f54b8 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 14 Jun 2016 15:18:00 -0400 Subject: [PATCH 0391/1644] Give application containers a naming service name (same as their instantiation ID) --- redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp b/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp index 87a454d3f..c35d0588f 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp @@ -126,10 +126,11 @@ ContainerDeployment* ApplicationDeployment::createContainer(redhawk::ProfileCach const ossie::SoftPkg* softpkg = cache.loadSoftPkg("/components/rh/AppContainer/AppContainer.spd.xml"); - // Create an instantiation with the ID based on the device label; the - // deployment will own this object + // Create an instantiation with the ID and naming service name based on the + // device label; the deployment will own this object ossie::ComponentInstantiation* instantiation = new ossie::ComponentInstantiation; instantiation->instantiationId = "Container_" + device->label; + instantiation->namingservicename = instantiation->instantiationId; LOG_DEBUG(ApplicationDeployment, "Creating container " << instantiation->getID()); std::string container_id = identifier + ":" + instantiation->getID(); From 4e90262aa893d22c2b6e9c4b71c1e473dad3cd42 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 14 Jun 2016 15:19:29 -0400 Subject: [PATCH 0392/1644] Don't include DOM_PATH and logging command line arguments for components inside of a container (for now, at least); add the assigned devices for containers to the Application --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 51 +++++++++++-------- 1 file changed, 31 insertions(+), 20 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 9029238ed..de82456d4 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -865,6 +865,13 @@ CF::Application_ptr createHelper::create ( ossie::corba::push_back(app_devices, assignment); } + BOOST_FOREACH(redhawk::ContainerDeployment* container, app_deployment.getContainerDeployments()) { + CF::DeviceAssignmentType comp_assignment; + comp_assignment.componentId = container->getIdentifier().c_str(); + comp_assignment.assignedDeviceId = container->getAssignedDevice()->identifier.c_str(); + ossie::corba::push_back(app_devices, comp_assignment); + } + const DeploymentList& deployments = app_deployment.getComponentDeployments(); for (DeploymentList::const_iterator dep = deployments.begin(); dep != deployments.end(); ++dep) { CF::DeviceAssignmentType comp_assignment; @@ -1612,29 +1619,33 @@ void createHelper::attemptComponentExecution (CF::ApplicationRegistrar_ptr regis if (deployment->getInstantiation()->isNamingService()) { execParameters["NAME_BINDING"] = deployment->getInstantiation()->getFindByNamingServiceName(); } - execParameters["DOM_PATH"] = _baseNamingContext; execParameters["PROFILE_NAME"] = deployment->getSoftPkg()->getSPDFile(); - // Pass logging configuration - std::string logging_uri = resolveLoggingConfiguration(deployment); - if (!logging_uri.empty()) { - // Check for sca: URI type, and append the IOR for the file system - if (logging_uri.find("sca:/") == 0) { - string ior = ossie::corba::objectToString(_appFact._domainManager->_fileMgr); - logging_uri += ("?fs=" + ior); - LOG_TRACE(ApplicationFactory_impl, "Adding file system IOR " << logging_uri); - } - LOG_DEBUG(ApplicationFactory_impl, " LOGGING_CONFIG_URI: " << logging_uri); - execParameters["LOGGING_CONFIG_URI"] = logging_uri; - } else { - // No LOGGING_CONFIG_URI can be found, pass DEBUG_LEVEL - rh_logger::LoggerPtr dom_logger = _appFact._domainManager->getLogger(); - if (dom_logger) { - rh_logger::LevelPtr dlevel = dom_logger->getLevel(); - if (!dlevel) { - dlevel = rh_logger::Logger::getRootLogger()->getLevel(); + // Pass logging configuration, unless the component is being run in a + // container + // TODO: Determine how to handle configuration of logging in containers + if (!deployment->getContainer()) { + execParameters["DOM_PATH"] = _baseNamingContext; + std::string logging_uri = resolveLoggingConfiguration(deployment); + if (!logging_uri.empty()) { + // Check for sca: URI type, and append the IOR for the file system + if (logging_uri.find("sca:/") == 0) { + string ior = ossie::corba::objectToString(_appFact._domainManager->_fileMgr); + logging_uri += ("?fs=" + ior); + LOG_TRACE(ApplicationFactory_impl, "Adding file system IOR " << logging_uri); + } + LOG_DEBUG(ApplicationFactory_impl, " LOGGING_CONFIG_URI: " << logging_uri); + execParameters["LOGGING_CONFIG_URI"] = logging_uri; + } else { + // No LOGGING_CONFIG_URI can be found, pass DEBUG_LEVEL + rh_logger::LoggerPtr dom_logger = _appFact._domainManager->getLogger(); + if (dom_logger) { + rh_logger::LevelPtr dlevel = dom_logger->getLevel(); + if (!dlevel) { + dlevel = rh_logger::Logger::getRootLogger()->getLevel(); + } + execParameters["DEBUG_LEVEL"] = static_cast(ossie::logging::ConvertRHLevelToDebug(dlevel)); } - execParameters["DEBUG_LEVEL"] = static_cast(ossie::logging::ConvertRHLevelToDebug(dlevel)); } } From 52449bf90161c4759de90694772f7c66fd798e77 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 14 Jun 2016 16:26:46 -0400 Subject: [PATCH 0393/1644] Quick fixes for application cleanup with containers: release containers last, don't terminate hosted components, make sure name binding gets cleaned up --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 7 +++- .../control/sdr/dommgr/Application_impl.cpp | 35 +++++++++++++++++-- .../src/control/sdr/dommgr/Application_impl.h | 1 + .../src/control/sdr/dommgr/PersistenceStore.h | 2 ++ 4 files changed, 42 insertions(+), 3 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index de82456d4..efc140137 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -1432,6 +1432,7 @@ void createHelper::loadAndExecuteContainers(const ContainerList& containers, BOOST_FOREACH(redhawk::ContainerDeployment* container, containers) { const ossie::SoftPkg* softpkg = container->getSoftPkg(); const ossie::SPD::Implementation* implementation = container->getImplementation(); + const ossie::ComponentInstantiation* instantiation = container->getInstantiation(); boost::shared_ptr device = container->getAssignedDevice(); if (!device) { @@ -1441,7 +1442,11 @@ void createHelper::loadAndExecuteContainers(const ContainerList& containers, } // Let the application know to expect the given component - _application->addComponent(container->getIdentifier(), softpkg->getSPDFile()); + _application->addContainer(container->getIdentifier(), softpkg->getSPDFile()); + if (instantiation->isNamingService()) { + std::string lookupName = _baseNamingContext + "/" + instantiation->getFindByNamingServiceName(); + _application->setComponentNamingContext(container->getIdentifier(), lookupName); + } _application->setComponentImplementation(container->getIdentifier(), implementation->getID()); _application->setComponentDevice(container->getIdentifier(), device->device); diff --git a/redhawk/src/control/sdr/dommgr/Application_impl.cpp b/redhawk/src/control/sdr/dommgr/Application_impl.cpp index d1ffaab3b..687666b62 100644 --- a/redhawk/src/control/sdr/dommgr/Application_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/Application_impl.cpp @@ -997,7 +997,7 @@ throw (CORBA::SystemException, CF::LifeCycle::ReleaseError) void Application_impl::releaseComponents() { for (ossie::ComponentList::iterator ii = _components.begin(); ii != _components.end(); ++ii) { - if (CORBA::is_nil(ii->componentObject)) { + if (ii->isContainer || CORBA::is_nil(ii->componentObject)) { // Ignore components that never registered continue; } @@ -1010,6 +1010,21 @@ void Application_impl::releaseComponents() resource->releaseObject(); } CATCH_LOG_WARN(Application_impl, "releaseObject failed for component '" << ii->identifier << "'"); } + + for (ossie::ComponentList::iterator ii = _components.begin(); ii != _components.end(); ++ii) { + if (!(ii->isContainer) || CORBA::is_nil(ii->componentObject)) { + // Ignore components that never registered + continue; + } + + LOG_DEBUG(Application_impl, "Releasing container '" << ii->identifier << "'"); + try { + CF::Resource_var resource = CF::Resource::_narrow(ii->componentObject); + unsigned long timeout = 3; // seconds + omniORB::setClientCallTimeout(resource, timeout * 1000); + resource->releaseObject(); + } CATCH_LOG_WARN(Application_impl, "releaseObject failed for component '" << ii->identifier << "'"); + } } void Application_impl::terminateComponents() @@ -1017,7 +1032,7 @@ void Application_impl::terminateComponents() // Terminate any components that were executed on devices for (ossie::ComponentList::iterator ii = _components.begin(); ii != _components.end(); ++ii) { const unsigned long pid = ii->processId; - if (pid == 0) { + if (pid == 0 || pid >= 65536) { continue; } @@ -1298,6 +1313,21 @@ ossie::ApplicationComponent* Application_impl::findComponent(const std::string& return 0; } +void Application_impl::addContainer(const std::string& identifier, const std::string& profile) +{ + if (findComponent(identifier)) { + LOG_ERROR(Application_impl, "Container '" << identifier << "' is already registered"); + return; + } + LOG_DEBUG(Application_impl, "Adding container '" << identifier << "' with profile " << profile); + ossie::ApplicationComponent component; + component.identifier = identifier; + component.softwareProfile = profile; + component.processId = 0; + component.isContainer = true; + _components.push_back(component); +} + void Application_impl::addComponent(const std::string& identifier, const std::string& profile) { if (findComponent(identifier)) { @@ -1309,6 +1339,7 @@ void Application_impl::addComponent(const std::string& identifier, const std::st component.identifier = identifier; component.softwareProfile = profile; component.processId = 0; + component.isContainer = false; _components.push_back(component); } diff --git a/redhawk/src/control/sdr/dommgr/Application_impl.h b/redhawk/src/control/sdr/dommgr/Application_impl.h index 15b65455b..bbab68b84 100644 --- a/redhawk/src/control/sdr/dommgr/Application_impl.h +++ b/redhawk/src/control/sdr/dommgr/Application_impl.h @@ -142,6 +142,7 @@ class Application_impl : public virtual POA_CF::Application, public Logging_impl // Set component state void addComponent(const std::string& identifier, const std::string& profile); + void addContainer(const std::string& identifier, const std::string& profile); void setComponentPid(const std::string& identifier, unsigned long pid); void setComponentNamingContext(const std::string& identifier, const std::string& name); void setComponentImplementation(const std::string& identifier, const std::string& implementationId); diff --git a/redhawk/src/control/sdr/dommgr/PersistenceStore.h b/redhawk/src/control/sdr/dommgr/PersistenceStore.h index e2888719c..f70aa906f 100644 --- a/redhawk/src/control/sdr/dommgr/PersistenceStore.h +++ b/redhawk/src/control/sdr/dommgr/PersistenceStore.h @@ -104,6 +104,7 @@ namespace ossie { unsigned long processId; CORBA::Object_var componentObject; CF::Device_var assignedDevice; + bool isContainer; }; typedef std::list ComponentList; @@ -261,6 +262,7 @@ namespace boost { ar & node.processId; ar & node.componentObject; ar & node.assignedDevice; + ar & node.isContainer; } template From 98ab658141b5153379da0b35ef3c1fbb47aa5fa2 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 14 Jun 2016 16:50:17 -0400 Subject: [PATCH 0394/1644] Exclude containers from external visibility in Application --- redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp | 7 ------- redhawk/src/control/sdr/dommgr/Application_impl.cpp | 6 ++++-- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index efc140137..8821aeae3 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -865,13 +865,6 @@ CF::Application_ptr createHelper::create ( ossie::corba::push_back(app_devices, assignment); } - BOOST_FOREACH(redhawk::ContainerDeployment* container, app_deployment.getContainerDeployments()) { - CF::DeviceAssignmentType comp_assignment; - comp_assignment.componentId = container->getIdentifier().c_str(); - comp_assignment.assignedDeviceId = container->getAssignedDevice()->identifier.c_str(); - ossie::corba::push_back(app_devices, comp_assignment); - } - const DeploymentList& deployments = app_deployment.getComponentDeployments(); for (DeploymentList::const_iterator dep = deployments.begin(); dep != deployments.end(); ++dep) { CF::DeviceAssignmentType comp_assignment; diff --git a/redhawk/src/control/sdr/dommgr/Application_impl.cpp b/redhawk/src/control/sdr/dommgr/Application_impl.cpp index 687666b62..45e6bbc8a 100644 --- a/redhawk/src/control/sdr/dommgr/Application_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/Application_impl.cpp @@ -92,7 +92,9 @@ namespace { void convert_sequence(Sequence& out, Iterator begin, const Iterator end, Function func) { for (; begin != end; ++begin) { - ossie::corba::push_back(out, func(*begin)); + if (!begin->isContainer) { + ossie::corba::push_back(out, func(*begin)); + } } } @@ -106,7 +108,7 @@ namespace { void convert_sequence_if(Sequence& out, Iterator begin, const Iterator end, Function func, Predicate pred) { for (; begin != end; ++begin) { - if (pred(*begin)) { + if (!(begin->isContainer) && pred(*begin)) { ossie::corba::push_back(out, func(*begin)); } } From f23817a7257f59e823e0edab89dcfcfb481d23a9 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 20 Jun 2016 09:47:23 -0400 Subject: [PATCH 0395/1644] Use the same pattern for container identifiers as for components; clean up the container list; use the device identifier instead of the device label for the container identifier to guarantee uniqueness --- .../control/sdr/dommgr/ApplicationDeployment.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp b/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp index c35d0588f..337aa576e 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp @@ -57,8 +57,11 @@ ApplicationDeployment::ApplicationDeployment(const SoftwareAssembly& sad, ApplicationDeployment::~ApplicationDeployment() { - for (ComponentList::iterator comp = components.begin(); comp != components.end(); ++comp) { - delete *comp; + BOOST_FOREACH(ComponentDeployment* component, components) { + delete component; + } + BOOST_FOREACH(ContainerDeployment* container, containers) { + delete container; } } @@ -127,13 +130,14 @@ ContainerDeployment* ApplicationDeployment::createContainer(redhawk::ProfileCach const ossie::SoftPkg* softpkg = cache.loadSoftPkg("/components/rh/AppContainer/AppContainer.spd.xml"); // Create an instantiation with the ID and naming service name based on the - // device label; the deployment will own this object + // device identifier; the deployment will own this object ossie::ComponentInstantiation* instantiation = new ossie::ComponentInstantiation; - instantiation->instantiationId = "Container_" + device->label; + instantiation->instantiationId = "Container_" + device->identifier; instantiation->namingservicename = instantiation->instantiationId; + // Use the same pattern as components to generate the unique runtime ID LOG_DEBUG(ApplicationDeployment, "Creating container " << instantiation->getID()); - std::string container_id = identifier + ":" + instantiation->getID(); + std::string container_id = instantiation->getID() + ":" + instanceName; container = new ContainerDeployment(softpkg, instantiation, container_id); containers.push_back(container); From dd79486346c1d668c80d9b9f232bfb853bd2b0c2 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 20 Jun 2016 10:02:51 -0400 Subject: [PATCH 0396/1644] Propagate the message from an InvalidFilename exception in executeLinked --- redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 8821aeae3..3e1acdf19 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -1689,8 +1689,8 @@ void createHelper::attemptComponentExecution (CF::ApplicationRegistrar_ptr regis try { // call 'execute' on the ExecutableDevice to execute the component pid = execdev->executeLinked(entryPoint.c_str(), options, execParameters, dep_seq); - } catch (const CF::InvalidFileName&) { - throw redhawk::ExecuteError(deployment, "invalid filename"); + } catch (const CF::InvalidFileName& exc) { + throw redhawk::ExecuteError(deployment, "invalid filename " + std::string(exc.msg)); } catch (const CF::Device::InvalidState& exc) { std::string message = "invalid device state " + std::string(exc.msg); throw redhawk::ExecuteError(deployment, message); From 7905b9e255b79b5c846f65f841fd4a9bf154ad98 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 20 Jun 2016 13:55:24 -0400 Subject: [PATCH 0397/1644] Provide a new system-defined RH::DEPLOYMENT_ROOT property as a command-line argument to components, along with a corresponding member variable, so that deployed components have a way of locating other deployed softpkgs --- redhawk/src/base/framework/ExecutableDevice_impl.cpp | 8 +++++--- redhawk/src/base/framework/LoadableDevice_impl.cpp | 9 +++++---- redhawk/src/base/framework/Resource_impl.cpp | 7 +++++++ redhawk/src/base/framework/python/ossie/device.py | 2 ++ redhawk/src/base/include/ossie/LoadableDevice_impl.h | 7 ++++--- redhawk/src/base/include/ossie/Resource_impl.h | 3 +++ 6 files changed, 26 insertions(+), 10 deletions(-) diff --git a/redhawk/src/base/framework/ExecutableDevice_impl.cpp b/redhawk/src/base/framework/ExecutableDevice_impl.cpp index 26757f2cc..786b89081 100644 --- a/redhawk/src/base/framework/ExecutableDevice_impl.cpp +++ b/redhawk/src/base/framework/ExecutableDevice_impl.cpp @@ -154,9 +154,11 @@ CF::ExecutableDevice::ProcessID_Type ExecutableDevice_impl::executeLinked (const } update_selected_paths(selected_paths); - std::vector prepend_args; - CF::ExecutableDevice::ProcessID_Type pid = execute(name, options, parameters); - return pid; + // Add the system-defined DEPLOYMENT_ROOT property to the command line + redhawk::PropertyMap arguments(parameters); + arguments["RH::DEPLOYMENT_ROOT"] = getCacheDirectory(); + + return execute(name, options, arguments); } CF::ExecutableDevice::ProcessID_Type ExecutableDevice_impl::execute (const char* name, const CF::Properties& options, const CF::Properties& parameters) throw (CORBA::SystemException, CF::Device::InvalidState, CF::ExecutableDevice::InvalidFunction, CF::ExecutableDevice::InvalidParameters, CF::ExecutableDevice::InvalidOptions, CF::InvalidFileName, CF::ExecutableDevice::ExecuteFail) diff --git a/redhawk/src/base/framework/LoadableDevice_impl.cpp b/redhawk/src/base/framework/LoadableDevice_impl.cpp index 33f81e5ed..63e2fc3f8 100644 --- a/redhawk/src/base/framework/LoadableDevice_impl.cpp +++ b/redhawk/src/base/framework/LoadableDevice_impl.cpp @@ -174,6 +174,9 @@ void LoadableDevice_impl::_init () { "bytes", "external", "configure"); + + // Default to the current working directory + cacheDirectory = ossie::getCurrentDirName(); } @@ -881,9 +884,7 @@ bool LoadableDevice_impl::isFileLoaded (const char* fileName) } -void LoadableDevice_impl ::configure (const CF::Properties& capacities) -throw (CF::PropertySet::PartialConfiguration, CF::PropertySet:: - InvalidConfiguration, CORBA::SystemException) +const std::string& LoadableDevice_impl::getCacheDirectory() const { - Device_impl::configure(capacities); + return cacheDirectory; } diff --git a/redhawk/src/base/framework/Resource_impl.cpp b/redhawk/src/base/framework/Resource_impl.cpp index bf862a8be..24b4dd032 100644 --- a/redhawk/src/base/framework/Resource_impl.cpp +++ b/redhawk/src/base/framework/Resource_impl.cpp @@ -190,10 +190,17 @@ std::string& Resource_impl::getCurrentWorkingDirectory() { return this->currentWorkingDirectory; } +const std::string& Resource_impl::getDeploymentRoot() const +{ + return _deploymentRoot; +} + void Resource_impl::setCommandLineProperty(const std::string& id, const redhawk::Value& value) { if (id == "PROFILE_NAME") { _softwareProfile = value.toString(); + } else if (id == "RH::DEPLOYMENT_ROOT") { + _deploymentRoot = value.toString(); } else { PropertySet_impl::setCommandLineProperty(id, value); } diff --git a/redhawk/src/base/framework/python/ossie/device.py b/redhawk/src/base/framework/python/ossie/device.py index 2b23340d3..9ee4c0459 100644 --- a/redhawk/src/base/framework/python/ossie/device.py +++ b/redhawk/src/base/framework/python/ossie/device.py @@ -709,6 +709,7 @@ def __init__(self, devmgr, identifier, label, softwareProfile, compositeDevice, self.__cacheLock = threading.Lock() self._sharedPkgs = {} self.initialState = envStateContainer() + self._cacheDirectory = os.getcwd() def releaseObject(self): self._unloadAll() @@ -1139,6 +1140,7 @@ def executeLinked(self, name, options, parameters, deps): if self._sharedPkgs.has_key(dep): selected_paths.append(self._sharedPkgs[dep]) self._update_selected_paths(selected_paths) + parameters.append(CF.DataType('RH::DEPLOYMENT_ROOT', any.to_any(self._cacheDirectory))) pid = self.execute(name, options, parameters) finally: self._cmdLock.release() diff --git a/redhawk/src/base/include/ossie/LoadableDevice_impl.h b/redhawk/src/base/include/ossie/LoadableDevice_impl.h index 57f104321..c857bf56e 100644 --- a/redhawk/src/base/include/ossie/LoadableDevice_impl.h +++ b/redhawk/src/base/include/ossie/LoadableDevice_impl.h @@ -170,9 +170,6 @@ class LoadableDevice_impl: LoadableDevice_impl (char*, char*, char*, char*, char*); LoadableDevice_impl (char*, char*, char*, char*, CF::Properties capacities, char*); virtual ~LoadableDevice_impl (); - void configure (const CF::Properties& configProperties) - throw (CF::PropertySet::PartialConfiguration, - CF::PropertySet::InvalidConfiguration, CORBA::SystemException); // Externally visible function call to load a file void load (CF::FileSystem_ptr fs, const char* fileName, @@ -227,12 +224,16 @@ class LoadableDevice_impl: // Transfer size when loading files CORBA::LongLong transferSize; // block transfer size when loading files + // Returns the base directory in use for the file cache + const std::string& getCacheDirectory() const; + private: LoadableDevice_impl(); // No default constructor LoadableDevice_impl(LoadableDevice_impl&); // No copying void _init(); std::map cacheTimestamps; std::map > duplicate_filenames; + std::string cacheDirectory; void _loadTree(CF::FileSystem_ptr fs, std::string remotePath, boost::filesystem::path& localPath, std::string fileKey); void _deleteTree(const std::string &fileKey); diff --git a/redhawk/src/base/include/ossie/Resource_impl.h b/redhawk/src/base/include/ossie/Resource_impl.h index c34af5c6d..6e687374b 100644 --- a/redhawk/src/base/include/ossie/Resource_impl.h +++ b/redhawk/src/base/include/ossie/Resource_impl.h @@ -126,6 +126,8 @@ class Resource_impl: void setDomainManager(CF::DomainManager_ptr domainManager); + const std::string& getDeploymentRoot() const; + /* * Boolean describing whether or not this Resource is started */ @@ -158,6 +160,7 @@ class Resource_impl: std::string currentWorkingDirectory; boost::scoped_ptr _domMgr; bool _initialized; + std::string _deploymentRoot; ossie::notification _resourceReleased; From 34e4c0f02d72ba9401342c975560c4ee9100ce8d Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 20 Jun 2016 15:00:44 -0400 Subject: [PATCH 0398/1644] Integrate ComponentHost (previously, AppContainer) into core --- redhawk/src/configure.ac | 1 + .../sdr/ComponentHost/ComponentHost.cpp | 225 ++++++++++++++++++ .../control/sdr/ComponentHost/ComponentHost.h | 76 ++++++ .../sdr/ComponentHost/ComponentHost.prf.xml | 22 ++ .../sdr/ComponentHost/ComponentHost.scd.xml | 64 +++++ .../sdr/ComponentHost/ComponentHost.spd.xml | 46 ++++ .../src/control/sdr/ComponentHost/Makefile.am | 33 +++ .../sdr/ComponentHost/ModuleLoader.cpp | 189 +++++++++++++++ .../control/sdr/ComponentHost/ModuleLoader.h | 110 +++++++++ .../src/control/sdr/ComponentHost/main.cpp | 28 +++ redhawk/src/control/sdr/Makefile.am | 2 +- .../sdr/dommgr/ApplicationDeployment.cpp | 2 +- 12 files changed, 796 insertions(+), 2 deletions(-) create mode 100644 redhawk/src/control/sdr/ComponentHost/ComponentHost.cpp create mode 100644 redhawk/src/control/sdr/ComponentHost/ComponentHost.h create mode 100644 redhawk/src/control/sdr/ComponentHost/ComponentHost.prf.xml create mode 100644 redhawk/src/control/sdr/ComponentHost/ComponentHost.scd.xml create mode 100644 redhawk/src/control/sdr/ComponentHost/ComponentHost.spd.xml create mode 100644 redhawk/src/control/sdr/ComponentHost/Makefile.am create mode 100644 redhawk/src/control/sdr/ComponentHost/ModuleLoader.cpp create mode 100644 redhawk/src/control/sdr/ComponentHost/ModuleLoader.h create mode 100644 redhawk/src/control/sdr/ComponentHost/main.cpp diff --git a/redhawk/src/configure.ac b/redhawk/src/configure.ac index 43ab53adc..fe6278af3 100644 --- a/redhawk/src/configure.ac +++ b/redhawk/src/configure.ac @@ -296,6 +296,7 @@ AC_CONFIG_FILES(Makefile \ control/sdr/Makefile \ control/sdr/dommgr/Makefile \ control/sdr/devmgr/Makefile \ + control/sdr/ComponentHost/Makefile \ base/Makefile \ base/framework/python/Makefile \ base/framework/java/Makefile \ diff --git a/redhawk/src/control/sdr/ComponentHost/ComponentHost.cpp b/redhawk/src/control/sdr/ComponentHost/ComponentHost.cpp new file mode 100644 index 000000000..f75b8088f --- /dev/null +++ b/redhawk/src/control/sdr/ComponentHost/ComponentHost.cpp @@ -0,0 +1,225 @@ +/* +* This file is protected by Copyright. Please refer to the COPYRIGHT file +* distributed with this source distribution. +* +* This file is part of REDHAWK core. +* +* REDHAWK core is free software: you can redistribute it and/or modify it +* under the terms of the GNU Lesser General Public License as published by the +* Free Software Foundation, either version 3 of the License, or (at your +* option) any later version. +* +* REDHAWK core is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License +* for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see http://www.gnu.org/licenses/. +*/ + +#include + +#include "ComponentHost.h" +#include "ModuleLoader.h" + +using namespace redhawk; +namespace fs = boost::filesystem; + +namespace redhawk { + struct ComponentEntry { + boost::scoped_ptr bundle; + Resource_impl* servant; + }; +} + +PREPARE_LOGGING(ComponentHost); + +ComponentHost::ComponentHost(const char* identifier, const char* label) : + Component(identifier, label), + counter(0) +{ + executorService.start(); +} + +ComponentHost::~ComponentHost() +{ + executorService.stop(); +} + +void ComponentHost::constructor() +{ +} + +CORBA::Boolean ComponentHost::allocateCapacity(const CF::Properties& capacities) +{ + return false; +} + +void ComponentHost::deallocateCapacity(const CF::Properties& capacites) +{ +} + +CF::Device::UsageType ComponentHost::usageState() +{ + return CF::Device::IDLE; +} + +CF::Device::AdminType ComponentHost::adminState() +{ + return CF::Device::UNLOCKED; +} + +void ComponentHost::adminState(CF::Device::AdminType state) +{ +} + +CF::Device::OperationalType ComponentHost::operationalState() +{ + return CF::Device::ENABLED; +} + +char* ComponentHost::label() +{ + return Resource_impl::identifier(); +} + +CF::AggregateDevice_ptr ComponentHost::compositeDevice() +{ + return CF::AggregateDevice::_nil(); +} + +void ComponentHost::load(CF::FileSystem_ptr, const char* fileName, CF::LoadableDevice::LoadType loadKind) +{ +} + +void ComponentHost::unload(const char* fileName) +{ +} + +void ComponentHost::terminate(CF::ExecutableDevice::ProcessID_Type processId) +{ + Resource_impl* component = 0; + { + boost::mutex::scoped_lock lock(loadMutex); + ComponentTable::iterator entry = activeComponents.find(processId); + if (entry == activeComponents.end()) { + throw CF::ExecutableDevice::InvalidProcess(CF::CF_EINVAL, "No such component"); + } + component = entry->second->servant; + } + component->releaseObject(); +} + +CF::ExecutableDevice::ProcessID_Type ComponentHost::execute(const char* name, const CF::Properties& options, const CF::Properties& parameters) +{ + return executeLinked(name, options, parameters, CF::StringSequence()); +} + +std::string ComponentHost::getRealPath(const std::string& path) +{ + // Assume that all paths are relative to the deployment root, which is + // given by the launching device (or the Sandbox) + fs::path realpath = fs::path(getDeploymentRoot()) / path; + if (!fs::exists(realpath)) { + std::string message = "File " + path + " does not exist"; + throw CF::InvalidFileName(CF::CF_EEXIST, message.c_str()); + } + return realpath.string(); +} + +CF::ExecutableDevice::ProcessID_Type ComponentHost::executeLinked(const char* name, const CF::Properties& options, const CF::Properties& parameters, const CF::StringSequence& deps) +{ + const std::string path = getRealPath(name); + + boost::scoped_ptr bundle(new ModuleBundle(path)); + + boost::mutex::scoped_lock lock(loadMutex); + for (size_t ii = 0; ii < deps.length(); ++ii) { + const std::string libpath = getRealPath(std::string(deps[ii])); + LOG_DEBUG(ComponentHost, "Loading dependency: " << libpath); + try { + // We don't know which symbols are needed from this library; they + // just need to be accessible to the component entry point. Loading + // them as "local" instead of "global" allows symbol conflicts to + // be resolved correctly (it seems). + if (fs::is_directory(libpath)) { + bundle->loadDirectory(libpath, ModuleLoader::LAZY, ModuleLoader::LOCAL); + } else { + bundle->load(libpath, ModuleLoader::LAZY, ModuleLoader::LOCAL); + } + } catch (const std::exception& exc) { + throw CF::InvalidFileName(CF::CF_EINVAL, exc.what()); + } + } + + typedef Resource_impl* (*ConstructorPtr)(const std::string&, const std::string&); + ConstructorPtr make_component; + try { + // Resolve all required symbols now so that we can catch the error and + // turn it into an exception, rather than having the process exit at + // point-of-use + Module* module = bundle->load(path, ModuleLoader::NOW, ModuleLoader::LOCAL); + LOG_DEBUG(ComponentHost, "Resolving module entry point"); + make_component = reinterpret_cast(module->symbol("make_component")); + } catch (const std::exception& exc) { + make_component = 0; + } + if (!make_component) { + throw CF::ExecutableDevice::InvalidFunction(); + } + + LOG_DEBUG(ComponentHost, "Creating component"); + Resource_impl* servant = Resource_impl::create_component(make_component, parameters); + + ComponentEntry* component = new ComponentEntry; + component->bundle.swap(bundle); + component->servant = servant; + + int thread_id = (++counter) | getpid() << 16; + activeComponents[thread_id] = component; + LOG_DEBUG(ComponentHost, "Assigning thread ID " << thread_id); + + servant->addReleaseListener(this, &ComponentHost::componentReleased); + + return thread_id; +} + +void ComponentHost::componentReleased(Resource_impl* component) +{ + LOG_DEBUG(ComponentHost, "Component released: " << component->getIdentifier()); + boost::mutex::scoped_lock lock(loadMutex); + ComponentTable::iterator entry; + for (entry = activeComponents.begin(); entry != activeComponents.end(); ++entry) { + if (entry->second->servant == component) { + break; + } + } + + if (entry == activeComponents.end()) { + LOG_DEBUG(ComponentHost, "Received release notification from unmanaged component " + << component->getIdentifier()); + return; + } + + executorService.execute(&ComponentHost::cleanupComponent, this, entry->second); + activeComponents.erase(entry); +} + +void ComponentHost::cleanupComponent(ComponentEntry* component) +{ + // Only if this is the last reference to the servant can we safely unload + // its shared libraries, because we need to know that it has been deleted + if (component->servant->_refcount_value() == 1) { + component->servant->_remove_ref(); + LOG_DEBUG(ComponentHost, "Unloading bundle " << component->bundle->name()); + component->bundle->unload(); + delete component; + return; + } + + // Try again after a small delay + LOG_DEBUG(ComponentHost, "Rescheduling component cleanup"); + boost::system_time when = boost::get_system_time() + boost::posix_time::microseconds(125); + executorService.schedule(when, &ComponentHost::cleanupComponent, this, component); +} diff --git a/redhawk/src/control/sdr/ComponentHost/ComponentHost.h b/redhawk/src/control/sdr/ComponentHost/ComponentHost.h new file mode 100644 index 000000000..ed2a08c14 --- /dev/null +++ b/redhawk/src/control/sdr/ComponentHost/ComponentHost.h @@ -0,0 +1,76 @@ +/* +* This file is protected by Copyright. Please refer to the COPYRIGHT file +* distributed with this source distribution. +* +* This file is part of REDHAWK core. +* +* REDHAWK core is free software: you can redistribute it and/or modify it +* under the terms of the GNU Lesser General Public License as published by the +* Free Software Foundation, either version 3 of the License, or (at your +* option) any later version. +* +* REDHAWK core is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License +* for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see http://www.gnu.org/licenses/. +*/ + +#ifndef COMPONENTHOST_H +#define COMPONENTHOST_H + +#include +#include + +namespace redhawk { + class ComponentEntry; + + class ComponentHost : public Component, public virtual POA_CF::ExecutableDevice + { + ENABLE_LOGGING; + + public: + ComponentHost(const char* identifier, const char* label); + ~ComponentHost(); + + void constructor(); + + // Device functions + virtual CORBA::Boolean allocateCapacity(const CF::Properties& capacities); + virtual void deallocateCapacity(const CF::Properties& capacites); + virtual CF::Device::UsageType usageState(); + virtual CF::Device::AdminType adminState(); + virtual void adminState(CF::Device::AdminType state); + virtual CF::Device::OperationalType operationalState(); + virtual char* label(); + virtual CF::AggregateDevice_ptr compositeDevice(); + + // Loadable device functions + virtual void load(CF::FileSystem_ptr fs, const char* fileName, CF::LoadableDevice::LoadType loadKind); + virtual void unload(const char* fileName); + + // Executable device functions + virtual void terminate(CF::ExecutableDevice::ProcessID_Type processId); + virtual CF::ExecutableDevice::ProcessID_Type execute(const char* name, const CF::Properties& options, const CF::Properties& parameters); + virtual CF::ExecutableDevice::ProcessID_Type executeLinked(const char* name, const CF::Properties& options, const CF::Properties& parameters, const CF::StringSequence& deps); + + private: + void componentReleased(Resource_impl* object); + void cleanupComponent(ComponentEntry* entry); + + std::string getRealPath(const std::string& path); + + int counter; + + boost::mutex loadMutex; + typedef std::map ComponentTable; + ComponentTable activeComponents; + + // Threaded service for performing cleanup checks + redhawk::ExecutorService executorService; + }; +} + +#endif // COMPONENTHOST_H diff --git a/redhawk/src/control/sdr/ComponentHost/ComponentHost.prf.xml b/redhawk/src/control/sdr/ComponentHost/ComponentHost.prf.xml new file mode 100644 index 000000000..0bce0fe97 --- /dev/null +++ b/redhawk/src/control/sdr/ComponentHost/ComponentHost.prf.xml @@ -0,0 +1,22 @@ + + + + diff --git a/redhawk/src/control/sdr/ComponentHost/ComponentHost.scd.xml b/redhawk/src/control/sdr/ComponentHost/ComponentHost.scd.xml new file mode 100644 index 000000000..d32fcdd38 --- /dev/null +++ b/redhawk/src/control/sdr/ComponentHost/ComponentHost.scd.xml @@ -0,0 +1,64 @@ + + + + + 2.2 + + resource + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/redhawk/src/control/sdr/ComponentHost/ComponentHost.spd.xml b/redhawk/src/control/sdr/ComponentHost/ComponentHost.spd.xml new file mode 100644 index 000000000..6c5d5f57e --- /dev/null +++ b/redhawk/src/control/sdr/ComponentHost/ComponentHost.spd.xml @@ -0,0 +1,46 @@ + + + + + + + null + + + + + + + + + Deployable container for launching multiple components in the same process + + + ComponentHost + + + + + + + + + diff --git a/redhawk/src/control/sdr/ComponentHost/Makefile.am b/redhawk/src/control/sdr/ComponentHost/Makefile.am new file mode 100644 index 000000000..91bd9a689 --- /dev/null +++ b/redhawk/src/control/sdr/ComponentHost/Makefile.am @@ -0,0 +1,33 @@ +# +# This file is protected by Copyright. Please refer to the COPYRIGHT file +# distributed with this source distribution. +# +# This file is part of REDHAWK core. +# +# REDHAWK core is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation, either version 3 of the License, or (at your option) any +# later version. +# +# REDHAWK core is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +# details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/. +# + +bindir = $(SDR_ROOT)/dom/mgr/rh/ComponentHost +bin_PROGRAMS = ComponentHost + +xmldir = $(SDR_ROOT)/dom/mgr/rh/ComponentHost +dist_xml_DATA = ComponentHost.scd.xml ComponentHost.prf.xml ComponentHost.spd.xml + +ComponentHost_SOURCES = ComponentHost.cpp ModuleLoader.cpp main.cpp + +ComponentHost_LDADD = $(top_builddir)/base/framework/libossiecf.la $(top_builddir)/base/framework/idl/libossieidl.la +ComponentHost_LDADD += $(BOOST_LDFLAGS) $(BOOST_THREAD_LIB) $(BOOST_REGEX_LIB) $(BOOST_SYSTEM_LIB) +ComponentHost_CPPFLAGS = -I$(top_srcdir)/base/include $(BOOST_CPPFLAGS) +ComponentHost_CXXFLAGS = -Wall + diff --git a/redhawk/src/control/sdr/ComponentHost/ModuleLoader.cpp b/redhawk/src/control/sdr/ComponentHost/ModuleLoader.cpp new file mode 100644 index 000000000..76b579b81 --- /dev/null +++ b/redhawk/src/control/sdr/ComponentHost/ModuleLoader.cpp @@ -0,0 +1,189 @@ +/* +* This file is protected by Copyright. Please refer to the COPYRIGHT file +* distributed with this source distribution. +* +* This file is part of REDHAWK core. +* +* REDHAWK core is free software: you can redistribute it and/or modify it +* under the terms of the GNU Lesser General Public License as published by the +* Free Software Foundation, either version 3 of the License, or (at your +* option) any later version. +* +* REDHAWK core is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License +* for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see http://www.gnu.org/licenses/. +*/ + +#include +#include +#include + +#include + +#include + +#include "ModuleLoader.h" + +using namespace redhawk; +namespace fs = boost::filesystem; + +bool Module::IsLoadable(const std::string& filename) +{ + std::ifstream file(filename.c_str()); + if (!file) { + return false; + } + char ident[EI_NIDENT]; + file.read(ident, EI_NIDENT); + if (!file) { + return false; + } + if (std::strncmp(ident, ELFMAG, SELFMAG)) { + return false; + } + return true; +} + +Module::Module(const std::string& path, void* handle) : + _path(path), + _handle(handle), + _refcount(1) +{ +} + +const std::string& Module::path() const +{ + return _path; +} + +void Module::load() +{ + ++_refcount; +} + +void Module::unload() +{ + _refcount--; + if (_refcount == 0) { + ModuleLoader::Instance().unloaded(this); + delete this; + } +} + +void Module::close() +{ + dlclose(_handle); + _handle = 0; +} + +void* Module::symbol(const std::string& name) +{ + // Clear error state; dlysm() can succeed but return null if the symbol is + // supposed to be null, so checking dlerror() is the only reliable way to + // catch failures + dlerror(); + void *symbol = dlsym(_handle, name.c_str()); + if (const char* error = dlerror()) { + throw std::runtime_error(error); + } + return symbol; +} + +PREPARE_LOGGING(ModuleLoader); + +ModuleLoader::ModuleLoader() +{ +} + +ModuleLoader& ModuleLoader::Instance() +{ + static ModuleLoader loader; + return loader; +} + +Module* ModuleLoader::Load(const std::string& path, LoadBinding binding, LoadVisibility visibility) +{ + return Instance().load(path, binding, visibility); +} + +Module* ModuleLoader::load(const std::string& path, LoadBinding binding, LoadVisibility visibility) +{ + Module* module = findModule(path); + if (!module) { + LOG_DEBUG(ModuleLoader, "Loading module " << path); + int flags = binding | visibility; + void* handle = dlopen(path.c_str(), flags); + if (!handle) { + throw std::runtime_error(dlerror()); + } + module = new Module(path, handle); + _modules[path] = module; + } else { + module->load(); + } + return module; +} + +void ModuleLoader::unloaded(Module* module) +{ + LOG_DEBUG(ModuleLoader, "Unloading module " << module->path()); + _modules.erase(module->path()); + module->close(); +} + +Module* ModuleLoader::findModule(const std::string& path) +{ + LoadTable::iterator module = _modules.find(path); + if (module != _modules.end()) { + return module->second; + } + return 0; +} + + +ModuleBundle::ModuleBundle(const std::string& name) : + _name(name) +{ +} + +ModuleBundle::~ModuleBundle() +{ + unload(); +} + +const std::string& ModuleBundle::name() const +{ + return _name; +} + +Module* ModuleBundle::load(const std::string& path, ModuleLoader::LoadBinding binding, ModuleLoader::LoadVisibility visibility) +{ + Module* module = ModuleLoader::Load(path, binding, visibility); + _modules.push_back(module); + return module; +} + +void ModuleBundle::loadDirectory(const std::string& path, ModuleLoader::LoadBinding binding, ModuleLoader::LoadVisibility visibility) +{ + for (fs::directory_iterator entry = fs::directory_iterator(path); entry != fs::directory_iterator(); ++entry) { + if (!fs::is_directory(entry->path())) { + const std::string filename = entry->path().string(); + if (Module::IsLoadable(filename)) { + load(filename, binding, visibility); + } + } + } +} + +void ModuleBundle::unload() +{ + // Unload modules in reverse order of loading + for (ModuleList::reverse_iterator module = _modules.rbegin(); module != _modules.rend(); ++module) { + (*module)->unload(); + } + _modules.clear(); +} diff --git a/redhawk/src/control/sdr/ComponentHost/ModuleLoader.h b/redhawk/src/control/sdr/ComponentHost/ModuleLoader.h new file mode 100644 index 000000000..2d8565220 --- /dev/null +++ b/redhawk/src/control/sdr/ComponentHost/ModuleLoader.h @@ -0,0 +1,110 @@ +/* +* This file is protected by Copyright. Please refer to the COPYRIGHT file +* distributed with this source distribution. +* +* This file is part of REDHAWK core. +* +* REDHAWK core is free software: you can redistribute it and/or modify it +* under the terms of the GNU Lesser General Public License as published by the +* Free Software Foundation, either version 3 of the License, or (at your +* option) any later version. +* +* REDHAWK core is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License +* for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see http://www.gnu.org/licenses/. +*/ + +#ifndef MODULELOADER_H +#define MODULELOADER_H + +#include +#include +#include + +#include + +#include + +namespace redhawk { + + class Module { + public: + const std::string& path() const; + void* symbol(const std::string& name); + void unload(); + + static bool IsLoadable(const std::string& path); + + private: + Module(const std::string& path, void* handle); + + void load(); + + void close(); + + friend class ModuleLoader; + + const std::string _path; + void* _handle; + int _refcount; + }; + + class ModuleLoader { + + ENABLE_LOGGING; + + public: + enum LoadBinding { + LAZY = RTLD_LAZY, + NOW = RTLD_NOW + }; + + enum LoadVisibility { + GLOBAL = RTLD_GLOBAL, + LOCAL = RTLD_LOCAL + }; + + static Module* Load(const std::string& path, LoadBinding binding, LoadVisibility visibility); + + private: + ModuleLoader(); + + static ModuleLoader& Instance(); + + Module* load(const std::string& path, LoadBinding binding, LoadVisibility visibility); + void unloaded(Module* module); + + Module* findModule(const std::string& path); + + friend class Module; + + typedef std::map LoadTable; + LoadTable _modules; + }; + + class ModuleBundle { + public: + ModuleBundle(const std::string& name); + + ~ModuleBundle(); + + const std::string& name() const; + + Module* load(const std::string& path, ModuleLoader::LoadBinding binding, ModuleLoader::LoadVisibility visibility); + void loadDirectory(const std::string& path, ModuleLoader::LoadBinding binding, ModuleLoader::LoadVisibility visibility); + + void unload(); + + private: + const std::string _name; + typedef std::vector ModuleList; + ModuleList _modules; + }; + +} + +#endif // MODULELOADER_H diff --git a/redhawk/src/control/sdr/ComponentHost/main.cpp b/redhawk/src/control/sdr/ComponentHost/main.cpp new file mode 100644 index 000000000..bb5e22f87 --- /dev/null +++ b/redhawk/src/control/sdr/ComponentHost/main.cpp @@ -0,0 +1,28 @@ +/* +* This file is protected by Copyright. Please refer to the COPYRIGHT file +* distributed with this source distribution. +* +* This file is part of REDHAWK core. +* +* REDHAWK core is free software: you can redistribute it and/or modify it +* under the terms of the GNU Lesser General Public License as published by the +* Free Software Foundation, either version 3 of the License, or (at your +* option) any later version. +* +* REDHAWK core is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License +* for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see http://www.gnu.org/licenses/. +*/ + +#include "ComponentHost.h" + +int main(int argc, char* argv[]) +{ + redhawk::ComponentHost* servant; + Component::start_component(servant, argc, argv); + return 0; +} diff --git a/redhawk/src/control/sdr/Makefile.am b/redhawk/src/control/sdr/Makefile.am index d2933feaa..9336733c3 100644 --- a/redhawk/src/control/sdr/Makefile.am +++ b/redhawk/src/control/sdr/Makefile.am @@ -31,7 +31,7 @@ nodesdir = $(devdir)/nodes dist_domain_DATA = domain/DomainManager.dmd.xml \ domain/DomainManager.dmd.xml.template -SUBDIRS = dommgr devmgr +SUBDIRS = dommgr devmgr ComponentHost install-exec-hook: $(mkdir_p) $(DESTDIR)$(depsdir) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp b/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp index 337aa576e..7083c5aa2 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp @@ -127,7 +127,7 @@ ContainerDeployment* ApplicationDeployment::createContainer(redhawk::ProfileCach return container; } - const ossie::SoftPkg* softpkg = cache.loadSoftPkg("/components/rh/AppContainer/AppContainer.spd.xml"); + const ossie::SoftPkg* softpkg = cache.loadSoftPkg("/mgr/rh/ComponentHost/ComponentHost.spd.xml"); // Create an instantiation with the ID and naming service name based on the // device identifier; the deployment will own this object From 688ca792bb9907924bd112a623eee843409ce6ab Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 20 Jun 2016 15:02:30 -0400 Subject: [PATCH 0399/1644] Ignore ComponentHost executable --- redhawk/src/control/sdr/ComponentHost/.gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 redhawk/src/control/sdr/ComponentHost/.gitignore diff --git a/redhawk/src/control/sdr/ComponentHost/.gitignore b/redhawk/src/control/sdr/ComponentHost/.gitignore new file mode 100644 index 000000000..30be27505 --- /dev/null +++ b/redhawk/src/control/sdr/ComponentHost/.gitignore @@ -0,0 +1 @@ +ComponentHost From 260d97d3774e95a931d8e0f77b5db12463661142 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 21 Jun 2016 10:08:02 -0400 Subject: [PATCH 0400/1644] Partially refactor local Sandbox launcher to create a "virtual device" that is responsible for the execution of the entry point, gradually moving the higher-level softpkg management to the LocalLauncher --- .../python/ossie/utils/sandbox/launcher.py | 211 ++++++------------ .../python/ossie/utils/sandbox/local.py | 17 +- 2 files changed, 82 insertions(+), 146 deletions(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/launcher.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/launcher.py index d3249dbd3..4d807b871 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/launcher.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/launcher.py @@ -26,12 +26,13 @@ import threading import tempfile import subprocess +import platform from ossie.utils import log4py from ossie import parsers from ossie.utils.popen import Popen -__all__ = ('LocalProcess', 'launchSoftpkg') +__all__ = ('LocalProcess', 'VirtualDevice') log = logging.getLogger(__name__) @@ -112,53 +113,65 @@ def addChild(self, process): self.__children.append(process) -class LocalLauncher(object): - def __init__(self, profile, sandbox): +class VirtualDevice(object): + def __init__(self, sandbox): self._sandbox = sandbox - self._profile = profile - self._xmlpath = os.path.dirname(self._profile) + self._processor = platform.machine() + self._osName = platform.system() - def _selectImplementation(self, spd): - for implementation in spd.get_implementation(): - entry_point = self._getEntryPoint(implementation) - if os.path.exists(entry_point): - return implementation - raise RuntimeError, "Softpkg '%s' has no usable entry point" % spd.get_name() + def getEntryPoint(self, spd, implementation): + entry_point = implementation.get_code().get_entrypoint() + if not entry_point.startswith('/'): + entry_point = os.path.join(os.path.dirname(spd), entry_point) + return entry_point - def _getImplementation(self, spd, identifier): + def getImplementation(self, spd, identifier): for implementation in spd.get_implementation(): if implementation.get_id() == identifier: return implementation raise KeyError, "Softpkg '%s' has no implementation '%s'" % (spd.get_name(), identifier) - def _getEntryPoint(self, implementation): - entry_point = implementation.get_code().get_entrypoint() - if not entry_point.startswith('/'): - entry_point = os.path.join(self._xmlpath, entry_point) - return entry_point + def _matchProcessor(self, implementation): + for proc in implementation.get_processor(): + if proc.get_name() == self._processor: + return True + return False - def execute(self, spd, impl, execparams, debugger, window): - # Find a suitable implementation. - if impl: - implementation = self._getImplementation(spd, impl) - else: - implementation = self._selectImplementation(spd) - log.trace("Using implementation '%s'", implementation.get_id()) + def _matchOS(self, implementation): + for operating_system in implementation.get_os(): + if operating_system.get_name() == self._osName: + return True + return False + def matchImplementation(self, profile, spd): + for impl in spd.get_implementation(): + if self._matchProcessor(impl) and self._matchOS(impl): + entry_point = self.getEntryPoint(profile, impl) + if os.path.exists(entry_point): + return impl + raise RuntimeError, "Softpkg '%s' has no usable implementation" % spd.get_name() + + def execute(self, entryPoint, deps, execparams, debugger, window): # Make sure the entry point can be run. - entry_point = self._getEntryPoint(implementation) - if not os.access(entry_point, os.X_OK|os.R_OK): - raise RuntimeError, "Entry point '%s' is not executable" % entry_point - log.trace("Using entry point '%s'", entry_point) + if not os.access(entryPoint, os.X_OK|os.R_OK): + raise RuntimeError, "Entry point '%s' is not executable" % entryPoint + log.trace("Using entry point '%s'", entryPoint) # Process softpkg dependencies and modify the child environment. environment = dict(os.environ.items()) - for dependency in implementation.get_dependency(): - for varname, pathname in self._resolveDependency(implementation, dependency): - self._extendEnvironment(environment, varname, pathname) + for dependency in deps: + if self._isSharedLibrary(dependency): + self._extendEnvironment(environment, "LD_LIBRARY_PATH", os.path.dirname(dependency)) + elif self._isPythonLibrary(dependency): + self._extendEnvironment(environment, "PYTHONPATH", os.path.dirname(dependency)) + elif self._isJarfile(dependency): + self._extendEnvironment(environment, "CLASSPATH", dependency) + else: + self._extendEnvironment(environment, "LD_LIBRARY_PATH", dependency) + self._extendEnvironment(environment, "OCTAVE_PATH", dependency) for varname in ('LD_LIBRARY_PATH', 'PYTHONPATH', 'CLASSPATH'): - log.trace('%s=%s', varname, environment.get(varname, '')) + log.trace('%s=%s', varname, environment.get(varname, '').split(':')) # Convert execparams into arguments. arguments = [] @@ -172,12 +185,12 @@ def execute(self, spd, impl, execparams, debugger, window): if debugger and debugger.modifiesCommand(): # Run the command in the debugger. - command, arguments = debugger.wrap(entry_point, arguments) + command, arguments = debugger.wrap(entryPoint, arguments) if debugger.isInteractive() and not debugger.canAttach(): window_mode = 'direct' else: # Run the command directly. - command = entry_point + command = entryPoint stdout = None if window_mode == 'monitor': @@ -199,116 +212,30 @@ def execute(self, spd, impl, execparams, debugger, window): return process - # this function checks that the base dependencies match an impl exactly - def _equalDeps(self, base, impl): - if len(base[0]) != len(impl[0]): - return False - if len(base[1]) != len(impl[1]): - return False - for val in base[0]: - if not val in impl[0]: - return False - for val in base[1]: - if not val in impl[1]: - return False - return True - - # this function checks if the base has a dependency not supported by impl for non-zero impls - def _subsetDeps(self, base, impl): - foundMatch = True - if len(impl[0]) != 0: - foundMatch = False - for val in base[0]: - if val in impl[0]: - foundMatch = True - if not foundMatch: - return False - if len(impl[1]) != 0: - foundMatch = False - for val in base[1]: - if val in impl[1]: - foundMatch = True - if not foundMatch: - return False - return True - - def _assembleOsProc(self, depimpl): - impl_os = [] - impl_proc = [] - for operating_system in depimpl.get_os(): - impl_os.append(operating_system.get_name()) - for proc in depimpl.get_processor(): - impl_proc.append(proc.get_name()) - return impl_os, impl_proc - - - def _findExactMatch(self, dep_spd, dep_base): - impl = None - for depimpl in dep_spd.get_implementation(): - impl_os, impl_proc = self._assembleOsProc(depimpl) - if self._equalDeps(dep_base,(impl_os,impl_proc)): - impl = depimpl - break - return impl - - def _findGenericMatch(self, dep_spd, dep_base): - impl = None - for depimpl in dep_spd.get_implementation(): - impl_os, impl_proc = self._assembleOsProc(depimpl) - if self._subsetDeps(dep_base,(impl_os,impl_proc)): - impl = depimpl - break - return impl - - def _resolveDependency(self, implementation, dependency): - softpkg = dependency.get_softpkgref() - if not softpkg: - return [] - filename = softpkg.get_localfile().get_name() - log.trace("Resolving softpkg dependency '%s'", filename) - local_filename = self._sandbox.getSdrRoot()._sdrPath('dom' + filename) - dep_spd = parsers.spd.parse(local_filename) - dep_impl = softpkg.get_implref() - if dep_impl: - impl = self._getImplementation(dep_spd, dep_impl.get_refid()) - else: # no implementation requested. Search for a matching implementation - try: - dep_base_os = [] - dep_base_proc = [] - for operating_system in implementation.get_os(): - dep_base_os.append(operating_system.get_name()) - for proc in implementation.get_processor(): - dep_base_proc.append(proc.get_name()) - impl = self._findExactMatch(dep_spd, (dep_base_os, dep_base_proc)) - if impl == None: - impl = self._findGenericMatch(dep_spd, (dep_base_os, dep_base_proc)) - except: - raise RuntimeError, "Softpkg '%s' has no implementation" % dep_spd.get_name() - envvars = [] - if impl != None: + def resolveDependencies(self, implementation): + dep_files = [] + for dependency in implementation.get_dependency(): + softpkg = dependency.get_softpkgref() + if not softpkg: + continue + filename = softpkg.get_localfile().get_name() + log.trace("Resolving softpkg dependency '%s'", filename) + local_filename = self._sandbox.getSdrRoot()._sdrPath('dom' + filename) + dep_spd = parsers.spd.parse(local_filename) + dep_impl = softpkg.get_implref() + if dep_impl: + impl = self.getImplementation(dep_spd, dep_impl.get_refid()) + else: # no implementation requested. Search for a matching implementation + impl = self.matchImplementation(filename, dep_spd) + log.trace("Using implementation '%s'", impl.get_id()) dep_localfile = impl.get_code().get_localfile().name + dep_files.append(os.path.join(os.path.dirname(local_filename), dep_localfile)) # Resolve nested dependencies. - for dep in impl.dependency: - envvars.extend(self._resolveDependency(implementation, dep)) - - localfile = os.path.join(os.path.dirname(local_filename), dep_localfile) - envvars.insert(0, self._getDependencyConfiguration(localfile)) - if not self._isSharedLibrary(localfile) and not self._isPythonLibrary(localfile) and not self._isJarfile(localfile): - envvars.insert(0, ('OCTAVE_PATH', localfile)) - return envvars - - def _getDependencyConfiguration(self, localfile): - if self._isSharedLibrary(localfile): - return ('LD_LIBRARY_PATH', os.path.dirname(localfile)) - elif self._isPythonLibrary(localfile): - return ('PYTHONPATH', os.path.dirname(localfile)) - elif self._isJarfile(localfile): - return ('CLASSPATH', localfile) - else: - # Assume it's a set of shared libraries. - return ('LD_LIBRARY_PATH', localfile) + dep_files.extend(self.resolveDependencies(impl)) + + return dep_files def _isSharedLibrary(self, filename): status, output = commands.getstatusoutput('nm ' + filename) @@ -339,7 +266,3 @@ def _extendEnvironment(self, env, keyname, value): return oldvalue.insert(0,value) env[keyname] = ':'.join(oldvalue) - -def launchSoftpkg(profile, sandbox, spd, impl, execparams, debugger, window): - launcher = LocalLauncher(profile, sandbox) - return launcher.execute(spd, impl, execparams, debugger, window) diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py index 1dfe9e5e2..6adb7b40a 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py @@ -157,8 +157,21 @@ def launch(self, comp): log.warning('Cannot run terminal %s (%s)', window, e) debugger = None - process = launcher.launchSoftpkg(comp._profile, comp._sandbox, comp._spd, - comp._impl, execparams, debugger, window) + # Find a suitable implementation + device = launcher.VirtualDevice(comp._sandbox) + if comp._impl: + impl = device.getImplementation(comp._spd, comp._impl) + else: + impl = device.matchImplementation(comp._profile, comp._spd) + log.trace("Using implementation '%s'", impl.get_id()) + + entry_point = device.getEntryPoint(comp._profile, impl) + deps = device.resolveDependencies(impl) + + if impl.get_code().get_type() == 'SharedLibrary': + raise RuntimeError, 'SharedLibrary entry point not implemented' + + process = device.execute(entry_point, deps, execparams, debugger, window) # Set up a callback to notify when the component exits abnormally. name = comp._instanceName From 52db04487d25018fdd5c29116e53354b4323ee80 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 21 Jun 2016 10:29:58 -0400 Subject: [PATCH 0401/1644] Move dependency resolution to LocalLauncher; VirtualDevice no longer needs a reference to the Sandbox --- .../python/ossie/utils/sandbox/launcher.py | 59 +++++-------------- .../python/ossie/utils/sandbox/local.py | 41 ++++++++++++- 2 files changed, 54 insertions(+), 46 deletions(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/launcher.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/launcher.py index 4d807b871..328b2ea3b 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/launcher.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/launcher.py @@ -114,8 +114,7 @@ def addChild(self, process): class VirtualDevice(object): - def __init__(self, sandbox): - self._sandbox = sandbox + def __init__(self): self._processor = platform.machine() self._osName = platform.system() @@ -125,12 +124,6 @@ def getEntryPoint(self, spd, implementation): entry_point = os.path.join(os.path.dirname(spd), entry_point) return entry_point - def getImplementation(self, spd, identifier): - for implementation in spd.get_implementation(): - if implementation.get_id() == identifier: - return implementation - raise KeyError, "Softpkg '%s' has no implementation '%s'" % (spd.get_name(), identifier) - def _matchProcessor(self, implementation): for proc in implementation.get_processor(): if proc.get_name() == self._processor: @@ -152,23 +145,17 @@ def matchImplementation(self, profile, spd): raise RuntimeError, "Softpkg '%s' has no usable implementation" % spd.get_name() def execute(self, entryPoint, deps, execparams, debugger, window): - # Make sure the entry point can be run. - if not os.access(entryPoint, os.X_OK|os.R_OK): + # Make sure the entry point exists and can be run. + if not os.path.exists(entryPoint): + raise RuntimeError, "Entry point '%s' does not exist" % entryPoint + elif not os.access(entryPoint, os.X_OK|os.R_OK): raise RuntimeError, "Entry point '%s' is not executable" % entryPoint log.trace("Using entry point '%s'", entryPoint) # Process softpkg dependencies and modify the child environment. environment = dict(os.environ.items()) for dependency in deps: - if self._isSharedLibrary(dependency): - self._extendEnvironment(environment, "LD_LIBRARY_PATH", os.path.dirname(dependency)) - elif self._isPythonLibrary(dependency): - self._extendEnvironment(environment, "PYTHONPATH", os.path.dirname(dependency)) - elif self._isJarfile(dependency): - self._extendEnvironment(environment, "CLASSPATH", dependency) - else: - self._extendEnvironment(environment, "LD_LIBRARY_PATH", dependency) - self._extendEnvironment(environment, "OCTAVE_PATH", dependency) + self._processDependency(environment, dependency) for varname in ('LD_LIBRARY_PATH', 'PYTHONPATH', 'CLASSPATH'): log.trace('%s=%s', varname, environment.get(varname, '').split(':')) @@ -212,30 +199,16 @@ def execute(self, entryPoint, deps, execparams, debugger, window): return process - def resolveDependencies(self, implementation): - dep_files = [] - for dependency in implementation.get_dependency(): - softpkg = dependency.get_softpkgref() - if not softpkg: - continue - filename = softpkg.get_localfile().get_name() - log.trace("Resolving softpkg dependency '%s'", filename) - local_filename = self._sandbox.getSdrRoot()._sdrPath('dom' + filename) - dep_spd = parsers.spd.parse(local_filename) - dep_impl = softpkg.get_implref() - if dep_impl: - impl = self.getImplementation(dep_spd, dep_impl.get_refid()) - else: # no implementation requested. Search for a matching implementation - impl = self.matchImplementation(filename, dep_spd) - - log.trace("Using implementation '%s'", impl.get_id()) - dep_localfile = impl.get_code().get_localfile().name - dep_files.append(os.path.join(os.path.dirname(local_filename), dep_localfile)) - - # Resolve nested dependencies. - dep_files.extend(self.resolveDependencies(impl)) - - return dep_files + def _processDependency(self, environment, filename): + if self._isSharedLibrary(filename): + self._extendEnvironment(environment, "LD_LIBRARY_PATH", os.path.dirname(filename)) + elif self._isPythonLibrary(filename): + self._extendEnvironment(environment, "PYTHONPATH", os.path.dirname(filename)) + elif self._isJarfile(filename): + self._extendEnvironment(environment, "CLASSPATH", filename) + else: + self._extendEnvironment(environment, "LD_LIBRARY_PATH", filename) + self._extendEnvironment(environment, "OCTAVE_PATH", filename) def _isSharedLibrary(self, filename): status, output = commands.getstatusoutput('nm ' + filename) diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py index 6adb7b40a..1a47b80f0 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py @@ -56,6 +56,9 @@ def _sdrPath(self, filename): # Assume the filename points to somewhere in SDRROOT return os.path.join(self.__sdrroot, filename) + def domPath(self, filename): + return os.path.join(self.__sdrroot, 'dom' + filename) + def _fileExists(self, filename): return os.path.isfile(filename) @@ -114,6 +117,38 @@ def __init__(self, execparams, initProps, initialize, configProps, debugger, win self._configProps = configProps self._timeout = timeout + def _getImplementation(self, spd, identifier): + for implementation in spd.get_implementation(): + if implementation.get_id() == identifier: + return implementation + raise KeyError, "Softpkg '%s' has no implementation '%s'" % (spd.get_name(), identifier) + + def _resolveDependencies(self, sdrRoot, device, implementation): + dep_files = [] + for dependency in implementation.get_dependency(): + softpkg = dependency.get_softpkgref() + if not softpkg: + continue + filename = softpkg.get_localfile().get_name() + log.trace("Resolving softpkg dependency '%s'", filename) + local_filename = sdrRoot.domPath(filename) + dep_spd = parsers.spd.parse(local_filename) + dep_impl = softpkg.get_implref() + if dep_impl: + impl = self._getImplementation(dep_spd, dep_impl.get_refid()) + else: + # No implementation requested, find one that matches the device + impl = device.matchImplementation(filename, dep_spd) + + log.trace("Using implementation '%s'", impl.get_id()) + dep_localfile = impl.get_code().get_localfile().get_name() + dep_files.append(os.path.join(os.path.dirname(local_filename), dep_localfile)) + + # Resolve nested dependencies. + dep_files.extend(self._resolveDependencies(sdrRoot, device, impl)) + + return dep_files + def launch(self, comp): # Build up the full set of command line arguments execparams = comp._getExecparams() @@ -158,15 +193,15 @@ def launch(self, comp): debugger = None # Find a suitable implementation - device = launcher.VirtualDevice(comp._sandbox) + device = launcher.VirtualDevice() if comp._impl: - impl = device.getImplementation(comp._spd, comp._impl) + impl = self._getImplementation(comp._spd, comp._impl) else: impl = device.matchImplementation(comp._profile, comp._spd) log.trace("Using implementation '%s'", impl.get_id()) entry_point = device.getEntryPoint(comp._profile, impl) - deps = device.resolveDependencies(impl) + deps = self._resolveDependencies(comp._sandbox.getSdrRoot(), device, impl) if impl.get_code().get_type() == 'SharedLibrary': raise RuntimeError, 'SharedLibrary entry point not implemented' From 6c0d9f44f56d1a6b668985d403b4c46e7aa73180 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 21 Jun 2016 13:57:26 -0400 Subject: [PATCH 0402/1644] Implement shared library component launching in Sandbox --- .../python/ossie/utils/sandbox/local.py | 45 +++++++++++++------ 1 file changed, 31 insertions(+), 14 deletions(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py index 1a47b80f0..daf5dcd9d 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py @@ -27,8 +27,10 @@ import warnings from omniORB import CORBA +from omniORB.any import to_any from ossie import parsers +from ossie.cf import CF from ossie.utils.model.connect import ConnectionManager from base import SdrRoot, Sandbox, SandboxLauncher @@ -200,22 +202,28 @@ def launch(self, comp): impl = device.matchImplementation(comp._profile, comp._spd) log.trace("Using implementation '%s'", impl.get_id()) - entry_point = device.getEntryPoint(comp._profile, impl) + # Resolve all dependency localfiles deps = self._resolveDependencies(comp._sandbox.getSdrRoot(), device, impl) + # Execute the entry point, either on the virtual device or the Sandbox + # component host + entry_point = device.getEntryPoint(comp._profile, impl) if impl.get_code().get_type() == 'SharedLibrary': - raise RuntimeError, 'SharedLibrary entry point not implemented' - - process = device.execute(entry_point, deps, execparams, debugger, window) + container = comp._sandbox._getComponentHost() + parameters = [CF.DataType(k, to_any(str(v))) for k, v in execparams.iteritems()] + container.ref.executeLinked(entry_point, [], parameters, deps) + process = container._process + else: + process = device.execute(entry_point, deps, execparams, debugger, window) - # Set up a callback to notify when the component exits abnormally. - name = comp._instanceName - def terminate_callback(pid, status): - if status > 0: - print 'Component %s (pid=%d) exited with status %d' % (name, pid, status) - elif status < 0: - print 'Component %s (pid=%d) terminated with signal %d' % (name, pid, -status) - process.setTerminationCallback(terminate_callback) + # Set up a callback to notify when the component exits abnormally. + name = comp._instanceName + def terminate_callback(pid, status): + if status > 0: + print 'Component %s (pid=%d) exited with status %d' % (name, pid, status) + elif status < 0: + print 'Component %s (pid=%d) terminated with signal %d' % (name, pid, -status) + process.setTerminationCallback(terminate_callback) # Wait for the component to register with the virtual naming service or # DeviceManager. @@ -248,8 +256,10 @@ def terminate_callback(pid, status): process.addChild(debug_process) # Store the process on the component proxy. - comp._process = process - comp._pid = process.pid() + if impl.get_code().get_type() == 'SharedLibrary': + comp._process = None + else: + comp._process = process # Return the now-resolved CORBA reference. ref = self.getReference(comp) @@ -378,6 +388,13 @@ def __init__(self, sdrroot): self.__components = {} self.__services = {} self._sdrroot = LocalSdrRoot(sdrroot) + self.__container = None + + def _getComponentHost(self): + if self.__container is None: + spd_file = self._sdrroot.domPath('/mgr/rh/ComponentHost/ComponentHost.spd.xml') + self.__container = self.launch(spd_file) + return self.__container def _getComponentContainer(self, componentType): if componentType == 'service': From 1200403be33dee8a7819c95e3b8fb4a6466b1ee3 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 21 Jun 2016 14:26:08 -0400 Subject: [PATCH 0403/1644] Update the Sandbox to use a virtual ApplicationRegistrar instead of just a NamingContext --- .../python/ossie/utils/sandbox/local.py | 16 +++--- .../python/ossie/utils/sandbox/naming.py | 49 +++++++++++++------ 2 files changed, 42 insertions(+), 23 deletions(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py index daf5dcd9d..9ac1235d0 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py @@ -35,7 +35,7 @@ from base import SdrRoot, Sandbox, SandboxLauncher from devmgr import DeviceManagerStub -from naming import NamingContextStub +from naming import ApplicationRegistrarStub import launcher from debugger import GDB, PDB, Valgrind import terminal @@ -319,22 +319,22 @@ def terminate(self, comp): class LocalComponentLauncher(LocalLauncher): def launch(self, *args, **kwargs): - self.__namingContext = NamingContextStub() - log.trace('Activating virtual NamingContext') - namingContextId = poa.activate_object(self.__namingContext) + self.__registrar = ApplicationRegistrarStub() + log.trace('Activating virtual ApplicationRegistrar') + namingContextId = poa.activate_object(self.__registrar) try: return LocalLauncher.launch(self, *args, **kwargs) finally: - log.trace('Deactivating virtual NamingContext') + log.trace('Deactivating virtual ApplicationRegistrar') poa.deactivate_object(namingContextId) - del self.__namingContext + del self.__registrar def getReference(self, component): - return self.__namingContext.getObject(component._instanceName) + return self.__registrar.getObject(component._instanceName) def _getRequiredExecparams(self, component): return {'COMPONENT_IDENTIFIER': component._refid, - 'NAMING_CONTEXT_IOR': orb.object_to_string(self.__namingContext._this()), + 'NAMING_CONTEXT_IOR': orb.object_to_string(self.__registrar._this()), 'PROFILE_NAME': component._profile, 'NAME_BINDING': component._instanceName} diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/naming.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/naming.py index 87795140f..a321850ca 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/naming.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/naming.py @@ -18,13 +18,13 @@ # along with this program. If not, see http://www.gnu.org/licenses/. # -import logging import threading +from omniORB import CORBA, URI import CosNaming, CosNaming__POA -from omniORB import CORBA, URI -from ossie.utils import log4py +from ossie.cf import CF, CF__POA +from ossie.utils.log4py import logging log = logging.getLogger(__name__) @@ -41,35 +41,35 @@ class NamingContextStub(CosNaming__POA.NamingContextExt): """ def __init__(self): - self.__context = {} - self.__lock = threading.RLock() + self._context = {} + self._lock = threading.RLock() def bind(self, name, object): uri = URI.nameToString(name) - self.__lock.acquire() + self._lock.acquire() try: - if uri in self.__context: + if uri in self._context: raise CosNaming.NamingContext.AlreadyBound() log.debug('Binding "%s" into virtual NamingContext', uri) - self.__context[uri] = object + self._context[uri] = object finally: - self.__lock.release() + self._lock.release() def rebind(self, name, object): uri = URI.nameToString(name) log.debug('Rebinding "%s" into virtual NamingContext', uri) - self.__lock.acquire() + self._lock.acquire() try: - self.__context[uri] = object + self._context[uri] = object finally: - self.__lock.release() + self._lock.release() def getObject(self, name): - self.__lock.acquire() + self._lock.acquire() try: - return self.__context.get(name, None) + return self._context.get(name, None) finally: - self.__lock.release() + self._lock.release() def to_name(self, name): """ @@ -127,3 +127,22 @@ def to_name(self, name): raise ValueError("NamingContextStub:to_name() '%s' is an invalid name" % name) return [] + + +class ApplicationRegistrarStub(CF__POA.ApplicationRegistrar, NamingContextStub): + """ + Class to extend virtual NamingContext to support ApplicationRegistrar + operations. + """ + def _get_app(self): + return None + + def _get_domMgr(self): + return None + + def registerComponent(self, name, obj): + with self._lock: + if name in self._context: + raise CF.DuplicateName() + log.debug('Registering component "%s" into virtual ApplicationRegistrar', name) + self._context[name] = obj From 0e5b785590ab01a4289fbc1b921f688632d8ca7e Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 21 Jun 2016 14:41:39 -0400 Subject: [PATCH 0404/1644] Directly check whether a dependency is an ELF file in Sandbox instead of using an external command; slight refactor of Python module checking --- .../python/ossie/utils/sandbox/launcher.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/launcher.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/launcher.py index 328b2ea3b..d3ddb216b 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/launcher.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/launcher.py @@ -22,7 +22,6 @@ import logging import signal import time -import commands import threading import tempfile import subprocess @@ -211,21 +210,25 @@ def _processDependency(self, environment, filename): self._extendEnvironment(environment, "OCTAVE_PATH", filename) def _isSharedLibrary(self, filename): - status, output = commands.getstatusoutput('nm ' + filename) - return status == 0 + try: + with open(filename, 'rb') as f: + return f.read(4) == '\x7fELF' + except: + return False def _isJarfile(self, filename): return filename.endswith('.jar') def _isPythonLibrary(self, filename): - if os.path.splitext(filename)[1] in ('.py', '.pyc', '.pyo'): + PYTHON_EXTS = ('.py', '.pyc', '.pyo') + if os.path.splitext(filename)[1] in PYTHON_EXTS: # File is a Python module return True elif os.path.isdir(filename): # Check for Python package - initpath = os.path.join(filename, '__init__.py') - for initfile in (initpath, initpath+'c', initpath+'o'): - if os.path.exists(initfile): + initpath = os.path.join(filename, '__init__') + for ext in PYTHON_EXTS: + if os.path.exists(initpath + ext): return True return False From f2afdc7128f3a0a7cda721ad7c42b3dc709cc6d1 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 21 Jun 2016 16:02:27 -0400 Subject: [PATCH 0405/1644] Fix Sandbox VirtualDevice implementation matching to check the localfile first, and only check the entry point if one is set --- .../python/ossie/utils/sandbox/launcher.py | 43 ++++++++++++++----- .../python/ossie/utils/sandbox/local.py | 17 +++++--- 2 files changed, 44 insertions(+), 16 deletions(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/launcher.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/launcher.py index d3ddb216b..5a86f5a83 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/launcher.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/launcher.py @@ -117,30 +117,51 @@ def __init__(self): self._processor = platform.machine() self._osName = platform.system() - def getEntryPoint(self, spd, implementation): - entry_point = implementation.get_code().get_entrypoint() - if not entry_point.startswith('/'): - entry_point = os.path.join(os.path.dirname(spd), entry_point) - return entry_point - def _matchProcessor(self, implementation): + if not implementation.get_processor(): + # Implementation specifies no processor dependency + return True + for proc in implementation.get_processor(): if proc.get_name() == self._processor: return True return False def _matchOS(self, implementation): + if not implementation.get_os(): + # Implementation specifies no OS dependency + return True + for operating_system in implementation.get_os(): if operating_system.get_name() == self._osName: return True return False - def matchImplementation(self, profile, spd): + def _checkImplementation(self, sdrroot, profile, impl): + # Match device properties + log.debug("Checking processor and OS") + if not self._matchProcessor(impl) or not self._matchOS(impl): + return False + + # Check that localfile points to a real location + localfile = sdrroot.relativePath(profile, impl.get_code().get_localfile().get_name()) + log.debug("Checking localfile '%s' ('%s')", localfile, impl.get_code().get_localfile().get_name()) + if not os.path.exists(localfile): + return False + + # If the implementation has an entry point, make sure it exists too + if impl.get_code().get_entrypoint(): + entry_point = sdrroot.relativePath(profile, impl.get_code().get_entrypoint()) + log.debug("Checking entrypoint '%s'", entry_point) + if not os.path.exists(entry_point): + return False + + return True + + def matchImplementation(self, sdrroot, profile, spd): for impl in spd.get_implementation(): - if self._matchProcessor(impl) and self._matchOS(impl): - entry_point = self.getEntryPoint(profile, impl) - if os.path.exists(entry_point): - return impl + if self._checkImplementation(sdrroot, profile, impl): + return impl raise RuntimeError, "Softpkg '%s' has no usable implementation" % spd.get_name() def execute(self, entryPoint, deps, execparams, debugger, window): diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py index 9ac1235d0..6e64cdcb0 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py @@ -61,6 +61,12 @@ def _sdrPath(self, filename): def domPath(self, filename): return os.path.join(self.__sdrroot, 'dom' + filename) + def relativePath(self, base, path): + if path.startswith('/'): + return self.domPath(path) + else: + return os.path.join(os.path.dirname(base), path) + def _fileExists(self, filename): return os.path.isfile(filename) @@ -140,11 +146,11 @@ def _resolveDependencies(self, sdrRoot, device, implementation): impl = self._getImplementation(dep_spd, dep_impl.get_refid()) else: # No implementation requested, find one that matches the device - impl = device.matchImplementation(filename, dep_spd) + impl = device.matchImplementation(sdrRoot, local_filename, dep_spd) log.trace("Using implementation '%s'", impl.get_id()) dep_localfile = impl.get_code().get_localfile().get_name() - dep_files.append(os.path.join(os.path.dirname(local_filename), dep_localfile)) + dep_files.append(sdrRoot.relativePath(local_filename, dep_localfile)) # Resolve nested dependencies. dep_files.extend(self._resolveDependencies(sdrRoot, device, impl)) @@ -196,18 +202,19 @@ def launch(self, comp): # Find a suitable implementation device = launcher.VirtualDevice() + sdrroot = comp._sandbox.getSdrRoot() if comp._impl: impl = self._getImplementation(comp._spd, comp._impl) else: - impl = device.matchImplementation(comp._profile, comp._spd) + impl = device.matchImplementation(sdrroot, comp._profile, comp._spd) log.trace("Using implementation '%s'", impl.get_id()) # Resolve all dependency localfiles - deps = self._resolveDependencies(comp._sandbox.getSdrRoot(), device, impl) + deps = self._resolveDependencies(sdrroot, device, impl) # Execute the entry point, either on the virtual device or the Sandbox # component host - entry_point = device.getEntryPoint(comp._profile, impl) + entry_point = sdrroot.relativePath(comp._profile, impl.get_code().get_entrypoint()) if impl.get_code().get_type() == 'SharedLibrary': container = comp._sandbox._getComponentHost() parameters = [CF.DataType(k, to_any(str(v))) for k, v in execparams.iteritems()] From 1b90f3342dc1b18d49c1accc74853739c3d024f0 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 22 Jun 2016 08:31:47 -0400 Subject: [PATCH 0406/1644] Remap 'i686' to 'x86' in Sandbox VirtualDevice for consistency with rest of REDHAWK --- .../base/framework/python/ossie/utils/sandbox/launcher.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/launcher.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/launcher.py index 5a86f5a83..7a3742b81 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/launcher.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/launcher.py @@ -115,8 +115,13 @@ def addChild(self, process): class VirtualDevice(object): def __init__(self): self._processor = platform.machine() + if self._processor == 'i686': + # Map from Linux standard machine name to REDHAWK + self._processor = 'x86' self._osName = platform.system() + log.debug("VirtualDevice processor '%s' OS '%s'", self._processor, self._osName) + def _matchProcessor(self, implementation): if not implementation.get_processor(): # Implementation specifies no processor dependency From 951693af5cdf0d82698eb92966506025e10a6500 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 22 Jun 2016 09:52:29 -0400 Subject: [PATCH 0407/1644] Use a specialized subclass of SandboxComponent to manage the component host --- .../python/ossie/utils/sandbox/local.py | 50 ++++++++++++++++--- .../python/ossie/utils/sandbox/model.py | 7 ++- 2 files changed, 50 insertions(+), 7 deletions(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py index 6e64cdcb0..7be8458af 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py @@ -32,8 +32,9 @@ from ossie import parsers from ossie.cf import CF from ossie.utils.model.connect import ConnectionManager +from ossie.utils.uuid import uuid4 -from base import SdrRoot, Sandbox, SandboxLauncher +from base import SdrRoot, Sandbox, SandboxLauncher, SandboxComponent from devmgr import DeviceManagerStub from naming import ApplicationRegistrarStub import launcher @@ -217,8 +218,7 @@ def launch(self, comp): entry_point = sdrroot.relativePath(comp._profile, impl.get_code().get_entrypoint()) if impl.get_code().get_type() == 'SharedLibrary': container = comp._sandbox._getComponentHost() - parameters = [CF.DataType(k, to_any(str(v))) for k, v in execparams.iteritems()] - container.ref.executeLinked(entry_point, [], parameters, deps) + container.executeLinked(entry_point, [], execparams, deps) process = container._process else: process = device.execute(entry_point, deps, execparams, debugger, window) @@ -389,6 +389,21 @@ def _getType(self): return 'service' +class ComponentHost(SandboxComponent): + def __init__(self, *args, **kwargs): + SandboxComponent.__init__(self, *args, **kwargs) + + def _register(self): + pass + + def _unregister(self): + pass + + def executeLinked(self, entryPoint, options, parameters, deps): + params = [CF.DataType(k, to_any(str(v))) for k, v in parameters.iteritems()] + self.ref.executeLinked(entryPoint, options, params, deps) + + class LocalSandbox(Sandbox): def __init__(self, sdrroot): super(LocalSandbox, self).__init__() @@ -399,10 +414,19 @@ def __init__(self, sdrroot): def _getComponentHost(self): if self.__container is None: - spd_file = self._sdrroot.domPath('/mgr/rh/ComponentHost/ComponentHost.spd.xml') - self.__container = self.launch(spd_file) + self.__container = self._launchComponentHost() return self.__container + def _launchComponentHost(self): + profile = self._sdrroot.domPath('/mgr/rh/ComponentHost/ComponentHost.spd.xml') + spd, scd, prf = self._sdrroot.readProfile(profile) + instanceName = self._createInstanceName('ComponentHost', 'resource') + refid = str(uuid4()) + comp = ComponentHost(self, profile, spd, scd, prf, instanceName, refid, None) + comp._launcher = LocalComponentLauncher({}, {}, True, {}, None, None, None) + comp._kick() + return comp + def _getComponentContainer(self, componentType): if componentType == 'service': return self.__services @@ -492,20 +516,34 @@ def setSdrRoot(self, path): def shutdown(self): ConnectionManager.instance().cleanup() self.stop() + + # Clean up all components for name, component in self.__components.items(): log.debug("Releasing component '%s'", name) try: component.releaseObject() except: log.debug("Component '%s' raised an exception while exiting", name) + self.__components = {} + + # Terminate all services for name, service in self.__services.items(): log.debug("Terminating service '%s'", name) try: service._terminate() except: log.debug("Service '%s' raised an exception while terminating", name) - self.__components = {} self.__services = {} + + # Clean up the component host + if self.__container: + log.debug('Releasing component host') + try: + self.__container.releaseObject() + except: + log.debug('Component host raised an exception while terminating') + self.__container = None + super(LocalSandbox,self).shutdown() def browse(self, searchPath=None, objType=None,withDescription=False): diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/model.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/model.py index 6346b0208..bfc2bdafe 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/model.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/model.py @@ -87,6 +87,9 @@ def _readProfile(self): def _register(self): self._sandbox._registerComponent(self) + def _unregister(self): + self._sandbox._unregisterComponent(self) + @property def _ports(self): #DEPRECATED: replaced with ports @@ -112,7 +115,9 @@ def reset(self): def releaseObject(self): # Break any connections involving this component. self._sandbox._breakConnections(self) - self._sandbox._unregisterComponent(self) + + # Unregister from the sandbox + self._unregister() # Call superclass release, which calls the CORBA method. super(SandboxResource,self).releaseObject() From f5f1c3704e2a2e498cd810d0da5325e06a83c16b Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 22 Jun 2016 11:02:05 -0400 Subject: [PATCH 0408/1644] Explicitly set the deployment root for component host launched from the sandbox --- .../base/framework/python/ossie/utils/sandbox/local.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py index 7be8458af..1efb20a72 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py @@ -400,6 +400,7 @@ def _unregister(self): pass def executeLinked(self, entryPoint, options, parameters, deps): + log.debug('Executing shared library %s %s', entryPoint, ' '.join('%s=%s' % (k,v) for k,v in parameters.iteritems())) params = [CF.DataType(k, to_any(str(v))) for k, v in parameters.iteritems()] self.ref.executeLinked(entryPoint, options, params, deps) @@ -418,12 +419,19 @@ def _getComponentHost(self): return self.__container def _launchComponentHost(self): + # Directly create the sandbox object instead of going through launch() profile = self._sdrroot.domPath('/mgr/rh/ComponentHost/ComponentHost.spd.xml') spd, scd, prf = self._sdrroot.readProfile(profile) instanceName = self._createInstanceName('ComponentHost', 'resource') refid = str(uuid4()) comp = ComponentHost(self, profile, spd, scd, prf, instanceName, refid, None) - comp._launcher = LocalComponentLauncher({}, {}, True, {}, None, None, None) + + # Likewise, since the specific component type is known, create the + # launcher directly. The deployment root is overridden to point to the + # root of the local filesystem; all component paths provided to the + # component host will be absolute. + execparams = {'RH::DEPLOYMENT_ROOT':'/'} + comp._launcher = LocalComponentLauncher(execparams, {}, True, {}, None, None, None) comp._kick() return comp From c091adbdf7c79c29fb9152406c352c6d356b4535 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 22 Jun 2016 11:11:02 -0400 Subject: [PATCH 0409/1644] Change VirtualDevice implementation matching log messages to trace --- .../python/ossie/utils/sandbox/launcher.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/launcher.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/launcher.py index 7a3742b81..7df67e445 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/launcher.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/launcher.py @@ -144,21 +144,23 @@ def _matchOS(self, implementation): def _checkImplementation(self, sdrroot, profile, impl): # Match device properties - log.debug("Checking processor and OS") + log.trace("Checking processor and OS for implementation '%s'", impl.get_id()) if not self._matchProcessor(impl) or not self._matchOS(impl): return False # Check that localfile points to a real location - localfile = sdrroot.relativePath(profile, impl.get_code().get_localfile().get_name()) - log.debug("Checking localfile '%s' ('%s')", localfile, impl.get_code().get_localfile().get_name()) - if not os.path.exists(localfile): + localfile = impl.get_code().get_localfile().get_name() + filename = sdrroot.relativePath(profile, localfile) + log.trace("Checking localfile '%s' ('%s')", localfile, filename) + if not os.path.exists(filename): return False # If the implementation has an entry point, make sure it exists too if impl.get_code().get_entrypoint(): - entry_point = sdrroot.relativePath(profile, impl.get_code().get_entrypoint()) - log.debug("Checking entrypoint '%s'", entry_point) - if not os.path.exists(entry_point): + entry_point = impl.get_code().get_entrypoint() + filename = sdrroot.relativePath(profile, entry_point) + log.trace("Checking entrypoint '%s' ('%s')", entry_point, filename) + if not os.path.exists(filename): return False return True From 09993a2405b56a51f75f90f8575a6d2fbd2f4cfa Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 22 Jun 2016 11:19:11 -0400 Subject: [PATCH 0410/1644] Use zipfile to check if a .jar file is really a ZIP file in sandbox dependency processing --- .../base/framework/python/ossie/utils/sandbox/launcher.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/launcher.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/launcher.py index 7df67e445..3c394ad20 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/launcher.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/launcher.py @@ -26,6 +26,7 @@ import tempfile import subprocess import platform +import zipfile from ossie.utils import log4py from ossie import parsers @@ -242,10 +243,10 @@ def _isSharedLibrary(self, filename): with open(filename, 'rb') as f: return f.read(4) == '\x7fELF' except: - return False + return False def _isJarfile(self, filename): - return filename.endswith('.jar') + return filename.endswith('.jar') and zipfile.is_zipfile(filename) def _isPythonLibrary(self, filename): PYTHON_EXTS = ('.py', '.pyc', '.pyo') From b1e018f3577fecd8fafff5264c593b211a718f8f Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 22 Jun 2016 12:49:41 -0400 Subject: [PATCH 0411/1644] Update test components used in Sandbox tests to support x86_64 processor to work with Sandbox VirtualDevice's processor matching --- .../CommandWrapperNestedSPDDep.spd.xml | 1 + .../MessageReceiverPy.spd.xml | 1 + .../PropertyChangeEvents.spd.xml | 1 + .../SlowComponent/SlowComponent.spd.xml | 1 + .../ticket_490_double.spd.xml | 1 + .../ticket_490_none/ticket_490_none.spd.xml | 1 + .../ticket_490_single.spd.xml | 1 + .../ticket_490_dep_single/softpkgDep.spd.xml | 10 ++++++++++ .../ticket_490_dep_single_x86_64/__init__.py | 20 +++++++++++++++++++ 9 files changed, 37 insertions(+) create mode 100644 redhawk/src/testing/sdr/dom/deps/ticket_490_dep_single/ticket_490_dep_single_x86_64/__init__.py diff --git a/redhawk/src/testing/sdr/dom/components/CommandWrapperNestedSPDDep/CommandWrapperNestedSPDDep.spd.xml b/redhawk/src/testing/sdr/dom/components/CommandWrapperNestedSPDDep/CommandWrapperNestedSPDDep.spd.xml index ba404df82..e7fa52cf9 100644 --- a/redhawk/src/testing/sdr/dom/components/CommandWrapperNestedSPDDep/CommandWrapperNestedSPDDep.spd.xml +++ b/redhawk/src/testing/sdr/dom/components/CommandWrapperNestedSPDDep/CommandWrapperNestedSPDDep.spd.xml @@ -46,6 +46,7 @@ with this program. If not, see http://www.gnu.org/licenses/. + diff --git a/redhawk/src/testing/sdr/dom/components/MessageReceiverPy/MessageReceiverPy.spd.xml b/redhawk/src/testing/sdr/dom/components/MessageReceiverPy/MessageReceiverPy.spd.xml index cb8b04d86..9c136f2f1 100644 --- a/redhawk/src/testing/sdr/dom/components/MessageReceiverPy/MessageReceiverPy.spd.xml +++ b/redhawk/src/testing/sdr/dom/components/MessageReceiverPy/MessageReceiverPy.spd.xml @@ -41,5 +41,6 @@ with this program. If not, see http://www.gnu.org/licenses/. + diff --git a/redhawk/src/testing/sdr/dom/components/PropertyChangeEvents/PropertyChangeEvents.spd.xml b/redhawk/src/testing/sdr/dom/components/PropertyChangeEvents/PropertyChangeEvents.spd.xml index c787a4486..1bee8f53a 100644 --- a/redhawk/src/testing/sdr/dom/components/PropertyChangeEvents/PropertyChangeEvents.spd.xml +++ b/redhawk/src/testing/sdr/dom/components/PropertyChangeEvents/PropertyChangeEvents.spd.xml @@ -41,5 +41,6 @@ with this program. If not, see http://www.gnu.org/licenses/. + diff --git a/redhawk/src/testing/sdr/dom/components/SlowComponent/SlowComponent.spd.xml b/redhawk/src/testing/sdr/dom/components/SlowComponent/SlowComponent.spd.xml index 581df59c0..b8e7a8b3f 100644 --- a/redhawk/src/testing/sdr/dom/components/SlowComponent/SlowComponent.spd.xml +++ b/redhawk/src/testing/sdr/dom/components/SlowComponent/SlowComponent.spd.xml @@ -43,6 +43,7 @@ with this program. If not, see http://www.gnu.org/licenses/. + diff --git a/redhawk/src/testing/sdr/dom/components/ticket_490_double/ticket_490_double.spd.xml b/redhawk/src/testing/sdr/dom/components/ticket_490_double/ticket_490_double.spd.xml index 69c46738c..295f8f12b 100644 --- a/redhawk/src/testing/sdr/dom/components/ticket_490_double/ticket_490_double.spd.xml +++ b/redhawk/src/testing/sdr/dom/components/ticket_490_double/ticket_490_double.spd.xml @@ -41,6 +41,7 @@ with this program. If not, see http://www.gnu.org/licenses/. + diff --git a/redhawk/src/testing/sdr/dom/components/ticket_490_none/ticket_490_none.spd.xml b/redhawk/src/testing/sdr/dom/components/ticket_490_none/ticket_490_none.spd.xml index 1f2219a3a..72caef0c9 100644 --- a/redhawk/src/testing/sdr/dom/components/ticket_490_none/ticket_490_none.spd.xml +++ b/redhawk/src/testing/sdr/dom/components/ticket_490_none/ticket_490_none.spd.xml @@ -41,6 +41,7 @@ with this program. If not, see http://www.gnu.org/licenses/. + diff --git a/redhawk/src/testing/sdr/dom/components/ticket_490_single/ticket_490_single.spd.xml b/redhawk/src/testing/sdr/dom/components/ticket_490_single/ticket_490_single.spd.xml index 86f94962e..2221051e5 100644 --- a/redhawk/src/testing/sdr/dom/components/ticket_490_single/ticket_490_single.spd.xml +++ b/redhawk/src/testing/sdr/dom/components/ticket_490_single/ticket_490_single.spd.xml @@ -41,6 +41,7 @@ with this program. If not, see http://www.gnu.org/licenses/. + diff --git a/redhawk/src/testing/sdr/dom/deps/ticket_490_dep_single/softpkgDep.spd.xml b/redhawk/src/testing/sdr/dom/deps/ticket_490_dep_single/softpkgDep.spd.xml index 04b695b8e..81e27d10c 100644 --- a/redhawk/src/testing/sdr/dom/deps/ticket_490_dep_single/softpkgDep.spd.xml +++ b/redhawk/src/testing/sdr/dom/deps/ticket_490_dep_single/softpkgDep.spd.xml @@ -29,6 +29,16 @@ with this program. If not, see http://www.gnu.org/licenses/. An empty SPD to test softpkg dependencies + + + This implementation should never be matchable. + + + + + + + diff --git a/redhawk/src/testing/sdr/dom/deps/ticket_490_dep_single/ticket_490_dep_single_x86_64/__init__.py b/redhawk/src/testing/sdr/dom/deps/ticket_490_dep_single/ticket_490_dep_single_x86_64/__init__.py new file mode 100644 index 000000000..5c719e450 --- /dev/null +++ b/redhawk/src/testing/sdr/dom/deps/ticket_490_dep_single/ticket_490_dep_single_x86_64/__init__.py @@ -0,0 +1,20 @@ +# +# This file is protected by Copyright. Please refer to the COPYRIGHT file +# distributed with this source distribution. +# +# This file is part of REDHAWK core. +# +# REDHAWK core is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation, either version 3 of the License, or (at your option) any +# later version. +# +# REDHAWK core is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +# details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/. +# + From 475e7d332b1ec5d50093440d739094b1d577f139 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 22 Jun 2016 12:50:11 -0400 Subject: [PATCH 0412/1644] Update sandbox tests to use newer APIs, plus some cleanup --- redhawk/src/testing/tests/test_13_TestSB.py | 50 ++++++++++++--------- 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/redhawk/src/testing/tests/test_13_TestSB.py b/redhawk/src/testing/tests/test_13_TestSB.py index ca9015638..9a0186080 100644 --- a/redhawk/src/testing/tests/test_13_TestSB.py +++ b/redhawk/src/testing/tests/test_13_TestSB.py @@ -18,24 +18,28 @@ # along with this program. If not, see http://www.gnu.org/licenses/. # -import unittest -from _unitTestHelpers import scatest -from ossie.cf import CF -from ossie.cf import StandardEvent -from omniORB import CORBA, any import os import Queue -from ossie.utils import sb -from ossie.utils import type_helpers -from ossie import properties as _properties -import threading -globalsdrRoot = os.environ['SDRROOT'] +import unittest import sys import commands import cStringIO import time import copy -import ossie.utils.bulkio.bulkio_helpers as _bulkio_helpers +import threading +import warnings + +from omniORB import CORBA, any + +from ossie import properties +from ossie.cf import CF, StandardEvent +from ossie.utils import sb, type_helpers +from ossie.utils.bulkio import bulkio_helpers + +from _unitTestHelpers import scatest, runtestHelpers + +globalsdrRoot = os.environ['SDRROOT'] +java_support = runtestHelpers.haveJavaSupport('../Makefile') def _initSourceAndSink(dataFormat): @@ -69,7 +73,7 @@ def assertComponentCount(self, count): self.assertEquals(len(sb.domainless._getSandbox().getComponents()), count) def tearDown(self): - sb.domainless._getSandbox().shutdown() + sb.release() sb.setDEBUG(False) os.environ['SDRROOT'] = globalsdrRoot @@ -229,8 +233,10 @@ def test_propertyInitialization(self): comp.releaseObject() # Test with overrides in deprecated 'execparams' and 'configure' arguments - comp = sb.launch('sdr/dom/components/property_init/property_init.spd.xml', - execparams={'cmdline':'override'}, configure={'initial':'override'}) + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + comp = sb.launch('sdr/dom/components/property_init/property_init.spd.xml', + execparams={'cmdline':'override'}, configure={'initial':'override'}) self.assertFalse('initial' in comp.cmdline_args) self.assertFalse('cmdline' in comp.initialize_props) self.assertEquals('override', comp.cmdline) @@ -1203,7 +1209,7 @@ def test_LaunchTimeout(self): sandbox. """ try: - comp = sb.launch('SlowComponent', execparams={'CREATE_DELAY': 15}, timeout=20) + comp = sb.launch('SlowComponent', properties={'CREATE_DELAY': 15}, timeout=20) except RuntimeError: self.fail('Launch timeout was not honored') @@ -1215,7 +1221,7 @@ def test_ComplexSequenceFromRealSequence(self): # NB: The default value for 'complexCharProp' raises a non-fatal # exception during launch. Overriding it avoids the error message, # though in general, complex char properties should be avoided. - comp = sb.launch('TestComplexProps', configure={'complexCharProp':('a','b')}) + comp = sb.launch('TestComplexProps', properties={'complexCharProp':('a','b')}) value = range(4) try: comp.complexFloatSequence = value @@ -1275,7 +1281,7 @@ def test_Services(self): service1_id = service1._refid # Launch second instance by ID (added in 1.10) - service2 = sb.launch('BasicService', execparams={'PARAM4':True,'PARAM5':'Message'}) + service2 = sb.launch('BasicService', properties={'PARAM4':True,'PARAM5':'Message'}) service2_name = service2._instanceName service2_id = service2._refid @@ -1302,19 +1308,19 @@ def test_Services(self): def test_ComplexListConversions(self): # Test interleaved-to-complex inData = range(4) - outData = _bulkio_helpers.bulkioComplexToPythonComplexList(inData) + outData = bulkio_helpers.bulkioComplexToPythonComplexList(inData) self.assertEqual(outData,[complex(0,1),complex(2,3)]) # Test complex-to-interleaved cxData = [complex(x+0.5,0) for x in xrange(4)] - outData = _bulkio_helpers.pythonComplexListToBulkioComplex(cxData) + outData = bulkio_helpers.pythonComplexListToBulkioComplex(cxData) self.assertEqual(outData, [0.5,0.0,1.5,0.0,2.5,0.0,3.5,0.0]) # Ensure that conversion does not modify the original list self.assertTrue(isinstance(cxData[0],complex)) # Test inline type conversion (should truncate) - outDataInt = _bulkio_helpers.pythonComplexListToBulkioComplex(cxData, int) + outDataInt = bulkio_helpers.pythonComplexListToBulkioComplex(cxData, int) self.assertEqual(outDataInt[0], 0) self.assertEqual(outDataInt, [int(x) for x in outData]) @@ -1444,7 +1450,7 @@ def isComplex(x) : return type(x) == type(complex()) if len(filter(isComplex, originalData)): # in this case, the DataSink will return bulkio complex data # convert the originalData to the bulkio data format. - originalData = _bulkio_helpers.pythonComplexListToBulkioComplex(originalData) + originalData = bulkio_helpers.pythonComplexListToBulkioComplex(originalData) # make sure the mode flag was automatically set self.assertEquals(sink.sri().mode, True) @@ -1696,7 +1702,7 @@ def __init__(self, cond): self.count=0 def msgCallback(self, id, msg): - self.msg = _properties.prop_to_dict(msg) + self.msg = properties.prop_to_dict(msg) self.count = self.count + 1 self.cond.acquire() self.cond.notify() From 418358a369d0c8897fdf18c2eab75d2789bd0b9f Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 22 Jun 2016 13:48:07 -0400 Subject: [PATCH 0413/1644] Update port connection tests to use x86/x86_64 instead of i686 --- .../devices/EventPortTestDevice/EventPortTestDevice.prf.xml | 2 +- .../sdr/dev/devices/PortTestDevice/PortTestDevice.prf.xml | 2 +- .../PortTestDeviceService/PortTestDeviceService.prf.xml | 2 +- .../FileManagerPortTest/FileManagerPortTest.spd.xml | 5 +++-- .../src/testing/sdr/dom/components/PortTest/PortTest.spd.xml | 5 +++-- redhawk/src/testing/tests/test_08_SADConnections.py | 2 +- 6 files changed, 10 insertions(+), 8 deletions(-) diff --git a/redhawk/src/testing/sdr/dev/devices/EventPortTestDevice/EventPortTestDevice.prf.xml b/redhawk/src/testing/sdr/dev/devices/EventPortTestDevice/EventPortTestDevice.prf.xml index 7005550de..2dc5402ba 100644 --- a/redhawk/src/testing/sdr/dev/devices/EventPortTestDevice/EventPortTestDevice.prf.xml +++ b/redhawk/src/testing/sdr/dev/devices/EventPortTestDevice/EventPortTestDevice.prf.xml @@ -42,7 +42,7 @@ with this program. If not, see http://www.gnu.org/licenses/. SCA required property describing the CPU type - i686 + x86 diff --git a/redhawk/src/testing/sdr/dev/devices/PortTestDevice/PortTestDevice.prf.xml b/redhawk/src/testing/sdr/dev/devices/PortTestDevice/PortTestDevice.prf.xml index 7005550de..2dc5402ba 100644 --- a/redhawk/src/testing/sdr/dev/devices/PortTestDevice/PortTestDevice.prf.xml +++ b/redhawk/src/testing/sdr/dev/devices/PortTestDevice/PortTestDevice.prf.xml @@ -42,7 +42,7 @@ with this program. If not, see http://www.gnu.org/licenses/. SCA required property describing the CPU type - i686 + x86 diff --git a/redhawk/src/testing/sdr/dev/devices/PortTestDeviceService/PortTestDeviceService.prf.xml b/redhawk/src/testing/sdr/dev/devices/PortTestDeviceService/PortTestDeviceService.prf.xml index 7005550de..2dc5402ba 100644 --- a/redhawk/src/testing/sdr/dev/devices/PortTestDeviceService/PortTestDeviceService.prf.xml +++ b/redhawk/src/testing/sdr/dev/devices/PortTestDeviceService/PortTestDeviceService.prf.xml @@ -42,7 +42,7 @@ with this program. If not, see http://www.gnu.org/licenses/. SCA required property describing the CPU type - i686 + x86 diff --git a/redhawk/src/testing/sdr/dom/components/FileManagerPortTest/FileManagerPortTest.spd.xml b/redhawk/src/testing/sdr/dom/components/FileManagerPortTest/FileManagerPortTest.spd.xml index 92ce7f78a..d747e50d0 100644 --- a/redhawk/src/testing/sdr/dom/components/FileManagerPortTest/FileManagerPortTest.spd.xml +++ b/redhawk/src/testing/sdr/dom/components/FileManagerPortTest/FileManagerPortTest.spd.xml @@ -38,7 +38,8 @@ with this program. If not, see http://www.gnu.org/licenses/. - + + @@ -54,7 +55,7 @@ with this program. If not, see http://www.gnu.org/licenses/. - + diff --git a/redhawk/src/testing/sdr/dom/components/PortTest/PortTest.spd.xml b/redhawk/src/testing/sdr/dom/components/PortTest/PortTest.spd.xml index 543b81ccc..294923d01 100644 --- a/redhawk/src/testing/sdr/dom/components/PortTest/PortTest.spd.xml +++ b/redhawk/src/testing/sdr/dom/components/PortTest/PortTest.spd.xml @@ -41,7 +41,8 @@ with this program. If not, see http://www.gnu.org/licenses/. - + + @@ -57,7 +58,7 @@ with this program. If not, see http://www.gnu.org/licenses/. - + diff --git a/redhawk/src/testing/tests/test_08_SADConnections.py b/redhawk/src/testing/tests/test_08_SADConnections.py index 28a3a5c1d..0573f789e 100644 --- a/redhawk/src/testing/tests/test_08_SADConnections.py +++ b/redhawk/src/testing/tests/test_08_SADConnections.py @@ -97,7 +97,7 @@ def test_FindByNamingService(self): def test_FindByAbsoluteNamingService(self): from ossie.utils import sb - comp=sb.Component('PortTest') + comp = sb.launch('PortTest') orb = CORBA.ORB_init() obj = orb.resolve_initial_references("NameService") rootContext = obj._narrow(CosNaming.NamingContext) From 41c6b53710f5f6e1429ef698182c21c1a2a0db10 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 24 Jun 2016 11:12:24 -0400 Subject: [PATCH 0414/1644] Convert local sandbox paths to absolute, so that launching shared library-based components with relative paths works --- .../src/base/framework/python/ossie/utils/sandbox/local.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py index 1efb20a72..eefbef160 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py @@ -55,7 +55,9 @@ def __init__(self, sdrroot): def _sdrPath(self, filename): # Give precedence to filenames that are valid as-is if os.path.isfile(filename): - return filename + # Convert to an absolute path, to avoid any problems with relative + # paths when passed to other contexts + return os.path.abspath(filename) # Assume the filename points to somewhere in SDRROOT return os.path.join(self.__sdrroot, filename) From 23b1bec353c43770215aca2a1f1fa94e0394a509 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 13 Jul 2016 08:36:58 -0400 Subject: [PATCH 0415/1644] For the time being, drop DEBUG_LEVEL on the floor for components created inside of the component host --- redhawk/src/base/framework/Resource_impl.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/redhawk/src/base/framework/Resource_impl.cpp b/redhawk/src/base/framework/Resource_impl.cpp index 24b4dd032..322a986f5 100644 --- a/redhawk/src/base/framework/Resource_impl.cpp +++ b/redhawk/src/base/framework/Resource_impl.cpp @@ -222,6 +222,11 @@ Resource_impl* Resource_impl::create_component(Resource_impl::ctor_type ctor, co name_binding = prop->getValue().toString(); } else if (id == "NAMING_CONTEXT_IOR") { application_registrar_ior = prop->getValue().toString(); + } else if (id == "DEBUG_LEVEL") { + // If DEBUG_LEVEL is in the parameters, this component is being + // created from a shared library entry point, not the command line; + // logging has already been set up by the component host. + // TODO: Revisit as part of logging update } else { cmdlineProps.push_back(*prop); } From b165c27530839b685f98b5370d3d991798ded34b Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 14 Jul 2016 07:55:11 -0400 Subject: [PATCH 0416/1644] Provide a way to set the thread name in ThreadedComponent --- .../src/base/framework/ThreadedComponent.cpp | 22 ++++++++++++++++--- .../src/base/include/ossie/ProcessThread.h | 3 ++- .../base/include/ossie/ThreadedComponent.h | 3 +++ 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/redhawk/src/base/framework/ThreadedComponent.cpp b/redhawk/src/base/framework/ThreadedComponent.cpp index 40af49513..dc0661c19 100644 --- a/redhawk/src/base/framework/ThreadedComponent.cpp +++ b/redhawk/src/base/framework/ThreadedComponent.cpp @@ -22,10 +22,11 @@ namespace ossie { -ProcessThread::ProcessThread(ThreadedComponent *target, float delay) : +ProcessThread::ProcessThread(ThreadedComponent *target, float delay, const std::string& name) : _thread(0), _running(false), _target(target), + _name(name), _mythread(_thread) { updateDelay(delay); @@ -41,6 +42,14 @@ void ProcessThread::start() void ProcessThread::run() { + // If a name was given, set it on the current thread + // NB: On RHEL/CentOS 6, the name is limited to 15 characters, and the call + // fails if the name exceeds that limit + if (!_name.empty()) { + std::string name = _name.substr(0, 15); + pthread_setname_np(pthread_self(), name.c_str()); + } + while (_running) { int state = _target->serviceFunction(); if (state == FINISH) { @@ -102,6 +111,7 @@ bool ProcessThread::threadRunning() ThreadedComponent::ThreadedComponent() : serviceThread(0), serviceThreadLock(), + _threadName(), _defaultDelay(0.1) { } @@ -114,8 +124,8 @@ void ThreadedComponent::startThread () { boost::mutex::scoped_lock lock(serviceThreadLock); if (!serviceThread) { - serviceThread = new ossie::ProcessThread(this, _defaultDelay); - serviceThread->start(); + serviceThread = new ossie::ProcessThread(this, _defaultDelay, _threadName); + serviceThread->start(); } } @@ -145,3 +155,9 @@ void ThreadedComponent::setThreadDelay (float delay) serviceThread->updateDelay(delay); } } + +void ThreadedComponent::setThreadName (const std::string& name) +{ + boost::mutex::scoped_lock lock(serviceThreadLock); + _threadName = name; +} diff --git a/redhawk/src/base/include/ossie/ProcessThread.h b/redhawk/src/base/include/ossie/ProcessThread.h index 9a6c44800..2d28480e6 100644 --- a/redhawk/src/base/include/ossie/ProcessThread.h +++ b/redhawk/src/base/include/ossie/ProcessThread.h @@ -31,7 +31,7 @@ namespace ossie { class ProcessThread { public: - ProcessThread(ThreadedComponent* target, float delay); + ProcessThread(ThreadedComponent* target, float delay, const std::string& name=std::string()); ~ProcessThread(); // Kicks off the thread @@ -55,6 +55,7 @@ class ProcessThread volatile bool _running; ThreadedComponent* _target; struct timespec _delay; + std::string _name; public: boost::thread*& _mythread; diff --git a/redhawk/src/base/include/ossie/ThreadedComponent.h b/redhawk/src/base/include/ossie/ThreadedComponent.h index ff5bb1cc9..404a73cbe 100644 --- a/redhawk/src/base/include/ossie/ThreadedComponent.h +++ b/redhawk/src/base/include/ossie/ThreadedComponent.h @@ -57,7 +57,10 @@ class ThreadedComponent { ossie::ProcessThread* serviceThread; boost::mutex serviceThreadLock; + void setThreadName(const std::string& name); + private: + std::string _threadName; float _defaultDelay; }; From 832238b6c42603c7001ba3860f65e287769a4925 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 14 Jul 2016 10:24:01 -0400 Subject: [PATCH 0417/1644] Set the main process/thread name for components based on NAME_BINDING --- redhawk/src/base/framework/Resource_impl.cpp | 25 +++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/redhawk/src/base/framework/Resource_impl.cpp b/redhawk/src/base/framework/Resource_impl.cpp index 322a986f5..ebfd9e531 100644 --- a/redhawk/src/base/framework/Resource_impl.cpp +++ b/redhawk/src/base/framework/Resource_impl.cpp @@ -285,18 +285,31 @@ static void sigint_handler(int signum) void Resource_impl::start_component(Resource_impl::ctor_type ctor, int argc, char* argv[]) { - int debug_level = -1; // use log config uri as log level context - std::string logcfg_uri; - std::string dpath(""); - bool skip_run = false; + // Scan the arguments for NAME_BINDING, setting the thread/process name + // based on the name. If this isn't done prior to initializing CORBA, the + // ORB creates some threads that will get the original process name, and + // any threads they create, and so on. + for (size_t index = 1; index < argc; ++index) { + if (strcmp("NAME_BINDING", argv[index]) == 0) { + if (++index < argc) { + std::string value = argv[index]; + value = value.substr(0, 15); + pthread_setname_np(pthread_self(), value.c_str()); + } + break; + } + } // The ORB must be initialized before anything that might depend on CORBA, // such as PropertyMap and logging configuration ossie::corba::CorbaInit(argc, argv); - redhawk::PropertyMap cmdlineProps; - // Parse command line arguments. + int debug_level = -1; // use log config uri as log level context + std::string logcfg_uri; + std::string dpath(""); + bool skip_run = false; + redhawk::PropertyMap cmdlineProps; for (int i = 1; i < argc; i++) { if (strcmp("SKIP_RUN", argv[i]) == 0) { skip_run = true; From ef99f61de5d4bfa7a3efa326f5229d56fd203ce9 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 15 Jul 2016 11:06:45 -0400 Subject: [PATCH 0418/1644] Refactor C++ MessageSupplierPort to use transport layer pattern --- .../src/base/framework/MessageInterface.cpp | 129 +++++++++++++----- .../src/base/include/ossie/MessageInterface.h | 13 +- 2 files changed, 102 insertions(+), 40 deletions(-) diff --git a/redhawk/src/base/framework/MessageInterface.cpp b/redhawk/src/base/framework/MessageInterface.cpp index b1ac13fe0..d92227519 100644 --- a/redhawk/src/base/framework/MessageInterface.cpp +++ b/redhawk/src/base/framework/MessageInterface.cpp @@ -18,8 +18,8 @@ * along with this program. If not, see http://www.gnu.org/licenses/. */ -#include "ossie/MessageInterface.h" -#include +#include +#include PREPARE_CF_LOGGING(MessageConsumerPort) @@ -179,6 +179,80 @@ std::string MessageConsumerPort::getDirection() const return CF::PortSet::DIRECTION_BIDIR; } + +class MessageSupplierPort::MessageTransport +{ +public: + MessageTransport(CosEventChannelAdmin::EventChannel_ptr channel) : + _channel(CosEventChannelAdmin::EventChannel::_duplicate(channel)) + { + } + + virtual void push(const CORBA::Any& data) = 0; + virtual void disconnect() = 0; + +private: + CosEventChannelAdmin::EventChannel_var _channel; +}; + +class MessageSupplierPort::RemoteTransport : public MessageSupplierPort::MessageTransport +{ +public: + RemoteTransport(CosEventChannelAdmin::EventChannel_ptr channel) : + MessageTransport(channel) + { + CosEventChannelAdmin::SupplierAdmin_var supplier_admin = channel->for_suppliers(); + _consumer = supplier_admin->obtain_push_consumer(); + _consumer->connect_push_supplier(CosEventComm::PushSupplier::_nil()); + } + + void push(const CORBA::Any& data) + { + _consumer->push(data); + } + + void disconnect() + { + try { + _consumer->disconnect_push_consumer(); + } catch (...) { + // Ignore errors on disconnect + } + } + +private: + CosEventChannelAdmin::ProxyPushConsumer_var _consumer; +}; + +class MessageSupplierPort::LocalTransport : public MessageSupplierPort::MessageTransport +{ +public: + LocalTransport(MessageConsumerPort* consumer, CosEventChannelAdmin::EventChannel_ptr channel) : + MessageTransport(channel), + _consumer(consumer) + { + } + + void push(const CORBA::Any& data) + { + CF::Properties* temp; + if (!(data >>= temp)) { + return; + } + const redhawk::PropertyMap& props = redhawk::PropertyMap::cast(*temp); + for (redhawk::PropertyMap::const_iterator msg = props.begin(); msg != props.end(); ++msg) { + _consumer->fireCallback(msg->getId(), msg->getValue()); + } + } + + void disconnect() + { + } + +private: + MessageConsumerPort* _consumer; +}; + MessageSupplierPort::MessageSupplierPort (std::string port_name) : Port_Uses_base_impl(port_name) { @@ -190,58 +264,45 @@ MessageSupplierPort::~MessageSupplierPort (void) void MessageSupplierPort::connectPort(CORBA::Object_ptr connection, const char* connectionId) { - boost::mutex::scoped_lock lock(portInterfaceAccess); - this->active = true; CosEventChannelAdmin::EventChannel_var channel = ossie::corba::_narrowSafe(connection); if (CORBA::is_nil(channel)) { throw CF::Port::InvalidPort(0, "The object provided did not narrow to a CosEventChannelAdmin::EventChannel type"); } - CosEventChannelAdmin::SupplierAdmin_var supplier_admin = channel->for_suppliers(); - CosEventChannelAdmin::ProxyPushConsumer_ptr proxy_consumer = supplier_admin->obtain_push_consumer(); - proxy_consumer->connect_push_supplier(CosEventComm::PushSupplier::_nil()); - extendConsumers(connectionId, proxy_consumer); + + { + boost::mutex::scoped_lock lock(portInterfaceAccess); + MessageTransport* transport; + MessageConsumerPort* local_port = ossie::corba::getLocalServant(channel); + if (local_port) { + transport = new LocalTransport(local_port, channel); + } else { + transport = new RemoteTransport(channel); + } + _connections[connectionId] = transport; + } } void MessageSupplierPort::disconnectPort(const char* connectionId) { boost::mutex::scoped_lock lock(portInterfaceAccess); - CosEventChannelAdmin::ProxyPushConsumer_var consumer = removeConsumer(connectionId); - if (CORBA::is_nil(consumer)) { + TransportMap::iterator connection = _connections.find(connectionId); + if (connection == _connections.end()) { return; } - consumer->disconnect_push_consumer(); - if (this->consumers.empty()) { - this->active = false; - } + connection->second->disconnect(); + delete connection->second; + _connections.erase(connection); } void MessageSupplierPort::push(const CORBA::Any& data) { boost::mutex::scoped_lock lock(portInterfaceAccess); - std::map::iterator connection = consumers.begin(); - while (connection != consumers.end()) { + for (TransportMap::iterator connection = _connections.begin(); connection != _connections.end(); ++connection) { try { - (connection->second)->push(data); + connection->second->push(data); } catch ( ... ) { } - connection++; - } -} - -CosEventChannelAdmin::ProxyPushConsumer_ptr MessageSupplierPort::removeConsumer(std::string consumer_id) -{ - std::map::iterator connection = consumers.find(consumer_id); - if (connection == consumers.end()) { - return CosEventChannelAdmin::ProxyPushConsumer::_nil(); } - CosEventChannelAdmin::ProxyPushConsumer_var consumer = connection->second; - consumers.erase(connection); - return consumer._retn(); -} - -void MessageSupplierPort::extendConsumers(std::string consumer_id, CosEventChannelAdmin::ProxyPushConsumer_ptr proxy_consumer) -{ - consumers[std::string(consumer_id)] = proxy_consumer; } std::string MessageSupplierPort::getRepid() const diff --git a/redhawk/src/base/include/ossie/MessageInterface.h b/redhawk/src/base/include/ossie/MessageInterface.h index d4ff3c5c5..bcfe98374 100644 --- a/redhawk/src/base/include/ossie/MessageInterface.h +++ b/redhawk/src/base/include/ossie/MessageInterface.h @@ -217,9 +217,6 @@ class MessageSupplierPort : public Port_Uses_base_impl void push(const CORBA::Any& data); - CosEventChannelAdmin::ProxyPushConsumer_ptr removeConsumer(std::string consumer_id); - void extendConsumers(std::string consumer_id, CosEventChannelAdmin::ProxyPushConsumer_ptr proxy_consumer); - // Send a single message template void sendMessage(const Message& message) { @@ -255,12 +252,16 @@ class MessageSupplierPort : public Port_Uses_base_impl push(data); } - std::string getRepid() const; + std::string getRepid() const; protected: + class MessageTransport; + class RemoteTransport; + class LocalTransport; + typedef std::map TransportMap; + TransportMap _connections; + boost::mutex portInterfaceAccess; - std::map consumers; - std::map _connections; }; From 2c2fb8178a9cde48cf661789b354d43ade567a83 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 18 Jul 2016 11:35:08 -0400 Subject: [PATCH 0419/1644] Accelerate C++ message dispatch in local case by skipping Any marshalling/unmarshalling entirely; allow remote transport to queue up a set of messages before sending --- .../src/base/framework/MessageInterface.cpp | 84 +++++++++++++++++++ .../src/base/include/ossie/MessageInterface.h | 51 +++++++---- 2 files changed, 121 insertions(+), 14 deletions(-) diff --git a/redhawk/src/base/framework/MessageInterface.cpp b/redhawk/src/base/framework/MessageInterface.cpp index d92227519..bee9943f2 100644 --- a/redhawk/src/base/framework/MessageInterface.cpp +++ b/redhawk/src/base/framework/MessageInterface.cpp @@ -169,6 +169,15 @@ void MessageConsumerPort::fireCallback (const std::string& id, const CORBA::Any& generic_callbacks_(id, data); }; +bool MessageConsumerPort::pushLocal (const std::string& id, const void* data) { + CallbackTable::iterator callback = callbacks_.find(id); + if (callback != callbacks_.end()) { + (*callback->second)(id, data); + return true; + } + return false; +} + std::string MessageConsumerPort::getRepid() const { return ExtendedEvent::MessageEvent::_PD_repoId; @@ -189,6 +198,11 @@ class MessageSupplierPort::MessageTransport } virtual void push(const CORBA::Any& data) = 0; + + virtual void beginQueue(size_t count) = 0; + virtual void queueMessage(const std::string& msgId, const void* msgData, MessageSupplierPort::SerializerFunc serializer) = 0; + virtual void sendMessages() = 0; + virtual void disconnect() = 0; private: @@ -211,6 +225,32 @@ class MessageSupplierPort::RemoteTransport : public MessageSupplierPort::Message _consumer->push(data); } + void beginQueue(size_t count) + { + // Pre-allocate enough space to hold the entire queue + if (_queue.maximum() < count) { + _queue.replace(count, 0, CF::Properties::allocbuf(count), true); + } else { + _queue.length(0); + } + } + + void queueMessage(const std::string& msgId, const void* msgData, MessageSupplierPort::SerializerFunc serializer) + { + CORBA::ULong index = _queue.length(); + _queue.length(index+1); + CF::DataType& message = _queue[index]; + message.id = msgId.c_str(); + serializer(message.value, msgData); + } + + void sendMessages() + { + CORBA::Any data; + data <<= _queue; + push(data); + } + void disconnect() { try { @@ -222,6 +262,7 @@ class MessageSupplierPort::RemoteTransport : public MessageSupplierPort::Message private: CosEventChannelAdmin::ProxyPushConsumer_var _consumer; + CF::Properties _queue; }; class MessageSupplierPort::LocalTransport : public MessageSupplierPort::MessageTransport @@ -245,6 +286,25 @@ class MessageSupplierPort::LocalTransport : public MessageSupplierPort::MessageT } } + void beginQueue(size_t /*unused*/) + { + } + + void queueMessage(const std::string& msgId, const void* msgData, MessageSupplierPort::SerializerFunc serializer) + { + if (_consumer->pushLocal(msgId, msgData)) { + return; + } + + CORBA::Any data; + serializer(data, msgData); + _consumer->fireCallback(msgId, data); + } + + void sendMessages() + { + } + void disconnect() { } @@ -309,3 +369,27 @@ std::string MessageSupplierPort::getRepid() const { return ExtendedEvent::MessageEvent::_PD_repoId; } + +void MessageSupplierPort::_beginMessageQueue(size_t count) +{ + for (TransportMap::iterator connection = _connections.begin(); connection != _connections.end(); ++connection) { + connection->second->beginQueue(count); + } +} + +void MessageSupplierPort::_queueMessage(const std::string& msgId, const void* msgData, SerializerFunc serializer) +{ + for (TransportMap::iterator connection = _connections.begin(); connection != _connections.end(); ++connection) { + try { + connection->second->queueMessage(msgId, msgData, serializer); + } catch ( ... ) { + } + } +} + +void MessageSupplierPort::_sendMessageQueue() +{ + for (TransportMap::iterator connection = _connections.begin(); connection != _connections.end(); ++connection) { + connection->second->sendMessages(); + } +} diff --git a/redhawk/src/base/include/ossie/MessageInterface.h b/redhawk/src/base/include/ossie/MessageInterface.h index bcfe98374..51a7586cb 100644 --- a/redhawk/src/base/include/ossie/MessageInterface.h +++ b/redhawk/src/base/include/ossie/MessageInterface.h @@ -132,6 +132,10 @@ class MessageConsumerPort : public Port_Provides_base_impl protected: + friend class MessageSupplierPort; + + bool pushLocal (const std::string& id, const void* data); + void addSupplier (const std::string& connectionId, CosEventComm::PushSupplier_ptr supplier); CosEventComm::PushSupplier_ptr removeSupplier (const std::string& connectionId); @@ -149,6 +153,7 @@ class MessageConsumerPort : public Port_Provides_base_impl { public: virtual void operator() (const std::string& value, const CORBA::Any& data) = 0; + virtual void operator() (const std::string& value, const void* data) = 0; virtual ~MessageCallback () { } protected: @@ -173,6 +178,12 @@ class MessageConsumerPort : public Port_Provides_base_impl } } + virtual void operator() (const std::string& value, const void* data) + { + const M* message = reinterpret_cast(data); + (target_.*func_)(value, *message); + } + protected: // Only allow MessageConsumerPort to instantiate this class. MemberCallback (Class& target, MemberFn func) : @@ -235,26 +246,38 @@ class MessageSupplierPort : public Port_Uses_base_impl template void sendMessages(Iterator first, Iterator last) { - CF::Properties properties; - properties.length(std::distance(first, last)); - for (CORBA::ULong ii = 0; first != last; ++ii, ++first) { - // Workaround for older components whose structs have a non-const, - // non-static member function getId(): determine the type of value - // pointed to by the iterator, and const_cast the dereferenced - // value; this ensures that it works for both bare pointers and - // "true" iterators - typedef typename std::iterator_traits::value_type value_type; - properties[ii].id = const_cast(*first).getId().c_str(); - properties[ii].value <<= *first; + boost::mutex::scoped_lock lock(portInterfaceAccess); + _beginMessageQueue(std::distance(first, last)); + for (; first != last; ++first) { + _queueMessage(*first); } - CORBA::Any data; - data <<= properties; - push(data); + _sendMessageQueue(); } std::string getRepid() const; protected: + template + inline void _queueMessage(const Message& message) + { + // Workaround for older components whose structs have a non-const, + // non-static member function getId(): const_cast the value + const std::string messageId = const_cast(message).getId(); + _queueMessage(messageId, &message, &MessageSupplierPort::_serializeMessage); + } + + template + static void _serializeMessage(CORBA::Any& any, const void* data) + { + any <<= *(reinterpret_cast(data)); + } + + typedef boost::function SerializerFunc; + + void _beginMessageQueue(size_t count); + void _queueMessage(const std::string& msgId, const void* msgData, SerializerFunc serializer); + void _sendMessageQueue(); + class MessageTransport; class RemoteTransport; class LocalTransport; From e937a04a9916f975ef7afbbc77cf9b9d097ae01e Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 18 Jul 2016 15:22:02 -0400 Subject: [PATCH 0420/1644] Use boost function for internal implementation of message callback --- .../src/base/framework/MessageInterface.cpp | 4 +- .../src/base/include/ossie/MessageInterface.h | 54 ++++++++----------- 2 files changed, 25 insertions(+), 33 deletions(-) diff --git a/redhawk/src/base/framework/MessageInterface.cpp b/redhawk/src/base/framework/MessageInterface.cpp index bee9943f2..b81f3f7fe 100644 --- a/redhawk/src/base/framework/MessageInterface.cpp +++ b/redhawk/src/base/framework/MessageInterface.cpp @@ -146,7 +146,7 @@ CosEventComm::PushSupplier_ptr MessageConsumerPort::removeSupplier (const std::s void MessageConsumerPort::fireCallback (const std::string& id, const CORBA::Any& data) { CallbackTable::iterator callback = callbacks_.find(id); if (callback != callbacks_.end()) { - (*callback->second)(id, data); + callback->second->dispatch(id, data); } else { if (generic_callbacks_.empty()) { std::string warning = "no callbacks registered for messages with id: "+id+"."; @@ -172,7 +172,7 @@ void MessageConsumerPort::fireCallback (const std::string& id, const CORBA::Any& bool MessageConsumerPort::pushLocal (const std::string& id, const void* data) { CallbackTable::iterator callback = callbacks_.find(id); if (callback != callbacks_.end()) { - (*callback->second)(id, data); + callback->second->dispatch(id, data); return true; } return false; diff --git a/redhawk/src/base/include/ossie/MessageInterface.h b/redhawk/src/base/include/ossie/MessageInterface.h index 51a7586cb..899d64d7d 100644 --- a/redhawk/src/base/include/ossie/MessageInterface.h +++ b/redhawk/src/base/include/ossie/MessageInterface.h @@ -100,7 +100,7 @@ class MessageConsumerPort : public Port_Provides_base_impl template void registerMessage (const std::string& id, Class* target, void (Class::*func)(const std::string&, const MessageStruct&)) { - callbacks_[id] = new MemberCallback(*target, func); + callbacks_[id] = new MessageCallback(boost::bind(func, target, _1, _2)); } template @@ -147,58 +147,50 @@ class MessageConsumerPort : public Port_Provides_base_impl SupplierAdmin_i *supplier_admin; /* - * Abstract interface for message callbacks. + * Abstract untyped interface for message callbacks. */ - class MessageCallback + class MessageCallbackBase { public: - virtual void operator() (const std::string& value, const CORBA::Any& data) = 0; - virtual void operator() (const std::string& value, const void* data) = 0; - virtual ~MessageCallback () { } - - protected: - MessageCallback () { } + virtual void dispatch (const std::string& value, const CORBA::Any& data) = 0; + virtual void dispatch (const std::string& value, const void* data) = 0; + virtual ~MessageCallbackBase () { } }; /* - * Concrete class for member function property change callbacks. + * Concrete typed class for message callbacks. */ - template - class MemberCallback : public MessageCallback + template + class MessageCallback : public MessageCallbackBase { public: - typedef void (Class::*MemberFn)(const std::string&, const M&); + typedef boost::function CallbackFunc;; - virtual void operator() (const std::string& value, const CORBA::Any& data) + MessageCallback (CallbackFunc func) : + func_(func) { - M message; - if (data >>= message) { - (target_.*func_)(value, message); - } } - virtual void operator() (const std::string& value, const void* data) + virtual void dispatch (const std::string& value, const CORBA::Any& data) { - const M* message = reinterpret_cast(data); - (target_.*func_)(value, *message); + Message message; + if (data >>= message) { + func_(value, message); + } } - protected: - // Only allow MessageConsumerPort to instantiate this class. - MemberCallback (Class& target, MemberFn func) : - target_(target), - func_(func) + virtual void dispatch (const std::string& value, const void* data) { + const Message* message = reinterpret_cast(data); + func_(value, *message); } - friend class MessageConsumerPort; - - Class& target_; - MemberFn func_; + private: + CallbackFunc func_; }; - typedef std::map CallbackTable; + typedef std::map CallbackTable; CallbackTable callbacks_; ossie::notification generic_callbacks_; From 8fd9baf161741a336795e2957f7491e7d1ec32d4 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 20 Jul 2016 13:24:47 -0400 Subject: [PATCH 0421/1644] Implement a working format check for local messages in C++ that must succeed to use void* to pass messages; message structs will have to have a generated static method to provide the format string, but it gracefully falls back to bouncing through Any --- .../src/base/framework/MessageInterface.cpp | 16 ++--- .../src/base/include/ossie/MessageInterface.h | 71 +++++++++++++++++-- 2 files changed, 74 insertions(+), 13 deletions(-) diff --git a/redhawk/src/base/framework/MessageInterface.cpp b/redhawk/src/base/framework/MessageInterface.cpp index b81f3f7fe..34c73f7fa 100644 --- a/redhawk/src/base/framework/MessageInterface.cpp +++ b/redhawk/src/base/framework/MessageInterface.cpp @@ -169,9 +169,9 @@ void MessageConsumerPort::fireCallback (const std::string& id, const CORBA::Any& generic_callbacks_(id, data); }; -bool MessageConsumerPort::pushLocal (const std::string& id, const void* data) { +bool MessageConsumerPort::pushLocal (const std::string& id, const char* format, const void* data) { CallbackTable::iterator callback = callbacks_.find(id); - if (callback != callbacks_.end()) { + if (callback != callbacks_.end() && callback->second->isCompatible(format)) { callback->second->dispatch(id, data); return true; } @@ -200,7 +200,7 @@ class MessageSupplierPort::MessageTransport virtual void push(const CORBA::Any& data) = 0; virtual void beginQueue(size_t count) = 0; - virtual void queueMessage(const std::string& msgId, const void* msgData, MessageSupplierPort::SerializerFunc serializer) = 0; + virtual void queueMessage(const std::string& msgId, const char* format, const void* msgData, MessageSupplierPort::SerializerFunc serializer) = 0; virtual void sendMessages() = 0; virtual void disconnect() = 0; @@ -235,7 +235,7 @@ class MessageSupplierPort::RemoteTransport : public MessageSupplierPort::Message } } - void queueMessage(const std::string& msgId, const void* msgData, MessageSupplierPort::SerializerFunc serializer) + void queueMessage(const std::string& msgId, const char* /*unused*/, const void* msgData, MessageSupplierPort::SerializerFunc serializer) { CORBA::ULong index = _queue.length(); _queue.length(index+1); @@ -290,9 +290,9 @@ class MessageSupplierPort::LocalTransport : public MessageSupplierPort::MessageT { } - void queueMessage(const std::string& msgId, const void* msgData, MessageSupplierPort::SerializerFunc serializer) + void queueMessage(const std::string& msgId, const char* format, const void* msgData, MessageSupplierPort::SerializerFunc serializer) { - if (_consumer->pushLocal(msgId, msgData)) { + if (_consumer->pushLocal(msgId, format, msgData)) { return; } @@ -377,11 +377,11 @@ void MessageSupplierPort::_beginMessageQueue(size_t count) } } -void MessageSupplierPort::_queueMessage(const std::string& msgId, const void* msgData, SerializerFunc serializer) +void MessageSupplierPort::_queueMessage(const std::string& msgId, const char* format, const void* msgData, SerializerFunc serializer) { for (TransportMap::iterator connection = _connections.begin(); connection != _connections.end(); ++connection) { try { - connection->second->queueMessage(msgId, msgData, serializer); + connection->second->queueMessage(msgId, format, msgData, serializer); } catch ( ... ) { } } diff --git a/redhawk/src/base/include/ossie/MessageInterface.h b/redhawk/src/base/include/ossie/MessageInterface.h index 899d64d7d..3379bcad3 100644 --- a/redhawk/src/base/include/ossie/MessageInterface.h +++ b/redhawk/src/base/include/ossie/MessageInterface.h @@ -26,6 +26,8 @@ #include #include +#include + #include "CF/ExtendedEvent.h" #include "CF/cf.h" #include "CorbaUtils.h" @@ -80,6 +82,42 @@ class SupplierAdmin_i : public virtual POA_CosEventChannelAdmin::SupplierAdmin { */ #endif +namespace internal { + template + struct has_format + { + typedef ::boost::type_traits::no_type no_type; + typedef ::boost::type_traits::yes_type yes_type; + template struct type_check; + + template + static yes_type& check(type_check*); + + template + static no_type& check(...); + + static bool const value = (sizeof(check(0)) == sizeof(yes_type)); + }; + + template + struct message_traits + { + static const char* format() + { + return ""; + } + }; + + template + struct message_traits >::type> + { + static const char* format() + { + return T::getFormat(); + } + }; +} + class MessageConsumerPort : public Port_Provides_base_impl #ifdef BEGIN_AUTOCOMPLETE_IGNORE , public virtual POA_ExtendedEvent::MessageEvent @@ -100,7 +138,8 @@ class MessageConsumerPort : public Port_Provides_base_impl template void registerMessage (const std::string& id, Class* target, void (Class::*func)(const std::string&, const MessageStruct&)) { - callbacks_[id] = new MessageCallback(boost::bind(func, target, _1, _2)); + const char* format = ::internal::message_traits::format(); + callbacks_[id] = new MessageCallback(format, boost::bind(func, target, _1, _2)); } template @@ -134,7 +173,7 @@ class MessageConsumerPort : public Port_Provides_base_impl protected: friend class MessageSupplierPort; - bool pushLocal (const std::string& id, const void* data); + bool pushLocal (const std::string& id, const char* format, const void* data); void addSupplier (const std::string& connectionId, CosEventComm::PushSupplier_ptr supplier); @@ -155,6 +194,26 @@ class MessageConsumerPort : public Port_Provides_base_impl virtual void dispatch (const std::string& value, const CORBA::Any& data) = 0; virtual void dispatch (const std::string& value, const void* data) = 0; virtual ~MessageCallbackBase () { } + + bool isCompatible (const char* format) + { + if (_format.empty()) { + // Message type has no format descriptor, assume that it cannot + // be passed via void* + return false; + } + // The format descriptors must be identical, otherwise go through + // CORBA::Any + return _format == format; + } + + protected: + MessageCallbackBase(const std::string& format) : + _format(format) + { + } + + const std::string _format; }; @@ -167,7 +226,8 @@ class MessageConsumerPort : public Port_Provides_base_impl public: typedef boost::function CallbackFunc;; - MessageCallback (CallbackFunc func) : + MessageCallback (const std::string& format, CallbackFunc func) : + MessageCallbackBase(format), func_(func) { } @@ -255,7 +315,8 @@ class MessageSupplierPort : public Port_Uses_base_impl // Workaround for older components whose structs have a non-const, // non-static member function getId(): const_cast the value const std::string messageId = const_cast(message).getId(); - _queueMessage(messageId, &message, &MessageSupplierPort::_serializeMessage); + const char* format = ::internal::message_traits::format(); + _queueMessage(messageId, format, &message, &MessageSupplierPort::_serializeMessage); } template @@ -267,7 +328,7 @@ class MessageSupplierPort : public Port_Uses_base_impl typedef boost::function SerializerFunc; void _beginMessageQueue(size_t count); - void _queueMessage(const std::string& msgId, const void* msgData, SerializerFunc serializer); + void _queueMessage(const std::string& msgId, const char* format, const void* msgData, SerializerFunc serializer); void _sendMessageQueue(); class MessageTransport; From 2257b5dd0416b0bd8aca91f680d06309ec1b144b Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 21 Jul 2016 11:38:28 -0400 Subject: [PATCH 0422/1644] Negotiate whether local message connections can use direct dispatch (via void*) once by checking the format string the first time through, instead of checking the format on every push. This gives back the roughly 20% message throughput (1.4m messages/sec to 1.6m on my machine) that adding the format checking cost. --- .../src/base/framework/MessageInterface.cpp | 89 +++++++++++++++---- .../src/base/include/ossie/MessageInterface.h | 25 +++--- 2 files changed, 87 insertions(+), 27 deletions(-) diff --git a/redhawk/src/base/framework/MessageInterface.cpp b/redhawk/src/base/framework/MessageInterface.cpp index 34c73f7fa..d16fff285 100644 --- a/redhawk/src/base/framework/MessageInterface.cpp +++ b/redhawk/src/base/framework/MessageInterface.cpp @@ -144,9 +144,9 @@ CosEventComm::PushSupplier_ptr MessageConsumerPort::removeSupplier (const std::s }; void MessageConsumerPort::fireCallback (const std::string& id, const CORBA::Any& data) { - CallbackTable::iterator callback = callbacks_.find(id); - if (callback != callbacks_.end()) { - callback->second->dispatch(id, data); + MessageCallback* callback = getMessageCallback(id); + if (callback) { + callback->dispatch(id, data); } else { if (generic_callbacks_.empty()) { std::string warning = "no callbacks registered for messages with id: "+id+"."; @@ -157,8 +157,8 @@ void MessageConsumerPort::fireCallback (const std::string& id, const CORBA::Any& warning += " The only registered callback is for message with id: "+callbacks_.begin()->first; } else { warning += " The available message callbacks are for messages with any of the following id: "; - for (callback = callbacks_.begin();callback != callbacks_.end(); callback++) { - warning += callback->first+" "; + for (CallbackTable::iterator cb = callbacks_.begin(); cb != callbacks_.end(); ++cb) { + warning += cb->first+" "; } } LOG_WARN(MessageConsumerPort,warning); @@ -166,16 +166,26 @@ void MessageConsumerPort::fireCallback (const std::string& id, const CORBA::Any& } // Invoke the callback for those messages that are generic - generic_callbacks_(id, data); + dispatchGeneric(id, data); }; -bool MessageConsumerPort::pushLocal (const std::string& id, const char* format, const void* data) { +MessageConsumerPort::MessageCallback* MessageConsumerPort::getMessageCallback(const std::string& id) +{ CallbackTable::iterator callback = callbacks_.find(id); - if (callback != callbacks_.end() && callback->second->isCompatible(format)) { - callback->second->dispatch(id, data); - return true; + if (callback != callbacks_.end()) { + return callback->second; } - return false; + return 0; +} + +bool MessageConsumerPort::hasGenericCallbacks() +{ + return !generic_callbacks_.empty(); +} + +void MessageConsumerPort::dispatchGeneric(const std::string& id, const CORBA::Any& data) +{ + generic_callbacks_(id, data); } std::string MessageConsumerPort::getRepid() const @@ -292,13 +302,29 @@ class MessageSupplierPort::LocalTransport : public MessageSupplierPort::MessageT void queueMessage(const std::string& msgId, const char* format, const void* msgData, MessageSupplierPort::SerializerFunc serializer) { - if (_consumer->pushLocal(msgId, format, msgData)) { - return; + CallbackEntry* entry = getCallback(msgId, format); + if (entry) { + // There is a message-specific callback registered; use direct + // dispatch if available, otherwise fall back to CORBA Any + if (entry->direct) { + entry->callback->dispatch(msgId, msgData); + } else { + CORBA::Any data; + serializer(data, msgData); + entry->callback->dispatch(msgId, data); + } } - CORBA::Any data; - serializer(data, msgData); - _consumer->fireCallback(msgId, data); + // If the receiver has any generic callbacks registered, serialize the + // message to a CORBA Any (which, technically speaking, may have also + // been done above if the message format differed) and send it along. + // By serializing only when it's required, the best case of direct + // message dispatch runs significantly faster. + if (_consumer->hasGenericCallbacks()) { + CORBA::Any data; + serializer(data, msgData); + _consumer->dispatchGeneric(msgId, data); + } } void sendMessages() @@ -310,7 +336,38 @@ class MessageSupplierPort::LocalTransport : public MessageSupplierPort::MessageT } private: + struct CallbackEntry { + MessageConsumerPort::MessageCallback* callback; + bool direct; + }; + + typedef std::map CallbackTable; + + CallbackEntry* getCallback(const std::string& msgId, const char* format) + { + CallbackTable::iterator callback = _callbacks.find(msgId); + if (callback != _callbacks.end()) { + // The callback has already been found and negotiated + return &(callback->second); + } + + // No callback has been found yet; ask the consumer for its callback, + // and if it has one, negotiate whether we can use direct dispatch via + // void* + CallbackEntry entry; + entry.callback = _consumer->getMessageCallback(msgId); + if (entry.callback) { + entry.direct = entry.callback->isCompatible(format); + callback = _callbacks.insert(std::make_pair(msgId, entry)).first; + return &(callback->second); + } + + // There is no callback registered for the given message + return 0; + } + MessageConsumerPort* _consumer; + CallbackTable _callbacks; }; MessageSupplierPort::MessageSupplierPort (std::string port_name) : diff --git a/redhawk/src/base/include/ossie/MessageInterface.h b/redhawk/src/base/include/ossie/MessageInterface.h index 3379bcad3..dbf80b348 100644 --- a/redhawk/src/base/include/ossie/MessageInterface.h +++ b/redhawk/src/base/include/ossie/MessageInterface.h @@ -139,7 +139,7 @@ class MessageConsumerPort : public Port_Provides_base_impl void registerMessage (const std::string& id, Class* target, void (Class::*func)(const std::string&, const MessageStruct&)) { const char* format = ::internal::message_traits::format(); - callbacks_[id] = new MessageCallback(format, boost::bind(func, target, _1, _2)); + callbacks_[id] = new MessageCallbackImpl(format, boost::bind(func, target, _1, _2)); } template @@ -173,11 +173,12 @@ class MessageConsumerPort : public Port_Provides_base_impl protected: friend class MessageSupplierPort; - bool pushLocal (const std::string& id, const char* format, const void* data); - void addSupplier (const std::string& connectionId, CosEventComm::PushSupplier_ptr supplier); CosEventComm::PushSupplier_ptr removeSupplier (const std::string& connectionId); + + bool hasGenericCallbacks(); + void dispatchGeneric(const std::string& id, const CORBA::Any& data); boost::mutex portInterfaceAccess; std::map consumers; @@ -188,12 +189,12 @@ class MessageConsumerPort : public Port_Provides_base_impl /* * Abstract untyped interface for message callbacks. */ - class MessageCallbackBase + class MessageCallback { public: virtual void dispatch (const std::string& value, const CORBA::Any& data) = 0; virtual void dispatch (const std::string& value, const void* data) = 0; - virtual ~MessageCallbackBase () { } + virtual ~MessageCallback () { } bool isCompatible (const char* format) { @@ -208,7 +209,7 @@ class MessageConsumerPort : public Port_Provides_base_impl } protected: - MessageCallbackBase(const std::string& format) : + MessageCallback(const std::string& format) : _format(format) { } @@ -221,13 +222,13 @@ class MessageConsumerPort : public Port_Provides_base_impl * Concrete typed class for message callbacks. */ template - class MessageCallback : public MessageCallbackBase + class MessageCallbackImpl : public MessageCallback { public: - typedef boost::function CallbackFunc;; + typedef boost::function CallbackFunc; - MessageCallback (const std::string& format, CallbackFunc func) : - MessageCallbackBase(format), + MessageCallbackImpl (const std::string& format, CallbackFunc func) : + MessageCallback(format), func_(func) { } @@ -250,9 +251,11 @@ class MessageConsumerPort : public Port_Provides_base_impl CallbackFunc func_; }; - typedef std::map CallbackTable; + typedef std::map CallbackTable; CallbackTable callbacks_; + MessageCallback* getMessageCallback(const std::string& msgId); + ossie::notification generic_callbacks_; typedef std::map SupplierTable; From fa6b2fc5e2237725e26316206b6254ce5b5d89d1 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 21 Jul 2016 12:34:54 -0400 Subject: [PATCH 0423/1644] CF-1505 Implement QueryablePort for C++ MessageSupplierPort --- .../src/base/framework/MessageInterface.cpp | 18 ++++++++++++++++++ .../src/base/include/ossie/MessageInterface.h | 6 +++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/redhawk/src/base/framework/MessageInterface.cpp b/redhawk/src/base/framework/MessageInterface.cpp index d16fff285..9187202c9 100644 --- a/redhawk/src/base/framework/MessageInterface.cpp +++ b/redhawk/src/base/framework/MessageInterface.cpp @@ -215,6 +215,11 @@ class MessageSupplierPort::MessageTransport virtual void disconnect() = 0; + CosEventChannelAdmin::EventChannel_ptr objref() + { + return CosEventChannelAdmin::EventChannel::_narrow(_channel); + } + private: CosEventChannelAdmin::EventChannel_var _channel; }; @@ -411,6 +416,19 @@ void MessageSupplierPort::disconnectPort(const char* connectionId) _connections.erase(connection); } +ExtendedCF::UsesConnectionSequence* MessageSupplierPort::connections() +{ + ExtendedCF::UsesConnectionSequence_var result = new ExtendedCF::UsesConnectionSequence(); + boost::mutex::scoped_lock lock(portInterfaceAccess); + result->length(_connections.size()); + CORBA::ULong index = 0; + for (TransportMap::iterator connection = _connections.begin(); connection != _connections.end(); ++connection) { + result[index].connectionId = connection->first.c_str(); + result[index].port = connection->second->objref(); + } + return result._retn(); +} + void MessageSupplierPort::push(const CORBA::Any& data) { boost::mutex::scoped_lock lock(portInterfaceAccess); diff --git a/redhawk/src/base/include/ossie/MessageInterface.h b/redhawk/src/base/include/ossie/MessageInterface.h index dbf80b348..1682feea4 100644 --- a/redhawk/src/base/include/ossie/MessageInterface.h +++ b/redhawk/src/base/include/ossie/MessageInterface.h @@ -29,6 +29,7 @@ #include #include "CF/ExtendedEvent.h" +#include "CF/QueryablePort.h" #include "CF/cf.h" #include "CorbaUtils.h" #include "Port_impl.h" @@ -269,7 +270,7 @@ class MessageConsumerPort : public Port_Provides_base_impl class MessageSupplierPort : public Port_Uses_base_impl #ifdef BEGIN_AUTOCOMPLETE_IGNORE -, public virtual POA_CF::Port +, public virtual POA_ExtendedCF::QueryablePort #endif { @@ -281,6 +282,9 @@ class MessageSupplierPort : public Port_Uses_base_impl void connectPort(CORBA::Object_ptr connection, const char* connectionId); void disconnectPort(const char* connectionId); + // ExtendedCF::QueryablePort methods + ExtendedCF::UsesConnectionSequence* connections(); + void push(const CORBA::Any& data); // Send a single message From ebbd5d91e554751c027836c30b697e51966973c2 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 21 Jul 2016 13:38:26 -0400 Subject: [PATCH 0424/1644] Use mutex from C++ base uses port --- redhawk/src/base/framework/MessageInterface.cpp | 8 ++++---- redhawk/src/base/include/ossie/MessageInterface.h | 5 +---- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/redhawk/src/base/framework/MessageInterface.cpp b/redhawk/src/base/framework/MessageInterface.cpp index 9187202c9..492621fea 100644 --- a/redhawk/src/base/framework/MessageInterface.cpp +++ b/redhawk/src/base/framework/MessageInterface.cpp @@ -392,7 +392,7 @@ void MessageSupplierPort::connectPort(CORBA::Object_ptr connection, const char* } { - boost::mutex::scoped_lock lock(portInterfaceAccess); + boost::mutex::scoped_lock lock(updatingPortsLock); MessageTransport* transport; MessageConsumerPort* local_port = ossie::corba::getLocalServant(channel); if (local_port) { @@ -406,7 +406,7 @@ void MessageSupplierPort::connectPort(CORBA::Object_ptr connection, const char* void MessageSupplierPort::disconnectPort(const char* connectionId) { - boost::mutex::scoped_lock lock(portInterfaceAccess); + boost::mutex::scoped_lock lock(updatingPortsLock); TransportMap::iterator connection = _connections.find(connectionId); if (connection == _connections.end()) { return; @@ -419,7 +419,7 @@ void MessageSupplierPort::disconnectPort(const char* connectionId) ExtendedCF::UsesConnectionSequence* MessageSupplierPort::connections() { ExtendedCF::UsesConnectionSequence_var result = new ExtendedCF::UsesConnectionSequence(); - boost::mutex::scoped_lock lock(portInterfaceAccess); + boost::mutex::scoped_lock lock(updatingPortsLock); result->length(_connections.size()); CORBA::ULong index = 0; for (TransportMap::iterator connection = _connections.begin(); connection != _connections.end(); ++connection) { @@ -431,7 +431,7 @@ ExtendedCF::UsesConnectionSequence* MessageSupplierPort::connections() void MessageSupplierPort::push(const CORBA::Any& data) { - boost::mutex::scoped_lock lock(portInterfaceAccess); + boost::mutex::scoped_lock lock(updatingPortsLock); for (TransportMap::iterator connection = _connections.begin(); connection != _connections.end(); ++connection) { try { connection->second->push(data); diff --git a/redhawk/src/base/include/ossie/MessageInterface.h b/redhawk/src/base/include/ossie/MessageInterface.h index 1682feea4..327be0231 100644 --- a/redhawk/src/base/include/ossie/MessageInterface.h +++ b/redhawk/src/base/include/ossie/MessageInterface.h @@ -305,7 +305,7 @@ class MessageSupplierPort : public Port_Uses_base_impl template void sendMessages(Iterator first, Iterator last) { - boost::mutex::scoped_lock lock(portInterfaceAccess); + boost::mutex::scoped_lock lock(updatingPortsLock); _beginMessageQueue(std::distance(first, last)); for (; first != last; ++first) { _queueMessage(*first); @@ -343,9 +343,6 @@ class MessageSupplierPort : public Port_Uses_base_impl class LocalTransport; typedef std::map TransportMap; TransportMap _connections; - - boost::mutex portInterfaceAccess; - }; #endif // MESSAGEINTERFACE_H From e3167b2855f331b9a06116920a67c3bfb8626152 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 21 Jul 2016 16:03:36 -0400 Subject: [PATCH 0425/1644] Fix some memory leaks in C++ message ports --- .../src/base/framework/MessageInterface.cpp | 37 +++++++++++++++++-- .../src/base/include/ossie/MessageInterface.h | 2 +- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/redhawk/src/base/framework/MessageInterface.cpp b/redhawk/src/base/framework/MessageInterface.cpp index 492621fea..e909f7c9c 100644 --- a/redhawk/src/base/framework/MessageInterface.cpp +++ b/redhawk/src/base/framework/MessageInterface.cpp @@ -69,11 +69,28 @@ CosEventChannelAdmin::ProxyPullConsumer_ptr SupplierAdmin_i::obtain_pull_consume return CosEventChannelAdmin::ProxyPullConsumer::_nil(); }; -MessageConsumerPort::MessageConsumerPort(std::string port_name) : Port_Provides_base_impl(port_name) { - supplier_admin = new SupplierAdmin_i(this); +MessageConsumerPort::MessageConsumerPort(std::string port_name) : + Port_Provides_base_impl(port_name), + supplier_admin(0) +{ +} + +MessageConsumerPort::~MessageConsumerPort() +{ + // If a SupplierAdmin was created, deactivate and delete it + if (supplier_admin) { + PortableServer::POA_var poa = supplier_admin->_default_POA(); + PortableServer::ObjectId_var oid = poa->servant_to_id(supplier_admin); + poa->deactivate_object(oid); + supplier_admin->_remove_ref(); + } + + for (CallbackTable::iterator callback = callbacks_.begin(); callback != callbacks_.end(); ++callback) { + delete callback->second; + } } - // CF::Port methods +// CF::Port methods void MessageConsumerPort::connectPort(CORBA::Object_ptr connection, const char* connectionId) { CosEventChannelAdmin::EventChannel_var channel = ossie::corba::_narrowSafe(connection); if (CORBA::is_nil(channel)) { @@ -101,6 +118,12 @@ CosEventChannelAdmin::ConsumerAdmin_ptr MessageConsumerPort::for_consumers() { }; CosEventChannelAdmin::SupplierAdmin_ptr MessageConsumerPort::for_suppliers() { + boost::mutex::scoped_lock lock(portInterfaceAccess); + if (!supplier_admin) { + supplier_admin = new SupplierAdmin_i(this); + PortableServer::POA_var poa = supplier_admin->_default_POA(); + PortableServer::ObjectId_var oid = poa->activate_object(supplier_admin); + } return supplier_admin->_this(); }; @@ -207,6 +230,10 @@ class MessageSupplierPort::MessageTransport { } + virtual ~MessageTransport() + { + } + virtual void push(const CORBA::Any& data) = 0; virtual void beginQueue(size_t count) = 0; @@ -382,6 +409,9 @@ MessageSupplierPort::MessageSupplierPort (std::string port_name) : MessageSupplierPort::~MessageSupplierPort (void) { + for (TransportMap::iterator connection = _connections.begin(); connection != _connections.end(); ++connection) { + delete connection->second; + } } void MessageSupplierPort::connectPort(CORBA::Object_ptr connection, const char* connectionId) @@ -425,6 +455,7 @@ ExtendedCF::UsesConnectionSequence* MessageSupplierPort::connections() for (TransportMap::iterator connection = _connections.begin(); connection != _connections.end(); ++connection) { result[index].connectionId = connection->first.c_str(); result[index].port = connection->second->objref(); + ++index; } return result._retn(); } diff --git a/redhawk/src/base/include/ossie/MessageInterface.h b/redhawk/src/base/include/ossie/MessageInterface.h index 327be0231..2c0a31bb8 100644 --- a/redhawk/src/base/include/ossie/MessageInterface.h +++ b/redhawk/src/base/include/ossie/MessageInterface.h @@ -128,7 +128,7 @@ class MessageConsumerPort : public Port_Provides_base_impl public: MessageConsumerPort (std::string port_name); - virtual ~MessageConsumerPort (void) { }; + virtual ~MessageConsumerPort (void); /* * Register a callback function From afa82d65ae7369ddd2a06cb6528b2c2f9c048073 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 22 Jul 2016 13:45:13 -0400 Subject: [PATCH 0426/1644] Add a "shared" flag to sandbox launch to enable forcing components into separate ComponentHost instances --- .../python/ossie/utils/sandbox/base.py | 4 ++-- .../python/ossie/utils/sandbox/ide.py | 3 ++- .../python/ossie/utils/sandbox/local.py | 24 ++++++++++++------- .../python/ossie/utils/sb/domainless.py | 7 ++++-- 4 files changed, 24 insertions(+), 14 deletions(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/base.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/base.py index a300b1829..fdd415d7e 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/base.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/base.py @@ -215,7 +215,7 @@ def reset(self): def launch(self, descriptor, instanceName=None, refid=None, impl=None, debugger=None, window=None, properties={}, configure=True, - initialize=True, timeout=None, objType=None): + initialize=True, timeout=None, objType=None, shared=True): sdrRoot = self.getSdrRoot() # Parse the component XML profile. @@ -257,7 +257,7 @@ def launch(self, descriptor, instanceName=None, refid=None, impl=None, # Determine the class for the component type and create a new instance. comp = clazz(self, profile, spd, scd, prf, instanceName, refid, impl) - launcher = self._createLauncher(comptype, execparams, initProps, initialize, configProps, debugger, window, timeout) + launcher = self._createLauncher(comptype, execparams, initProps, initialize, configProps, debugger, window, timeout, shared) if not launcher: raise NotImplementedError("No support for component type '%s'" % comptype) comp._launcher = launcher diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/ide.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/ide.py index 5fe474af2..30193387b 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/ide.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/ide.py @@ -149,7 +149,8 @@ def _checkInstanceId(self, refid, componentType='resource'): # "valid" return True - def _createLauncher(self, comptype, execparams, initProps, initialize, configProps, debugger, window, timeout): + def _createLauncher(self, comptype, execparams, initProps, initialize, configProps, debugger, + window, timeout, shared): if comptype in ('resource', 'device', 'loadabledevice', 'executabledevice'): return IDELauncher(execparams, initProps, configProps) return None diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py index eefbef160..682751c45 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py @@ -119,7 +119,7 @@ def findProfile(self, descriptor, objType=None): class LocalLauncher(SandboxLauncher): - def __init__(self, execparams, initProps, initialize, configProps, debugger, window, timeout): + def __init__(self, execparams, initProps, initialize, configProps, debugger, window, timeout, shared): self._execparams = execparams self._debugger = debugger self._window = window @@ -127,6 +127,7 @@ def __init__(self, execparams, initProps, initialize, configProps, debugger, win self._initialize = initialize self._configProps = configProps self._timeout = timeout + self._shared = shared def _getImplementation(self, spd, identifier): for implementation in spd.get_implementation(): @@ -219,7 +220,10 @@ def launch(self, comp): # component host entry_point = sdrroot.relativePath(comp._profile, impl.get_code().get_entrypoint()) if impl.get_code().get_type() == 'SharedLibrary': - container = comp._sandbox._getComponentHost() + if self._shared: + container = comp._sandbox._getComponentHost() + else: + container = comp._sandbox._launchComponentHost(comp._instanceName) container.executeLinked(entry_point, [], execparams, deps) process = container._process else: @@ -265,7 +269,7 @@ def terminate_callback(pid, status): process.addChild(debug_process) # Store the process on the component proxy. - if impl.get_code().get_type() == 'SharedLibrary': + if impl.get_code().get_type() == 'SharedLibrary' and self._shared: comp._process = None else: comp._process = process @@ -420,11 +424,12 @@ def _getComponentHost(self): self.__container = self._launchComponentHost() return self.__container - def _launchComponentHost(self): + def _launchComponentHost(self, instanceName=None): # Directly create the sandbox object instead of going through launch() profile = self._sdrroot.domPath('/mgr/rh/ComponentHost/ComponentHost.spd.xml') spd, scd, prf = self._sdrroot.readProfile(profile) - instanceName = self._createInstanceName('ComponentHost', 'resource') + if instanceName is None: + instanceName = self._createInstanceName('ComponentHost', 'resource') refid = str(uuid4()) comp = ComponentHost(self, profile, spd, scd, prf, instanceName, refid, None) @@ -433,7 +438,7 @@ def _launchComponentHost(self): # root of the local filesystem; all component paths provided to the # component host will be absolute. execparams = {'RH::DEPLOYMENT_ROOT':'/'} - comp._launcher = LocalComponentLauncher(execparams, {}, True, {}, None, None, None) + comp._launcher = LocalComponentLauncher(execparams, {}, True, {}, None, None, None, False) comp._kick() return comp @@ -466,16 +471,17 @@ def _checkInstanceId(self, refid, componentType): return False return True - def _createLauncher(self, comptype, execparams, initProps, initialize, configProps, debugger, window, timeout): + def _createLauncher(self, comptype, execparams, initProps, initialize, configProps, debugger, + window, timeout, shared): if comptype == 'resource': clazz = LocalComponentLauncher elif comptype in ('device', 'loadabledevice', 'executabledevice'): clazz = LocalDeviceLauncher elif comptype == 'service': - clazz = LocalServiceLauncher + clazz = LocalServiceLauncher else: return None - return clazz(execparams, initProps, initialize, configProps, debugger, window, timeout) + return clazz(execparams, initProps, initialize, configProps, debugger, window, timeout, shared) def getComponents(self): return self.__components.values() diff --git a/redhawk/src/base/framework/python/ossie/utils/sb/domainless.py b/redhawk/src/base/framework/python/ossie/utils/sb/domainless.py index 0628024f3..d4509dc40 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sb/domainless.py +++ b/redhawk/src/base/framework/python/ossie/utils/sb/domainless.py @@ -1136,7 +1136,8 @@ def release(): def launch(descriptor, instanceName=None, refid=None, impl=None, debugger=None, window=None, execparams={}, configure=True, - initialize=True, timeout=None, objType=None, properties={}): + initialize=True, timeout=None, objType=None, properties={}, + shared=True): """ Execute a softpkg, returning a proxy object. This is a factory function that may return a component, device or service depending on the SPD. @@ -1179,6 +1180,8 @@ def launch(descriptor, instanceName=None, refid=None, impl=None, objType - The type that you would like to launch. Options are component, device, or service. If not given, all types will be searched for with the descriptor given. + shared - Launch this component into a shared address space, if + possible. Deprecated arguments: execparams - Execparams to override on component execution. All property @@ -1202,7 +1205,7 @@ def launch(descriptor, instanceName=None, refid=None, impl=None, return _getSandbox().launch(descriptor=descriptor, instanceName=instanceName, refid=refid, impl=impl, debugger=debugger, window=window, properties=properties, initialize=initialize, configure=configure, timeout=timeout, - objType=objType) + objType=objType, shared=shared) def createEventChannel(name, exclusive=False): """ From 878f65897c8a2e235060e2778aac8c912fe6393d Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 25 Jul 2016 10:26:47 -0400 Subject: [PATCH 0427/1644] Add a trim method to shared buffer classes, and redefine slice in terms of trim --- .../src/base/include/ossie/shared_buffer.h | 31 ++++++++++--------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/redhawk/src/base/include/ossie/shared_buffer.h b/redhawk/src/base/include/ossie/shared_buffer.h index c36b0f74d..6a6ad7afa 100644 --- a/redhawk/src/base/include/ossie/shared_buffer.h +++ b/redhawk/src/base/include/ossie/shared_buffer.h @@ -219,10 +219,24 @@ namespace redhawk { shared_buffer slice(size_t start, size_t end=size_t(-1)) const { shared_buffer result(*this); - this->_M_slice(result, start, end); + result.trim(start, end); return result; } + /** + * @brief Adjusts the start and end indices of this %shared_buffer. + * @param start Index of first element. + * @param end Index of last element, exclusive (default end). + */ + void trim(size_t start, size_t end=size_t(-1)) + { + if (end == (size_t)-1) { + end = this->size(); + } + this->_M_start += start; + this->_M_finish = this->_M_start + end - start; + } + /** * @brief Returns a copy of this %shared_buffer. * @@ -333,17 +347,6 @@ namespace redhawk { std::swap(this->_M_finish, other._M_finish); } - // Adjusts the start and end pointers of a shared_buffer to a the given - // slice indices. - void _M_slice(shared_buffer& result, size_t start, size_t end) const - { - if (end == (size_t)-1) { - end = result.size(); - } - result._M_start += start; - result._M_finish = result._M_start + end - start; - } - // Internal implementation of copy. Copies the contents of this buffer // into another, pre-existing buffer. void _M_copy(shared_buffer& dest) const @@ -473,7 +476,7 @@ namespace redhawk { * @param size Number of elements. * @param deleter Callable object. * - * @a D must by copy-constructible. When the last %buffer pointing to + * @a D must be copy-constructible. When the last %buffer pointing to * @a data is destroyed, @a deleter will be called on @a data. This can * be used to define custom release behavior. */ @@ -599,7 +602,7 @@ namespace redhawk { buffer slice(size_t start, size_t end=size_t(-1)) { buffer result(*this); - this->_M_slice(result, start, end); + result.trim(start, end); return result; } From e9f8ec4d3f49721ea0edcc43825d16c77b7d1b07 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 25 Jul 2016 10:38:58 -0400 Subject: [PATCH 0428/1644] Add operator== support for shared buffers --- .../src/base/include/ossie/shared_buffer.h | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/redhawk/src/base/include/ossie/shared_buffer.h b/redhawk/src/base/include/ossie/shared_buffer.h index 6a6ad7afa..75dbecd24 100644 --- a/redhawk/src/base/include/ossie/shared_buffer.h +++ b/redhawk/src/base/include/ossie/shared_buffer.h @@ -670,6 +670,28 @@ namespace redhawk { /// @endcond }; + /** + * @brief Buffer equality comparison. + * @param lhs A %shared_buffer. + * @param rhs A %shared_buffer of the same type as @a lhs. + * @return True iff the size and elements of the shared_buffers are equal. + */ + template + inline bool operator==(const shared_buffer& lhs, const shared_buffer& rhs) + { + if (lhs.size() != rhs.size()) { + // Different sizes always compare unequal + return false; + } else if (lhs.data() == rhs.data()) { + // If the data pointer is the same (the size is already known to be + // the same), no further comparison is required + return true; + } else { + // Perform element-wise comparison + return std::equal(lhs.begin(), lhs.end(), rhs.begin()); + } + } + } // namespace redhawk #endif // REDHAWK_SHARED_BUFFER_H From 52d2faecf619efae368e6998c7342354b203879d Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 26 Jul 2016 10:06:55 -0400 Subject: [PATCH 0429/1644] Log the error from ComponentHost when loading the module entry point fails so that the caller can debug the problem --- redhawk/src/control/sdr/ComponentHost/ComponentHost.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/redhawk/src/control/sdr/ComponentHost/ComponentHost.cpp b/redhawk/src/control/sdr/ComponentHost/ComponentHost.cpp index f75b8088f..06fa74a5c 100644 --- a/redhawk/src/control/sdr/ComponentHost/ComponentHost.cpp +++ b/redhawk/src/control/sdr/ComponentHost/ComponentHost.cpp @@ -163,6 +163,7 @@ CF::ExecutableDevice::ProcessID_Type ComponentHost::executeLinked(const char* na LOG_DEBUG(ComponentHost, "Resolving module entry point"); make_component = reinterpret_cast(module->symbol("make_component")); } catch (const std::exception& exc) { + LOG_ERROR(ComponentHost, "Unable to load module entry point: " << exc.what()) make_component = 0; } if (!make_component) { From 0ca0c6d59aea38375c53ecffcb71998479b68295 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 27 Jul 2016 08:30:57 -0400 Subject: [PATCH 0430/1644] Add convenience wrappers for creating buffers from a pointer, size and optional deleter that deduce the return type from the arguments (cf. std::make_pair) --- .../src/base/include/ossie/shared_buffer.h | 31 +++++++++++++++++-- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/redhawk/src/base/include/ossie/shared_buffer.h b/redhawk/src/base/include/ossie/shared_buffer.h index 75dbecd24..29963ff8a 100644 --- a/redhawk/src/base/include/ossie/shared_buffer.h +++ b/redhawk/src/base/include/ossie/shared_buffer.h @@ -293,9 +293,9 @@ namespace redhawk { * @param data Pointer to first element. * @param size Number of elements. * - * Adapts externally aquired memory work with the %shared_buffer API; - * however, additional care must be taken to ensure that the data is - * copied if it needs to be held past the lifetime of the call. + * Adapts externally aquired memory to work with the %shared_buffer + * API; however, additional care must be taken to ensure that the data + * is copied if it needs to be held past the lifetime of the call. */ static shared_buffer make_transient(const value_type* data, size_t size) { @@ -692,6 +692,31 @@ namespace redhawk { } } + /** + * @brief A convenience wrapper for creating a buffer. + * @param data Pointer to first element. + * @param size Number of elements. + * @return A newly-constructed buffer<> of the appropriate type. + */ + template + inline redhawk::buffer make_buffer(T* data, size_t size) + { + return redhawk::buffer(data, size); + } + + /** + * @brief A convenience wrapper for creating a buffer with a custom deleter. + * @param data Pointer to first element. + * @param size Number of elements. + * @param deleter Callable object. + * @return A newly-constructed buffer<> of the appropriate type. + */ + template + inline redhawk::buffer make_buffer(T* data, size_t size, D deleter) + { + return redhawk::buffer(data, size, deleter); + } + } // namespace redhawk #endif // REDHAWK_SHARED_BUFFER_H From c6f024faf729a7cc6f39970f4f8243d5363491a2 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 3 Aug 2016 16:36:35 -0400 Subject: [PATCH 0431/1644] Rename the application's component host(s) to match to soft package name, and use the device label instead of the identifier --- redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp b/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp index 7083c5aa2..4e6a784d8 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp @@ -130,13 +130,13 @@ ContainerDeployment* ApplicationDeployment::createContainer(redhawk::ProfileCach const ossie::SoftPkg* softpkg = cache.loadSoftPkg("/mgr/rh/ComponentHost/ComponentHost.spd.xml"); // Create an instantiation with the ID and naming service name based on the - // device identifier; the deployment will own this object + // device label; the deployment will own this object ossie::ComponentInstantiation* instantiation = new ossie::ComponentInstantiation; - instantiation->instantiationId = "Container_" + device->identifier; + instantiation->instantiationId = "ComponentHost_" + device->label; instantiation->namingservicename = instantiation->instantiationId; // Use the same pattern as components to generate the unique runtime ID - LOG_DEBUG(ApplicationDeployment, "Creating container " << instantiation->getID()); + LOG_DEBUG(ApplicationDeployment, "Creating component host " << instantiation->getID()); std::string container_id = instantiation->getID() + ":" + instanceName; container = new ContainerDeployment(softpkg, instantiation, container_id); From e1f1b041de08a3d6de1112943e658a059204b396 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 4 Aug 2016 10:13:42 -0400 Subject: [PATCH 0432/1644] Add iterator-based trim for shared buffers --- redhawk/src/base/include/ossie/shared_buffer.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/redhawk/src/base/include/ossie/shared_buffer.h b/redhawk/src/base/include/ossie/shared_buffer.h index 29963ff8a..081e985ce 100644 --- a/redhawk/src/base/include/ossie/shared_buffer.h +++ b/redhawk/src/base/include/ossie/shared_buffer.h @@ -237,6 +237,17 @@ namespace redhawk { this->_M_finish = this->_M_start + end - start; } + /** + * @brief Adjusts the beginning and end of this %shared_buffer. + * @param start Iterator to first element. + * @param end Iterator to last element, exclusive (default end). + */ + void trim(iterator first, iterator last=end()) + { + this->_M_start = const_cast(first); + this->_M_finish = const_cast(last); + } + /** * @brief Returns a copy of this %shared_buffer. * From ae08b4bb0a0c1ef80c08250258adefa366fce927 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 5 Aug 2016 15:22:07 -0400 Subject: [PATCH 0433/1644] Add development-time, preprocessor-controlled feature to shared buffers that allows individual compilation units to enable additional checking on access, iterators and allocation/deallocation --- redhawk/src/base/include/ossie/Makefile.am | 4 +- .../include/ossie/debug/checked_allocator.h | 137 +++++++ .../include/ossie/debug/checked_iterator.h | 387 ++++++++++++++++++ .../src/base/include/ossie/shared_buffer.h | 108 ++++- 4 files changed, 626 insertions(+), 10 deletions(-) create mode 100644 redhawk/src/base/include/ossie/debug/checked_allocator.h create mode 100644 redhawk/src/base/include/ossie/debug/checked_iterator.h diff --git a/redhawk/src/base/include/ossie/Makefile.am b/redhawk/src/base/include/ossie/Makefile.am index 3da135258..24398c7e3 100644 --- a/redhawk/src/base/include/ossie/Makefile.am +++ b/redhawk/src/base/include/ossie/Makefile.am @@ -67,4 +67,6 @@ pkginclude_HEADERS = AggregateDevice_impl.h \ nobase_pkginclude_HEADERS = internal/equals.h \ logging/rh_logger.h \ logging/LogConfigUriResolver.h \ - logging/loghelpers.h + logging/loghelpers.h \ + debug/checked_allocator.h \ + debug/checked_iterator.h diff --git a/redhawk/src/base/include/ossie/debug/checked_allocator.h b/redhawk/src/base/include/ossie/debug/checked_allocator.h new file mode 100644 index 000000000..badf99e1b --- /dev/null +++ b/redhawk/src/base/include/ossie/debug/checked_allocator.h @@ -0,0 +1,137 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK core. + * + * REDHAWK core is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +#ifndef REDHAWK_DEBUG_CHECKED_ALLOCATOR_H +#define REDHAWK_DEBUG_CHECKED_ALLOCATOR_H + +#include +#include + +namespace redhawk { + + namespace debug { + + /** + * @brief Allocator that checks for buffer overruns and underruns. + * + * A custom allocator to perform additional checking for some classes + * of memory error. Upon allocation, padding is added on the front and + * back of the buffer and filled with a known pattern. When the memory + * is deallocated, the front and back pads are checked to ensure that + * they were not overwritten (or at least, are statistically unlikely + * to have been). If the pattern has been disturbed, the allocator + * aborts the program. + * + * This allocator is intended for development-time use only and should + * never be used in production systems. + */ + template + struct checked_allocator + { + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + typedef T* pointer; + typedef const T* const_pointer; + typedef T& reference; + typedef const T& const_reference; + typedef T value_type; + + template + struct rebind { + typedef checked_allocator other; + }; + + pointer allocate(size_type count, const void* = 0) + { + // Allocate enough total bytes to accomodate the requested number + // of elements plus the "magic number" pads on the front and back + size_type bytes = count * sizeof(T); + bytes += 2 * MAGIC_COUNT * sizeof(magic_type); + void* data = ::operator new(bytes); + + // Mark the front and back pads with the known pattern and adjust + // the returned pointer to just after the front pad + magic_type* front = static_cast(data); + T* result = _M_mark_block(front); + magic_type* back = _M_get_back(result, count); + _M_mark_block(back); + return result; + } + + void deallocate(pointer ptr, size_type count) + { + // Adjust the pointer to the start of the front pad, which was the + // beginning of the original allocation + magic_type* front = _M_get_front(ptr); + + // Check that neither the front or the back pad has been written to + assert(_M_is_unmodified(front)); + magic_type* back = _M_get_back(ptr, count); + assert(_M_is_unmodified(back)); + + ::operator delete(front); + } + + private: + // Use two 64-bit ints with a known pattern to mark the front and back + // pads; this maintains the original alignment up to 16 bytes + typedef int64_t magic_type; + static const magic_type MAGIC_NUMBER = 0xfeedfacedeadbeef; + static const size_t MAGIC_COUNT = 2; + + // Writes the known pattern to the given pad + T* _M_mark_block(magic_type* ptr) + { + for (size_t ii = 0; ii < MAGIC_COUNT; ++ii) { + *ptr++ = MAGIC_NUMBER; + } + return reinterpret_cast(ptr); + } + + // Recovers the front pad from a data pointer + magic_type* _M_get_front(T* ptr) + { + magic_type* result = reinterpret_cast(ptr); + return (result - MAGIC_COUNT); + } + + // Given data pointer and number of elements, returns the rear pad + magic_type* _M_get_back(T* ptr, size_t count) + { + return reinterpret_cast(ptr + count); + } + + // Checks whether the known patter in a pad has been disturbed + bool _M_is_unmodified(magic_type* ptr) + { + for (size_t ii = 0; ii < MAGIC_COUNT; ++ii) { + if (ptr[ii] != MAGIC_NUMBER) { + return false; + } + } + return true; + } + }; + + } // namespace debug + +} // namespace redhawk + +#endif // _CHECKED_ALLOCATOR_HH_ diff --git a/redhawk/src/base/include/ossie/debug/checked_iterator.h b/redhawk/src/base/include/ossie/debug/checked_iterator.h new file mode 100644 index 000000000..55bbc51fe --- /dev/null +++ b/redhawk/src/base/include/ossie/debug/checked_iterator.h @@ -0,0 +1,387 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK core. + * + * REDHAWK core is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +/** + * @file ossie/debug/checked_iterator.h + * + * Checked iterator classes for conditionally enabling additional run-time + * checking, and to an extent stricter compile-time checking. + * + * Inspired by GNU's C++ safe_iterator extensions, but limited in scope to + * avoid imposing any binary changes on the sequences. This allows users to + * selectively enable this feature in a compilation unit without affecting + * other code that may have been compiled with the feature disabled. + * + * Checked iterators are intended for development-time use only and should + * never be used in production systems. + */ + +#ifndef REDHAWK_DEBUG_CHECKED_ITERATOR_H +#define REDHAWK_DEBUG_CHECKED_ITERATOR_H + +#include + +namespace redhawk { + + namespace debug { + + /** + * @brief Base checked iterator wrapper. + * + * Aids in comparing const and non-const iterators, providing a common + * base class and a method to verify both point to the same sequence. + */ + template + class checked_iterator_base { + public: + + typedef Sequence sequence_type; + + /** + * @brief Checks if this iterator can be compared to another. + * @param other Iterator to compare against. + * @return true if the iterators can be compared. + * + * Checked iterators are considered comparable if they belong to + * the same sequence. + */ + bool _M_can_compare(const checked_iterator_base& other) const + { + return _M_sequence == other._M_sequence; + } + + protected: + checked_iterator_base(const sequence_type* sequence) : + _M_sequence(sequence) + { + } + + // Owning sequence + const sequence_type* _M_sequence; + }; + + /** + * @brief Checked iterator wrapper. + * + * Iterator wrapper class that performs runtime validity checks on the + * underlying iterator instance. + */ + template + class checked_iterator : public checked_iterator_base { + + typedef std::iterator_traits _Traits; + + public: + typedef Iterator iterator_type; + typedef Sequence sequence_type; + typedef typename _Traits::difference_type difference_type; + typedef typename _Traits::value_type value_type; + typedef typename _Traits::reference reference; + typedef typename _Traits::pointer pointer; + typedef typename _Traits::iterator_category iterator_category; + + /** + * @brief Create a %checked_iterator. + * @param current Underlying iterator. + * @param sequence Containing sequence. + */ + checked_iterator(iterator_type current, const sequence_type* sequence) : + checked_iterator_base(sequence), + _M_current(current) + { + } + + /** + * @brief Copy constructor from a mutable iterator to a constant + * iterator. + * + * If used in the opposite direction (copy from const to mutable), + * the initialization of _M_current will fail. This is intentional, + * and easier than conditionally disabling this overload. + */ + template + checked_iterator(const checked_iterator& other): + checked_iterator_base(other), + _M_current(other.base()) + { + } + + /** + * @brief Iterator dereference. + * @pre iterator is dereferenceable. + */ + reference operator*() const + { + assert(_M_can_dereference()); + return *_M_current; + } + + /** + * @brief Iterator dereference. + * @pre iterator is dereferenceable. + */ + pointer operator->() const + { + assert(_M_can_dereference()); + return &*_M_current; + } + + /** + * @brief Iterator pre-increment. + * @pre iterator is incrementable. + */ + checked_iterator operator++(int) + { + // Can't increment past the end + assert(!_M_is_end()); + checked_iterator tmp(*this); + ++_M_current; + return tmp; + } + + /** + * @brief Iterator post-increment. + * @pre iterator is incrementable. + */ + checked_iterator& operator++() + { + // Can't increment past the end + assert(!_M_is_end()); + ++_M_current; + return *this; + } + + /** + * @brief Iterator pre-decrement. + * @pre iterator is decrementable. + */ + checked_iterator operator--(int) + { + // Can't decrement past the first element + assert(!_M_is_begin()); + checked_iterator tmp(*this); + --_M_current; + return tmp; + } + + /** + * @brief Iterator post-decrement. + * @pre iterator is decrementable. + */ + checked_iterator& operator--() + { + // Can't decrement past the first element + assert(!_M_is_begin()); + --_M_current; + return *this; + } + + /** + * @brief Indexed iterator dereference. + * @param index Index of element to dereference. + * @pre iterator plus index does not exceed bounds of sequence. + */ + reference operator[](const difference_type& index) const + { + assert(_M_can_increment(index+1)); + return _M_current[index]; + } + + /** + * @brief Iterator in-place add. + * @param offset Number of elements to advance. + * @pre iterator plus offset does not go past the sequence's end(). + */ + checked_iterator& operator+=(const difference_type& offset) + { + assert(_M_can_increment(offset)); + _M_current += offset; + return *this; + } + + /** + * @brief Iterator add. + * @param offset Number of elements to advance. + * @return Iterator advanced by offset elements. + * @pre iterator plus offset does not go past the sequence's end(). + */ + checked_iterator operator+(const difference_type& offset) const + { + checked_iterator result(*this); + result += offset; + return result; + } + + /** + * @brief Iterator in-place subtract. + * @param offset Number of elements to reverse. + * @pre iterator minus offset does not go past the sequence's + * begin(). + */ + checked_iterator& operator-=(const difference_type& offset) + { + assert(_M_can_decrement(offset)); + _M_current -= offset; + return *this; + } + + /** + * @brief Iterator subtract. + * @param offset Number of elements to reverse. + * @return Iterator moved backwards by offset elements. + * @pre iterator minus offset does not go past the sequence's + * begin(). + */ + checked_iterator operator-(const difference_type& offset) const + { + checked_iterator result(*this); + result -= offset; + return result; + } + + /** + * @brief Return the underlying iterator. + */ + iterator_type base() const + { + return _M_current; + } + + /** + * @brief Conversion to underlying iterator type. + * + * Allows implicit conversions in expressions. + */ + operator iterator_type() const + { + return _M_current; + } + + private: + // Predicate to check if this iterator is at the beginning of the + // sequence + bool _M_is_begin() const + { + return *this == this->_M_sequence->begin(); + } + + // Predicate to check if this iterator is at the end of the + // sequence + bool _M_is_end() const + { + return *this == this->_M_sequence->end(); + } + + // Predicate to check if this iterator can be dereferenced (i.e., + // can use operator*); the only condition that is checked is that + // it is not at the end, under the assumption that it cannot be + // outside the range [begin, end), otherwise a prior check would + // have failed + bool _M_can_dereference() const + { + return !_M_is_end(); + } + + // Checks whether this iterator can be incremented by the given + // number of elements + bool _M_can_increment(int count) const + { + typedef typename Sequence::const_iterator const_iterator_type; + return std::distance(*this, this->_M_sequence->end()) >= count; + } + + // Checks whether this iterator can be decremented by the given + // number of elements + bool _M_can_decrement(int count) const + { + typedef typename Sequence::const_iterator const_iterator_type; + return std::distance(this->_M_sequence->begin(), this) >= count; + } + + // Underlying iterator value + iterator_type _M_current; + }; + + // The operators below are templatized for two iterator types instead + // of just one to support operations between const and non-const + // iterators. + + template + inline bool operator==(const checked_iterator& lhs, + const checked_iterator& rhs) + { + assert(lhs._M_can_compare(rhs)); + return lhs.base() == rhs.base(); + } + + template + inline bool operator!=(const checked_iterator& lhs, + const checked_iterator& rhs) + { + assert(lhs._M_can_compare(rhs)); + return lhs.base() != rhs.base(); + } + + template + inline bool operator<(const checked_iterator& lhs, + const checked_iterator& rhs) + { + assert(lhs._M_can_compare(rhs)); + return lhs.base() < rhs.base(); + } + + template + inline bool operator<=(const checked_iterator& lhs, + const checked_iterator& rhs) + { + assert(lhs._M_can_compare(rhs)); + return lhs.base() <= rhs.base(); + } + + template + inline bool operator>(const checked_iterator& lhs, + const checked_iterator& rhs) + { + assert(lhs._M_can_compare(rhs)); + return lhs.base() > rhs.base(); + } + + template + inline bool operator>=(const checked_iterator& lhs, + const checked_iterator& rhs) + { + assert(lhs._M_can_compare(rhs)); + return lhs.base() >= rhs.base(); + } + + template + inline typename checked_iterator::difference_type + operator-(const checked_iterator& lhs, + const checked_iterator& rhs) + { + assert(lhs._M_can_compare(rhs)); + return lhs.base() - rhs.base(); + } + + } // namespace debug + +} // namespace redhawk + +#endif // _CHECKED_ITERATOR_HH_ diff --git a/redhawk/src/base/include/ossie/shared_buffer.h b/redhawk/src/base/include/ossie/shared_buffer.h index 081e985ce..2b3d91bde 100644 --- a/redhawk/src/base/include/ossie/shared_buffer.h +++ b/redhawk/src/base/include/ossie/shared_buffer.h @@ -26,6 +26,15 @@ #include +#ifdef _RH_SHARED_BUFFER_DEBUG +#include "debug/checked_allocator.h" +#include "debug/checked_iterator.h" + +#define _RH_SHARED_BUFFER_CHECK(X) assert(X) +#else // !_RH_SHARED_BUFFER_DEBUG +#define _RH_SHARED_BUFFER_CHECK(X) +#endif + namespace redhawk { /** @@ -96,7 +105,11 @@ namespace redhawk { * Note that all access to %shared_buffer is const. This means that * %iterator and %const_iterator are equivalent. */ +#ifdef _RH_SHARED_BUFFER_DEBUG + typedef ::redhawk::debug::checked_iterator iterator; +#else typedef const value_type* iterator; +#endif /** * @brief A random access iterator to const value_type. * @@ -164,7 +177,7 @@ namespace redhawk { */ iterator begin() const { - return iterator(this->_M_begin()); + return _M_iterator(this->_M_begin()); } /** @@ -173,12 +186,12 @@ namespace redhawk { */ iterator end() const { - return iterator(this->_M_end()); + return _M_iterator(this->_M_end()); } /** * @brief Subscript access to the data contained in the %shared_buffer. - * @param index The index of the element to access + * @param index The index of the element to access * @return Read-only reference to element */ const value_type& operator[] (size_t index) const @@ -233,6 +246,8 @@ namespace redhawk { if (end == (size_t)-1) { end = this->size(); } + _RH_SHARED_BUFFER_CHECK(end >= start); + _RH_SHARED_BUFFER_CHECK(end <= this->size()); this->_M_start += start; this->_M_finish = this->_M_start + end - start; } @@ -244,8 +259,7 @@ namespace redhawk { */ void trim(iterator first, iterator last=end()) { - this->_M_start = const_cast(first); - this->_M_finish = const_cast(last); + this->_M_trim(first, last); } /** @@ -335,6 +349,7 @@ namespace redhawk { // use. value_type& _M_index(size_t index) const { + _RH_SHARED_BUFFER_CHECK(index < this->size()); return this->_M_start[index]; } @@ -350,6 +365,28 @@ namespace redhawk { return this->_M_finish; } + // Converts a pointer into an iterator; if debug is enabled, the ctor + // requires an additional parameter (a pointer back to the originating + // conatiner), otherwise, it's a no-op + inline iterator _M_iterator(value_type* iter) const + { +#ifdef _RH_SHARED_BUFFER_DEBUG + return iterator(iter, this); +#else + return iterator(iter); +#endif + } + + // Internal implementation of trim to support checked iterators, which + // are different classes for shared_buffer and buffer + void _M_trim(const value_type* first, const value_type* last) + { + _RH_SHARED_BUFFER_CHECK(last >= first); + _RH_SHARED_BUFFER_CHECK(last <= this->_M_finish); + this->_M_start = const_cast(first); + this->_M_finish = const_cast(last); + } + // Internal implementation of swap. void _M_swap(shared_buffer& other) { @@ -425,11 +462,23 @@ namespace redhawk { /// @brief The element type (T). typedef T value_type; /// @brief A random access iterator to value_type. +#ifdef _RH_SHARED_BUFFER_DEBUG + typedef ::redhawk::debug::checked_iterator iterator; +#else typedef value_type* iterator; +#endif /// @brief A random access iterator to const value_type. +#ifdef _RH_SHARED_BUFFER_DEBUG + typedef ::redhawk::debug::checked_iterator const_iterator; +#else typedef const value_type* const_iterator; +#endif /// @brief The default allocator class. +#ifdef _RH_SHARED_BUFFER_DEBUG + typedef ::redhawk::debug::checked_allocator default_allocator; +#else typedef std::allocator default_allocator; +#endif /** * @brief Construct an empty %buffer. @@ -511,7 +560,7 @@ namespace redhawk { */ iterator begin() { - return iterator(this->_M_begin()); + return _M_iterator(this->_M_begin()); } /** @@ -520,7 +569,7 @@ namespace redhawk { */ const_iterator begin() const { - return const_iterator(this->_M_begin()); + return _M_const_iterator(this->_M_begin()); } /** @@ -529,7 +578,7 @@ namespace redhawk { */ iterator end() { - return iterator(this->_M_end()); + return _M_iterator(this->_M_end()); } /** @@ -538,7 +587,7 @@ namespace redhawk { */ const_iterator end() const { - return const_iterator(this->_M_end()); + return _M_const_iterator(this->_M_end()); } /** @@ -617,6 +666,26 @@ namespace redhawk { return result; } + /** + * @brief Adjusts the start and end indices of this %buffer. + * @param start Index of first element. + * @param end Index of last element, exclusive (default end). + */ + void trim(size_t start, size_t end=size_t(-1)) + { + read_type::trim(start, end); + } + + /** + * @brief Adjusts the beginning and end of this %buffer. + * @param start Iterator to first element. + * @param end Iterator to last element, exclusive (default end). + */ + void trim(iterator first, iterator last=end()) + { + this->_M_trim(first, last); + } + /** * @brief Returns a copy of this %buffer. * @@ -670,6 +739,27 @@ namespace redhawk { protected: /// @cond IMPL + // Converts a pointer into an iterator (see shared_buffer::_M_iterator + // for more explanation) + inline iterator _M_iterator(value_type* iter) + { +#ifdef _RH_SHARED_BUFFER_DEBUG + return iterator(iter, this); +#else + return iterator(iter); +#endif + } + + // Converts a const pointer into an const_iterator (see above) + inline const_iterator _M_const_iterator(const value_type* iter) const + { +#ifdef _RH_SHARED_BUFFER_DEBUG + return const_iterator(iter, this); +#else + return const_iterator(iter); +#endif + } + // Implementation of allocate. template static read_type _M_allocate(size_t size, const Alloc& allocator) From f862fa85195869098d2f158487d565ac22b84ecc Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 8 Aug 2016 11:32:39 -0400 Subject: [PATCH 0434/1644] Separate the implementation of debug check from its usage, so that we aren't tied to assert() --- redhawk/src/base/include/ossie/Makefile.am | 1 + redhawk/src/base/include/ossie/debug/check.h | 28 +++++++++++++++ .../include/ossie/debug/checked_allocator.h | 6 ++-- .../include/ossie/debug/checked_iterator.h | 34 ++++++++++--------- .../src/base/include/ossie/shared_buffer.h | 3 +- 5 files changed, 53 insertions(+), 19 deletions(-) create mode 100644 redhawk/src/base/include/ossie/debug/check.h diff --git a/redhawk/src/base/include/ossie/Makefile.am b/redhawk/src/base/include/ossie/Makefile.am index 24398c7e3..ec76ce3e6 100644 --- a/redhawk/src/base/include/ossie/Makefile.am +++ b/redhawk/src/base/include/ossie/Makefile.am @@ -68,5 +68,6 @@ nobase_pkginclude_HEADERS = internal/equals.h \ logging/rh_logger.h \ logging/LogConfigUriResolver.h \ logging/loghelpers.h \ + debug/check.h \ debug/checked_allocator.h \ debug/checked_iterator.h diff --git a/redhawk/src/base/include/ossie/debug/check.h b/redhawk/src/base/include/ossie/debug/check.h new file mode 100644 index 000000000..484531c94 --- /dev/null +++ b/redhawk/src/base/include/ossie/debug/check.h @@ -0,0 +1,28 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK core. + * + * REDHAWK core is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +#ifndef REDHAWK_DEBUG_CHECK_H +#define REDHAWK_DEBUG_CHECK_H + +#include + +#define _RH_DEBUG_CHECK(X) assert(X) + +#endif diff --git a/redhawk/src/base/include/ossie/debug/checked_allocator.h b/redhawk/src/base/include/ossie/debug/checked_allocator.h index badf99e1b..fd9f0ca26 100644 --- a/redhawk/src/base/include/ossie/debug/checked_allocator.h +++ b/redhawk/src/base/include/ossie/debug/checked_allocator.h @@ -24,6 +24,8 @@ #include #include +#include "check.h" + namespace redhawk { namespace debug { @@ -82,9 +84,9 @@ namespace redhawk { magic_type* front = _M_get_front(ptr); // Check that neither the front or the back pad has been written to - assert(_M_is_unmodified(front)); + _RH_DEBUG_CHECK(_M_is_unmodified(front)); magic_type* back = _M_get_back(ptr, count); - assert(_M_is_unmodified(back)); + _RH_DEBUG_CHECK(_M_is_unmodified(back)); ::operator delete(front); } diff --git a/redhawk/src/base/include/ossie/debug/checked_iterator.h b/redhawk/src/base/include/ossie/debug/checked_iterator.h index 55bbc51fe..d6b0a2532 100644 --- a/redhawk/src/base/include/ossie/debug/checked_iterator.h +++ b/redhawk/src/base/include/ossie/debug/checked_iterator.h @@ -38,6 +38,8 @@ #include +#include "check.h" + namespace redhawk { namespace debug { @@ -129,7 +131,7 @@ namespace redhawk { */ reference operator*() const { - assert(_M_can_dereference()); + _RH_DEBUG_CHECK(_M_can_dereference()); return *_M_current; } @@ -139,7 +141,7 @@ namespace redhawk { */ pointer operator->() const { - assert(_M_can_dereference()); + _RH_DEBUG_CHECK(_M_can_dereference()); return &*_M_current; } @@ -150,7 +152,7 @@ namespace redhawk { checked_iterator operator++(int) { // Can't increment past the end - assert(!_M_is_end()); + _RH_DEBUG_CHECK(!_M_is_end()); checked_iterator tmp(*this); ++_M_current; return tmp; @@ -163,7 +165,7 @@ namespace redhawk { checked_iterator& operator++() { // Can't increment past the end - assert(!_M_is_end()); + _RH_DEBUG_CHECK(!_M_is_end()); ++_M_current; return *this; } @@ -175,7 +177,7 @@ namespace redhawk { checked_iterator operator--(int) { // Can't decrement past the first element - assert(!_M_is_begin()); + _RH_DEBUG_CHECK(!_M_is_begin()); checked_iterator tmp(*this); --_M_current; return tmp; @@ -188,7 +190,7 @@ namespace redhawk { checked_iterator& operator--() { // Can't decrement past the first element - assert(!_M_is_begin()); + _RH_DEBUG_CHECK(!_M_is_begin()); --_M_current; return *this; } @@ -200,7 +202,7 @@ namespace redhawk { */ reference operator[](const difference_type& index) const { - assert(_M_can_increment(index+1)); + _RH_DEBUG_CHECK(_M_can_increment(index+1)); return _M_current[index]; } @@ -211,7 +213,7 @@ namespace redhawk { */ checked_iterator& operator+=(const difference_type& offset) { - assert(_M_can_increment(offset)); + _RH_DEBUG_CHECK(_M_can_increment(offset)); _M_current += offset; return *this; } @@ -237,7 +239,7 @@ namespace redhawk { */ checked_iterator& operator-=(const difference_type& offset) { - assert(_M_can_decrement(offset)); + _RH_DEBUG_CHECK(_M_can_decrement(offset)); _M_current -= offset; return *this; } @@ -327,7 +329,7 @@ namespace redhawk { inline bool operator==(const checked_iterator& lhs, const checked_iterator& rhs) { - assert(lhs._M_can_compare(rhs)); + _RH_DEBUG_CHECK(lhs._M_can_compare(rhs)); return lhs.base() == rhs.base(); } @@ -335,7 +337,7 @@ namespace redhawk { inline bool operator!=(const checked_iterator& lhs, const checked_iterator& rhs) { - assert(lhs._M_can_compare(rhs)); + _RH_DEBUG_CHECK(lhs._M_can_compare(rhs)); return lhs.base() != rhs.base(); } @@ -343,7 +345,7 @@ namespace redhawk { inline bool operator<(const checked_iterator& lhs, const checked_iterator& rhs) { - assert(lhs._M_can_compare(rhs)); + _RH_DEBUG_CHECK(lhs._M_can_compare(rhs)); return lhs.base() < rhs.base(); } @@ -351,7 +353,7 @@ namespace redhawk { inline bool operator<=(const checked_iterator& lhs, const checked_iterator& rhs) { - assert(lhs._M_can_compare(rhs)); + _RH_DEBUG_CHECK(lhs._M_can_compare(rhs)); return lhs.base() <= rhs.base(); } @@ -359,7 +361,7 @@ namespace redhawk { inline bool operator>(const checked_iterator& lhs, const checked_iterator& rhs) { - assert(lhs._M_can_compare(rhs)); + _RH_DEBUG_CHECK(lhs._M_can_compare(rhs)); return lhs.base() > rhs.base(); } @@ -367,7 +369,7 @@ namespace redhawk { inline bool operator>=(const checked_iterator& lhs, const checked_iterator& rhs) { - assert(lhs._M_can_compare(rhs)); + _RH_DEBUG_CHECK(lhs._M_can_compare(rhs)); return lhs.base() >= rhs.base(); } @@ -376,7 +378,7 @@ namespace redhawk { operator-(const checked_iterator& lhs, const checked_iterator& rhs) { - assert(lhs._M_can_compare(rhs)); + _RH_DEBUG_CHECK(lhs._M_can_compare(rhs)); return lhs.base() - rhs.base(); } diff --git a/redhawk/src/base/include/ossie/shared_buffer.h b/redhawk/src/base/include/ossie/shared_buffer.h index 2b3d91bde..4f1a5886d 100644 --- a/redhawk/src/base/include/ossie/shared_buffer.h +++ b/redhawk/src/base/include/ossie/shared_buffer.h @@ -27,10 +27,11 @@ #include #ifdef _RH_SHARED_BUFFER_DEBUG +#include "debug/check.h" #include "debug/checked_allocator.h" #include "debug/checked_iterator.h" -#define _RH_SHARED_BUFFER_CHECK(X) assert(X) +#define _RH_SHARED_BUFFER_CHECK(X) _RH_DEBUG_CHECK(X) #else // !_RH_SHARED_BUFFER_DEBUG #define _RH_SHARED_BUFFER_CHECK(X) #endif From 62d9e9ae1ba1ae97fc925b3033754a4067382377 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 8 Aug 2016 11:58:39 -0400 Subject: [PATCH 0435/1644] Reimplement index-based trim in terms of iterator version to share validity checks --- redhawk/src/base/include/ossie/shared_buffer.h | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/redhawk/src/base/include/ossie/shared_buffer.h b/redhawk/src/base/include/ossie/shared_buffer.h index 4f1a5886d..00c1518a6 100644 --- a/redhawk/src/base/include/ossie/shared_buffer.h +++ b/redhawk/src/base/include/ossie/shared_buffer.h @@ -247,10 +247,7 @@ namespace redhawk { if (end == (size_t)-1) { end = this->size(); } - _RH_SHARED_BUFFER_CHECK(end >= start); - _RH_SHARED_BUFFER_CHECK(end <= this->size()); - this->_M_start += start; - this->_M_finish = this->_M_start + end - start; + this->_M_trim(this->_M_begin() + start, this->_M_begin() + end); } /** From ed3cec695333f25d80cd6c8ca2575c4f0bcac4a3 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 8 Aug 2016 14:33:45 -0400 Subject: [PATCH 0436/1644] Add a stream insertion operator for CORBA::Any, mostly so that the Value class can be easily written to a log message --- redhawk/src/base/framework/Value.cpp | 5 +++++ redhawk/src/base/include/ossie/Value.h | 1 + 2 files changed, 6 insertions(+) diff --git a/redhawk/src/base/framework/Value.cpp b/redhawk/src/base/framework/Value.cpp index 8769c2e5a..9761f72b4 100644 --- a/redhawk/src/base/framework/Value.cpp +++ b/redhawk/src/base/framework/Value.cpp @@ -138,6 +138,11 @@ const ValueSequence& Value::asSequence() const return ValueSequence::cast(*prop_seq); } +std::ostream& redhawk::operator<<(std::ostream& out, const CORBA::Any& value) +{ + out << Value::cast(value).toString(); + return out; +} ValueSequence::ValueSequence() : CORBA::AnySeq() diff --git a/redhawk/src/base/include/ossie/Value.h b/redhawk/src/base/include/ossie/Value.h index aea050b60..d2bc26bc3 100644 --- a/redhawk/src/base/include/ossie/Value.h +++ b/redhawk/src/base/include/ossie/Value.h @@ -94,6 +94,7 @@ namespace redhawk { } }; + std::ostream& operator<<(std::ostream& out, const CORBA::Any& value); class ValueSequence : public CORBA::AnySeq { public: From cebad4559e52372f7fa26f0f15eca14fa5e1a950 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 16 Sep 2016 09:49:01 -0400 Subject: [PATCH 0437/1644] Fix sized/unsized comparison warning --- redhawk/src/base/framework/Resource_impl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/redhawk/src/base/framework/Resource_impl.cpp b/redhawk/src/base/framework/Resource_impl.cpp index ebfd9e531..9f5316135 100644 --- a/redhawk/src/base/framework/Resource_impl.cpp +++ b/redhawk/src/base/framework/Resource_impl.cpp @@ -289,7 +289,7 @@ void Resource_impl::start_component(Resource_impl::ctor_type ctor, int argc, cha // based on the name. If this isn't done prior to initializing CORBA, the // ORB creates some threads that will get the original process name, and // any threads they create, and so on. - for (size_t index = 1; index < argc; ++index) { + for (int index = 1; index < argc; ++index) { if (strcmp("NAME_BINDING", argv[index]) == 0) { if (++index < argc) { std::string value = argv[index]; From e86ba99b79f14ff144c3fbc81bba180dae91d6ba Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 16 Sep 2016 11:18:44 -0400 Subject: [PATCH 0438/1644] Reference unmangled module name --- redhawk/src/testing/tests/test_13_TestSB.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/redhawk/src/testing/tests/test_13_TestSB.py b/redhawk/src/testing/tests/test_13_TestSB.py index 9a0186080..1bd6b39f8 100644 --- a/redhawk/src/testing/tests/test_13_TestSB.py +++ b/redhawk/src/testing/tests/test_13_TestSB.py @@ -1779,7 +1779,7 @@ def __init__(self, cond): def msgCallback(self, id, msg): - self.msg = _properties.prop_to_dict(msg) + self.msg = properties.prop_to_dict(msg) self.count = self.count + 1 self.cond.acquire() self.cond.notify() From d724d53de4ec2fd002ede7f0ddae597c871e71c3 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 16 Sep 2016 11:20:28 -0400 Subject: [PATCH 0439/1644] Convert strings to boolean values in C++ by checking for "true" and "false" string literals first and, if that fails, converting via double. Prior, literal values raised boost::bad_lexical_cast exceptions. --- redhawk/src/base/framework/AnyUtils.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/redhawk/src/base/framework/AnyUtils.cpp b/redhawk/src/base/framework/AnyUtils.cpp index 97bf52f35..b6e7a96ab 100644 --- a/redhawk/src/base/framework/AnyUtils.cpp +++ b/redhawk/src/base/framework/AnyUtils.cpp @@ -79,6 +79,24 @@ namespace { } } + // Specialization for boolean, first checking for literal values "true" and + // "false" (case insensitive), then convering via lexical cast to double + // (for widest range) and comparing with zero + template<> + inline bool stringToNumber (const std::string& str) + { + std::string out; + std::transform(str.begin(), str.end(), std::back_inserter(out), ::tolower); + if (out == "true") { + return true; + } else if (out == "false") { + return false; + } else { + double temp = boost::lexical_cast(str); + return (temp != 0.0); + } + } + // Specialization for CORBA::Octet (unsigned char), always converting via // double because lexical_cast throws a bad_lexical_cast exception with // CORBA::Octet From e4d1fa4ecff1706ce74dfa8912d838c0fa97486f Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 16 Sep 2016 13:14:58 -0400 Subject: [PATCH 0440/1644] Add operator != for shared buffers --- redhawk/src/base/include/ossie/shared_buffer.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/redhawk/src/base/include/ossie/shared_buffer.h b/redhawk/src/base/include/ossie/shared_buffer.h index 00c1518a6..8476992e1 100644 --- a/redhawk/src/base/include/ossie/shared_buffer.h +++ b/redhawk/src/base/include/ossie/shared_buffer.h @@ -791,6 +791,18 @@ namespace redhawk { } } + /** + * @brief Buffer inequality comparison. + * @param lhs A %shared_buffer. + * @param rhs A %shared_buffer of the same type as @a lhs. + * @return True iff the size or elements of the shared_buffers are not equal. + */ + template + inline bool operator!=(const shared_buffer& lhs, const shared_buffer& rhs) + { + return !(lhs == rhs); + } + /** * @brief A convenience wrapper for creating a buffer. * @param data Pointer to first element. From 0acf1e203df61fd66c8c591364d197e527ecedac Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 16 Sep 2016 14:31:16 -0400 Subject: [PATCH 0441/1644] Split one and two argument shared buffer trim() method, because end() cannot be used as a default argument value in that context --- redhawk/src/base/include/ossie/shared_buffer.h | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/redhawk/src/base/include/ossie/shared_buffer.h b/redhawk/src/base/include/ossie/shared_buffer.h index 8476992e1..a7c9dc4e2 100644 --- a/redhawk/src/base/include/ossie/shared_buffer.h +++ b/redhawk/src/base/include/ossie/shared_buffer.h @@ -250,12 +250,21 @@ namespace redhawk { this->_M_trim(this->_M_begin() + start, this->_M_begin() + end); } + /** + * @brief Adjusts the beginning of this %shared_buffer. + * @param start Iterator to first element. + */ + void trim(iterator first) + { + this->_M_trim(first, end()); + } + /** * @brief Adjusts the beginning and end of this %shared_buffer. * @param start Iterator to first element. - * @param end Iterator to last element, exclusive (default end). + * @param end Iterator to last element, exclusive. */ - void trim(iterator first, iterator last=end()) + void trim(iterator first, iterator last) { this->_M_trim(first, last); } From 4d6fe3c45f656e3603ebd91b0b9b93232ca72f4b Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 16 Sep 2016 15:16:43 -0400 Subject: [PATCH 0442/1644] Add start of CppUnit testing framework for the core, including a unit test for redhawk::shared_buffer --- redhawk/src/configure.ac | 4 + redhawk/src/testing/Makefile.am | 2 + redhawk/src/testing/cpp/.gitignore | 1 + redhawk/src/testing/cpp/Makefile.am | 6 + redhawk/src/testing/cpp/SharedBufferTest.cpp | 289 +++++++++++++++++++ redhawk/src/testing/cpp/SharedBufferTest.h | 40 +++ redhawk/src/testing/cpp/standalone.cpp | 22 ++ 7 files changed, 364 insertions(+) create mode 100644 redhawk/src/testing/cpp/.gitignore create mode 100644 redhawk/src/testing/cpp/Makefile.am create mode 100644 redhawk/src/testing/cpp/SharedBufferTest.cpp create mode 100644 redhawk/src/testing/cpp/SharedBufferTest.h create mode 100644 redhawk/src/testing/cpp/standalone.cpp diff --git a/redhawk/src/configure.ac b/redhawk/src/configure.ac index fe6278af3..b430a2e25 100644 --- a/redhawk/src/configure.ac +++ b/redhawk/src/configure.ac @@ -273,6 +273,9 @@ if test "$HAVE_JAVASUPPORT" = yes; then IDLJNICXX='$(IDL) -p $(OMNIJNI_PYTHONDIR) -b omnijni.idljni' fi +# C++ unit testing support. May want to conditionally enable/disable this. +AM_PATH_CPPUNIT(1.12.1) + # Undefine the PACKAGE_ variables to avoid warnings when omniORB is installed outside of # /usr. OSSIE doesn't use these variables anyways...and even if it did # they would get undefined in any file that included CORBA.h (because ossieconfig.h @@ -316,6 +319,7 @@ AC_CONFIG_FILES(Makefile \ tools/LogEventAppender/Makefile \ testing/Makefile \ testing/_unitTestHelpers/buildconfig.py \ + testing/cpp/Makefile \ testing/sdr/dev/devices/ExecutableDevice/Makefile \ testing/sdr/dev/devices/BasicTestDevice_cpp/BasicTestDevice_cpp_impl1/Makefile \ testing/sdr/dev/devices/BasicTestDevice_java/java/Makefile \ diff --git a/redhawk/src/testing/Makefile.am b/redhawk/src/testing/Makefile.am index 85b871412..e3a7bd518 100644 --- a/redhawk/src/testing/Makefile.am +++ b/redhawk/src/testing/Makefile.am @@ -94,6 +94,8 @@ SUBDIRS += sdr/dev/devices/BasicTestDevice_java/java \ sdr/dom/components/TestJavaOptionalProps/java endif +SUBDIRS += cpp + all-local: python setup.py $(OSSIE_V_pysetup) build diff --git a/redhawk/src/testing/cpp/.gitignore b/redhawk/src/testing/cpp/.gitignore new file mode 100644 index 000000000..6827d9fdf --- /dev/null +++ b/redhawk/src/testing/cpp/.gitignore @@ -0,0 +1 @@ +standalone diff --git a/redhawk/src/testing/cpp/Makefile.am b/redhawk/src/testing/cpp/Makefile.am new file mode 100644 index 000000000..20249f864 --- /dev/null +++ b/redhawk/src/testing/cpp/Makefile.am @@ -0,0 +1,6 @@ +TESTS = standalone + +check_PROGRAMS = $(TESTS) +standalone_SOURCES = standalone.cpp SharedBufferTest.cpp SharedBufferTest.h +standalone_CXXFLAGS = $(CPPUNIT_CFLAGS) -I $(top_srcdir)/base/include +standalone_LDFLAGS = $(CPPUNIT_LIBS) diff --git a/redhawk/src/testing/cpp/SharedBufferTest.cpp b/redhawk/src/testing/cpp/SharedBufferTest.cpp new file mode 100644 index 000000000..fe624e010 --- /dev/null +++ b/redhawk/src/testing/cpp/SharedBufferTest.cpp @@ -0,0 +1,289 @@ +#include "SharedBufferTest.h" + +#include + +#include + +CPPUNIT_TEST_SUITE_REGISTRATION(SharedBufferTest); + +namespace { + // Special allocator that wraps an existing char buffer, marking allocated + // data with ones and deallocated data with zeros. + template + struct CustomAllocator : public std::allocator + { + CustomAllocator(char* buffer) : + _buffer(buffer) + { + } + + T* allocate(size_t count, void* ptr=0) + { + size_t bytes = count * sizeof(T); + std::fill(_buffer, _buffer + bytes, 1); + return reinterpret_cast(_buffer); + } + + void deallocate(void* ptr, size_t count) + { + size_t bytes = count * sizeof(T); + std::fill(_buffer, _buffer + bytes, 0); + } + + private: + char* _buffer; + }; + + // Special deleter that writes to a boolean flag pointer to notify when it + // has been called. Using a pointer-to-value instead of its own local flag + // allows it to be passed by value, which is the preferred way of passing a + // deleter to boost::shared_array (and by extension redhawk::shared_buffer) + struct CustomDeleter { + CustomDeleter(bool* deleted) : + _deleted(deleted) + { + } + + void operator() (void* ptr) + { + std::free(ptr); + *_deleted = true; + } + + bool* _deleted; + }; +} + +void SharedBufferTest::setUp() +{ +} + +void SharedBufferTest::tearDown() +{ +} + +void SharedBufferTest::testDefaultConstructor() +{ + // Empty shared buffer + redhawk::shared_buffer shared; + CPPUNIT_ASSERT(shared.size() == 0); + CPPUNIT_ASSERT(shared.empty()); + CPPUNIT_ASSERT_EQUAL(shared.begin(), shared.end()); +} + +void SharedBufferTest::testConstructor() +{ + // Test allocating constructor + const size_t BUFFER_SIZE = 16; + redhawk::buffer buffer(BUFFER_SIZE); + CPPUNIT_ASSERT(!buffer.empty()); + CPPUNIT_ASSERT_EQUAL(buffer.size(), BUFFER_SIZE); + CPPUNIT_ASSERT(buffer.begin() != buffer.end()); + + // Test construction of shared buffer from mutable buffer + redhawk::shared_buffer shared(buffer); + CPPUNIT_ASSERT(!shared.empty()); + CPPUNIT_ASSERT_EQUAL(shared.size(), buffer.size()); + CPPUNIT_ASSERT(shared.data() == buffer.data()); +} + +void SharedBufferTest::testEquals() +{ + // Create a buffer with known data + redhawk::buffer first(6); + std::fill(first.begin(), first.end(), 8); + + // Create a second, identical buffer and check that it is equal + redhawk::buffer second = first.copy(); + std::copy(first.begin(), first.end(), second.begin()); + CPPUNIT_ASSERT(first.data() != second.data()); + CPPUNIT_ASSERT(first == second); + + // Modify an element, breaking equality + second[3] = -25; + CPPUNIT_ASSERT(first != second); + + // Re-allocate the second buffer with one extra element + second = redhawk::buffer(first.size() + 1); + std::copy(first.begin(), first.end(), second.begin()); + second[second.size() - 1] = second[0]; + CPPUNIT_ASSERT(first != second); +} + +void SharedBufferTest::testSharing() +{ + // Fill a new buffer + redhawk::buffer > buffer(8); + for (int index = 0; index < buffer.size(); ++index) { + buffer[index] = std::complex(0.5, 0.5) * (double) index; + } + + // Create a shared buffer aliasing the original + redhawk::shared_buffer > shared = buffer; + CPPUNIT_ASSERT(shared == buffer); + + // Conjugate values and ensure that the buffers are still equal + std::transform(buffer.begin(), buffer.end(), buffer.begin(), std::conj); + CPPUNIT_ASSERT(shared == buffer); +} + +void SharedBufferTest::testSlicing() +{ + // Fill a new buffer + redhawk::buffer buffer(12); + for (int index = 0; index < buffer.size(); ++index) { + buffer[index] = index; + } + + // Take a 4-element slice from the middle and check that it points to the + // same data (offset by the start index) + redhawk::shared_buffer middle = buffer.slice(4, 8); + CPPUNIT_ASSERT_EQUAL(middle.size(), (size_t) 4); + CPPUNIT_ASSERT(middle.data() == buffer.data() + 4); + + // Take a slice from the midpoint to the end, and check that the elements + // match + redhawk::shared_buffer end = buffer.slice(6); + CPPUNIT_ASSERT_EQUAL(end.size(), buffer.size() - 6); + for (int index = 0; index < end.size(); ++index) { + CPPUNIT_ASSERT_EQUAL(end[index], buffer[index + 6]); + } + + // Compare the overlap between the two slices by taking sub-slices + CPPUNIT_ASSERT(middle.slice(2) == end.slice(0, 2)); +} + +void SharedBufferTest::testTrim() +{ + // Fill a new buffer + redhawk::buffer buffer(10); + for (size_t index = 0; index < buffer.size(); ++index) { + buffer[index] = index; + } + + // Create a shared buffer alias, then trim one element off each end + redhawk::shared_buffer shared = buffer; + shared.trim(1, buffer.size() - 1); + CPPUNIT_ASSERT_EQUAL(shared.size(), buffer.size() - 2); + CPPUNIT_ASSERT(std::equal(shared.begin(), shared.end(), buffer.begin() + 1)); + + // Trim another element off the beginning + shared.trim(1); + CPPUNIT_ASSERT_EQUAL(shared.size(), buffer.size() - 3); + CPPUNIT_ASSERT(std::equal(shared.begin(), shared.end(), buffer.begin() + 2)); + + // Iterator-based trim: find specific values and trim to [first, last) + redhawk::shared_buffer::iterator first = std::find(shared.begin(), shared.end(), 4); + redhawk::shared_buffer::iterator last = std::find(shared.begin(), shared.end(), 7); + CPPUNIT_ASSERT(first != shared.end()); + CPPUNIT_ASSERT(last != shared.end()); + shared.trim(first, last); + CPPUNIT_ASSERT(shared.size() == 3); + CPPUNIT_ASSERT_EQUAL(shared[0], (unsigned short) 4); + + // Use iterator-based trim to take another element off the beginning + shared.trim(shared.begin() + 1); + CPPUNIT_ASSERT(shared.size() == 2); + CPPUNIT_ASSERT_EQUAL(shared[0], (unsigned short) 5); +} + +void SharedBufferTest::testRecast() +{ + // Fill a new buffer with an odd number of elements + redhawk::buffer buffer(13); + for (size_t index = 0; index < buffer.size(); ++index) { + buffer[index] = index * 2.0 * M_PI; + } + + // Recast to the complex equivalent, and check that its size is determined + // using floor division (i.e., the extra real value is excluded) + redhawk::shared_buffer > cxbuffer; + cxbuffer = redhawk::shared_buffer >::recast(buffer); + CPPUNIT_ASSERT_EQUAL(cxbuffer.size(), buffer.size() / 2); + CPPUNIT_ASSERT_EQUAL(cxbuffer.size() * 2, buffer.size() - 1); + + // Check that the complex buffer has the original values interleaved as + // real/imaginary pairs + for (size_t index = 0; index < (cxbuffer.size() * 2); index += 2) { + CPPUNIT_ASSERT_EQUAL(cxbuffer[index/2].real(), buffer[index]); + CPPUNIT_ASSERT_EQUAL(cxbuffer[index/2].imag(), buffer[index+1]); + } + + // Recast into short; this is basically nonsensical, but technically valid, + // so only check that the size is correct + redhawk::shared_buffer shbuffer; + shbuffer = redhawk::shared_buffer::recast(buffer); + CPPUNIT_ASSERT_EQUAL(shbuffer.size(), buffer.size() * 2); +} + +void SharedBufferTest::testAllocator() +{ + typedef std::complex value_type; + typedef CustomAllocator allocator_type; + + // Start with a zero-filled buffer of "raw" memory + std::vector arena; + arena.resize(32); + + // The initial condition of the arena should be all zeros + std::fill(arena.begin(), arena.end(), 0); + CPPUNIT_ASSERT(std::count(arena.begin(), arena.end(), 0) == arena.size()); + + // Create a new buffer using a custom allocator; we should see that it's + // marked the allocated space with ones + redhawk::buffer buffer(4, allocator_type(&arena[0])); + const size_t MIN_BYTES = sizeof(value_type) * buffer.size(); + size_t index = 0; + while ((index < arena.size()) && (arena[index] == 1)) { + ++index; + } + CPPUNIT_ASSERT(index >= MIN_BYTES); + + // Release the buffer, which should trigger a deallocation; we should see + // that it's reset the allocated space to zeros + buffer = redhawk::buffer(); + CPPUNIT_ASSERT(std::count(arena.begin(), arena.end(), 0) == arena.size()); +} + +void SharedBufferTest::testCustomDeleter() +{ + // Local flag given to the custom deleter for checking when deletion has + // occurred + bool deleted = false; + + // Allocate a buffer through other means, then wrap it with a buffer using + // a custom deleter + char* data = static_cast(std::malloc(16)); + redhawk::shared_buffer buffer(data, sizeof(data), CustomDeleter(&deleted)); + CPPUNIT_ASSERT(buffer.data() == data); + + // Make a new shared alias and replace the first buffer; there is still one + // outstanding reference, so the deleter should not be called + redhawk::shared_buffer shared = buffer; + buffer = redhawk::shared_buffer(); + CPPUNIT_ASSERT(!deleted); + + // Replace the second buffer, which should be the last reference; the + // deleter should be called + shared = redhawk::shared_buffer(); + CPPUNIT_ASSERT(deleted); +} + +void SharedBufferTest::testTransient() +{ + // Wrap a transient shared buffer around a C-style array + int data[] = { 8, 6, 7, 5, 3, 0, 9 }; + const size_t BUFFER_SIZE = sizeof(data) / sizeof(data[0]); + redhawk::shared_buffer buffer = redhawk::shared_buffer::make_transient(data, BUFFER_SIZE); + CPPUNIT_ASSERT(buffer.transient()); + CPPUNIT_ASSERT(buffer.data() == data); + CPPUNIT_ASSERT(buffer.size() == BUFFER_SIZE); + for (size_t index = 0; index < buffer.size(); ++index) { + CPPUNIT_ASSERT_EQUAL(buffer[index], data[index]); + } + + // Allocate a new buffer and assign it back to our original buffer, making + // sure that it is no longer transient + buffer = redhawk::buffer(1); + CPPUNIT_ASSERT(!buffer.transient()); +} diff --git a/redhawk/src/testing/cpp/SharedBufferTest.h b/redhawk/src/testing/cpp/SharedBufferTest.h new file mode 100644 index 000000000..fbf496a4a --- /dev/null +++ b/redhawk/src/testing/cpp/SharedBufferTest.h @@ -0,0 +1,40 @@ +#ifndef SHAREDBUFFERTEST_H +#define SHAREDBUFFERTEST_H + +#include + +class SharedBufferTest : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE(SharedBufferTest); + CPPUNIT_TEST(testDefaultConstructor); + CPPUNIT_TEST(testConstructor); + CPPUNIT_TEST(testEquals); + CPPUNIT_TEST(testSharing); + CPPUNIT_TEST(testSlicing); + CPPUNIT_TEST(testTrim); + CPPUNIT_TEST(testRecast); + CPPUNIT_TEST(testAllocator); + CPPUNIT_TEST(testCustomDeleter); + CPPUNIT_TEST(testTransient); + CPPUNIT_TEST_SUITE_END(); + +public: + void setUp(); + void tearDown(); + + void testDefaultConstructor(); + void testConstructor(); + + void testEquals(); + + void testSharing(); + void testSlicing(); + void testTrim(); + void testRecast(); + + void testAllocator(); + void testCustomDeleter(); + void testTransient(); +}; + +#endif // SHARED_BUFFER_TEST_H diff --git a/redhawk/src/testing/cpp/standalone.cpp b/redhawk/src/testing/cpp/standalone.cpp new file mode 100644 index 000000000..b95eb8334 --- /dev/null +++ b/redhawk/src/testing/cpp/standalone.cpp @@ -0,0 +1,22 @@ +#include +#include +#include + + +int main(int argc, char* argv[]) +{ + // Get the top level suite from the registry + CppUnit::Test* suite = CppUnit::TestFactoryRegistry::getRegistry().makeTest(); + + // Adds the test to the list of test to run + CppUnit::TextUi::TestRunner runner; + runner.addTest(suite); + + // Change the default outputter to a compiler error format outputter + runner.setOutputter(new CppUnit::CompilerOutputter(&runner.result(), std::cerr)); + // Run the tests. + bool wasSucessful = runner.run(); + + // Return error code 1 if the one of test failed. + return wasSucessful ? 0 : 1; +} From 27a380970015acd67cc7a3d00e9d6d5471f99e7a Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 16 Sep 2016 15:42:37 -0400 Subject: [PATCH 0443/1644] Add a test for shared buffer iteration; use const shared buffers as much as possible to test const-correctness --- redhawk/src/testing/cpp/SharedBufferTest.cpp | 34 ++++++++++++++++---- redhawk/src/testing/cpp/SharedBufferTest.h | 2 ++ 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/redhawk/src/testing/cpp/SharedBufferTest.cpp b/redhawk/src/testing/cpp/SharedBufferTest.cpp index fe624e010..42a7442da 100644 --- a/redhawk/src/testing/cpp/SharedBufferTest.cpp +++ b/redhawk/src/testing/cpp/SharedBufferTest.cpp @@ -64,8 +64,8 @@ void SharedBufferTest::tearDown() void SharedBufferTest::testDefaultConstructor() { - // Empty shared buffer - redhawk::shared_buffer shared; + // Empty const shared buffer + const redhawk::shared_buffer shared; CPPUNIT_ASSERT(shared.size() == 0); CPPUNIT_ASSERT(shared.empty()); CPPUNIT_ASSERT_EQUAL(shared.begin(), shared.end()); @@ -110,6 +110,28 @@ void SharedBufferTest::testEquals() CPPUNIT_ASSERT(first != second); } +void SharedBufferTest::testIteration() +{ + // Create a buffer with known data + redhawk::buffer buffer(20); + for (unsigned long index = 0; index < buffer.size(); ++index) { + buffer[index] = index; + } + + // The distance between the begin and end iterators must be the same as the + // size, and iteration should yield the same result as sequential indexing + CPPUNIT_ASSERT(std::distance(buffer.begin(), buffer.end()) == buffer.size()); + size_t offset = 0; + for (redhawk::buffer::iterator iter = buffer.begin(); iter != buffer.end(); ++iter, ++offset) { + CPPUNIT_ASSERT_EQUAL(*iter, buffer[offset]); + } + + // Repeat, via a const shared buffer alias + const redhawk::shared_buffer shared = buffer; + CPPUNIT_ASSERT(std::distance(shared.begin(), shared.end()) == shared.size()); + CPPUNIT_ASSERT(std::equal(shared.begin(), shared.end(), buffer.begin())); +} + void SharedBufferTest::testSharing() { // Fill a new buffer @@ -118,8 +140,8 @@ void SharedBufferTest::testSharing() buffer[index] = std::complex(0.5, 0.5) * (double) index; } - // Create a shared buffer aliasing the original - redhawk::shared_buffer > shared = buffer; + // Create a const shared buffer aliasing the original + const redhawk::shared_buffer > shared = buffer; CPPUNIT_ASSERT(shared == buffer); // Conjugate values and ensure that the buffers are still equal @@ -137,13 +159,13 @@ void SharedBufferTest::testSlicing() // Take a 4-element slice from the middle and check that it points to the // same data (offset by the start index) - redhawk::shared_buffer middle = buffer.slice(4, 8); + const redhawk::shared_buffer middle = buffer.slice(4, 8); CPPUNIT_ASSERT_EQUAL(middle.size(), (size_t) 4); CPPUNIT_ASSERT(middle.data() == buffer.data() + 4); // Take a slice from the midpoint to the end, and check that the elements // match - redhawk::shared_buffer end = buffer.slice(6); + const redhawk::shared_buffer end = buffer.slice(6); CPPUNIT_ASSERT_EQUAL(end.size(), buffer.size() - 6); for (int index = 0; index < end.size(); ++index) { CPPUNIT_ASSERT_EQUAL(end[index], buffer[index + 6]); diff --git a/redhawk/src/testing/cpp/SharedBufferTest.h b/redhawk/src/testing/cpp/SharedBufferTest.h index fbf496a4a..6a1828057 100644 --- a/redhawk/src/testing/cpp/SharedBufferTest.h +++ b/redhawk/src/testing/cpp/SharedBufferTest.h @@ -9,6 +9,7 @@ class SharedBufferTest : public CppUnit::TestFixture CPPUNIT_TEST(testDefaultConstructor); CPPUNIT_TEST(testConstructor); CPPUNIT_TEST(testEquals); + CPPUNIT_TEST(testIteration); CPPUNIT_TEST(testSharing); CPPUNIT_TEST(testSlicing); CPPUNIT_TEST(testTrim); @@ -26,6 +27,7 @@ class SharedBufferTest : public CppUnit::TestFixture void testConstructor(); void testEquals(); + void testIteration(); void testSharing(); void testSlicing(); From 390120380474e96f68ca43612a20d6b317e3ed47 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 16 Sep 2016 16:06:27 -0400 Subject: [PATCH 0444/1644] Test shared buffer copy, with both default and custom allocators --- redhawk/src/testing/cpp/SharedBufferTest.cpp | 47 +++++++++++++++++++- redhawk/src/testing/cpp/SharedBufferTest.h | 8 ++++ 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/redhawk/src/testing/cpp/SharedBufferTest.cpp b/redhawk/src/testing/cpp/SharedBufferTest.cpp index 42a7442da..23c1ab20b 100644 --- a/redhawk/src/testing/cpp/SharedBufferTest.cpp +++ b/redhawk/src/testing/cpp/SharedBufferTest.cpp @@ -69,6 +69,12 @@ void SharedBufferTest::testDefaultConstructor() CPPUNIT_ASSERT(shared.size() == 0); CPPUNIT_ASSERT(shared.empty()); CPPUNIT_ASSERT_EQUAL(shared.begin(), shared.end()); + + // Empty regular buffer + redhawk::buffer buffer; + CPPUNIT_ASSERT(buffer.size() == 0); + CPPUNIT_ASSERT(buffer.empty()); + CPPUNIT_ASSERT_EQUAL(buffer.begin(), buffer.end()); } void SharedBufferTest::testConstructor() @@ -94,7 +100,7 @@ void SharedBufferTest::testEquals() std::fill(first.begin(), first.end(), 8); // Create a second, identical buffer and check that it is equal - redhawk::buffer second = first.copy(); + redhawk::buffer second(first.size()); std::copy(first.begin(), first.end(), second.begin()); CPPUNIT_ASSERT(first.data() != second.data()); CPPUNIT_ASSERT(first == second); @@ -132,6 +138,24 @@ void SharedBufferTest::testIteration() CPPUNIT_ASSERT(std::equal(shared.begin(), shared.end(), buffer.begin())); } +void SharedBufferTest::testCopy() +{ + // Create a buffer with known data + redhawk::buffer original(9); + for (size_t index = 0; index < original.size(); ++index) { + // Value is true if index is odd + original[index] = index & ~1; + } + + // Create a const shared buffer alias + const redhawk::shared_buffer buffer = original; + CPPUNIT_ASSERT(buffer.data() == original.data()); + + // Make a copy, and verify that it's a new underlying buffer + redhawk::buffer copy = buffer.copy(); + CPPUNIT_ASSERT(copy.data() != buffer.data()); +} + void SharedBufferTest::testSharing() { // Fill a new buffer @@ -267,6 +291,27 @@ void SharedBufferTest::testAllocator() CPPUNIT_ASSERT(std::count(arena.begin(), arena.end(), 0) == arena.size()); } +void SharedBufferTest::testAllocatorCopy() +{ + typedef CustomAllocator allocator_type; + + // Initialize source buffer + redhawk::buffer buffer(16); + for (size_t index = 0; index < buffer.size(); ++index) { + buffer[index] = index * 2.0 * M_PI / buffer.size(); + } + + // Over-allocate memory for the custom allocator, just to be safe + std::vector arena; + arena.resize(buffer.size() * sizeof(double) * 2); + + // Create a copy using the custom allocator, then ensure that the copy was + // allocated into our memory (and the copy is correct) + redhawk::shared_buffer copy = buffer.copy(allocator_type(&arena[0])); + CPPUNIT_ASSERT(reinterpret_cast(copy.data()) == &arena[0]); + CPPUNIT_ASSERT(copy == buffer); +} + void SharedBufferTest::testCustomDeleter() { // Local flag given to the custom deleter for checking when deletion has diff --git a/redhawk/src/testing/cpp/SharedBufferTest.h b/redhawk/src/testing/cpp/SharedBufferTest.h index 6a1828057..3f5aa1bbc 100644 --- a/redhawk/src/testing/cpp/SharedBufferTest.h +++ b/redhawk/src/testing/cpp/SharedBufferTest.h @@ -10,11 +10,13 @@ class SharedBufferTest : public CppUnit::TestFixture CPPUNIT_TEST(testConstructor); CPPUNIT_TEST(testEquals); CPPUNIT_TEST(testIteration); + CPPUNIT_TEST(testCopy); CPPUNIT_TEST(testSharing); CPPUNIT_TEST(testSlicing); CPPUNIT_TEST(testTrim); CPPUNIT_TEST(testRecast); CPPUNIT_TEST(testAllocator); + CPPUNIT_TEST(testAllocatorCopy); CPPUNIT_TEST(testCustomDeleter); CPPUNIT_TEST(testTransient); CPPUNIT_TEST_SUITE_END(); @@ -23,18 +25,24 @@ class SharedBufferTest : public CppUnit::TestFixture void setUp(); void tearDown(); + // Constructors void testDefaultConstructor(); void testConstructor(); + // Basic container behavior void testEquals(); void testIteration(); + void testCopy(); + // Extended container behavior void testSharing(); void testSlicing(); void testTrim(); void testRecast(); + // Advanced features void testAllocator(); + void testAllocatorCopy(); void testCustomDeleter(); void testTransient(); }; From 1ab9cec7bc600798f16235b09d09b7863d44502d Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 19 Sep 2016 13:23:58 -0400 Subject: [PATCH 0445/1644] Add a test for shared buffer swap() --- redhawk/src/testing/cpp/SharedBufferTest.cpp | 30 ++++++++++++++++++++ redhawk/src/testing/cpp/SharedBufferTest.h | 2 ++ 2 files changed, 32 insertions(+) diff --git a/redhawk/src/testing/cpp/SharedBufferTest.cpp b/redhawk/src/testing/cpp/SharedBufferTest.cpp index 23c1ab20b..38f312ab2 100644 --- a/redhawk/src/testing/cpp/SharedBufferTest.cpp +++ b/redhawk/src/testing/cpp/SharedBufferTest.cpp @@ -156,6 +156,36 @@ void SharedBufferTest::testCopy() CPPUNIT_ASSERT(copy.data() != buffer.data()); } +void SharedBufferTest::testSwap() +{ + // Create two mutable buffers with different contents + redhawk::buffer first(3); + std::fill(first.begin(), first.end(), 7); + CPPUNIT_ASSERT(std::count(first.begin(), first.end(), 7) == first.size()); + redhawk::buffer second(5); + std::fill(second.begin(), second.end(), -2); + CPPUNIT_ASSERT(std::count(second.begin(), second.end(), -2) == second.size()); + + // Swap them and check that the swap worked as expected + first.swap(second); + CPPUNIT_ASSERT(first.size() == 5); + CPPUNIT_ASSERT(first[0] == -2); + CPPUNIT_ASSERT(second.size() == 3); + CPPUNIT_ASSERT(second[0] == 7); + + // Create one shared buffer alias for each buffer + redhawk::shared_buffer shared_first = first; + CPPUNIT_ASSERT(shared_first.data() == first.data()); + redhawk::shared_buffer shared_second = second; + CPPUNIT_ASSERT(shared_second.data() == second.data()); + + // Swap the shared buffers and make sure that the underlying data pointers + // are correct + shared_first.swap(shared_second); + CPPUNIT_ASSERT(shared_first.data() == second.data()); + CPPUNIT_ASSERT(shared_second.data() == first.data()); +} + void SharedBufferTest::testSharing() { // Fill a new buffer diff --git a/redhawk/src/testing/cpp/SharedBufferTest.h b/redhawk/src/testing/cpp/SharedBufferTest.h index 3f5aa1bbc..7ac27fd0d 100644 --- a/redhawk/src/testing/cpp/SharedBufferTest.h +++ b/redhawk/src/testing/cpp/SharedBufferTest.h @@ -11,6 +11,7 @@ class SharedBufferTest : public CppUnit::TestFixture CPPUNIT_TEST(testEquals); CPPUNIT_TEST(testIteration); CPPUNIT_TEST(testCopy); + CPPUNIT_TEST(testSwap); CPPUNIT_TEST(testSharing); CPPUNIT_TEST(testSlicing); CPPUNIT_TEST(testTrim); @@ -33,6 +34,7 @@ class SharedBufferTest : public CppUnit::TestFixture void testEquals(); void testIteration(); void testCopy(); + void testSwap(); // Extended container behavior void testSharing(); From 32fd30f4d12a18214ead19804f146c156ef27eac Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 19 Sep 2016 14:00:34 -0400 Subject: [PATCH 0446/1644] Fix iterator-based trim for buffer class (same problem as was already fixed in shared_buffer); expand tests to cover more of buffer/shared_buffer interfaces. --- .../src/base/include/ossie/shared_buffer.h | 11 ++- redhawk/src/testing/cpp/SharedBufferTest.cpp | 75 ++++++++++++------- redhawk/src/testing/cpp/SharedBufferTest.h | 6 ++ 3 files changed, 63 insertions(+), 29 deletions(-) diff --git a/redhawk/src/base/include/ossie/shared_buffer.h b/redhawk/src/base/include/ossie/shared_buffer.h index a7c9dc4e2..b9495c743 100644 --- a/redhawk/src/base/include/ossie/shared_buffer.h +++ b/redhawk/src/base/include/ossie/shared_buffer.h @@ -683,12 +683,21 @@ namespace redhawk { read_type::trim(start, end); } + /** + * @brief Adjusts the beginning of this %buffer. + * @param start Iterator to first element. + */ + void trim(iterator first) + { + this->_M_trim(first, end()); + } + /** * @brief Adjusts the beginning and end of this %buffer. * @param start Iterator to first element. * @param end Iterator to last element, exclusive (default end). */ - void trim(iterator first, iterator last=end()) + void trim(iterator first, iterator last) { this->_M_trim(first, last); } diff --git a/redhawk/src/testing/cpp/SharedBufferTest.cpp b/redhawk/src/testing/cpp/SharedBufferTest.cpp index 38f312ab2..20a0a0cb8 100644 --- a/redhawk/src/testing/cpp/SharedBufferTest.cpp +++ b/redhawk/src/testing/cpp/SharedBufferTest.cpp @@ -153,7 +153,14 @@ void SharedBufferTest::testCopy() // Make a copy, and verify that it's a new underlying buffer redhawk::buffer copy = buffer.copy(); + CPPUNIT_ASSERT(copy == buffer); CPPUNIT_ASSERT(copy.data() != buffer.data()); + + // Make a second copy, exercising copy() from buffer (instead of + // shared_buffer) + redhawk::buffer second = copy.copy(); + CPPUNIT_ASSERT(second == buffer); + CPPUNIT_ASSERT(second.data() != copy.data()); } void SharedBufferTest::testSwap() @@ -229,38 +236,48 @@ void SharedBufferTest::testSlicing() CPPUNIT_ASSERT(middle.slice(2) == end.slice(0, 2)); } -void SharedBufferTest::testTrim() +template +void SharedBufferTest::testTrimImpl() { - // Fill a new buffer - redhawk::buffer buffer(10); - for (size_t index = 0; index < buffer.size(); ++index) { - buffer[index] = index; + redhawk::buffer original(10); + for (size_t index = 0; index < original.size(); ++index) { + original[index] = index; } - // Create a shared buffer alias, then trim one element off each end - redhawk::shared_buffer shared = buffer; - shared.trim(1, buffer.size() - 1); - CPPUNIT_ASSERT_EQUAL(shared.size(), buffer.size() - 2); - CPPUNIT_ASSERT(std::equal(shared.begin(), shared.end(), buffer.begin() + 1)); + // Create an alias of the template type, then trim one element off each end + Buffer buffer = original; + buffer.trim(1, original.size() - 1); + CPPUNIT_ASSERT_EQUAL(buffer.size(), original.size() - 2); + CPPUNIT_ASSERT(std::equal(buffer.begin(), buffer.end(), original.begin() + 1)); // Trim another element off the beginning - shared.trim(1); - CPPUNIT_ASSERT_EQUAL(shared.size(), buffer.size() - 3); - CPPUNIT_ASSERT(std::equal(shared.begin(), shared.end(), buffer.begin() + 2)); + buffer.trim(1); + CPPUNIT_ASSERT_EQUAL(buffer.size(), original.size() - 3); + CPPUNIT_ASSERT(std::equal(buffer.begin(), buffer.end(), original.begin() + 2)); // Iterator-based trim: find specific values and trim to [first, last) - redhawk::shared_buffer::iterator first = std::find(shared.begin(), shared.end(), 4); - redhawk::shared_buffer::iterator last = std::find(shared.begin(), shared.end(), 7); - CPPUNIT_ASSERT(first != shared.end()); - CPPUNIT_ASSERT(last != shared.end()); - shared.trim(first, last); - CPPUNIT_ASSERT(shared.size() == 3); - CPPUNIT_ASSERT_EQUAL(shared[0], (unsigned short) 4); + typename Buffer::iterator first = std::find(buffer.begin(), buffer.end(), 4); + typename Buffer::iterator last = std::find(buffer.begin(), buffer.end(), 7); + CPPUNIT_ASSERT(first != buffer.end()); + CPPUNIT_ASSERT(last != buffer.end()); + buffer.trim(first, last); + CPPUNIT_ASSERT(buffer.size() == 3); + CPPUNIT_ASSERT_EQUAL(buffer[0], (unsigned short) 4); // Use iterator-based trim to take another element off the beginning - shared.trim(shared.begin() + 1); - CPPUNIT_ASSERT(shared.size() == 2); - CPPUNIT_ASSERT_EQUAL(shared[0], (unsigned short) 5); + buffer.trim(buffer.begin() + 1); + CPPUNIT_ASSERT(buffer.size() == 2); + CPPUNIT_ASSERT_EQUAL(buffer[0], (unsigned short) 5); +} + +void SharedBufferTest::testTrim() +{ + testTrimImpl >(); +} + +void SharedBufferTest::testTrimShared() +{ + testTrimImpl >(); } void SharedBufferTest::testRecast() @@ -285,11 +302,13 @@ void SharedBufferTest::testRecast() CPPUNIT_ASSERT_EQUAL(cxbuffer[index/2].imag(), buffer[index+1]); } - // Recast into short; this is basically nonsensical, but technically valid, - // so only check that the size is correct - redhawk::shared_buffer shbuffer; - shbuffer = redhawk::shared_buffer::recast(buffer); - CPPUNIT_ASSERT_EQUAL(shbuffer.size(), buffer.size() * 2); + // Recast into short, this time using buffer::recast (such that the result + // is mutable); this is basically nonsensical, but technically valid, so + // only check that the data pointer and size are correct + redhawk::buffer short_buffer; + short_buffer = redhawk::buffer::recast(buffer); + CPPUNIT_ASSERT_EQUAL((void*) short_buffer.data(), (void*) buffer.data()); + CPPUNIT_ASSERT_EQUAL(short_buffer.size(), buffer.size() * 2); } void SharedBufferTest::testAllocator() diff --git a/redhawk/src/testing/cpp/SharedBufferTest.h b/redhawk/src/testing/cpp/SharedBufferTest.h index 7ac27fd0d..6e8146343 100644 --- a/redhawk/src/testing/cpp/SharedBufferTest.h +++ b/redhawk/src/testing/cpp/SharedBufferTest.h @@ -15,6 +15,7 @@ class SharedBufferTest : public CppUnit::TestFixture CPPUNIT_TEST(testSharing); CPPUNIT_TEST(testSlicing); CPPUNIT_TEST(testTrim); + CPPUNIT_TEST(testTrimShared); CPPUNIT_TEST(testRecast); CPPUNIT_TEST(testAllocator); CPPUNIT_TEST(testAllocatorCopy); @@ -40,6 +41,7 @@ class SharedBufferTest : public CppUnit::TestFixture void testSharing(); void testSlicing(); void testTrim(); + void testTrimShared(); void testRecast(); // Advanced features @@ -47,6 +49,10 @@ class SharedBufferTest : public CppUnit::TestFixture void testAllocatorCopy(); void testCustomDeleter(); void testTransient(); + +private: + template + void testTrimImpl(); }; #endif // SHARED_BUFFER_TEST_H From 36e194a12790e28bb35dbfe152cbf0c509f12f15 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 20 Sep 2016 13:14:06 -0400 Subject: [PATCH 0447/1644] Add interface to redhawk::Value to get the type as a C++ enumeration, to allow for better inspection of properties prior to trying to extract values --- redhawk/src/base/framework/CorbaUtils.cpp | 9 ++++ redhawk/src/base/framework/Value.cpp | 57 ++++++++++++++++++++ redhawk/src/base/include/ossie/CorbaUtils.h | 2 + redhawk/src/base/include/ossie/Value.h | 26 +++++++++ redhawk/src/control/framework/prop_utils.cpp | 18 ++++--- 5 files changed, 104 insertions(+), 8 deletions(-) diff --git a/redhawk/src/base/framework/CorbaUtils.cpp b/redhawk/src/base/framework/CorbaUtils.cpp index 211040f08..8a1601c27 100644 --- a/redhawk/src/base/framework/CorbaUtils.cpp +++ b/redhawk/src/base/framework/CorbaUtils.cpp @@ -150,6 +150,15 @@ bool isPersistenceEnabled () return persistenceEnabled; } +CORBA::TypeCode_ptr unalias(CORBA::TypeCode_ptr type) +{ + if (type->kind() == CORBA::tk_alias) { + return type->content_type(); + } else { + return CORBA::TypeCode::_duplicate(type); + } +} + bool isValidType (const CORBA::Any& lhs, const CORBA::Any& rhs) { CORBA::TypeCode_var tc1 = lhs.type(); diff --git a/redhawk/src/base/framework/Value.cpp b/redhawk/src/base/framework/Value.cpp index 9761f72b4..66ee7e3b9 100644 --- a/redhawk/src/base/framework/Value.cpp +++ b/redhawk/src/base/framework/Value.cpp @@ -50,6 +50,63 @@ Value& Value::operator=(const Value& any) return operator=(static_cast(any)); } +Value::Type Value::getType(CORBA::TypeCode_ptr typecode) +{ + if (CF::_tc_Properties->equivalent(typecode)) { + return TYPE_PROPERTIES; + } else if (CF::_tc_DataType->equivalent(typecode)) { + return TYPE_DATATYPE; + } else if (CORBA::_tc_AnySeq->equivalent(typecode)) { + return TYPE_VALUE_SEQUENCE; + } + + // Remove any aliases + CORBA::TypeCode_var base_type = ossie::corba::unalias(typecode); + switch (base_type->kind()) { + case CORBA::tk_null: return TYPE_NONE; + case CORBA::tk_boolean: return TYPE_BOOLEAN; + case CORBA::tk_octet: return TYPE_OCTET; + case CORBA::tk_short: return TYPE_SHORT; + case CORBA::tk_ushort: return TYPE_USHORT; + case CORBA::tk_long: return TYPE_LONG; + case CORBA::tk_ulong: return TYPE_ULONG; + case CORBA::tk_longlong: return TYPE_LONGLONG; + case CORBA::tk_ulonglong: return TYPE_ULONGLONG; + case CORBA::tk_float: return TYPE_FLOAT; + case CORBA::tk_double: return TYPE_DOUBLE; + case CORBA::tk_string: return TYPE_STRING; + case CORBA::tk_sequence: return TYPE_SEQUENCE; + case CORBA::tk_any: return TYPE_VALUE; + default: + return TYPE_OTHER; + } +} + +Value::Type Value::getType() const +{ + CORBA::TypeCode_var any_type = type(); + return getType(any_type); +} + +bool Value::isSequence() const +{ + CORBA::TypeCode_var any_type = type(); + any_type = ossie::corba::unalias(any_type); + return (any_type->kind() == CORBA::tk_sequence); +} + +Value::Type Value::getElementType() const +{ + CORBA::TypeCode_var any_type = type(); + any_type = ossie::corba::unalias(any_type); + if (any_type->kind() != CORBA::tk_sequence) { + return TYPE_NONE; + } + + CORBA::TypeCode_var element_type = any_type->content_type(); + return getType(element_type); +} + std::string Value::toString() const { return ossie::any_to_string(*this); diff --git a/redhawk/src/base/include/ossie/CorbaUtils.h b/redhawk/src/base/include/ossie/CorbaUtils.h index b1fcddc02..bb9831e63 100644 --- a/redhawk/src/base/include/ossie/CorbaUtils.h +++ b/redhawk/src/base/include/ossie/CorbaUtils.h @@ -204,6 +204,8 @@ namespace ossie { return std::string(static_cast(corbaString)); } + CORBA::TypeCode_ptr unalias(CORBA::TypeCode_ptr type); + bool isValidType (const CORBA::Any& lhs, const CORBA::Any& rhs); inline bool objectExists(CORBA::Object_ptr obj) { diff --git a/redhawk/src/base/include/ossie/Value.h b/redhawk/src/base/include/ossie/Value.h index d2bc26bc3..1b9c31f0f 100644 --- a/redhawk/src/base/include/ossie/Value.h +++ b/redhawk/src/base/include/ossie/Value.h @@ -31,6 +31,26 @@ namespace redhawk { class Value : public CORBA::Any { public: + enum Type { + TYPE_NONE, + TYPE_STRING, + TYPE_BOOLEAN, + TYPE_FLOAT, + TYPE_DOUBLE, + TYPE_OCTET, + TYPE_SHORT, + TYPE_USHORT, + TYPE_LONG, + TYPE_ULONG, + TYPE_LONGLONG, + TYPE_ULONGLONG, + TYPE_DATATYPE, + TYPE_VALUE, + TYPE_SEQUENCE, + TYPE_VALUE_SEQUENCE, + TYPE_PROPERTIES, + TYPE_OTHER + }; Value(); explicit Value(const CORBA::Any& any); @@ -62,6 +82,12 @@ namespace redhawk { return *this; } + static Type getType(CORBA::TypeCode_ptr typecode); + + Type getType() const; + bool isSequence() const; + Type getElementType() const; + std::string toString() const; bool toBoolean() const; float toFloat() const; diff --git a/redhawk/src/control/framework/prop_utils.cpp b/redhawk/src/control/framework/prop_utils.cpp index 59bcff84f..a38728dfd 100644 --- a/redhawk/src/control/framework/prop_utils.cpp +++ b/redhawk/src/control/framework/prop_utils.cpp @@ -686,21 +686,23 @@ CF::Properties ossie::getPartialStructs(const CF::Properties& properties) CF::Properties partials; const redhawk::PropertyMap& configProps = redhawk::PropertyMap::cast(properties); for (redhawk::PropertyMap::const_iterator prop = configProps.begin(); prop != configProps.end(); ++prop) { - CORBA::TypeCode_var type = prop->getValue().type(); - if (CORBA::_tc_AnySeq->equivalent(type)) { + redhawk::Value::Type type = prop->getValue().getType(); + if (type == redhawk::Value::TYPE_PROPERTIES) { + // Property is a struct + if (ossie::structContainsMixedNilValues(prop->getValue().asProperties())) { + ossie::corba::push_back(partials, *prop); + } + } else if (type == redhawk::Value::TYPE_VALUE_SEQUENCE) { + // Property is a struct sequence const redhawk::ValueSequence& sequence = prop->getValue().asSequence(); for (redhawk::ValueSequence::const_iterator item = sequence.begin(); item != sequence.end(); ++item) { - type = item->type(); - if (CF::_tc_Properties->equivalent(type)) { + if (item->getType() == redhawk::Value::TYPE_PROPERTIES) { if (ossie::structContainsMixedNilValues(item->asProperties())) { ossie::corba::push_back(partials, *prop); + continue; } } } - } else if (CF::_tc_Properties->equivalent(type)) { - if (ossie::structContainsMixedNilValues(prop->getValue().asProperties())) { - ossie::corba::push_back(partials, *prop); - } } } return partials; From 5780f650b1eb269d04173fc18e4fb16da26b6b61 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 20 Sep 2016 14:24:09 -0400 Subject: [PATCH 0448/1644] Use PropertyMap::get() instead of find() --- redhawk/src/base/framework/LoadableDevice_impl.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/redhawk/src/base/framework/LoadableDevice_impl.cpp b/redhawk/src/base/framework/LoadableDevice_impl.cpp index 63e2fc3f8..4036bf752 100644 --- a/redhawk/src/base/framework/LoadableDevice_impl.cpp +++ b/redhawk/src/base/framework/LoadableDevice_impl.cpp @@ -597,10 +597,8 @@ void LoadableDevice_impl::_loadTree(CF::FileSystem_ptr fs, std::string remotePat _copyFile(fs, remotePath, localFile.string(), fileKey); } const redhawk::PropertyMap& fileprops = redhawk::PropertyMap::cast(fis[i].fileProperties); - redhawk::PropertyMap::const_iterator iter_fileprops = fileprops.find("EXECUTABLE"); - if (iter_fileprops != fileprops.end()) { - if (fileprops["EXECUTABLE"].toBoolean()) - chmod(localFile.string().c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); + if (fileprops.get("EXECUTABLE", false).toBoolean()) { + chmod(localFile.string().c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); } } else if (fis[i].kind == CF::FileSystem::DIRECTORY) { std::string directoryName(fis[i].name); From 598a0d22f6bc4179064512797b73404a94923077 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 20 Sep 2016 16:35:31 -0400 Subject: [PATCH 0449/1644] Add a way to check if a redhawk::Value is of a numeric type --- redhawk/src/base/framework/Value.cpp | 24 ++++++++++++++++++++++++ redhawk/src/base/include/ossie/Value.h | 2 ++ 2 files changed, 26 insertions(+) diff --git a/redhawk/src/base/framework/Value.cpp b/redhawk/src/base/framework/Value.cpp index 66ee7e3b9..fd4c84b43 100644 --- a/redhawk/src/base/framework/Value.cpp +++ b/redhawk/src/base/framework/Value.cpp @@ -82,12 +82,36 @@ Value::Type Value::getType(CORBA::TypeCode_ptr typecode) } } +bool Value::IsNumeric(Type type) +{ + switch (type) { + case TYPE_BOOLEAN: + case TYPE_OCTET: + case TYPE_SHORT: + case TYPE_USHORT: + case TYPE_LONG: + case TYPE_ULONG: + case TYPE_LONGLONG: + case TYPE_ULONGLONG: + case TYPE_FLOAT: + case TYPE_DOUBLE: + return true; + default: + return false; + } +} + Value::Type Value::getType() const { CORBA::TypeCode_var any_type = type(); return getType(any_type); } +bool Value::isNumeric() const +{ + return Value::IsNumeric(getType()); +} + bool Value::isSequence() const { CORBA::TypeCode_var any_type = type(); diff --git a/redhawk/src/base/include/ossie/Value.h b/redhawk/src/base/include/ossie/Value.h index 1b9c31f0f..c1b2b2f1a 100644 --- a/redhawk/src/base/include/ossie/Value.h +++ b/redhawk/src/base/include/ossie/Value.h @@ -83,8 +83,10 @@ namespace redhawk { } static Type getType(CORBA::TypeCode_ptr typecode); + static bool IsNumeric(Type type); Type getType() const; + bool isNumeric() const; bool isSequence() const; Type getElementType() const; From 464377b1b18986bcc3debb3fc666ea4a2a4465f1 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 20 Sep 2016 16:41:40 -0400 Subject: [PATCH 0450/1644] Disambiguate static/member version of redhawk::Value type functions --- redhawk/src/base/framework/Value.cpp | 6 +++--- redhawk/src/base/include/ossie/Value.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/redhawk/src/base/framework/Value.cpp b/redhawk/src/base/framework/Value.cpp index fd4c84b43..f4e4e636a 100644 --- a/redhawk/src/base/framework/Value.cpp +++ b/redhawk/src/base/framework/Value.cpp @@ -50,7 +50,7 @@ Value& Value::operator=(const Value& any) return operator=(static_cast(any)); } -Value::Type Value::getType(CORBA::TypeCode_ptr typecode) +Value::Type Value::GetType(CORBA::TypeCode_ptr typecode) { if (CF::_tc_Properties->equivalent(typecode)) { return TYPE_PROPERTIES; @@ -104,7 +104,7 @@ bool Value::IsNumeric(Type type) Value::Type Value::getType() const { CORBA::TypeCode_var any_type = type(); - return getType(any_type); + return Value::GetType(any_type); } bool Value::isNumeric() const @@ -128,7 +128,7 @@ Value::Type Value::getElementType() const } CORBA::TypeCode_var element_type = any_type->content_type(); - return getType(element_type); + return Value::GetType(element_type); } std::string Value::toString() const diff --git a/redhawk/src/base/include/ossie/Value.h b/redhawk/src/base/include/ossie/Value.h index c1b2b2f1a..1a0cea963 100644 --- a/redhawk/src/base/include/ossie/Value.h +++ b/redhawk/src/base/include/ossie/Value.h @@ -82,7 +82,7 @@ namespace redhawk { return *this; } - static Type getType(CORBA::TypeCode_ptr typecode); + static Type GetType(CORBA::TypeCode_ptr typecode); static bool IsNumeric(Type type); Type getType() const; From a3e72d8ec1846f8b499b121a813f68d287d44a3f Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 22 Sep 2016 11:11:20 -0400 Subject: [PATCH 0451/1644] Add CppUnit testing for redhawk::Value class --- redhawk/src/testing/cpp/.gitignore | 1 + redhawk/src/testing/cpp/Makefile.am | 7 +- redhawk/src/testing/cpp/ValueTest.cpp | 225 ++++++++++++++++++++ redhawk/src/testing/cpp/ValueTest.h | 30 +++ redhawk/src/testing/cpp/test_libossiecf.cpp | 27 +++ 5 files changed, 289 insertions(+), 1 deletion(-) create mode 100644 redhawk/src/testing/cpp/ValueTest.cpp create mode 100644 redhawk/src/testing/cpp/ValueTest.h create mode 100644 redhawk/src/testing/cpp/test_libossiecf.cpp diff --git a/redhawk/src/testing/cpp/.gitignore b/redhawk/src/testing/cpp/.gitignore index 6827d9fdf..3055470f1 100644 --- a/redhawk/src/testing/cpp/.gitignore +++ b/redhawk/src/testing/cpp/.gitignore @@ -1 +1,2 @@ standalone +test_libossiecf diff --git a/redhawk/src/testing/cpp/Makefile.am b/redhawk/src/testing/cpp/Makefile.am index 20249f864..f48da5036 100644 --- a/redhawk/src/testing/cpp/Makefile.am +++ b/redhawk/src/testing/cpp/Makefile.am @@ -1,6 +1,11 @@ -TESTS = standalone +TESTS = standalone test_libossiecf check_PROGRAMS = $(TESTS) + standalone_SOURCES = standalone.cpp SharedBufferTest.cpp SharedBufferTest.h standalone_CXXFLAGS = $(CPPUNIT_CFLAGS) -I $(top_srcdir)/base/include standalone_LDFLAGS = $(CPPUNIT_LIBS) + +test_libossiecf_SOURCES = test_libossiecf.cpp ValueTest.cpp ValueTest.h +test_libossiecf_CXXFLAGS = $(CPPUNIT_CFLAGS) -I $(top_srcdir)/base/include +test_libossiecf_LDFLAGS = $(CPPUNIT_LIBS) $(top_builddir)/base/framework/libossiecf.la $(top_builddir)/base/framework/idl/libossieidl.la diff --git a/redhawk/src/testing/cpp/ValueTest.cpp b/redhawk/src/testing/cpp/ValueTest.cpp new file mode 100644 index 000000000..dd9a5f8b4 --- /dev/null +++ b/redhawk/src/testing/cpp/ValueTest.cpp @@ -0,0 +1,225 @@ +#include "ValueTest.h" + +#include +#include + +#include + +CPPUNIT_TEST_SUITE_REGISTRATION(ValueTest); + +void ValueTest::setUp() +{ +} + +void ValueTest::tearDown() +{ +} + +void ValueTest::testConstructor() +{ + // This test is mostly to make sure that the constructors for all supported + // types compile. + + // Start with an empty value + { + redhawk::Value value; + CPPUNIT_ASSERT(value.isNil()); + } + + // NB: The CORBA C++ mapping does not allow directly setting an octet value, + // nor does it have true 8-bit numeric types. Use the helper to insert an + // octet for the purposes of testing. + { + redhawk::Value value(CORBA::Any::from_octet(0)); + CPPUNIT_ASSERT_MESSAGE("Octet constructor", !value.isNil()); + } + + // Numeric and common sequence types +#define ASSERT_CTOR(x, v) \ + { \ + redhawk::Value value((x) v); \ + CPPUNIT_ASSERT_MESSAGE(#x " constructor", !value.isNil()); \ + } + ASSERT_CTOR(CORBA::Short, 0); + ASSERT_CTOR(CORBA::UShort, 0); + ASSERT_CTOR(CORBA::Long, 0); + ASSERT_CTOR(CORBA::ULong, 0); + ASSERT_CTOR(CORBA::LongLong, 0); + ASSERT_CTOR(CORBA::ULongLong, 0); + ASSERT_CTOR(CORBA::Float, 0.0); + ASSERT_CTOR(CORBA::Double, 0.0); + ASSERT_CTOR(std::string, "abc"); + + CORBA::AnySeq anys; + ASSERT_CTOR(CORBA::AnySeq, anys); + + CF::Properties properties; + ASSERT_CTOR(CF::Properties, properties); +} + +void ValueTest::testType() +{ + redhawk::Value value; + CPPUNIT_ASSERT(value.getType() == redhawk::Value::TYPE_NONE); + CPPUNIT_ASSERT(!value.isNumeric()); + CPPUNIT_ASSERT(!value.isSequence()); + + value = std::string("test"); + CPPUNIT_ASSERT_EQUAL(value.getType(), redhawk::Value::TYPE_STRING); + CPPUNIT_ASSERT(!value.isNumeric()); + CPPUNIT_ASSERT(!value.isSequence()); + +#define ASSERT_BASIC_NUMERIC(v, t) \ + CPPUNIT_ASSERT_EQUAL(v.getType(), t); \ + CPPUNIT_ASSERT(v.isNumeric()); \ + CPPUNIT_ASSERT(!v.isSequence()); + + value = true; + ASSERT_BASIC_NUMERIC(value, redhawk::Value::TYPE_BOOLEAN); + + // See testConstructor() for note about octet. + value = CORBA::Any::from_octet(1); + ASSERT_BASIC_NUMERIC(value, redhawk::Value::TYPE_OCTET); + + value = (CORBA::Short) -2; + ASSERT_BASIC_NUMERIC(value, redhawk::Value::TYPE_SHORT); + + value = (CORBA::UShort) 3; + ASSERT_BASIC_NUMERIC(value, redhawk::Value::TYPE_USHORT); + + value = (CORBA::Long) -4; + ASSERT_BASIC_NUMERIC(value, redhawk::Value::TYPE_LONG); + + value = (CORBA::ULong) 5; + ASSERT_BASIC_NUMERIC(value, redhawk::Value::TYPE_ULONG); + + value = (CORBA::LongLong) -6; + ASSERT_BASIC_NUMERIC(value, redhawk::Value::TYPE_LONGLONG); + + value = (CORBA::ULongLong) 7; + ASSERT_BASIC_NUMERIC(value, redhawk::Value::TYPE_ULONGLONG); + + value = (CORBA::Float) -8.0; + ASSERT_BASIC_NUMERIC(value, redhawk::Value::TYPE_FLOAT); + + value = (CORBA::Double) 1e100; + ASSERT_BASIC_NUMERIC(value, redhawk::Value::TYPE_DOUBLE); + + value = CORBA::AnySeq(); + CPPUNIT_ASSERT_EQUAL(value.getType(), redhawk::Value::TYPE_VALUE_SEQUENCE); + CPPUNIT_ASSERT(!value.isNumeric()); + CPPUNIT_ASSERT(value.isSequence()); + CPPUNIT_ASSERT_EQUAL(value.getElementType(), redhawk::Value::TYPE_VALUE); + + value = CF::Properties(); + CPPUNIT_ASSERT_EQUAL(value.getType(), redhawk::Value::TYPE_PROPERTIES); + CPPUNIT_ASSERT(!value.isNumeric()); + CPPUNIT_ASSERT(value.isSequence()); + CPPUNIT_ASSERT_EQUAL(value.getElementType(), redhawk::Value::TYPE_DATATYPE); +} + +void ValueTest::testNumericConversion() +{ + // Boolean conversion from case-insensitive string literals and numbers + // (where zero is false and non-zero is true) + CPPUNIT_ASSERT_EQUAL(true, redhawk::Value("True").toBoolean()); + CPPUNIT_ASSERT_EQUAL(false, redhawk::Value("false").toBoolean()); + CPPUNIT_ASSERT_EQUAL(true, redhawk::Value(-1).toBoolean()); + CPPUNIT_ASSERT_EQUAL(false, redhawk::Value(0).toBoolean()); + + // Octet conversion from string, int and double; range test + CPPUNIT_ASSERT_EQUAL((CORBA::Octet) 222, redhawk::Value("222").toOctet()); + CPPUNIT_ASSERT_EQUAL((CORBA::Octet) 1, redhawk::Value(1).toOctet()); + CPPUNIT_ASSERT_EQUAL((CORBA::Octet) 125, redhawk::Value(125.5).toOctet()); + CPPUNIT_ASSERT_THROW(redhawk::Value(-1).toOctet(), std::range_error); + CPPUNIT_ASSERT_THROW(redhawk::Value(256).toOctet(), std::range_error); + + // Short conversion from string, int and double; range test + CPPUNIT_ASSERT_EQUAL((CORBA::Short) -25000, redhawk::Value("-25000").toShort()); + CPPUNIT_ASSERT_EQUAL((CORBA::Short) 1, redhawk::Value(1).toShort()); + CPPUNIT_ASSERT_EQUAL((CORBA::Short) 16000, redhawk::Value(16000.1).toShort()); + CPPUNIT_ASSERT_THROW(redhawk::Value(65536).toShort(), std::range_error); + + // UShort conversion from string, int and double; range test + CPPUNIT_ASSERT_EQUAL((CORBA::UShort) 60000, redhawk::Value("60000").toUShort()); + CPPUNIT_ASSERT_EQUAL((CORBA::UShort) 1, redhawk::Value(1).toUShort()); + CPPUNIT_ASSERT_EQUAL((CORBA::UShort) 50000, redhawk::Value(50000.999).toUShort()); + CPPUNIT_ASSERT_THROW(redhawk::Value(-1).toUShort(), std::range_error); + CPPUNIT_ASSERT_THROW(redhawk::Value(65536).toUShort(), std::range_error); + + // Long conversion from string, short and double; range test + CPPUNIT_ASSERT_EQUAL((CORBA::Long) -262144, redhawk::Value("-262144").toLong()); + CPPUNIT_ASSERT_EQUAL((CORBA::Long) 1, redhawk::Value((short) 1).toLong()); + CPPUNIT_ASSERT_EQUAL((CORBA::Long) 100000000, redhawk::Value(1e8).toLong()); + CPPUNIT_ASSERT_THROW(redhawk::Value(1e10).toLong(), std::range_error); + CPPUNIT_ASSERT_THROW(redhawk::Value(-1e10).toLong(), std::range_error); + + // ULong conversion from string, int and double; range test + CPPUNIT_ASSERT_EQUAL((CORBA::ULong) 4294967295, redhawk::Value("4294967295").toULong()); + CPPUNIT_ASSERT_EQUAL((CORBA::ULong) 1, redhawk::Value(1).toULong()); + CPPUNIT_ASSERT_EQUAL((CORBA::ULong) 3000000000, redhawk::Value(3e9).toULong()); + CPPUNIT_ASSERT_THROW(redhawk::Value(-1).toULong(), std::range_error); + CPPUNIT_ASSERT_THROW(redhawk::Value(4294967296L).toULong(), std::range_error); + + // LongLong conversion from string, int and double; range test + CPPUNIT_ASSERT_EQUAL((CORBA::LongLong) 1099511627776L, redhawk::Value("1099511627776").toLongLong()); + CPPUNIT_ASSERT_EQUAL((CORBA::LongLong) 1, redhawk::Value(1).toLongLong()); + CPPUNIT_ASSERT_EQUAL((CORBA::LongLong) 10000000000, redhawk::Value(1e10).toLongLong()); + CPPUNIT_ASSERT_THROW(redhawk::Value(1e19).toLongLong(), std::range_error); + CPPUNIT_ASSERT_THROW(redhawk::Value(-1e19).toLongLong(), std::range_error); + + // ULongLong conversion from string, boolean and double; range test + CPPUNIT_ASSERT_EQUAL((CORBA::ULongLong) 9223372036854775808UL, redhawk::Value("9223372036854775808").toULongLong()); + CPPUNIT_ASSERT_EQUAL((CORBA::ULongLong) 1, redhawk::Value(true).toULongLong()); + CPPUNIT_ASSERT_EQUAL((CORBA::ULongLong) 500000000000, redhawk::Value(5e11).toULongLong()); + CPPUNIT_ASSERT_THROW(redhawk::Value(-1).toULongLong(), std::range_error); + CPPUNIT_ASSERT_THROW(redhawk::Value(1e20).toULongLong(), std::range_error); +} + +void ValueTest::testStringConversion() +{ + // Not defined: TYPE_NONE, TYPE_VALUE_SEQUENCE + // Not tested: TYPE_PROPERTIES + + // Boolean + // NB: This would probably be more helpful if it were "true" and "false" + CPPUNIT_ASSERT_EQUAL(std::string("1"), redhawk::Value(true).toString()); + CPPUNIT_ASSERT_EQUAL(std::string("0"), redhawk::Value(false).toString()); + + // Octet (we have to use from_octet because of ambiguity in any insertion; + // see above) + CPPUNIT_ASSERT_EQUAL(std::string("255"), redhawk::Value(CORBA::Any::from_octet(255)).toString()); + + // Integer numeric types + CPPUNIT_ASSERT_EQUAL(std::string("-16000"), redhawk::Value((CORBA::Short) -16000).toString()); + CPPUNIT_ASSERT_EQUAL(std::string("65535"), redhawk::Value((CORBA::UShort) 65535).toString()); + CPPUNIT_ASSERT_EQUAL(std::string("-200000"), redhawk::Value((CORBA::Long) -200000).toString()); + CPPUNIT_ASSERT_EQUAL(std::string("4294967295"), redhawk::Value((CORBA::ULong) 4294967295).toString()); + CPPUNIT_ASSERT_EQUAL(std::string("-5000000000"), redhawk::Value((CORBA::LongLong) -5000000000L).toString()); + CPPUNIT_ASSERT_EQUAL(std::string("9223372036854775808"), redhawk::Value((CORBA::ULongLong) 9223372036854775808UL).toString()); + + // Floating point numeric types--this is a little more fragile because it + // depends on the specific output format + CPPUNIT_ASSERT_EQUAL(std::string("5.125"), redhawk::Value((CORBA::Float) 5.125).toString()); + CPPUNIT_ASSERT_EQUAL(std::string("-2.25e+40"), redhawk::Value((CORBA::Double) -2.25e40).toString()); +} + +void ValueTest::testCast() +{ + CORBA::Any any; + const double dval = 1.25; + any <<= dval; + + // Create a Value alias and check that it matches the Any + redhawk::Value& value = redhawk::Value::cast(any); + CPPUNIT_ASSERT_EQUAL(redhawk::Value::TYPE_DOUBLE, value.getType()); + CPPUNIT_ASSERT_EQUAL(dval, value.toDouble()); + + // Set the value to nil and check that the Any was modified (ergo, they + // are both the same object) + CPPUNIT_ASSERT(!ossie::any::isNull(any)); + CPPUNIT_ASSERT(!value.isNil()); + value = redhawk::Value(); + CPPUNIT_ASSERT(value.isNil()); + CPPUNIT_ASSERT(ossie::any::isNull(any)); +} diff --git a/redhawk/src/testing/cpp/ValueTest.h b/redhawk/src/testing/cpp/ValueTest.h new file mode 100644 index 000000000..96251369a --- /dev/null +++ b/redhawk/src/testing/cpp/ValueTest.h @@ -0,0 +1,30 @@ +#ifndef VALUETEST_H +#define VALUETEST_H + +#include + +class ValueTest : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE(ValueTest); + CPPUNIT_TEST(testConstructor); + CPPUNIT_TEST(testType); + CPPUNIT_TEST(testNumericConversion); + CPPUNIT_TEST(testStringConversion); + CPPUNIT_TEST(testCast); + CPPUNIT_TEST_SUITE_END(); + +public: + void setUp(); + void tearDown(); + + void testConstructor(); + + void testType(); + + void testNumericConversion(); + void testStringConversion(); + + void testCast(); +}; + +#endif // VALUETEST_H diff --git a/redhawk/src/testing/cpp/test_libossiecf.cpp b/redhawk/src/testing/cpp/test_libossiecf.cpp new file mode 100644 index 000000000..aa649d525 --- /dev/null +++ b/redhawk/src/testing/cpp/test_libossiecf.cpp @@ -0,0 +1,27 @@ +#include +#include +#include + +#include + +int main(int argc, char* argv[]) +{ + // Initialize the CORBA ORB, which is a prerequisite for some uses of the + // Value and PropertyMap classes + ossie::corba::OrbInit(argc, argv, false); + + // Get the top level suite from the registry + CppUnit::Test* suite = CppUnit::TestFactoryRegistry::getRegistry().makeTest(); + + // Adds the test to the list of test to run + CppUnit::TextUi::TestRunner runner; + runner.addTest(suite); + + // Change the default outputter to a compiler error format outputter + runner.setOutputter(new CppUnit::CompilerOutputter(&runner.result(), std::cerr)); + // Run the tests. + bool wasSucessful = runner.run(); + + // Return error code 1 if the one of test failed. + return wasSucessful ? 0 : 1; +} From 12f0afee04d150e2796c4fe1e59f2ad6f95d70a8 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 22 Sep 2016 12:48:42 -0400 Subject: [PATCH 0452/1644] Add CppUnit testing for redhawk::ValueSequence class --- redhawk/src/testing/cpp/Makefile.am | 4 +- redhawk/src/testing/cpp/ValueSequenceTest.cpp | 208 ++++++++++++++++++ redhawk/src/testing/cpp/ValueSequenceTest.h | 44 ++++ 3 files changed, 255 insertions(+), 1 deletion(-) create mode 100644 redhawk/src/testing/cpp/ValueSequenceTest.cpp create mode 100644 redhawk/src/testing/cpp/ValueSequenceTest.h diff --git a/redhawk/src/testing/cpp/Makefile.am b/redhawk/src/testing/cpp/Makefile.am index f48da5036..62fc26b20 100644 --- a/redhawk/src/testing/cpp/Makefile.am +++ b/redhawk/src/testing/cpp/Makefile.am @@ -6,6 +6,8 @@ standalone_SOURCES = standalone.cpp SharedBufferTest.cpp SharedBufferTest.h standalone_CXXFLAGS = $(CPPUNIT_CFLAGS) -I $(top_srcdir)/base/include standalone_LDFLAGS = $(CPPUNIT_LIBS) -test_libossiecf_SOURCES = test_libossiecf.cpp ValueTest.cpp ValueTest.h +test_libossiecf_SOURCES = test_libossiecf.cpp +test_libossiecf_SOURCES += ValueTest.cpp ValueTest.h +test_libossiecf_SOURCES += ValueSequenceTest.cpp ValueSequenceTest.h test_libossiecf_CXXFLAGS = $(CPPUNIT_CFLAGS) -I $(top_srcdir)/base/include test_libossiecf_LDFLAGS = $(CPPUNIT_LIBS) $(top_builddir)/base/framework/libossiecf.la $(top_builddir)/base/framework/idl/libossieidl.la diff --git a/redhawk/src/testing/cpp/ValueSequenceTest.cpp b/redhawk/src/testing/cpp/ValueSequenceTest.cpp new file mode 100644 index 000000000..866d325fc --- /dev/null +++ b/redhawk/src/testing/cpp/ValueSequenceTest.cpp @@ -0,0 +1,208 @@ +#include "ValueSequenceTest.h" + +#include +#include + +#include + +CPPUNIT_TEST_SUITE_REGISTRATION(ValueSequenceTest); + +void ValueSequenceTest::setUp() +{ +} + +void ValueSequenceTest::tearDown() +{ +} + +void ValueSequenceTest::testDefaultConstructor() +{ + redhawk::ValueSequence values; + CPPUNIT_ASSERT(values.empty()); + CPPUNIT_ASSERT_EQUAL((size_t) 0, values.size()); +} + +void ValueSequenceTest::testAnySeqConstructor() +{ + CORBA::AnySeq anys; + anys.length(1); + redhawk::ValueSequence values(anys); + CPPUNIT_ASSERT(!values.empty()); + CPPUNIT_ASSERT_EQUAL((size_t) anys.length(), values.size()); +} + +void ValueSequenceTest::testConstCast() +{ + CORBA::AnySeq anys; + anys.length(2); + anys[0] <<= "abc"; + anys[1] <<= 1.0; + + // Create a const ValueSequence reference alias and check the values + const CORBA::AnySeq& const_anys = anys; + const redhawk::ValueSequence& values = redhawk::ValueSequence::cast(const_anys); + CPPUNIT_ASSERT(!values.empty()); + CPPUNIT_ASSERT_EQUAL((size_t) anys.length(), values.size()); + CPPUNIT_ASSERT_EQUAL(std::string("abc"), values[0].toString()); + CPPUNIT_ASSERT_EQUAL(1.0, values[1].toDouble()); + + // Modify the AnySeq and check that the change is reflected in the aliased + // ValueSequence + anys.length(3); + anys[2] <<= (CORBA::Long) 20; + CPPUNIT_ASSERT_EQUAL((size_t) anys.length(), values.size()); + CPPUNIT_ASSERT_EQUAL((CORBA::Long) 20, values[2].toLong()); +} + +void ValueSequenceTest::testCast() +{ + CORBA::AnySeq anys; + + // Create a ValueSequence reference alias + redhawk::ValueSequence& values = redhawk::ValueSequence::cast(anys); + CPPUNIT_ASSERT(values.empty()); + + // Append a boolean to the end of the ValueSequence and check that the + // change is reflected in the aliased AnySeq + values.push_back(true); + CPPUNIT_ASSERT_EQUAL((size_t) 1, values.size()); + CPPUNIT_ASSERT_EQUAL((size_t) anys.length(), values.size()); + bool result = false; + CPPUNIT_ASSERT(anys[0] >>= result); + CPPUNIT_ASSERT_EQUAL(true, result); +} + +void ValueSequenceTest::testPushBack() +{ + redhawk::ValueSequence values; + CPPUNIT_ASSERT(values.empty()); + + values.push_back(0); + CPPUNIT_ASSERT_EQUAL((size_t) 1, values.size()); + CPPUNIT_ASSERT_EQUAL((CORBA::Long) 0, values[0].toLong()); + + values.push_back("one"); + CPPUNIT_ASSERT_EQUAL((size_t) 2, values.size()); + CPPUNIT_ASSERT_EQUAL(std::string("one"), values[1].toString()); +} + +void ValueSequenceTest::testConstIndexing() +{ + // Fill an AnySeq such that seq[x] = x + CORBA::AnySeq anys; + anys.length(8); + for (CORBA::ULong index = 0; index < anys.length(); ++index) { + anys[index] <<= index; + } + + // Check that accessing returns the expected values + const redhawk::ValueSequence values(anys); + CPPUNIT_ASSERT_EQUAL((CORBA::Long) 3, values[3].toLong()); + CPPUNIT_ASSERT_EQUAL((CORBA::Long) 5, values[5].toLong()); +} + +void ValueSequenceTest::testIndexing() +{ + // Fill an AnySeq such that seq[x] = x + CORBA::AnySeq anys; + anys.length(8); + for (CORBA::ULong index = 0; index < anys.length(); ++index) { + anys[index] <<= index; + } + + // Check that accessing returns the expected values + redhawk::ValueSequence& values = redhawk::ValueSequence::cast(anys); + CPPUNIT_ASSERT_EQUAL((CORBA::ULong) 3, values[3].toULong()); + CPPUNIT_ASSERT_EQUAL((CORBA::ULong) 5, values[5].toULong()); + + // Modify values within the sequence + values[4] = (CORBA::Long) -4; + values[6] = (CORBA::Double) -6.0; + + // Check that the correct values were modified + CORBA::Long lval = 0; + CPPUNIT_ASSERT(anys[4] >>= lval); + CPPUNIT_ASSERT_EQUAL((CORBA::Long) -4, lval); + CORBA::Double dval = 0.0; + CPPUNIT_ASSERT(anys[6] >>= dval); + CPPUNIT_ASSERT_EQUAL((CORBA::Double) -6.0, dval); +} + +void ValueSequenceTest::testConstIteration() +{ + // Create a source AnySequence with predictable values + CORBA::AnySeq anys; + anys.length(16); + for (CORBA::ULong index = 0; index < anys.length(); ++index) { + anys[index] <<= (CORBA::Double) index; + } + + // Use copy constructor to create a const ValueSequence + const redhawk::ValueSequence values(anys); + + // The distance between the begin and end iterators must be the same as the + // size, and iteration should yield the same result as sequential indexing + CPPUNIT_ASSERT(std::distance(values.begin(), values.end()) == values.size()); + size_t offset = 0; + for (redhawk::ValueSequence::const_iterator iter = values.begin(); iter != values.end(); ++iter, ++offset) { + CPPUNIT_ASSERT_EQUAL(values[offset].toDouble(), iter->toDouble()); + } +} + +void ValueSequenceTest::testMutableIteration() +{ + // Start with an empty sequence + redhawk::ValueSequence values; + CPPUNIT_ASSERT_EQUAL(values.begin(), values.end()); + + // Fill the sequence with predictable values + for (size_t index = 0; index < 10; ++index) { + values.push_back((CORBA::Double) index); + } + + // Modify one value via an iterator + for (redhawk::ValueSequence::iterator iter = values.begin(); iter != values.end(); ++iter) { + if (iter->toDouble() == 5.0) { + *iter = -1000; + } + } + + // Check that the expected value was modified + CPPUNIT_ASSERT_EQUAL((CORBA::Long) -1000, values[5].toLong()); +} + +void ValueSequenceTest::testFromConstValue() +{ + // Create a ValueSequence with known values + redhawk::ValueSequence original; + original.push_back("name"); + original.push_back(1000); + + // Create a const Value with a copy of the original sequence + const redhawk::Value rvalue(original); + CPPUNIT_ASSERT_EQUAL(redhawk::Value::TYPE_VALUE_SEQUENCE, rvalue.getType()); + + // Create a const ValueSequence alias to the Value and check that it + // matches the original + const redhawk::ValueSequence& values = rvalue.asSequence(); + CPPUNIT_ASSERT_EQUAL(original.size(), values.size()); + CPPUNIT_ASSERT_EQUAL(original[0].toString(), values[0].toString()); +} + +void ValueSequenceTest::testFromMutableValue() +{ + // Create a new Value from an empty ValueSequence + redhawk::Value rvalue = redhawk::ValueSequence(); + CPPUNIT_ASSERT_EQUAL(redhawk::Value::TYPE_VALUE_SEQUENCE, rvalue.getType()); + + // Create an alias and insert a value at the back, making sure it modifies + // the Value by extracting the AnySeq + redhawk::ValueSequence& values = rvalue.asSequence(); + values.push_back("test"); + CORBA::AnySeq* anys; + CPPUNIT_ASSERT(rvalue >>= anys); + CPPUNIT_ASSERT_EQUAL(values.size(), (size_t) anys->length()); + std::string result; + CPPUNIT_ASSERT((*anys)[0] >>= result); + CPPUNIT_ASSERT_EQUAL(std::string("test"), result); +} diff --git a/redhawk/src/testing/cpp/ValueSequenceTest.h b/redhawk/src/testing/cpp/ValueSequenceTest.h new file mode 100644 index 000000000..88e39581a --- /dev/null +++ b/redhawk/src/testing/cpp/ValueSequenceTest.h @@ -0,0 +1,44 @@ +#ifndef VALUESEQUENCETEST_H +#define VALUESEQUENCETEST_H + +#include + +class ValueSequenceTest : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE(ValueSequenceTest); + CPPUNIT_TEST(testDefaultConstructor); + CPPUNIT_TEST(testAnySeqConstructor); + CPPUNIT_TEST(testConstCast); + CPPUNIT_TEST(testCast); + CPPUNIT_TEST(testPushBack); + CPPUNIT_TEST(testConstIndexing); + CPPUNIT_TEST(testIndexing); + CPPUNIT_TEST(testConstIteration); + CPPUNIT_TEST(testMutableIteration); + CPPUNIT_TEST(testFromConstValue); + CPPUNIT_TEST(testFromMutableValue); + CPPUNIT_TEST_SUITE_END(); + +public: + void setUp(); + void tearDown(); + + void testDefaultConstructor(); + void testAnySeqConstructor(); + + void testConstCast(); + void testCast(); + + void testPushBack(); + + void testConstIndexing(); + void testIndexing(); + + void testConstIteration(); + void testMutableIteration(); + + void testFromConstValue(); + void testFromMutableValue(); +}; + +#endif // VALUESEQUENCETEST_H From a68b8aa38f4825b84e011249c5646ff68ac74d9f Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 22 Sep 2016 17:47:55 -0400 Subject: [PATCH 0453/1644] Add CppUnit testing for redhawk::PropertyMap (which implicitly covers redhawk::PropertyType as well) --- redhawk/src/testing/cpp/Makefile.am | 1 + redhawk/src/testing/cpp/PropertyMapTest.cpp | 367 ++++++++++++++++++++ redhawk/src/testing/cpp/PropertyMapTest.h | 62 ++++ 3 files changed, 430 insertions(+) create mode 100644 redhawk/src/testing/cpp/PropertyMapTest.cpp create mode 100644 redhawk/src/testing/cpp/PropertyMapTest.h diff --git a/redhawk/src/testing/cpp/Makefile.am b/redhawk/src/testing/cpp/Makefile.am index 62fc26b20..9b7b8e81e 100644 --- a/redhawk/src/testing/cpp/Makefile.am +++ b/redhawk/src/testing/cpp/Makefile.am @@ -9,5 +9,6 @@ standalone_LDFLAGS = $(CPPUNIT_LIBS) test_libossiecf_SOURCES = test_libossiecf.cpp test_libossiecf_SOURCES += ValueTest.cpp ValueTest.h test_libossiecf_SOURCES += ValueSequenceTest.cpp ValueSequenceTest.h +test_libossiecf_SOURCES += PropertyMapTest.cpp PropertyMapTest.h test_libossiecf_CXXFLAGS = $(CPPUNIT_CFLAGS) -I $(top_srcdir)/base/include test_libossiecf_LDFLAGS = $(CPPUNIT_LIBS) $(top_builddir)/base/framework/libossiecf.la $(top_builddir)/base/framework/idl/libossieidl.la diff --git a/redhawk/src/testing/cpp/PropertyMapTest.cpp b/redhawk/src/testing/cpp/PropertyMapTest.cpp new file mode 100644 index 000000000..64786c570 --- /dev/null +++ b/redhawk/src/testing/cpp/PropertyMapTest.cpp @@ -0,0 +1,367 @@ +#include "PropertyMapTest.h" + +#include + +#include + +CPPUNIT_TEST_SUITE_REGISTRATION(PropertyMapTest); + +namespace { + redhawk::PropertyMap generate_test_data() + { + redhawk::PropertyMap propmap; + propmap["first"] = 123; + propmap["second"] = "abc"; + propmap["third"] = 5.25; + return propmap; + } + + redhawk::PropertyMap generate_test_sequence(size_t count) + { + redhawk::PropertyMap propmap; + for (size_t index = 0; index < count; ++index) { + std::ostringstream key; + key << "prop_" << index; + propmap[key.str()] = (CORBA::Long) index; + } + return propmap; + } +} + +void PropertyMapTest::setUp() +{ +} + +void PropertyMapTest::tearDown() +{ +} + +void PropertyMapTest::testDefaultConstructor() +{ + // Default constructor should create an empty PropertyMap + redhawk::PropertyMap propmap; + CPPUNIT_ASSERT(propmap.empty()); + CPPUNIT_ASSERT_EQUAL((size_t) 0, propmap.size()); +} + +void PropertyMapTest::testPropertiesConstructor() +{ + // Copy constructor from CF::Properties + CF::Properties properties; + properties.length(2); + redhawk::PropertyMap propmap(properties); + CPPUNIT_ASSERT(!propmap.empty()); + CPPUNIT_ASSERT_EQUAL((size_t) properties.length(), propmap.size()); +} + +void PropertyMapTest::testConstCast() +{ + // Create a known set of CF::Properties + CF::Properties properties; + properties.length(2); + properties[0].id = "first"; + properties[0].value <<= "abc"; + properties[1].id = "second"; + properties[1].value <<= 1.0; + + // Create a const PropertyMap reference alias and check the values + const CF::Properties& const_properties = properties; + const redhawk::PropertyMap& propmap = redhawk::PropertyMap::cast(const_properties); + CPPUNIT_ASSERT(!propmap.empty()); + CPPUNIT_ASSERT_EQUAL((size_t) properties.length(), propmap.size()); + CPPUNIT_ASSERT_EQUAL(std::string("first"), propmap[0].getId()); + CPPUNIT_ASSERT_EQUAL(std::string("abc"), propmap[0].getValue().toString()); + CPPUNIT_ASSERT_EQUAL(std::string("second"), propmap[1].getId()); + CPPUNIT_ASSERT_EQUAL(1.0, propmap[1].getValue().toDouble()); + + // Append to the Properties and check that the change is reflected in the + // PropertyMap + properties.length(3); + properties[2].id = "third"; + properties[2].value <<= false; + CPPUNIT_ASSERT_EQUAL((size_t) properties.length(), propmap.size()); + CPPUNIT_ASSERT_EQUAL(std::string("third"), propmap[2].getId()); + CPPUNIT_ASSERT_EQUAL(false, propmap[2].getValue().toBoolean()); +} + +void PropertyMapTest::testCast() +{ + // Start with an empty CF::Properties + CF::Properties properties; + + // Create a PropertyMap reference alias + redhawk::PropertyMap& propmap = redhawk::PropertyMap::cast(properties); + CPPUNIT_ASSERT(propmap.empty()); + + // Add a boolean PropertyType to the end of the PropertyMap and check that + // the change is reflected in the aliased Properties + propmap["boolean"] = true; + CPPUNIT_ASSERT_EQUAL((size_t) 1, propmap.size()); + CPPUNIT_ASSERT_EQUAL((size_t) properties.length(), propmap.size()); + CPPUNIT_ASSERT_EQUAL(std::string(properties[0].id), propmap[0].getId()); + bool result = false; + CPPUNIT_ASSERT(properties[0].value >>= result); + CPPUNIT_ASSERT_EQUAL(true, result); +} + +void PropertyMapTest::testPushBack() +{ + redhawk::PropertyMap propmap; + CPPUNIT_ASSERT(propmap.empty()); + + // Push a raw CF::DataType; it should be the first property + CF::DataType dt; + dt.id = "dt"; + dt.value <<= "one"; + propmap.push_back(dt); + CPPUNIT_ASSERT_EQUAL((size_t) 1, propmap.size()); + CPPUNIT_ASSERT_EQUAL(std::string("dt"), propmap[0].getId()); + CPPUNIT_ASSERT_EQUAL(std::string("one"), propmap[0].getValue().toString()); + + // Push a PropertyType; it should be the second property + propmap.push_back(redhawk::PropertyType("test", 0)); + CPPUNIT_ASSERT_EQUAL((size_t) 2, propmap.size()); + CPPUNIT_ASSERT_EQUAL(std::string("test"), propmap[1].getId()); + CPPUNIT_ASSERT_EQUAL((CORBA::Long) 0, propmap[1].getValue().toLong()); +} + +void PropertyMapTest::testContains() +{ + // Use a const PropertyMap with known test data; contains() is intended to + // be const-friendly + const redhawk::PropertyMap propmap = generate_test_data(); + CPPUNIT_ASSERT(propmap.contains("first")); + CPPUNIT_ASSERT(propmap.contains("third")); + CPPUNIT_ASSERT(!propmap.contains("fourth")); +} + +void PropertyMapTest::testConstIndexing() +{ + // Generate sequential properties (propN=N) and make sure the indexed + // values match up + const redhawk::PropertyMap propmap = generate_test_sequence(8); + CPPUNIT_ASSERT_EQUAL(std::string("prop_4"), propmap[4].getId()); + CPPUNIT_ASSERT_EQUAL((CORBA::Long) 7, propmap[7].getValue().toLong()); +} + +void PropertyMapTest::testMutableIndexing() +{ + // Create Properties with sequential IDs/values and a PropertyMap reference + // alias--this allows us to use the trusted CORBA sequence operator[] for + // comparison + CF::Properties properties = generate_test_sequence(8); + redhawk::PropertyMap& propmap = redhawk::PropertyMap::cast(properties); + + // Basic indexing + CPPUNIT_ASSERT_EQUAL(std::string("prop_4"), propmap[4].getId()); + CPPUNIT_ASSERT_EQUAL((CORBA::Long) 7, propmap[7].getValue().toLong()); + + // Overwrite a value by index + propmap[3] = redhawk::PropertyType("overwrite", -128); + CPPUNIT_ASSERT_EQUAL(std::string("overwrite"), std::string(properties[3].id)); + CORBA::Long lval = 0; + CPPUNIT_ASSERT(properties[3].value >>= lval); + CPPUNIT_ASSERT_EQUAL((CORBA::Long) -128, lval); + + // Modify ID of an indexed item + propmap[5].setId("modified"); + CPPUNIT_ASSERT_EQUAL(std::string("modified"), std::string(properties[5].id)); + + // Modiyf value of an indexed item + propmap[7].setValue((CORBA::Double) 9.75); + CORBA::Double dval = 0.0; + CPPUNIT_ASSERT(properties[7].value >>= dval); + CPPUNIT_ASSERT_EQUAL((CORBA::Double) 9.75, dval); +} + +void PropertyMapTest::testConstMapping() +{ + const redhawk::PropertyMap propmap = generate_test_data(); + + // Check for a known property value + CPPUNIT_ASSERT_EQUAL(std::string("abc"), propmap["second"].toString()); + + // IDs that are not found should throw an exception + CPPUNIT_ASSERT_THROW(propmap["fourth"], std::invalid_argument); +} + +void PropertyMapTest::testMutableMapping() +{ + // Use the standard test data, with the caveat that if for some reason its + // size changes, or the property IDs are different than we expect, this + // test will intentionally fail. + redhawk::PropertyMap propmap = generate_test_data(); + CPPUNIT_ASSERT_EQUAL((size_t) 3, propmap.size()); + + // Set a value for a new key, and check that it adds a new property to the + // end of the map + CPPUNIT_ASSERT(!propmap.contains("fourth")); + propmap["fourth"] = true; + CPPUNIT_ASSERT_EQUAL((size_t) 4, propmap.size()); + CPPUNIT_ASSERT_EQUAL(std::string("fourth"), propmap[3].getId()); + CPPUNIT_ASSERT_EQUAL(true, propmap[3].getValue().toBoolean()); + + // Set a value for an existing key, and check that it overwrote the old + // value + CPPUNIT_ASSERT_EQUAL(std::string("second"), propmap[1].getId()); + propmap["second"] = 5000; + CPPUNIT_ASSERT_EQUAL((size_t) 4, propmap.size()); + CPPUNIT_ASSERT_EQUAL((CORBA::Long) 5000, propmap[1].getValue().toLong()); + + // When the property isn't found, it should create one using the default + // Value constructor + CPPUNIT_ASSERT(!propmap.contains("nil")); + CPPUNIT_ASSERT(propmap["nil"].isNil()); + CPPUNIT_ASSERT_EQUAL((size_t) 5, propmap.size()); +} + +void PropertyMapTest::testConstFind() +{ + const redhawk::PropertyMap propmap = generate_test_data(); + + // If the key is not found, find() should return the end iterator + CPPUNIT_ASSERT_EQUAL(propmap.end(), propmap.find("missing")); + + // With a known good key, make sure that find() returns a valid iterator, + // to the correct property + redhawk::PropertyMap::const_iterator prop = propmap.find("third"); + CPPUNIT_ASSERT(prop != propmap.end()); + CPPUNIT_ASSERT_EQUAL(std::string("third"), prop->getId()); + CPPUNIT_ASSERT_EQUAL((CORBA::Double) 5.25, prop->getValue().toDouble()); +} + +void PropertyMapTest::testMutableFind() +{ + redhawk::PropertyMap propmap = generate_test_data(); + + // If the key is not found, find() should return the end iterator (this is + // essentially identical to the const version) + CPPUNIT_ASSERT_EQUAL(propmap.end(), propmap.find("bogus")); + + // Find a known good key, and use the iterator to overwrite the value + redhawk::PropertyMap::iterator prop = propmap.find("second"); + CPPUNIT_ASSERT(prop != propmap.end()); + CPPUNIT_ASSERT_EQUAL(std::string("second"), prop->getId()); + prop->setValue("override"); + CPPUNIT_ASSERT_EQUAL(std::string("override"), propmap["second"].toString()); +} + +void PropertyMapTest::testConstIteration() +{ + const redhawk::PropertyMap empty; + CPPUNIT_ASSERT_EQUAL(empty.begin(), empty.end()); + + const redhawk::PropertyMap propmap = generate_test_sequence(8); + CORBA::Long offset = 0; + for (redhawk::PropertyMap::const_iterator iter = propmap.begin(); iter != propmap.end(); ++iter, ++offset) { + CPPUNIT_ASSERT_EQUAL(offset, iter->getValue().toLong()); + } + CPPUNIT_ASSERT_EQUAL((size_t) offset, propmap.size()); +} + +void PropertyMapTest::testMutableIteration() +{ + redhawk::PropertyMap empty; + CPPUNIT_ASSERT_EQUAL(empty.begin(), empty.end()); + + redhawk::PropertyMap propmap = generate_test_sequence(8); + CORBA::Long offset = 0; + for (redhawk::PropertyMap::iterator iter = propmap.begin(); iter != propmap.end(); ++iter, ++offset) { + if (iter->getId() == "prop_6") { + iter->setValue("override"); + } + } + CPPUNIT_ASSERT_EQUAL((size_t) offset, propmap.size()); + CPPUNIT_ASSERT_EQUAL(std::string("override"), propmap[6].getValue().toString()); +} + +void PropertyMapTest::testUpdate() +{ + // Start with a PropertyMap that partially intersects the standard test + // properties ("second" is in both) + redhawk::PropertyMap propmap; + propmap["second"] = "default"; + propmap["fourth"] = true; + + // Update with the standard test properties + const redhawk::PropertyMap overrides = generate_test_data(); + propmap.update(overrides); + + // Two properties should have been added ("first" and "third") + CPPUNIT_ASSERT_EQUAL((size_t) 4, propmap.size()); + CPPUNIT_ASSERT(propmap.contains("first")); + CPPUNIT_ASSERT_EQUAL(overrides["first"].toLong(), propmap["first"].toLong()); + CPPUNIT_ASSERT(propmap.contains("third")); + + // The common property "second" should be updated according to the standard + // test properties + CPPUNIT_ASSERT_EQUAL(overrides["second"].toString(), propmap["second"].toString()); + + // The "fourth" property should remain unchanged + CPPUNIT_ASSERT_EQUAL(true, propmap["fourth"].toBoolean()); +} + +void PropertyMapTest::testErase() +{ + // Use the sequential test data, because we're going to delete several + // entries, and it's easier with predictable property names + redhawk::PropertyMap propmap = generate_test_sequence(10); + + // Erase a single property by ID + CPPUNIT_ASSERT(propmap.contains("prop_4")); + propmap.erase("prop_4"); + CPPUNIT_ASSERT_EQUAL((size_t) 9, propmap.size()); + CPPUNIT_ASSERT(!propmap.contains("prop_4")); + + // Erase a single property by iterator + redhawk::PropertyMap::iterator prop = propmap.find("prop_2"); + CPPUNIT_ASSERT(prop != propmap.end()); + propmap.erase(prop); + CPPUNIT_ASSERT_EQUAL((size_t) 8, propmap.size()); + CPPUNIT_ASSERT(!propmap.contains("prop_2")); + + // Erase a range of properties; this should remove 3, 5 and 6 + redhawk::PropertyMap::iterator first = propmap.find("prop_3"); + redhawk::PropertyMap::iterator last = propmap.find("prop_7"); + propmap.erase(first, last); + CPPUNIT_ASSERT_EQUAL((size_t) 5, propmap.size()); + + // Check that the gap is where we expect it (from 1 to 7) + prop = propmap.find("prop_1"); + prop++; + CPPUNIT_ASSERT_EQUAL(std::string("prop_7"), prop->getId()); +} + +void PropertyMapTest::testGet() +{ + const redhawk::PropertyMap propmap = generate_test_data(); + + // Property exists, default ignored + CPPUNIT_ASSERT_EQUAL(std::string("abc"), propmap.get("second", "fail").toString()); + + // Property exists, default returned + CPPUNIT_ASSERT(!propmap.contains("missing")); + CPPUNIT_ASSERT_EQUAL(std::string("pass"), propmap.get("missing", "pass").toString()); +} + +void PropertyMapTest::testToString() +{ + // Using the standard test properties, create a string representation; this + // test shouldn't necessarily be considered canonical, but should at least + // raise a red flag if the format changes inadvertently + const redhawk::PropertyMap propmap = generate_test_data(); + const std::string stringval = propmap.toString(); + + // The string representation should: + // * be non-empty + // * be enclosed in curly braces + // * contain one "key=value" for each property + CPPUNIT_ASSERT(!stringval.empty()); + CPPUNIT_ASSERT_EQUAL('{', *stringval.begin()); + CPPUNIT_ASSERT_EQUAL('}', *(stringval.end()-1)); + CPPUNIT_ASSERT(stringval.find("first") != std::string::npos); + CPPUNIT_ASSERT(stringval.find("second") != std::string::npos); + CPPUNIT_ASSERT(stringval.find("third") != std::string::npos); + size_t item_count = std::count(stringval.begin(), stringval.end(), '='); + CPPUNIT_ASSERT_EQUAL(propmap.size(), item_count); +} diff --git a/redhawk/src/testing/cpp/PropertyMapTest.h b/redhawk/src/testing/cpp/PropertyMapTest.h new file mode 100644 index 000000000..5ad20ec9a --- /dev/null +++ b/redhawk/src/testing/cpp/PropertyMapTest.h @@ -0,0 +1,62 @@ +#ifndef PROPERTYMAPTEST_H +#define PROPERTYMAPTEST_H + +#include + +class PropertyMapTest : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE(PropertyMapTest); + CPPUNIT_TEST(testDefaultConstructor); + CPPUNIT_TEST(testPropertiesConstructor); + CPPUNIT_TEST(testConstCast); + CPPUNIT_TEST(testCast); + CPPUNIT_TEST(testPushBack); + CPPUNIT_TEST(testConstIndexing); + CPPUNIT_TEST(testMutableIndexing); + CPPUNIT_TEST(testConstMapping); + CPPUNIT_TEST(testMutableMapping); + CPPUNIT_TEST(testConstFind); + CPPUNIT_TEST(testMutableFind); + CPPUNIT_TEST(testConstIteration); + CPPUNIT_TEST(testMutableIteration); + CPPUNIT_TEST(testUpdate); + CPPUNIT_TEST(testErase); + CPPUNIT_TEST(testGet); + CPPUNIT_TEST(testToString); + CPPUNIT_TEST_SUITE_END(); + +public: + void setUp(); + void tearDown(); + + void testDefaultConstructor(); + void testPropertiesConstructor(); + + void testConstCast(); + void testCast(); + + void testPushBack(); + + void testContains(); + + void testConstIndexing(); + void testMutableIndexing(); + + void testConstMapping(); + void testMutableMapping(); + + void testConstFind(); + void testMutableFind(); + + void testConstIteration(); + void testMutableIteration(); + + void testUpdate(); + void testErase(); + + void testGet(); + + void testToString(); +}; + +#endif // PROPERTYMAPTEST_H From 87afee225882c5f4f5acfffdcddc991280f84766 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 22 Sep 2016 17:54:17 -0400 Subject: [PATCH 0454/1644] Compile CppUnit tests with all warnings on; fix warnings --- redhawk/src/testing/cpp/Makefile.am | 2 ++ redhawk/src/testing/cpp/SharedBufferTest.cpp | 18 +++++++++--------- redhawk/src/testing/cpp/ValueSequenceTest.cpp | 2 +- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/redhawk/src/testing/cpp/Makefile.am b/redhawk/src/testing/cpp/Makefile.am index 9b7b8e81e..c58decfb2 100644 --- a/redhawk/src/testing/cpp/Makefile.am +++ b/redhawk/src/testing/cpp/Makefile.am @@ -1,5 +1,7 @@ TESTS = standalone test_libossiecf +AM_CPPFLAGS = -Wall + check_PROGRAMS = $(TESTS) standalone_SOURCES = standalone.cpp SharedBufferTest.cpp SharedBufferTest.h diff --git a/redhawk/src/testing/cpp/SharedBufferTest.cpp b/redhawk/src/testing/cpp/SharedBufferTest.cpp index 20a0a0cb8..cfbd41786 100644 --- a/redhawk/src/testing/cpp/SharedBufferTest.cpp +++ b/redhawk/src/testing/cpp/SharedBufferTest.cpp @@ -126,15 +126,15 @@ void SharedBufferTest::testIteration() // The distance between the begin and end iterators must be the same as the // size, and iteration should yield the same result as sequential indexing - CPPUNIT_ASSERT(std::distance(buffer.begin(), buffer.end()) == buffer.size()); size_t offset = 0; for (redhawk::buffer::iterator iter = buffer.begin(); iter != buffer.end(); ++iter, ++offset) { CPPUNIT_ASSERT_EQUAL(*iter, buffer[offset]); } + CPPUNIT_ASSERT_EQUAL(buffer.size(), offset); // Repeat, via a const shared buffer alias const redhawk::shared_buffer shared = buffer; - CPPUNIT_ASSERT(std::distance(shared.begin(), shared.end()) == shared.size()); + CPPUNIT_ASSERT_EQUAL((ptrdiff_t) shared.size(), std::distance(shared.begin(), shared.end())); CPPUNIT_ASSERT(std::equal(shared.begin(), shared.end(), buffer.begin())); } @@ -168,10 +168,10 @@ void SharedBufferTest::testSwap() // Create two mutable buffers with different contents redhawk::buffer first(3); std::fill(first.begin(), first.end(), 7); - CPPUNIT_ASSERT(std::count(first.begin(), first.end(), 7) == first.size()); + CPPUNIT_ASSERT_EQUAL(first.size(), (size_t) std::count(first.begin(), first.end(), 7)); redhawk::buffer second(5); std::fill(second.begin(), second.end(), -2); - CPPUNIT_ASSERT(std::count(second.begin(), second.end(), -2) == second.size()); + CPPUNIT_ASSERT_EQUAL(second.size(), (size_t) std::count(second.begin(), second.end(), -2)); // Swap them and check that the swap worked as expected first.swap(second); @@ -197,7 +197,7 @@ void SharedBufferTest::testSharing() { // Fill a new buffer redhawk::buffer > buffer(8); - for (int index = 0; index < buffer.size(); ++index) { + for (size_t index = 0; index < buffer.size(); ++index) { buffer[index] = std::complex(0.5, 0.5) * (double) index; } @@ -214,7 +214,7 @@ void SharedBufferTest::testSlicing() { // Fill a new buffer redhawk::buffer buffer(12); - for (int index = 0; index < buffer.size(); ++index) { + for (size_t index = 0; index < buffer.size(); ++index) { buffer[index] = index; } @@ -228,7 +228,7 @@ void SharedBufferTest::testSlicing() // match const redhawk::shared_buffer end = buffer.slice(6); CPPUNIT_ASSERT_EQUAL(end.size(), buffer.size() - 6); - for (int index = 0; index < end.size(); ++index) { + for (size_t index = 0; index < end.size(); ++index) { CPPUNIT_ASSERT_EQUAL(end[index], buffer[index + 6]); } @@ -322,7 +322,7 @@ void SharedBufferTest::testAllocator() // The initial condition of the arena should be all zeros std::fill(arena.begin(), arena.end(), 0); - CPPUNIT_ASSERT(std::count(arena.begin(), arena.end(), 0) == arena.size()); + CPPUNIT_ASSERT_EQUAL(arena.size(), (size_t) std::count(arena.begin(), arena.end(), 0)); // Create a new buffer using a custom allocator; we should see that it's // marked the allocated space with ones @@ -337,7 +337,7 @@ void SharedBufferTest::testAllocator() // Release the buffer, which should trigger a deallocation; we should see // that it's reset the allocated space to zeros buffer = redhawk::buffer(); - CPPUNIT_ASSERT(std::count(arena.begin(), arena.end(), 0) == arena.size()); + CPPUNIT_ASSERT_EQUAL(arena.size(), (size_t) std::count(arena.begin(), arena.end(), 0)); } void SharedBufferTest::testAllocatorCopy() diff --git a/redhawk/src/testing/cpp/ValueSequenceTest.cpp b/redhawk/src/testing/cpp/ValueSequenceTest.cpp index 866d325fc..6e1550c4f 100644 --- a/redhawk/src/testing/cpp/ValueSequenceTest.cpp +++ b/redhawk/src/testing/cpp/ValueSequenceTest.cpp @@ -142,11 +142,11 @@ void ValueSequenceTest::testConstIteration() // The distance between the begin and end iterators must be the same as the // size, and iteration should yield the same result as sequential indexing - CPPUNIT_ASSERT(std::distance(values.begin(), values.end()) == values.size()); size_t offset = 0; for (redhawk::ValueSequence::const_iterator iter = values.begin(); iter != values.end(); ++iter, ++offset) { CPPUNIT_ASSERT_EQUAL(values[offset].toDouble(), iter->toDouble()); } + CPPUNIT_ASSERT_EQUAL(values.size(), offset); } void ValueSequenceTest::testMutableIteration() From b2602ac356e5f5b402d63ad68331fe173473c008 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 22 Sep 2016 18:02:58 -0400 Subject: [PATCH 0455/1644] Add a test for redhawk::make_buffer --- redhawk/src/testing/cpp/SharedBufferTest.cpp | 19 +++++++++++++++++++ redhawk/src/testing/cpp/SharedBufferTest.h | 2 ++ 2 files changed, 21 insertions(+) diff --git a/redhawk/src/testing/cpp/SharedBufferTest.cpp b/redhawk/src/testing/cpp/SharedBufferTest.cpp index cfbd41786..1c62ef696 100644 --- a/redhawk/src/testing/cpp/SharedBufferTest.cpp +++ b/redhawk/src/testing/cpp/SharedBufferTest.cpp @@ -52,6 +52,12 @@ namespace { bool* _deleted; }; + + struct NullDeleter { + void operator() (void*) + { + } + }; } void SharedBufferTest::setUp() @@ -93,6 +99,19 @@ void SharedBufferTest::testConstructor() CPPUNIT_ASSERT(shared.data() == buffer.data()); } +void SharedBufferTest::testMakeBuffer() +{ + // Simple wrapper for externally-allocated array + int* array = new int[16]; + redhawk::buffer buffer = redhawk::make_buffer(array, 16); + CPPUNIT_ASSERT_EQUAL(array, buffer.data()); + + // Use a custom deleter that is a no-op, with a stack-based array + double darray[4] = { 1.0, 2.0, 3.0, 4.0 }; + redhawk::buffer dbuffer = redhawk::make_buffer(darray, 4, NullDeleter()); + CPPUNIT_ASSERT_EQUAL(&darray[0], dbuffer.data()); +} + void SharedBufferTest::testEquals() { // Create a buffer with known data diff --git a/redhawk/src/testing/cpp/SharedBufferTest.h b/redhawk/src/testing/cpp/SharedBufferTest.h index 6e8146343..f1b742446 100644 --- a/redhawk/src/testing/cpp/SharedBufferTest.h +++ b/redhawk/src/testing/cpp/SharedBufferTest.h @@ -8,6 +8,7 @@ class SharedBufferTest : public CppUnit::TestFixture CPPUNIT_TEST_SUITE(SharedBufferTest); CPPUNIT_TEST(testDefaultConstructor); CPPUNIT_TEST(testConstructor); + CPPUNIT_TEST(testMakeBuffer); CPPUNIT_TEST(testEquals); CPPUNIT_TEST(testIteration); CPPUNIT_TEST(testCopy); @@ -30,6 +31,7 @@ class SharedBufferTest : public CppUnit::TestFixture // Constructors void testDefaultConstructor(); void testConstructor(); + void testMakeBuffer(); // Basic container behavior void testEquals(); From 0f8ec1c46b4b9c246fe6ac2fa05b220cfc7f8bad Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 22 Sep 2016 18:06:35 -0400 Subject: [PATCH 0456/1644] Add copyright header to C++ unit tests --- redhawk/src/testing/cpp/PropertyMapTest.cpp | 20 +++++++++++++++++++ redhawk/src/testing/cpp/PropertyMapTest.h | 20 +++++++++++++++++++ redhawk/src/testing/cpp/SharedBufferTest.cpp | 20 +++++++++++++++++++ redhawk/src/testing/cpp/SharedBufferTest.h | 20 +++++++++++++++++++ redhawk/src/testing/cpp/ValueSequenceTest.cpp | 20 +++++++++++++++++++ redhawk/src/testing/cpp/ValueSequenceTest.h | 20 +++++++++++++++++++ redhawk/src/testing/cpp/ValueTest.cpp | 20 +++++++++++++++++++ redhawk/src/testing/cpp/ValueTest.h | 20 +++++++++++++++++++ redhawk/src/testing/cpp/standalone.cpp | 20 +++++++++++++++++++ redhawk/src/testing/cpp/test_libossiecf.cpp | 20 +++++++++++++++++++ 10 files changed, 200 insertions(+) diff --git a/redhawk/src/testing/cpp/PropertyMapTest.cpp b/redhawk/src/testing/cpp/PropertyMapTest.cpp index 64786c570..685e6f391 100644 --- a/redhawk/src/testing/cpp/PropertyMapTest.cpp +++ b/redhawk/src/testing/cpp/PropertyMapTest.cpp @@ -1,3 +1,23 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK core. + * + * REDHAWK core is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + #include "PropertyMapTest.h" #include diff --git a/redhawk/src/testing/cpp/PropertyMapTest.h b/redhawk/src/testing/cpp/PropertyMapTest.h index 5ad20ec9a..24a7df183 100644 --- a/redhawk/src/testing/cpp/PropertyMapTest.h +++ b/redhawk/src/testing/cpp/PropertyMapTest.h @@ -1,3 +1,23 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK core. + * + * REDHAWK core is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + #ifndef PROPERTYMAPTEST_H #define PROPERTYMAPTEST_H diff --git a/redhawk/src/testing/cpp/SharedBufferTest.cpp b/redhawk/src/testing/cpp/SharedBufferTest.cpp index 1c62ef696..a70e2bb79 100644 --- a/redhawk/src/testing/cpp/SharedBufferTest.cpp +++ b/redhawk/src/testing/cpp/SharedBufferTest.cpp @@ -1,3 +1,23 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK core. + * + * REDHAWK core is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + #include "SharedBufferTest.h" #include diff --git a/redhawk/src/testing/cpp/SharedBufferTest.h b/redhawk/src/testing/cpp/SharedBufferTest.h index f1b742446..c6cf28bfc 100644 --- a/redhawk/src/testing/cpp/SharedBufferTest.h +++ b/redhawk/src/testing/cpp/SharedBufferTest.h @@ -1,3 +1,23 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK core. + * + * REDHAWK core is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + #ifndef SHAREDBUFFERTEST_H #define SHAREDBUFFERTEST_H diff --git a/redhawk/src/testing/cpp/ValueSequenceTest.cpp b/redhawk/src/testing/cpp/ValueSequenceTest.cpp index 6e1550c4f..da0b3fe7a 100644 --- a/redhawk/src/testing/cpp/ValueSequenceTest.cpp +++ b/redhawk/src/testing/cpp/ValueSequenceTest.cpp @@ -1,3 +1,23 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK core. + * + * REDHAWK core is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + #include "ValueSequenceTest.h" #include diff --git a/redhawk/src/testing/cpp/ValueSequenceTest.h b/redhawk/src/testing/cpp/ValueSequenceTest.h index 88e39581a..d540330e4 100644 --- a/redhawk/src/testing/cpp/ValueSequenceTest.h +++ b/redhawk/src/testing/cpp/ValueSequenceTest.h @@ -1,3 +1,23 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK core. + * + * REDHAWK core is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + #ifndef VALUESEQUENCETEST_H #define VALUESEQUENCETEST_H diff --git a/redhawk/src/testing/cpp/ValueTest.cpp b/redhawk/src/testing/cpp/ValueTest.cpp index dd9a5f8b4..f05eaef3b 100644 --- a/redhawk/src/testing/cpp/ValueTest.cpp +++ b/redhawk/src/testing/cpp/ValueTest.cpp @@ -1,3 +1,23 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK core. + * + * REDHAWK core is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + #include "ValueTest.h" #include diff --git a/redhawk/src/testing/cpp/ValueTest.h b/redhawk/src/testing/cpp/ValueTest.h index 96251369a..dc059cd3f 100644 --- a/redhawk/src/testing/cpp/ValueTest.h +++ b/redhawk/src/testing/cpp/ValueTest.h @@ -1,3 +1,23 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK core. + * + * REDHAWK core is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + #ifndef VALUETEST_H #define VALUETEST_H diff --git a/redhawk/src/testing/cpp/standalone.cpp b/redhawk/src/testing/cpp/standalone.cpp index b95eb8334..bb3ead102 100644 --- a/redhawk/src/testing/cpp/standalone.cpp +++ b/redhawk/src/testing/cpp/standalone.cpp @@ -1,3 +1,23 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK core. + * + * REDHAWK core is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + #include #include #include diff --git a/redhawk/src/testing/cpp/test_libossiecf.cpp b/redhawk/src/testing/cpp/test_libossiecf.cpp index aa649d525..acff55a93 100644 --- a/redhawk/src/testing/cpp/test_libossiecf.cpp +++ b/redhawk/src/testing/cpp/test_libossiecf.cpp @@ -1,3 +1,23 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK core. + * + * REDHAWK core is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + #include #include #include From ed6ce7a834903fc6ff0a5e8266e32c92680ba4ef Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 22 Sep 2016 18:10:09 -0400 Subject: [PATCH 0457/1644] Add a test for the const version of redhawk::Value::cast --- redhawk/src/testing/cpp/ValueTest.cpp | 19 +++++++++++++++++++ redhawk/src/testing/cpp/ValueTest.h | 2 ++ 2 files changed, 21 insertions(+) diff --git a/redhawk/src/testing/cpp/ValueTest.cpp b/redhawk/src/testing/cpp/ValueTest.cpp index f05eaef3b..cdc495b03 100644 --- a/redhawk/src/testing/cpp/ValueTest.cpp +++ b/redhawk/src/testing/cpp/ValueTest.cpp @@ -224,6 +224,25 @@ void ValueTest::testStringConversion() CPPUNIT_ASSERT_EQUAL(std::string("-2.25e+40"), redhawk::Value((CORBA::Double) -2.25e40).toString()); } +void ValueTest::testConstCast() +{ + CORBA::Any any; + const double dval = 1.25; + any <<= dval; + + // Create a const Value alias and check that it matches the Any + const CORBA::Any& const_any = any; + const redhawk::Value& value = redhawk::Value::cast(const_any); + CPPUNIT_ASSERT_EQUAL(redhawk::Value::TYPE_DOUBLE, value.getType()); + CPPUNIT_ASSERT_EQUAL(dval, value.toDouble()); + + // Modify the Any and check that the change is reflected in the Value + const std::string stringval = "value"; + any <<= stringval; + CPPUNIT_ASSERT_EQUAL(redhawk::Value::TYPE_STRING, value.getType()); + CPPUNIT_ASSERT_EQUAL(stringval, value.toString()); +} + void ValueTest::testCast() { CORBA::Any any; diff --git a/redhawk/src/testing/cpp/ValueTest.h b/redhawk/src/testing/cpp/ValueTest.h index dc059cd3f..ca7e88ea0 100644 --- a/redhawk/src/testing/cpp/ValueTest.h +++ b/redhawk/src/testing/cpp/ValueTest.h @@ -30,6 +30,7 @@ class ValueTest : public CppUnit::TestFixture CPPUNIT_TEST(testType); CPPUNIT_TEST(testNumericConversion); CPPUNIT_TEST(testStringConversion); + CPPUNIT_TEST(testConstCast); CPPUNIT_TEST(testCast); CPPUNIT_TEST_SUITE_END(); @@ -44,6 +45,7 @@ class ValueTest : public CppUnit::TestFixture void testNumericConversion(); void testStringConversion(); + void testConstCast(); void testCast(); }; From d3e82785704e5c2b5b75d62a41af61be70dff39e Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 23 Sep 2016 08:52:06 -0400 Subject: [PATCH 0458/1644] CF-1505 C++ unit test for querying MessageSupplierPort connections --- redhawk/src/testing/cpp/Makefile.am | 1 + redhawk/src/testing/cpp/MessagingTest.cpp | 105 ++++++++++++++++++++++ redhawk/src/testing/cpp/MessagingTest.h | 45 ++++++++++ 3 files changed, 151 insertions(+) create mode 100644 redhawk/src/testing/cpp/MessagingTest.cpp create mode 100644 redhawk/src/testing/cpp/MessagingTest.h diff --git a/redhawk/src/testing/cpp/Makefile.am b/redhawk/src/testing/cpp/Makefile.am index c58decfb2..5af745888 100644 --- a/redhawk/src/testing/cpp/Makefile.am +++ b/redhawk/src/testing/cpp/Makefile.am @@ -12,5 +12,6 @@ test_libossiecf_SOURCES = test_libossiecf.cpp test_libossiecf_SOURCES += ValueTest.cpp ValueTest.h test_libossiecf_SOURCES += ValueSequenceTest.cpp ValueSequenceTest.h test_libossiecf_SOURCES += PropertyMapTest.cpp PropertyMapTest.h +test_libossiecf_SOURCES += MessagingTest.cpp MessagingTest.h test_libossiecf_CXXFLAGS = $(CPPUNIT_CFLAGS) -I $(top_srcdir)/base/include test_libossiecf_LDFLAGS = $(CPPUNIT_LIBS) $(top_builddir)/base/framework/libossiecf.la $(top_builddir)/base/framework/idl/libossieidl.la diff --git a/redhawk/src/testing/cpp/MessagingTest.cpp b/redhawk/src/testing/cpp/MessagingTest.cpp new file mode 100644 index 000000000..e6365629f --- /dev/null +++ b/redhawk/src/testing/cpp/MessagingTest.cpp @@ -0,0 +1,105 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK core. + * + * REDHAWK core is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +#include "MessagingTest.h" + +CPPUNIT_TEST_SUITE_REGISTRATION(MessagingTest); + +void MessagingTest::setUp() +{ + _supplier = new MessageSupplierPort("supplier"); + _consumer = new MessageConsumerPort("consumer"); + + PortableServer::POA_ptr root_poa = ossie::corba::RootPOA(); + PortableServer::ObjectId_var oid = root_poa->activate_object(_supplier); + oid = root_poa->activate_object(_consumer); + + // Simulate component start + _supplier->startPort(); + _consumer->startPort(); +} + +void MessagingTest::tearDown() +{ + // Simulate component stop/shutdown + _supplier->stopPort(); + _consumer->stopPort(); + + PortableServer::POA_ptr root_poa = ossie::corba::RootPOA(); + try { + PortableServer::ObjectId_var oid = root_poa->servant_to_id(_supplier); + root_poa->deactivate_object(oid); + _supplier->_remove_ref(); + } catch (const CORBA::Exception&) { + // TODO: Print message? + } + _supplier = 0; + + try { + PortableServer::ObjectId_var oid = root_poa->servant_to_id(_consumer); + root_poa->deactivate_object(oid); + _consumer->_remove_ref(); + } catch (const CORBA::Exception&) { + // TODO: Print message? + } + _consumer = 0; +} + +void MessagingTest::testConnections() +{ + // Connect the supplier and consumer + CORBA::Object_var objref = _consumer->_this(); + _supplier->connectPort(objref, "connection_1"); + + // Verify the connections list + ExtendedCF::UsesConnectionSequence_var connections = _supplier->connections(); + CPPUNIT_ASSERT_EQUAL((CORBA::ULong) 1, connections->length()); + CPPUNIT_ASSERT_EQUAL(std::string("connection_1"), std::string(connections[0].connectionId)); + CPPUNIT_ASSERT(objref->_is_equivalent(connections[0].port)); + + // Make two more connections + _supplier->connectPort(objref, "connection_2"); + _supplier->connectPort(objref, "connection_3"); + connections = _supplier->connections(); + CPPUNIT_ASSERT_EQUAL((CORBA::ULong) 3, connections->length()); + + // Check all the connections; there is no guarantee of ordering in the + // connection list, so collect the names in a set + std::set names; + for (CORBA::ULong index = 0; index < connections->length(); ++index) { + names.insert(std::string(connections[index].connectionId)); + CPPUNIT_ASSERT(objref->_is_equivalent(connections[index].port)); + } + CPPUNIT_ASSERT(names.find("connection_1") != names.end()); + CPPUNIT_ASSERT(names.find("connection_2") != names.end()); + CPPUNIT_ASSERT(names.find("connection_3") != names.end()); + + // Disconnect one of the connections and check again + _supplier->disconnectPort("connection_2"); + connections = _supplier->connections(); + CPPUNIT_ASSERT_EQUAL((CORBA::ULong) 2, connections->length()); + names.clear(); + for (CORBA::ULong index = 0; index < connections->length(); ++index) { + names.insert(std::string(connections[index].connectionId)); + CPPUNIT_ASSERT(objref->_is_equivalent(connections[index].port)); + } + CPPUNIT_ASSERT(names.find("connection_1") != names.end()); + CPPUNIT_ASSERT(names.find("connection_3") != names.end()); +} diff --git a/redhawk/src/testing/cpp/MessagingTest.h b/redhawk/src/testing/cpp/MessagingTest.h new file mode 100644 index 000000000..7e2547118 --- /dev/null +++ b/redhawk/src/testing/cpp/MessagingTest.h @@ -0,0 +1,45 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK core. + * + * REDHAWK core is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +#ifndef MESSAGINGTEST_H +#define MESSAGINGTEST_H + +#include + +#include + +class MessagingTest : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE(MessagingTest); + CPPUNIT_TEST(testConnections); + CPPUNIT_TEST_SUITE_END(); + +public: + void setUp(); + void tearDown(); + + void testConnections(); + +private: + MessageSupplierPort* _supplier; + MessageConsumerPort* _consumer; +}; + +#endif // MESSAGINGTEST_H From 125007a16057fd20f26735443ac8cd331defe62e Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 23 Sep 2016 11:21:27 -0400 Subject: [PATCH 0459/1644] CF-1529 C++ unit test for direct message transfer in same process --- redhawk/src/testing/cpp/MessagingTest.cpp | 252 +++++++++++++++++++++- redhawk/src/testing/cpp/MessagingTest.h | 10 + 2 files changed, 260 insertions(+), 2 deletions(-) diff --git a/redhawk/src/testing/cpp/MessagingTest.cpp b/redhawk/src/testing/cpp/MessagingTest.cpp index e6365629f..9bf92f773 100644 --- a/redhawk/src/testing/cpp/MessagingTest.cpp +++ b/redhawk/src/testing/cpp/MessagingTest.cpp @@ -20,8 +20,137 @@ #include "MessagingTest.h" +#include + CPPUNIT_TEST_SUITE_REGISTRATION(MessagingTest); +namespace { + // Internal structs and methods are encapsulated in an anonymous namespace + // to prevent external symbol table pollution and collisions. + + // NB: Because the Any extraction operator for std::string is defined in + // the global namespace (not std), we need to bring it into this namespace + // so that it can be found by the custom struct extraction operators. + using ::operator>>=; + + // Legacy message struct generated with REDHAWK 1.8. This serves two + // purposes: it maintains compatibility with 1.8 code, and forces the + // MessageSupplierPort to use Any serialization instead of direct message + // transfer. + struct legacy_message_struct { + legacy_message_struct () + { + }; + + std::string getId() { + return std::string("legacy_message"); + }; + + CORBA::Long value; + }; + + inline bool operator>>= (const CORBA::Any& a, legacy_message_struct& s) { + CF::Properties* temp; + if (!(a >>= temp)) return false; + CF::Properties& props = *temp; + for (unsigned int idx = 0; idx < props.length(); idx++) { + if (!strcmp("value", props[idx].id)) { + if (!(props[idx].value >>= s.value)) return false; + } + } + return true; + }; + + inline void operator<<= (CORBA::Any& a, const legacy_message_struct& s) { + CF::Properties props; + props.length(1); + props[0].id = CORBA::string_dup("value"); + props[0].value <<= s.value; + a <<= props; + }; + + // REDHAWK 2.1 message struct, with a getFormat() method that allows it to + // be used with direct in-process messaging to skip Any serialization + struct direct_message_struct { + direct_message_struct () + { + } + + static std::string getId() { + return std::string("direct_message"); + } + + static const char* getFormat() { + return "is"; + } + + CORBA::Long value; + std::string body; + }; + + inline bool operator>>= (const CORBA::Any& a, direct_message_struct& s) { + CF::Properties* temp; + if (!(a >>= temp)) return false; + const redhawk::PropertyMap& props = redhawk::PropertyMap::cast(*temp); + if (props.contains("value")) { + if (!(props["value"] >>= s.value)) return false; + } + if (props.contains("body")) { + if (!(props["body"] >>= s.body)) return false; + } + return true; + } + + inline void operator<<= (CORBA::Any& a, const direct_message_struct& s) { + redhawk::PropertyMap props; + + props["value"] = s.value; + + props["body"] = s.body; + a <<= props; + } + + inline bool operator== (const direct_message_struct& s1, const direct_message_struct& s2) { + if (s1.value!=s2.value) + return false; + if (s1.body!=s2.body) + return false; + return true; + } + + inline bool operator!= (const direct_message_struct& s1, const direct_message_struct& s2) { + return !(s1==s2); + } + + // Utility class for message consumer callbacks + template + class MessageReceiver + { + public: + typedef T message_type; + + void messageReceived(const std::string& messageId, const message_type& msgData) + { + _received.push_back(msgData); + _addresses.push_back(&msgData); + } + + const std::vector& received() const + { + return _received; + } + + const std::vector& addresses() const + { + return _addresses; + } + + private: + std::vector _received; + std::vector _addresses; + }; +} + void MessagingTest::setUp() { _supplier = new MessageSupplierPort("supplier"); @@ -31,6 +160,10 @@ void MessagingTest::setUp() PortableServer::ObjectId_var oid = root_poa->activate_object(_supplier); oid = root_poa->activate_object(_consumer); + // Connect the supplier and consumer + CORBA::Object_var objref = _consumer->_this(); + _supplier->connectPort(objref, "connection_1"); + // Simulate component start _supplier->startPort(); _consumer->startPort(); @@ -64,9 +197,7 @@ void MessagingTest::tearDown() void MessagingTest::testConnections() { - // Connect the supplier and consumer CORBA::Object_var objref = _consumer->_this(); - _supplier->connectPort(objref, "connection_1"); // Verify the connections list ExtendedCF::UsesConnectionSequence_var connections = _supplier->connections(); @@ -103,3 +234,120 @@ void MessagingTest::testConnections() CPPUNIT_ASSERT(names.find("connection_1") != names.end()); CPPUNIT_ASSERT(names.find("connection_3") != names.end()); } + +void MessagingTest::testSendMessage() +{ + // Set up receiver + typedef MessageReceiver receiver_type; + receiver_type receiver; + _consumer->registerMessage("legacy_message", &receiver, &receiver_type::messageReceived); + + legacy_message_struct msg; + msg.value = 1; + + // Send the message and check that it's received. Currently, the consumer's + // message handler is called directly from sendMessage, so this is a + // synchronous operation; however, if at some point in the future, threaded + // message dispatch is added, this test will need to be revisted. + CPPUNIT_ASSERT(receiver.received().empty()); + _supplier->sendMessage(msg); + CPPUNIT_ASSERT_EQUAL((size_t) 1, receiver.received().size()); + + // Check the message contents, working around the old code generators' non- + // const, non-static getId() method with a const_cast + const legacy_message_struct& received = receiver.received().front(); + CPPUNIT_ASSERT_EQUAL(std::string("legacy_message"), const_cast(received).getId()); + CPPUNIT_ASSERT_EQUAL(msg.value, received.value); + + // This test is designed to use the slower Any serialization path for + // message transfer, so check that it actually does + CPPUNIT_ASSERT_MESSAGE("unexpected direct message send", receiver.addresses().front() != &msg); +} + +void MessagingTest::testSendMessageDirect() +{ + // Set up receiver + typedef MessageReceiver receiver_type; + receiver_type receiver; + _consumer->registerMessage("direct_message", &receiver, &receiver_type::messageReceived); + + direct_message_struct msg; + msg.value = 2; + msg.body = "text string"; + + // Send the message and check that it's received. Currently, the consumer's + // message handler is called directly from sendMessage, so this is a + // synchronous operation; however, if at some point in the future, threaded + // message dispatch is added, this test will need to be revisted. + CPPUNIT_ASSERT(receiver.received().empty()); + _supplier->sendMessage(msg); + CPPUNIT_ASSERT_EQUAL((size_t) 1, receiver.received().size()); + + // Check the message contents + const direct_message_struct& received = receiver.received().front(); + CPPUNIT_ASSERT_EQUAL(direct_message_struct::getId(), received.getId()); + CPPUNIT_ASSERT(msg == received); + + // This test is designed to use the slower Any serialization path for + // message transfer, so check that it actually does + CPPUNIT_ASSERT_MESSAGE("direct message transfer not used", receiver.addresses().front() == &msg); +} + +void MessagingTest::testSendMessages() +{ + // Set up receiver + typedef MessageReceiver receiver_type; + receiver_type receiver; + _consumer->registerMessage("legacy_message", &receiver, &receiver_type::messageReceived); + + std::vector messages; + for (size_t index = 0; index < 3; ++index) { + legacy_message_struct msg; + msg.value = index; + messages.push_back(msg); + } + + // Send the messages and check that they are received (see above re: + // threading). + CPPUNIT_ASSERT(receiver.received().empty()); + _supplier->sendMessages(messages); + CPPUNIT_ASSERT_EQUAL(messages.size(), receiver.received().size()); + + // Check the message bodies and make sure that the port used the Any + // serialization path for message transfer + for (size_t index = 0; index < messages.size(); ++index) { + CPPUNIT_ASSERT_EQUAL(messages[index].value, receiver.received()[index].value); + CPPUNIT_ASSERT_MESSAGE("unexpected direct message transfer", &messages[index] != receiver.addresses()[index]); + } +} + +void MessagingTest::testSendMessagesDirect() +{ + // Set up receiver + typedef MessageReceiver receiver_type; + receiver_type receiver; + _consumer->registerMessage("direct_message", &receiver, &receiver_type::messageReceived); + + const char* text[] = { "lorem", "ipsum", "dolor", "sit", "amet", 0 }; + std::vector messages; + for (size_t index = 0; text[index] != 0; ++index) { + direct_message_struct msg; + msg.value = index; + msg.body = text[index]; + messages.push_back(msg); + } + + // Send the messages and check that they are received (see above re: + // threading). + CPPUNIT_ASSERT(receiver.received().empty()); + _supplier->sendMessages(messages); + CPPUNIT_ASSERT_EQUAL(messages.size(), receiver.received().size()); + + // Check all the messages at once + CPPUNIT_ASSERT(messages == receiver.received()); + + // Make sure the port used direct transfer + for (size_t index = 0; index < messages.size(); ++index) { + CPPUNIT_ASSERT_MESSAGE("direct message transfer not used", &messages[index] == receiver.addresses()[index]); + } +} diff --git a/redhawk/src/testing/cpp/MessagingTest.h b/redhawk/src/testing/cpp/MessagingTest.h index 7e2547118..b4d3c1ee4 100644 --- a/redhawk/src/testing/cpp/MessagingTest.h +++ b/redhawk/src/testing/cpp/MessagingTest.h @@ -29,6 +29,10 @@ class MessagingTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(MessagingTest); CPPUNIT_TEST(testConnections); + CPPUNIT_TEST(testSendMessage); + CPPUNIT_TEST(testSendMessageDirect); + CPPUNIT_TEST(testSendMessages); + CPPUNIT_TEST(testSendMessagesDirect); CPPUNIT_TEST_SUITE_END(); public: @@ -37,6 +41,12 @@ class MessagingTest : public CppUnit::TestFixture void testConnections(); + void testSendMessage(); + void testSendMessageDirect(); + + void testSendMessages(); + void testSendMessagesDirect(); + private: MessageSupplierPort* _supplier; MessageConsumerPort* _consumer; From 3d67b8a11786a6fab965f54209d776d172ad57bf Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 26 Sep 2016 12:05:23 -0400 Subject: [PATCH 0460/1644] Add a test for Value's copy constructors --- redhawk/src/testing/cpp/ValueTest.cpp | 18 ++++++++++++++++++ redhawk/src/testing/cpp/ValueTest.h | 2 ++ 2 files changed, 20 insertions(+) diff --git a/redhawk/src/testing/cpp/ValueTest.cpp b/redhawk/src/testing/cpp/ValueTest.cpp index cdc495b03..517b96789 100644 --- a/redhawk/src/testing/cpp/ValueTest.cpp +++ b/redhawk/src/testing/cpp/ValueTest.cpp @@ -77,6 +77,24 @@ void ValueTest::testConstructor() ASSERT_CTOR(CF::Properties, properties); } +void ValueTest::testCopyConstructor() +{ + CORBA::Any any; + CF::Properties properties; + any <<= properties; + CORBA::TypeCode_ptr typecode = any.type(); + redhawk::Value::Type type = redhawk::Value::GetType(typecode); + + // Copy constructor from Any (mostly making sure the type is the same, as + // opposed to nesting another level of Any) + redhawk::Value value(any); + CPPUNIT_ASSERT_EQUAL(type, value.getType()); + + // Copy constructor (again, checking that no accidental nesting occurred) + redhawk::Value copy(value); + CPPUNIT_ASSERT_EQUAL(type, copy.getType()); +} + void ValueTest::testType() { redhawk::Value value; diff --git a/redhawk/src/testing/cpp/ValueTest.h b/redhawk/src/testing/cpp/ValueTest.h index ca7e88ea0..341a75d24 100644 --- a/redhawk/src/testing/cpp/ValueTest.h +++ b/redhawk/src/testing/cpp/ValueTest.h @@ -27,6 +27,7 @@ class ValueTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(ValueTest); CPPUNIT_TEST(testConstructor); + CPPUNIT_TEST(testCopyConstructor); CPPUNIT_TEST(testType); CPPUNIT_TEST(testNumericConversion); CPPUNIT_TEST(testStringConversion); @@ -39,6 +40,7 @@ class ValueTest : public CppUnit::TestFixture void tearDown(); void testConstructor(); + void testCopyConstructor(); void testType(); From aa279ea802358069ca669459f026b7b3a6b53aaa Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 26 Sep 2016 13:05:19 -0400 Subject: [PATCH 0461/1644] Add a constructor for PropertyType that takes a CORBA::Any, to prevent implicit conversions that wrap an Any in another Any --- redhawk/src/base/framework/PropertyType.cpp | 9 ++++++++- redhawk/src/base/include/ossie/PropertyType.h | 1 + redhawk/src/testing/cpp/PropertyMapTest.cpp | 13 +++++++++++++ redhawk/src/testing/cpp/PropertyMapTest.h | 2 ++ 4 files changed, 24 insertions(+), 1 deletion(-) diff --git a/redhawk/src/base/framework/PropertyType.cpp b/redhawk/src/base/framework/PropertyType.cpp index 950f28eb6..7c84fbfb7 100644 --- a/redhawk/src/base/framework/PropertyType.cpp +++ b/redhawk/src/base/framework/PropertyType.cpp @@ -32,11 +32,18 @@ PropertyType::PropertyType(const CF::DataType& dt) : { } +PropertyType::PropertyType(const std::string& identifier, const CORBA::Any& value) : + CF::DataType() +{ + setId(identifier); + this->value = value; +} + PropertyType::PropertyType(const std::string& identifier, const Value& value) : CF::DataType() { setId(identifier); - setValue(value); + this->value = value; } PropertyType& PropertyType::operator=(const CF::DataType& dt) diff --git a/redhawk/src/base/include/ossie/PropertyType.h b/redhawk/src/base/include/ossie/PropertyType.h index 2598001b0..16fabbbd4 100644 --- a/redhawk/src/base/include/ossie/PropertyType.h +++ b/redhawk/src/base/include/ossie/PropertyType.h @@ -41,6 +41,7 @@ namespace redhawk { PropertyType(); explicit PropertyType(const CF::DataType& dt); + PropertyType(const std::string& id, const CORBA::Any& value); PropertyType(const std::string& id, const Value& value); PropertyType& operator=(const CF::DataType& dt); diff --git a/redhawk/src/testing/cpp/PropertyMapTest.cpp b/redhawk/src/testing/cpp/PropertyMapTest.cpp index 685e6f391..269ca0ba1 100644 --- a/redhawk/src/testing/cpp/PropertyMapTest.cpp +++ b/redhawk/src/testing/cpp/PropertyMapTest.cpp @@ -74,6 +74,19 @@ void PropertyMapTest::testPropertiesConstructor() CPPUNIT_ASSERT_EQUAL((size_t) properties.length(), propmap.size()); } +void PropertyMapTest::testPropertyTypeFromAny() +{ + // Due to the implicit conversion from the templatized constructor for + // Value (the explicit keyword was removed for 2.1), it was necessary to + // add a constructor to PropertyType that takes a CORBA::Any as the value + // argument to prevent accidental nesting of Anys; this test simply ensures + // that this works + CORBA::Any any; + any <<= CF::Properties(); + redhawk::PropertyType prop("test", any); + CPPUNIT_ASSERT_EQUAL(redhawk::Value::TYPE_PROPERTIES, prop.getValue().getType()); +} + void PropertyMapTest::testConstCast() { // Create a known set of CF::Properties diff --git a/redhawk/src/testing/cpp/PropertyMapTest.h b/redhawk/src/testing/cpp/PropertyMapTest.h index 24a7df183..20cfe49c3 100644 --- a/redhawk/src/testing/cpp/PropertyMapTest.h +++ b/redhawk/src/testing/cpp/PropertyMapTest.h @@ -28,6 +28,7 @@ class PropertyMapTest : public CppUnit::TestFixture CPPUNIT_TEST_SUITE(PropertyMapTest); CPPUNIT_TEST(testDefaultConstructor); CPPUNIT_TEST(testPropertiesConstructor); + CPPUNIT_TEST(testPropertyTypeFromAny); CPPUNIT_TEST(testConstCast); CPPUNIT_TEST(testCast); CPPUNIT_TEST(testPushBack); @@ -51,6 +52,7 @@ class PropertyMapTest : public CppUnit::TestFixture void testDefaultConstructor(); void testPropertiesConstructor(); + void testPropertyTypeFromAny(); void testConstCast(); void testCast(); From eeeb1114cbc9947352da2fb2bef67aad1a1e055c Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 26 Sep 2016 13:15:45 -0400 Subject: [PATCH 0462/1644] CppUnit test for generic message callbacks --- redhawk/src/testing/cpp/MessagingTest.cpp | 51 +++++++++++++++++++++++ redhawk/src/testing/cpp/MessagingTest.h | 3 ++ 2 files changed, 54 insertions(+) diff --git a/redhawk/src/testing/cpp/MessagingTest.cpp b/redhawk/src/testing/cpp/MessagingTest.cpp index 9bf92f773..5b3092a10 100644 --- a/redhawk/src/testing/cpp/MessagingTest.cpp +++ b/redhawk/src/testing/cpp/MessagingTest.cpp @@ -149,6 +149,24 @@ namespace { std::vector _received; std::vector _addresses; }; + + // Utility class for generic message (CORBA::Any) callbacks + class GenericReceiver + { + public: + void messageReceived(const std::string& messageId, const CORBA::Any& msgData) + { + _received.push_back(redhawk::PropertyType(messageId, msgData)); + } + + const redhawk::PropertyMap& received() const + { + return _received; + } + + private: + redhawk::PropertyMap _received; + }; } void MessagingTest::setUp() @@ -351,3 +369,36 @@ void MessagingTest::testSendMessagesDirect() CPPUNIT_ASSERT_MESSAGE("direct message transfer not used", &messages[index] == receiver.addresses()[index]); } } + +void MessagingTest::testGenericCallback() +{ + // Set up receiver + GenericReceiver receiver; + _consumer->registerMessage(&receiver, &GenericReceiver::messageReceived); + + // Send legacy_message and direct_message; with a generic callback, + // everything necessarily goes through Any serialization, so there's no + // distinction made other than there being two different message types + legacy_message_struct legacy; + legacy.value = 50; + _supplier->sendMessage(legacy); + + direct_message_struct direct; + direct.value = 100; + direct.body = "lorem ipsum"; + _supplier->sendMessage(direct); + + // Check that the messages were received (see above re: threading) + const redhawk::PropertyMap& messages = receiver.received(); + CPPUNIT_ASSERT_EQUAL((size_t) 2, messages.size()); + + legacy_message_struct legacy_out; + CPPUNIT_ASSERT_EQUAL(std::string("legacy_message"), messages[0].getId()); + CPPUNIT_ASSERT(messages[0].getValue() >>= legacy_out); + CPPUNIT_ASSERT_EQUAL(legacy.value, legacy_out.value); + + direct_message_struct direct_out; + CPPUNIT_ASSERT_EQUAL(direct_message_struct::getId(), messages[1].getId()); + CPPUNIT_ASSERT(messages[1].getValue() >>= direct_out); + CPPUNIT_ASSERT(direct == direct_out); +} diff --git a/redhawk/src/testing/cpp/MessagingTest.h b/redhawk/src/testing/cpp/MessagingTest.h index b4d3c1ee4..ccd66f182 100644 --- a/redhawk/src/testing/cpp/MessagingTest.h +++ b/redhawk/src/testing/cpp/MessagingTest.h @@ -33,6 +33,7 @@ class MessagingTest : public CppUnit::TestFixture CPPUNIT_TEST(testSendMessageDirect); CPPUNIT_TEST(testSendMessages); CPPUNIT_TEST(testSendMessagesDirect); + CPPUNIT_TEST(testGenericCallback); CPPUNIT_TEST_SUITE_END(); public: @@ -47,6 +48,8 @@ class MessagingTest : public CppUnit::TestFixture void testSendMessages(); void testSendMessagesDirect(); + void testGenericCallback(); + private: MessageSupplierPort* _supplier; MessageConsumerPort* _consumer; From 1fc824604925060105627459fa38cee0bae87cd7 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 27 Sep 2016 08:24:25 -0400 Subject: [PATCH 0463/1644] CppUnit test for ExecutorService --- .../src/testing/cpp/ExecutorServiceTest.cpp | 177 ++++++++++++++++++ redhawk/src/testing/cpp/ExecutorServiceTest.h | 48 +++++ redhawk/src/testing/cpp/Makefile.am | 1 + 3 files changed, 226 insertions(+) create mode 100644 redhawk/src/testing/cpp/ExecutorServiceTest.cpp create mode 100644 redhawk/src/testing/cpp/ExecutorServiceTest.h diff --git a/redhawk/src/testing/cpp/ExecutorServiceTest.cpp b/redhawk/src/testing/cpp/ExecutorServiceTest.cpp new file mode 100644 index 000000000..f15f36c39 --- /dev/null +++ b/redhawk/src/testing/cpp/ExecutorServiceTest.cpp @@ -0,0 +1,177 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK core. + * + * REDHAWK core is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +#include "ExecutorServiceTest.h" + +CPPUNIT_TEST_SUITE_REGISTRATION(ExecutorServiceTest); + +namespace { + + class CommandTracker + { + public: + CommandTracker() + { + } + + void run() + { + runCommand(std::string()); + } + + void runCommand(const std::string& command) + { + boost::mutex::scoped_lock lock(_mutex); + _commands.push_back(command); + _cond.notify_all(); + } + + int count() const + { + return _commands.size(); + } + + bool wait(size_t count, boost::system_time when) + { + boost::mutex::scoped_lock lock(_mutex); + while (_commands.size() < count) { + if (!_cond.timed_wait(lock, when)) { + break; + } + } + return _commands.size() >= count; + } + + void reset() + { + _commands.clear(); + } + + static CommandTracker& Global() + { + static CommandTracker tracker; + return tracker; + } + + static void runGlobal() + { + Global().run(); + } + + private: + boost::mutex _mutex; + boost::condition_variable _cond; + + std::vector _commands; + }; +} + +void ExecutorServiceTest::setUp() +{ + CommandTracker::Global().reset(); +} + +void ExecutorServiceTest::tearDown() +{ + _service.stop(); +} + +void ExecutorServiceTest::testExecute() +{ + _service.start(); + + // No-argument (global) function + CPPUNIT_ASSERT_EQUAL(0, CommandTracker::Global().count()); + _service.execute(&CommandTracker::runGlobal); + + CommandTracker tracker; + CPPUNIT_ASSERT_EQUAL(0, tracker.count()); + + // One-argument (member) function + _service.execute(&CommandTracker::run, &tracker); + + // Two-argument (member) function + _service.execute(&CommandTracker::runCommand, &tracker, "testExecute"); + + // Wait up to 1000us for the commands to be executed + boost::system_time timeout = boost::get_system_time() + boost::posix_time::microseconds(1000); + CPPUNIT_ASSERT(CommandTracker::Global().wait(1, timeout)); + CPPUNIT_ASSERT_EQUAL(1, CommandTracker::Global().count()); + + CPPUNIT_ASSERT(tracker.wait(2, timeout)); + CPPUNIT_ASSERT_EQUAL(2, tracker.count()); +} + +void ExecutorServiceTest::testSchedule() +{ + _service.start(); + + // No-argument (global) function + CPPUNIT_ASSERT_EQUAL(0, CommandTracker::Global().count()); + boost::system_time first = boost::get_system_time() + boost::posix_time::microseconds(1000); + _service.schedule(first, &CommandTracker::runGlobal); + + CommandTracker tracker; + CPPUNIT_ASSERT_EQUAL(0, tracker.count()); + + // One-argument (member) function + boost::system_time second = first + boost::posix_time::microseconds(1000); + _service.schedule(second, &CommandTracker::run, &tracker); + + // Two-argument (member) function + boost::system_time third = second + boost::posix_time::microseconds(1000); + _service.schedule(third, &CommandTracker::runCommand, &tracker, "testSchedule"); + + // Use maximum wait of 10000us (from now) for the commands to be executed + // (it should take approximately 3000us, but allow some slack in the event + // of scheduler delays) + boost::system_time timeout = boost::get_system_time() + boost::posix_time::microseconds(10000); + + // Wait for the first command, and check enough time has passed + CPPUNIT_ASSERT(CommandTracker::Global().wait(1, timeout)); + CPPUNIT_ASSERT_EQUAL(1, CommandTracker::Global().count()); + CPPUNIT_ASSERT(boost::get_system_time() >= first); + + // Wait for the second and third commands, again checking that enough time + // has passed + CPPUNIT_ASSERT(tracker.wait(1, timeout)); + CPPUNIT_ASSERT(boost::get_system_time() >= second); + CPPUNIT_ASSERT(tracker.wait(2, timeout)); + CPPUNIT_ASSERT(boost::get_system_time() >= third); + CPPUNIT_ASSERT_EQUAL(2, tracker.count()); +} + +void ExecutorServiceTest::testClear() +{ + CommandTracker tracker; + + _service.execute(&CommandTracker::run, &tracker); + + boost::system_time when = boost::get_system_time() + boost::posix_time::seconds(1); + _service.schedule(when, &CommandTracker::run, &tracker); + + _service.clear(); + _service.start(); + + // TODO: Better determination of pending + usleep(1000); + + CPPUNIT_ASSERT_EQUAL(0, tracker.count()); +} diff --git a/redhawk/src/testing/cpp/ExecutorServiceTest.h b/redhawk/src/testing/cpp/ExecutorServiceTest.h new file mode 100644 index 000000000..29a0abdd2 --- /dev/null +++ b/redhawk/src/testing/cpp/ExecutorServiceTest.h @@ -0,0 +1,48 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK core. + * + * REDHAWK core is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +#ifndef EXECUTORSERVICETEST_H +#define EXECUTORSERVICETEST_H + +#include + +#include + +class ExecutorServiceTest : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE(ExecutorServiceTest); + CPPUNIT_TEST(testExecute); + CPPUNIT_TEST(testSchedule); + CPPUNIT_TEST(testClear); + CPPUNIT_TEST_SUITE_END(); + +public: + void setUp(); + void tearDown(); + + void testExecute(); + void testSchedule(); + void testClear(); + +private: + redhawk::ExecutorService _service; +}; + +#endif // EXECUTORSERVICETEST_H diff --git a/redhawk/src/testing/cpp/Makefile.am b/redhawk/src/testing/cpp/Makefile.am index 5af745888..829c17114 100644 --- a/redhawk/src/testing/cpp/Makefile.am +++ b/redhawk/src/testing/cpp/Makefile.am @@ -13,5 +13,6 @@ test_libossiecf_SOURCES += ValueTest.cpp ValueTest.h test_libossiecf_SOURCES += ValueSequenceTest.cpp ValueSequenceTest.h test_libossiecf_SOURCES += PropertyMapTest.cpp PropertyMapTest.h test_libossiecf_SOURCES += MessagingTest.cpp MessagingTest.h +test_libossiecf_SOURCES += ExecutorServiceTest.cpp ExecutorServiceTest.h test_libossiecf_CXXFLAGS = $(CPPUNIT_CFLAGS) -I $(top_srcdir)/base/include test_libossiecf_LDFLAGS = $(CPPUNIT_LIBS) $(top_builddir)/base/framework/libossiecf.la $(top_builddir)/base/framework/idl/libossieidl.la From 31ade028e1706c44cfd3b8fbccca10645dd39328 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 27 Sep 2016 11:00:46 -0400 Subject: [PATCH 0464/1644] Add a pending() method to ExecutorService for checking the queue depth, and use that for the clear() unit test; add a unit test for stop() --- .../src/base/include/ossie/ExecutorService.h | 2 + .../src/testing/cpp/ExecutorServiceTest.cpp | 53 +++++++++++++++++-- redhawk/src/testing/cpp/ExecutorServiceTest.h | 2 + 3 files changed, 53 insertions(+), 4 deletions(-) diff --git a/redhawk/src/base/include/ossie/ExecutorService.h b/redhawk/src/base/include/ossie/ExecutorService.h index cb11e81c9..d55adff2b 100644 --- a/redhawk/src/base/include/ossie/ExecutorService.h +++ b/redhawk/src/base/include/ossie/ExecutorService.h @@ -106,6 +106,8 @@ namespace redhawk { cond_.notify_all(); } + size_t pending (); + private: typedef boost::function func_type; typedef std::pair task_type; diff --git a/redhawk/src/testing/cpp/ExecutorServiceTest.cpp b/redhawk/src/testing/cpp/ExecutorServiceTest.cpp index f15f36c39..f384cec4e 100644 --- a/redhawk/src/testing/cpp/ExecutorServiceTest.cpp +++ b/redhawk/src/testing/cpp/ExecutorServiceTest.cpp @@ -158,20 +158,65 @@ void ExecutorServiceTest::testSchedule() CPPUNIT_ASSERT_EQUAL(2, tracker.count()); } +void ExecutorServiceTest::testStop() +{ + _service.start(); + + CommandTracker tracker; + + // Schedule a task far enough in the future that we can stop the service's + // thread before it is executed + boost::system_time when = boost::get_system_time() + boost::posix_time::microseconds(1000); + _service.schedule(when, &CommandTracker::run, &tracker); + + // Stop the service; check that the scheduled time for the task is still in + // the future, and that it was not executed + _service.stop(); + CPPUNIT_ASSERT_MESSAGE("scheduled time already passed", boost::get_system_time() < when); + CPPUNIT_ASSERT_EQUAL(0, tracker.count()); + CPPUNIT_ASSERT_EQUAL((size_t) 1, _service.pending()); + + // Wait until the scheduled time for the task has passed, plus a small + // fudge factor to account for thread timing + when += boost::posix_time::microseconds(500); + while (boost::get_system_time() < when) { + CPPUNIT_ASSERT(!tracker.wait(1, when)); + } + CPPUNIT_ASSERT_MESSAGE("failed to wait requested time", boost::get_system_time() >= when); + + // The task should still not have executed + CPPUNIT_ASSERT_EQUAL(0, tracker.count()); + CPPUNIT_ASSERT_EQUAL((size_t) 1, _service.pending()); + + // Start the service; it should be able to run the task as soon as the + // thread begins + _service.start(); + + // Wait a little bit to give the service's thread time to execute the task + // and check that it has, in fact, happenend + boost::system_time timeout = boost::get_system_time() + boost::posix_time::microseconds(500); + CPPUNIT_ASSERT(tracker.wait(1, timeout)); + CPPUNIT_ASSERT_EQUAL((size_t) 0, _service.pending()); +} + void ExecutorServiceTest::testClear() { CommandTracker tracker; + // Queue a command to be executed now, and one in the future _service.execute(&CommandTracker::run, &tracker); - boost::system_time when = boost::get_system_time() + boost::posix_time::seconds(1); _service.schedule(when, &CommandTracker::run, &tracker); + // Check that both tasks are currently pending + CPPUNIT_ASSERT_EQUAL((size_t) 2, _service.pending()); + + // Clear the pending tasks and then start the service--doing it in this + // order makes it deterministic whether any tasks are executed _service.clear(); _service.start(); - // TODO: Better determination of pending - usleep(1000); - + // There should be no pending tasks, and nothing should have been executed + CPPUNIT_ASSERT_EQUAL((size_t) 0, _service.pending()); CPPUNIT_ASSERT_EQUAL(0, tracker.count()); } diff --git a/redhawk/src/testing/cpp/ExecutorServiceTest.h b/redhawk/src/testing/cpp/ExecutorServiceTest.h index 29a0abdd2..a1b26b5ab 100644 --- a/redhawk/src/testing/cpp/ExecutorServiceTest.h +++ b/redhawk/src/testing/cpp/ExecutorServiceTest.h @@ -30,6 +30,7 @@ class ExecutorServiceTest : public CppUnit::TestFixture CPPUNIT_TEST_SUITE(ExecutorServiceTest); CPPUNIT_TEST(testExecute); CPPUNIT_TEST(testSchedule); + CPPUNIT_TEST(testStop); CPPUNIT_TEST(testClear); CPPUNIT_TEST_SUITE_END(); @@ -39,6 +40,7 @@ class ExecutorServiceTest : public CppUnit::TestFixture void testExecute(); void testSchedule(); + void testStop(); void testClear(); private: From 24ae76966e7546799a426559deb8890b399f9011 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 27 Sep 2016 13:27:37 -0400 Subject: [PATCH 0465/1644] Add Doxygen comment documentation to ExecutorService --- .../src/base/include/ossie/ExecutorService.h | 242 +++++++++++------- 1 file changed, 155 insertions(+), 87 deletions(-) diff --git a/redhawk/src/base/include/ossie/ExecutorService.h b/redhawk/src/base/include/ossie/ExecutorService.h index d55adff2b..d6a0af92b 100644 --- a/redhawk/src/base/include/ossie/ExecutorService.h +++ b/redhawk/src/base/include/ossie/ExecutorService.h @@ -17,6 +17,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see http://www.gnu.org/licenses/. */ + #ifndef REDHAWK_EXECUTORSERVICE_H #define REDHAWK_EXECUTORSERVICE_H @@ -28,142 +29,209 @@ namespace redhawk { + /** + * @brief A class for scheduling functions to run at a later time. + * + * %ExecutorService provides an interface for queueing functions to run on + * another thread at a specified time. This can be used for implementing + * periodic monitors, executing deferred callbacks, or other operations + * that do not need to be performed immediately (and do not require a + * return value). + */ class ExecutorService { public: - ExecutorService() : - thread_(0), - running_(false) - { - } - - void start () - { - boost::mutex::scoped_lock lock(mutex_); - if (running_) { - return; - } - - running_ = true; - thread_ = new boost::thread(&ExecutorService::run, this); - } - - void stop () - { - boost::thread* old_thread = 0; - { - boost::mutex::scoped_lock lock(mutex_); - running_ = false; - old_thread = thread_; - thread_ = 0; - cond_.notify_all(); - } - if (old_thread) { - old_thread->join(); - delete old_thread; - } - } - + /** + * @brief Construct an %ExecutorService. + * + * The %ExecutorService is created in a stopped state. To begin + * executing scheduled functions, call start(). + */ + ExecutorService(); + + /** + * @brief Starts executing scheduled functions. + * + * If the executor thread is not running, it is started. Any functions + * scheduled for the current time (or earlier) will be run at the next + * possible time. + */ + void start (); + + /** + * @brief Stops executing scheduled functions. + * + * If the executor thread is running, it is stopped. Any remaining + * scheduled functions will not be run until the %ExecutorService is + * started again. + */ + void stop (); + + /** + * @brief Calls a function on the executor thread. + * @param func Callable object. + * + * Queues the callable object @a func to be called on the executor + * thread at the next possible time. This function does not wait for + * @a func to execute. + * + * If the %ExecutorService is not running, @a func will run after the + * next call to start(). + */ template void execute (F func) { insert_sorted(func); } + /** + * @brief Calls a function on the executor thread. + * @param func Callable object. + * @param A1 Argument to pass to callable object. + * + * Queues the callable object @a func to be called with the single + * argument @a A1 on the executor thread at the next possible time. + * This function does not wait for @a func to execute. + * + * If @a func is a class member function, the class instance should be + * passed as @a A1. + * + * If the %ExecutorService is not running, @a func will run after the + * next call to start(). + */ template void execute (F func, A1 arg1) { insert_sorted(boost::bind(func, arg1)); } + /** + * @brief Calls a function on the executor thread. + * @param func Callable object. + * @param A1 First argument to pass to callable object. + * @param A2 Second argument to pass to callable object. + * + * Queues the callable object @a func to be called with the arguments + * @a A1 and @a A2 on the executor thread at the next possible time. + * This function does not wait for @a func to execute. + * + * If @a func is a class member function, the class instance should be + * passed as @a A1. + * + * If the %ExecutorService is not running, @a func will run after the + * next call to start(). + */ template void execute (F func, A1 arg1, A2 arg2) { insert_sorted(boost::bind(func, arg1, arg2)); } + /** + * @brief Schedules a function on the executor thread. + * @param when The time at which to run the function. + * @param func Callable object. + * + * Queues the callable object @a func to be called on the executor + * thread at @a when. The actual time at which it runs is guaranteed to + * be at least @a when, but may be later, depending on the system and + * what the %ExecutorService is doing at the time. + * + * If the %ExecutorService is not running at the scheduled time, + * @a func will run after the next call to start(). + */ template void schedule (boost::system_time when, F func) { insert_sorted(func, when); } + /** + * @brief Schedules a function on the executor thread. + * @param when The time at which to run the function. + * @param func Callable object. + * @param A1 Argument to pass to callable object. + * + * Queues the callable object @a func to be called with the single + * argument @a A1 on the executor thread at @a when. The actual time + * at which it runs is guaranteed to be at least @a when, but may be + * later, depending on the system and what the %ExecutorService is + * doing at the time. + * + * If @a func is a class member function, the class instance should be + * passed as @a A1. + * + * If the %ExecutorService is not running at the scheduled time, + * @a func will run after the next call to start(). + */ template void schedule (boost::system_time when, F func, A1 arg1) { insert_sorted(boost::bind(func, arg1), when); } + /** + * @brief Schedules a function on the executor thread. + * @param when The time at which to run the function. + * @param func Callable object. + * @param A1 First argument to pass to callable object. + * @param A2 Second argument to pass to callable object. + * + * Queues the callable object @a func to be called with the arguments + * @a A1 and @a A2 on the executor thread at @a when. The actual time + * at which it runs is guaranteed to be at least @a when, but may be + * later, depending on the system and what the %ExecutorService is + * doing at the time. + * + * If @a func is a class member function, the class instance should be + * passed as @a A1. + * + * If the %ExecutorService is not running at the scheduled time, + * @a func will run after the next call to start(). + */ template void schedule (boost::system_time when, F func, A1 arg1, A2 arg2) { insert_sorted(boost::bind(func, arg1, arg2), when); } - void clear () - { - boost::mutex::scoped_lock lock(mutex_); - queue_.clear(); - cond_.notify_all(); - } + /** + * @brief Discards all pending functions. + */ + void clear (); + /** + * @brief Returns the number of queued functions to be run. + */ size_t pending (); private: + /// @cond IMPL + typedef boost::function func_type; typedef std::pair task_type; typedef std::list task_queue; - void run () - { - boost::mutex::scoped_lock lock(mutex_); - while (running_) { - while (!queue_.empty()) { - // Start at the front of the queue every time--a task may - // have been added while the lock was released to service - // the last task - task_queue::iterator task = queue_.begin(); - if (task->first > boost::get_system_time()) { - // Head of queue is scheduled in the future - break; - } - - // Copy the task's function and remove it from the queue - func_type func = task->second; - queue_.erase(task); - - // Run task with the lock released - lock.unlock(); - func(); - lock.lock(); - } - - if (queue_.empty()) { - cond_.wait(lock); - } else { - boost::system_time when = queue_.front().first; - cond_.timed_wait(lock, when); - } - } - } - - void insert_sorted (func_type func, boost::system_time when=boost::get_system_time()) - { - boost::mutex::scoped_lock lock(mutex_); - task_queue::iterator pos = queue_.begin(); - while ((pos != queue_.end()) && (when > pos->first)) { - ++pos; - } - queue_.insert(pos, std::make_pair(when, func)); - cond_.notify_all(); - } + // Thread main function. + void _run (); + // Inserts a callable object into the task queue at the given time, + // defaulting to now (i.e., run at the next possible time). + void _insertSorted (func_type func, boost::system_time when=boost::get_system_time()); - boost::mutex mutex_; - boost::condition_variable cond_; + // Mutex/condvar pair to synchronize access and handle waiting for the + // next scheduled event. + boost::mutex _mutex; + boost::condition_variable _cond; - boost::thread* thread_; - task_queue queue_; - bool running_; + // Executor thread and control flag. + boost::thread* _thread; + volatile bool _running; + + // Function queue, sorted by scheduled time such that the first item on + // the queue is the next function to call. + task_queue _queue; + + /// @endcond }; } From 9ce4624b41e513e90b7309e674f238d95a3b4753 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 27 Sep 2016 13:29:49 -0400 Subject: [PATCH 0466/1644] Rename standalone test to make it clear that it's a test --- redhawk/src/testing/cpp/.gitignore | 2 +- redhawk/src/testing/cpp/Makefile.am | 8 ++++---- .../testing/cpp/{standalone.cpp => test_standalone.cpp} | 0 3 files changed, 5 insertions(+), 5 deletions(-) rename redhawk/src/testing/cpp/{standalone.cpp => test_standalone.cpp} (100%) diff --git a/redhawk/src/testing/cpp/.gitignore b/redhawk/src/testing/cpp/.gitignore index 3055470f1..3cda5b88d 100644 --- a/redhawk/src/testing/cpp/.gitignore +++ b/redhawk/src/testing/cpp/.gitignore @@ -1,2 +1,2 @@ -standalone +test_standalone test_libossiecf diff --git a/redhawk/src/testing/cpp/Makefile.am b/redhawk/src/testing/cpp/Makefile.am index 829c17114..cfa6b2151 100644 --- a/redhawk/src/testing/cpp/Makefile.am +++ b/redhawk/src/testing/cpp/Makefile.am @@ -1,12 +1,12 @@ -TESTS = standalone test_libossiecf +TESTS = test_standalone test_libossiecf AM_CPPFLAGS = -Wall check_PROGRAMS = $(TESTS) -standalone_SOURCES = standalone.cpp SharedBufferTest.cpp SharedBufferTest.h -standalone_CXXFLAGS = $(CPPUNIT_CFLAGS) -I $(top_srcdir)/base/include -standalone_LDFLAGS = $(CPPUNIT_LIBS) +test_standalone_SOURCES = test_standalone.cpp SharedBufferTest.cpp SharedBufferTest.h +test_standalone_CXXFLAGS = $(CPPUNIT_CFLAGS) -I $(top_srcdir)/base/include +test_standalone_LDFLAGS = $(CPPUNIT_LIBS) test_libossiecf_SOURCES = test_libossiecf.cpp test_libossiecf_SOURCES += ValueTest.cpp ValueTest.h diff --git a/redhawk/src/testing/cpp/standalone.cpp b/redhawk/src/testing/cpp/test_standalone.cpp similarity index 100% rename from redhawk/src/testing/cpp/standalone.cpp rename to redhawk/src/testing/cpp/test_standalone.cpp From f354f465702370062cac515a814f9933a9e82a26 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 28 Sep 2016 16:38:17 -0400 Subject: [PATCH 0467/1644] Prevent exceptions escaping from ossie::any:toNumber() functions, instead returning false in all cases where the conversion fails (which was the original intent) --- redhawk/src/base/framework/AnyUtils.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/redhawk/src/base/framework/AnyUtils.cpp b/redhawk/src/base/framework/AnyUtils.cpp index b6e7a96ab..2031dde94 100644 --- a/redhawk/src/base/framework/AnyUtils.cpp +++ b/redhawk/src/base/framework/AnyUtils.cpp @@ -163,12 +163,16 @@ namespace { #define ANY_TO_NUMERIC_TYPE(T,N) \ bool ossie::any::toNumber (const CORBA::Any& any, T& value) \ { \ - return anyToNumber(any, value); \ + try { \ + return ::anyToNumber(any, value); \ + } catch (...) { \ + return false; \ + } \ } \ T ossie::any::to##N (const CORBA::Any& any) \ { \ - T value; \ - if (ossie::any::toNumber(any, value)) { \ + T value = 0; \ + if (::anyToNumber(any, value)) { \ return value; \ } else { \ throw std::invalid_argument("Non-numeric Any type"); \ From 09c48700dc87d4fd0b8d194e4eba586a44e8acaf Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 29 Sep 2016 14:32:02 -0400 Subject: [PATCH 0468/1644] Basic AnyUtils unit tests --- redhawk/src/testing/cpp/AnyUtilsTest.cpp | 301 +++++++++++++++++++++++ redhawk/src/testing/cpp/AnyUtilsTest.h | 73 ++++++ redhawk/src/testing/cpp/Makefile.am | 1 + 3 files changed, 375 insertions(+) create mode 100644 redhawk/src/testing/cpp/AnyUtilsTest.cpp create mode 100644 redhawk/src/testing/cpp/AnyUtilsTest.h diff --git a/redhawk/src/testing/cpp/AnyUtilsTest.cpp b/redhawk/src/testing/cpp/AnyUtilsTest.cpp new file mode 100644 index 000000000..0d457900b --- /dev/null +++ b/redhawk/src/testing/cpp/AnyUtilsTest.cpp @@ -0,0 +1,301 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK core. + * + * REDHAWK core is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +#include "AnyUtilsTest.h" + +#include +#include +#include + +#include + +CPPUNIT_TEST_SUITE_REGISTRATION(AnyUtilsTest); + +namespace { + + template + struct range_test + { + typedef std::numeric_limits limits; + + static T min() + { + return limits::min(); + } + + static T max() + { + return limits::max(); + } + + static double exceed_min() + { + return limits::min() - 1.0; + } + + static double exceed_max() + { + return limits::max() + 1.0; + } + + static double epsilon() + { + int bits = limits::digits - std::numeric_limits::digits; + if (bits < 0) { + bits = 0; + } + return 1 << bits; + } + }; + + template <> + CORBA::LongLong range_test::min() + { + return limits::min() + epsilon(); + } + + template <> + CORBA::LongLong range_test::max() + { + return limits::max() - (epsilon() - 1); + } + + template <> + CORBA::ULongLong range_test::max() + { + return limits::max() - (epsilon() - 1); + } + + template <> + float range_test::min() + { + return -max(); + } + + template <> + double range_test::exceed_max() + { + return 2.0 * max(); + } + + template <> + double range_test::exceed_min() + { + return -exceed_max(); + } +} + +void AnyUtilsTest::setUp() +{ +} + +void AnyUtilsTest::tearDown() +{ +} + +void AnyUtilsTest::testIsNull() +{ + // Default constructor, Any has no type information + CORBA::Any any; + CPPUNIT_ASSERT(ossie::any::isNull(any)); + + // Insert a number, should no longer be null + any <<= 1; + CPPUNIT_ASSERT(!ossie::any::isNull(any)); + + // Likewise, a more complex type should not be null + any <<= CF::Properties(); + CPPUNIT_ASSERT(!ossie::any::isNull(any)); +} + +void AnyUtilsTest::testToBoolean() +{ + CORBA::Any any; + bool result; + + // Case-insensitive string literal + any <<= "true"; + CPPUNIT_ASSERT(ossie::any::toBoolean(any)); + CPPUNIT_ASSERT(ossie::any::toNumber(any, result)); + CPPUNIT_ASSERT_EQUAL(true, result); + + // Case-insensitive string literal + any <<= "False"; + CPPUNIT_ASSERT(!ossie::any::toBoolean(any)); + CPPUNIT_ASSERT(ossie::any::toNumber(any, result)); + CPPUNIT_ASSERT_EQUAL(false, result); + + // Integer, converted by C++ rules (zero == false) + any <<= 0; + CPPUNIT_ASSERT(!ossie::any::toBoolean(any)); + CPPUNIT_ASSERT(ossie::any::toNumber(any, result)); + CPPUNIT_ASSERT_EQUAL(false, result); + + // Double, converted by C++ rules (non-zero == true) + any <<= 100.5; + CPPUNIT_ASSERT(ossie::any::toBoolean(any)); + CPPUNIT_ASSERT(ossie::any::toNumber(any, result)); + CPPUNIT_ASSERT_EQUAL(true, result); + + // String that can be converted via a number + any <<= "5000"; + CPPUNIT_ASSERT(ossie::any::toBoolean(any)); + CPPUNIT_ASSERT(ossie::any::toNumber(any, result)); + CPPUNIT_ASSERT_EQUAL(true, result); + + // String that cannot be interpreted as a boolean at all + any <<= "invalid"; + CPPUNIT_ASSERT_THROW(ossie::any::toBoolean(any), std::bad_cast); + CPPUNIT_ASSERT(!ossie::any::toNumber(any, result)); +} + +void AnyUtilsTest::testOctetConversion() +{ + CORBA::Any any; + any <<= "0"; + CPPUNIT_ASSERT_EQUAL((CORBA::Octet) 0, ossie::any::toOctet(any)); + + any <<= "255"; + CPPUNIT_ASSERT_EQUAL((CORBA::Octet) 255, ossie::any::toOctet(any)); + + any <<= "256"; + CPPUNIT_ASSERT_THROW(ossie::any::toOctet(any), std::range_error); + + testConversionImpl(&ossie::any::toOctet); +} + +void AnyUtilsTest::testShortConversion() +{ + testConversionImpl(&ossie::any::toShort); +} + +void AnyUtilsTest::testUShortConversion() +{ + testConversionImpl(&ossie::any::toUShort); +} + +void AnyUtilsTest::testLongConversion() +{ + testConversionImpl(&ossie::any::toLong); +} + +void AnyUtilsTest::testULongConversion() +{ + testConversionImpl(&ossie::any::toULong); +} + +void AnyUtilsTest::testLongLongConversion() +{ + testConversionImpl(&ossie::any::toLongLong); +} + +void AnyUtilsTest::testULongLongConversion() +{ + testConversionImpl(&ossie::any::toULongLong); +} + +void AnyUtilsTest::testFloatConversion() +{ + testConversionImpl(&ossie::any::toFloat); +} + +void AnyUtilsTest::testStringToNumber() +{ + CORBA::Any any; + + // Simple integer conversion + any <<= "100000"; + CORBA::Long lval; + CPPUNIT_ASSERT_NO_THROW(lval = ossie::any::toLong(any)); + CPPUNIT_ASSERT_EQUAL((CORBA::Long) 100000, lval); + + // Use a floating point value that is known to show a decimal point and + // exponent + double value = 1.125e7; + std::ostringstream oss; + oss << value; + any <<= oss.str(); + + // Conversion back to double should be simple + double dval; + CPPUNIT_ASSERT_NO_THROW(dval = ossie::any::toDouble(any)); + CPPUNIT_ASSERT_EQUAL(value, dval); + + // Conversion to an integer requires it to parse the number as a double + // (because of the decimal point and exponent) before converting to the + // final integer type + lval = 0; + CPPUNIT_ASSERT_NO_THROW(lval = ossie::any::toLong(any)); + CPPUNIT_ASSERT_EQUAL((CORBA::Long)value, lval); +} + +template +void AnyUtilsTest::testFromBoolean(T (*func)(const CORBA::Any&)) +{ + CORBA::Any any; + + any <<= true; + CPPUNIT_ASSERT_EQUAL((T) 1, func(any)); + + any <<= false; + CPPUNIT_ASSERT_EQUAL((T) 0, func(any)); +} + +template +void AnyUtilsTest::testConversionRange(T (*func)(const CORBA::Any&)) +{ + testFromBoolean(func); + + const T min = ::range_test::min(); + const T max = ::range_test::max(); + + CORBA::Any any; + any <<= (double) min; + T result; + CPPUNIT_ASSERT_NO_THROW(result = func(any)); + CPPUNIT_ASSERT_EQUAL(min, result); + + result = max; + CPPUNIT_ASSERT(ossie::any::toNumber(any, result)); + CPPUNIT_ASSERT_EQUAL(min, result); + + any <<= (double) max; + CPPUNIT_ASSERT_NO_THROW(result = func(any)); + CPPUNIT_ASSERT_EQUAL(max, result); + + result = min; + CPPUNIT_ASSERT(ossie::any::toNumber(any, result)); + CPPUNIT_ASSERT_EQUAL(max, result); + + any <<= ::range_test::exceed_min(); + CPPUNIT_ASSERT_THROW(result = func(any), std::range_error); + CPPUNIT_ASSERT(!ossie::any::toNumber(any, result)); + + any <<= ::range_test::exceed_max(); + CPPUNIT_ASSERT_THROW(result = func(any), std::range_error); + CPPUNIT_ASSERT(!ossie::any::toNumber(any, result)); +} + +template +void AnyUtilsTest::testConversionImpl(T (*func)(const CORBA::Any&)) +{ + testFromBoolean(func); + testConversionRange(func); +} diff --git a/redhawk/src/testing/cpp/AnyUtilsTest.h b/redhawk/src/testing/cpp/AnyUtilsTest.h new file mode 100644 index 000000000..b881a20c6 --- /dev/null +++ b/redhawk/src/testing/cpp/AnyUtilsTest.h @@ -0,0 +1,73 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK core. + * + * REDHAWK core is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +#ifndef ANYUTILSTEST_H +#define ANYUTILSTEST_H + +#include + +#include + +class AnyUtilsTest : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE(AnyUtilsTest); + CPPUNIT_TEST(testIsNull); + CPPUNIT_TEST(testToBoolean); + CPPUNIT_TEST(testOctetConversion); + CPPUNIT_TEST(testShortConversion); + CPPUNIT_TEST(testUShortConversion); + CPPUNIT_TEST(testLongConversion); + CPPUNIT_TEST(testULongConversion); + CPPUNIT_TEST(testLongLongConversion); + CPPUNIT_TEST(testULongLongConversion); + CPPUNIT_TEST(testFloatConversion); + CPPUNIT_TEST(testStringToNumber); + CPPUNIT_TEST_SUITE_END(); + +public: + void setUp(); + void tearDown(); + + void testIsNull(); + + void testToBoolean(); + void testOctetConversion(); + void testShortConversion(); + void testUShortConversion(); + void testLongConversion(); + void testULongConversion(); + void testLongLongConversion(); + void testULongLongConversion(); + void testFloatConversion(); + + void testStringToNumber(); + +private: + template + void testConversionImpl(T (*func)(const CORBA::Any&)); + + template + void testFromBoolean(T (*func)(const CORBA::Any&)); + + template + void testConversionRange(T (*func)(const CORBA::Any&)); +}; + +#endif // ANYUTILS_TEST_H diff --git a/redhawk/src/testing/cpp/Makefile.am b/redhawk/src/testing/cpp/Makefile.am index cfa6b2151..f4b842996 100644 --- a/redhawk/src/testing/cpp/Makefile.am +++ b/redhawk/src/testing/cpp/Makefile.am @@ -9,6 +9,7 @@ test_standalone_CXXFLAGS = $(CPPUNIT_CFLAGS) -I $(top_srcdir)/base/include test_standalone_LDFLAGS = $(CPPUNIT_LIBS) test_libossiecf_SOURCES = test_libossiecf.cpp +test_libossiecf_SOURCES += AnyUtilsTest.cpp AnyUtilsTest.h test_libossiecf_SOURCES += ValueTest.cpp ValueTest.h test_libossiecf_SOURCES += ValueSequenceTest.cpp ValueSequenceTest.h test_libossiecf_SOURCES += PropertyMapTest.cpp PropertyMapTest.h From ad5479302a78ad53d3f27aa36c6029c5a471ace4 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 29 Sep 2016 14:32:25 -0400 Subject: [PATCH 0469/1644] Better breakdown of different conversion tests --- redhawk/src/testing/cpp/AnyUtilsTest.cpp | 333 ++++++++++++----------- redhawk/src/testing/cpp/AnyUtilsTest.h | 50 ++-- 2 files changed, 196 insertions(+), 187 deletions(-) diff --git a/redhawk/src/testing/cpp/AnyUtilsTest.cpp b/redhawk/src/testing/cpp/AnyUtilsTest.cpp index 0d457900b..6546aa414 100644 --- a/redhawk/src/testing/cpp/AnyUtilsTest.cpp +++ b/redhawk/src/testing/cpp/AnyUtilsTest.cpp @@ -31,74 +31,214 @@ CPPUNIT_TEST_SUITE_REGISTRATION(AnyUtilsTest); namespace { template - struct range_test + class NumericTestImpl { + public: + typedef T (*conversion_func)(const CORBA::Any&); + typedef std::numeric_limits limits; - static T min() + NumericTestImpl(conversion_func func) : + func(func) { - return limits::min(); } - static T max() + void testFromBoolean() { - return limits::max(); + CORBA::Any any; + + any <<= true; + CPPUNIT_ASSERT_EQUAL((T) 1, func(any)); + + any <<= false; + CPPUNIT_ASSERT_EQUAL((T) 0, func(any)); } - static double exceed_min() + void testFromString() { - return limits::min() - 1.0; + const T mid = (limits::min() / 2) + (limits::max() / 2); + std::ostringstream oss; + oss << mid; + + CORBA::Any any; + any <<= oss.str(); + CPPUNIT_ASSERT_EQUAL(mid, func(any)); + + any <<= "1.27e2"; + CPPUNIT_ASSERT_EQUAL((T) 127, func(any)); } - static double exceed_max() + void testFromNumber() { - return limits::max() + 1.0; + CORBA::Any any; + + any <<= CORBA::Any::from_octet(1); + CPPUNIT_ASSERT_EQUAL((T) 1, func(any)); + + any <<= (CORBA::Short) 2; + CPPUNIT_ASSERT_EQUAL((T) 2, func(any)); + + any <<= (CORBA::UShort) 3; + CPPUNIT_ASSERT_EQUAL((T) 3, func(any)); + + any <<= (CORBA::Long) 4; + CPPUNIT_ASSERT_EQUAL((T) 4, func(any)); + + any <<= (CORBA::ULong) 5; + CPPUNIT_ASSERT_EQUAL((T) 5, func(any)); + + any <<= (CORBA::LongLong) 6; + CPPUNIT_ASSERT_EQUAL((T) 6, func(any)); + + any <<= (CORBA::ULongLong) 7; + CPPUNIT_ASSERT_EQUAL((T) 7, func(any)); + + any <<= (CORBA::Float) 8; + CPPUNIT_ASSERT_EQUAL((T) 8, func(any)); + + any <<= (CORBA::Double) 9; + CPPUNIT_ASSERT_EQUAL((T) 9, func(any)); + } + + void testRange() + { + T min = limits::min(); + T max = limits::max(); + testRangeImpl(min, max, min - 1.0, max + 1.0); } - static double epsilon() + private: + void testRangeImpl(T min, T max, double under, double over) { - int bits = limits::digits - std::numeric_limits::digits; - if (bits < 0) { - bits = 0; - } - return 1 << bits; + CORBA::Any any; + any <<= (double) min; + T result; + CPPUNIT_ASSERT_NO_THROW(result = func(any)); + CPPUNIT_ASSERT_EQUAL(min, result); + + result = max; + CPPUNIT_ASSERT(ossie::any::toNumber(any, result)); + CPPUNIT_ASSERT_EQUAL(min, result); + + any <<= (double) max; + CPPUNIT_ASSERT_NO_THROW(result = func(any)); + CPPUNIT_ASSERT_EQUAL(max, result); + + result = min; + CPPUNIT_ASSERT(ossie::any::toNumber(any, result)); + CPPUNIT_ASSERT_EQUAL(max, result); + + any <<= under; + CPPUNIT_ASSERT_THROW(func(any), std::range_error); + CPPUNIT_ASSERT(!ossie::any::toNumber(any, result)); + + any <<= over; + CPPUNIT_ASSERT_THROW(func(any), std::range_error); + CPPUNIT_ASSERT(!ossie::any::toNumber(any, result)); } + + conversion_func func; }; template <> - CORBA::LongLong range_test::min() + void NumericTestImpl::testRange() + { + // Double has a wider range but less precision (52 bits) than 64-bit + // integers, so it cannot precisely represent the maximum or minimum + // values. To ensure that the minimum and maximum are within the legal + // range of the converters (see boost::numeric::converter), adjust the + // test values towards zero by the effective epsilon (the minimum + // difference representible with a double at a given magnitude). In + // other words, the double values are quantized, so explicitly pick the + // nearest value that is less than the "real" value. + int bits = limits::digits - std::numeric_limits::digits; + double epsilon = (1 << bits); + CORBA::LongLong min = limits::min() + epsilon; + // In essence, mask out the least significant bits of the maximum + CORBA::LongLong max = limits::max() - (epsilon - 1); + testRangeImpl(min, max, min - epsilon, max + epsilon); + } + + template <> + void NumericTestImpl::testRange() { - return limits::min() + epsilon(); + // See above, except only the maximum actually uses the full precision + int bits = limits::digits - std::numeric_limits::digits; + double epsilon = (1 << bits); + CORBA::ULongLong max = limits::max() - (epsilon - 1); + testRangeImpl(0, max, -1.0, max + epsilon); } template <> - CORBA::LongLong range_test::max() + void NumericTestImpl::testFromString() { - return limits::max() - (epsilon() - 1); + CORBA::Any any; + any <<= "0"; + CPPUNIT_ASSERT_EQUAL((CORBA::Octet) 0, ossie::any::toOctet(any)); + + any <<= "255"; + CPPUNIT_ASSERT_EQUAL((CORBA::Octet) 255, ossie::any::toOctet(any)); + + any <<= "256"; + CPPUNIT_ASSERT_THROW(ossie::any::toOctet(any), std::range_error); } template <> - CORBA::ULongLong range_test::max() + void NumericTestImpl::testRange() { - return limits::max() - (epsilon() - 1); + CORBA::Float max = limits::max(); + testRangeImpl(-max, max, -2.0 * max, 2.0 * max); } template <> - float range_test::min() + void NumericTestImpl::testFromString() { - return -max(); + // Very large value + CORBA::Any any; + any <<= "1.125e+38"; + CPPUNIT_ASSERT_EQUAL(1.125e38f, ossie::any::toFloat(any)); + + // Very small value + any <<= "-1.0002441406250e-32"; + CPPUNIT_ASSERT_EQUAL(-1.0002441406250e-32f, ossie::any::toFloat(any)); + + // Beyond the maximum range of float should throw an exception + any <<= "7e40"; + CPPUNIT_ASSERT_THROW(ossie::any::toFloat(any), std::range_error); + + // Number too small to be represented as a float (but valid for double) + // should get rounded to zero + any <<= "5.03125e-46"; + CPPUNIT_ASSERT_EQUAL(0.0f, ossie::any::toFloat(any)); } template <> - double range_test::exceed_max() + void NumericTestImpl::testRange() { - return 2.0 * max(); + // Double has the largest range of the common numeric primitive types, + // so it's not possible to exceed its range with another primitive type + // (this test is here so that double tests can be created using the + // same macros as the other types) } template <> - double range_test::exceed_min() + void NumericTestImpl::testFromString() { - return -exceed_max(); + CORBA::Any any; + + // Simple integer conversion + any <<= "100000"; + CPPUNIT_ASSERT_EQUAL(100000.0, ossie::any::toDouble(any)); + + // Use a floating point value that is known to show a decimal point and + // exponent + double value = 1.125e7; + std::ostringstream oss; + oss << value; + any <<= oss.str(); + + // Conversion back to double should be simple + CPPUNIT_ASSERT_EQUAL(value, ossie::any::toDouble(any)); } } @@ -166,136 +306,11 @@ void AnyUtilsTest::testToBoolean() CPPUNIT_ASSERT(!ossie::any::toNumber(any, result)); } -void AnyUtilsTest::testOctetConversion() -{ - CORBA::Any any; - any <<= "0"; - CPPUNIT_ASSERT_EQUAL((CORBA::Octet) 0, ossie::any::toOctet(any)); - - any <<= "255"; - CPPUNIT_ASSERT_EQUAL((CORBA::Octet) 255, ossie::any::toOctet(any)); - - any <<= "256"; - CPPUNIT_ASSERT_THROW(ossie::any::toOctet(any), std::range_error); - - testConversionImpl(&ossie::any::toOctet); -} - -void AnyUtilsTest::testShortConversion() -{ - testConversionImpl(&ossie::any::toShort); -} - -void AnyUtilsTest::testUShortConversion() -{ - testConversionImpl(&ossie::any::toUShort); -} - -void AnyUtilsTest::testLongConversion() -{ - testConversionImpl(&ossie::any::toLong); -} - -void AnyUtilsTest::testULongConversion() -{ - testConversionImpl(&ossie::any::toULong); -} - -void AnyUtilsTest::testLongLongConversion() -{ - testConversionImpl(&ossie::any::toLongLong); -} - -void AnyUtilsTest::testULongLongConversion() -{ - testConversionImpl(&ossie::any::toULongLong); -} - -void AnyUtilsTest::testFloatConversion() -{ - testConversionImpl(&ossie::any::toFloat); -} - -void AnyUtilsTest::testStringToNumber() -{ - CORBA::Any any; - - // Simple integer conversion - any <<= "100000"; - CORBA::Long lval; - CPPUNIT_ASSERT_NO_THROW(lval = ossie::any::toLong(any)); - CPPUNIT_ASSERT_EQUAL((CORBA::Long) 100000, lval); - - // Use a floating point value that is known to show a decimal point and - // exponent - double value = 1.125e7; - std::ostringstream oss; - oss << value; - any <<= oss.str(); - - // Conversion back to double should be simple - double dval; - CPPUNIT_ASSERT_NO_THROW(dval = ossie::any::toDouble(any)); - CPPUNIT_ASSERT_EQUAL(value, dval); - - // Conversion to an integer requires it to parse the number as a double - // (because of the decimal point and exponent) before converting to the - // final integer type - lval = 0; - CPPUNIT_ASSERT_NO_THROW(lval = ossie::any::toLong(any)); - CPPUNIT_ASSERT_EQUAL((CORBA::Long)value, lval); -} - -template -void AnyUtilsTest::testFromBoolean(T (*func)(const CORBA::Any&)) -{ - CORBA::Any any; - - any <<= true; - CPPUNIT_ASSERT_EQUAL((T) 1, func(any)); - - any <<= false; - CPPUNIT_ASSERT_EQUAL((T) 0, func(any)); -} - -template -void AnyUtilsTest::testConversionRange(T (*func)(const CORBA::Any&)) -{ - testFromBoolean(func); - - const T min = ::range_test::min(); - const T max = ::range_test::max(); - - CORBA::Any any; - any <<= (double) min; - T result; - CPPUNIT_ASSERT_NO_THROW(result = func(any)); - CPPUNIT_ASSERT_EQUAL(min, result); - - result = max; - CPPUNIT_ASSERT(ossie::any::toNumber(any, result)); - CPPUNIT_ASSERT_EQUAL(min, result); - - any <<= (double) max; - CPPUNIT_ASSERT_NO_THROW(result = func(any)); - CPPUNIT_ASSERT_EQUAL(max, result); - - result = min; - CPPUNIT_ASSERT(ossie::any::toNumber(any, result)); - CPPUNIT_ASSERT_EQUAL(max, result); - - any <<= ::range_test::exceed_min(); - CPPUNIT_ASSERT_THROW(result = func(any), std::range_error); - CPPUNIT_ASSERT(!ossie::any::toNumber(any, result)); - - any <<= ::range_test::exceed_max(); - CPPUNIT_ASSERT_THROW(result = func(any), std::range_error); - CPPUNIT_ASSERT(!ossie::any::toNumber(any, result)); -} +#define DEFINE_NUMERIC_TEST(T,NAME) \ + void AnyUtilsTest::testTo##T##NAME() \ + { \ + NumericTestImpl impl(ossie::any::to##T); \ + impl.test##NAME(); \ + } -template -void AnyUtilsTest::testConversionImpl(T (*func)(const CORBA::Any&)) -{ - testFromBoolean(func); - testConversionRange(func); -} +FOREACH_TYPE_TEST(DEFINE_NUMERIC_TEST); diff --git a/redhawk/src/testing/cpp/AnyUtilsTest.h b/redhawk/src/testing/cpp/AnyUtilsTest.h index b881a20c6..fc1156da8 100644 --- a/redhawk/src/testing/cpp/AnyUtilsTest.h +++ b/redhawk/src/testing/cpp/AnyUtilsTest.h @@ -25,20 +25,31 @@ #include +#define FOREACH_TEST(X, T) \ + X(T, FromBoolean) \ + X(T, FromNumber) \ + X(T, FromString) \ + X(T, Range) + +#define FOREACH_TYPE_TEST(X) \ + FOREACH_TEST(X, Octet) \ + FOREACH_TEST(X, Short) \ + FOREACH_TEST(X, UShort) \ + FOREACH_TEST(X, Long) \ + FOREACH_TEST(X, ULong) \ + FOREACH_TEST(X, LongLong) \ + FOREACH_TEST(X, ULongLong) \ + FOREACH_TEST(X, Float) \ + FOREACH_TEST(X, Double) + class AnyUtilsTest : public CppUnit::TestFixture { +#define REGISTER_TESTS(T,NAME) CPPUNIT_TEST(testTo##T##NAME); + CPPUNIT_TEST_SUITE(AnyUtilsTest); CPPUNIT_TEST(testIsNull); CPPUNIT_TEST(testToBoolean); - CPPUNIT_TEST(testOctetConversion); - CPPUNIT_TEST(testShortConversion); - CPPUNIT_TEST(testUShortConversion); - CPPUNIT_TEST(testLongConversion); - CPPUNIT_TEST(testULongConversion); - CPPUNIT_TEST(testLongLongConversion); - CPPUNIT_TEST(testULongLongConversion); - CPPUNIT_TEST(testFloatConversion); - CPPUNIT_TEST(testStringToNumber); + FOREACH_TYPE_TEST(REGISTER_TESTS); CPPUNIT_TEST_SUITE_END(); public: @@ -48,26 +59,9 @@ class AnyUtilsTest : public CppUnit::TestFixture void testIsNull(); void testToBoolean(); - void testOctetConversion(); - void testShortConversion(); - void testUShortConversion(); - void testLongConversion(); - void testULongConversion(); - void testLongLongConversion(); - void testULongLongConversion(); - void testFloatConversion(); - - void testStringToNumber(); - -private: - template - void testConversionImpl(T (*func)(const CORBA::Any&)); - - template - void testFromBoolean(T (*func)(const CORBA::Any&)); - template - void testConversionRange(T (*func)(const CORBA::Any&)); +#define DECLARE_TESTS(T,NAME) void testTo##T##NAME(); + FOREACH_TYPE_TEST(DECLARE_TESTS); }; #endif // ANYUTILS_TEST_H From 5fce39dbbc1bc1913ea9ac56e29343e6325ea928 Mon Sep 17 00:00:00 2001 From: Ryan Bauman Date: Wed, 12 Oct 2016 15:29:04 -0400 Subject: [PATCH 0470/1644] RELENG-459 - reconcile redhawk shared_address differences after applying patches from legacy repo --- .../src/base/framework/ExecutorService.cpp | 113 ++++++++++++++++++ redhawk/src/base/framework/Makefile.am | 3 +- redhawk/src/base/framework/Versions.cpp | 14 +-- .../python/ossie/utils/sandbox/local.py | 2 + .../src/base/include/ossie/ExecutorService.h | 12 +- redhawk/src/base/include/ossie/Makefile.am | 1 + redhawk/src/base/include/ossie/Versions.h | 2 +- redhawk/src/control/sdr/devmgr/spdSupport.cpp | 8 +- .../sdr/dommgr/ApplicationDeployment.cpp | 2 +- .../sdr/dommgr/ApplicationFactory_impl.cpp | 31 +++-- .../sdr/dommgr/ApplicationFactory_impl.h | 2 +- .../sdr/dommgr/ApplicationValidator.cpp | 2 +- .../sdr/dommgr/DomainManager_EventSupport.cpp | 2 +- .../src/control/sdr/dommgr/ProfileCache.cpp | 55 ++++++++- redhawk/src/control/sdr/dommgr/ProfileCache.h | 2 + .../control/sdr/dommgr/applicationSupport.cpp | 89 -------------- .../control/sdr/dommgr/connectionSupport.cpp | 2 +- redhawk/src/releng/redhawk.spec | 3 + 18 files changed, 219 insertions(+), 126 deletions(-) create mode 100644 redhawk/src/base/framework/ExecutorService.cpp delete mode 100644 redhawk/src/control/sdr/dommgr/applicationSupport.cpp diff --git a/redhawk/src/base/framework/ExecutorService.cpp b/redhawk/src/base/framework/ExecutorService.cpp new file mode 100644 index 000000000..bf8915521 --- /dev/null +++ b/redhawk/src/base/framework/ExecutorService.cpp @@ -0,0 +1,113 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK core. + * + * REDHAWK core is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +#include + +using namespace redhawk; + +ExecutorService::ExecutorService() : + _thread(0), + _running(false) +{ +} + +void ExecutorService::start () +{ + boost::mutex::scoped_lock lock(_mutex); + if (_running) { + return; + } + + _running = true; + _thread = new boost::thread(&ExecutorService::_run, this); +} + +void ExecutorService::stop () +{ + boost::thread* old_thread = 0; + { + boost::mutex::scoped_lock lock(_mutex); + _running = false; + old_thread = _thread; + _thread = 0; + _cond.notify_all(); + } + if (old_thread) { + old_thread->join(); + delete old_thread; + } +} + +void ExecutorService::clear () +{ + boost::mutex::scoped_lock lock(_mutex); + _queue.clear(); + _cond.notify_all(); +} + +size_t ExecutorService::pending () +{ + boost::mutex::scoped_lock lock(_mutex); + return _queue.size(); +} + +void ExecutorService::_run () +{ + boost::mutex::scoped_lock lock(_mutex); + while (_running) { + while (!_queue.empty()) { + // Start at the front of the queue every time--a task may + // have been added while the lock was released to service + // the last task + task_queue::iterator task = _queue.begin(); + if (task->first > boost::get_system_time()) { + // Head of queue is scheduled in the future + break; + } + + // Copy the task's function and remove it from the queue + func_type func = task->second; + _queue.erase(task); + + // Run task with the lock released + lock.unlock(); + func(); + lock.lock(); + } + + if (_queue.empty()) { + _cond.wait(lock); + } else { + boost::system_time when = _queue.front().first; + _cond.timed_wait(lock, when); + } + } +} + +void ExecutorService::_insertSorted (func_type func, boost::system_time when) +{ + boost::mutex::scoped_lock lock(_mutex); + task_queue::iterator pos = _queue.begin(); + while ((pos != _queue.end()) && (when > pos->first)) { + ++pos; + } + _queue.insert(pos, std::make_pair(when, func)); + _cond.notify_all(); +} diff --git a/redhawk/src/base/framework/Makefile.am b/redhawk/src/base/framework/Makefile.am index 9249ee6b2..3d22d8cec 100644 --- a/redhawk/src/base/framework/Makefile.am +++ b/redhawk/src/base/framework/Makefile.am @@ -56,7 +56,8 @@ libossiecf_la_SOURCES = AggregateDevice_impl.cpp \ Value.cpp \ PropertyType.cpp \ PropertyMap.cpp \ - Versions.cpp + Versions.cpp \ + ExecutorService.cpp libossiecf_la_CXXFLAGS = -Wall $(BOOST_CPPFLAGS) $(OMNICOS_CFLAGS) $(OMNIORB_CFLAGS) $(LOG4CXX_FLAGS) # Include the omniORB internal directory, otherwise CorbaUtils will not build diff --git a/redhawk/src/base/framework/Versions.cpp b/redhawk/src/base/framework/Versions.cpp index 0153125e1..2794b3d92 100644 --- a/redhawk/src/base/framework/Versions.cpp +++ b/redhawk/src/base/framework/Versions.cpp @@ -21,22 +21,20 @@ #include namespace redhawk { - int compareVersions(std::string &a, std::string &b) { + int compareVersions(const std::string& a, const std::string& b) { - std::string token; - - if (!a.compare("sca_compliant") and !b.compare("sca_compliant")) + if (a == b) { return 0; - - if (!a.compare("sca_compliant")) + } else if (a == "sca_compliant") { return 1; - - if (!b.compare("sca_compliant")) + } else if (b == "sca_compliant") { return -1; + } std::vector first_tokens; std::vector second_tokens; try { + std::string token; std::istringstream first(a); while (std::getline(first, token, '.')) { if (!token.empty()) diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py index 682751c45..762d837fb 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py @@ -271,8 +271,10 @@ def terminate_callback(pid, status): # Store the process on the component proxy. if impl.get_code().get_type() == 'SharedLibrary' and self._shared: comp._process = None + comp._pid = None else: comp._process = process + comp._pid = process.pid() # Return the now-resolved CORBA reference. ref = self.getReference(comp) diff --git a/redhawk/src/base/include/ossie/ExecutorService.h b/redhawk/src/base/include/ossie/ExecutorService.h index d6a0af92b..e318aea28 100644 --- a/redhawk/src/base/include/ossie/ExecutorService.h +++ b/redhawk/src/base/include/ossie/ExecutorService.h @@ -80,7 +80,7 @@ namespace redhawk { template void execute (F func) { - insert_sorted(func); + _insertSorted(func); } /** @@ -101,7 +101,7 @@ namespace redhawk { template void execute (F func, A1 arg1) { - insert_sorted(boost::bind(func, arg1)); + _insertSorted(boost::bind(func, arg1)); } /** @@ -123,7 +123,7 @@ namespace redhawk { template void execute (F func, A1 arg1, A2 arg2) { - insert_sorted(boost::bind(func, arg1, arg2)); + _insertSorted(boost::bind(func, arg1, arg2)); } /** @@ -142,7 +142,7 @@ namespace redhawk { template void schedule (boost::system_time when, F func) { - insert_sorted(func, when); + _insertSorted(func, when); } /** @@ -166,7 +166,7 @@ namespace redhawk { template void schedule (boost::system_time when, F func, A1 arg1) { - insert_sorted(boost::bind(func, arg1), when); + _insertSorted(boost::bind(func, arg1), when); } /** @@ -191,7 +191,7 @@ namespace redhawk { template void schedule (boost::system_time when, F func, A1 arg1, A2 arg2) { - insert_sorted(boost::bind(func, arg1, arg2), when); + _insertSorted(boost::bind(func, arg1, arg2), when); } /** diff --git a/redhawk/src/base/include/ossie/Makefile.am b/redhawk/src/base/include/ossie/Makefile.am index ec76ce3e6..73739e95f 100644 --- a/redhawk/src/base/include/ossie/Makefile.am +++ b/redhawk/src/base/include/ossie/Makefile.am @@ -61,6 +61,7 @@ pkginclude_HEADERS = AggregateDevice_impl.h \ OptionalProperty.h \ PropertyMonitor.h \ Autocomplete.h \ + Versions.h \ shared_buffer.h \ ExecutorService.h diff --git a/redhawk/src/base/include/ossie/Versions.h b/redhawk/src/base/include/ossie/Versions.h index dcd47425b..85d288c9e 100644 --- a/redhawk/src/base/include/ossie/Versions.h +++ b/redhawk/src/base/include/ossie/Versions.h @@ -29,7 +29,7 @@ namespace redhawk { - int compareVersions(std::string &a, std::string &b); + int compareVersions(const std::string& a, const std::string& b); } diff --git a/redhawk/src/control/sdr/devmgr/spdSupport.cpp b/redhawk/src/control/sdr/devmgr/spdSupport.cpp index bdc8151cb..9bb65d5b0 100644 --- a/redhawk/src/control/sdr/devmgr/spdSupport.cpp +++ b/redhawk/src/control/sdr/devmgr/spdSupport.cpp @@ -436,10 +436,10 @@ void ResourceInfo::load(CF::FileSystem_ptr fileSys) _scd.close(); } catch (ossie::parser_error& e) { std::string parser_error_line = ossie::retrieveParserErrorLineNumber(e.what()); - LOG_ERROR(ResourceInfo, "Building component info problem; error parsing SCD: " << newComponent.spd.getSCDFile() << ". " << parser_error_line << " The XML parser returned the following error: " << e.what()); + LOG_ERROR(ResourceInfo, "Building component info problem; error parsing SCD: " << spd.getSCDFile() << ". " << parser_error_line << " The XML parser returned the following error: " << e.what()); throw 0; } catch( ... ) { - LOG_ERROR(ResourceInfo, "Building component info problem; unknown error parsing SCD: " << newComponent.spd.getSCDFile() ); + LOG_ERROR(ResourceInfo, "Building component info problem; unknown error parsing SCD: " << spd.getSCDFile() ); throw 0; } } @@ -454,10 +454,10 @@ void ResourceInfo::load(CF::FileSystem_ptr fileSys) _prf.close(); } catch (ossie::parser_error& e) { std::string parser_error_line = ossie::retrieveParserErrorLineNumber(e.what()); - LOG_ERROR(ResourceInfo, "Building component info problem; error parsing PRF: " << newComponent.spd.getPRFFile() << ". " << parser_error_line << " The XML parser returned the following error: " << e.what()); + LOG_ERROR(ResourceInfo, "Building component info problem; error parsing PRF: " << spd.getPRFFile() << ". " << parser_error_line << " The XML parser returned the following error: " << e.what()); throw 0; } catch( ... ) { - LOG_ERROR(ResourceInfo, "Building component info problem; unknown error parsing PRF: " << newComponent.spd.getPRFFile() ); + LOG_ERROR(ResourceInfo, "Building component info problem; unknown error parsing PRF: " << spd.getPRFFile() ); throw 0; } } diff --git a/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp b/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp index 4e6a784d8..addc50b81 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp @@ -31,7 +31,7 @@ using namespace redhawk; using namespace ossie; -PREPARE_LOGGING(ApplicationDeployment); +PREPARE_CF_LOGGING(ApplicationDeployment); ContainerDeployment::ContainerDeployment(const ossie::SoftPkg* softpkg, ossie::ComponentInstantiation* instantiation, diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 3e1acdf19..eae382405 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include #include "Application_impl.h" @@ -126,9 +127,19 @@ namespace { return !first.empty(); } } + + static std::string getVersionMismatchMessage(const SoftPkg* softpkg) + { + const std::string& softpkg_version = softpkg->getSoftPkgType(); + if (redhawk::compareVersions(VERSION, softpkg_version) > 0) { + return " (attempting to run a component from version " + softpkg_version + " on REDHAWK version " VERSION ")"; + } else { + return std::string(); + } + } } -PREPARE_LOGGING(ApplicationFactory_impl); +PREPARE_CF_LOGGING(ApplicationFactory_impl); ApplicationFactory_impl::ApplicationFactory_impl (const std::string& softwareProfile, const std::string& domainName, @@ -1499,10 +1510,9 @@ void createHelper::loadAndExecuteComponents(const DeploymentList& deployments, throw std::logic_error(message.str()); } - LOG_TRACE(ApplicationFactory_impl, "Component - " << softpkg->getName() - << " Assigned device - " << device->identifier); - LOG_INFO(ApplicationFactory_impl, "APPLICATION: " << _waveformContextName << " COMPONENT ID: " - << component->getIdentifier() << " ASSIGNED TO DEVICE ID/LABEL: " << device->identifier << "/" << device->label); + LOG_INFO(ApplicationFactory_impl, "Application '" << _waveformContextName << "' component '" + << deployment->getIdentifier() << "' assigned to device '" << device->label + << "' (" << device->identifier << ")"); // Let the application know to expect the given component _application->addComponent(deployment->getIdentifier(), softpkg->getSPDFile()); @@ -1839,7 +1849,9 @@ void createHelper::waitForComponentRegistration(redhawk::ApplicationDeployment& // create() exception handler will turn it into a CF exception throw; } - throw redhawk::ExecuteError(deployment, "component terminated before registering with application"); + std::string message = "component terminated before registering with application"; + message += ::getVersionMismatchMessage(deployment->getSoftPkg()); + throw redhawk::ExecuteError(deployment, message); } // For reference, determine much time has really elapsed. @@ -1852,12 +1864,15 @@ void createHelper::waitForComponentRegistration(redhawk::ApplicationDeployment& // Fetch the objects, finding any components that did not register BOOST_FOREACH(redhawk::ComponentDeployment* deployment, deployments) { - if (deployment->getSoftPkg()->isScaCompliant()) { + const SoftPkg* softpkg = deployment->getSoftPkg(); + if (softpkg->isScaCompliant()) { // Find the component on the Application const std::string componentId = deployment->getIdentifier(); CORBA::Object_var objref = _application->getComponentObject(componentId); if (CORBA::is_nil(objref)) { - throw redhawk::ExecuteError(deployment, "component did not register with application"); + std::string message = "component did not register with application"; + message += ::getVersionMismatchMessage(softpkg); + throw redhawk::ExecuteError(deployment, message); } // Occasionally, omniORB may have a cached connection where the diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h index 36c036e40..f19f86378 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h @@ -87,7 +87,7 @@ class ApplicationFactory_impl: public virtual POA_CF::ApplicationFactory const std::string & getID () { return _identifier; } const std::string & getName () { return _name; } - + // allow createHelper to have access to ApplicationFactory_impl friend class createHelper; friend class ScopedAllocations; diff --git a/redhawk/src/control/sdr/dommgr/ApplicationValidator.cpp b/redhawk/src/control/sdr/dommgr/ApplicationValidator.cpp index 17b0b7e34..2896ab060 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationValidator.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationValidator.cpp @@ -40,7 +40,7 @@ class bad_implementation : public redhawk::validation_error } }; -PREPARE_LOGGING(ApplicationValidator); +PREPARE_CF_LOGGING(ApplicationValidator); ApplicationValidator::ApplicationValidator(CF::FileSystem_ptr fileSystem) : fileSystem(CF::FileSystem::_duplicate(fileSystem)), diff --git a/redhawk/src/control/sdr/dommgr/DomainManager_EventSupport.cpp b/redhawk/src/control/sdr/dommgr/DomainManager_EventSupport.cpp index 88754b609..71d9fe40a 100644 --- a/redhawk/src/control/sdr/dommgr/DomainManager_EventSupport.cpp +++ b/redhawk/src/control/sdr/dommgr/DomainManager_EventSupport.cpp @@ -186,7 +186,7 @@ void DomainManager_impl::idmTerminationMessages(const redhawk::events::Component if (application) { application->componentTerminated(termMsg.component_id, termMsg.device_id); } else { - LOG_WARN(DomainManager_impl, "Abormal Component Termination, Reporting Device: " << termMsg.device_id + LOG_WARN(DomainManager_impl, "Abnormal Component Termination, Reporting Device: " << termMsg.device_id << " Application/Component " << termMsg.application_id << "/" << termMsg.component_id); } } diff --git a/redhawk/src/control/sdr/dommgr/ProfileCache.cpp b/redhawk/src/control/sdr/dommgr/ProfileCache.cpp index 7c68c6f55..5ce8cd618 100644 --- a/redhawk/src/control/sdr/dommgr/ProfileCache.cpp +++ b/redhawk/src/control/sdr/dommgr/ProfileCache.cpp @@ -22,13 +22,25 @@ #include #include +#include #include "ProfileCache.h" using namespace redhawk; using namespace ossie; -PREPARE_LOGGING(ProfileCache); +PREPARE_CF_LOGGING(ProfileCache); + +namespace { + static std::string getVersionMismatchMessage(const std::string& version) + { + if (redhawk::compareVersions(VERSION, version) > 0) { + return " (attempting to load a profile from version " + version + " on REDHAWK version " VERSION ")"; + } else { + return std::string(); + } + } +} ProfileCache::ProfileCache(CF::FileSystem_ptr fileSystem) : fileSystem(CF::FileSystem::_duplicate(fileSystem)) @@ -51,6 +63,7 @@ const SoftPkg* ProfileCache::loadProfile(const std::string& spdFilename) softpkg->loadProperties(prf_stream); } catch (const std::exception& exc) { std::string message = spdFilename + " has invalid PRF file " + prf_file + ": " + exc.what(); + message += ::getVersionMismatchMessage(softpkg->getSoftPkgType()); throw invalid_profile(spdFilename, message); } } @@ -65,6 +78,7 @@ const SoftPkg* ProfileCache::loadProfile(const std::string& spdFilename) softpkg->loadDescriptor(scd_stream); } catch (const std::exception& exc) { std::string message = spdFilename + " has invalid SCD file " + scd_file + ": " + exc.what(); + message += ::getVersionMismatchMessage(softpkg->getSoftPkgType()); throw invalid_profile(spdFilename, message); } } @@ -83,13 +97,46 @@ const SoftPkg* ProfileCache::loadSoftPkg(const std::string& filename) } LOG_TRACE(ProfileCache, "Loading SPD file " << filename); + SoftPkg* softpkg = 0; try { File_stream spd_stream(fileSystem, filename.c_str()); - SoftPkg* softpkg = new SoftPkg(spd_stream, filename); - profiles.push_back(softpkg); - return softpkg; + softpkg = new SoftPkg(spd_stream, filename); } catch (const std::exception& exc) { std::string message = filename + " is invalid: " + exc.what(); + std::string softpkg_version = _extractVersion(filename); + if (!softpkg_version.empty()) { + message += ::getVersionMismatchMessage(softpkg_version); + } throw invalid_profile(filename, message); } + + profiles.push_back(softpkg); + return softpkg; +} + +std::string ProfileCache::_extractVersion(const std::string& filename) +{ + // When the SPD itself cannot be parsed, try to recover the type attribute + // from the element manually. If the SPD is from a newer version + // of REDHAWK that has extended the XSD, this allows for a more helpful + // error message. + try { + File_stream stream(fileSystem, filename.c_str()); + std::string line; + while (std::getline(stream, line)) { + std::string::size_type type_idx = line.find("type"); + if (type_idx != std::string::npos) { + std::string::size_type first_quote = line.find('"', type_idx); + if (first_quote != std::string::npos) { + size_t second_quote = line.find('"', first_quote + 1); + if (second_quote != std::string::npos) { + return line.substr(first_quote + 1, second_quote-(first_quote+1)); + } + } + } + } + } catch (...) { + // Ignore all errors + } + return std::string(); } diff --git a/redhawk/src/control/sdr/dommgr/ProfileCache.h b/redhawk/src/control/sdr/dommgr/ProfileCache.h index cd60fe9a4..2be395201 100644 --- a/redhawk/src/control/sdr/dommgr/ProfileCache.h +++ b/redhawk/src/control/sdr/dommgr/ProfileCache.h @@ -112,6 +112,8 @@ namespace redhawk { protected: ossie::SoftPkg* findSoftPkg(const std::string& filename); + std::string _extractVersion(const std::string& filename); + CF::FileSystem_var fileSystem; boost::ptr_vector profiles; }; diff --git a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp b/redhawk/src/control/sdr/dommgr/applicationSupport.cpp deleted file mode 100644 index d0b92ba26..000000000 --- a/redhawk/src/control/sdr/dommgr/applicationSupport.cpp +++ /dev/null @@ -1,89 +0,0 @@ -/* - * This file is protected by Copyright. Please refer to the COPYRIGHT file - * distributed with this source distribution. - * - * This file is part of REDHAWK core. - * - * REDHAWK core is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see http://www.gnu.org/licenses/. - */ - - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "applicationSupport.h" -#include "PersistenceStore.h" -#include "ossie/PropertyMap.h" - - -using namespace ossie; - -static void addProperty(const CF::DataType& dt, CF::Properties& prop) -{ - for (unsigned int ii = 0; ii < prop.length(); ++ii) { - if (strcmp(dt.id, prop[ii].id) == 0) { - // Overwrite existing value - prop[ii].value = dt.value; - return; - } - } - - // New id, add property at end - unsigned int index = prop.length(); - prop.length(index + 1); - prop[index] = dt; -} - - -//////////////////////////////////////////////////// -/* - * ComponentInfo member function definitions - */ -PREPARE_CF_LOGGING(ComponentInfo); - -ComponentInfo* ComponentInfo::buildComponentInfoFromSPDFile(const SoftPkg* softpkg, - const ComponentInstantiation* instantiation) -{ - LOG_TRACE(ComponentInfo, "Building component info from softpkg " << softpkg->getName()); - - ossie::ComponentInfo* newComponent = new ossie::ComponentInfo(softpkg, instantiation); - LOG_TRACE(ComponentInfo, "Done building component info from soft package " << softpkg->getName()); - return newComponent; -} - -ComponentInfo::ComponentInfo(const SoftPkg* softpkg, const ComponentInstantiation* instantiation) : - spd(softpkg), - instantiation(instantiation) -{ -} - -ComponentInfo::~ComponentInfo () -{ -} - -const ComponentInstantiation* ComponentInfo::getInstantiation() const -{ - return instantiation; -} diff --git a/redhawk/src/control/sdr/dommgr/connectionSupport.cpp b/redhawk/src/control/sdr/dommgr/connectionSupport.cpp index 5135d29ac..efa0cea47 100644 --- a/redhawk/src/control/sdr/dommgr/connectionSupport.cpp +++ b/redhawk/src/control/sdr/dommgr/connectionSupport.cpp @@ -128,7 +128,7 @@ bool ConnectionManager::exceptionsEnabled() return _enableExceptions; } -PREPARE_LOGGING(AppConnectionManager); +PREPARE_CF_LOGGING(AppConnectionManager); AppConnectionManager::AppConnectionManager(DomainLookup* domainLookup, ComponentLookup* componentLookup, diff --git a/redhawk/src/releng/redhawk.spec b/redhawk/src/releng/redhawk.spec index 1b7824d6d..efdcde046 100644 --- a/redhawk/src/releng/redhawk.spec +++ b/redhawk/src/releng/redhawk.spec @@ -205,8 +205,11 @@ fi %attr(2775,redhawk,redhawk) %dir %{_sdrroot}/dom/deps %attr(2775,redhawk,redhawk) %dir %{_sdrroot}/dom/domain %attr(2775,redhawk,redhawk) %dir %{_sdrroot}/dom/mgr +%attr(2775,redhawk,redhawk) %dir %{_sdrroot}/dom/mgr/rh %attr(775,redhawk,redhawk) %{_sdrroot}/dom/mgr/DomainManager +%attr(775,redhawk,redhawk) %{_sdrroot}/dom/mgr/rh/ComponentHost %{_sdrroot}/dom/mgr/*.xml +%{_sdrroot}/dom/mgr/rh/ComponentHost/* %attr(2775,redhawk,redhawk) %dir %{_sdrroot}/dom/waveforms %attr(644,root,root) %{_sysconfdir}/profile.d/redhawk-sdrroot.csh %attr(644,root,root) %{_sysconfdir}/profile.d/redhawk-sdrroot.sh From f9a7810ce41760d41bc4f01b5fd58b16b89fe7b4 Mon Sep 17 00:00:00 2001 From: Ryan Bauman Date: Wed, 12 Oct 2016 16:08:12 -0400 Subject: [PATCH 0471/1644] RELENG-459 - update REDHAWK version on develop branch --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index e2c7c75f8..08942a39a 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,5 +1,5 @@ variables: - REDHAWK_VERSION: '2.0.4' + REDHAWK_VERSION: '2.1.0' FRONTEND_VERSION: '2.3.4' stages: From 5b8cd2f8c426caf9cdd6b679577d0ff5b984b257 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 14 Oct 2016 14:43:54 -0400 Subject: [PATCH 0472/1644] Fix Java compiler warning for variable arguments (which began showing up when the minimum source level was raised to 1.8) --- .../ossie/src/org/ossie/properties/StructSequenceProperty.java | 1 + 1 file changed, 1 insertion(+) diff --git a/redhawk/src/base/framework/java/ossie/src/org/ossie/properties/StructSequenceProperty.java b/redhawk/src/base/framework/java/ossie/src/org/ossie/properties/StructSequenceProperty.java index a474f1883..8ac8b3ddc 100644 --- a/redhawk/src/base/framework/java/ossie/src/org/ossie/properties/StructSequenceProperty.java +++ b/redhawk/src/base/framework/java/ossie/src/org/ossie/properties/StructSequenceProperty.java @@ -43,6 +43,7 @@ public StructSequenceProperty(String id, String name, Class structClass, List this(id, name, structClass, value, Mode.get(mode), Kind.get(kinds)); } + @SafeVarargs public static List asList(E... array) { return new ArrayList(Arrays.asList(array)); } From 10ef4f81e21f373b0c09eb0a0e1b20ff3afbdbde Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 17 Oct 2016 15:34:32 -0400 Subject: [PATCH 0473/1644] Relax application validation at installation time (sometimes done implicitly in createApplication) so that it only rejects the installation if there are no valid combinations of implementations, as opposed to rejecting it when any implementation is invalid (missing localfile, dependency, etc.) --- .../sdr/dommgr/ApplicationValidator.cpp | 65 +++++++++++++++---- .../control/sdr/dommgr/ApplicationValidator.h | 2 + 2 files changed, 53 insertions(+), 14 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationValidator.cpp b/redhawk/src/control/sdr/dommgr/ApplicationValidator.cpp index 2896ab060..3371bbd4f 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationValidator.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationValidator.cpp @@ -40,6 +40,15 @@ class bad_implementation : public redhawk::validation_error } }; +class no_valid_implemenation : public redhawk::validation_error +{ +public: + no_valid_implemenation(const SoftPkg* softpkg) : + redhawk::validation_error("Soft package " + softpkg->getSPDFile() + " has no valid implementations") + { + } +}; + PREPARE_CF_LOGGING(ApplicationValidator); ApplicationValidator::ApplicationValidator(CF::FileSystem_ptr fileSystem) : @@ -112,13 +121,13 @@ void ApplicationValidator::validateSoftPkgRef(const SPD::SoftPkgRef& softpkgref) { const std::string& spd_file = softpkgref.localfile; if (spd_file.empty()) { - throw std::runtime_error("empty softpkgref"); + throw validation_error("empty softpkgref"); } // Basic checking for valid, existing filename LOG_TRACE(ApplicationValidator, "Validating SPD " << spd_file); if (!fileExists(spd_file)) { - throw std::runtime_error("softpkgref " + spd_file + " does not exist"); + throw validation_error("softpkgref " + spd_file + " does not exist"); } if (!endsWith(spd_file, ".spd.xml")) { LOG_WARN(ApplicationValidator, "SPD file " << spd_file << " should end with .spd.xml"); @@ -133,14 +142,23 @@ void ApplicationValidator::validateSoftPkgRef(const SPD::SoftPkgRef& softpkgref) const std::string& impl_id = *(softpkgref.implref); const SPD::Implementation* implementation = softpkg->getImplementation(impl_id); if (!implementation) { - throw std::runtime_error("softpkgref " + spd_file + " has no implementation " + impl_id); + throw validation_error("softpkgref " + spd_file + " has no implementation " + impl_id); } validateImplementation(softpkg, *implementation, false); } else { // Validate all implementations + int valid_implementations = 0; BOOST_FOREACH(const SPD::Implementation& implementation, softpkg->getImplementations()) { - validateImplementation(softpkg, implementation, false); + try { + validateImplementation(softpkg, implementation, false); + valid_implementations++; + } catch (const validation_error& err) { + LOG_WARN(ApplicationValidator, err.what()); + } + } + if (valid_implementations == 0) { + throw no_valid_implemenation(softpkg); } } } @@ -152,10 +170,10 @@ void ApplicationValidator::validateImplementation(const SoftPkg* softpkg, LOG_TRACE(ApplicationValidator, "Validating SPD implementation " << implementation.getID()); // Always ensure that the localfile exists - fs::path code = fs::path(softpkg->getSPDPath()) / implementation.getCodeFile(); - LOG_TRACE(ApplicationValidator, "Validating code localfile " << code.string()); - if (!fileExists(code.string())) { - throw bad_implementation(softpkg, implementation, "missing localfile " + code.string()); + std::string localfile = _relativePath(softpkg, implementation.getCodeFile()); + LOG_TRACE(ApplicationValidator, "Validating code localfile " << localfile); + if (!fileExists(localfile)) { + throw bad_implementation(softpkg, implementation, "missing localfile " + localfile); } // If the implementation needs to be executable (i.e., would be used for a @@ -164,10 +182,10 @@ void ApplicationValidator::validateImplementation(const SoftPkg* softpkg, if (!implementation.getEntryPoint()) { throw bad_implementation(softpkg, implementation, "has no entry point"); } - fs::path entry_point = fs::path(softpkg->getSPDPath()) / implementation.getEntryPoint(); - LOG_TRACE(ApplicationValidator, "Validating code entry point " << entry_point.string()); - if (!fileExists(entry_point.string())) { - throw bad_implementation(softpkg, implementation, "missing entrypoint " + entry_point.string()); + std::string entry_point = _relativePath(softpkg, implementation.getEntryPoint()); + LOG_TRACE(ApplicationValidator, "Validating code entry point " << entry_point); + if (!fileExists(entry_point)) { + throw bad_implementation(softpkg, implementation, "missing entrypoint " + entry_point); } } @@ -175,7 +193,7 @@ void ApplicationValidator::validateImplementation(const SoftPkg* softpkg, BOOST_FOREACH(const SPD::SoftPkgRef& spdref, implementation.getSoftPkgDependencies()) { try { validateSoftPkgRef(spdref); - } catch (const std::runtime_error& exc) { + } catch (const validation_error& exc) { // Turn the exception into a more detailed bad_implementation that // includes enough context to debug the XML throw bad_implementation(softpkg, implementation, exc.what()); @@ -223,8 +241,17 @@ void ApplicationValidator::validateComponentPlacement(const ComponentPlacement& } } + int valid_implementations = 0; BOOST_FOREACH(const SPD::Implementation& implementation, softpkg->getImplementations()) { - validateImplementation(softpkg, implementation, true); + try { + validateImplementation(softpkg, implementation, true); + valid_implementations++; + } catch (const validation_error& err) { + LOG_WARN(ApplicationValidator, err.what()); + } + } + if (valid_implementations == 0) { + throw no_valid_implemenation(softpkg); } // If the softpkg is SCA-compliant, make sure it has a descriptor @@ -272,3 +299,13 @@ bool ApplicationValidator::endsWith(const std::string& filename, const std::stri std::string::size_type start = filename.size() - suffix.size(); return filename.compare(start, suffix.size(), suffix) == 0; } + +std::string ApplicationValidator::_relativePath(const SoftPkg* softpkg, const std::string& path) +{ + if (path.find('/') == 0) { + return path; + } else { + fs::path abspath = fs::path(softpkg->getSPDPath()) / path; + return abspath.string(); + } +} diff --git a/redhawk/src/control/sdr/dommgr/ApplicationValidator.h b/redhawk/src/control/sdr/dommgr/ApplicationValidator.h index 549d6bedd..f22fb6aca 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationValidator.h +++ b/redhawk/src/control/sdr/dommgr/ApplicationValidator.h @@ -82,6 +82,8 @@ namespace redhawk { bool endsWith(const std::string& filename, const std::string& suffix); bool fileExists(const std::string& filename); + std::string _relativePath(const ossie::SoftPkg* softpkg, const std::string& path); + CF::FileSystem_var fileSystem; redhawk::ProfileCache cache; }; From 859583f3c6705c65cb2fbb593b18a4e047d54c49 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 17 Oct 2016 16:27:57 -0400 Subject: [PATCH 0474/1644] Add missing NewSriCallback class in BulkIO test --- .../testing/tests/cpp/Bulkio_OutPort_Fixture.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/bulkioInterfaces/libsrc/testing/tests/cpp/Bulkio_OutPort_Fixture.cpp b/bulkioInterfaces/libsrc/testing/tests/cpp/Bulkio_OutPort_Fixture.cpp index 7d12bb4d8..a0f657635 100644 --- a/bulkioInterfaces/libsrc/testing/tests/cpp/Bulkio_OutPort_Fixture.cpp +++ b/bulkioInterfaces/libsrc/testing/tests/cpp/Bulkio_OutPort_Fixture.cpp @@ -27,6 +27,19 @@ // Registers the fixture into the 'registry' CPPUNIT_TEST_SUITE_REGISTRATION( Bulkio_OutPort_Fixture ); +class NewSriCallback { + +public: + + std::vector sids; + + ~NewSriCallback() {}; + + void newSriCB( const BULKIO::StreamSRI& sri) { + std::string sid(sri.streamID); + sids.push_back( sid ); + } +}; // Global connection/disconnection callbacks static void port_connected( const char* connectionId ) { From ac3b4aeb9e899d6214ec51aafeb7f0e8ba913a17 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 17 Oct 2016 16:42:05 -0400 Subject: [PATCH 0475/1644] Fix BurstIO test targets for out-of-place build --- burstioInterfaces/testing/tests/cpp/Makefile.am | 2 +- burstioInterfaces/testing/tests/java/Makefile.am | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/burstioInterfaces/testing/tests/cpp/Makefile.am b/burstioInterfaces/testing/tests/cpp/Makefile.am index 5d1ca219f..dddcd4420 100644 --- a/burstioInterfaces/testing/tests/cpp/Makefile.am +++ b/burstioInterfaces/testing/tests/cpp/Makefile.am @@ -20,7 +20,7 @@ burstio_include=$(top_srcdir)/src/cpp/include Burstio_SOURCES = Burstio.cpp Burstio_InPort.cpp Burstio_OutPort.cpp Burstio_PushTest.cpp Burstio_Utils_Test.cpp -Burstio_INCLUDES = -I$(burstio_include) -I$(burstio_include)/burstio -I$(top_builddir)/src/cpp/redhawk +Burstio_INCLUDES = -I$(burstio_include) -I$(burstio_include)/burstio -I$(top_builddir)/src/cpp -I$(top_builddir)/src/cpp/redhawk Burstio_CXXFLAGS = $(CPPUNIT_CFLAGS) $(Burstio_INCLUDES) $(BOOST_CPPFLAGS) $(BULKIO_CFLAGS) Burstio_LDADD = $(BULKIO_LIBS) $(BOOST_LDFLAGS) $(BOOST_SYSTEM_LIB) $(CPPUNIT_LIBS) -llog4cxx -ldl Burstio_LDADD += $(top_builddir)/src/cpp/libburstio.la $(top_builddir)/src/cpp/libburstioInterfaces.la diff --git a/burstioInterfaces/testing/tests/java/Makefile.am b/burstioInterfaces/testing/tests/java/Makefile.am index 8b8fc9056..1eeea7732 100644 --- a/burstioInterfaces/testing/tests/java/Makefile.am +++ b/burstioInterfaces/testing/tests/java/Makefile.am @@ -50,6 +50,7 @@ check_SCRIPTS = Burstio Burstio : $(Burstio_CLASSES) Makefile.am @echo "#!/bin/sh" > $@ + @echo "export LD_LIBRARY_PATH=$(top_builddir)/src/java/.libs:${LD_LIBRARY_PATH}" >> $@ @echo "exec java -cp $(Burstio_CLASSPATH):. -Dlog4j.configuration=file:$(srcdir)/log4j_config.txt org.junit.runner.JUnitCore $(TEST_CLASSES)" >> $@ @chmod +x $@ From f76d4bd7f57ebfac9572f1cdbe222c7890deb75f Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 17 Oct 2016 16:46:54 -0400 Subject: [PATCH 0476/1644] Ignore build products --- GPP/.gitignore | 1 + throughput/.gitignore | 1 + throughput/m4/.gitignore | 1 + 3 files changed, 3 insertions(+) create mode 100644 throughput/m4/.gitignore diff --git a/GPP/.gitignore b/GPP/.gitignore index 2f78cf5b6..8a622b0fb 100644 --- a/GPP/.gitignore +++ b/GPP/.gitignore @@ -1,2 +1,3 @@ +*.o *.pyc diff --git a/throughput/.gitignore b/throughput/.gitignore index f0639bc0b..5d20faf25 100644 --- a/throughput/.gitignore +++ b/throughput/.gitignore @@ -3,6 +3,7 @@ *.lo *.m4 *.o +*.pyc *.so .deps/ .libs/ diff --git a/throughput/m4/.gitignore b/throughput/m4/.gitignore new file mode 100644 index 000000000..0f4126cd6 --- /dev/null +++ b/throughput/m4/.gitignore @@ -0,0 +1 @@ +*.m4 From 2d1aa3e1c5ab76a8052dd48154ac72c8a59d7955 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 17 Oct 2016 16:51:08 -0400 Subject: [PATCH 0477/1644] Build BurstIO unit tests by default --- burstioInterfaces/configure.ac | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/burstioInterfaces/configure.ac b/burstioInterfaces/configure.ac index d6b1eb3df..7b859a3c7 100644 --- a/burstioInterfaces/configure.ac +++ b/burstioInterfaces/configure.ac @@ -132,16 +132,16 @@ AC_MSG_RESULT($HAVE_JAVASUPPORT) AM_CONDITIONAL(HAVE_JAVASUPPORT, test $HAVE_JAVASUPPORT = yes) # End optional java support -# Optionally enable unit tests -AC_ARG_ENABLE([testing], AS_HELP_STRING([--enable-testing], [enable build of unit tests])) -AS_IF([test "x$enable_testing" == "xyes"], [ - AM_PATH_CPPUNIT(1.9.6) +# Optionally disable unit tests +AC_ARG_ENABLE([testing], AS_HELP_STRING([--disable-testing], [disable build of unit tests])) +AS_IF([test "x$enable_testing" != "xno"], [ + AM_PATH_CPPUNIT(1.12.1) AS_IF([test "x$HAVE_JAVASUPPORT" == "xyes"], [ dnl Use RPM location hard-coded for now AC_SUBST([JUNIT_CLASSPATH], "/usr/share/java/junit4.jar") ]) ]) -AM_CONDITIONAL(ENABLE_TESTING, test "x$enable_testing" == "xyes") +AM_CONDITIONAL(ENABLE_TESTING, test "x$enable_testing" != "xno") AC_SUBST(idldir, '${prefix}/share/idl') From c8647b107e34496631d2e8e408a50628b9f50809 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 18 Oct 2016 09:40:30 -0400 Subject: [PATCH 0478/1644] Update BulkIO library version to 2.1, otherwise components will fail to build --- bulkioInterfaces/configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bulkioInterfaces/configure.ac b/bulkioInterfaces/configure.ac index f328ca504..93707a2a2 100644 --- a/bulkioInterfaces/configure.ac +++ b/bulkioInterfaces/configure.ac @@ -54,7 +54,7 @@ AM_CONDITIONAL([BUILD_BASE_CLASSES], [test "$enable_base_classes" != "no"]) if test "$enable_base_classes" != "no"; then AC_SUBST([BULKIO_SO_VERSION], [0:0:0]) - AC_SUBST([BULKIO_API_VERSION], [2.0]) + AC_SUBST([BULKIO_API_VERSION], [2.1]) AX_BOOST_BASE([1.41]) AX_BOOST_THREAD From d19ddfca3ac6dfe4f023886d7d2de85c1d5d435f Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 19 Oct 2016 14:40:38 -0400 Subject: [PATCH 0479/1644] Update BulkIO API version to 2.1 --- bulkioInterfaces/configure.ac | 2 +- bulkioInterfaces/libsrc/testing/tests/cpp/Makefile.am | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bulkioInterfaces/configure.ac b/bulkioInterfaces/configure.ac index f328ca504..93707a2a2 100644 --- a/bulkioInterfaces/configure.ac +++ b/bulkioInterfaces/configure.ac @@ -54,7 +54,7 @@ AM_CONDITIONAL([BUILD_BASE_CLASSES], [test "$enable_base_classes" != "no"]) if test "$enable_base_classes" != "no"; then AC_SUBST([BULKIO_SO_VERSION], [0:0:0]) - AC_SUBST([BULKIO_API_VERSION], [2.0]) + AC_SUBST([BULKIO_API_VERSION], [2.1]) AX_BOOST_BASE([1.41]) AX_BOOST_THREAD diff --git a/bulkioInterfaces/libsrc/testing/tests/cpp/Makefile.am b/bulkioInterfaces/libsrc/testing/tests/cpp/Makefile.am index 58338fe8c..e657f1d80 100644 --- a/bulkioInterfaces/libsrc/testing/tests/cpp/Makefile.am +++ b/bulkioInterfaces/libsrc/testing/tests/cpp/Makefile.am @@ -24,4 +24,4 @@ bulkio_top=../../../../ bulkio_libsrc_top=$(bulkio_top)/libsrc Bulkio_SOURCES = Bulkio.cpp Bulkio_Helper_Fixture.cpp Bulkio_InPort_Fixture.cpp Bulkio_OutPort_Fixture.cpp Bulkio_MultiOut_Port.cpp Bulkio_CXXFLAGS = $(CPPUNIT_CFLAGS) -I$(bulkio_libsrc_top)/cpp -I$(bulkio_top)/src/cpp -I$(bulkio_top)/src/cpp/ossie $(BOOST_CPPFLAGS) $(RH_DEPS_CFLAGS) -Bulkio_LDADD = -L$(bulkio_libsrc_top)/.libs -L$(bulkio_top)/.libs -lbulkio-2.0 -lbulkioInterfaces $(BOOST_LDFLAGS) $(BOOST_SYSTEM_LIB) $(RH_DEPS_LIBS) $(CPPUNIT_LIBS) -llog4cxx +Bulkio_LDADD = -L$(bulkio_libsrc_top)/.libs -L$(bulkio_top)/.libs -lbulkio-2.1 -lbulkioInterfaces $(BOOST_LDFLAGS) $(BOOST_SYSTEM_LIB) $(RH_DEPS_LIBS) $(CPPUNIT_LIBS) -llog4cxx From 5b1e601cd30600ce09ca549436efcadf2ba2ce3e Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 20 Oct 2016 13:23:12 -0400 Subject: [PATCH 0480/1644] CF-1505 Implement QueryablePort for Python MessageSupplierPort --- .../framework/python/ossie/events/__init__.py | 6 ++++- .../MessageSenderPy/MessageSenderPy.py | 2 +- .../MessageSenderPy/MessageSenderPy.scd.xml | 6 ++--- .../MessageTestPy/MessageTestPy.sad.xml | 20 +++++++------- .../src/testing/tests/test_08_Messaging.py | 27 ++++++++++++++++++- 5 files changed, 45 insertions(+), 16 deletions(-) mode change 100644 => 100755 redhawk/src/testing/sdr/dom/components/MessageSenderPy/MessageSenderPy.py diff --git a/redhawk/src/base/framework/python/ossie/events/__init__.py b/redhawk/src/base/framework/python/ossie/events/__init__.py index 9946e9c91..d233586bd 100644 --- a/redhawk/src/base/framework/python/ossie/events/__init__.py +++ b/redhawk/src/base/framework/python/ossie/events/__init__.py @@ -28,6 +28,7 @@ from omniORB import any, URI, CORBA from ossie.cf import CF, CF__POA +from ossie.cf import ExtendedCF, ExtendedCF__POA from ossie.cf import ExtendedEvent, ExtendedEvent__POA from ossie.properties import struct_from_any, struct_to_any, props_to_any from ossie.properties import simple_property, simpleseq_property, struct_property, structseq_property @@ -488,7 +489,7 @@ def _run(self): else: _time.sleep(self.thread_sleep) -class MessageSupplierPort(CF__POA.Port): +class MessageSupplierPort(ExtendedCF__POA.QueryablePort): class Supplier_i(CosEventComm__POA.PushSupplier): def disconnect_push_supplier(self): pass @@ -586,3 +587,6 @@ def sendMessages(self, data_structs): def disconnect_push_supplier(self): pass + + def _get_connections(self): + return [ExtendedCF.UsesConnection(k, v['port']) for k, v in self._connections.iteritems()] diff --git a/redhawk/src/testing/sdr/dom/components/MessageSenderPy/MessageSenderPy.py b/redhawk/src/testing/sdr/dom/components/MessageSenderPy/MessageSenderPy.py old mode 100644 new mode 100755 index 8cd387791..83e8d1c5d --- a/redhawk/src/testing/sdr/dom/components/MessageSenderPy/MessageSenderPy.py +++ b/redhawk/src/testing/sdr/dom/components/MessageSenderPy/MessageSenderPy.py @@ -47,7 +47,7 @@ class TestMessagePort(CF__POA.Resource, Resource): Example component to demonstrate REDHAWK sender-side messaging port. """ message_out = usesport(name="message_out", - repid="IDL:CosEventComm/PushConsumer:1.0", + repid="IDL:ExtendedEvent/MessageEvent:1.0", type_="data") def __init__(self, identifier, execparams): diff --git a/redhawk/src/testing/sdr/dom/components/MessageSenderPy/MessageSenderPy.scd.xml b/redhawk/src/testing/sdr/dom/components/MessageSenderPy/MessageSenderPy.scd.xml index 511b588cc..4247cfc02 100644 --- a/redhawk/src/testing/sdr/dom/components/MessageSenderPy/MessageSenderPy.scd.xml +++ b/redhawk/src/testing/sdr/dom/components/MessageSenderPy/MessageSenderPy.scd.xml @@ -31,9 +31,9 @@ with this program. If not, see http://www.gnu.org/licenses/. - - - + + + diff --git a/redhawk/src/testing/sdr/dom/waveforms/MessageTestPy/MessageTestPy.sad.xml b/redhawk/src/testing/sdr/dom/waveforms/MessageTestPy/MessageTestPy.sad.xml index 71f2c44e8..b8069f349 100644 --- a/redhawk/src/testing/sdr/dom/waveforms/MessageTestPy/MessageTestPy.sad.xml +++ b/redhawk/src/testing/sdr/dom/waveforms/MessageTestPy/MessageTestPy.sad.xml @@ -32,7 +32,7 @@ with this program. If not, see http://www.gnu.org/licenses/. - + MessageReceiverPy_1 @@ -41,7 +41,7 @@ with this program. If not, see http://www.gnu.org/licenses/. - + MessageSenderPy_1 @@ -50,32 +50,32 @@ with this program. If not, see http://www.gnu.org/licenses/. - + - + message_out - + message_in - + - + message_in - + - + message_out - + diff --git a/redhawk/src/testing/tests/test_08_Messaging.py b/redhawk/src/testing/tests/test_08_Messaging.py index 6beb4538e..08aba4c8c 100644 --- a/redhawk/src/testing/tests/test_08_Messaging.py +++ b/redhawk/src/testing/tests/test_08_Messaging.py @@ -25,6 +25,7 @@ import threading import time +import CosEventChannelAdmin class EventPortConnectionsTest(scatest.CorbaTestCase): def setUp(self): @@ -72,10 +73,34 @@ def test_EventDevicePortConnection(self): components = app._get_registeredComponents() for component in components: print component.componentObject._get_identifier() - if 'DCE:b1fe6cc1-2562-4878-9a69-f191f89a6ef8' in component.componentObject._get_identifier(): + if 'MessageReceiverPy_1' in component.componentObject._get_identifier(): stuff = component.componentObject.query([]) recval = any.from_any(stuff[0].value) self.assertEquals(6, len(recval)) for val in recval: self.assertEquals('test_message' in val, True) app.releaseObject() + + def test_QueryablePortPython(self): + self._devBooter, self._devMgr = self.launchDeviceManager("/nodes/test_BasicTestDevice_node/DeviceManager.dcd.xml", self._domMgr) + self.assertNotEqual(self._devBooter, None) + self._domMgr.installApplication("/waveforms/MessageTestPy/MessageTestPy.sad.xml") + appFact = self._domMgr._get_applicationFactories()[0] + app = appFact.create(appFact._get_name(), [], []) + for component in app._get_registeredComponents(): + if 'MessageSenderPy_1' in component.componentObject._get_identifier(): + sender_port = component.componentObject.getPort('message_out') + elif 'MessageReceiverPy_1' in component.componentObject._get_identifier(): + receiver_port = component.componentObject.getPort('message_in') + + # There should be two connections, one to the receiver's port and + # another to the event channel + connections = sender_port._get_connections() + self.assertEqual(len(connections), 2) + for connection in connections: + if 'direct' in connection.connectionId: + self.assertTrue(connection.port._is_equivalent(receiver_port)) + else: + channel = connection.port._narrow(CosEventChannelAdmin.EventChannel) + self.assertNotEqual(channel, None) + app.releaseObject() From 89e008f78427e64f1932bf7f3d5b3b1293abe511 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 20 Oct 2016 14:24:07 -0400 Subject: [PATCH 0481/1644] CF-1505 Implement QueryablePort for Java MessageSupplierPort --- .../ossie/component/QueryableUsesPort.java | 12 ++++++-- .../org/ossie/events/MessageSupplierPort.java | 10 +++++-- .../EventReceive/EventReceive.scd.xml | 8 ++++-- .../components/EventSend/EventSend.scd.xml | 5 ++-- .../MessageTestJava/MessageTestJava.sad.xml | 20 ++++++------- .../testing/tests/test_08_MessagingJava.py | 28 ++++++++++++++++++- 6 files changed, 64 insertions(+), 19 deletions(-) diff --git a/redhawk/src/base/framework/java/ossie/src/org/ossie/component/QueryableUsesPort.java b/redhawk/src/base/framework/java/ossie/src/org/ossie/component/QueryableUsesPort.java index 71806f485..1bb4c4585 100644 --- a/redhawk/src/base/framework/java/ossie/src/org/ossie/component/QueryableUsesPort.java +++ b/redhawk/src/base/framework/java/ossie/src/org/ossie/component/QueryableUsesPort.java @@ -24,6 +24,7 @@ */ package org.ossie.component; +import java.util.Map; import java.util.HashMap; import org.ossie.component.UsesPort; @@ -93,7 +94,14 @@ public void disconnectPort(final String connectionId) { protected abstract E narrow(org.omg.CORBA.Object connection); public UsesConnection[] connections() { - final UsesConnection[] connList = new UsesConnection[0]; - return connList; + synchronized (this.updatingPortsLock) { + final UsesConnection[] connList = new UsesConnection[this.outPorts.size()]; + int index = 0; + for (Map.Entry entry : this.outPorts.entrySet()) { + org.omg.CORBA.Object obj = (org.omg.CORBA.Object)entry.getValue(); + connList[index++] = new UsesConnection(entry.getKey(), obj); + } + return connList; + } } } diff --git a/redhawk/src/base/framework/java/ossie/src/org/ossie/events/MessageSupplierPort.java b/redhawk/src/base/framework/java/ossie/src/org/ossie/events/MessageSupplierPort.java index 7719bc714..340f5bfcb 100644 --- a/redhawk/src/base/framework/java/ossie/src/org/ossie/events/MessageSupplierPort.java +++ b/redhawk/src/base/framework/java/ossie/src/org/ossie/events/MessageSupplierPort.java @@ -39,11 +39,11 @@ import org.apache.log4j.Logger; -import org.ossie.component.UsesPort; +import org.ossie.component.QueryableUsesPort; import org.ossie.component.PortBase; import org.ossie.properties.StructDef; -public class MessageSupplierPort extends UsesPort implements EventChannelOperations, PortBase { +public class MessageSupplierPort extends QueryableUsesPort implements EventChannelOperations, PortBase { /** * Internal class to adapt PushSupplier CORBA interface for disconnection @@ -126,6 +126,8 @@ public void connectPort(final org.omg.CORBA.Object connection, final String conn } synchronized (this.updatingPortsLock) { + // Store the original channel in the parent object's container + this.outPorts.put(connectionId, channel); this.suppliers.put(connectionId, supplier); this.consumers.put(connectionId, proxy_consumer); this.active = true; @@ -180,6 +182,10 @@ private void removeConnection(String connectionId, boolean notifyConsumer) SupplierAdapter supplier = null; PushConsumer proxy_consumer = null; synchronized (this.updatingPortsLock) { + // Remove the original EventChannel object from the parent class' + // container + this.outPorts.remove(connectionId); + proxy_consumer = this.consumers.get(connectionId); if (proxy_consumer == null) { return; diff --git a/redhawk/src/testing/sdr/dom/components/EventReceive/EventReceive.scd.xml b/redhawk/src/testing/sdr/dom/components/EventReceive/EventReceive.scd.xml index 6f2532037..aea5f6fd7 100644 --- a/redhawk/src/testing/sdr/dom/components/EventReceive/EventReceive.scd.xml +++ b/redhawk/src/testing/sdr/dom/components/EventReceive/EventReceive.scd.xml @@ -31,7 +31,12 @@ with this program. If not, see http://www.gnu.org/licenses/. - + + + + + + @@ -45,6 +50,5 @@ with this program. If not, see http://www.gnu.org/licenses/. - diff --git a/redhawk/src/testing/sdr/dom/components/EventSend/EventSend.scd.xml b/redhawk/src/testing/sdr/dom/components/EventSend/EventSend.scd.xml index 9d8e3e3ef..92373711b 100644 --- a/redhawk/src/testing/sdr/dom/components/EventSend/EventSend.scd.xml +++ b/redhawk/src/testing/sdr/dom/components/EventSend/EventSend.scd.xml @@ -31,7 +31,9 @@ with this program. If not, see http://www.gnu.org/licenses/. - + + + @@ -45,6 +47,5 @@ with this program. If not, see http://www.gnu.org/licenses/. - diff --git a/redhawk/src/testing/sdr/dom/waveforms/MessageTestJava/MessageTestJava.sad.xml b/redhawk/src/testing/sdr/dom/waveforms/MessageTestJava/MessageTestJava.sad.xml index f6340ca37..056e50f30 100644 --- a/redhawk/src/testing/sdr/dom/waveforms/MessageTestJava/MessageTestJava.sad.xml +++ b/redhawk/src/testing/sdr/dom/waveforms/MessageTestJava/MessageTestJava.sad.xml @@ -32,7 +32,7 @@ with this program. If not, see http://www.gnu.org/licenses/. - + EventReceiveJava_1 @@ -41,7 +41,7 @@ with this program. If not, see http://www.gnu.org/licenses/. - + EventSenderJava_1 @@ -50,32 +50,32 @@ with this program. If not, see http://www.gnu.org/licenses/. - + - + message_out - + message_in - + - + message_in - + - + message_out - + diff --git a/redhawk/src/testing/tests/test_08_MessagingJava.py b/redhawk/src/testing/tests/test_08_MessagingJava.py index 28de1c66b..4565e50f9 100644 --- a/redhawk/src/testing/tests/test_08_MessagingJava.py +++ b/redhawk/src/testing/tests/test_08_MessagingJava.py @@ -25,6 +25,8 @@ import threading import time +import CosEventChannelAdmin + @scatest.requireJava class EventPortConnectionsTest(scatest.CorbaTestCase): def setUp(self): @@ -96,10 +98,34 @@ def test_EventDevicePortConnectionJavaOnly(self): time.sleep(2) for component in components: print component.componentObject._get_identifier() - if 'DCE:b1fe6cc1-2562-4878-9a69-f191f89a6ef8' in component.componentObject._get_identifier(): + if 'EventReceiveJava_1' in component.componentObject._get_identifier(): stuff = component.componentObject.query([CF.DataType("received_messages", any.to_any(None))]) recval = any.from_any(stuff[0].value) self.assertEquals(6, len(recval)) for val in recval: self.assertEquals('test_message' in val, True) app.releaseObject() # kill producer/consumer + + def test_QueryablePortJava(self): + self._devBooter, self._devMgr = self.launchDeviceManager("/nodes/test_BasicTestDevice_node/DeviceManager.dcd.xml", self._domMgr) + self.assertNotEqual(self._devBooter, None) + self._domMgr.installApplication("/waveforms/MessageTestJava/MessageTestJava.sad.xml") + appFact = self._domMgr._get_applicationFactories()[0] + app = appFact.create(appFact._get_name(), [], []) + for component in app._get_registeredComponents(): + if 'EventSenderJava_1' in component.componentObject._get_identifier(): + sender_port = component.componentObject.getPort('message_out') + elif 'EventReceiveJava_1' in component.componentObject._get_identifier(): + receiver_port = component.componentObject.getPort('message_in') + + # There should be two connections, one to the receiver's port and + # another to the event channel + connections = sender_port._get_connections() + self.assertEqual(len(connections), 2) + for connection in connections: + if 'direct' in connection.connectionId: + self.assertTrue(connection.port._is_equivalent(receiver_port)) + else: + channel = connection.port._narrow(CosEventChannelAdmin.EventChannel) + self.assertNotEqual(channel, None) + app.releaseObject() From 46fbbd9c38005be8ca67b378ba5264784f73bb85 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 25 Oct 2016 10:07:36 -0400 Subject: [PATCH 0482/1644] Use the device label first (if available) when logging an abnormal component termination --- .../sdr/dommgr/DomainManager_EventSupport.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/DomainManager_EventSupport.cpp b/redhawk/src/control/sdr/dommgr/DomainManager_EventSupport.cpp index 71d9fe40a..ab9d3c77b 100644 --- a/redhawk/src/control/sdr/dommgr/DomainManager_EventSupport.cpp +++ b/redhawk/src/control/sdr/dommgr/DomainManager_EventSupport.cpp @@ -183,10 +183,21 @@ void DomainManager_impl::idmTerminationMessages(const redhawk::events::Component } } + // Make the device identification as useful as possible by providing the + // label first (if available) and then the unique identifier, which is + // often a UUID + std::string device_label; + DeviceList::iterator device = findDeviceById(termMsg.device_id); + if (device != _registeredDevices.end()) { + device_label = "'" + (*device)->label + "' (" + termMsg.device_id + ")"; + } else { + device_label = termMsg.device_id; + } + if (application) { - application->componentTerminated(termMsg.component_id, termMsg.device_id); + application->componentTerminated(termMsg.component_id, device_label); } else { - LOG_WARN(DomainManager_impl, "Abnormal Component Termination, Reporting Device: " << termMsg.device_id + LOG_WARN(DomainManager_impl, "Abnormal Component Termination, Reporting Device: " << device_label << " Application/Component " << termMsg.application_id << "/" << termMsg.component_id); } } From b2d59f2f815dd8ce9c43b0a510ee74538faf6a73 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 25 Oct 2016 10:08:37 -0400 Subject: [PATCH 0483/1644] Move some of the mapping of deployment-time component state to run-time component state into the Application object --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 34 ++++----- .../control/sdr/dommgr/Application_impl.cpp | 70 ++++++++----------- .../src/control/sdr/dommgr/Application_impl.h | 9 ++- 3 files changed, 44 insertions(+), 69 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 4f101ec4c..5044b19e7 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -1436,10 +1436,6 @@ void createHelper::loadAndExecuteContainers(const ContainerList& containers, // TODO: Promote contained component affinity values BOOST_FOREACH(redhawk::ContainerDeployment* container, containers) { - const ossie::SoftPkg* softpkg = container->getSoftPkg(); - const ossie::SPD::Implementation* implementation = container->getImplementation(); - const ossie::ComponentInstantiation* instantiation = container->getInstantiation(); - boost::shared_ptr device = container->getAssignedDevice(); if (!device) { std::ostringstream message; @@ -1448,13 +1444,11 @@ void createHelper::loadAndExecuteContainers(const ContainerList& containers, } // Let the application know to expect the given component - _application->addContainer(container->getIdentifier(), softpkg->getSPDFile()); + ossie::ApplicationComponent* app_container = _application->addContainer(container); + const ossie::ComponentInstantiation* instantiation = container->getInstantiation(); if (instantiation->isNamingService()) { - std::string lookupName = _baseNamingContext + "/" + instantiation->getFindByNamingServiceName(); - _application->setComponentNamingContext(container->getIdentifier(), lookupName); + app_container->namingContext = _baseNamingContext + "/" + instantiation->getFindByNamingServiceName(); } - _application->setComponentImplementation(container->getIdentifier(), implementation->getID()); - _application->setComponentDevice(container->getIdentifier(), device->device); // get the code.localfile LOG_TRACE(ApplicationFactory_impl, "Host is " << device->label << " Local file name is " @@ -1499,31 +1493,27 @@ void createHelper::loadAndExecuteComponents(const DeploymentList& deployments, // apply application affinity options to required components applyApplicationAffinityOptions(deployments); - for (unsigned int rc_idx = 0; rc_idx < deployments.size (); rc_idx++) { - redhawk::ComponentDeployment* deployment = deployments[rc_idx]; - const ossie::SoftPkg* softpkg = deployment->getSoftPkg(); - const ossie::ComponentInstantiation* instantiation = deployment->getInstantiation(); - const ossie::SPD::Implementation* implementation = deployment->getImplementation(); + BOOST_FOREACH(redhawk::ComponentDeployment* deployment, deployments) { + const std::string& component_id = deployment->getIdentifier(); + LOG_TRACE(ApplicationFactory_impl, "Loading and executing component '" << component_id << "'"); boost::shared_ptr device = deployment->getAssignedDevice(); if (!device) { std::ostringstream message; - message << "component " << deployment->getIdentifier() << " was not assigned to a device"; + message << "component " << component_id << " was not assigned to a device"; throw std::logic_error(message.str()); } LOG_INFO(ApplicationFactory_impl, "Application '" << _waveformContextName << "' component '" - << deployment->getIdentifier() << "' assigned to device '" << device->label + << component_id << "' assigned to device '" << device->label << "' (" << device->identifier << ")"); // Let the application know to expect the given component - _application->addComponent(deployment->getIdentifier(), softpkg->getSPDFile()); - _application->setComponentImplementation(deployment->getIdentifier(), implementation->getID()); + ossie::ApplicationComponent* app_component = _application->addComponent(deployment); + const ossie::ComponentInstantiation* instantiation = deployment->getInstantiation(); if (instantiation->isNamingService()) { - std::string lookupName = _baseNamingContext + "/" + instantiation->getFindByNamingServiceName(); - _application->setComponentNamingContext(deployment->getIdentifier(), lookupName); + app_component->namingContext = _baseNamingContext + "/" + instantiation->getFindByNamingServiceName(); } - _application->setComponentDevice(deployment->getIdentifier(), device->device); // get the code.localfile LOG_TRACE(ApplicationFactory_impl, "Host is " << device->label << " Local file name is " @@ -1540,7 +1530,7 @@ void createHelper::loadAndExecuteComponents(const DeploymentList& deployments, CF::LoadableDevice_var loadabledev = ossie::corba::_narrowSafe(device->device); if (CORBA::is_nil(loadabledev)) { std::ostringstream message; - message << "component " << deployment->getIdentifier() << " was assigned to non-loadable device " + message << "component " << component_id << " was assigned to non-loadable device " << device->identifier; LOG_ERROR(ApplicationFactory_impl, message); throw std::logic_error(message.str()); diff --git a/redhawk/src/control/sdr/dommgr/Application_impl.cpp b/redhawk/src/control/sdr/dommgr/Application_impl.cpp index 45e6bbc8a..995e29251 100644 --- a/redhawk/src/control/sdr/dommgr/Application_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/Application_impl.cpp @@ -1315,34 +1315,42 @@ ossie::ApplicationComponent* Application_impl::findComponent(const std::string& return 0; } -void Application_impl::addContainer(const std::string& identifier, const std::string& profile) +ossie::ApplicationComponent* Application_impl::addContainer(const redhawk::ContainerDeployment* container) { + const std::string& identifier = container->getIdentifier(); if (findComponent(identifier)) { - LOG_ERROR(Application_impl, "Container '" << identifier << "' is already registered"); - return; + throw std::logic_error("container '" + identifier + "' is already registered"); } + const std::string& profile = container->getSoftPkg()->getSPDFile(); LOG_DEBUG(Application_impl, "Adding container '" << identifier << "' with profile " << profile); ossie::ApplicationComponent component; component.identifier = identifier; component.softwareProfile = profile; component.processId = 0; component.isContainer = true; + component.implementationId = container->getImplementation()->getID(); + component.assignedDevice = CF::Device::_duplicate(container->getAssignedDevice()->device); _components.push_back(component); + return &(_components.back()); } -void Application_impl::addComponent(const std::string& identifier, const std::string& profile) +ossie::ApplicationComponent* Application_impl::addComponent(const redhawk::ComponentDeployment* deployment) { + const std::string& identifier = deployment->getIdentifier(); if (findComponent(identifier)) { - LOG_ERROR(Application_impl, "Component '" << identifier << "' is already registered"); - return; + throw std::logic_error("component '" + identifier + "' is already registered"); } + const std::string& profile = deployment->getSoftPkg()->getSPDFile(); LOG_DEBUG(Application_impl, "Adding component '" << identifier << "' with profile " << profile); ossie::ApplicationComponent component; component.identifier = identifier; component.softwareProfile = profile; component.processId = 0; component.isContainer = false; + component.implementationId = deployment->getImplementation()->getID(); + component.assignedDevice = CF::Device::_duplicate(deployment->getAssignedDevice()->device); _components.push_back(component); + return &(_components.back()); } void Application_impl::setComponentPid(const std::string& identifier, unsigned long pid) @@ -1355,36 +1363,6 @@ void Application_impl::setComponentPid(const std::string& identifier, unsigned l } } -void Application_impl::setComponentNamingContext(const std::string& identifier, const std::string& name) -{ - ossie::ApplicationComponent* component = findComponent(identifier); - if (!component) { - LOG_ERROR(Application_impl, "Setting naming context for unknown component '" << identifier << "'"); - } else { - component->namingContext = name; - } -} - -void Application_impl::setComponentImplementation(const std::string& identifier, const std::string& implementationId) -{ - ossie::ApplicationComponent* component = findComponent(identifier); - if (!component) { - LOG_ERROR(Application_impl, "Setting implementation for unknown component '" << identifier << "'"); - } else { - component->implementationId = implementationId; - } -} - -void Application_impl::setComponentDevice(const std::string& identifier, CF::Device_ptr device) -{ - ossie::ApplicationComponent* component = findComponent(identifier); - if (!component) { - LOG_ERROR(Application_impl, "Setting device for unknown component '" << identifier << "'"); - } else { - component->assignedDevice = CF::Device::_duplicate(device); - } -} - void Application_impl::addComponentLoadedFile(const std::string& identifier, const std::string& fileName) { ossie::ApplicationComponent* component = findComponent(identifier); @@ -1408,12 +1386,20 @@ CORBA::Object_ptr Application_impl::getComponentObject(const std::string& identi void Application_impl::componentTerminated(const std::string& componentId, const std::string& deviceId) { - LOG_WARN(Application_impl, "Component '" << componentId << "' from application '" << _identifier - << "' terminated abnormally on device '" << deviceId << "'"); + boost::mutex::scoped_lock lock(_registrationMutex); ossie::ApplicationComponent* component = findComponent(componentId); - if (component) { - boost::mutex::scoped_lock lock(_registrationMutex); - component->processId = 0; - _registrationCondition.notify_all(); + if (!component) { + LOG_WARN(Application_impl, "Unrecognized component '" << componentId << "' from application '" << _identifier + << "' terminated abnormally on device " << deviceId); + return; } + if (component->isContainer) { + LOG_WARN(Application_impl, "Component host from application '" << _identifier + << "' terminated abnormally on device " << deviceId); + } else { + LOG_WARN(Application_impl, "Component '" << componentId << "' from application '" << _identifier + << "' terminated abnormally on device " << deviceId); + } + component->processId = 0; + _registrationCondition.notify_all(); } diff --git a/redhawk/src/control/sdr/dommgr/Application_impl.h b/redhawk/src/control/sdr/dommgr/Application_impl.h index bbab68b84..cf4e194e7 100644 --- a/redhawk/src/control/sdr/dommgr/Application_impl.h +++ b/redhawk/src/control/sdr/dommgr/Application_impl.h @@ -32,6 +32,8 @@ #include #include +#include "Deployment.h" +#include "ApplicationDeployment.h" #include "PersistenceStore.h" #include "connectionSupport.h" @@ -141,12 +143,9 @@ class Application_impl : public virtual POA_CF::Application, public Logging_impl void _cleanupActivations(); // Set component state - void addComponent(const std::string& identifier, const std::string& profile); - void addContainer(const std::string& identifier, const std::string& profile); + ossie::ApplicationComponent* addComponent(const redhawk::ComponentDeployment* deployment); + ossie::ApplicationComponent* addContainer(const redhawk::ContainerDeployment* container); void setComponentPid(const std::string& identifier, unsigned long pid); - void setComponentNamingContext(const std::string& identifier, const std::string& name); - void setComponentImplementation(const std::string& identifier, const std::string& implementationId); - void setComponentDevice(const std::string& identifier, CF::Device_ptr device); void addComponentLoadedFile(const std::string& identifier, const std::string& fileName); CORBA::Object_ptr getComponentObject(const std::string& identifier); From a0b0290088f7356dd7972117b8df19821599e4f7 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 25 Oct 2016 15:04:59 -0400 Subject: [PATCH 0484/1644] Remove unused code --- redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp b/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp index 1f64c396e..152d73c6d 100644 --- a/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp @@ -2151,10 +2151,6 @@ ossie::ServiceList::iterator DomainManager_impl::_local_unregisterService(ossie: if (!_applications.empty()) { std::vector appsToRelease; - - PortableServer::POA_var dm_poa = ossie::corba::RootPOA()->find_POA("DomainManager", 0); - PortableServer::POA_var poa = dm_poa->find_POA("Applications", 1); - for (ApplicationTable::iterator app = _applications.begin(); app != _applications.end(); ++app) { if (app->second->checkConnectionDependency(ossie::Endpoint::SERVICENAME, serviceName)) { app->second->_add_ref(); From 9dc2fa55ba9bbd8a5faf757d7a044ad478c328f2 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 25 Oct 2016 15:34:22 -0400 Subject: [PATCH 0485/1644] Reduce unnecessary use of returnString() with local objects --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 15 +++++ .../sdr/dommgr/ApplicationFactory_impl.h | 5 +- .../control/sdr/dommgr/Application_impl.cpp | 10 ++++ .../src/control/sdr/dommgr/Application_impl.h | 2 + .../control/sdr/dommgr/DomainManager_impl.cpp | 56 +++++++++---------- .../control/sdr/dommgr/DomainManager_impl.h | 5 +- 6 files changed, 58 insertions(+), 35 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 5044b19e7..b0491259d 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -248,6 +248,21 @@ ApplicationFactory_impl::~ApplicationFactory_impl () } +const std::string& ApplicationFactory_impl::getIdentifier() const +{ + return _identifier; +} + +const std::string& ApplicationFactory_impl::getName() const +{ + return _name; +} + +const std::string& ApplicationFactory_impl::getSoftwareProfile() const +{ + return _softwareProfile; +} + void createHelper::assignPlacementsToDevices(redhawk::ApplicationDeployment& appDeployment, const DeviceAssignmentMap& devices) { diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h index f19f86378..e1134e12b 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.h @@ -85,8 +85,9 @@ class ApplicationFactory_impl: public virtual POA_CF::ApplicationFactory return CORBA::string_dup(_softwareProfile.c_str()); } - const std::string & getID () { return _identifier; } - const std::string & getName () { return _name; } + const std::string& getIdentifier () const; + const std::string& getName () const; + const std::string& getSoftwareProfile() const; // allow createHelper to have access to ApplicationFactory_impl friend class createHelper; diff --git a/redhawk/src/control/sdr/dommgr/Application_impl.cpp b/redhawk/src/control/sdr/dommgr/Application_impl.cpp index 995e29251..002b8168d 100644 --- a/redhawk/src/control/sdr/dommgr/Application_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/Application_impl.cpp @@ -1182,6 +1182,16 @@ const std::string& Application_impl::getIdentifier() const return _identifier; } +const std::string& Application_impl::getName() const +{ + return _appName; +} + +const std::string& Application_impl::getProfile() const +{ + return _sadProfile; +} + void Application_impl::addExternalPort (const std::string& identifier, CORBA::Object_ptr port) { if (_ports.count(identifier)) { diff --git a/redhawk/src/control/sdr/dommgr/Application_impl.h b/redhawk/src/control/sdr/dommgr/Application_impl.h index cf4e194e7..828d7f88d 100644 --- a/redhawk/src/control/sdr/dommgr/Application_impl.h +++ b/redhawk/src/control/sdr/dommgr/Application_impl.h @@ -133,6 +133,8 @@ class Application_impl : public virtual POA_CF::Application, public Logging_impl CF::ApplicationRegistrar_ptr appReg (void); const std::string& getIdentifier() const; + const std::string& getName() const; + const std::string& getProfile() const; void addExternalPort (const std::string&, CORBA::Object_ptr); void addExternalProperty (const std::string&, const std::string&, CF::Resource_ptr); diff --git a/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp b/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp index 152d73c6d..789c1c97c 100644 --- a/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp @@ -596,7 +596,7 @@ void DomainManager_impl::releaseAllApplications() try { (*app)->releaseObject(); } catch ( ... ) { - LOG_TRACE(DomainManager_impl, "Error releasing application " << ossie::corba::returnString((*app)->name())); + LOG_TRACE(DomainManager_impl, "Error releasing application " << (*app)->getName()); } (*app)->_remove_ref(); } @@ -1600,16 +1600,16 @@ throw (CORBA::SystemException, CF::DomainManager::ApplicationInstallationError, CF::DomainManager::ApplicationAlreadyInstalled) { - boost::mutex::scoped_lock lock(interfaceAccess); - _local_installApplication(profileFileName); + boost::mutex::scoped_lock lock(interfaceAccess); + _local_installApplication(profileFileName); - ApplicationFactoryTable::iterator appFact = _applicationFactories.find(profileFileName); - if (appFact != _applicationFactories.end()) { - std::string identifier = ossie::corba::returnString(appFact->first.c_str()); - std::string name = ossie::corba::returnString(appFact->second->name()); - CF::ApplicationFactory_var appFactRef = appFact->second->_this(); - sendAddEvent( _identifier.c_str(), identifier, name, appFactRef, StandardEvent::APPLICATION_FACTORY ); - } + ApplicationFactoryTable::iterator appFact = _applicationFactories.find(profileFileName); + if (appFact != _applicationFactories.end()) { + const std::string& identifier = appFact->first; + const std::string& name = appFact->second->getName(); + CF::ApplicationFactory_var appFactRef = appFact->second->_this(); + sendAddEvent( _identifier.c_str(), identifier, name, appFactRef, StandardEvent::APPLICATION_FACTORY ); + } } void DomainManager_impl::_local_installApplication (const char* profileFileName) @@ -1628,12 +1628,12 @@ void DomainManager_impl::_local_installApplication (const char* profileFileName) LOG_TRACE(DomainManager_impl, "installApplication: Createing new AppFac"); ApplicationFactory_impl* appFact = new ApplicationFactory_impl(profileFileName, this->_domainName, this); - const std::string appFactoryId = appFact->getID(); + const std::string& appFactoryId = appFact->getIdentifier(); // Check if application factory already exists for this profile LOG_TRACE(DomainManager_impl, "Installing application ID " << appFactoryId); if (_applicationFactories.count(appFactoryId)) { - LOG_INFO(DomainManager_impl, "Application " << appFact->getName() << " with id " << appFact->getID() + LOG_INFO(DomainManager_impl, "Application " << appFact->getName() << " with id " << appFactoryId << " already installed (Application Factory already exists)"); delete appFact; appFact=NULL; @@ -1694,7 +1694,7 @@ throw (CORBA::SystemException, CF::DomainManager::InvalidIdentifier, ApplicationFactoryTable::iterator appFact = _applicationFactories.find(applicationId); if (appFact != _applicationFactories.end()) { appFactory_id = appFact->first; - appFactory_name = ossie::corba::returnString(appFact->second->name()); + appFactory_name = appFact->second->getName(); } _local_uninstallApplication(applicationId); @@ -1728,7 +1728,7 @@ void DomainManager_impl::_local_uninstallApplication (const char* applicationId) } // Update the persistence database - const std::string sad_file = ossie::corba::returnString(appFact->second->softwareProfile()); + const std::string sad_file = appFact->second->getSoftwareProfile(); _installedApplications.erase(sad_file); try { db.store("APP_FACTORIES", _installedApplications); @@ -1775,17 +1775,16 @@ DomainManager_impl::addApplication(Application_impl* new_app) TRACE_ENTER(DomainManager_impl) boost::recursive_mutex::scoped_lock lock(stateAccess); - LOG_TRACE(DomainManager_impl, "Attempting to add application to AppSeq with id: " << ossie::corba::returnString(new_app->identifier())); - + const std::string& identifier = new_app->getIdentifier(); + LOG_TRACE(DomainManager_impl, "Attempting to add application to AppSeq with id: " << identifier); try { - const std::string identifier = ossie::corba::returnString(new_app->identifier()); _applications[identifier] = new_app; new_app->_add_ref(); ApplicationNode appNode; - appNode.name = ossie::corba::returnString(new_app->name()); + appNode.name = new_app->getName(); appNode.identifier = new_app->getIdentifier(); - appNode.profile = ossie::corba::returnString(new_app->profile()); + appNode.profile = new_app->getProfile(); appNode.contextName = new_app->_waveformContextName; appNode.context = CosNaming::NamingContext::_duplicate(new_app->_waveformContext); appNode.componentDevices = new_app->_componentDevices; @@ -1821,7 +1820,6 @@ DomainManager_impl::addApplication(Application_impl* new_app) } } catch (...) { - const std::string identifier = ossie::corba::returnString(new_app->identifier()); ostringstream eout; eout << "Could not add new application to AppSeq; "; eout << " application id: " << identifier << "; "; @@ -1926,14 +1924,12 @@ throw (CORBA::SystemException, CF::InvalidObjectReference, CF::DomainManager::AlreadyConnected) { boost::mutex::scoped_lock lock(interfaceAccess); - std::string tmp_id = ossie::corba::returnString(registeringId); - std::string eventchannel_name = ossie::corba::returnString(eventChannelName); - _local_registerWithEventChannel(registeringObject, tmp_id, eventchannel_name); + _local_registerWithEventChannel(registeringObject, registeringId, eventChannelName); } void DomainManager_impl::_local_registerWithEventChannel (CORBA::Object_ptr registeringObject, - std::string ®isteringId, - std::string &eventChannelName) + const std::string& registeringId, + const std::string& eventChannelName) { TRACE_ENTER(DomainManager_impl) @@ -1974,13 +1970,11 @@ throw (CORBA::SystemException, CF::DomainManager::InvalidEventChannelName, CF::DomainManager::NotConnected) { boost::mutex::scoped_lock lock(interfaceAccess); - std::string tmp_id = ossie::corba::returnString(unregisteringId); - std::string eventchannel_name = ossie::corba::returnString(eventChannelName); - _local_unregisterFromEventChannel(tmp_id, eventchannel_name); + _local_unregisterFromEventChannel(unregisteringId, eventChannelName); } -void DomainManager_impl::_local_unregisterFromEventChannel (std::string &unregisteringId, - std::string &eventChannelName) +void DomainManager_impl::_local_unregisterFromEventChannel (const std::string& unregisteringId, + const std::string& eventChannelName) { TRACE_ENTER(DomainManager_impl) @@ -2161,7 +2155,7 @@ ossie::ServiceList::iterator DomainManager_impl::_local_unregisterService(ossie: LOG_DEBUG(DomainManager_impl, "Releasing " << appsToRelease.size() << " applications"); for (std::vector::iterator iter = appsToRelease.begin(); iter != appsToRelease.end(); ++iter) { Application_impl* app = *iter; - LOG_DEBUG(DomainManager_impl, "Releasing " << ossie::corba::returnString(app->identifier())); + LOG_DEBUG(DomainManager_impl, "Releasing " << app->getIdentifier()); app->releaseObject(); app->_remove_ref(); } diff --git a/redhawk/src/control/sdr/dommgr/DomainManager_impl.h b/redhawk/src/control/sdr/dommgr/DomainManager_impl.h index a7794a03e..5430bbc89 100644 --- a/redhawk/src/control/sdr/dommgr/DomainManager_impl.h +++ b/redhawk/src/control/sdr/dommgr/DomainManager_impl.h @@ -132,11 +132,9 @@ class DomainManager_impl: public virtual POA_CF::DomainManager, public PropertyS void registerWithEventChannel (CORBA::Object_ptr registeringObject, const char* registeringId, const char* eventChannelName) throw (CF::DomainManager::AlreadyConnected, CF::DomainManager::InvalidEventChannelName, CF::InvalidObjectReference, CORBA::SystemException); - void _local_registerWithEventChannel (CORBA::Object_ptr registeringObject, std::string ®isteringId, std::string &eventChannelName); void unregisterFromEventChannel (const char* unregisteringId, const char* eventChannelName) throw (CF::DomainManager::NotConnected, CF::DomainManager::InvalidEventChannelName, CORBA::SystemException); - void _local_unregisterFromEventChannel (std::string &unregisteringId, std::string &eventChannelName); void registerRemoteDomainManager (CF::DomainManager_ptr registeringRemoteDomainManager) throw (CF::DomainManager::RegisterError, CF::InvalidObjectReference, CORBA::SystemException); @@ -250,6 +248,9 @@ class DomainManager_impl: public virtual POA_CF::DomainManager, public PropertyS ossie::DeviceList::iterator _local_unregisterDevice (ossie::DeviceList::iterator device); ossie::ServiceList::iterator _local_unregisterService (ossie::ServiceList::iterator service); + void _local_registerWithEventChannel (CORBA::Object_ptr registeringObject, const std::string& registeringId, const std::string& eventChannelName); + void _local_unregisterFromEventChannel (const std::string& unregisteringId, const std::string& eventChannelName); + void parseDMDProfile(); void storeDeviceInDomainMgr (CF::Device_ptr, CF::DeviceManager_ptr); void storeServiceInDomainMgr (CORBA::Object_ptr, CF::DeviceManager_ptr, const char*, const char*); From e5ef196d0c61fd8ed5f2b3f3cb4aa1f52179e1bf Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 25 Oct 2016 15:49:48 -0400 Subject: [PATCH 0486/1644] Move application persistence code into separate functions for ease of maintenance --- .../control/sdr/dommgr/DomainManager_impl.cpp | 173 ++++++++++-------- .../control/sdr/dommgr/DomainManager_impl.h | 3 +- 2 files changed, 94 insertions(+), 82 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp b/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp index 789c1c97c..7a0ec771e 100644 --- a/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp @@ -432,53 +432,12 @@ void DomainManager_impl::restoreState(const std::string& _db_uri) { try { if (ossie::corba::objectExists(i->context)) { LOG_TRACE(DomainManager_impl, "Creating application " << i->identifier << " " << _domainName << " " << i->contextName); - Application_impl* _application = new Application_impl (i->identifier.c_str(), - i->name.c_str(), i->profile.c_str(), - this, - i->contextName, - i->context, - i->aware_application, - CosNaming::NamingContext::_nil() ); - LOG_TRACE(DomainManager_impl, "Restored " << i->connections.size() << " connections"); - - _application->populateApplication(i->assemblyController, - i->componentDevices, - i->componentRefs, - i->connections, - i->allocationIDs); - - // Restore various state about the components in the waveform - _application->_components = i->components; - - // Add external ports - for (std::map::const_iterator it = i->ports.begin(); - it != i->ports.end(); - ++it) { - _application->addExternalPort(it->first, it->second); - } - - // Add external properties - for (std::map >::const_iterator it = i->properties.begin(); - it != i->properties.end(); - ++it) { - std::string extId = it->first; - std::string propId = it->second.first; - std::string compId = it->second.second; - std::vector comps = i->componentRefs; - comps.push_back(i->assemblyController); - for (unsigned int ii = 0; ii < comps.size(); ++ii) { - if (compId == ossie::corba::returnString(comps[ii]->identifier())) { - _application->addExternalProperty(propId, extId, comps[ii]); - break; - } - } - } - - Application_impl::Activate(_application); - addApplication(_application); - _application->_remove_ref(); + Application_impl* application = _restoreApplication(*i); + Application_impl::Activate(application); + addApplication(application); + application->_remove_ref(); - LOG_INFO(DomainManager_impl, "Restored application " << i->identifier); + LOG_INFO(DomainManager_impl, "Restored application " << application->getIdentifier()); } } CATCH_LOG_WARN(DomainManager_impl, "Failed to restore application" << i->identifier); } @@ -1781,44 +1740,10 @@ DomainManager_impl::addApplication(Application_impl* new_app) _applications[identifier] = new_app; new_app->_add_ref(); - ApplicationNode appNode; - appNode.name = new_app->getName(); - appNode.identifier = new_app->getIdentifier(); - appNode.profile = new_app->getProfile(); - appNode.contextName = new_app->_waveformContextName; - appNode.context = CosNaming::NamingContext::_duplicate(new_app->_waveformContext); - appNode.componentDevices = new_app->_componentDevices; - appNode.components = new_app->_components; - appNode.assemblyController = CF::Resource::_duplicate(new_app->assemblyController); - appNode.componentRefs.clear(); - for (unsigned int i = 0; i < new_app->_appStartSeq.size(); ++i) { - appNode.componentRefs.push_back(CF::Resource::_duplicate(new_app->_appStartSeq[i])); - } - appNode.allocationIDs = new_app->_allocationIDs; - appNode.connections = new_app->_connections; - appNode.aware_application = new_app->_isAware; - appNode.ports = new_app->_ports; - // Adds external properties - for (std::map >::const_iterator it = new_app->_properties.begin(); - it != new_app->_properties.end(); - ++it) { - std::string extId = it->first; - std::string propId = it->second.first; - std::string compId = ossie::corba::returnString(it->second.second->identifier()); - appNode.properties[extId] = std::pair(propId, compId); - } - - _runningApplications.push_back(appNode); - // Make any deferred connections dependent on this application _connectionManager.applicationRegistered(identifier); - try { - db.store("APPLICATIONS", _runningApplications); - } catch (const ossie::PersistenceException& ex) { - LOG_ERROR(DomainManager_impl, "Error persisting change to device managers"); - } - + _persistApplication(new_app); } catch (...) { ostringstream eout; eout << "Could not add new application to AppSeq; "; @@ -2524,3 +2449,89 @@ void DomainManager_impl::parseDeviceProfile (ossie::DeviceNode& node) LOG_WARN(DomainManager_impl, "Unable to find device " << node.identifier << " in DCD"); } } + +Application_impl* DomainManager_impl::_restoreApplication(ossie::ApplicationNode& node) +{ + Application_impl* application = new Application_impl(node.identifier.c_str(), + node.name.c_str(), + node.profile.c_str(), + this, + node.contextName, + node.context, + node.aware_application, + CosNaming::NamingContext::_nil()); + LOG_TRACE(DomainManager_impl, "Restored " << node.connections.size() << " connections"); + + application->populateApplication(node.assemblyController, + node.componentDevices, + node.componentRefs, + node.connections, + node.allocationIDs); + + // Restore various state about the components in the waveform + application->_components = node.components; + + // Add external ports + for (std::map::const_iterator it = node.ports.begin(); + it != node.ports.end(); + ++it) { + application->addExternalPort(it->first, it->second); + } + + // Add external properties + for (std::map >::const_iterator it = node.properties.begin(); + it != node.properties.end(); + ++it) { + std::string extId = it->first; + std::string propId = it->second.first; + std::string compId = it->second.second; + std::vector comps = node.componentRefs; + comps.push_back(node.assemblyController); + for (unsigned int ii = 0; ii < comps.size(); ++ii) { + if (compId == ossie::corba::returnString(comps[ii]->identifier())) { + application->addExternalProperty(propId, extId, comps[ii]); + break; + } + } + } + + return application; +} + +void DomainManager_impl::_persistApplication(Application_impl* application) +{ + ApplicationNode appNode; + appNode.name = application->getName(); + appNode.identifier = application->getIdentifier(); + appNode.profile = application->getProfile(); + appNode.contextName = application->_waveformContextName; + appNode.context = CosNaming::NamingContext::_duplicate(application->_waveformContext); + appNode.componentDevices = application->_componentDevices; + appNode.components = application->_components; + appNode.assemblyController = CF::Resource::_duplicate(application->assemblyController); + appNode.componentRefs.clear(); + for (unsigned int i = 0; i < application->_appStartSeq.size(); ++i) { + appNode.componentRefs.push_back(CF::Resource::_duplicate(application->_appStartSeq[i])); + } + appNode.allocationIDs = application->_allocationIDs; + appNode.connections = application->_connections; + appNode.aware_application = application->_isAware; + appNode.ports = application->_ports; + // Adds external properties + for (std::map >::const_iterator it = application->_properties.begin(); + it != application->_properties.end(); + ++it) { + std::string extId = it->first; + std::string propId = it->second.first; + std::string compId = ossie::corba::returnString(it->second.second->identifier()); + appNode.properties[extId] = std::pair(propId, compId); + } + + _runningApplications.push_back(appNode); + + try { + db.store("APPLICATIONS", _runningApplications); + } catch (const ossie::PersistenceException& ex) { + LOG_ERROR(DomainManager_impl, "Error persisting change to device managers"); + } +} diff --git a/redhawk/src/control/sdr/dommgr/DomainManager_impl.h b/redhawk/src/control/sdr/dommgr/DomainManager_impl.h index 5430bbc89..854c0b39d 100644 --- a/redhawk/src/control/sdr/dommgr/DomainManager_impl.h +++ b/redhawk/src/control/sdr/dommgr/DomainManager_impl.h @@ -311,7 +311,8 @@ class DomainManager_impl: public virtual POA_CF::DomainManager, public PropertyS ossie::ServiceList _registeredServices; std::vector < ossie::EventChannelNode > _eventChannels; - + Application_impl* _restoreApplication(ossie::ApplicationNode& node); + void _persistApplication(Application_impl* application); // // Handle to EventChannelManager for the Domain From 5f68a41c6a58374c9974d7094d1bd2df13a279e0 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 25 Oct 2016 15:55:59 -0400 Subject: [PATCH 0487/1644] Remove unnecessary use of c_str() --- .../control/sdr/dommgr/DomainManager_impl.cpp | 48 +++++++++---------- .../control/sdr/dommgr/DomainManager_impl.h | 6 +-- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp b/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp index 7a0ec771e..011d6b48f 100644 --- a/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp @@ -141,7 +141,7 @@ DomainManager_impl::DomainManager_impl (const char* dmdFile, const char* _rootpa _exit(EXIT_FAILURE); } } catch ( ... ) { - LOG_FATAL(DomainManager_impl, "Stopping domain manager; error creating new context for domain " << this->_domainName.c_str()) + LOG_FATAL(DomainManager_impl, "Stopping domain manager; error creating new context for domain " << this->_domainName); _exit(EXIT_FAILURE); } @@ -369,7 +369,7 @@ void DomainManager_impl::restoreState(const std::string& _db_uri) { LOG_INFO(DomainManager_impl, "Recovered connection to Service: " << ii->name); ossie::DeviceManagerList::iterator deviceManager = findDeviceManagerById(ii->deviceManagerId); if (deviceManager != _registeredDeviceManagers.end()) { - storeServiceInDomainMgr(ii->service, deviceManager->deviceManager, ii->name.c_str(), ii->serviceId.c_str()); + storeServiceInDomainMgr(ii->service, deviceManager->deviceManager, ii->name, ii->serviceId); } else { LOG_WARN(DomainManager_impl, "Failed to recover connection to Service: " << ii->name << ": DeviceManager " << ii->deviceManagerId << " no longer exists"); @@ -411,7 +411,7 @@ void DomainManager_impl::restoreState(const std::string& _db_uri) { for (std::set::iterator profile = restoredSADs.begin(); profile != restoredSADs.end(); ++profile) { LOG_TRACE(DomainManager_impl, "Attempting to restore application factory " << *profile); try { - _local_installApplication(profile->c_str()); + _local_installApplication(*profile); LOG_INFO(DomainManager_impl, "Restored application factory " << *profile); } CATCH_LOG_WARN(DomainManager_impl, "Failed to restore application factory " << *profile); } @@ -932,7 +932,7 @@ throw (CORBA::SystemException, CF::InvalidObjectReference, CF::InvalidProfile, std::string identifier = ossie::corba::returnString(deviceMgr->identifier()); std::string label = ossie::corba::returnString(deviceMgr->label()); - sendAddEvent( _identifier.c_str(), identifier, label, deviceMgr, StandardEvent::DEVICE_MANAGER ); + sendAddEvent(_identifier, identifier, label, deviceMgr, StandardEvent::DEVICE_MANAGER); } void DomainManager_impl::_local_registerDeviceManager (CF::DeviceManager_ptr deviceMgr) @@ -1122,7 +1122,7 @@ throw (CORBA::SystemException, CF::InvalidObjectReference, _local_unregisterDeviceManager(devMgrIter); } CATCH_LOG_ERROR(DomainManager_impl, "Exception unregistering device manager"); - sendRemoveEvent( _identifier.c_str(), identifier.c_str(), label.c_str(), StandardEvent::DEVICE_MANAGER ); + sendRemoveEvent(_identifier, identifier, label, StandardEvent::DEVICE_MANAGER); } ossie::DeviceManagerList::iterator DomainManager_impl::_local_unregisterDeviceManager (ossie::DeviceManagerList::iterator deviceManager) @@ -1238,7 +1238,7 @@ throw (CORBA::SystemException, CF::InvalidObjectReference, CF::InvalidProfile, std::string identifier = ossie::corba::returnString(registeringDevice->identifier()); std::string label = ossie::corba::returnString(registeringDevice->label()); - sendAddEvent( _identifier.c_str(), identifier, label, registeringDevice, StandardEvent::DEVICE ); + sendAddEvent(_identifier, identifier, label, registeringDevice, StandardEvent::DEVICE); } void DomainManager_impl::_local_registerDevice (CF::Device_ptr registeringDevice, @@ -1357,7 +1357,7 @@ void DomainManager_impl::storeDeviceInDomainMgr (CF::Device_ptr registeringDevic //This function adds the registeringService and its name to the DomainMgr. //if the service already exists it does nothing void -DomainManager_impl::storeServiceInDomainMgr (CORBA::Object_ptr registeringService, CF::DeviceManager_ptr registeredDeviceMgr, const char* name, const char * serviceId) +DomainManager_impl::storeServiceInDomainMgr (CORBA::Object_ptr registeringService, CF::DeviceManager_ptr registeredDeviceMgr, const std::string& name, const std::string& serviceId) { TRACE_ENTER(DomainManager_impl) boost::recursive_mutex::scoped_lock lock(stateAccess); @@ -1448,8 +1448,7 @@ ossie::DeviceList::iterator DomainManager_impl::_local_unregisterDevice (ossie:: // Sent event here (as opposed to unregisterDevice), so we see the event on regular // unregisterDevice calls, and on cleanup (deviceManager shutdown, catastropic cleanup, etc.) - sendRemoveEvent( _identifier.c_str(), (*deviceNode)->identifier.c_str(), (*deviceNode)->label.c_str(), - StandardEvent::DEVICE ); + sendRemoveEvent(_identifier, (*deviceNode)->identifier, (*deviceNode)->label, StandardEvent::DEVICE); // Remove the device from the internal list. deviceNode = _registeredDevices.erase(deviceNode); @@ -1478,7 +1477,7 @@ bool DomainManager_impl::deviceIsRegistered (CF::Device_ptr registeredDevice) } -bool DomainManager_impl::serviceIsRegistered (const char* serviceName) +bool DomainManager_impl::serviceIsRegistered (const std::string& serviceName) { TRACE_ENTER(DomainManager_impl) boost::recursive_mutex::scoped_lock lock(stateAccess); @@ -1567,11 +1566,11 @@ throw (CORBA::SystemException, const std::string& identifier = appFact->first; const std::string& name = appFact->second->getName(); CF::ApplicationFactory_var appFactRef = appFact->second->_this(); - sendAddEvent( _identifier.c_str(), identifier, name, appFactRef, StandardEvent::APPLICATION_FACTORY ); + sendAddEvent(_identifier, identifier, name, appFactRef, StandardEvent::APPLICATION_FACTORY); } } -void DomainManager_impl::_local_installApplication (const char* profileFileName) +void DomainManager_impl::_local_installApplication (const std::string& profileFileName) { TRACE_ENTER(DomainManager_impl) boost::recursive_mutex::scoped_lock lock(stateAccess); @@ -1580,11 +1579,12 @@ void DomainManager_impl::_local_installApplication (const char* profileFileName) // that is currently installed because it is the installed factory that // provides the value of profileFileName - try { - // check the profile ends with .sad.xml, warn if it doesn't - if ((strstr (profileFileName, ".sad.xml")) == NULL) - { LOG_WARN(DomainManager_impl, "File " << profileFileName << " should end with .sad.xml."); } + // check the profile ends with .sad.xml, warn if it doesn't + if (profileFileName.find(".sad.xml") == std::string::npos) { + LOG_WARN(DomainManager_impl, "File " << profileFileName << " should end with .sad.xml."); + } + try { LOG_TRACE(DomainManager_impl, "installApplication: Createing new AppFac"); ApplicationFactory_impl* appFact = new ApplicationFactory_impl(profileFileName, this->_domainName, this); const std::string& appFactoryId = appFact->getIdentifier(); @@ -1671,7 +1671,7 @@ throw (CORBA::SystemException, CF::DomainManager::InvalidIdentifier, // sourceCategory = APPLICATION_FACTORY // StandardEvent enumeration - sendRemoveEvent(_identifier.c_str(), appFactory_id.c_str(), appFactory_name.c_str(),StandardEvent::APPLICATION_FACTORY); + sendRemoveEvent(_identifier, appFactory_id, appFactory_name, StandardEvent::APPLICATION_FACTORY); } void DomainManager_impl::_local_uninstallApplication (const char* applicationId) @@ -1989,7 +1989,7 @@ void DomainManager_impl::_local_registerService (CORBA::Object_ptr registeringSe //Add registeringService and its name to domain manager try { - storeServiceInDomainMgr(registeringService, registeredDeviceMgr, name, serviceId.c_str()); + storeServiceInDomainMgr(registeringService, registeredDeviceMgr, name, serviceId); } catch ( ... ) { throw; } @@ -2019,7 +2019,7 @@ void DomainManager_impl::_local_registerService (CORBA::Object_ptr registeringSe //3. The sourceName shall be the input name parameter for the registering service. //4. The sourceIOR shall be the registered service object reference. //5. The sourceCategory shall be SERVICE. - sendAddEvent( _identifier.c_str(), serviceId.c_str(), name, registeringService, StandardEvent::SERVICE ); + sendAddEvent(_identifier, serviceId, name, registeringService, StandardEvent::SERVICE); //The registerService operation shall raise the RegisterError exception when an internal error //exists which causes an unsuccessful registration. @@ -2103,7 +2103,7 @@ ossie::ServiceList::iterator DomainManager_impl::_local_unregisterService(ossie: //4. The sourceCategory shall be SERVICE. // Sent event here (as opposed to unregisterDevice), so we see the event on regular // unregisterDevice calls, and on cleanup (deviceManager shutdown, catastropic cleanup, etc.) - sendRemoveEvent( _identifier.c_str(), serviceId.c_str(), serviceName.c_str(), StandardEvent::SERVICE ); + sendRemoveEvent(_identifier, serviceId, serviceName, StandardEvent::SERVICE); return service; } @@ -2436,7 +2436,7 @@ void DomainManager_impl::parseDeviceProfile (ossie::DeviceNode& node) dcd.load(dcd_file); } catch (const ossie::parser_error& error) { std::string parser_error_line = ossie::retrieveParserErrorLineNumber(error.what()); - LOG_WARN(DomainManager_impl, "Error parsing DCD: " << deviceManagerProfile.c_str() << " overrides for Device: " << node.identifier << ". " << parser_error_line << " The XML parser returned the following error: " << error.what()); + LOG_WARN(DomainManager_impl, "Error parsing DCD: " << deviceManagerProfile << " overrides for Device: " << node.identifier << ". " << parser_error_line << " The XML parser returned the following error: " << error.what()); } catch (...) { LOG_WARN(DomainManager_impl, "Unable to cache DCD overrides for Device: " << node.identifier); } @@ -2452,9 +2452,9 @@ void DomainManager_impl::parseDeviceProfile (ossie::DeviceNode& node) Application_impl* DomainManager_impl::_restoreApplication(ossie::ApplicationNode& node) { - Application_impl* application = new Application_impl(node.identifier.c_str(), - node.name.c_str(), - node.profile.c_str(), + Application_impl* application = new Application_impl(node.identifier, + node.name, + node.profile, this, node.contextName, node.context, diff --git a/redhawk/src/control/sdr/dommgr/DomainManager_impl.h b/redhawk/src/control/sdr/dommgr/DomainManager_impl.h index 854c0b39d..40ac7eb1d 100644 --- a/redhawk/src/control/sdr/dommgr/DomainManager_impl.h +++ b/redhawk/src/control/sdr/dommgr/DomainManager_impl.h @@ -117,7 +117,7 @@ class DomainManager_impl: public virtual POA_CF::DomainManager, public PropertyS void installApplication (const char* profileFileName) throw (CF::DomainManager::ApplicationInstallationError, CF::InvalidFileName, CF::InvalidProfile, CORBA::SystemException, CF::DomainManager::ApplicationAlreadyInstalled); - void _local_installApplication (const char* profileFileName); + void _local_installApplication (const std::string& profileFileName); void uninstallApplication (const char* applicationId) throw (CF::DomainManager::ApplicationUninstallationError, CF::DomainManager::InvalidIdentifier, CORBA::SystemException); @@ -253,11 +253,11 @@ class DomainManager_impl: public virtual POA_CF::DomainManager, public PropertyS void parseDMDProfile(); void storeDeviceInDomainMgr (CF::Device_ptr, CF::DeviceManager_ptr); - void storeServiceInDomainMgr (CORBA::Object_ptr, CF::DeviceManager_ptr, const char*, const char*); + void storeServiceInDomainMgr (CORBA::Object_ptr, CF::DeviceManager_ptr, const std::string&, const std::string&); bool deviceMgrIsRegistered (CF::DeviceManager_ptr); bool domainMgrIsRegistered (CF::DomainManager_ptr); bool deviceIsRegistered (CF::Device_ptr); - bool serviceIsRegistered (const char*); + bool serviceIsRegistered (const std::string&); void addDeviceMgr (CF::DeviceManager_ptr deviceMgr); void mountDeviceMgrFileSys (CF::DeviceManager_ptr deviceMgr); void addDomainMgr (CF::DomainManager_ptr domainMgr); From d0f06c4e0cd7ff3ffca22d4e807df17f29ea1acb Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 25 Oct 2016 16:18:51 -0400 Subject: [PATCH 0488/1644] Make persisted external properties consistent with application object --- .../control/sdr/dommgr/DomainManager_impl.cpp | 22 +++---------------- .../src/control/sdr/dommgr/PersistenceStore.h | 3 +-- 2 files changed, 4 insertions(+), 21 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp b/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp index 011d6b48f..90880ed0d 100644 --- a/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp @@ -2479,20 +2479,12 @@ Application_impl* DomainManager_impl::_restoreApplication(ossie::ApplicationNode } // Add external properties - for (std::map >::const_iterator it = node.properties.begin(); + for (std::map >::const_iterator it = node.properties.begin(); it != node.properties.end(); ++it) { std::string extId = it->first; std::string propId = it->second.first; - std::string compId = it->second.second; - std::vector comps = node.componentRefs; - comps.push_back(node.assemblyController); - for (unsigned int ii = 0; ii < comps.size(); ++ii) { - if (compId == ossie::corba::returnString(comps[ii]->identifier())) { - application->addExternalProperty(propId, extId, comps[ii]); - break; - } - } + application->addExternalProperty(propId, extId, it->second.second); } return application; @@ -2517,15 +2509,7 @@ void DomainManager_impl::_persistApplication(Application_impl* application) appNode.connections = application->_connections; appNode.aware_application = application->_isAware; appNode.ports = application->_ports; - // Adds external properties - for (std::map >::const_iterator it = application->_properties.begin(); - it != application->_properties.end(); - ++it) { - std::string extId = it->first; - std::string propId = it->second.first; - std::string compId = ossie::corba::returnString(it->second.second->identifier()); - appNode.properties[extId] = std::pair(propId, compId); - } + appNode.properties = application->_properties; _runningApplications.push_back(appNode); diff --git a/redhawk/src/control/sdr/dommgr/PersistenceStore.h b/redhawk/src/control/sdr/dommgr/PersistenceStore.h index f70aa906f..794053441 100644 --- a/redhawk/src/control/sdr/dommgr/PersistenceStore.h +++ b/redhawk/src/control/sdr/dommgr/PersistenceStore.h @@ -121,8 +121,7 @@ namespace ossie { std::vector allocationIDs; std::vector componentRefs; std::map ports; - // Ext Props map : extid -> (propid, compid) - std::map > properties; + std::map > properties; bool aware_application; }; From f00b3c791bc5b9920242475245a8e6586229cc1f Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 25 Oct 2016 16:56:09 -0400 Subject: [PATCH 0489/1644] Remove dead code --- redhawk/src/control/sdr/dommgr/Application_impl.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/redhawk/src/control/sdr/dommgr/Application_impl.cpp b/redhawk/src/control/sdr/dommgr/Application_impl.cpp index 002b8168d..3f60a9d4d 100644 --- a/redhawk/src/control/sdr/dommgr/Application_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/Application_impl.cpp @@ -944,7 +944,6 @@ throw (CORBA::SystemException, CF::LifeCycle::ReleaseError) LOG_TRACE(Application_impl, "Unbinding application naming context " << _waveformContextName); CosNaming::Name DNContextname; DNContextname.length(1); - std::string domainName = _domainManager->getDomainManagerName(); DNContextname[0].id = CORBA::string_dup(_waveformContextName.c_str()); try { if ( CORBA::is_nil(_domainContext) == false ) { From 2e9b2a9e4b51fe869ec648fa495260502098b2b4 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 26 Oct 2016 10:14:40 -0400 Subject: [PATCH 0490/1644] Link deployment objects to application components, instead of always going through the application itself --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 21 +++++----- .../control/sdr/dommgr/Application_impl.cpp | 40 +++++-------------- .../src/control/sdr/dommgr/Application_impl.h | 6 +-- redhawk/src/control/sdr/dommgr/Deployment.cpp | 29 ++++++++++---- redhawk/src/control/sdr/dommgr/Deployment.h | 12 ++++-- 5 files changed, 52 insertions(+), 56 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index b0491259d..ffc559938 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -1464,6 +1464,7 @@ void createHelper::loadAndExecuteContainers(const ContainerList& containers, if (instantiation->isNamingService()) { app_container->namingContext = _baseNamingContext + "/" + instantiation->getFindByNamingServiceName(); } + container->setApplicationComponent(app_container); // get the code.localfile LOG_TRACE(ApplicationFactory_impl, "Host is " << device->label << " Local file name is " @@ -1489,7 +1490,7 @@ void createHelper::loadAndExecuteContainers(const ContainerList& containers, LOG_TRACE(ApplicationFactory_impl, "Loading " << codeLocalFile << " and dependencies on device " << device->label); try { - container->load(_application, _appFact._fileMgr, loadabledev); + container->load(_appFact._fileMgr, loadabledev); } catch (const std::exception& exc) { throw redhawk::ComponentError(container, exc.what()); } @@ -1529,6 +1530,7 @@ void createHelper::loadAndExecuteComponents(const DeploymentList& deployments, if (instantiation->isNamingService()) { app_component->namingContext = _baseNamingContext + "/" + instantiation->getFindByNamingServiceName(); } + deployment->setApplicationComponent(app_component); // get the code.localfile LOG_TRACE(ApplicationFactory_impl, "Host is " << device->label << " Local file name is " @@ -1554,7 +1556,7 @@ void createHelper::loadAndExecuteComponents(const DeploymentList& deployments, LOG_TRACE(ApplicationFactory_impl, "Loading " << codeLocalFile << " and dependencies on device " << device->label); try { - deployment->load(_application, _appFact._fileMgr, loadabledev); + deployment->load(_appFact._fileMgr, loadabledev); } catch (const std::exception& exc) { throw redhawk::ComponentError(deployment, exc.what()); } @@ -1732,7 +1734,8 @@ void createHelper::attemptComponentExecution (CF::ApplicationRegistrar_ptr regis if (pid < 0) { throw redhawk::ExecuteError(deployment, "execute returned invalid process ID"); } else { - _application->setComponentPid(deployment->getIdentifier(), pid); + ossie::ApplicationComponent* app_component = deployment->getApplicationComponent(); + app_component->processId = pid; } } @@ -1808,9 +1811,9 @@ void createHelper::waitForContainerRegistration(redhawk::ApplicationDeployment& // Fetch the objects, finding any components that did not register BOOST_FOREACH(redhawk::ContainerDeployment* container, appDeployment.getContainerDeployments()) { - // Find the component on the Application - const std::string component_id = container->getIdentifier(); - CORBA::Object_var objref = _application->getComponentObject(component_id); + // Check that the component host registered with the application; it + // should have a valid CORBA reference + CORBA::Object_ptr objref = container->getApplicationComponent()->componentObject; if (CORBA::is_nil(objref)) { throw redhawk::ExecuteError(container, "container did not register with application"); } @@ -1873,9 +1876,9 @@ void createHelper::waitForComponentRegistration(redhawk::ApplicationDeployment& BOOST_FOREACH(redhawk::ComponentDeployment* deployment, deployments) { const SoftPkg* softpkg = deployment->getSoftPkg(); if (softpkg->isScaCompliant()) { - // Find the component on the Application - const std::string componentId = deployment->getIdentifier(); - CORBA::Object_var objref = _application->getComponentObject(componentId); + // Check that the component registered with the application; it + // should have a valid CORBA reference + CORBA::Object_ptr objref = deployment->getApplicationComponent()->componentObject; if (CORBA::is_nil(objref)) { std::string message = "component did not register with application"; message += ::getVersionMismatchMessage(softpkg); diff --git a/redhawk/src/control/sdr/dommgr/Application_impl.cpp b/redhawk/src/control/sdr/dommgr/Application_impl.cpp index 3f60a9d4d..f1177114e 100644 --- a/redhawk/src/control/sdr/dommgr/Application_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/Application_impl.cpp @@ -1266,6 +1266,15 @@ CF::DomainManager_ptr Application_impl::getComponentDomainManager () } } +ossie::ApplicationComponent* Application_impl::getComponent(const std::string& identifier) +{ + ossie::ApplicationComponent* component = findComponent(identifier); + if (!component) { + throw std::logic_error("unknown component '" + identifier + "'"); + } + return component; +} + void Application_impl::registerComponent (CF::Resource_ptr resource) { const std::string componentId = ossie::corba::returnString(resource->identifier()); @@ -1362,37 +1371,6 @@ ossie::ApplicationComponent* Application_impl::addComponent(const redhawk::Compo return &(_components.back()); } -void Application_impl::setComponentPid(const std::string& identifier, unsigned long pid) -{ - ossie::ApplicationComponent* component = findComponent(identifier); - if (!component) { - LOG_ERROR(Application_impl, "Setting process ID for unknown component '" << identifier << "'"); - } else { - component->processId = pid; - } -} - -void Application_impl::addComponentLoadedFile(const std::string& identifier, const std::string& fileName) -{ - ossie::ApplicationComponent* component = findComponent(identifier); - if (!component) { - LOG_ERROR(Application_impl, "Adding loaded file for unknown component '" << identifier << "'"); - } else { - component->loadedFiles.push_back(fileName); - } -} - -CORBA::Object_ptr Application_impl::getComponentObject(const std::string& identifier) -{ - ossie::ApplicationComponent* component = findComponent(identifier); - if (!component) { - LOG_ERROR(Application_impl, "Cannot return object for unknown component '" << identifier << "'"); - return CORBA::Object::_nil(); - } else { - return CORBA::Object::_duplicate(component->componentObject); - } -} - void Application_impl::componentTerminated(const std::string& componentId, const std::string& deviceId) { boost::mutex::scoped_lock lock(_registrationMutex); diff --git a/redhawk/src/control/sdr/dommgr/Application_impl.h b/redhawk/src/control/sdr/dommgr/Application_impl.h index 828d7f88d..9a6fa06c9 100644 --- a/redhawk/src/control/sdr/dommgr/Application_impl.h +++ b/redhawk/src/control/sdr/dommgr/Application_impl.h @@ -147,10 +147,6 @@ class Application_impl : public virtual POA_CF::Application, public Logging_impl // Set component state ossie::ApplicationComponent* addComponent(const redhawk::ComponentDeployment* deployment); ossie::ApplicationComponent* addContainer(const redhawk::ContainerDeployment* container); - void setComponentPid(const std::string& identifier, unsigned long pid); - void addComponentLoadedFile(const std::string& identifier, const std::string& fileName); - - CORBA::Object_ptr getComponentObject(const std::string& identifier); void releaseComponents(); void terminateComponents(); @@ -163,6 +159,8 @@ class Application_impl : public virtual POA_CF::Application, public Logging_impl CF::Application_ptr getComponentApplication(); CF::DomainManager_ptr getComponentDomainManager(); + ossie::ApplicationComponent* getComponent(const std::string& identifier); + private: Application_impl (); // No default constructor Application_impl(Application_impl&); // No copying diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index 0d9314f97..da3f5b75b 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -143,8 +143,8 @@ std::vector SoftPkgDeployment::getDependencyLocalFiles() return files; } -void SoftPkgDeployment::load(Application_impl* application, CF::FileSystem_ptr fileSystem, - CF::LoadableDevice_ptr device, const std::string& componentId) +void SoftPkgDeployment::load(ossie::ApplicationComponent* appComponent, CF::FileSystem_ptr fileSystem, + CF::LoadableDevice_ptr device) { if (!implementation) { throw std::logic_error("no implementation selected for soft package " + softpkg->getName()); @@ -155,7 +155,7 @@ void SoftPkgDeployment::load(Application_impl* application, CF::FileSystem_ptr f RH_NL_TRACE("ApplicationFactory_impl", "Loading " << dependencies.size() << " dependency(ies) for soft package " << softpkg->getName()); for (DeploymentList::iterator dep = dependencies.begin(); dep != dependencies.end(); ++dep) { - (*dep)->load(application, fileSystem, device, componentId); + (*dep)->load(appComponent, fileSystem, device); } } @@ -185,7 +185,7 @@ void SoftPkgDeployment::load(Application_impl* application, CF::FileSystem_ptr f message += " loading " + fileName; throw DeploymentError(message); } - application->addComponentLoadedFile(componentId, fileName); + appComponent->loadedFiles.push_back(fileName); } std::string SoftPkgDeployment::getLocalFile() @@ -249,7 +249,8 @@ ComponentDeployment::ComponentDeployment(const SoftPkg* softpkg, instantiation(instantiation), identifier(identifier), assemblyController(false), - container(0) + container(0), + appComponent(0) { // If the SoftPkg has an associated Properties, check the overrides for // validity @@ -560,10 +561,12 @@ CF::Resource_ptr ComponentDeployment::getResourcePtr() const return CF::Resource::_duplicate(resource); } -void ComponentDeployment::load(Application_impl* application, CF::FileSystem_ptr fileSystem, - CF::LoadableDevice_ptr device) +void ComponentDeployment::load(CF::FileSystem_ptr fileSystem, CF::LoadableDevice_ptr device) { - SoftPkgDeployment::load(application, fileSystem, device, identifier); + if (!appComponent) { + throw std::logic_error("deployment is not assigned to an application component"); + } + SoftPkgDeployment::load(appComponent, fileSystem, device); } std::string ComponentDeployment::getLoggingConfiguration() const @@ -603,6 +606,16 @@ std::string ComponentDeployment::getLoggingConfiguration() const return std::string(); } +ossie::ApplicationComponent* ComponentDeployment::getApplicationComponent() +{ + return appComponent; +} + +void ComponentDeployment::setApplicationComponent(ossie::ApplicationComponent* component) +{ + appComponent = component; +} + void ComponentDeployment::initializeProperties() { redhawk::PropertyMap init_props = getInitializeProperties(); diff --git a/redhawk/src/control/sdr/dommgr/Deployment.h b/redhawk/src/control/sdr/dommgr/Deployment.h index fa4144ae6..d2e7d9558 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.h +++ b/redhawk/src/control/sdr/dommgr/Deployment.h @@ -89,8 +89,8 @@ namespace redhawk { std::vector getDependencyLocalFiles(); protected: - void load(Application_impl* application, CF::FileSystem_ptr fileSystem, - CF::LoadableDevice_ptr device, const std::string& componentId); + void load(ossie::ApplicationComponent* appComponent, CF::FileSystem_ptr fileSystem, + CF::LoadableDevice_ptr device); const ossie::SoftPkg* softpkg; const ossie::SPD::Implementation* implementation; @@ -155,11 +155,13 @@ namespace redhawk { void setResourcePtr(CF::Resource_ptr resource); CF::Resource_ptr getResourcePtr() const; - void load(Application_impl* application, CF::FileSystem_ptr fileSystem, - CF::LoadableDevice_ptr device); + void load(CF::FileSystem_ptr fileSystem, CF::LoadableDevice_ptr device); std::string getLoggingConfiguration() const; + ossie::ApplicationComponent* getApplicationComponent(); + void setApplicationComponent(ossie::ApplicationComponent* appComponent); + /** * @brief Initializes the deployed component * @exception ossie::properties_error invalid properties in property @@ -206,6 +208,8 @@ namespace redhawk { ComponentDeployment* container; CF::Resource_var resource; + ossie::ApplicationComponent* appComponent; + redhawk::PropertyMap overrides; std::string nicAssignment; ossie::optional_value cpuReservation; From e99f7c2917105e5395c87f32db887701f0861271 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 26 Oct 2016 11:18:26 -0400 Subject: [PATCH 0491/1644] Create split between a functional ApplicationComponent object and a POD ComponentNode (for serialization), to enable moving functionality from the Application object to the former --- .../sdr/dommgr/ApplicationComponent.cpp | 44 ++++++++ .../control/sdr/dommgr/ApplicationComponent.h | 52 +++++++++ .../sdr/dommgr/ApplicationFactory_impl.cpp | 8 +- .../control/sdr/dommgr/Application_impl.cpp | 100 ++++++++---------- .../src/control/sdr/dommgr/Application_impl.h | 13 +-- redhawk/src/control/sdr/dommgr/Deployment.cpp | 6 +- redhawk/src/control/sdr/dommgr/Deployment.h | 12 +-- .../control/sdr/dommgr/DomainManager_impl.cpp | 33 +++++- redhawk/src/control/sdr/dommgr/Makefile.am | 1 + .../src/control/sdr/dommgr/PersistenceStore.h | 6 +- 10 files changed, 195 insertions(+), 80 deletions(-) create mode 100644 redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp create mode 100644 redhawk/src/control/sdr/dommgr/ApplicationComponent.h diff --git a/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp b/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp new file mode 100644 index 000000000..541399152 --- /dev/null +++ b/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp @@ -0,0 +1,44 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK core. + * + * REDHAWK core is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +#include "ApplicationComponent.h" + +using redhawk::ApplicationComponent; + +ApplicationComponent::ApplicationComponent(const std::string& identifier) : + _identifier(identifier), + _processId(0) +{ +} + +const std::string& ApplicationComponent::getIdentifier() const +{ + return _identifier; +} + +unsigned long ApplicationComponent::getProcessId() const +{ + return _processId; +} + +void ApplicationComponent::setProcessId(unsigned long processId) +{ + _processId = processId; +} diff --git a/redhawk/src/control/sdr/dommgr/ApplicationComponent.h b/redhawk/src/control/sdr/dommgr/ApplicationComponent.h new file mode 100644 index 000000000..37b1309f2 --- /dev/null +++ b/redhawk/src/control/sdr/dommgr/ApplicationComponent.h @@ -0,0 +1,52 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK core. + * + * REDHAWK core is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +#ifndef APPLICATIONCOMPONENT_H +#define APPLICATIONCOMPONENT_H + +#include +#include + +#include + +namespace redhawk { + struct ApplicationComponent { + ApplicationComponent(const std::string& identifier); + + const std::string& getIdentifier() const; + + unsigned long getProcessId() const; + void setProcessId(unsigned long processId); + + std::string softwareProfile; + std::string namingContext; + std::string implementationId; + std::vector loadedFiles; + CORBA::Object_var componentObject; + CF::Device_var assignedDevice; + bool isContainer; + + private: + std::string _identifier; + unsigned long _processId; + }; +} + +#endif // APPLICATIONCOMPONENT_H diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index ffc559938..192dc57a8 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -1459,7 +1459,7 @@ void createHelper::loadAndExecuteContainers(const ContainerList& containers, } // Let the application know to expect the given component - ossie::ApplicationComponent* app_container = _application->addContainer(container); + redhawk::ApplicationComponent* app_container = _application->addContainer(container); const ossie::ComponentInstantiation* instantiation = container->getInstantiation(); if (instantiation->isNamingService()) { app_container->namingContext = _baseNamingContext + "/" + instantiation->getFindByNamingServiceName(); @@ -1525,7 +1525,7 @@ void createHelper::loadAndExecuteComponents(const DeploymentList& deployments, << "' (" << device->identifier << ")"); // Let the application know to expect the given component - ossie::ApplicationComponent* app_component = _application->addComponent(deployment); + redhawk::ApplicationComponent* app_component = _application->addComponent(deployment); const ossie::ComponentInstantiation* instantiation = deployment->getInstantiation(); if (instantiation->isNamingService()) { app_component->namingContext = _baseNamingContext + "/" + instantiation->getFindByNamingServiceName(); @@ -1734,8 +1734,8 @@ void createHelper::attemptComponentExecution (CF::ApplicationRegistrar_ptr regis if (pid < 0) { throw redhawk::ExecuteError(deployment, "execute returned invalid process ID"); } else { - ossie::ApplicationComponent* app_component = deployment->getApplicationComponent(); - app_component->processId = pid; + redhawk::ApplicationComponent* app_component = deployment->getApplicationComponent(); + app_component->setProcessId(pid); } } diff --git a/redhawk/src/control/sdr/dommgr/Application_impl.cpp b/redhawk/src/control/sdr/dommgr/Application_impl.cpp index f1177114e..cbe9ab686 100644 --- a/redhawk/src/control/sdr/dommgr/Application_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/Application_impl.cpp @@ -39,49 +39,49 @@ PREPARE_CF_LOGGING(Application_impl); using namespace ossie; namespace { - CF::Application::ComponentElementType to_impl_element(const ossie::ApplicationComponent& component) + CF::Application::ComponentElementType to_impl_element(const redhawk::ApplicationComponent& component) { CF::Application::ComponentElementType result; - result.componentId = component.identifier.c_str(); + result.componentId = component.getIdentifier().c_str(); result.elementId = component.implementationId.c_str(); return result; } - bool has_naming_context(const ossie::ApplicationComponent& component) + bool has_naming_context(const redhawk::ApplicationComponent& component) { return !component.namingContext.empty(); } - CF::Application::ComponentElementType to_name_element(const ossie::ApplicationComponent& component) + CF::Application::ComponentElementType to_name_element(const redhawk::ApplicationComponent& component) { CF::Application::ComponentElementType result; - result.componentId = component.identifier.c_str(); + result.componentId = component.getIdentifier().c_str(); result.elementId = component.namingContext.c_str(); return result; } - CF::Application::ComponentProcessIdType to_pid_type(const ossie::ApplicationComponent& component) + CF::Application::ComponentProcessIdType to_pid_type(const redhawk::ApplicationComponent& component) { CF::Application::ComponentProcessIdType result; - result.componentId = component.identifier.c_str(); - result.processId = component.processId; + result.componentId = component.getIdentifier().c_str(); + result.processId = component.getProcessId(); return result; } - bool is_registered(const ossie::ApplicationComponent& component) + bool is_registered(const redhawk::ApplicationComponent& component) { return !CORBA::is_nil(component.componentObject); } - bool is_terminated(const ossie::ApplicationComponent& component) + bool is_terminated(const redhawk::ApplicationComponent& component) { - return (component.processId == 0); + return (component.getProcessId() == 0); } - CF::ComponentType to_component_type(const ossie::ApplicationComponent& component) + CF::ComponentType to_component_type(const redhawk::ApplicationComponent& component) { CF::ComponentType result; - result.identifier = component.identifier.c_str(); + result.identifier = component.getIdentifier().c_str(); result.softwareProfile = component.softwareProfile.c_str(); result.type = CF::APPLICATION_COMPONENT; result.componentObject = CORBA::Object::_duplicate(component.componentObject); @@ -761,7 +761,7 @@ CF::PortSet::PortInfoSequence* Application_impl::getPortSet () { CF::PortSet::PortInfoSequence_var retval = new CF::PortSet::PortInfoSequence(); std::vector comp_portsets; - for (ossie::ComponentList::iterator _component_iter=this->_components.begin(); _component_iter!=this->_components.end(); _component_iter++) { + for (ComponentList::iterator _component_iter=this->_components.begin(); _component_iter!=this->_components.end(); _component_iter++) { try { CF::Resource_ptr comp = CF::Resource::_narrow(_component_iter->componentObject); comp_portsets.push_back(comp->getPortSet()); @@ -902,9 +902,7 @@ throw (CORBA::SystemException, CF::LifeCycle::ReleaseError) // - unbind from NS // - release each component // - unload and deallocate - for (ossie::ComponentList::iterator ii = _components.begin(); ii != _components.end(); ++ii) { - - const std::string id = ii->identifier; + for (ComponentList::iterator ii = _components.begin(); ii != _components.end(); ++ii) { if (!ii->namingContext.empty()) { std::string componentName = ii->namingContext; @@ -997,54 +995,54 @@ throw (CORBA::SystemException, CF::LifeCycle::ReleaseError) void Application_impl::releaseComponents() { - for (ossie::ComponentList::iterator ii = _components.begin(); ii != _components.end(); ++ii) { + for (ComponentList::iterator ii = _components.begin(); ii != _components.end(); ++ii) { if (ii->isContainer || CORBA::is_nil(ii->componentObject)) { // Ignore components that never registered continue; } - LOG_DEBUG(Application_impl, "Releasing component '" << ii->identifier << "'"); + LOG_DEBUG(Application_impl, "Releasing component '" << ii->getIdentifier() << "'"); try { CF::Resource_var resource = CF::Resource::_narrow(ii->componentObject); unsigned long timeout = 3; // seconds omniORB::setClientCallTimeout(resource, timeout * 1000); resource->releaseObject(); - } CATCH_LOG_WARN(Application_impl, "releaseObject failed for component '" << ii->identifier << "'"); + } CATCH_LOG_WARN(Application_impl, "releaseObject failed for component '" << ii->getIdentifier() << "'"); } - for (ossie::ComponentList::iterator ii = _components.begin(); ii != _components.end(); ++ii) { + for (ComponentList::iterator ii = _components.begin(); ii != _components.end(); ++ii) { if (!(ii->isContainer) || CORBA::is_nil(ii->componentObject)) { // Ignore components that never registered continue; } - LOG_DEBUG(Application_impl, "Releasing container '" << ii->identifier << "'"); + LOG_DEBUG(Application_impl, "Releasing container '" << ii->getIdentifier() << "'"); try { CF::Resource_var resource = CF::Resource::_narrow(ii->componentObject); unsigned long timeout = 3; // seconds omniORB::setClientCallTimeout(resource, timeout * 1000); resource->releaseObject(); - } CATCH_LOG_WARN(Application_impl, "releaseObject failed for component '" << ii->identifier << "'"); + } CATCH_LOG_WARN(Application_impl, "releaseObject failed for component '" << ii->getIdentifier() << "'"); } } void Application_impl::terminateComponents() { // Terminate any components that were executed on devices - for (ossie::ComponentList::iterator ii = _components.begin(); ii != _components.end(); ++ii) { - const unsigned long pid = ii->processId; + for (ComponentList::iterator ii = _components.begin(); ii != _components.end(); ++ii) { + const unsigned long pid = ii->getProcessId(); if (pid == 0 || pid >= 65536) { continue; } - LOG_DEBUG(Application_impl, "Terminating component '" << ii->identifier << "' pid " << pid); + LOG_DEBUG(Application_impl, "Terminating component '" << ii->getIdentifier() << "' pid " << pid); CF::ExecutableDevice_var device = ossie::corba::_narrowSafe(ii->assignedDevice); if (CORBA::is_nil(device)) { - LOG_WARN(Application_impl, "Cannot find device to terminate component " << ii->identifier); + LOG_WARN(Application_impl, "Cannot find device to terminate component " << ii->getIdentifier()); } else { try { - device->terminate(ii->processId); + device->terminate(pid); } CATCH_LOG_WARN(Application_impl, "Unable to terminate process " << pid); } } @@ -1053,17 +1051,17 @@ void Application_impl::terminateComponents() void Application_impl::unloadComponents() { // Terminate any components that were executed on devices - for (ossie::ComponentList::iterator ii = _components.begin(); ii != _components.end(); ++ii) { + for (ComponentList::iterator ii = _components.begin(); ii != _components.end(); ++ii) { if (ii->loadedFiles.empty()) { continue; } LOG_DEBUG(Application_impl, "Unloading " << ii->loadedFiles.size() << " file(s) for component '" - << ii->identifier << "'"); + << ii->getIdentifier() << "'"); CF::LoadableDevice_var device = ossie::corba::_narrowSafe(ii->assignedDevice); if (CORBA::is_nil(device)) { - LOG_WARN(Application_impl, "Cannot find device to unload files for component " << ii->identifier); + LOG_WARN(Application_impl, "Cannot find device to unload files for component " << ii->getIdentifier()); continue; } @@ -1222,11 +1220,11 @@ bool Application_impl::checkConnectionDependency (Endpoint::DependencyType type, bool Application_impl::_checkRegistrations (std::set& identifiers) { - for (ossie::ComponentList::iterator ii = _components.begin(); ii != _components.end(); ++ii) { + for (ComponentList::iterator ii = _components.begin(); ii != _components.end(); ++ii) { if (is_registered(*ii)) { - identifiers.erase(ii->identifier); + identifiers.erase(ii->getIdentifier()); } else if (is_terminated(*ii)) { - throw redhawk::ComponentTerminated(ii->identifier); + throw redhawk::ComponentTerminated(ii->getIdentifier()); } } return identifiers.empty(); @@ -1266,9 +1264,9 @@ CF::DomainManager_ptr Application_impl::getComponentDomainManager () } } -ossie::ApplicationComponent* Application_impl::getComponent(const std::string& identifier) +redhawk::ApplicationComponent* Application_impl::getComponent(const std::string& identifier) { - ossie::ApplicationComponent* component = findComponent(identifier); + redhawk::ApplicationComponent* component = findComponent(identifier); if (!component) { throw std::logic_error("unknown component '" + identifier + "'"); } @@ -1282,16 +1280,14 @@ void Application_impl::registerComponent (CF::Resource_ptr resource) boost::mutex::scoped_lock lock(_registrationMutex); - ossie::ApplicationComponent* comp = findComponent(componentId); + redhawk::ApplicationComponent* comp = findComponent(componentId); if (!comp) { LOG_WARN(Application_impl, "Unexpected component '" << componentId << "' registered with application '" << _appName << "'"); - _components.push_back(ossie::ApplicationComponent()); + _components.push_back(redhawk::ApplicationComponent(componentId)); comp = &(_components.back()); - comp->identifier = componentId; comp->softwareProfile = softwareProfile; - comp->processId = 0; } else if (softwareProfile != comp->softwareProfile) { // Mismatch between expected and reported SPD path LOG_WARN(Application_impl, "Component '" << componentId << "' software profile " << softwareProfile @@ -1299,7 +1295,7 @@ void Application_impl::registerComponent (CF::Resource_ptr resource) comp->softwareProfile = softwareProfile; } - LOG_TRACE(Application_impl, "REGISTERING Component '" << componentId << "' software profile " << softwareProfile << " pid:" << comp->processId ); + LOG_TRACE(Application_impl, "REGISTERING Component '" << componentId << "' software profile " << softwareProfile << " pid:" << comp->getProcessId()); comp->componentObject = CORBA::Object::_duplicate(resource); _registrationCondition.notify_all(); } @@ -1322,10 +1318,10 @@ std::string Application_impl::getExternalPropertyId(std::string compIdIn, std::s return ""; } -ossie::ApplicationComponent* Application_impl::findComponent(const std::string& identifier) +redhawk::ApplicationComponent* Application_impl::findComponent(const std::string& identifier) { - for (ossie::ComponentList::iterator ii = _components.begin(); ii != _components.end(); ++ii) { - if (identifier == ii->identifier) { + for (ComponentList::iterator ii = _components.begin(); ii != _components.end(); ++ii) { + if (identifier == ii->getIdentifier()) { return &(*ii); } } @@ -1333,7 +1329,7 @@ ossie::ApplicationComponent* Application_impl::findComponent(const std::string& return 0; } -ossie::ApplicationComponent* Application_impl::addContainer(const redhawk::ContainerDeployment* container) +redhawk::ApplicationComponent* Application_impl::addContainer(const redhawk::ContainerDeployment* container) { const std::string& identifier = container->getIdentifier(); if (findComponent(identifier)) { @@ -1341,10 +1337,8 @@ ossie::ApplicationComponent* Application_impl::addContainer(const redhawk::Conta } const std::string& profile = container->getSoftPkg()->getSPDFile(); LOG_DEBUG(Application_impl, "Adding container '" << identifier << "' with profile " << profile); - ossie::ApplicationComponent component; - component.identifier = identifier; + redhawk::ApplicationComponent component(identifier); component.softwareProfile = profile; - component.processId = 0; component.isContainer = true; component.implementationId = container->getImplementation()->getID(); component.assignedDevice = CF::Device::_duplicate(container->getAssignedDevice()->device); @@ -1352,7 +1346,7 @@ ossie::ApplicationComponent* Application_impl::addContainer(const redhawk::Conta return &(_components.back()); } -ossie::ApplicationComponent* Application_impl::addComponent(const redhawk::ComponentDeployment* deployment) +redhawk::ApplicationComponent* Application_impl::addComponent(const redhawk::ComponentDeployment* deployment) { const std::string& identifier = deployment->getIdentifier(); if (findComponent(identifier)) { @@ -1360,10 +1354,8 @@ ossie::ApplicationComponent* Application_impl::addComponent(const redhawk::Compo } const std::string& profile = deployment->getSoftPkg()->getSPDFile(); LOG_DEBUG(Application_impl, "Adding component '" << identifier << "' with profile " << profile); - ossie::ApplicationComponent component; - component.identifier = identifier; + redhawk::ApplicationComponent component(identifier); component.softwareProfile = profile; - component.processId = 0; component.isContainer = false; component.implementationId = deployment->getImplementation()->getID(); component.assignedDevice = CF::Device::_duplicate(deployment->getAssignedDevice()->device); @@ -1374,7 +1366,7 @@ ossie::ApplicationComponent* Application_impl::addComponent(const redhawk::Compo void Application_impl::componentTerminated(const std::string& componentId, const std::string& deviceId) { boost::mutex::scoped_lock lock(_registrationMutex); - ossie::ApplicationComponent* component = findComponent(componentId); + redhawk::ApplicationComponent* component = findComponent(componentId); if (!component) { LOG_WARN(Application_impl, "Unrecognized component '" << componentId << "' from application '" << _identifier << "' terminated abnormally on device " << deviceId); @@ -1387,6 +1379,6 @@ void Application_impl::componentTerminated(const std::string& componentId, const LOG_WARN(Application_impl, "Component '" << componentId << "' from application '" << _identifier << "' terminated abnormally on device " << deviceId); } - component->processId = 0; + component->setProcessId(0); _registrationCondition.notify_all(); } diff --git a/redhawk/src/control/sdr/dommgr/Application_impl.h b/redhawk/src/control/sdr/dommgr/Application_impl.h index 9a6fa06c9..f68957ccb 100644 --- a/redhawk/src/control/sdr/dommgr/Application_impl.h +++ b/redhawk/src/control/sdr/dommgr/Application_impl.h @@ -36,7 +36,7 @@ #include "ApplicationDeployment.h" #include "PersistenceStore.h" #include "connectionSupport.h" - +#include "ApplicationComponent.h" class DomainManager_impl; class ApplicationRegistrar_impl; @@ -145,8 +145,8 @@ class Application_impl : public virtual POA_CF::Application, public Logging_impl void _cleanupActivations(); // Set component state - ossie::ApplicationComponent* addComponent(const redhawk::ComponentDeployment* deployment); - ossie::ApplicationComponent* addContainer(const redhawk::ContainerDeployment* container); + redhawk::ApplicationComponent* addComponent(const redhawk::ComponentDeployment* deployment); + redhawk::ApplicationComponent* addContainer(const redhawk::ContainerDeployment* container); void releaseComponents(); void terminateComponents(); @@ -159,7 +159,7 @@ class Application_impl : public virtual POA_CF::Application, public Logging_impl CF::Application_ptr getComponentApplication(); CF::DomainManager_ptr getComponentDomainManager(); - ossie::ApplicationComponent* getComponent(const std::string& identifier); + redhawk::ApplicationComponent* getComponent(const std::string& identifier); private: Application_impl (); // No default constructor @@ -198,7 +198,8 @@ class Application_impl : public virtual POA_CF::Application, public Logging_impl ApplicationRegistrar_impl* _registrar; - ossie::ComponentList _components; + typedef std::list ComponentList; + ComponentList _components; CosNaming::NamingContext_var _domainContext; boost::mutex _registrationMutex; @@ -212,7 +213,7 @@ class Application_impl : public virtual POA_CF::Application, public Logging_impl PropertyChangeRegistry _propertyChangeRegistrations; - ossie::ApplicationComponent* findComponent(const std::string& identifier); + redhawk::ApplicationComponent* findComponent(const std::string& identifier); // Returns externalpropid if one exists based off of compId and // internal propId, returns empty string if no external prop exists diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index da3f5b75b..85ab28daf 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -143,7 +143,7 @@ std::vector SoftPkgDeployment::getDependencyLocalFiles() return files; } -void SoftPkgDeployment::load(ossie::ApplicationComponent* appComponent, CF::FileSystem_ptr fileSystem, +void SoftPkgDeployment::load(redhawk::ApplicationComponent* appComponent, CF::FileSystem_ptr fileSystem, CF::LoadableDevice_ptr device) { if (!implementation) { @@ -606,12 +606,12 @@ std::string ComponentDeployment::getLoggingConfiguration() const return std::string(); } -ossie::ApplicationComponent* ComponentDeployment::getApplicationComponent() +redhawk::ApplicationComponent* ComponentDeployment::getApplicationComponent() { return appComponent; } -void ComponentDeployment::setApplicationComponent(ossie::ApplicationComponent* component) +void ComponentDeployment::setApplicationComponent(redhawk::ApplicationComponent* component) { appComponent = component; } diff --git a/redhawk/src/control/sdr/dommgr/Deployment.h b/redhawk/src/control/sdr/dommgr/Deployment.h index d2e7d9558..dd6e5c19e 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.h +++ b/redhawk/src/control/sdr/dommgr/Deployment.h @@ -29,10 +29,10 @@ #include #include "PersistenceStore.h" -class Application_impl; - namespace redhawk { + class ApplicationComponent; + class UsesDeviceAssignment { public: @@ -89,7 +89,7 @@ namespace redhawk { std::vector getDependencyLocalFiles(); protected: - void load(ossie::ApplicationComponent* appComponent, CF::FileSystem_ptr fileSystem, + void load(redhawk::ApplicationComponent* appComponent, CF::FileSystem_ptr fileSystem, CF::LoadableDevice_ptr device); const ossie::SoftPkg* softpkg; @@ -159,8 +159,8 @@ namespace redhawk { std::string getLoggingConfiguration() const; - ossie::ApplicationComponent* getApplicationComponent(); - void setApplicationComponent(ossie::ApplicationComponent* appComponent); + redhawk::ApplicationComponent* getApplicationComponent(); + void setApplicationComponent(redhawk::ApplicationComponent* appComponent); /** * @brief Initializes the deployed component @@ -208,7 +208,7 @@ namespace redhawk { ComponentDeployment* container; CF::Resource_var resource; - ossie::ApplicationComponent* appComponent; + redhawk::ApplicationComponent* appComponent; redhawk::PropertyMap overrides; std::string nicAssignment; diff --git a/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp b/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp index 90880ed0d..877a82085 100644 --- a/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp @@ -27,6 +27,8 @@ #include #include +#include + #include #include #include @@ -2126,8 +2128,8 @@ CF::Resource_ptr DomainManager_impl::lookupComponentByInstantiationId(const std: return CF::Resource::_nil(); } std::string normalized_comp_id = identifier.substr(0,pos)+std::string(":")+appid.substr(appid.rfind(":")+1); - for (ossie::ComponentList::iterator _comp=_applications[appid]->_components.begin(); _comp!=_applications[appid]->_components.end(); _comp++) {\ - if (normalized_comp_id == _comp->identifier) { + for (Application_impl::ComponentList::iterator _comp=_applications[appid]->_components.begin(); _comp!=_applications[appid]->_components.end(); _comp++) {\ + if (normalized_comp_id == _comp->getIdentifier()) { return CF::Resource::_duplicate(CF::Resource::_narrow(_comp->componentObject)); } } @@ -2469,7 +2471,18 @@ Application_impl* DomainManager_impl::_restoreApplication(ossie::ApplicationNode node.allocationIDs); // Restore various state about the components in the waveform - application->_components = node.components; + BOOST_FOREACH(ossie::ComponentNode& compNode, node.components) { + redhawk::ApplicationComponent component(compNode.identifier); + component.softwareProfile = compNode.softwareProfile; + component.namingContext = compNode.namingContext; + component.implementationId = compNode.implementationId; + component.loadedFiles = compNode.loadedFiles; + component.setProcessId(compNode.processId); + component.componentObject = CORBA::Object::_duplicate(compNode.componentObject); + component.assignedDevice = compNode.assignedDevice; + component.isContainer = compNode.isContainer; + application->_components.push_back(component); + } // Add external ports for (std::map::const_iterator it = node.ports.begin(); @@ -2499,7 +2512,19 @@ void DomainManager_impl::_persistApplication(Application_impl* application) appNode.contextName = application->_waveformContextName; appNode.context = CosNaming::NamingContext::_duplicate(application->_waveformContext); appNode.componentDevices = application->_componentDevices; - appNode.components = application->_components; + BOOST_FOREACH(redhawk::ApplicationComponent& component, application->_components) { + ossie::ComponentNode compNode; + compNode.identifier = component.getIdentifier(); + compNode.softwareProfile = component.softwareProfile; + compNode.namingContext = component.namingContext; + compNode.implementationId = component.implementationId; + compNode.loadedFiles = component.loadedFiles; + compNode.processId = component.getProcessId(); + compNode.componentObject = CORBA::Object::_duplicate(component.componentObject); + compNode.assignedDevice = component.assignedDevice; + compNode.isContainer = component.isContainer; + appNode.components.push_back(compNode); + } appNode.assemblyController = CF::Resource::_duplicate(application->assemblyController); appNode.componentRefs.clear(); for (unsigned int i = 0; i < application->_appStartSeq.size(); ++i) { diff --git a/redhawk/src/control/sdr/dommgr/Makefile.am b/redhawk/src/control/sdr/dommgr/Makefile.am index a0c733ae2..e2dcc377d 100644 --- a/redhawk/src/control/sdr/dommgr/Makefile.am +++ b/redhawk/src/control/sdr/dommgr/Makefile.am @@ -37,6 +37,7 @@ DomainManager_SOURCES = connectionSupport.cpp \ DeploymentExceptions.cpp \ ApplicationDeployment.cpp \ ApplicationValidator.cpp \ + ApplicationComponent.cpp \ ProfileCache.cpp \ main.cpp DomainManager_CPPFLAGS = -I../../include -I../../parser -I$(top_srcdir)/base/include -I$(top_srcdir)/base $(BOOST_CPPFLAGS) $(OMNIORB_CFLAGS) $(LOG4CXX_FLAGS) diff --git a/redhawk/src/control/sdr/dommgr/PersistenceStore.h b/redhawk/src/control/sdr/dommgr/PersistenceStore.h index 794053441..9ba57188b 100644 --- a/redhawk/src/control/sdr/dommgr/PersistenceStore.h +++ b/redhawk/src/control/sdr/dommgr/PersistenceStore.h @@ -95,7 +95,7 @@ namespace ossie { typedef std::map AllocationTable; typedef std::map RemoteAllocationTable; - struct ApplicationComponent { + struct ComponentNode { std::string identifier; std::string softwareProfile; std::string namingContext; @@ -106,7 +106,7 @@ namespace ossie { CF::Device_var assignedDevice; bool isContainer; }; - typedef std::list ComponentList; + typedef std::list ComponentList; struct ApplicationNode { std::string name; @@ -252,7 +252,7 @@ namespace boost { } template - void serialize(Archive& ar, ossie::ApplicationComponent& node, const unsigned int version) { + void serialize(Archive& ar, ossie::ComponentNode& node, const unsigned int version) { ar & node.identifier; ar & node.softwareProfile; ar & node.namingContext; From 536adc05c31c0ca565c51365f539080ce50e1d76 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 26 Oct 2016 12:10:56 -0400 Subject: [PATCH 0492/1644] Move CORBA reference management into ApplicationComponent and encapsulate naming context --- .../sdr/dommgr/ApplicationComponent.cpp | 40 +++++++++++++++++ .../control/sdr/dommgr/ApplicationComponent.h | 16 ++++++- .../sdr/dommgr/ApplicationFactory_impl.cpp | 8 ++-- .../control/sdr/dommgr/Application_impl.cpp | 45 +++++++------------ .../control/sdr/dommgr/DomainManager_impl.cpp | 10 ++--- 5 files changed, 79 insertions(+), 40 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp b/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp index 541399152..17c6c36fb 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp @@ -42,3 +42,43 @@ void ApplicationComponent::setProcessId(unsigned long processId) { _processId = processId; } + +bool ApplicationComponent::isTerminated() const +{ + return (_processId == 0); +} + +bool ApplicationComponent::isRegistered() const +{ + return !CORBA::is_nil(_componentObject); +} + +CORBA::Object_ptr ApplicationComponent::getComponentObject() const +{ + return CORBA::Object::_duplicate(_componentObject); +} + +void ApplicationComponent::setComponentObject(CORBA::Object_ptr object) +{ + _componentObject = CORBA::Object::_duplicate(object); +} + +CF::Resource_ptr ApplicationComponent::getResourcePtr() const +{ + return CF::Resource::_narrow(_componentObject); +} + +bool ApplicationComponent::hasNamingContext() const +{ + return !_namingContext.empty(); +} + +const std::string& ApplicationComponent::getNamingContext() const +{ + return _namingContext; +} + +void ApplicationComponent::setNamingContext(const std::string& namingContext) +{ + _namingContext = namingContext; +} diff --git a/redhawk/src/control/sdr/dommgr/ApplicationComponent.h b/redhawk/src/control/sdr/dommgr/ApplicationComponent.h index 37b1309f2..33b3e96ab 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationComponent.h +++ b/redhawk/src/control/sdr/dommgr/ApplicationComponent.h @@ -35,17 +35,29 @@ namespace redhawk { unsigned long getProcessId() const; void setProcessId(unsigned long processId); + bool isTerminated() const; + bool isRegistered() const; + + CORBA::Object_ptr getComponentObject() const; + void setComponentObject(CORBA::Object_ptr object); + + CF::Resource_ptr getResourcePtr() const; + + bool hasNamingContext() const; + const std::string& getNamingContext() const; + void setNamingContext(const std::string& namingContext); + std::string softwareProfile; - std::string namingContext; std::string implementationId; std::vector loadedFiles; - CORBA::Object_var componentObject; CF::Device_var assignedDevice; bool isContainer; private: std::string _identifier; + std::string _namingContext; unsigned long _processId; + CORBA::Object_var _componentObject; }; } diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 192dc57a8..f03137307 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -1462,7 +1462,7 @@ void createHelper::loadAndExecuteContainers(const ContainerList& containers, redhawk::ApplicationComponent* app_container = _application->addContainer(container); const ossie::ComponentInstantiation* instantiation = container->getInstantiation(); if (instantiation->isNamingService()) { - app_container->namingContext = _baseNamingContext + "/" + instantiation->getFindByNamingServiceName(); + app_container->setNamingContext(_baseNamingContext + "/" + instantiation->getFindByNamingServiceName()); } container->setApplicationComponent(app_container); @@ -1528,7 +1528,7 @@ void createHelper::loadAndExecuteComponents(const DeploymentList& deployments, redhawk::ApplicationComponent* app_component = _application->addComponent(deployment); const ossie::ComponentInstantiation* instantiation = deployment->getInstantiation(); if (instantiation->isNamingService()) { - app_component->namingContext = _baseNamingContext + "/" + instantiation->getFindByNamingServiceName(); + app_component->setNamingContext(_baseNamingContext + "/" + instantiation->getFindByNamingServiceName()); } deployment->setApplicationComponent(app_component); @@ -1813,7 +1813,7 @@ void createHelper::waitForContainerRegistration(redhawk::ApplicationDeployment& BOOST_FOREACH(redhawk::ContainerDeployment* container, appDeployment.getContainerDeployments()) { // Check that the component host registered with the application; it // should have a valid CORBA reference - CORBA::Object_ptr objref = container->getApplicationComponent()->componentObject; + CORBA::Object_ptr objref = container->getApplicationComponent()->getComponentObject(); if (CORBA::is_nil(objref)) { throw redhawk::ExecuteError(container, "container did not register with application"); } @@ -1878,7 +1878,7 @@ void createHelper::waitForComponentRegistration(redhawk::ApplicationDeployment& if (softpkg->isScaCompliant()) { // Check that the component registered with the application; it // should have a valid CORBA reference - CORBA::Object_ptr objref = deployment->getApplicationComponent()->componentObject; + CORBA::Object_ptr objref = deployment->getApplicationComponent()->getComponentObject(); if (CORBA::is_nil(objref)) { std::string message = "component did not register with application"; message += ::getVersionMismatchMessage(softpkg); diff --git a/redhawk/src/control/sdr/dommgr/Application_impl.cpp b/redhawk/src/control/sdr/dommgr/Application_impl.cpp index cbe9ab686..2447cc863 100644 --- a/redhawk/src/control/sdr/dommgr/Application_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/Application_impl.cpp @@ -47,16 +47,11 @@ namespace { return result; } - bool has_naming_context(const redhawk::ApplicationComponent& component) - { - return !component.namingContext.empty(); - } - CF::Application::ComponentElementType to_name_element(const redhawk::ApplicationComponent& component) { CF::Application::ComponentElementType result; result.componentId = component.getIdentifier().c_str(); - result.elementId = component.namingContext.c_str(); + result.elementId = component.getNamingContext().c_str(); return result; } @@ -68,23 +63,13 @@ namespace { return result; } - bool is_registered(const redhawk::ApplicationComponent& component) - { - return !CORBA::is_nil(component.componentObject); - } - - bool is_terminated(const redhawk::ApplicationComponent& component) - { - return (component.getProcessId() == 0); - } - CF::ComponentType to_component_type(const redhawk::ApplicationComponent& component) { CF::ComponentType result; result.identifier = component.getIdentifier().c_str(); result.softwareProfile = component.softwareProfile.c_str(); result.type = CF::APPLICATION_COMPONENT; - result.componentObject = CORBA::Object::_duplicate(component.componentObject); + result.componentObject = component.getComponentObject(); return result; } @@ -763,7 +748,7 @@ CF::PortSet::PortInfoSequence* Application_impl::getPortSet () std::vector comp_portsets; for (ComponentList::iterator _component_iter=this->_components.begin(); _component_iter!=this->_components.end(); _component_iter++) { try { - CF::Resource_ptr comp = CF::Resource::_narrow(_component_iter->componentObject); + CF::Resource_var comp = _component_iter->getResourcePtr(); comp_portsets.push_back(comp->getPortSet()); } catch ( ... ) { // failed to get the port set from the component @@ -904,8 +889,8 @@ throw (CORBA::SystemException, CF::LifeCycle::ReleaseError) // - unload and deallocate for (ComponentList::iterator ii = _components.begin(); ii != _components.end(); ++ii) { - if (!ii->namingContext.empty()) { - std::string componentName = ii->namingContext; + if (ii->hasNamingContext()) { + const std::string& componentName = ii->getNamingContext(); // Unbind the component from the naming context. This assumes that the component is // bound into the waveform context, and its name inside of the context follows the @@ -996,14 +981,14 @@ throw (CORBA::SystemException, CF::LifeCycle::ReleaseError) void Application_impl::releaseComponents() { for (ComponentList::iterator ii = _components.begin(); ii != _components.end(); ++ii) { - if (ii->isContainer || CORBA::is_nil(ii->componentObject)) { + if (ii->isContainer || !ii->isRegistered()) { // Ignore components that never registered continue; } LOG_DEBUG(Application_impl, "Releasing component '" << ii->getIdentifier() << "'"); try { - CF::Resource_var resource = CF::Resource::_narrow(ii->componentObject); + CF::Resource_var resource = ii->getResourcePtr(); unsigned long timeout = 3; // seconds omniORB::setClientCallTimeout(resource, timeout * 1000); resource->releaseObject(); @@ -1011,14 +996,14 @@ void Application_impl::releaseComponents() } for (ComponentList::iterator ii = _components.begin(); ii != _components.end(); ++ii) { - if (!(ii->isContainer) || CORBA::is_nil(ii->componentObject)) { + if (!(ii->isContainer) || !ii->isRegistered()) { // Ignore components that never registered continue; } LOG_DEBUG(Application_impl, "Releasing container '" << ii->getIdentifier() << "'"); try { - CF::Resource_var resource = CF::Resource::_narrow(ii->componentObject); + CF::Resource_var resource = ii->getResourcePtr(); unsigned long timeout = 3; // seconds omniORB::setClientCallTimeout(resource, timeout * 1000); resource->releaseObject(); @@ -1141,7 +1126,8 @@ throw (CORBA::SystemException) CF::Components* Application_impl::registeredComponents () { CF::Components_var result = new CF::Components(); - convert_sequence_if(result, _components, to_component_type, is_registered); + convert_sequence_if(result, _components, to_component_type, + std::mem_fun_ref(&redhawk::ApplicationComponent::isRegistered)); return result._retn(); } @@ -1154,7 +1140,8 @@ CF::Application::ComponentElementSequence* Application_impl::componentNamingCont throw (CORBA::SystemException) { CF::Application::ComponentElementSequence_var result = new CF::Application::ComponentElementSequence(); - convert_sequence_if(result, _components, to_name_element, has_naming_context); + convert_sequence_if(result, _components, to_name_element, + std::mem_fun_ref(&redhawk::ApplicationComponent::hasNamingContext)); return result._retn(); } @@ -1221,9 +1208,9 @@ bool Application_impl::checkConnectionDependency (Endpoint::DependencyType type, bool Application_impl::_checkRegistrations (std::set& identifiers) { for (ComponentList::iterator ii = _components.begin(); ii != _components.end(); ++ii) { - if (is_registered(*ii)) { + if (ii->isRegistered()) { identifiers.erase(ii->getIdentifier()); - } else if (is_terminated(*ii)) { + } else if (ii->isTerminated()) { throw redhawk::ComponentTerminated(ii->getIdentifier()); } } @@ -1296,7 +1283,7 @@ void Application_impl::registerComponent (CF::Resource_ptr resource) } LOG_TRACE(Application_impl, "REGISTERING Component '" << componentId << "' software profile " << softwareProfile << " pid:" << comp->getProcessId()); - comp->componentObject = CORBA::Object::_duplicate(resource); + comp->setComponentObject(resource); _registrationCondition.notify_all(); } diff --git a/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp b/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp index 877a82085..da60db10a 100644 --- a/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp @@ -2130,7 +2130,7 @@ CF::Resource_ptr DomainManager_impl::lookupComponentByInstantiationId(const std: std::string normalized_comp_id = identifier.substr(0,pos)+std::string(":")+appid.substr(appid.rfind(":")+1); for (Application_impl::ComponentList::iterator _comp=_applications[appid]->_components.begin(); _comp!=_applications[appid]->_components.end(); _comp++) {\ if (normalized_comp_id == _comp->getIdentifier()) { - return CF::Resource::_duplicate(CF::Resource::_narrow(_comp->componentObject)); + return _comp->getResourcePtr(); } } } @@ -2474,11 +2474,11 @@ Application_impl* DomainManager_impl::_restoreApplication(ossie::ApplicationNode BOOST_FOREACH(ossie::ComponentNode& compNode, node.components) { redhawk::ApplicationComponent component(compNode.identifier); component.softwareProfile = compNode.softwareProfile; - component.namingContext = compNode.namingContext; + component.setNamingContext(compNode.namingContext); component.implementationId = compNode.implementationId; component.loadedFiles = compNode.loadedFiles; component.setProcessId(compNode.processId); - component.componentObject = CORBA::Object::_duplicate(compNode.componentObject); + component.setComponentObject(compNode.componentObject); component.assignedDevice = compNode.assignedDevice; component.isContainer = compNode.isContainer; application->_components.push_back(component); @@ -2516,11 +2516,11 @@ void DomainManager_impl::_persistApplication(Application_impl* application) ossie::ComponentNode compNode; compNode.identifier = component.getIdentifier(); compNode.softwareProfile = component.softwareProfile; - compNode.namingContext = component.namingContext; + compNode.namingContext = component.getNamingContext(); compNode.implementationId = component.implementationId; compNode.loadedFiles = component.loadedFiles; compNode.processId = component.getProcessId(); - compNode.componentObject = CORBA::Object::_duplicate(component.componentObject); + compNode.componentObject = component.getComponentObject(); compNode.assignedDevice = component.assignedDevice; compNode.isContainer = component.isContainer; appNode.components.push_back(compNode); From b8f4eeeaae4efe263554b2e3c862a3250fb2d459 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 26 Oct 2016 12:37:26 -0400 Subject: [PATCH 0493/1644] Encapsulate ApplicationComponent software profile, implementation ID and assigned device --- .../sdr/dommgr/ApplicationComponent.cpp | 48 +++++++++++++++---- .../control/sdr/dommgr/ApplicationComponent.h | 21 +++++--- .../control/sdr/dommgr/Application_impl.cpp | 30 ++++++------ .../control/sdr/dommgr/DomainManager_impl.cpp | 12 ++--- 4 files changed, 76 insertions(+), 35 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp b/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp index 17c6c36fb..fcec78f82 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp @@ -33,6 +33,41 @@ const std::string& ApplicationComponent::getIdentifier() const return _identifier; } +const std::string& ApplicationComponent::getSoftwareProfile() const +{ + return _softwareProfile; +} + +void ApplicationComponent::setSoftwareProfile(const std::string& softwareProfile) +{ + _softwareProfile = softwareProfile; +} + +bool ApplicationComponent::hasNamingContext() const +{ + return !_namingContext.empty(); +} + +const std::string& ApplicationComponent::getNamingContext() const +{ + return _namingContext; +} + +void ApplicationComponent::setNamingContext(const std::string& namingContext) +{ + _namingContext = namingContext; +} + +const std::string& ApplicationComponent::getImplementationId() const +{ + return _implementationId; +} + +void ApplicationComponent::setImplementationId(const std::string& implementationId) +{ + _implementationId = implementationId; +} + unsigned long ApplicationComponent::getProcessId() const { return _processId; @@ -68,17 +103,12 @@ CF::Resource_ptr ApplicationComponent::getResourcePtr() const return CF::Resource::_narrow(_componentObject); } -bool ApplicationComponent::hasNamingContext() const +CF::Device_ptr ApplicationComponent::getAssignedDevice() const { - return !_namingContext.empty(); + return CF::Device::_duplicate(_assignedDevice); } -const std::string& ApplicationComponent::getNamingContext() const +void ApplicationComponent::setAssignedDevice(CF::Device_ptr assignedDevice) { - return _namingContext; -} - -void ApplicationComponent::setNamingContext(const std::string& namingContext) -{ - _namingContext = namingContext; + _assignedDevice = CF::Device::_duplicate(assignedDevice); } diff --git a/redhawk/src/control/sdr/dommgr/ApplicationComponent.h b/redhawk/src/control/sdr/dommgr/ApplicationComponent.h index 33b3e96ab..6b8c037e2 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationComponent.h +++ b/redhawk/src/control/sdr/dommgr/ApplicationComponent.h @@ -32,6 +32,16 @@ namespace redhawk { const std::string& getIdentifier() const; + const std::string& getSoftwareProfile() const; + void setSoftwareProfile(const std::string& softwareProfile); + + bool hasNamingContext() const; + const std::string& getNamingContext() const; + void setNamingContext(const std::string& namingContext); + + const std::string& getImplementationId() const; + void setImplementationId(const std::string& implementationId); + unsigned long getProcessId() const; void setProcessId(unsigned long processId); @@ -43,21 +53,20 @@ namespace redhawk { CF::Resource_ptr getResourcePtr() const; - bool hasNamingContext() const; - const std::string& getNamingContext() const; - void setNamingContext(const std::string& namingContext); + CF::Device_ptr getAssignedDevice() const; + void setAssignedDevice(CF::Device_ptr assignedDevice); - std::string softwareProfile; - std::string implementationId; std::vector loadedFiles; - CF::Device_var assignedDevice; bool isContainer; private: std::string _identifier; + std::string _softwareProfile; std::string _namingContext; + std::string _implementationId; unsigned long _processId; CORBA::Object_var _componentObject; + CF::Device_var _assignedDevice; }; } diff --git a/redhawk/src/control/sdr/dommgr/Application_impl.cpp b/redhawk/src/control/sdr/dommgr/Application_impl.cpp index 2447cc863..5e99ddf10 100644 --- a/redhawk/src/control/sdr/dommgr/Application_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/Application_impl.cpp @@ -43,7 +43,7 @@ namespace { { CF::Application::ComponentElementType result; result.componentId = component.getIdentifier().c_str(); - result.elementId = component.implementationId.c_str(); + result.elementId = component.getImplementationId().c_str(); return result; } @@ -67,7 +67,7 @@ namespace { { CF::ComponentType result; result.identifier = component.getIdentifier().c_str(); - result.softwareProfile = component.softwareProfile.c_str(); + result.softwareProfile = component.getSoftwareProfile().c_str(); result.type = CF::APPLICATION_COMPONENT; result.componentObject = component.getComponentObject(); return result; @@ -1022,7 +1022,8 @@ void Application_impl::terminateComponents() LOG_DEBUG(Application_impl, "Terminating component '" << ii->getIdentifier() << "' pid " << pid); - CF::ExecutableDevice_var device = ossie::corba::_narrowSafe(ii->assignedDevice); + CF::Device_var assignedDevice = ii->getAssignedDevice(); + CF::ExecutableDevice_var device = ossie::corba::_narrowSafe(assignedDevice); if (CORBA::is_nil(device)) { LOG_WARN(Application_impl, "Cannot find device to terminate component " << ii->getIdentifier()); } else { @@ -1044,7 +1045,8 @@ void Application_impl::unloadComponents() LOG_DEBUG(Application_impl, "Unloading " << ii->loadedFiles.size() << " file(s) for component '" << ii->getIdentifier() << "'"); - CF::LoadableDevice_var device = ossie::corba::_narrowSafe(ii->assignedDevice); + CF::Device_var assignedDevice = ii->getAssignedDevice(); + CF::LoadableDevice_var device = ossie::corba::_narrowSafe(assignedDevice); if (CORBA::is_nil(device)) { LOG_WARN(Application_impl, "Cannot find device to unload files for component " << ii->getIdentifier()); continue; @@ -1274,12 +1276,12 @@ void Application_impl::registerComponent (CF::Resource_ptr resource) << "' registered with application '" << _appName << "'"); _components.push_back(redhawk::ApplicationComponent(componentId)); comp = &(_components.back()); - comp->softwareProfile = softwareProfile; - } else if (softwareProfile != comp->softwareProfile) { + comp->setSoftwareProfile(softwareProfile); + } else if (softwareProfile != comp->getSoftwareProfile()) { // Mismatch between expected and reported SPD path LOG_WARN(Application_impl, "Component '" << componentId << "' software profile " << softwareProfile - << " does not match expected profile " << comp->softwareProfile); - comp->softwareProfile = softwareProfile; + << " does not match expected profile " << comp->getSoftwareProfile()); + comp->setSoftwareProfile(softwareProfile); } LOG_TRACE(Application_impl, "REGISTERING Component '" << componentId << "' software profile " << softwareProfile << " pid:" << comp->getProcessId()); @@ -1325,10 +1327,10 @@ redhawk::ApplicationComponent* Application_impl::addContainer(const redhawk::Con const std::string& profile = container->getSoftPkg()->getSPDFile(); LOG_DEBUG(Application_impl, "Adding container '" << identifier << "' with profile " << profile); redhawk::ApplicationComponent component(identifier); - component.softwareProfile = profile; + component.setSoftwareProfile(profile); component.isContainer = true; - component.implementationId = container->getImplementation()->getID(); - component.assignedDevice = CF::Device::_duplicate(container->getAssignedDevice()->device); + component.setImplementationId(container->getImplementation()->getID()); + component.setAssignedDevice(container->getAssignedDevice()->device); _components.push_back(component); return &(_components.back()); } @@ -1342,10 +1344,10 @@ redhawk::ApplicationComponent* Application_impl::addComponent(const redhawk::Com const std::string& profile = deployment->getSoftPkg()->getSPDFile(); LOG_DEBUG(Application_impl, "Adding component '" << identifier << "' with profile " << profile); redhawk::ApplicationComponent component(identifier); - component.softwareProfile = profile; + component.setSoftwareProfile(profile); component.isContainer = false; - component.implementationId = deployment->getImplementation()->getID(); - component.assignedDevice = CF::Device::_duplicate(deployment->getAssignedDevice()->device); + component.setImplementationId(deployment->getImplementation()->getID()); + component.setAssignedDevice(deployment->getAssignedDevice()->device); _components.push_back(component); return &(_components.back()); } diff --git a/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp b/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp index da60db10a..dec763696 100644 --- a/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp @@ -2473,13 +2473,13 @@ Application_impl* DomainManager_impl::_restoreApplication(ossie::ApplicationNode // Restore various state about the components in the waveform BOOST_FOREACH(ossie::ComponentNode& compNode, node.components) { redhawk::ApplicationComponent component(compNode.identifier); - component.softwareProfile = compNode.softwareProfile; + component.setSoftwareProfile(compNode.softwareProfile); component.setNamingContext(compNode.namingContext); - component.implementationId = compNode.implementationId; + component.setImplementationId(compNode.implementationId); component.loadedFiles = compNode.loadedFiles; component.setProcessId(compNode.processId); component.setComponentObject(compNode.componentObject); - component.assignedDevice = compNode.assignedDevice; + component.setAssignedDevice(compNode.assignedDevice); component.isContainer = compNode.isContainer; application->_components.push_back(component); } @@ -2515,13 +2515,13 @@ void DomainManager_impl::_persistApplication(Application_impl* application) BOOST_FOREACH(redhawk::ApplicationComponent& component, application->_components) { ossie::ComponentNode compNode; compNode.identifier = component.getIdentifier(); - compNode.softwareProfile = component.softwareProfile; + compNode.softwareProfile = component.getSoftwareProfile(); compNode.namingContext = component.getNamingContext(); - compNode.implementationId = component.implementationId; + compNode.implementationId = component.getImplementationId(); compNode.loadedFiles = component.loadedFiles; compNode.processId = component.getProcessId(); compNode.componentObject = component.getComponentObject(); - compNode.assignedDevice = component.assignedDevice; + compNode.assignedDevice = component.getAssignedDevice(); compNode.isContainer = component.isContainer; appNode.components.push_back(compNode); } From 78511b9045371e0ace3536f104074032ad74e6bb Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 26 Oct 2016 14:44:19 -0400 Subject: [PATCH 0494/1644] Move some cleanup behavior into ApplicationComponent --- .../sdr/dommgr/ApplicationComponent.cpp | 57 ++++++++++++++++ .../control/sdr/dommgr/ApplicationComponent.h | 4 ++ .../control/sdr/dommgr/Application_impl.cpp | 67 +++---------------- .../src/control/sdr/dommgr/Application_impl.h | 2 +- 4 files changed, 70 insertions(+), 60 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp b/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp index fcec78f82..4e7d088f7 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp @@ -18,7 +18,10 @@ * along with this program. If not, see http://www.gnu.org/licenses/. */ +#include + #include "ApplicationComponent.h" +#include "Application_impl.h" using redhawk::ApplicationComponent; @@ -112,3 +115,57 @@ void ApplicationComponent::setAssignedDevice(CF::Device_ptr assignedDevice) { _assignedDevice = CF::Device::_duplicate(assignedDevice); } + +void ApplicationComponent::releaseObject() +{ + if (!isRegistered()) { + return; + } + + LOG_DEBUG(Application_impl, "Releasing component '" << _identifier << "'"); + try { + CF::Resource_var resource = CF::Resource::_narrow(_componentObject); + unsigned long timeout = 3; // seconds; + omniORB::setClientCallTimeout(resource, timeout * 1000); + resource->releaseObject(); + } CATCH_LOG_WARN(Application_impl, "releaseObject failed for component '" << _identifier << "'"); +} + +void ApplicationComponent::terminate() +{ + // TODO: PIDs are not necessarily capped at 64K; the limit is system- + // dependent + if (_processId == 0 || _processId >= 65536) { + return; + } + + CF::ExecutableDevice_var device = ossie::corba::_narrowSafe(_assignedDevice); + if (CORBA::is_nil(device)) { + LOG_WARN(Application_impl, "Cannot find device to terminate component " << _identifier); + } else { + device->terminate(_processId); + } +} + +void ApplicationComponent::unloadFiles() +{ + if (loadedFiles.empty()) { + return; + } + + LOG_DEBUG(Application_impl, "Unloading " << loadedFiles.size() << " file(s) for component '" + << _identifier << "'"); + + CF::LoadableDevice_var device = ossie::corba::_narrowSafe(_assignedDevice); + if (CORBA::is_nil(device)) { + LOG_WARN(Application_impl, "Cannot find device to unload files for component " << _identifier); + return; + } + + BOOST_FOREACH(const std::string& file, loadedFiles) { + LOG_TRACE(Application_impl, "Unloading file " << file); + try { + device->unload(file.c_str()); + } CATCH_LOG_WARN(Application_impl, "Unable to unload file " << file); + } +} diff --git a/redhawk/src/control/sdr/dommgr/ApplicationComponent.h b/redhawk/src/control/sdr/dommgr/ApplicationComponent.h index 6b8c037e2..b918f9b33 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationComponent.h +++ b/redhawk/src/control/sdr/dommgr/ApplicationComponent.h @@ -59,6 +59,10 @@ namespace redhawk { std::vector loadedFiles; bool isContainer; + void releaseObject(); + void terminate(); + void unloadFiles(); + private: std::string _identifier; std::string _softwareProfile; diff --git a/redhawk/src/control/sdr/dommgr/Application_impl.cpp b/redhawk/src/control/sdr/dommgr/Application_impl.cpp index 5e99ddf10..005a02dae 100644 --- a/redhawk/src/control/sdr/dommgr/Application_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/Application_impl.cpp @@ -981,33 +981,17 @@ throw (CORBA::SystemException, CF::LifeCycle::ReleaseError) void Application_impl::releaseComponents() { for (ComponentList::iterator ii = _components.begin(); ii != _components.end(); ++ii) { - if (ii->isContainer || !ii->isRegistered()) { - // Ignore components that never registered - continue; + if (!ii->isContainer) { + // Release "real" components first + ii->releaseObject(); } - - LOG_DEBUG(Application_impl, "Releasing component '" << ii->getIdentifier() << "'"); - try { - CF::Resource_var resource = ii->getResourcePtr(); - unsigned long timeout = 3; // seconds - omniORB::setClientCallTimeout(resource, timeout * 1000); - resource->releaseObject(); - } CATCH_LOG_WARN(Application_impl, "releaseObject failed for component '" << ii->getIdentifier() << "'"); } for (ComponentList::iterator ii = _components.begin(); ii != _components.end(); ++ii) { - if (!(ii->isContainer) || !ii->isRegistered()) { - // Ignore components that never registered - continue; + if (ii->isContainer) { + // Release containers once all "real" components have been released + ii->releaseObject(); } - - LOG_DEBUG(Application_impl, "Releasing container '" << ii->getIdentifier() << "'"); - try { - CF::Resource_var resource = ii->getResourcePtr(); - unsigned long timeout = 3; // seconds - omniORB::setClientCallTimeout(resource, timeout * 1000); - resource->releaseObject(); - } CATCH_LOG_WARN(Application_impl, "releaseObject failed for component '" << ii->getIdentifier() << "'"); } } @@ -1015,22 +999,7 @@ void Application_impl::terminateComponents() { // Terminate any components that were executed on devices for (ComponentList::iterator ii = _components.begin(); ii != _components.end(); ++ii) { - const unsigned long pid = ii->getProcessId(); - if (pid == 0 || pid >= 65536) { - continue; - } - - LOG_DEBUG(Application_impl, "Terminating component '" << ii->getIdentifier() << "' pid " << pid); - - CF::Device_var assignedDevice = ii->getAssignedDevice(); - CF::ExecutableDevice_var device = ossie::corba::_narrowSafe(assignedDevice); - if (CORBA::is_nil(device)) { - LOG_WARN(Application_impl, "Cannot find device to terminate component " << ii->getIdentifier()); - } else { - try { - device->terminate(pid); - } CATCH_LOG_WARN(Application_impl, "Unable to terminate process " << pid); - } + ii->terminate(); } } @@ -1038,27 +1007,7 @@ void Application_impl::unloadComponents() { // Terminate any components that were executed on devices for (ComponentList::iterator ii = _components.begin(); ii != _components.end(); ++ii) { - if (ii->loadedFiles.empty()) { - continue; - } - - LOG_DEBUG(Application_impl, "Unloading " << ii->loadedFiles.size() << " file(s) for component '" - << ii->getIdentifier() << "'"); - - CF::Device_var assignedDevice = ii->getAssignedDevice(); - CF::LoadableDevice_var device = ossie::corba::_narrowSafe(assignedDevice); - if (CORBA::is_nil(device)) { - LOG_WARN(Application_impl, "Cannot find device to unload files for component " << ii->getIdentifier()); - continue; - } - - for (std::vector::iterator file = ii->loadedFiles.begin(); file != ii->loadedFiles.end(); - ++file) { - LOG_TRACE(Application_impl, "Unloading file " << *file); - try { - device->unload(file->c_str()); - } CATCH_LOG_WARN(Application_impl, "Unable to unload file " << *file); - } + ii->unloadFiles(); } } diff --git a/redhawk/src/control/sdr/dommgr/Application_impl.h b/redhawk/src/control/sdr/dommgr/Application_impl.h index f68957ccb..cc80cd229 100644 --- a/redhawk/src/control/sdr/dommgr/Application_impl.h +++ b/redhawk/src/control/sdr/dommgr/Application_impl.h @@ -219,7 +219,7 @@ class Application_impl : public virtual POA_CF::Application, public Logging_impl // internal propId, returns empty string if no external prop exists std::string getExternalPropertyId(std::string compId, std::string propId); - + friend class redhawk::ApplicationComponent; // for logger access friend class ApplicationRegistrar_impl; }; From 7bac89758057b69dfea5aa5f463c68bd9996a593 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 27 Oct 2016 11:28:11 -0400 Subject: [PATCH 0495/1644] Encapsulate ApplicationComponent loaded files --- .../control/sdr/dommgr/ApplicationComponent.cpp | 16 +++++++++++++--- .../control/sdr/dommgr/ApplicationComponent.h | 5 ++++- redhawk/src/control/sdr/dommgr/Deployment.cpp | 2 +- .../control/sdr/dommgr/DomainManager_impl.cpp | 6 ++++-- 4 files changed, 22 insertions(+), 7 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp b/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp index 4e7d088f7..987234ec1 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp @@ -91,6 +91,16 @@ bool ApplicationComponent::isRegistered() const return !CORBA::is_nil(_componentObject); } +const std::vector& ApplicationComponent::getLoadedFiles() const +{ + return _loadedFiles; +} + +void ApplicationComponent::addLoadedFile(const std::string& fileName) +{ + _loadedFiles.push_back(fileName); +} + CORBA::Object_ptr ApplicationComponent::getComponentObject() const { return CORBA::Object::_duplicate(_componentObject); @@ -149,11 +159,11 @@ void ApplicationComponent::terminate() void ApplicationComponent::unloadFiles() { - if (loadedFiles.empty()) { + if (_loadedFiles.empty()) { return; } - LOG_DEBUG(Application_impl, "Unloading " << loadedFiles.size() << " file(s) for component '" + LOG_DEBUG(Application_impl, "Unloading " << _loadedFiles.size() << " file(s) for component '" << _identifier << "'"); CF::LoadableDevice_var device = ossie::corba::_narrowSafe(_assignedDevice); @@ -162,7 +172,7 @@ void ApplicationComponent::unloadFiles() return; } - BOOST_FOREACH(const std::string& file, loadedFiles) { + BOOST_FOREACH(const std::string& file, _loadedFiles) { LOG_TRACE(Application_impl, "Unloading file " << file); try { device->unload(file.c_str()); diff --git a/redhawk/src/control/sdr/dommgr/ApplicationComponent.h b/redhawk/src/control/sdr/dommgr/ApplicationComponent.h index b918f9b33..728d7cc12 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationComponent.h +++ b/redhawk/src/control/sdr/dommgr/ApplicationComponent.h @@ -48,6 +48,9 @@ namespace redhawk { bool isTerminated() const; bool isRegistered() const; + const std::vector& getLoadedFiles() const; + void addLoadedFile(const std::string& fileName); + CORBA::Object_ptr getComponentObject() const; void setComponentObject(CORBA::Object_ptr object); @@ -56,7 +59,6 @@ namespace redhawk { CF::Device_ptr getAssignedDevice() const; void setAssignedDevice(CF::Device_ptr assignedDevice); - std::vector loadedFiles; bool isContainer; void releaseObject(); @@ -68,6 +70,7 @@ namespace redhawk { std::string _softwareProfile; std::string _namingContext; std::string _implementationId; + std::vector _loadedFiles; unsigned long _processId; CORBA::Object_var _componentObject; CF::Device_var _assignedDevice; diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index 85ab28daf..43269a318 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -185,7 +185,7 @@ void SoftPkgDeployment::load(redhawk::ApplicationComponent* appComponent, CF::Fi message += " loading " + fileName; throw DeploymentError(message); } - appComponent->loadedFiles.push_back(fileName); + appComponent->addLoadedFile(fileName); } std::string SoftPkgDeployment::getLocalFile() diff --git a/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp b/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp index dec763696..13c52f15d 100644 --- a/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp @@ -2476,7 +2476,9 @@ Application_impl* DomainManager_impl::_restoreApplication(ossie::ApplicationNode component.setSoftwareProfile(compNode.softwareProfile); component.setNamingContext(compNode.namingContext); component.setImplementationId(compNode.implementationId); - component.loadedFiles = compNode.loadedFiles; + BOOST_FOREACH(const std::string& filename, compNode.loadedFiles) { + component.addLoadedFile(filename); + } component.setProcessId(compNode.processId); component.setComponentObject(compNode.componentObject); component.setAssignedDevice(compNode.assignedDevice); @@ -2518,7 +2520,7 @@ void DomainManager_impl::_persistApplication(Application_impl* application) compNode.softwareProfile = component.getSoftwareProfile(); compNode.namingContext = component.getNamingContext(); compNode.implementationId = component.getImplementationId(); - compNode.loadedFiles = component.loadedFiles; + compNode.loadedFiles = component.getLoadedFiles(); compNode.processId = component.getProcessId(); compNode.componentObject = component.getComponentObject(); compNode.assignedDevice = component.getAssignedDevice(); From e5d0c0ca4c877b302aab00175546a913e9943167 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 27 Oct 2016 12:10:06 -0400 Subject: [PATCH 0496/1644] Give ApplicationComponent a pointer to a DeviceNode, so it has more information about its assigned device --- .../sdr/dommgr/ApplicationComponent.cpp | 28 +++++++++++-------- .../control/sdr/dommgr/ApplicationComponent.h | 7 +++-- .../control/sdr/dommgr/Application_impl.cpp | 4 +-- .../control/sdr/dommgr/DomainManager_impl.cpp | 11 ++++++-- .../src/control/sdr/dommgr/PersistenceStore.h | 4 +-- 5 files changed, 34 insertions(+), 20 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp b/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp index 987234ec1..cfbcf1f31 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp @@ -116,14 +116,14 @@ CF::Resource_ptr ApplicationComponent::getResourcePtr() const return CF::Resource::_narrow(_componentObject); } -CF::Device_ptr ApplicationComponent::getAssignedDevice() const +const boost::shared_ptr& ApplicationComponent::getAssignedDevice() const { - return CF::Device::_duplicate(_assignedDevice); + return _assignedDevice; } -void ApplicationComponent::setAssignedDevice(CF::Device_ptr assignedDevice) +void ApplicationComponent::setAssignedDevice(const boost::shared_ptr& assignedDevice) { - _assignedDevice = CF::Device::_duplicate(assignedDevice); + _assignedDevice = assignedDevice; } void ApplicationComponent::releaseObject() @@ -149,11 +149,14 @@ void ApplicationComponent::terminate() return; } - CF::ExecutableDevice_var device = ossie::corba::_narrowSafe(_assignedDevice); - if (CORBA::is_nil(device)) { + CF::ExecutableDevice_var exec_device; + if (_assignedDevice && _assignedDevice->isExecutable) { + exec_device = ossie::corba::_narrowSafe(_assignedDevice->device); + } + if (CORBA::is_nil(exec_device)) { LOG_WARN(Application_impl, "Cannot find device to terminate component " << _identifier); } else { - device->terminate(_processId); + exec_device->terminate(_processId); } } @@ -165,9 +168,12 @@ void ApplicationComponent::unloadFiles() LOG_DEBUG(Application_impl, "Unloading " << _loadedFiles.size() << " file(s) for component '" << _identifier << "'"); - - CF::LoadableDevice_var device = ossie::corba::_narrowSafe(_assignedDevice); - if (CORBA::is_nil(device)) { + + CF::LoadableDevice_var loadable_device; + if (_assignedDevice && _assignedDevice->isExecutable) { + loadable_device = ossie::corba::_narrowSafe(_assignedDevice->device); + } + if (CORBA::is_nil(loadable_device)) { LOG_WARN(Application_impl, "Cannot find device to unload files for component " << _identifier); return; } @@ -175,7 +181,7 @@ void ApplicationComponent::unloadFiles() BOOST_FOREACH(const std::string& file, _loadedFiles) { LOG_TRACE(Application_impl, "Unloading file " << file); try { - device->unload(file.c_str()); + loadable_device->unload(file.c_str()); } CATCH_LOG_WARN(Application_impl, "Unable to unload file " << file); } } diff --git a/redhawk/src/control/sdr/dommgr/ApplicationComponent.h b/redhawk/src/control/sdr/dommgr/ApplicationComponent.h index 728d7cc12..f935dd2b4 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationComponent.h +++ b/redhawk/src/control/sdr/dommgr/ApplicationComponent.h @@ -25,6 +25,7 @@ #include #include +#include namespace redhawk { struct ApplicationComponent { @@ -56,8 +57,8 @@ namespace redhawk { CF::Resource_ptr getResourcePtr() const; - CF::Device_ptr getAssignedDevice() const; - void setAssignedDevice(CF::Device_ptr assignedDevice); + const boost::shared_ptr& getAssignedDevice() const; + void setAssignedDevice(const boost::shared_ptr& assignedDevice); bool isContainer; @@ -73,7 +74,7 @@ namespace redhawk { std::vector _loadedFiles; unsigned long _processId; CORBA::Object_var _componentObject; - CF::Device_var _assignedDevice; + boost::shared_ptr _assignedDevice; }; } diff --git a/redhawk/src/control/sdr/dommgr/Application_impl.cpp b/redhawk/src/control/sdr/dommgr/Application_impl.cpp index 005a02dae..337ebe0c2 100644 --- a/redhawk/src/control/sdr/dommgr/Application_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/Application_impl.cpp @@ -1279,7 +1279,7 @@ redhawk::ApplicationComponent* Application_impl::addContainer(const redhawk::Con component.setSoftwareProfile(profile); component.isContainer = true; component.setImplementationId(container->getImplementation()->getID()); - component.setAssignedDevice(container->getAssignedDevice()->device); + component.setAssignedDevice(container->getAssignedDevice()); _components.push_back(component); return &(_components.back()); } @@ -1296,7 +1296,7 @@ redhawk::ApplicationComponent* Application_impl::addComponent(const redhawk::Com component.setSoftwareProfile(profile); component.isContainer = false; component.setImplementationId(deployment->getImplementation()->getID()); - component.setAssignedDevice(deployment->getAssignedDevice()->device); + component.setAssignedDevice(deployment->getAssignedDevice()); _components.push_back(component); return &(_components.back()); } diff --git a/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp b/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp index 13c52f15d..963685035 100644 --- a/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp @@ -2481,7 +2481,14 @@ Application_impl* DomainManager_impl::_restoreApplication(ossie::ApplicationNode } component.setProcessId(compNode.processId); component.setComponentObject(compNode.componentObject); - component.setAssignedDevice(compNode.assignedDevice); + ossie::DeviceList::iterator device = findDeviceById(compNode.assignedDeviceId); + if (device == _registeredDevices.end()) { + LOG_WARN(DomainManager_impl, "Could not find assigned device '" << compNode.assignedDeviceId + << "' for application '" << node.name + << "' component '" << compNode.identifier); + } else { + component.setAssignedDevice(*device); + } component.isContainer = compNode.isContainer; application->_components.push_back(component); } @@ -2523,7 +2530,7 @@ void DomainManager_impl::_persistApplication(Application_impl* application) compNode.loadedFiles = component.getLoadedFiles(); compNode.processId = component.getProcessId(); compNode.componentObject = component.getComponentObject(); - compNode.assignedDevice = component.getAssignedDevice(); + compNode.assignedDeviceId = component.getAssignedDevice()->identifier; compNode.isContainer = component.isContainer; appNode.components.push_back(compNode); } diff --git a/redhawk/src/control/sdr/dommgr/PersistenceStore.h b/redhawk/src/control/sdr/dommgr/PersistenceStore.h index 9ba57188b..0a55ac16c 100644 --- a/redhawk/src/control/sdr/dommgr/PersistenceStore.h +++ b/redhawk/src/control/sdr/dommgr/PersistenceStore.h @@ -103,7 +103,7 @@ namespace ossie { std::vector loadedFiles; unsigned long processId; CORBA::Object_var componentObject; - CF::Device_var assignedDevice; + std::string assignedDeviceId; bool isContainer; }; typedef std::list ComponentList; @@ -260,7 +260,7 @@ namespace boost { ar & node.loadedFiles; ar & node.processId; ar & node.componentObject; - ar & node.assignedDevice; + ar & node.assignedDeviceId; ar & node.isContainer; } From 00ceda170ef6319850dfc9a44c5c7e058f237fe2 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 27 Oct 2016 12:18:44 -0400 Subject: [PATCH 0497/1644] Cache the LoadableDevice and ExecutableDevice references for DeviceNode object in the DomainManager --- .../control/sdr/dommgr/ApplicationComponent.cpp | 16 ++++------------ .../sdr/dommgr/ApplicationFactory_impl.cpp | 2 +- .../control/sdr/dommgr/DomainManager_impl.cpp | 4 ++-- .../src/control/sdr/dommgr/PersistenceStore.h | 14 ++++++++++++-- 4 files changed, 19 insertions(+), 17 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp b/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp index cfbcf1f31..2e61f98ac 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp @@ -149,14 +149,10 @@ void ApplicationComponent::terminate() return; } - CF::ExecutableDevice_var exec_device; - if (_assignedDevice && _assignedDevice->isExecutable) { - exec_device = ossie::corba::_narrowSafe(_assignedDevice->device); - } - if (CORBA::is_nil(exec_device)) { + if (!_assignedDevice || !_assignedDevice->isExecutable()) { LOG_WARN(Application_impl, "Cannot find device to terminate component " << _identifier); } else { - exec_device->terminate(_processId); + _assignedDevice->executableDevice->terminate(_processId); } } @@ -169,11 +165,7 @@ void ApplicationComponent::unloadFiles() LOG_DEBUG(Application_impl, "Unloading " << _loadedFiles.size() << " file(s) for component '" << _identifier << "'"); - CF::LoadableDevice_var loadable_device; - if (_assignedDevice && _assignedDevice->isExecutable) { - loadable_device = ossie::corba::_narrowSafe(_assignedDevice->device); - } - if (CORBA::is_nil(loadable_device)) { + if (!_assignedDevice || !_assignedDevice->isLoadable()) { LOG_WARN(Application_impl, "Cannot find device to unload files for component " << _identifier); return; } @@ -181,7 +173,7 @@ void ApplicationComponent::unloadFiles() BOOST_FOREACH(const std::string& file, _loadedFiles) { LOG_TRACE(Application_impl, "Unloading file " << file); try { - loadable_device->unload(file.c_str()); + _assignedDevice->loadableDevice->unload(file.c_str()); } CATCH_LOG_WARN(Application_impl, "Unable to unload file " << file); } } diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index f03137307..f083b6f70 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -781,7 +781,7 @@ CF::Application_ptr createHelper::create ( _registeredDevices = _appFact._domainManager->getRegisteredDevices(); _executableDevices.clear(); for (DeviceList::iterator iter = _registeredDevices.begin(); iter != _registeredDevices.end(); ++iter) { - if ((*iter)->isExecutable) { + if ((*iter)->isExecutable()) { _executableDevices.push_back(*iter); } } diff --git a/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp b/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp index 963685035..64fcfb26d 100644 --- a/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp @@ -1340,8 +1340,8 @@ void DomainManager_impl::storeDeviceInDomainMgr (CF::Device_ptr registeringDevic newDeviceNode->softwareProfile = ossie::corba::returnString(registeringDevice->softwareProfile()); newDeviceNode->identifier = ossie::corba::returnString(registeringDevice->identifier()); newDeviceNode->implementationId = ossie::corba::returnString(registeredDeviceMgr->getComponentImplementationId(newDeviceNode->identifier.c_str())); - newDeviceNode->isLoadable = registeringDevice->_is_a(CF::LoadableDevice::_PD_repoId); - newDeviceNode->isExecutable = registeringDevice->_is_a(CF::ExecutableDevice::_PD_repoId); + newDeviceNode->loadableDevice = ossie::corba::_narrowSafe(registeringDevice); + newDeviceNode->executableDevice = ossie::corba::_narrowSafe(registeringDevice); parseDeviceProfile(*newDeviceNode); diff --git a/redhawk/src/control/sdr/dommgr/PersistenceStore.h b/redhawk/src/control/sdr/dommgr/PersistenceStore.h index 0a55ac16c..9174f5bca 100644 --- a/redhawk/src/control/sdr/dommgr/PersistenceStore.h +++ b/redhawk/src/control/sdr/dommgr/PersistenceStore.h @@ -70,8 +70,18 @@ namespace ossie { ossie::SoftPkg spd; ossie::Properties prf; std::string implementationId; - bool isLoadable; - bool isExecutable; + CF::LoadableDevice_var loadableDevice; + CF::ExecutableDevice_var executableDevice; + + bool isLoadable() const + { + return !CORBA::is_nil(loadableDevice); + } + + bool isExecutable() const + { + return !CORBA::is_nil(executableDevice); + } }; typedef std::list > DeviceList; From 99041f18436db3df0911fa63dd0b1792a91193aa Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 27 Oct 2016 13:49:10 -0400 Subject: [PATCH 0498/1644] Maintain assembly controller as a pointer to ApplicationComponent, instead of just a CORBA ref --- .../sdr/dommgr/ApplicationComponent.cpp | 10 ++- .../control/sdr/dommgr/ApplicationComponent.h | 2 + .../sdr/dommgr/ApplicationFactory_impl.cpp | 13 ++- .../control/sdr/dommgr/Application_impl.cpp | 87 +++++++++++-------- .../src/control/sdr/dommgr/Application_impl.h | 10 +-- .../control/sdr/dommgr/DomainManager_impl.cpp | 12 +-- .../src/control/sdr/dommgr/PersistenceStore.h | 4 +- 7 files changed, 81 insertions(+), 57 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp b/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp index 2e61f98ac..fed1bbf55 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp @@ -20,6 +20,8 @@ #include +#include + #include "ApplicationComponent.h" #include "Application_impl.h" @@ -81,6 +83,11 @@ void ApplicationComponent::setProcessId(unsigned long processId) _processId = processId; } +bool ApplicationComponent::isResource() const +{ + return !CORBA::is_nil(_resource); +} + bool ApplicationComponent::isTerminated() const { return (_processId == 0); @@ -109,11 +116,12 @@ CORBA::Object_ptr ApplicationComponent::getComponentObject() const void ApplicationComponent::setComponentObject(CORBA::Object_ptr object) { _componentObject = CORBA::Object::_duplicate(object); + _resource = ossie::corba::_narrowSafe(object); } CF::Resource_ptr ApplicationComponent::getResourcePtr() const { - return CF::Resource::_narrow(_componentObject); + return CF::Resource::_duplicate(_resource); } const boost::shared_ptr& ApplicationComponent::getAssignedDevice() const diff --git a/redhawk/src/control/sdr/dommgr/ApplicationComponent.h b/redhawk/src/control/sdr/dommgr/ApplicationComponent.h index f935dd2b4..ad0c7027e 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationComponent.h +++ b/redhawk/src/control/sdr/dommgr/ApplicationComponent.h @@ -46,6 +46,7 @@ namespace redhawk { unsigned long getProcessId() const; void setProcessId(unsigned long processId); + bool isResource() const; bool isTerminated() const; bool isRegistered() const; @@ -74,6 +75,7 @@ namespace redhawk { std::vector _loadedFiles; unsigned long _processId; CORBA::Object_var _componentObject; + CF::Resource_var _resource; boost::shared_ptr _assignedDevice; }; } diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index f083b6f70..10e92509c 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -849,12 +849,13 @@ CF::Application_ptr createHelper::create ( // This condition should have been prevented by parser validation throw std::logic_error("Assembly controller has not been assigned"); } - CF::Resource_var assemblyController = assemblyController = ac_deployment->getResourcePtr(); + CF::Resource_var assemblyController = ac_deployment->getResourcePtr(); if (CORBA::is_nil(assemblyController) && ac_deployment->getSoftPkg()->isScaCompliant()) { // Likewise, component registration should have already thrown an // exception if an SCA-compliant component did not register throw std::logic_error("Assembly controller has not registered with the application"); } + _application->setAssemblyController(ac_deployment->getIdentifier()); initializeComponents(app_deployment.getComponentDeployments()); @@ -913,12 +914,10 @@ CF::Application_ptr createHelper::create ( } std::vector start_order = getStartOrder(app_deployment.getComponentDeployments()); - _application->populateApplication( - assemblyController, - app_devices, - start_order, - connections, - allocationIDs); + _application->populateApplication(app_devices, + start_order, + connections, + allocationIDs); // Add a reference to the new application to the // ApplicationSequence in DomainManager diff --git a/redhawk/src/control/sdr/dommgr/Application_impl.cpp b/redhawk/src/control/sdr/dommgr/Application_impl.cpp index 337ebe0c2..fcec1e962 100644 --- a/redhawk/src/control/sdr/dommgr/Application_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/Application_impl.cpp @@ -109,6 +109,7 @@ namespace { Application_impl::Application_impl (const std::string& id, const std::string& name, const std::string& profile, DomainManager_impl* domainManager, const std::string& waveformContextName, CosNaming::NamingContext_ptr waveformContext, bool aware, CosNaming::NamingContext_ptr DomainContext) : + _assemblyController(0), _identifier(id), _sadProfile(profile), _appName(name), @@ -127,8 +128,23 @@ Application_impl::Application_impl (const std::string& id, const std::string& na } }; -void Application_impl::populateApplication(CF::Resource_ptr _controller, - const CF::DeviceAssignmentSequence& assignedDevices, +void Application_impl::setAssemblyController(const std::string& assemblyControllerRef) +{ + LOG_DEBUG(Application_impl, "Assigning the assembly controller") + _assemblyController = findComponent(assemblyControllerRef); + // Assume _controller is NIL implies that the assembly controller component is Non SCA-Compliant + if (!_assemblyController || !_assemblyController->isResource()) { + LOG_INFO(Application_impl, "Assembly controller is non SCA-compliant"); + _assemblyController = 0; + } +} + +redhawk::ApplicationComponent* Application_impl::getAssemblyController() +{ + return _assemblyController; +} + +void Application_impl::populateApplication(const CF::DeviceAssignmentSequence& assignedDevices, std::vector _startSeq, std::vector& connections, std::vector allocationIDs) @@ -141,13 +157,6 @@ void Application_impl::populateApplication(CF::Resource_ptr _controller, LOG_DEBUG(Application_impl, "Creating allocation sequence"); this->_allocationIDs = allocationIDs; - LOG_DEBUG(Application_impl, "Assigning the assembly controller") - // Assume _controller is NIL implies that the assembly controller component is Non SCA-Compliant - if (CORBA::is_nil(_controller)) { - LOG_INFO(Application_impl, "Assembly controller is non SCA-compliant"); - } else { - assemblyController = CF::Resource::_duplicate(_controller); - } TRACE_EXIT(Application_impl) } @@ -194,15 +203,15 @@ CORBA::Boolean Application_impl::started () throw (CORBA::SystemException) void Application_impl::start () throw (CORBA::SystemException, CF::Resource::StartError) { - if (CORBA::is_nil(assemblyController) and (_appStartSeq.size() == 0)) { - throw(CF::Resource::StartError(CF::CF_ENOTSUP, "No assembly controller and no Components with startorder set")); - return; + if (!_assemblyController && _appStartSeq.empty()) { + throw CF::Resource::StartError(CF::CF_ENOTSUP, "No assembly controller and no Components with startorder set"); } try { - omniORB::setClientCallTimeout(assemblyController, 0); + CF::Resource_var resource = _assemblyController->getResourcePtr(); + omniORB::setClientCallTimeout(resource, 0); LOG_TRACE(Application_impl, "Calling start on assembly controller") - assemblyController->start (); + resource->start (); // Start the rest of the components for (unsigned int i = 0; i < _appStartSeq.size(); i++){ @@ -256,9 +265,8 @@ bool Application_impl::stopComponent (CF::Resource_ptr component) void Application_impl::stop () throw (CORBA::SystemException, CF::Resource::StopError) { - if (CORBA::is_nil(assemblyController) and (_appStartSeq.size() == 0)) { - throw(CF::Resource::StopError(CF::CF_ENOTSUP, "No assembly controller and no Components with startorder set")); - return; + if (!_assemblyController && _appStartSeq.empty()) { + throw CF::Resource::StopError(CF::CF_ENOTSUP, "No assembly controller and no Components with startorder set"); } int failures = 0; @@ -270,7 +278,8 @@ throw (CORBA::SystemException, CF::Resource::StopError) } LOG_TRACE(Application_impl, "Calling stop on assembly controller"); - if (!stopComponent(assemblyController)) { + CF::Resource_var ac_resource = _assemblyController->getResourcePtr(); + if (!stopComponent(ac_resource)) { failures++; } if (failures > 0) { @@ -307,9 +316,10 @@ throw (CF::PropertySet::PartialConfiguration, CF::PropertySet::InvalidConfigurat // to allow for one batched configure call per component CF::Properties acProps; - const std::string acId = ossie::corba::returnString(assemblyController->identifier()); + const std::string acId = _assemblyController->getIdentifier(); + CF::Resource_var ac_resource = _assemblyController->getResourcePtr(); std::map > batch; - batch[acId] = std::pair(assemblyController, acProps); + batch[acId] = std::pair(ac_resource, acProps); // Loop through each passed external property, mapping it with its respective resource for (unsigned int i = 0; i < configProperties.length(); ++i) { @@ -349,7 +359,7 @@ throw (CF::PropertySet::PartialConfiguration, CF::PropertySet::InvalidConfigurat batch[compId] = std::pair(comp, tempProp); } } - } else if (!CORBA::is_nil(assemblyController)) { + } else if (_assemblyController) { // Properties that are not external get batched with assembly controller LOG_TRACE(Application_impl, "Calling configure on assembly controller for property: " << configProperties[i].id); int count = batch[acId].second.length(); @@ -411,7 +421,7 @@ throw (CF::UnknownProperties, CORBA::SystemException) // Creates a map from componentIdentifier -> (rsc_ptr, ConfigPropSet) // to allow for one batched query call per component - const std::string acId = ossie::corba::returnString(assemblyController->identifier()); + const std::string acId = _assemblyController->getIdentifier(); std::map > batch; // For queries of zero length, return all external properties @@ -486,7 +496,8 @@ throw (CF::UnknownProperties, CORBA::SystemException) // Query Assembly Controller properties CF::Properties tempProp; try { - assemblyController->query(tempProp); + CF::Resource_var ac_resource = _assemblyController->getResourcePtr(); + ac_resource->query(tempProp); } catch (CF::UnknownProperties e) { int count = invalidProperties.length(); invalidProperties.length(count + e.invalidProperties.length()); @@ -510,7 +521,8 @@ throw (CF::UnknownProperties, CORBA::SystemException) // For queries of length > 0, return all requested pairs that are valid external properties // or are Assembly Controller Properties CF::Properties acProps; - batch[acId] = std::pair(assemblyController, acProps); + CF::Resource_var ac_resource = _assemblyController->getResourcePtr(); + batch[acId] = std::pair(ac_resource, acProps); for (unsigned int i = 0; i < configProperties.length(); ++i) { // Gets external ID for property mapping @@ -549,7 +561,7 @@ throw (CF::UnknownProperties, CORBA::SystemException) batch[compId] = std::pair(comp, tempProp); } } - } else if (!CORBA::is_nil(assemblyController)) { + } else if (_assemblyController) { // Properties that are not external get batched with assembly controller LOG_TRACE(Application_impl, "Calling query on assembly controller for property: " << configProperties[i].id); @@ -595,7 +607,7 @@ throw (CF::UnknownProperties, CORBA::SystemException) compId = ossie::corba::returnString(_properties[extId].second->identifier()); } else { propId = extId; - compId = ossie::corba::returnString(assemblyController->identifier()); + compId = _assemblyController->getIdentifier(); } // Loops through batched query results finding requested property @@ -641,8 +653,9 @@ char *Application_impl::registerPropertyListener( CORBA::Object_ptr listener, co ossie::corba::returnString(comp->identifier()) << "/" << prop_id); comp_regs[ comp ].push_back( prop_id ); - } else if (!CORBA::is_nil(assemblyController)) { - comp_regs[ assemblyController ].push_back( extId ) ; + } else if (_assemblyController) { + CF::Resource_var ac_resource = _assemblyController->getResourcePtr(); + comp_regs[ac_resource].push_back(extId); } } @@ -718,11 +731,14 @@ void Application_impl::unregisterPropertyListener( const char *reg_id ) void Application_impl::initialize () throw (CORBA::SystemException, CF::LifeCycle::InitializeError) { - if (CORBA::is_nil(assemblyController)) { return; } + if (!_assemblyController) { + return; + } try { - LOG_TRACE(Application_impl, "Calling initialize on assembly controller") - assemblyController->initialize (); + LOG_TRACE(Application_impl, "Calling initialize on assembly controller"); + CF::Resource_var resource = _assemblyController->getResourcePtr(); + resource->initialize(); } catch( CF::LifeCycle::InitializeError& ie ) { LOG_ERROR(Application_impl, "Initialize failed with CF::LifeCycle::InitializeError") throw; @@ -803,14 +819,15 @@ void Application_impl::runTest (CORBA::ULong _testId, CF::Properties& _props) throw (CORBA::SystemException, CF::UnknownProperties, CF::TestableObject::UnknownTest) { - if (CORBA::is_nil(assemblyController)) { + if (!_assemblyController) { LOG_ERROR(Application_impl, "Run test called with non SCA compliant assembly controller"); throw CF::TestableObject::UnknownTest(); } try { - LOG_TRACE(Application_impl, "Calling runTest on assembly controller") - assemblyController->runTest (_testId, _props); + LOG_TRACE(Application_impl, "Calling runTest on assembly controller"); + CF::Resource_var resource = _assemblyController->getResourcePtr(); + resource->runTest(_testId, _props); } catch( CF::UnknownProperties& up ) { std::ostringstream eout; eout << "Run test failed with CF::UnknownProperties for Test ID " << _testId << " for properties: "; @@ -867,8 +884,6 @@ throw (CORBA::SystemException, CF::LifeCycle::ReleaseError) LOG_TRACE(Application_impl, "Error occurred while stopping the application during tear-down. Ignoring the error and continuing") } - assemblyController = CF::Resource::_nil (); - try { // Break all connections in the application ConnectionManager::disconnectAll(_connections, _domainManager); diff --git a/redhawk/src/control/sdr/dommgr/Application_impl.h b/redhawk/src/control/sdr/dommgr/Application_impl.h index cc80cd229..92195f9b2 100644 --- a/redhawk/src/control/sdr/dommgr/Application_impl.h +++ b/redhawk/src/control/sdr/dommgr/Application_impl.h @@ -47,17 +47,13 @@ class Application_impl : public virtual POA_CF::Application, public Logging_impl ENABLE_LOGGING friend class DomainManager_impl; -protected: - CF::Resource_var assemblyController; - public: Application_impl (const std::string& id, const std::string& name, const std::string& profile, DomainManager_impl* domainManager, const std::string& waveformContextName, CosNaming::NamingContext_ptr waveformContext, bool aware, CosNaming::NamingContext_ptr DomainContext); - void populateApplication (CF::Resource_ptr _assemblyController, - const CF::DeviceAssignmentSequence& deviceAssignments, + void populateApplication (const CF::DeviceAssignmentSequence& deviceAssignments, std::vector _startSeq, std::vector& connections, std::vector allocationIDs); @@ -132,6 +128,9 @@ class Application_impl : public virtual POA_CF::Application, public Logging_impl CF::ApplicationRegistrar_ptr appReg (void); + void setAssemblyController (const std::string& assemblyControllerRef); + redhawk::ApplicationComponent* getAssemblyController(); + const std::string& getIdentifier() const; const std::string& getName() const; const std::string& getProfile() const; @@ -182,6 +181,7 @@ class Application_impl : public virtual POA_CF::Application, public Logging_impl bool _checkRegistrations(std::set& identifiers); + redhawk::ApplicationComponent* _assemblyController; const std::string _identifier; const std::string _sadProfile; const std::string _appName; diff --git a/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp b/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp index 64fcfb26d..347abc4cc 100644 --- a/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp @@ -2464,11 +2464,10 @@ Application_impl* DomainManager_impl::_restoreApplication(ossie::ApplicationNode CosNaming::NamingContext::_nil()); LOG_TRACE(DomainManager_impl, "Restored " << node.connections.size() << " connections"); - application->populateApplication(node.assemblyController, - node.componentDevices, - node.componentRefs, - node.connections, - node.allocationIDs); + application->populateApplication(node.componentDevices, + node.componentRefs, + node.connections, + node.allocationIDs); // Restore various state about the components in the waveform BOOST_FOREACH(ossie::ComponentNode& compNode, node.components) { @@ -2492,6 +2491,7 @@ Application_impl* DomainManager_impl::_restoreApplication(ossie::ApplicationNode component.isContainer = compNode.isContainer; application->_components.push_back(component); } + application->setAssemblyController(node.assemblyControllerId); // Add external ports for (std::map::const_iterator it = node.ports.begin(); @@ -2534,7 +2534,7 @@ void DomainManager_impl::_persistApplication(Application_impl* application) compNode.isContainer = component.isContainer; appNode.components.push_back(compNode); } - appNode.assemblyController = CF::Resource::_duplicate(application->assemblyController); + appNode.assemblyControllerId = application->getAssemblyController()->getIdentifier(); appNode.componentRefs.clear(); for (unsigned int i = 0; i < application->_appStartSeq.size(); ++i) { appNode.componentRefs.push_back(CF::Resource::_duplicate(application->_appStartSeq[i])); diff --git a/redhawk/src/control/sdr/dommgr/PersistenceStore.h b/redhawk/src/control/sdr/dommgr/PersistenceStore.h index 9174f5bca..da57da7aa 100644 --- a/redhawk/src/control/sdr/dommgr/PersistenceStore.h +++ b/redhawk/src/control/sdr/dommgr/PersistenceStore.h @@ -126,7 +126,7 @@ namespace ossie { CosNaming::NamingContext_var context; CF::DeviceAssignmentSequence componentDevices; ossie::ComponentList components; - CF::Resource_var assemblyController; + std::string assemblyControllerId; std::vector connections; std::vector allocationIDs; std::vector componentRefs; @@ -283,7 +283,7 @@ namespace boost { ar & (node.context); ar & (node.componentDevices); ar & (node.components); - ar & (node.assemblyController); + ar & (node.assemblyControllerId); ar & (node.allocationIDs); ar & (node.connections); ar & (node.componentRefs); From 02f029c46e8438cae23b55602ed5e4037916c952 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 27 Oct 2016 15:06:36 -0400 Subject: [PATCH 0499/1644] Maintain application start order as a list of pointers to ApplicationComponents instead of CORBA refs --- .../sdr/dommgr/ApplicationComponent.cpp | 19 +++++ .../control/sdr/dommgr/ApplicationComponent.h | 3 + .../sdr/dommgr/ApplicationFactory_impl.cpp | 11 +-- .../control/sdr/dommgr/Application_impl.cpp | 79 ++++++++----------- .../src/control/sdr/dommgr/Application_impl.h | 7 +- .../control/sdr/dommgr/DomainManager_impl.cpp | 17 ++-- .../src/control/sdr/dommgr/PersistenceStore.h | 4 +- redhawk/src/control/sdr/dommgr/createHelper.h | 2 +- 8 files changed, 79 insertions(+), 63 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp b/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp index fed1bbf55..bccfd278c 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp @@ -134,6 +134,25 @@ void ApplicationComponent::setAssignedDevice(const boost::shared_ptrstart(); +} + +bool ApplicationComponent::stop() +{ + const unsigned long timeout = 3; // seconds + omniORB::setClientCallTimeout(_resource, timeout * 1000); + try { + _resource->stop(); + return true; + } catch (const CF::Resource::StopError& error) { + LOG_ERROR(Application_impl, "Failed to stop " << _identifier << "; CF::Resource::StopError '" << error.msg << "'"); + } CATCH_LOG_ERROR(Application_impl, "Failed to stop " << _identifier); + return false; +} + void ApplicationComponent::releaseObject() { if (!isRegistered()) { diff --git a/redhawk/src/control/sdr/dommgr/ApplicationComponent.h b/redhawk/src/control/sdr/dommgr/ApplicationComponent.h index ad0c7027e..e5b02b9a4 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationComponent.h +++ b/redhawk/src/control/sdr/dommgr/ApplicationComponent.h @@ -63,6 +63,9 @@ namespace redhawk { bool isContainer; + void start(); + bool stop(); + void releaseObject(); void terminate(); void unloadFiles(); diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 10e92509c..b8b4ffdf9 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -913,9 +913,10 @@ CF::Application_ptr createHelper::create ( } } - std::vector start_order = getStartOrder(app_deployment.getComponentDeployments()); + std::vector start_order = getStartOrder(app_deployment.getComponentDeployments()); + _application->setStartOrder(start_order); + _application->populateApplication(app_devices, - start_order, connections, allocationIDs); @@ -1994,7 +1995,7 @@ void createHelper::connectComponents(redhawk::ApplicationDeployment& appDeployme std::copy(establishedConnections.begin(), establishedConnections.end(), std::back_inserter(connections)); } -std::vector createHelper::getStartOrder(const DeploymentList& deployments) +std::vector createHelper::getStartOrder(const DeploymentList& deployments) { LOG_TRACE(ApplicationFactory_impl, "Assigning start order"); @@ -2018,12 +2019,12 @@ std::vector createHelper::getStartOrder(const DeploymentList& } // Build the start order vector in the right order - std::vector start_order; + std::vector start_order; int index = 1; for (StartOrderMap::iterator ii = start_map.begin(); ii != start_map.end(); ++ii, ++index) { LOG_TRACE(ApplicationFactory_impl, index << ": " << ii->second->getInstantiation()->getID()); - start_order.push_back(ii->second->getResourcePtr()); + start_order.push_back(ii->second->getIdentifier()); } return start_order; } diff --git a/redhawk/src/control/sdr/dommgr/Application_impl.cpp b/redhawk/src/control/sdr/dommgr/Application_impl.cpp index fcec1e962..a9368e5a6 100644 --- a/redhawk/src/control/sdr/dommgr/Application_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/Application_impl.cpp @@ -22,6 +22,8 @@ #include #include +#include + #include #include #include @@ -145,14 +147,12 @@ redhawk::ApplicationComponent* Application_impl::getAssemblyController() } void Application_impl::populateApplication(const CF::DeviceAssignmentSequence& assignedDevices, - std::vector _startSeq, std::vector& connections, std::vector allocationIDs) { TRACE_ENTER(Application_impl) _connections = connections; _componentDevices = assignedDevices; - _appStartSeq = _startSeq; LOG_DEBUG(Application_impl, "Creating allocation sequence"); this->_allocationIDs = allocationIDs; @@ -160,6 +160,19 @@ void Application_impl::populateApplication(const CF::DeviceAssignmentSequence& a TRACE_EXIT(Application_impl) } +void Application_impl::setStartOrder(const std::vector& startOrder) +{ + _startOrder.clear(); + BOOST_FOREACH(const std::string& componentId, startOrder) { + redhawk::ApplicationComponent* component = findComponent(componentId); + if (component) { + _startOrder.push_back(component); + } else { + LOG_WARN(Application_impl, "Invalid component '" << componentId << "' in start order"); + } + } +} + Application_impl::~Application_impl () { TRACE_ENTER(Application_impl) @@ -203,24 +216,20 @@ CORBA::Boolean Application_impl::started () throw (CORBA::SystemException) void Application_impl::start () throw (CORBA::SystemException, CF::Resource::StartError) { - if (!_assemblyController && _appStartSeq.empty()) { + if (!_assemblyController && _startOrder.empty()) { throw CF::Resource::StartError(CF::CF_ENOTSUP, "No assembly controller and no Components with startorder set"); } try { - CF::Resource_var resource = _assemblyController->getResourcePtr(); - omniORB::setClientCallTimeout(resource, 0); - LOG_TRACE(Application_impl, "Calling start on assembly controller") - resource->start (); + if (_assemblyController) { + LOG_TRACE(Application_impl, "Calling start on assembly controller"); + _assemblyController->start(); + } // Start the rest of the components - for (unsigned int i = 0; i < _appStartSeq.size(); i++){ - std::string msg = "Calling start for "; - msg = msg.append(ossie::corba::returnString(_appStartSeq[i]->identifier())); - LOG_TRACE(Application_impl, msg) - - omniORB::setClientCallTimeout(_appStartSeq[i], 0); - _appStartSeq[i]-> start(); + BOOST_FOREACH(redhawk::ApplicationComponent* component, _startOrder) { + LOG_TRACE(Application_impl, "Calling start for " << component->getIdentifier()); + component->start(); } } catch( CF::Resource::StartError& se ) { LOG_ERROR(Application_impl, "Start failed with CF:Resource::StartError") @@ -237,51 +246,29 @@ throw (CORBA::SystemException, CF::Resource::StartError) } } - -bool Application_impl::stopComponent (CF::Resource_ptr component) -{ - std::string identifier; - try { - identifier = ossie::corba::returnString(component->identifier()); - } catch (const CORBA::SystemException& ex) { - LOG_ERROR(Application_impl, "CORBA::" << ex._name() << " getting component identifier"); - return false; - } catch (...) { - LOG_ERROR(Application_impl, "Unknown exception getting component identifier"); - return false; - } - LOG_TRACE(Application_impl, "Calling stop for " << identifier); - const unsigned long timeout = 3; // seconds - omniORB::setClientCallTimeout(component, timeout * 1000); - try { - component->stop(); - return true; - } catch (const CF::Resource::StopError& error) { - LOG_ERROR(Application_impl, "Failed to stop " << identifier << "; CF::Resource::StopError '" << error.msg << "'"); - } CATCH_LOG_ERROR(Application_impl, "Failed to stop " << identifier); - return false; -} - void Application_impl::stop () throw (CORBA::SystemException, CF::Resource::StopError) { - if (!_assemblyController && _appStartSeq.empty()) { + if (!_assemblyController && _startOrder.empty()) { throw CF::Resource::StopError(CF::CF_ENOTSUP, "No assembly controller and no Components with startorder set"); } int failures = 0; // Stop the components in the reverse order they were started - for (int i = (int)(_appStartSeq.size()-1); i >= 0; i--){ - if (!stopComponent(_appStartSeq[i])) { + BOOST_REVERSE_FOREACH(redhawk::ApplicationComponent* component, _startOrder) { + LOG_TRACE(Application_impl, "Calling stop for " << component->getIdentifier()); + if (!component->stop()) { failures++; } } - LOG_TRACE(Application_impl, "Calling stop on assembly controller"); - CF::Resource_var ac_resource = _assemblyController->getResourcePtr(); - if (!stopComponent(ac_resource)) { - failures++; + if (_assemblyController) { + LOG_TRACE(Application_impl, "Calling stop on assembly controller"); + if (!_assemblyController->stop()) { + failures++; + } } + if (failures > 0) { std::ostringstream oss; oss << failures << " component(s) failed to stop"; diff --git a/redhawk/src/control/sdr/dommgr/Application_impl.h b/redhawk/src/control/sdr/dommgr/Application_impl.h index 92195f9b2..4250ddd6a 100644 --- a/redhawk/src/control/sdr/dommgr/Application_impl.h +++ b/redhawk/src/control/sdr/dommgr/Application_impl.h @@ -54,10 +54,11 @@ class Application_impl : public virtual POA_CF::Application, public Logging_impl CosNaming::NamingContext_ptr waveformContext, bool aware, CosNaming::NamingContext_ptr DomainContext); void populateApplication (const CF::DeviceAssignmentSequence& deviceAssignments, - std::vector _startSeq, std::vector& connections, std::vector allocationIDs); + void setStartOrder(const std::vector& startOrder); + ~Application_impl (); static PortableServer::ObjectId* Activate(Application_impl* application); @@ -177,8 +178,6 @@ class Application_impl : public virtual POA_CF::Application, public Logging_impl void registerComponent(CF::Resource_ptr resource); - bool stopComponent(CF::Resource_ptr component); - bool _checkRegistrations(std::set& identifiers); redhawk::ApplicationComponent* _assemblyController; @@ -187,7 +186,7 @@ class Application_impl : public virtual POA_CF::Application, public Logging_impl const std::string _appName; CF::DeviceAssignmentSequence _componentDevices; std::vector _connections; - std::vector _appStartSeq; + std::vector _startOrder; std::vector _allocationIDs; DomainManager_impl* _domainManager; const std::string _waveformContextName; diff --git a/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp b/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp index 347abc4cc..356f0142d 100644 --- a/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp @@ -2465,7 +2465,6 @@ Application_impl* DomainManager_impl::_restoreApplication(ossie::ApplicationNode LOG_TRACE(DomainManager_impl, "Restored " << node.connections.size() << " connections"); application->populateApplication(node.componentDevices, - node.componentRefs, node.connections, node.allocationIDs); @@ -2492,6 +2491,7 @@ Application_impl* DomainManager_impl::_restoreApplication(ossie::ApplicationNode application->_components.push_back(component); } application->setAssemblyController(node.assemblyControllerId); + application->setStartOrder(node.startOrder); // Add external ports for (std::map::const_iterator it = node.ports.begin(); @@ -2534,11 +2534,18 @@ void DomainManager_impl::_persistApplication(Application_impl* application) compNode.isContainer = component.isContainer; appNode.components.push_back(compNode); } - appNode.assemblyControllerId = application->getAssemblyController()->getIdentifier(); - appNode.componentRefs.clear(); - for (unsigned int i = 0; i < application->_appStartSeq.size(); ++i) { - appNode.componentRefs.push_back(CF::Resource::_duplicate(application->_appStartSeq[i])); + + // If an assembly controller is set, store it by identifier + redhawk::ApplicationComponent* assembly_controller = application->getAssemblyController(); + if (assembly_controller) { + appNode.assemblyControllerId = assembly_controller->getIdentifier(); + } + + // Save the start order, storing just the component identifiers + BOOST_FOREACH(redhawk::ApplicationComponent* component, application->_startOrder) { + appNode.startOrder.push_back(component->getIdentifier()); } + appNode.allocationIDs = application->_allocationIDs; appNode.connections = application->_connections; appNode.aware_application = application->_isAware; diff --git a/redhawk/src/control/sdr/dommgr/PersistenceStore.h b/redhawk/src/control/sdr/dommgr/PersistenceStore.h index da57da7aa..2e25c03c7 100644 --- a/redhawk/src/control/sdr/dommgr/PersistenceStore.h +++ b/redhawk/src/control/sdr/dommgr/PersistenceStore.h @@ -129,7 +129,7 @@ namespace ossie { std::string assemblyControllerId; std::vector connections; std::vector allocationIDs; - std::vector componentRefs; + std::vector startOrder; std::map ports; std::map > properties; bool aware_application; @@ -286,7 +286,7 @@ namespace boost { ar & (node.assemblyControllerId); ar & (node.allocationIDs); ar & (node.connections); - ar & (node.componentRefs); + ar & (node.startOrder); ar & (node.ports); ar & (node.properties); } diff --git a/redhawk/src/control/sdr/dommgr/createHelper.h b/redhawk/src/control/sdr/dommgr/createHelper.h index 50cd13a2a..705709505 100644 --- a/redhawk/src/control/sdr/dommgr/createHelper.h +++ b/redhawk/src/control/sdr/dommgr/createHelper.h @@ -175,7 +175,7 @@ class createHelper std::string base_naming_context); std::string resolveLoggingConfiguration(redhawk::ComponentDeployment* deployment); - std::vector getStartOrder(const DeploymentList& deployments); + std::vector getStartOrder(const DeploymentList& deployments); // Cleanup - used when create fails/doesn't succeed for some reason bool _isComplete; From 3b456632569dff1f57ad5a383b14b56bfb966b5f Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 27 Oct 2016 15:35:58 -0400 Subject: [PATCH 0500/1644] Consolidate ApplicationComponent creation --- .../control/sdr/dommgr/Application_impl.cpp | 37 ++++++++++--------- .../src/control/sdr/dommgr/Application_impl.h | 1 + .../control/sdr/dommgr/DomainManager_impl.cpp | 18 ++++----- 3 files changed, 29 insertions(+), 27 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/Application_impl.cpp b/redhawk/src/control/sdr/dommgr/Application_impl.cpp index a9368e5a6..07ad16d2e 100644 --- a/redhawk/src/control/sdr/dommgr/Application_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/Application_impl.cpp @@ -1225,9 +1225,7 @@ void Application_impl::registerComponent (CF::Resource_ptr resource) if (!comp) { LOG_WARN(Application_impl, "Unexpected component '" << componentId << "' registered with application '" << _appName << "'"); - _components.push_back(redhawk::ApplicationComponent(componentId)); - comp = &(_components.back()); - comp->setSoftwareProfile(softwareProfile); + comp = addComponent(componentId, softwareProfile); } else if (softwareProfile != comp->getSoftwareProfile()) { // Mismatch between expected and reported SPD path LOG_WARN(Application_impl, "Component '" << componentId << "' software profile " << softwareProfile @@ -1269,6 +1267,15 @@ redhawk::ApplicationComponent* Application_impl::findComponent(const std::string return 0; } +redhawk::ApplicationComponent* Application_impl::addComponent(const std::string& componentId, + const std::string& softwareProfile) +{ + _components.push_back(redhawk::ApplicationComponent(componentId)); + redhawk::ApplicationComponent* component = &(_components.back()); + component->setSoftwareProfile(softwareProfile); + return component; +} + redhawk::ApplicationComponent* Application_impl::addContainer(const redhawk::ContainerDeployment* container) { const std::string& identifier = container->getIdentifier(); @@ -1277,13 +1284,11 @@ redhawk::ApplicationComponent* Application_impl::addContainer(const redhawk::Con } const std::string& profile = container->getSoftPkg()->getSPDFile(); LOG_DEBUG(Application_impl, "Adding container '" << identifier << "' with profile " << profile); - redhawk::ApplicationComponent component(identifier); - component.setSoftwareProfile(profile); - component.isContainer = true; - component.setImplementationId(container->getImplementation()->getID()); - component.setAssignedDevice(container->getAssignedDevice()); - _components.push_back(component); - return &(_components.back()); + redhawk::ApplicationComponent* component = addComponent(identifier, profile); + component->isContainer = true; + component->setImplementationId(container->getImplementation()->getID()); + component->setAssignedDevice(container->getAssignedDevice()); + return component; } redhawk::ApplicationComponent* Application_impl::addComponent(const redhawk::ComponentDeployment* deployment) @@ -1294,13 +1299,11 @@ redhawk::ApplicationComponent* Application_impl::addComponent(const redhawk::Com } const std::string& profile = deployment->getSoftPkg()->getSPDFile(); LOG_DEBUG(Application_impl, "Adding component '" << identifier << "' with profile " << profile); - redhawk::ApplicationComponent component(identifier); - component.setSoftwareProfile(profile); - component.isContainer = false; - component.setImplementationId(deployment->getImplementation()->getID()); - component.setAssignedDevice(deployment->getAssignedDevice()); - _components.push_back(component); - return &(_components.back()); + redhawk::ApplicationComponent* component = addComponent(identifier, profile); + component->isContainer = false; + component->setImplementationId(deployment->getImplementation()->getID()); + component->setAssignedDevice(deployment->getAssignedDevice()); + return component; } void Application_impl::componentTerminated(const std::string& componentId, const std::string& deviceId) diff --git a/redhawk/src/control/sdr/dommgr/Application_impl.h b/redhawk/src/control/sdr/dommgr/Application_impl.h index 4250ddd6a..98f0073b3 100644 --- a/redhawk/src/control/sdr/dommgr/Application_impl.h +++ b/redhawk/src/control/sdr/dommgr/Application_impl.h @@ -145,6 +145,7 @@ class Application_impl : public virtual POA_CF::Application, public Logging_impl void _cleanupActivations(); // Set component state + redhawk::ApplicationComponent* addComponent(const std::string& componentId, const std::string& softwareProfile); redhawk::ApplicationComponent* addComponent(const redhawk::ComponentDeployment* deployment); redhawk::ApplicationComponent* addContainer(const redhawk::ContainerDeployment* container); diff --git a/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp b/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp index 356f0142d..7db4f2ee2 100644 --- a/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp @@ -2470,25 +2470,23 @@ Application_impl* DomainManager_impl::_restoreApplication(ossie::ApplicationNode // Restore various state about the components in the waveform BOOST_FOREACH(ossie::ComponentNode& compNode, node.components) { - redhawk::ApplicationComponent component(compNode.identifier); - component.setSoftwareProfile(compNode.softwareProfile); - component.setNamingContext(compNode.namingContext); - component.setImplementationId(compNode.implementationId); + redhawk::ApplicationComponent* component = application->addComponent(compNode.identifier, compNode.softwareProfile); + component->setNamingContext(compNode.namingContext); + component->setImplementationId(compNode.implementationId); BOOST_FOREACH(const std::string& filename, compNode.loadedFiles) { - component.addLoadedFile(filename); + component->addLoadedFile(filename); } - component.setProcessId(compNode.processId); - component.setComponentObject(compNode.componentObject); + component->setProcessId(compNode.processId); + component->setComponentObject(compNode.componentObject); ossie::DeviceList::iterator device = findDeviceById(compNode.assignedDeviceId); if (device == _registeredDevices.end()) { LOG_WARN(DomainManager_impl, "Could not find assigned device '" << compNode.assignedDeviceId << "' for application '" << node.name << "' component '" << compNode.identifier); } else { - component.setAssignedDevice(*device); + component->setAssignedDevice(*device); } - component.isContainer = compNode.isContainer; - application->_components.push_back(component); + component->isContainer = compNode.isContainer; } application->setAssemblyController(node.assemblyControllerId); application->setStartOrder(node.startOrder); From 6db2270fdf7409d3c3d9015837defbd15c62a5f3 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 27 Oct 2016 16:39:57 -0400 Subject: [PATCH 0501/1644] Clean up unneeded narrows and c_str() calls --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 31 +++++++++---------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index b8b4ffdf9..801a2028f 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -936,13 +936,11 @@ CF::Application_ptr createHelper::create ( // so update the domain manager _appFact._domainManager->setLastDeviceUsedForDeployment(_executableDevices.front()->identifier); - if ( _appFact._domainManager ) { - _appFact._domainManager->sendAddEvent( _appFact._identifier.c_str(), - app_deployment.getIdentifier().c_str(), - name, - appObj, - StandardEvent::APPLICATION); - } + _appFact._domainManager->sendAddEvent(_appFact._identifier, + app_deployment.getIdentifier(), + name, + appObj, + StandardEvent::APPLICATION); LOG_INFO(ApplicationFactory_impl, "Done creating application " << app_deployment.getIdentifier() << " " << name); _isComplete = true; @@ -1477,9 +1475,8 @@ void createHelper::loadAndExecuteContainers(const ContainerList& containers, throw redhawk::ComponentError(container, "empty localfile"); } - // narrow to LoadableDevice interface - CF::LoadableDevice_var loadabledev = ossie::corba::_narrowSafe(device->device); - if (CORBA::is_nil(loadabledev)) { + // Check for LoadableDevice interface + if (!device->isLoadable()) { std::ostringstream message; message << "container " << container->getIdentifier() << " was assigned to non-loadable device " << device->identifier; @@ -1490,7 +1487,7 @@ void createHelper::loadAndExecuteContainers(const ContainerList& containers, LOG_TRACE(ApplicationFactory_impl, "Loading " << codeLocalFile << " and dependencies on device " << device->label); try { - container->load(_appFact._fileMgr, loadabledev); + container->load(_appFact._fileMgr, device->loadableDevice); } catch (const std::exception& exc) { throw redhawk::ComponentError(container, exc.what()); } @@ -1543,9 +1540,8 @@ void createHelper::loadAndExecuteComponents(const DeploymentList& deployments, throw redhawk::ComponentError(deployment, "empty localfile"); } - // narrow to LoadableDevice interface - CF::LoadableDevice_var loadabledev = ossie::corba::_narrowSafe(device->device); - if (CORBA::is_nil(loadabledev)) { + // Check for LoadableDevice interface + if (!device->isLoadable()) { std::ostringstream message; message << "component " << component_id << " was assigned to non-loadable device " << device->identifier; @@ -1556,7 +1552,7 @@ void createHelper::loadAndExecuteComponents(const DeploymentList& deployments, LOG_TRACE(ApplicationFactory_impl, "Loading " << codeLocalFile << " and dependencies on device " << device->label); try { - deployment->load(_appFact._fileMgr, loadabledev); + deployment->load(_appFact._fileMgr, device->loadableDevice); } catch (const std::exception& exc) { throw redhawk::ComponentError(deployment, exc.what()); } @@ -1610,8 +1606,7 @@ void createHelper::attemptComponentExecution (CF::ApplicationRegistrar_ptr regis { // Get executable device reference boost::shared_ptr device = deployment->getAssignedDevice(); - CF::ExecutableDevice_var execdev = ossie::corba::_narrowSafe(device->device); - if (CORBA::is_nil(execdev)){ + if (!device->isExecutable()){ std::ostringstream message; message << "component " << deployment->getIdentifier() << " was assigned to non-executable device " << device->identifier; @@ -1685,6 +1680,7 @@ void createHelper::attemptComponentExecution (CF::ApplicationRegistrar_ptr regis } // Attempt to execute the component + CF::ExecutableDevice_var execdev; if (deployment->getContainer()) { LOG_TRACE(ApplicationFactory_impl, "Executing " << entryPoint << " via container on device " << device->label); redhawk::ComponentDeployment* container = deployment->getContainer(); @@ -1692,6 +1688,7 @@ void createHelper::attemptComponentExecution (CF::ApplicationRegistrar_ptr regis execdev = CF::ExecutableDevice::_narrow(resource); } else { LOG_TRACE(ApplicationFactory_impl, "Executing " << entryPoint << " on device " << device->label); + execdev = CF::ExecutableDevice::_duplicate(device->executableDevice); } for (redhawk::PropertyMap::iterator prop = execParameters.begin(); prop != execParameters.end(); ++prop) { LOG_TRACE(ApplicationFactory_impl, " exec param " << prop->getId() << " " << prop->getValue().toString()); From 08345afda49f250f26d47cad83585b6a7eb4adf9 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 27 Oct 2016 17:42:16 -0400 Subject: [PATCH 0502/1644] Associate ApplicationComponents with their ComponentHost, and report its pid as their own --- .../sdr/ComponentHost/ComponentHost.cpp | 2 +- .../sdr/dommgr/ApplicationComponent.cpp | 20 ++++++++++++++++--- .../control/sdr/dommgr/ApplicationComponent.h | 4 ++++ .../sdr/dommgr/ApplicationFactory_impl.cpp | 3 +++ .../control/sdr/dommgr/DomainManager_impl.cpp | 11 ++++++++++ .../src/control/sdr/dommgr/PersistenceStore.h | 2 ++ 6 files changed, 38 insertions(+), 4 deletions(-) diff --git a/redhawk/src/control/sdr/ComponentHost/ComponentHost.cpp b/redhawk/src/control/sdr/ComponentHost/ComponentHost.cpp index 06fa74a5c..fe9fa7f35 100644 --- a/redhawk/src/control/sdr/ComponentHost/ComponentHost.cpp +++ b/redhawk/src/control/sdr/ComponentHost/ComponentHost.cpp @@ -177,7 +177,7 @@ CF::ExecutableDevice::ProcessID_Type ComponentHost::executeLinked(const char* na component->bundle.swap(bundle); component->servant = servant; - int thread_id = (++counter) | getpid() << 16; + int thread_id = ++counter; activeComponents[thread_id] = component; LOG_DEBUG(ComponentHost, "Assigning thread ID " << thread_id); diff --git a/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp b/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp index bccfd278c..d6f4144de 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp @@ -29,6 +29,7 @@ using redhawk::ApplicationComponent; ApplicationComponent::ApplicationComponent(const std::string& identifier) : _identifier(identifier), + _componentHost(0), _processId(0) { } @@ -73,8 +74,21 @@ void ApplicationComponent::setImplementationId(const std::string& implementation _implementationId = implementationId; } +ApplicationComponent* ApplicationComponent::getComponentHost() +{ + return _componentHost; +} + +void ApplicationComponent::setComponentHost(ApplicationComponent* componentHost) +{ + _componentHost = componentHost; +} + unsigned long ApplicationComponent::getProcessId() const { + if (_componentHost) { + return _componentHost->getProcessId(); + } return _processId; } @@ -170,9 +184,9 @@ void ApplicationComponent::releaseObject() void ApplicationComponent::terminate() { - // TODO: PIDs are not necessarily capped at 64K; the limit is system- - // dependent - if (_processId == 0 || _processId >= 65536) { + // If the process already terminated, or the component is running inside of + // a ComponentHost instance, skip termination + if (isTerminated() || _componentHost) { return; } diff --git a/redhawk/src/control/sdr/dommgr/ApplicationComponent.h b/redhawk/src/control/sdr/dommgr/ApplicationComponent.h index e5b02b9a4..b7206fbb8 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationComponent.h +++ b/redhawk/src/control/sdr/dommgr/ApplicationComponent.h @@ -43,6 +43,9 @@ namespace redhawk { const std::string& getImplementationId() const; void setImplementationId(const std::string& implementationId); + ApplicationComponent* getComponentHost(); + void setComponentHost(ApplicationComponent* componentHost); + unsigned long getProcessId() const; void setProcessId(unsigned long processId); @@ -75,6 +78,7 @@ namespace redhawk { std::string _softwareProfile; std::string _namingContext; std::string _implementationId; + ApplicationComponent* _componentHost; std::vector _loadedFiles; unsigned long _processId; CORBA::Object_var _componentObject; diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 801a2028f..5293f6ee6 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -1527,6 +1527,9 @@ void createHelper::loadAndExecuteComponents(const DeploymentList& deployments, if (instantiation->isNamingService()) { app_component->setNamingContext(_baseNamingContext + "/" + instantiation->getFindByNamingServiceName()); } + if (deployment->getContainer()) { + app_component->setComponentHost(deployment->getContainer()->getApplicationComponent()); + } deployment->setApplicationComponent(app_component); // get the code.localfile diff --git a/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp b/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp index 7db4f2ee2..f1ec0b8f0 100644 --- a/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp @@ -2487,6 +2487,14 @@ Application_impl* DomainManager_impl::_restoreApplication(ossie::ApplicationNode component->setAssignedDevice(*device); } component->isContainer = compNode.isContainer; + if (!compNode.componentHostId.empty()) { + redhawk::ApplicationComponent* host = application->findComponent(compNode.componentHostId); + if (!host) { + LOG_WARN(DomainManager_impl, "Could not find component host " << compNode.componentHostId); + } else { + component->setComponentHost(host); + } + } } application->setAssemblyController(node.assemblyControllerId); application->setStartOrder(node.startOrder); @@ -2530,6 +2538,9 @@ void DomainManager_impl::_persistApplication(Application_impl* application) compNode.componentObject = component.getComponentObject(); compNode.assignedDeviceId = component.getAssignedDevice()->identifier; compNode.isContainer = component.isContainer; + if (component.getComponentHost()) { + compNode.componentHostId = component.getComponentHost()->getIdentifier(); + } appNode.components.push_back(compNode); } diff --git a/redhawk/src/control/sdr/dommgr/PersistenceStore.h b/redhawk/src/control/sdr/dommgr/PersistenceStore.h index 2e25c03c7..731e0368e 100644 --- a/redhawk/src/control/sdr/dommgr/PersistenceStore.h +++ b/redhawk/src/control/sdr/dommgr/PersistenceStore.h @@ -115,6 +115,7 @@ namespace ossie { CORBA::Object_var componentObject; std::string assignedDeviceId; bool isContainer; + std::string componentHostId; }; typedef std::list ComponentList; @@ -272,6 +273,7 @@ namespace boost { ar & node.componentObject; ar & node.assignedDeviceId; ar & node.isContainer; + ar & node.componentHostId; } template From cd1bafb0068d1945c58690eb9540f99a6994e4eb Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 27 Oct 2016 18:33:53 -0400 Subject: [PATCH 0503/1644] Make ApplicationComponent-to-ComponentHost link bi-directional, using the presence of children as a signifier instead of an explicit flag --- .../src/control/sdr/dommgr/ApplicationComponent.cpp | 12 ++++++++++-- .../src/control/sdr/dommgr/ApplicationComponent.h | 6 ++++-- redhawk/src/control/sdr/dommgr/Application_impl.cpp | 12 +++++------- .../src/control/sdr/dommgr/DomainManager_impl.cpp | 2 -- redhawk/src/control/sdr/dommgr/PersistenceStore.h | 2 -- 5 files changed, 19 insertions(+), 15 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp b/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp index d6f4144de..036951d42 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp @@ -29,8 +29,8 @@ using redhawk::ApplicationComponent; ApplicationComponent::ApplicationComponent(const std::string& identifier) : _identifier(identifier), - _componentHost(0), - _processId(0) + _processId(0), + _componentHost(0) { } @@ -82,6 +82,14 @@ ApplicationComponent* ApplicationComponent::getComponentHost() void ApplicationComponent::setComponentHost(ApplicationComponent* componentHost) { _componentHost = componentHost; + if (_componentHost) { + _componentHost->_children.push_back(this); + } +} + +const std::vector& ApplicationComponent::getChildren() const +{ + return _children; } unsigned long ApplicationComponent::getProcessId() const diff --git a/redhawk/src/control/sdr/dommgr/ApplicationComponent.h b/redhawk/src/control/sdr/dommgr/ApplicationComponent.h index b7206fbb8..7636a7e31 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationComponent.h +++ b/redhawk/src/control/sdr/dommgr/ApplicationComponent.h @@ -64,7 +64,7 @@ namespace redhawk { const boost::shared_ptr& getAssignedDevice() const; void setAssignedDevice(const boost::shared_ptr& assignedDevice); - bool isContainer; + const std::vector& getChildren() const; void start(); bool stop(); @@ -78,12 +78,14 @@ namespace redhawk { std::string _softwareProfile; std::string _namingContext; std::string _implementationId; - ApplicationComponent* _componentHost; std::vector _loadedFiles; unsigned long _processId; CORBA::Object_var _componentObject; CF::Resource_var _resource; boost::shared_ptr _assignedDevice; + + ApplicationComponent* _componentHost; + std::vector _children; }; } diff --git a/redhawk/src/control/sdr/dommgr/Application_impl.cpp b/redhawk/src/control/sdr/dommgr/Application_impl.cpp index 07ad16d2e..d673925c7 100644 --- a/redhawk/src/control/sdr/dommgr/Application_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/Application_impl.cpp @@ -79,7 +79,7 @@ namespace { void convert_sequence(Sequence& out, Iterator begin, const Iterator end, Function func) { for (; begin != end; ++begin) { - if (!begin->isContainer) { + if (begin->getChildren().empty()) { ossie::corba::push_back(out, func(*begin)); } } @@ -95,7 +95,7 @@ namespace { void convert_sequence_if(Sequence& out, Iterator begin, const Iterator end, Function func, Predicate pred) { for (; begin != end; ++begin) { - if (!(begin->isContainer) && pred(*begin)) { + if (begin->getChildren().empty() && pred(*begin)) { ossie::corba::push_back(out, func(*begin)); } } @@ -983,14 +983,14 @@ throw (CORBA::SystemException, CF::LifeCycle::ReleaseError) void Application_impl::releaseComponents() { for (ComponentList::iterator ii = _components.begin(); ii != _components.end(); ++ii) { - if (!ii->isContainer) { + if (ii->getChildren().empty()) { // Release "real" components first ii->releaseObject(); } } for (ComponentList::iterator ii = _components.begin(); ii != _components.end(); ++ii) { - if (ii->isContainer) { + if (!ii->getChildren().empty()) { // Release containers once all "real" components have been released ii->releaseObject(); } @@ -1285,7 +1285,6 @@ redhawk::ApplicationComponent* Application_impl::addContainer(const redhawk::Con const std::string& profile = container->getSoftPkg()->getSPDFile(); LOG_DEBUG(Application_impl, "Adding container '" << identifier << "' with profile " << profile); redhawk::ApplicationComponent* component = addComponent(identifier, profile); - component->isContainer = true; component->setImplementationId(container->getImplementation()->getID()); component->setAssignedDevice(container->getAssignedDevice()); return component; @@ -1300,7 +1299,6 @@ redhawk::ApplicationComponent* Application_impl::addComponent(const redhawk::Com const std::string& profile = deployment->getSoftPkg()->getSPDFile(); LOG_DEBUG(Application_impl, "Adding component '" << identifier << "' with profile " << profile); redhawk::ApplicationComponent* component = addComponent(identifier, profile); - component->isContainer = false; component->setImplementationId(deployment->getImplementation()->getID()); component->setAssignedDevice(deployment->getAssignedDevice()); return component; @@ -1315,7 +1313,7 @@ void Application_impl::componentTerminated(const std::string& componentId, const << "' terminated abnormally on device " << deviceId); return; } - if (component->isContainer) { + if (!component->getChildren().empty()) { LOG_WARN(Application_impl, "Component host from application '" << _identifier << "' terminated abnormally on device " << deviceId); } else { diff --git a/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp b/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp index f1ec0b8f0..a5845547e 100644 --- a/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp @@ -2486,7 +2486,6 @@ Application_impl* DomainManager_impl::_restoreApplication(ossie::ApplicationNode } else { component->setAssignedDevice(*device); } - component->isContainer = compNode.isContainer; if (!compNode.componentHostId.empty()) { redhawk::ApplicationComponent* host = application->findComponent(compNode.componentHostId); if (!host) { @@ -2537,7 +2536,6 @@ void DomainManager_impl::_persistApplication(Application_impl* application) compNode.processId = component.getProcessId(); compNode.componentObject = component.getComponentObject(); compNode.assignedDeviceId = component.getAssignedDevice()->identifier; - compNode.isContainer = component.isContainer; if (component.getComponentHost()) { compNode.componentHostId = component.getComponentHost()->getIdentifier(); } diff --git a/redhawk/src/control/sdr/dommgr/PersistenceStore.h b/redhawk/src/control/sdr/dommgr/PersistenceStore.h index 731e0368e..360bd7016 100644 --- a/redhawk/src/control/sdr/dommgr/PersistenceStore.h +++ b/redhawk/src/control/sdr/dommgr/PersistenceStore.h @@ -114,7 +114,6 @@ namespace ossie { unsigned long processId; CORBA::Object_var componentObject; std::string assignedDeviceId; - bool isContainer; std::string componentHostId; }; typedef std::list ComponentList; @@ -272,7 +271,6 @@ namespace boost { ar & node.processId; ar & node.componentObject; ar & node.assignedDeviceId; - ar & node.isContainer; ar & node.componentHostId; } From 548ac0df851457fe896c5c0a3c947cffb79df639 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 28 Oct 2016 08:22:26 -0400 Subject: [PATCH 0504/1644] Use PropertyMap to collect invalid properties in Application query()/configure(); add extend() to PropertyMap and default nil value in PropertyType constructor --- redhawk/src/base/framework/PropertyMap.cpp | 5 ++ redhawk/src/base/include/ossie/PropertyMap.h | 2 + redhawk/src/base/include/ossie/PropertyType.h | 2 +- .../control/sdr/dommgr/Application_impl.cpp | 80 +++++-------------- 4 files changed, 26 insertions(+), 63 deletions(-) diff --git a/redhawk/src/base/framework/PropertyMap.cpp b/redhawk/src/base/framework/PropertyMap.cpp index 817e0de84..9c97bb6ce 100644 --- a/redhawk/src/base/framework/PropertyMap.cpp +++ b/redhawk/src/base/framework/PropertyMap.cpp @@ -130,6 +130,11 @@ void PropertyMap::push_back(const CF::DataType& property) ossie::corba::push_back(*this, property); } +void PropertyMap::extend(const CF::Properties& properties) +{ + ossie::corba::extend(*this, properties); +} + PropertyMap::iterator PropertyMap::begin() { return static_cast(this->get_buffer()); diff --git a/redhawk/src/base/include/ossie/PropertyMap.h b/redhawk/src/base/include/ossie/PropertyMap.h index 195928495..241a0adbe 100644 --- a/redhawk/src/base/include/ossie/PropertyMap.h +++ b/redhawk/src/base/include/ossie/PropertyMap.h @@ -66,6 +66,8 @@ namespace redhawk { void push_back (const CF::DataType& dt); + void extend(const CF::Properties& properties); + iterator begin(); iterator end(); diff --git a/redhawk/src/base/include/ossie/PropertyType.h b/redhawk/src/base/include/ossie/PropertyType.h index 16fabbbd4..fdc9863d5 100644 --- a/redhawk/src/base/include/ossie/PropertyType.h +++ b/redhawk/src/base/include/ossie/PropertyType.h @@ -42,7 +42,7 @@ namespace redhawk { explicit PropertyType(const CF::DataType& dt); PropertyType(const std::string& id, const CORBA::Any& value); - PropertyType(const std::string& id, const Value& value); + explicit PropertyType(const std::string& id, const Value& value=Value()); PropertyType& operator=(const CF::DataType& dt); diff --git a/redhawk/src/control/sdr/dommgr/Application_impl.cpp b/redhawk/src/control/sdr/dommgr/Application_impl.cpp index d673925c7..56845e41f 100644 --- a/redhawk/src/control/sdr/dommgr/Application_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/Application_impl.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include "Application_impl.h" #include "DomainManager_impl.h" @@ -296,17 +297,14 @@ throw (CF::PropertySet::PartialConfiguration, CF::PropertySet::InvalidConfigurat void Application_impl::configure (const CF::Properties& configProperties) throw (CF::PropertySet::PartialConfiguration, CF::PropertySet::InvalidConfiguration, CORBA::SystemException) { - int validProperties = 0; - CF::Properties invalidProperties; + redhawk::PropertyMap invalidProperties; // Creates a map from componentIdentifier -> (rsc_ptr, ConfigPropSet) // to allow for one batched configure call per component - - CF::Properties acProps; - const std::string acId = _assemblyController->getIdentifier(); + const std::string& acId = _assemblyController->getIdentifier(); CF::Resource_var ac_resource = _assemblyController->getResourcePtr(); std::map > batch; - batch[acId] = std::pair(ac_resource, acProps); + batch[acId] = std::pair(ac_resource, CF::Properties()); // Loop through each passed external property, mapping it with its respective resource for (unsigned int i = 0; i < configProperties.length(); ++i) { @@ -320,10 +318,7 @@ throw (CF::PropertySet::PartialConfiguration, CF::PropertySet::InvalidConfigurat if (CORBA::is_nil(comp)) { LOG_ERROR(Application_impl, "Unable to retrieve component for external property: " << extId); - int count = invalidProperties.length(); - invalidProperties.length(count + 1); - invalidProperties[count].id = CORBA::string_dup(extId.c_str()); - invalidProperties[count].value = configProperties[i].value; + invalidProperties.push_back(configProperties[i]); } else { // Key used for map const std::string compId = ossie::corba::returnString(comp->identifier()); @@ -355,10 +350,7 @@ throw (CF::PropertySet::PartialConfiguration, CF::PropertySet::InvalidConfigurat batch[acId].second[count].value = configProperties[i].value; } else { LOG_ERROR(Application_impl, "Unable to retrieve assembly controller for external property: " << extId); - int count = invalidProperties.length(); - invalidProperties.length(count + 1); - invalidProperties[count].id = CORBA::string_dup(extId.c_str()); - invalidProperties[count].value = configProperties[i].value; + invalidProperties.push_back(configProperties[i]); } } @@ -366,33 +358,20 @@ throw (CF::PropertySet::PartialConfiguration, CF::PropertySet::InvalidConfigurat // -Catch any errors for (std::map >::const_iterator comp = batch.begin(); comp != batch.end(); ++comp) { - int propLength = comp->second.second.length(); try { comp->second.first->configure(comp->second.second); - validProperties += propLength; } catch (CF::PropertySet::InvalidConfiguration e) { // Add invalid properties to return list - for (unsigned int i = 0; i < e.invalidProperties.length(); ++i) { - int count = invalidProperties.length(); - invalidProperties.length(count + 1); - invalidProperties[count].id = CORBA::string_dup(e.invalidProperties[i].id); - invalidProperties[count].value = e.invalidProperties[i].value; - } + invalidProperties.extend(e.invalidProperties); } catch (CF::PropertySet::PartialConfiguration e) { // Add invalid properties to return list - for (unsigned int i = 0; i < e.invalidProperties.length(); ++i) { - int count = invalidProperties.length(); - invalidProperties.length(count + 1); - invalidProperties[count].id = CORBA::string_dup(e.invalidProperties[i].id); - invalidProperties[count].value = e.invalidProperties[i].value; - } - validProperties += propLength - e.invalidProperties.length(); + invalidProperties.extend(e.invalidProperties); } } // Throw appropriate exception if any configure errors were handled - if (invalidProperties.length () > 0) { - if (validProperties > 0) { + if (!invalidProperties.empty()) { + if (invalidProperties.size() < configProperties.length()) { throw CF::PropertySet::PartialConfiguration(invalidProperties); } else { throw CF::PropertySet::InvalidConfiguration("No matching external properties found", invalidProperties); @@ -404,7 +383,7 @@ throw (CF::PropertySet::PartialConfiguration, CF::PropertySet::InvalidConfigurat void Application_impl::query (CF::Properties& configProperties) throw (CF::UnknownProperties, CORBA::SystemException) { - CF::Properties invalidProperties; + redhawk::PropertyMap invalidProperties; // Creates a map from componentIdentifier -> (rsc_ptr, ConfigPropSet) // to allow for one batched query call per component @@ -427,10 +406,7 @@ throw (CF::UnknownProperties, CORBA::SystemException) if (CORBA::is_nil(comp)) { LOG_ERROR(Application_impl, "Unable to retrieve component for external property: " << extId); - int count = invalidProperties.length(); - invalidProperties.length(count + 1); - invalidProperties[count].id = CORBA::string_dup(extId.c_str()); - invalidProperties[count].value = CORBA::Any(); + invalidProperties.push_back(redhawk::PropertyType(extId)); } else { // Key used for map const std::string compId = ossie::corba::returnString(comp->identifier()); @@ -470,13 +446,7 @@ throw (CF::UnknownProperties, CORBA::SystemException) configProperties[count].value = comp->second.second[i].value; } } catch (CF::UnknownProperties e) { - for (unsigned int i = 0; i < e.invalidProperties.length(); ++i) { - // Add invalid properties to return list - int count = invalidProperties.length(); - invalidProperties.length(count + 1); - invalidProperties[count].id = CORBA::string_dup(e.invalidProperties[i].id); - invalidProperties[count].value = e.invalidProperties[i].value; - } + invalidProperties.extend(e.invalidProperties); } } @@ -486,12 +456,10 @@ throw (CF::UnknownProperties, CORBA::SystemException) CF::Resource_var ac_resource = _assemblyController->getResourcePtr(); ac_resource->query(tempProp); } catch (CF::UnknownProperties e) { - int count = invalidProperties.length(); - invalidProperties.length(count + e.invalidProperties.length()); for (unsigned int i = 0; i < e.invalidProperties.length(); ++i) { LOG_ERROR(Application_impl, "Invalid assembly controller property name: " << e.invalidProperties[i].id); - invalidProperties[count + i] = e.invalidProperties[i]; } + invalidProperties.extend(e.invalidProperties); } // Adds Assembly Controller properties @@ -522,10 +490,7 @@ throw (CF::UnknownProperties, CORBA::SystemException) if (CORBA::is_nil(comp)) { LOG_ERROR(Application_impl, "Unable to retrieve component for external property: " << extId); - int count = invalidProperties.length(); - invalidProperties.length(count + 1); - invalidProperties[count].id = CORBA::string_dup(extId.c_str()); - invalidProperties[count].value = configProperties[i].value; + invalidProperties.push_back(configProperties[i]); } else { // Key used for map std::string compId = ossie::corba::returnString(comp->identifier()); @@ -558,10 +523,7 @@ throw (CF::UnknownProperties, CORBA::SystemException) batch[acId].second[count].value = configProperties[i].value; } else { LOG_ERROR(Application_impl, "Unable to retrieve assembly controller for external property: " << extId); - int count = invalidProperties.length(); - invalidProperties.length(count + 1); - invalidProperties[count].id = CORBA::string_dup(extId.c_str()); - invalidProperties[count].value = configProperties[i].value; + invalidProperties.push_back(configProperties[i]); } } @@ -572,13 +534,7 @@ throw (CF::UnknownProperties, CORBA::SystemException) try { comp->second.first->query(comp->second.second); } catch (CF::UnknownProperties e) { - for (unsigned int i = 0; i < e.invalidProperties.length(); ++i) { - // Add invalid properties to return list - int count = invalidProperties.length(); - invalidProperties.length(count + 1); - invalidProperties[count].id = CORBA::string_dup(e.invalidProperties[i].id); - invalidProperties[count].value = e.invalidProperties[i].value; - } + invalidProperties.extend(e.invalidProperties); } } @@ -610,7 +566,7 @@ throw (CF::UnknownProperties, CORBA::SystemException) } } - if (invalidProperties.length () != 0) { + if (!invalidProperties.empty()) { throw CF::UnknownProperties(invalidProperties); } From f6219f7403ae2580d2ee062f9624177e16d408e3 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 28 Oct 2016 09:02:27 -0400 Subject: [PATCH 0505/1644] Suppress error messages when stopping or releasing components whose processes are known to have terminated --- .../sdr/dommgr/ApplicationComponent.cpp | 27 +++++++++++++++---- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp b/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp index 036951d42..19361b5cb 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp @@ -112,7 +112,7 @@ bool ApplicationComponent::isResource() const bool ApplicationComponent::isTerminated() const { - return (_processId == 0); + return (getProcessId() == 0); } bool ApplicationComponent::isRegistered() const @@ -171,7 +171,17 @@ bool ApplicationComponent::stop() return true; } catch (const CF::Resource::StopError& error) { LOG_ERROR(Application_impl, "Failed to stop " << _identifier << "; CF::Resource::StopError '" << error.msg << "'"); - } CATCH_LOG_ERROR(Application_impl, "Failed to stop " << _identifier); + } catch (const CORBA::SystemException& exc) { + if (!isTerminated()) { + LOG_ERROR(Application_impl, "Failed to stop component '" << _identifier << "'; " + << ossie::corba::describeException(exc)); + } else { + LOG_DEBUG(Application_impl, "Ignoring CORBA exception stopping terminated component '" + << _identifier << "'"); + } + } catch (...) { + LOG_ERROR(Application_impl, "Failed to stop " << _identifier); + } return false; } @@ -183,10 +193,17 @@ void ApplicationComponent::releaseObject() LOG_DEBUG(Application_impl, "Releasing component '" << _identifier << "'"); try { - CF::Resource_var resource = CF::Resource::_narrow(_componentObject); unsigned long timeout = 3; // seconds; - omniORB::setClientCallTimeout(resource, timeout * 1000); - resource->releaseObject(); + omniORB::setClientCallTimeout(_resource, timeout * 1000); + _resource->releaseObject(); + } catch (const CORBA::SystemException& exc) { + if (!isTerminated()) { + LOG_ERROR(Application_impl, "Failed to release component '" << _identifier << "'; " + << ossie::corba::describeException(exc)); + } else { + LOG_DEBUG(Application_impl, "Ignoring CORBA exception releasing terminated component '" + << _identifier << "'"); + } } CATCH_LOG_WARN(Application_impl, "releaseObject failed for component '" << _identifier << "'"); } From 1c57b647a6fd0da9e1a062e435909ada20a3e053 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 28 Oct 2016 09:41:20 -0400 Subject: [PATCH 0506/1644] Check Application for connections that depend on terminated components --- .../sdr/dommgr/ApplicationComponent.cpp | 12 ++++++++++- .../control/sdr/dommgr/ApplicationComponent.h | 4 ++++ .../control/sdr/dommgr/Application_impl.cpp | 20 +++++++++++++++++++ .../src/control/sdr/dommgr/Application_impl.h | 2 ++ 4 files changed, 37 insertions(+), 1 deletion(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp b/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp index 19361b5cb..e757f4fa3 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp @@ -39,6 +39,16 @@ const std::string& ApplicationComponent::getIdentifier() const return _identifier; } +const std::string& ApplicationComponent::getInstantiationId() const +{ + return _instantiationId; +} + +void ApplicationComponent::setInstantiationId(const std::string& instantiationId) +{ + _instantiationId = instantiationId; +} + const std::string& ApplicationComponent::getSoftwareProfile() const { return _softwareProfile; @@ -187,7 +197,7 @@ bool ApplicationComponent::stop() void ApplicationComponent::releaseObject() { - if (!isRegistered()) { + if (!isResource()) { return; } diff --git a/redhawk/src/control/sdr/dommgr/ApplicationComponent.h b/redhawk/src/control/sdr/dommgr/ApplicationComponent.h index 7636a7e31..fd048800f 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationComponent.h +++ b/redhawk/src/control/sdr/dommgr/ApplicationComponent.h @@ -33,6 +33,9 @@ namespace redhawk { const std::string& getIdentifier() const; + const std::string& getInstantiationId() const; + void setInstantiationId(const std::string& instantiationId); + const std::string& getSoftwareProfile() const; void setSoftwareProfile(const std::string& softwareProfile); @@ -75,6 +78,7 @@ namespace redhawk { private: std::string _identifier; + std::string _instantiationId; std::string _softwareProfile; std::string _namingContext; std::string _implementationId; diff --git a/redhawk/src/control/sdr/dommgr/Application_impl.cpp b/redhawk/src/control/sdr/dommgr/Application_impl.cpp index 56845e41f..ea2409102 100644 --- a/redhawk/src/control/sdr/dommgr/Application_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/Application_impl.cpp @@ -1241,6 +1241,7 @@ redhawk::ApplicationComponent* Application_impl::addContainer(const redhawk::Con const std::string& profile = container->getSoftPkg()->getSPDFile(); LOG_DEBUG(Application_impl, "Adding container '" << identifier << "' with profile " << profile); redhawk::ApplicationComponent* component = addComponent(identifier, profile); + component->setInstantiationId(container->getInstantiation()->getID()); component->setImplementationId(container->getImplementation()->getID()); component->setAssignedDevice(container->getAssignedDevice()); return component; @@ -1255,6 +1256,7 @@ redhawk::ApplicationComponent* Application_impl::addComponent(const redhawk::Com const std::string& profile = deployment->getSoftPkg()->getSPDFile(); LOG_DEBUG(Application_impl, "Adding component '" << identifier << "' with profile " << profile); redhawk::ApplicationComponent* component = addComponent(identifier, profile); + component->setInstantiationId(deployment->getInstantiation()->getID()); component->setImplementationId(deployment->getImplementation()->getID()); component->setAssignedDevice(deployment->getAssignedDevice()); return component; @@ -1272,10 +1274,28 @@ void Application_impl::componentTerminated(const std::string& componentId, const if (!component->getChildren().empty()) { LOG_WARN(Application_impl, "Component host from application '" << _identifier << "' terminated abnormally on device " << deviceId); + BOOST_FOREACH(redhawk::ApplicationComponent* child, component->getChildren()) { + _checkComponentConnections(child); + } } else { LOG_WARN(Application_impl, "Component '" << componentId << "' from application '" << _identifier << "' terminated abnormally on device " << deviceId); + _checkComponentConnections(component); } component->setProcessId(0); _registrationCondition.notify_all(); } + +void Application_impl::_checkComponentConnections(redhawk::ApplicationComponent* component) +{ + const std::string& component_id = component->getIdentifier(); + const std::string& instantiation_id = component->getInstantiationId(); + LOG_DEBUG(Application_impl, "Checking for connections that depend on terminated component " + << component_id); + BOOST_FOREACH(ConnectionNode& connection, _connections) { + if (connection.checkDependency(ossie::Endpoint::COMPONENT, instantiation_id)) { + LOG_WARN(Application_impl, "Connection '" << connection.identifier + << "' depends on terminated component '" << component_id); + } + } +} diff --git a/redhawk/src/control/sdr/dommgr/Application_impl.h b/redhawk/src/control/sdr/dommgr/Application_impl.h index 98f0073b3..b5a8b30ca 100644 --- a/redhawk/src/control/sdr/dommgr/Application_impl.h +++ b/redhawk/src/control/sdr/dommgr/Application_impl.h @@ -181,6 +181,8 @@ class Application_impl : public virtual POA_CF::Application, public Logging_impl bool _checkRegistrations(std::set& identifiers); + void _checkComponentConnections(redhawk::ApplicationComponent* component); + redhawk::ApplicationComponent* _assemblyController; const std::string _identifier; const std::string _sadProfile; From 2ca2e1a4a83e43df43ba0a985a73a83373b9cb62 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 28 Oct 2016 12:34:34 -0400 Subject: [PATCH 0507/1644] Check component termination against the application's connections, marking the endpoints as terminated to limit excessive error logging --- .../control/sdr/dommgr/Application_impl.cpp | 28 ++++++++----- .../control/sdr/dommgr/connectionSupport.cpp | 40 ++++++++++++++++++- .../control/sdr/dommgr/connectionSupport.h | 17 ++++++-- 3 files changed, 70 insertions(+), 15 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/Application_impl.cpp b/redhawk/src/control/sdr/dommgr/Application_impl.cpp index ea2409102..506c989fd 100644 --- a/redhawk/src/control/sdr/dommgr/Application_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/Application_impl.cpp @@ -1272,14 +1272,16 @@ void Application_impl::componentTerminated(const std::string& componentId, const return; } if (!component->getChildren().empty()) { - LOG_WARN(Application_impl, "Component host from application '" << _identifier - << "' terminated abnormally on device " << deviceId); + LOG_ERROR(Application_impl, "Component host from application '" << _appName + << "' containing " << component->getChildren().size() + << " component(s) terminated abnormally on device " << deviceId); BOOST_FOREACH(redhawk::ApplicationComponent* child, component->getChildren()) { _checkComponentConnections(child); } } else { - LOG_WARN(Application_impl, "Component '" << componentId << "' from application '" << _identifier - << "' terminated abnormally on device " << deviceId); + LOG_ERROR(Application_impl, "Component '" << component->getInstantiationId() + << "' from application '" << _appName + << "' terminated abnormally on device " << deviceId); _checkComponentConnections(component); } component->setProcessId(0); @@ -1288,14 +1290,20 @@ void Application_impl::componentTerminated(const std::string& componentId, const void Application_impl::_checkComponentConnections(redhawk::ApplicationComponent* component) { - const std::string& component_id = component->getIdentifier(); - const std::string& instantiation_id = component->getInstantiationId(); LOG_DEBUG(Application_impl, "Checking for connections that depend on terminated component " - << component_id); + << component->getIdentifier()); + const std::string& instantiation_id = component->getInstantiationId(); + int connection_count = 0; BOOST_FOREACH(ConnectionNode& connection, _connections) { - if (connection.checkDependency(ossie::Endpoint::COMPONENT, instantiation_id)) { - LOG_WARN(Application_impl, "Connection '" << connection.identifier - << "' depends on terminated component '" << component_id); + if (connection.dependencyTerminated(ossie::Endpoint::COMPONENT, instantiation_id)) { + LOG_TRACE(Application_impl, "Application '" << _appName << "' connection '" + << connection.identifier << "' depends on terminated component '" + << instantiation_id << "'"); + connection_count++; } } + if (connection_count > 0) { + LOG_DEBUG(Application_impl, "Application '" << _appName << "' has " << connection_count + << " connection(s) depending on terminated component '" << instantiation_id << "'"); + } } diff --git a/redhawk/src/control/sdr/dommgr/connectionSupport.cpp b/redhawk/src/control/sdr/dommgr/connectionSupport.cpp index efa0cea47..335cca4ef 100644 --- a/redhawk/src/control/sdr/dommgr/connectionSupport.cpp +++ b/redhawk/src/control/sdr/dommgr/connectionSupport.cpp @@ -602,11 +602,16 @@ CF::ConnectionManager::EndpointStatusType Endpoint::toEndpointStatusType() const return status; } -bool Endpoint::isResolved() +bool Endpoint::isResolved() const { return !(CORBA::is_nil(object_)); } +bool Endpoint::isTerminated() const +{ + return terminated_; +} + CORBA::Object_ptr Endpoint::resolve(ConnectionManager& manager) { if (!isResolved()) { @@ -631,6 +636,11 @@ void Endpoint::setIdentifier(std::string identifier) identifier__ = identifier; } +void Endpoint::dependencyTerminated() +{ + terminated_ = true; +} + void Endpoint::release() { // Call the subclass-specific release method. @@ -770,7 +780,11 @@ void ConnectionNode::disconnect(DomainLookup* domainLookup) uses->release(); provides->release(); if (CORBA::is_nil(usesPort)) { - LOG_ERROR(ConnectionNode, "Uses port is not a CF::Port"); + if (uses->isTerminated()) { + LOG_DEBUG(ConnectionNode, "Uses port provider terminated"); + } else { + LOG_ERROR(ConnectionNode, "Uses port is not a CF::Port"); + } return; } @@ -778,6 +792,14 @@ void ConnectionNode::disconnect(DomainLookup* domainLookup) unsigned long timeout = 500; // milliseconds omniORB::setClientCallTimeout(usesPort, timeout); usesPort->disconnectPort(identifier.c_str()); + } catch (const CORBA::SystemException& exc) { + if (uses->isTerminated()) { + LOG_DEBUG(ConnectionNode, "Disconnecting port for connection " << identifier + << " failed, but uses port provider terminated"); + } else { + LOG_WARN(ConnectionNode, "Unable to disconnect port for connection " << identifier + << ": " << ossie::corba::describeException(exc)); + } } CATCH_LOG_WARN(ConnectionNode, "Unable to disconnect port for connection " << identifier); FindByDomainFinderEndpoint* endpoint = dynamic_cast(provides.get()); @@ -823,6 +845,20 @@ bool ConnectionNode::checkDependency(Endpoint::DependencyType type, const std::s return (uses->checkDependency(type, identifier) || provides->checkDependency(type, identifier)); } +bool ConnectionNode::dependencyTerminated(Endpoint::DependencyType type, const std::string& identifier) +{ + bool terminated = false; + if (uses->checkDependency(type, identifier)) { + uses->dependencyTerminated(); + terminated = true; + } + if (provides->checkDependency(type, identifier)) { + provides->dependencyTerminated(); + terminated = true; + } + return terminated; +} + CREATE_LOGGER(connectionSupport); std::string ossie::eventChannelName(const FindBy* findby) diff --git a/redhawk/src/control/sdr/dommgr/connectionSupport.h b/redhawk/src/control/sdr/dommgr/connectionSupport.h index 072d1ea33..8dda3a8c5 100644 --- a/redhawk/src/control/sdr/dommgr/connectionSupport.h +++ b/redhawk/src/control/sdr/dommgr/connectionSupport.h @@ -115,19 +115,27 @@ namespace ossie APPLICATION } DependencyType; - Endpoint() { } + Endpoint() : + terminated_(false) + { + } + virtual ~Endpoint() { } CORBA::Object_ptr resolve(ConnectionManager& manager); CORBA::Object_ptr object(); std::string getIdentifier(); void setIdentifier(std::string identifier); - bool isResolved(); + + bool isResolved() const; + bool isTerminated() const; virtual CF::ConnectionManager::EndpointStatusType toEndpointStatusType() const; virtual bool allowDeferral() = 0; virtual bool checkDependency(DependencyType type, const std::string& identifier) const = 0; + void dependencyTerminated(); + void release(); virtual std::string description() const = 0; @@ -139,7 +147,6 @@ namespace ossie static Endpoint* ParsePort(const Port* port); static Endpoint* ParseProvidesEndpoint(const ossie::Connection& connection); static Endpoint* ParseFindBy(const ossie::FindBy* findby); - private: // Subclasses must implement their own resolution method. virtual CORBA::Object_ptr resolve_(ConnectionManager& manager) = 0; @@ -154,10 +161,12 @@ namespace ossie void serialize(Archive& ar, const unsigned int version) { ar & object_; + ar & terminated_; } #endif CORBA::Object_var object_; + bool terminated_; protected: std::string identifier__; @@ -180,6 +189,8 @@ namespace ossie bool allowDeferral(Endpoint::DependencyType type, const std::string& identifier); bool checkDependency(Endpoint::DependencyType type, const std::string& identifier) const; + bool dependencyTerminated(Endpoint::DependencyType type, const std::string& identifier); + // Default ctor and assignment exist only for deserialization support. ConnectionNode() { } const ConnectionNode& operator=(const ConnectionNode& other) From bbb3dab024d94b5514e94423f81137988d12ea2e Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 28 Oct 2016 12:45:40 -0400 Subject: [PATCH 0508/1644] Allow application to mark components as not visible to exclude them from the external CORBA API, instead of checking (implicitly) that they are not component hosts --- .../src/control/sdr/dommgr/ApplicationComponent.cpp | 11 +++++++++++ redhawk/src/control/sdr/dommgr/ApplicationComponent.h | 4 ++++ redhawk/src/control/sdr/dommgr/Application_impl.cpp | 6 ++++-- redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp | 2 ++ redhawk/src/control/sdr/dommgr/PersistenceStore.h | 2 ++ 5 files changed, 23 insertions(+), 2 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp b/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp index e757f4fa3..3c4440092 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp @@ -29,6 +29,7 @@ using redhawk::ApplicationComponent; ApplicationComponent::ApplicationComponent(const std::string& identifier) : _identifier(identifier), + _isVisible(true), _processId(0), _componentHost(0) { @@ -84,6 +85,16 @@ void ApplicationComponent::setImplementationId(const std::string& implementation _implementationId = implementationId; } +bool ApplicationComponent::isVisible() const +{ + return _isVisible; +} + +void ApplicationComponent::setVisible(bool visible) +{ + _isVisible = visible; +} + ApplicationComponent* ApplicationComponent::getComponentHost() { return _componentHost; diff --git a/redhawk/src/control/sdr/dommgr/ApplicationComponent.h b/redhawk/src/control/sdr/dommgr/ApplicationComponent.h index fd048800f..a518ce9f9 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationComponent.h +++ b/redhawk/src/control/sdr/dommgr/ApplicationComponent.h @@ -46,6 +46,9 @@ namespace redhawk { const std::string& getImplementationId() const; void setImplementationId(const std::string& implementationId); + bool isVisible() const; + void setVisible(bool visible); + ApplicationComponent* getComponentHost(); void setComponentHost(ApplicationComponent* componentHost); @@ -82,6 +85,7 @@ namespace redhawk { std::string _softwareProfile; std::string _namingContext; std::string _implementationId; + bool _isVisible; std::vector _loadedFiles; unsigned long _processId; CORBA::Object_var _componentObject; diff --git a/redhawk/src/control/sdr/dommgr/Application_impl.cpp b/redhawk/src/control/sdr/dommgr/Application_impl.cpp index 506c989fd..1e73672d5 100644 --- a/redhawk/src/control/sdr/dommgr/Application_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/Application_impl.cpp @@ -80,7 +80,7 @@ namespace { void convert_sequence(Sequence& out, Iterator begin, const Iterator end, Function func) { for (; begin != end; ++begin) { - if (begin->getChildren().empty()) { + if (begin->isVisible()) { ossie::corba::push_back(out, func(*begin)); } } @@ -96,7 +96,7 @@ namespace { void convert_sequence_if(Sequence& out, Iterator begin, const Iterator end, Function func, Predicate pred) { for (; begin != end; ++begin) { - if (begin->getChildren().empty() && pred(*begin)) { + if (begin->isVisible() && pred(*begin)) { ossie::corba::push_back(out, func(*begin)); } } @@ -1243,6 +1243,8 @@ redhawk::ApplicationComponent* Application_impl::addContainer(const redhawk::Con redhawk::ApplicationComponent* component = addComponent(identifier, profile); component->setInstantiationId(container->getInstantiation()->getID()); component->setImplementationId(container->getImplementation()->getID()); + // Hide ComponentHost instances from the CORBA API + component->setVisible(false); component->setAssignedDevice(container->getAssignedDevice()); return component; } diff --git a/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp b/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp index a5845547e..364545239 100644 --- a/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp @@ -2473,6 +2473,7 @@ Application_impl* DomainManager_impl::_restoreApplication(ossie::ApplicationNode redhawk::ApplicationComponent* component = application->addComponent(compNode.identifier, compNode.softwareProfile); component->setNamingContext(compNode.namingContext); component->setImplementationId(compNode.implementationId); + component->setVisible(compNode.isVisible); BOOST_FOREACH(const std::string& filename, compNode.loadedFiles) { component->addLoadedFile(filename); } @@ -2532,6 +2533,7 @@ void DomainManager_impl::_persistApplication(Application_impl* application) compNode.softwareProfile = component.getSoftwareProfile(); compNode.namingContext = component.getNamingContext(); compNode.implementationId = component.getImplementationId(); + compNode.isVisible = component.isVisible(); compNode.loadedFiles = component.getLoadedFiles(); compNode.processId = component.getProcessId(); compNode.componentObject = component.getComponentObject(); diff --git a/redhawk/src/control/sdr/dommgr/PersistenceStore.h b/redhawk/src/control/sdr/dommgr/PersistenceStore.h index 360bd7016..17b858471 100644 --- a/redhawk/src/control/sdr/dommgr/PersistenceStore.h +++ b/redhawk/src/control/sdr/dommgr/PersistenceStore.h @@ -110,6 +110,7 @@ namespace ossie { std::string softwareProfile; std::string namingContext; std::string implementationId; + bool isVisible; std::vector loadedFiles; unsigned long processId; CORBA::Object_var componentObject; @@ -267,6 +268,7 @@ namespace boost { ar & node.softwareProfile; ar & node.namingContext; ar & node.implementationId; + ar & node.isVisible; ar & node.loadedFiles; ar & node.processId; ar & node.componentObject; From 33d36db53c82b6f96d1ae9ae762652084dcc4936 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 28 Oct 2016 13:27:07 -0400 Subject: [PATCH 0509/1644] Better reporting and handling of unexpected errors in application start --- .../control/sdr/dommgr/ApplicationComponent.cpp | 14 +++++++++++++- .../src/control/sdr/dommgr/Application_impl.cpp | 7 ++++--- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp b/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp index 3c4440092..a123bca93 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp @@ -180,7 +180,19 @@ void ApplicationComponent::setAssignedDevice(const boost::shared_ptrstart(); + try { + _resource->start(); + } catch (const CF::Resource::StartError& exc) { + std::ostringstream message; + message << "Component '" << _instantiationId << "' failed to start: "; + message << exc.msg; + throw CF::Resource::StartError(exc.errorNumber, message.str().c_str()); + } catch (const CORBA::SystemException& exc) { + std::ostringstream message; + message << "Component '" << _instantiationId << "' failed to start: "; + message << ossie::corba::describeException(exc); + throw CF::Resource::StartError(CF::CF_EIO, message.str().c_str()); + } } bool ApplicationComponent::stop() diff --git a/redhawk/src/control/sdr/dommgr/Application_impl.cpp b/redhawk/src/control/sdr/dommgr/Application_impl.cpp index 1e73672d5..3977e210b 100644 --- a/redhawk/src/control/sdr/dommgr/Application_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/Application_impl.cpp @@ -232,10 +232,11 @@ throw (CORBA::SystemException, CF::Resource::StartError) LOG_TRACE(Application_impl, "Calling start for " << component->getIdentifier()); component->start(); } - } catch( CF::Resource::StartError& se ) { - LOG_ERROR(Application_impl, "Start failed with CF:Resource::StartError") + } catch (const CF::Resource::StartError& se) { + LOG_ERROR(Application_impl, "Failed to start application '" << _appName << "': " << se.msg); throw; - } CATCH_THROW_LOG_ERROR(Application_impl, "Start failed", CF::Resource::StartError()) + } + if (!this->_started) { this->_started = true; if (_domainManager ) { From a94a13773e5484feb0cb5223e945bf00a7d7b899 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 28 Oct 2016 13:42:15 -0400 Subject: [PATCH 0510/1644] Pop up error dialogs when application start/stop fail --- .../ossie/apps/qtbrowse/browsewindowbase.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/redhawk/src/base/framework/python/ossie/apps/qtbrowse/browsewindowbase.py b/redhawk/src/base/framework/python/ossie/apps/qtbrowse/browsewindowbase.py index 5e540cd75..ef2411909 100644 --- a/redhawk/src/base/framework/python/ossie/apps/qtbrowse/browsewindowbase.py +++ b/redhawk/src/base/framework/python/ossie/apps/qtbrowse/browsewindowbase.py @@ -33,6 +33,7 @@ from ossie.utils import sb import copy from ossie.utils import redhawk,prop_helpers,type_helpers +from ossie.cf import CF import structdialog def createPlotMenu(parent): @@ -460,9 +461,19 @@ def contextMenuEvent(self, event): if resp == 'Release': self.callbackObject.addRequest(('releaseApplication(QString)',appname)) elif resp == 'Start': - contref.start() + try: + contref.start() + except CF.Resource.StartError as err: + QMessageBox.critical(self, 'Start error', err.msg, QMessageBox.Ok) + except: + QMessageBox.critical(self, 'Start error', 'Unable to start application', QMessageBox.Ok) elif resp == 'Stop': - contref.stop() + try: + contref.stop() + except CF.Resource.StopError as err: + QMessageBox.critical(self, 'Stop error', err.msg, QMessageBox.Ok) + except: + QMessageBox.critical(self, 'Stop error', 'Unable to stop application', QMessageBox.Ok) elif plotResponse(resp): plot = createPlot(resp) plot.start() From 3ba99998ac1609cce0eb31c6b637f1dadd89c408 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 28 Oct 2016 13:54:50 -0400 Subject: [PATCH 0511/1644] Give the ApplicationComponent class its own logger, even though it's still pointed at Application_impl --- .../sdr/dommgr/ApplicationComponent.cpp | 30 +++++++++++-------- .../control/sdr/dommgr/ApplicationComponent.h | 10 +++++-- .../src/control/sdr/dommgr/Application_impl.h | 1 - 3 files changed, 25 insertions(+), 16 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp b/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp index a123bca93..15a06d279 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp @@ -27,6 +27,10 @@ using redhawk::ApplicationComponent; +// TODO: Should probably use its own logger; using Application_impl's for +// consistency with old code +PREPARE_ALT_LOGGING(ApplicationComponent, "Application_impl"); + ApplicationComponent::ApplicationComponent(const std::string& identifier) : _identifier(identifier), _isVisible(true), @@ -203,17 +207,17 @@ bool ApplicationComponent::stop() _resource->stop(); return true; } catch (const CF::Resource::StopError& error) { - LOG_ERROR(Application_impl, "Failed to stop " << _identifier << "; CF::Resource::StopError '" << error.msg << "'"); + LOG_ERROR(ApplicationComponent, "Failed to stop " << _identifier << "; CF::Resource::StopError '" << error.msg << "'"); } catch (const CORBA::SystemException& exc) { if (!isTerminated()) { - LOG_ERROR(Application_impl, "Failed to stop component '" << _identifier << "'; " + LOG_ERROR(ApplicationComponent, "Failed to stop component '" << _identifier << "'; " << ossie::corba::describeException(exc)); } else { - LOG_DEBUG(Application_impl, "Ignoring CORBA exception stopping terminated component '" + LOG_DEBUG(ApplicationComponent, "Ignoring CORBA exception stopping terminated component '" << _identifier << "'"); } } catch (...) { - LOG_ERROR(Application_impl, "Failed to stop " << _identifier); + LOG_ERROR(ApplicationComponent, "Failed to stop " << _identifier); } return false; } @@ -224,20 +228,20 @@ void ApplicationComponent::releaseObject() return; } - LOG_DEBUG(Application_impl, "Releasing component '" << _identifier << "'"); + LOG_DEBUG(ApplicationComponent, "Releasing component '" << _identifier << "'"); try { unsigned long timeout = 3; // seconds; omniORB::setClientCallTimeout(_resource, timeout * 1000); _resource->releaseObject(); } catch (const CORBA::SystemException& exc) { if (!isTerminated()) { - LOG_ERROR(Application_impl, "Failed to release component '" << _identifier << "'; " + LOG_ERROR(ApplicationComponent, "Failed to release component '" << _identifier << "'; " << ossie::corba::describeException(exc)); } else { - LOG_DEBUG(Application_impl, "Ignoring CORBA exception releasing terminated component '" + LOG_DEBUG(ApplicationComponent, "Ignoring CORBA exception releasing terminated component '" << _identifier << "'"); } - } CATCH_LOG_WARN(Application_impl, "releaseObject failed for component '" << _identifier << "'"); + } CATCH_LOG_WARN(ApplicationComponent, "releaseObject failed for component '" << _identifier << "'"); } void ApplicationComponent::terminate() @@ -249,7 +253,7 @@ void ApplicationComponent::terminate() } if (!_assignedDevice || !_assignedDevice->isExecutable()) { - LOG_WARN(Application_impl, "Cannot find device to terminate component " << _identifier); + LOG_WARN(ApplicationComponent, "Cannot find device to terminate component " << _identifier); } else { _assignedDevice->executableDevice->terminate(_processId); } @@ -261,18 +265,18 @@ void ApplicationComponent::unloadFiles() return; } - LOG_DEBUG(Application_impl, "Unloading " << _loadedFiles.size() << " file(s) for component '" + LOG_DEBUG(ApplicationComponent, "Unloading " << _loadedFiles.size() << " file(s) for component '" << _identifier << "'"); if (!_assignedDevice || !_assignedDevice->isLoadable()) { - LOG_WARN(Application_impl, "Cannot find device to unload files for component " << _identifier); + LOG_WARN(ApplicationComponent, "Cannot find device to unload files for component " << _identifier); return; } BOOST_FOREACH(const std::string& file, _loadedFiles) { - LOG_TRACE(Application_impl, "Unloading file " << file); + LOG_TRACE(ApplicationComponent, "Unloading file " << file); try { _assignedDevice->loadableDevice->unload(file.c_str()); - } CATCH_LOG_WARN(Application_impl, "Unable to unload file " << file); + } CATCH_LOG_WARN(ApplicationComponent, "Unable to unload file " << file); } } diff --git a/redhawk/src/control/sdr/dommgr/ApplicationComponent.h b/redhawk/src/control/sdr/dommgr/ApplicationComponent.h index a518ce9f9..c995dfdab 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationComponent.h +++ b/redhawk/src/control/sdr/dommgr/ApplicationComponent.h @@ -25,10 +25,16 @@ #include #include -#include +#include + +#include "PersistenceStore.h" namespace redhawk { - struct ApplicationComponent { + class ApplicationComponent { + + ENABLE_LOGGING; + + public: ApplicationComponent(const std::string& identifier); const std::string& getIdentifier() const; diff --git a/redhawk/src/control/sdr/dommgr/Application_impl.h b/redhawk/src/control/sdr/dommgr/Application_impl.h index b5a8b30ca..b5d5903e3 100644 --- a/redhawk/src/control/sdr/dommgr/Application_impl.h +++ b/redhawk/src/control/sdr/dommgr/Application_impl.h @@ -221,7 +221,6 @@ class Application_impl : public virtual POA_CF::Application, public Logging_impl // internal propId, returns empty string if no external prop exists std::string getExternalPropertyId(std::string compId, std::string propId); - friend class redhawk::ApplicationComponent; // for logger access friend class ApplicationRegistrar_impl; }; From d33659711d9ab64330b5599477fce7a4bb86196b Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 28 Oct 2016 14:03:53 -0400 Subject: [PATCH 0512/1644] Rename ApplicationComponent attribute from instantationId to name, to reflect its intended use, and default to using the run-time identifier; make sure the name is persisted --- .../control/sdr/dommgr/ApplicationComponent.cpp | 13 +++++++------ .../src/control/sdr/dommgr/ApplicationComponent.h | 6 +++--- .../src/control/sdr/dommgr/Application_impl.cpp | 14 +++++++------- .../src/control/sdr/dommgr/DomainManager_impl.cpp | 2 ++ redhawk/src/control/sdr/dommgr/PersistenceStore.h | 2 ++ 5 files changed, 21 insertions(+), 16 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp b/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp index 15a06d279..224285138 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp @@ -33,6 +33,7 @@ PREPARE_ALT_LOGGING(ApplicationComponent, "Application_impl"); ApplicationComponent::ApplicationComponent(const std::string& identifier) : _identifier(identifier), + _name(identifier), _isVisible(true), _processId(0), _componentHost(0) @@ -44,14 +45,14 @@ const std::string& ApplicationComponent::getIdentifier() const return _identifier; } -const std::string& ApplicationComponent::getInstantiationId() const +const std::string& ApplicationComponent::getName() const { - return _instantiationId; + return _name; } -void ApplicationComponent::setInstantiationId(const std::string& instantiationId) +void ApplicationComponent::setName(const std::string& name) { - _instantiationId = instantiationId; + _name = name; } const std::string& ApplicationComponent::getSoftwareProfile() const @@ -188,12 +189,12 @@ void ApplicationComponent::start() _resource->start(); } catch (const CF::Resource::StartError& exc) { std::ostringstream message; - message << "Component '" << _instantiationId << "' failed to start: "; + message << "Component '" << _name << "' failed to start: "; message << exc.msg; throw CF::Resource::StartError(exc.errorNumber, message.str().c_str()); } catch (const CORBA::SystemException& exc) { std::ostringstream message; - message << "Component '" << _instantiationId << "' failed to start: "; + message << "Component '" << _name << "' failed to start: "; message << ossie::corba::describeException(exc); throw CF::Resource::StartError(CF::CF_EIO, message.str().c_str()); } diff --git a/redhawk/src/control/sdr/dommgr/ApplicationComponent.h b/redhawk/src/control/sdr/dommgr/ApplicationComponent.h index c995dfdab..9b1265e87 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationComponent.h +++ b/redhawk/src/control/sdr/dommgr/ApplicationComponent.h @@ -39,8 +39,8 @@ namespace redhawk { const std::string& getIdentifier() const; - const std::string& getInstantiationId() const; - void setInstantiationId(const std::string& instantiationId); + const std::string& getName() const; + void setName(const std::string& name); const std::string& getSoftwareProfile() const; void setSoftwareProfile(const std::string& softwareProfile); @@ -87,7 +87,7 @@ namespace redhawk { private: std::string _identifier; - std::string _instantiationId; + std::string _name; std::string _softwareProfile; std::string _namingContext; std::string _implementationId; diff --git a/redhawk/src/control/sdr/dommgr/Application_impl.cpp b/redhawk/src/control/sdr/dommgr/Application_impl.cpp index 3977e210b..2b5ce61d7 100644 --- a/redhawk/src/control/sdr/dommgr/Application_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/Application_impl.cpp @@ -1242,7 +1242,7 @@ redhawk::ApplicationComponent* Application_impl::addContainer(const redhawk::Con const std::string& profile = container->getSoftPkg()->getSPDFile(); LOG_DEBUG(Application_impl, "Adding container '" << identifier << "' with profile " << profile); redhawk::ApplicationComponent* component = addComponent(identifier, profile); - component->setInstantiationId(container->getInstantiation()->getID()); + component->setName(container->getInstantiation()->getID()); component->setImplementationId(container->getImplementation()->getID()); // Hide ComponentHost instances from the CORBA API component->setVisible(false); @@ -1259,7 +1259,7 @@ redhawk::ApplicationComponent* Application_impl::addComponent(const redhawk::Com const std::string& profile = deployment->getSoftPkg()->getSPDFile(); LOG_DEBUG(Application_impl, "Adding component '" << identifier << "' with profile " << profile); redhawk::ApplicationComponent* component = addComponent(identifier, profile); - component->setInstantiationId(deployment->getInstantiation()->getID()); + component->setName(deployment->getInstantiation()->getID()); component->setImplementationId(deployment->getImplementation()->getID()); component->setAssignedDevice(deployment->getAssignedDevice()); return component; @@ -1282,7 +1282,7 @@ void Application_impl::componentTerminated(const std::string& componentId, const _checkComponentConnections(child); } } else { - LOG_ERROR(Application_impl, "Component '" << component->getInstantiationId() + LOG_ERROR(Application_impl, "Component '" << component->getName() << "' from application '" << _appName << "' terminated abnormally on device " << deviceId); _checkComponentConnections(component); @@ -1295,18 +1295,18 @@ void Application_impl::_checkComponentConnections(redhawk::ApplicationComponent* { LOG_DEBUG(Application_impl, "Checking for connections that depend on terminated component " << component->getIdentifier()); - const std::string& instantiation_id = component->getInstantiationId(); + const std::string& name = component->getName(); int connection_count = 0; BOOST_FOREACH(ConnectionNode& connection, _connections) { - if (connection.dependencyTerminated(ossie::Endpoint::COMPONENT, instantiation_id)) { + if (connection.dependencyTerminated(ossie::Endpoint::COMPONENT, name)) { LOG_TRACE(Application_impl, "Application '" << _appName << "' connection '" << connection.identifier << "' depends on terminated component '" - << instantiation_id << "'"); + << name << "'"); connection_count++; } } if (connection_count > 0) { LOG_DEBUG(Application_impl, "Application '" << _appName << "' has " << connection_count - << " connection(s) depending on terminated component '" << instantiation_id << "'"); + << " connection(s) depending on terminated component '" << name << "'"); } } diff --git a/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp b/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp index 364545239..4cc787b6b 100644 --- a/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp @@ -2471,6 +2471,7 @@ Application_impl* DomainManager_impl::_restoreApplication(ossie::ApplicationNode // Restore various state about the components in the waveform BOOST_FOREACH(ossie::ComponentNode& compNode, node.components) { redhawk::ApplicationComponent* component = application->addComponent(compNode.identifier, compNode.softwareProfile); + component->setName(compNode.name); component->setNamingContext(compNode.namingContext); component->setImplementationId(compNode.implementationId); component->setVisible(compNode.isVisible); @@ -2530,6 +2531,7 @@ void DomainManager_impl::_persistApplication(Application_impl* application) BOOST_FOREACH(redhawk::ApplicationComponent& component, application->_components) { ossie::ComponentNode compNode; compNode.identifier = component.getIdentifier(); + compNode.name = component.getName(); compNode.softwareProfile = component.getSoftwareProfile(); compNode.namingContext = component.getNamingContext(); compNode.implementationId = component.getImplementationId(); diff --git a/redhawk/src/control/sdr/dommgr/PersistenceStore.h b/redhawk/src/control/sdr/dommgr/PersistenceStore.h index 17b858471..b37dd2c96 100644 --- a/redhawk/src/control/sdr/dommgr/PersistenceStore.h +++ b/redhawk/src/control/sdr/dommgr/PersistenceStore.h @@ -107,6 +107,7 @@ namespace ossie { struct ComponentNode { std::string identifier; + std::string name; std::string softwareProfile; std::string namingContext; std::string implementationId; @@ -265,6 +266,7 @@ namespace boost { template void serialize(Archive& ar, ossie::ComponentNode& node, const unsigned int version) { ar & node.identifier; + ar & node.name; ar & node.softwareProfile; ar & node.namingContext; ar & node.implementationId; From bec9d00b2b3fa512849a056b18d3a33651bcf3be Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 28 Oct 2016 14:51:46 -0400 Subject: [PATCH 0513/1644] Handle exceptions that may arise trying to terminate a component on a failed device --- .../sdr/dommgr/ApplicationComponent.cpp | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp b/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp index 224285138..3885e96ff 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp @@ -29,7 +29,7 @@ using redhawk::ApplicationComponent; // TODO: Should probably use its own logger; using Application_impl's for // consistency with old code -PREPARE_ALT_LOGGING(ApplicationComponent, "Application_impl"); +PREPARE_ALT_LOGGING(ApplicationComponent, Application_impl); ApplicationComponent::ApplicationComponent(const std::string& identifier) : _identifier(identifier), @@ -255,8 +255,23 @@ void ApplicationComponent::terminate() if (!_assignedDevice || !_assignedDevice->isExecutable()) { LOG_WARN(ApplicationComponent, "Cannot find device to terminate component " << _identifier); - } else { + return; + } + + LOG_DEBUG(ApplicationComponent, "Terminating component '" << _identifier + << "' on device '" << _assignedDevice->label + << "' (" << _assignedDevice->identifier << ")"); + try { _assignedDevice->executableDevice->terminate(_processId); + } catch (const CF::ExecutableDevice::InvalidProcess& ip) { + LOG_ERROR(ApplicationComponent, "Failed to terminate process for component '" << _identifier + << "': invalid process"); + } catch (const CF::Device::InvalidState& state) { + LOG_ERROR(ApplicationComponent, "Failed to terminate process for component '" << _identifier + << "': device '" << _assignedDevice->label << "' is in an invalid state"); + } catch (const CORBA::SystemException& exc) { + LOG_ERROR(ApplicationComponent, "Failed to terminate process for component '" << _identifier + << "': " << ossie::corba::describeException(exc)); } } From bd6005878719e05b1a543d5dad397c74639a7fea Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 8 Nov 2016 11:54:44 -0500 Subject: [PATCH 0514/1644] In the Python, tolerate exceptions from releaseObject() for consistency with 2.0 --- .../base/framework/python/ossie/utils/sandbox/model.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/model.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/model.py index 6346b0208..ef111d9fa 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/model.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/model.py @@ -114,8 +114,13 @@ def releaseObject(self): self._sandbox._breakConnections(self) self._sandbox._unregisterComponent(self) - # Call superclass release, which calls the CORBA method. - super(SandboxResource,self).releaseObject() + try: + # Call superclass release, which calls the CORBA method. + super(SandboxResource,self).releaseObject() + except: + # Tolerate exceptions (e.g., the object has already been released) + # and continue on to ensure that the process still gets terminated. + pass # Allow the launcher to peform any follow-up cleanup. SandboxMixin._terminate(self) From 87134aff3ca89e5d645a6cc9a82c1a290e56397a Mon Sep 17 00:00:00 2001 From: Max Robert Date: Thu, 21 Jul 2016 14:11:28 -0400 Subject: [PATCH 0515/1644] CF-1521. Removed duplicate id's in PRF --- GPP/GPP.prf.xml | 8 +++--- GPP/cpp/GPP_base.cpp | 2 +- GPP/cpp/GPP_base.h | 2 +- GPP/cpp/struct_props.h | 62 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 68 insertions(+), 6 deletions(-) diff --git a/GPP/GPP.prf.xml b/GPP/GPP.prf.xml index 23005216d..2b241d171 100644 --- a/GPP/GPP.prf.xml +++ b/GPP/GPP.prf.xml @@ -492,16 +492,16 @@ THRESHOLD_NOT_EXCEEDED: The measured value no longer exceeds the configured thr - + The current number of threads running on the system - + The maximum number of threads allowed to run on the system - + The current number of open file on the system. - + The maximum number of open file handles allowed for the system diff --git a/GPP/cpp/GPP_base.cpp b/GPP/cpp/GPP_base.cpp index 866ac9e34..abde01d52 100644 --- a/GPP/cpp/GPP_base.cpp +++ b/GPP/cpp/GPP_base.cpp @@ -384,7 +384,7 @@ void GPP_base::loadProperties() "property"); addProperty(sys_limits, - ulimit_struct(), + sys_limits_struct(), "sys_limits", "", "readonly", diff --git a/GPP/cpp/GPP_base.h b/GPP/cpp/GPP_base.h index 8ee7bc889..5809f2c19 100644 --- a/GPP/cpp/GPP_base.h +++ b/GPP/cpp/GPP_base.h @@ -85,7 +85,7 @@ class GPP_base : public ExecutableDevice_impl, protected ThreadedComponent // ulimits for the GPP process ulimit_struct gpp_limits; // ulimits for the system as a whole - ulimit_struct sys_limits; + sys_limits_struct sys_limits; /// Property: memFree CORBA::LongLong memFree; /// Property: memCapacity diff --git a/GPP/cpp/struct_props.h b/GPP/cpp/struct_props.h index 6a8426374..458f4afca 100644 --- a/GPP/cpp/struct_props.h +++ b/GPP/cpp/struct_props.h @@ -1343,5 +1343,67 @@ inline bool operator== (const component_monitor_struct& s1, const component_moni inline bool operator!= (const component_monitor_struct& s1, const component_monitor_struct& s2) { return !(s1==s2); } +struct sys_limits_struct { + sys_limits_struct () + { + }; + + static std::string getId() { + return std::string("sys_limits"); + }; + + CORBA::Long current_threads; + CORBA::Long max_threads; + CORBA::Long current_open_files; + CORBA::Long max_open_files; +}; + +inline bool operator>>= (const CORBA::Any& a, sys_limits_struct& s) { + CF::Properties* temp; + if (!(a >>= temp)) return false; + const redhawk::PropertyMap& props = redhawk::PropertyMap::cast(*temp); + if (props.contains("sys_limits::current_threads")) { + if (!(props["sys_limits::current_threads"] >>= s.current_threads)) return false; + } + if (props.contains("sys_limits::max_threads")) { + if (!(props["sys_limits::max_threads"] >>= s.max_threads)) return false; + } + if (props.contains("sys_limits::current_open_files")) { + if (!(props["sys_limits::current_open_files"] >>= s.current_open_files)) return false; + } + if (props.contains("sys_limits::max_open_files")) { + if (!(props["sys_limits::max_open_files"] >>= s.max_open_files)) return false; + } + return true; +} + +inline void operator<<= (CORBA::Any& a, const sys_limits_struct& s) { + redhawk::PropertyMap props; + + props["sys_limits::current_threads"] = s.current_threads; + + props["sys_limits::max_threads"] = s.max_threads; + + props["sys_limits::current_open_files"] = s.current_open_files; + + props["sys_limits::max_open_files"] = s.max_open_files; + a <<= props; +} + +inline bool operator== (const sys_limits_struct& s1, const sys_limits_struct& s2) { + if (s1.current_threads!=s2.current_threads) + return false; + if (s1.max_threads!=s2.max_threads) + return false; + if (s1.current_open_files!=s2.current_open_files) + return false; + if (s1.max_open_files!=s2.max_open_files) + return false; + return true; +} + +inline bool operator!= (const sys_limits_struct& s1, const sys_limits_struct& s2) { + return !(s1==s2); +} #endif // STRUCTPROPS_H From f65e4d4a62a099b89e01766c2b2d005e7dfc4372 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 9 Nov 2016 13:21:02 -0500 Subject: [PATCH 0516/1644] Fix accidentally masked error in Python sandbox when using _non_existent() in component launch to flush stale Java ORB connections --- redhawk/src/base/framework/python/ossie/utils/sandbox/local.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py index 1dfe9e5e2..3cc2de9a2 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py @@ -215,7 +215,7 @@ def terminate_callback(pid, status): # CORBA.COMM_FAILURE exception even though the reference is valid. # In this case, a call to _non_existent() should cause omniORB to # clean up the stale socket, and subsequent calls behave normally. - comp.ref._non_existent() + ref._non_existent() except: pass return ref From 7bfa1f8759fab717a50678fa145fbfc1fd7f60b4 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 10 Nov 2016 16:51:48 -0500 Subject: [PATCH 0517/1644] Shut down omnijni ORB in a Java runtime shutdown hook (only added if the ORB class is imported) instead of at the end of start_component() and start_device(). There were rare "terminated with omni_thread_fatal" messages from BulkIO's test_multiout_attachable.py that were most likely due to the JVM receiving a SIGINT in the middle of shutting down omniORB. --- .../framework/java/ossie/src/org/ossie/component/Device.java | 3 --- .../java/ossie/src/org/ossie/component/Resource.java | 3 --- redhawk/src/omnijni/src/java/omnijni/ORB.java | 5 +++++ 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/redhawk/src/base/framework/java/ossie/src/org/ossie/component/Device.java b/redhawk/src/base/framework/java/ossie/src/org/ossie/component/Device.java index fe50d4aee..226f2baa7 100644 --- a/redhawk/src/base/framework/java/ossie/src/org/ossie/component/Device.java +++ b/redhawk/src/base/framework/java/ossie/src/org/ossie/component/Device.java @@ -459,9 +459,6 @@ public void run() { } catch (InterruptedException e) { // PASS } - - // Shut down native ORB, if it's running - omnijni.ORB.shutdown(); } diff --git a/redhawk/src/base/framework/java/ossie/src/org/ossie/component/Resource.java b/redhawk/src/base/framework/java/ossie/src/org/ossie/component/Resource.java index 62d646943..cae1c0337 100644 --- a/redhawk/src/base/framework/java/ossie/src/org/ossie/component/Resource.java +++ b/redhawk/src/base/framework/java/ossie/src/org/ossie/component/Resource.java @@ -1283,9 +1283,6 @@ public void run() { // long time (~300ms). orb.destroy(); - // Shut down native ORB, if it's running - omnijni.ORB.shutdown(); - logger.debug("Goodbye!"); } diff --git a/redhawk/src/omnijni/src/java/omnijni/ORB.java b/redhawk/src/omnijni/src/java/omnijni/ORB.java index c38d95f6b..2d0bf626e 100644 --- a/redhawk/src/omnijni/src/java/omnijni/ORB.java +++ b/redhawk/src/omnijni/src/java/omnijni/ORB.java @@ -50,6 +50,11 @@ public static String object_to_string (org.omg.CORBA.Object obj) static { System.loadLibrary("omnijni"); + Runtime.getRuntime().addShutdownHook(new Thread() { + public void run() { + omnijni.ORB.shutdown(); + } + }); } private static native long string_to_object_ref (String ior); From 38760472aaf44f0c1fec15c94549d6102cde2d30 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 14 Nov 2016 12:43:24 -0500 Subject: [PATCH 0518/1644] Fix missing statement in codegenTesting component test from earlier merge --- .../sdr/dom/components/get_ports/tests/test_get_ports.py | 1 + 1 file changed, 1 insertion(+) diff --git a/codegenTesting/sdr/dom/components/get_ports/tests/test_get_ports.py b/codegenTesting/sdr/dom/components/get_ports/tests/test_get_ports.py index 95b79b717..2f6291dad 100644 --- a/codegenTesting/sdr/dom/components/get_ports/tests/test_get_ports.py +++ b/codegenTesting/sdr/dom/components/get_ports/tests/test_get_ports.py @@ -2,6 +2,7 @@ import ossie.utils.testing from ossie.utils import sb +from ossie.cf import CF class ComponentTests(ossie.utils.testing.RHTestCase): # Path to the SPD file, relative to this file. This must be set in order to From 8007dd2bb72a6d5cd7c60ae8ca22171d75edd8b4 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 14 Nov 2016 14:06:38 -0500 Subject: [PATCH 0519/1644] Split native omnijni ORB methods into a nested class to help avoid multiple initialization; register a shutdown hook for omnijni on library initialization instead of in a static block, because the library is loaded in multiple places --- redhawk/src/omnijni/src/cpp/omnijni.cpp | 33 ++++++++++--------- redhawk/src/omnijni/src/cpp/orb.cpp | 10 ++++-- redhawk/src/omnijni/src/java/omnijni/ORB.java | 24 ++++++++++---- 3 files changed, 42 insertions(+), 25 deletions(-) diff --git a/redhawk/src/omnijni/src/cpp/omnijni.cpp b/redhawk/src/omnijni/src/cpp/omnijni.cpp index 77b662a3f..4b5b8b3b6 100644 --- a/redhawk/src/omnijni/src/cpp/omnijni.cpp +++ b/redhawk/src/omnijni/src/cpp/omnijni.cpp @@ -31,23 +31,26 @@ namespace { extern "C" JNIEXPORT jint JNICALL JNI_OnLoad (JavaVM* jvm, void* reserved) { - // Map to the JVM enviroment. - JNIEnv* env; - if (jvm->GetEnv((void**)&env, JNI_VERSION_1_2)) { - return false; + // Only initialize if the shared mutex doesn't exist + if (!sharedMutex_) { + // Map to the JVM enviroment. + JNIEnv* env; + if (jvm->GetEnv((void**)&env, JNI_VERSION_1_4)) { + return false; + } + + // Must initialize the CORBA ORB before anything else happens. + omnijni::ORB::Init(env); + + // Initialize the omniORB/JVM thread interface code. + omnijni::threading::Init(env); + + // Create the shared mutex at JNI initialization time (rather than whenever + // static initializers are called) + sharedMutex_ = new omni_mutex(); } - // Must initialize the CORBA ORB before anything else happens. - omnijni::ORB::Init(env); - - // Initialize the omniORB/JVM thread interface code. - omnijni::threading::Init(env); - - // Create the shared mutex at JNI initialization time (rather than whenever - // static initializers are called) - sharedMutex_ = new omni_mutex(); - - return JNI_VERSION_1_2; + return JNI_VERSION_1_4; } namespace omnijni { diff --git a/redhawk/src/omnijni/src/cpp/orb.cpp b/redhawk/src/omnijni/src/cpp/orb.cpp index 04576de36..b1a384369 100644 --- a/redhawk/src/omnijni/src/cpp/orb.cpp +++ b/redhawk/src/omnijni/src/cpp/orb.cpp @@ -46,6 +46,10 @@ void omnijni::ORB::Init (JNIEnv* env) // Initialize JNI references cls_ = omnijni::loadClass(env, "omnijni.ORB"); object_to_string_ = env->GetStaticMethodID(cls_, "object_to_string", "(Lorg/omg/CORBA/Object;)Ljava/lang/String;"); + + // Set up for shutdown on JVM exit + jmethodID register_shutdown = env->GetStaticMethodID(cls_, "register_shutdown", "()V"); + env->CallStaticVoidMethod(cls_, register_shutdown); } CORBA::Object_ptr omnijni::ORB::object_to_native (JNIEnv* env, jobject obj) @@ -57,7 +61,7 @@ CORBA::Object_ptr omnijni::ORB::object_to_native (JNIEnv* env, jobject obj) return object; } -extern "C" JNIEXPORT jlong JNICALL Java_omnijni_ORB_string_1to_1object_1ref (JNIEnv* env, jclass, jstring jior) +extern "C" JNIEXPORT jlong JNICALL Java_omnijni_ORB_00024NativeORB_string_1to_1object_1ref (JNIEnv* env, jclass, jstring jior) { const char* ior = env->GetStringUTFChars(jior, NULL); CORBA::Object_ptr object = orb->string_to_object(ior); @@ -65,14 +69,14 @@ extern "C" JNIEXPORT jlong JNICALL Java_omnijni_ORB_string_1to_1object_1ref (JNI return reinterpret_cast(object); } -extern "C" JNIEXPORT jstring JNICALL Java_omnijni_ORB_objectref_1to_1string (JNIEnv* env, jclass, jlong ref) +extern "C" JNIEXPORT jstring JNICALL Java_omnijni_ORB_00024NativeORB_objectref_1to_1string (JNIEnv* env, jclass, jlong ref) { CORBA::Object_ptr object = reinterpret_cast(ref); CORBA::String_var ior = orb->object_to_string(object); return env->NewStringUTF(ior); } -extern "C" JNIEXPORT void JNICALL Java_omnijni_ORB_shutdown (JNIEnv* env, jclass) +extern "C" JNIEXPORT void JNICALL Java_omnijni_ORB_00024NativeORB_shutdown (JNIEnv* env, jclass) { if (!CORBA::is_nil(orb)) { orb->shutdown(true); diff --git a/redhawk/src/omnijni/src/java/omnijni/ORB.java b/redhawk/src/omnijni/src/java/omnijni/ORB.java index 2d0bf626e..cc9006071 100644 --- a/redhawk/src/omnijni/src/java/omnijni/ORB.java +++ b/redhawk/src/omnijni/src/java/omnijni/ORB.java @@ -32,24 +32,27 @@ public static org.omg.CORBA.portable.OutputStream create_output_stream () public static org.omg.CORBA.Object string_to_object (String ior) { - long ref = string_to_object_ref(ior); + long ref = NativeORB.string_to_object_ref(ior); return new CORBAObject(ref); } public static String object_to_string (org.omg.CORBA.Object obj) { if (obj instanceof omnijni.ObjectImpl) { - return objectref_to_string(((omnijni.ObjectImpl)obj)._get_object_ref()); + return NativeORB.objectref_to_string(((omnijni.ObjectImpl)obj)._get_object_ref()); } else { org.omg.CORBA.ORB orb = ((org.omg.CORBA.portable.ObjectImpl)obj)._orb(); return orb.object_to_string(obj); } } - public static native void shutdown (); + public static void shutdown () + { + NativeORB.shutdown(); + } - static { - System.loadLibrary("omnijni"); + private static void register_shutdown () + { Runtime.getRuntime().addShutdownHook(new Thread() { public void run() { omnijni.ORB.shutdown(); @@ -57,6 +60,13 @@ public void run() { }); } - private static native long string_to_object_ref (String ior); - private static native String objectref_to_string (long ref); + private static class NativeORB { + static { + System.loadLibrary("omnijni"); + } + + private static native void shutdown(); + private static native long string_to_object_ref (String ior); + private static native String objectref_to_string (long ref); + } } From 1aadf024b234e27aa53baca19680d9a2bb68fd8d Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 15 Nov 2016 13:20:09 -0500 Subject: [PATCH 0520/1644] Set C++ components' domain awareness members before registering with the domain, so they are guaranteed to be available when constructor() is called --- redhawk/src/base/framework/Resource_impl.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/redhawk/src/base/framework/Resource_impl.cpp b/redhawk/src/base/framework/Resource_impl.cpp index 9f5316135..c51963903 100644 --- a/redhawk/src/base/framework/Resource_impl.cpp +++ b/redhawk/src/base/framework/Resource_impl.cpp @@ -251,10 +251,6 @@ Resource_impl* Resource_impl::create_component(Resource_impl::ctor_type ctor, co CORBA::Object_var applicationRegistrarObject = ossie::corba::stringToObject(application_registrar_ior); CF::ApplicationRegistrar_var applicationRegistrar = ossie::corba::_narrowSafe(applicationRegistrarObject); if (!CORBA::is_nil(applicationRegistrar)) { - LOG_TRACE(Resource_impl, "Registering with application using name '" << name_binding << "'"); - // Register with the application - applicationRegistrar->registerComponent(name_binding.c_str(), resource_obj); - // Set up the DomainManager container CF::DomainManager_var domainManager = applicationRegistrar->domMgr(); resource->setDomainManager(domainManager); @@ -266,6 +262,10 @@ Resource_impl* Resource_impl::create_component(Resource_impl::ctor_type ctor, co CF::Application_var application = applicationRegistrar->app(); component->setApplication(application); } + + // Register with the application + LOG_TRACE(Resource_impl, "Registering with application using name '" << name_binding << "'"); + applicationRegistrar->registerComponent(name_binding.c_str(), resource_obj); } else { LOG_TRACE(Resource_impl, "Binding component to naming context with name '" << name_binding << "'"); // the registrar is not available (because the invoking infrastructure only uses the name service) From 3f06c36302ff3568b476d650fae0170e58999f25 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 15 Nov 2016 13:50:40 -0500 Subject: [PATCH 0521/1644] Adjust expected exceptions in "bad profile" application tests --- redhawk/src/testing/tests/test_01_DomainManager.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/redhawk/src/testing/tests/test_01_DomainManager.py b/redhawk/src/testing/tests/test_01_DomainManager.py index 1b3a52ab1..edcbaa632 100644 --- a/redhawk/src/testing/tests/test_01_DomainManager.py +++ b/redhawk/src/testing/tests/test_01_DomainManager.py @@ -403,7 +403,7 @@ def test_installApplicationFailures_dep_missing_dep_dir(self): self.dep_dir=dep_dir shutil.move(dep_dir, dep_dir+".XXX") # should work refers to code's localfile - self._domMgr.installApplication(sadfile) + self.assertRaises(CF.DomainManager.ApplicationInstallationError, self._domMgr.installApplication, sadfile) ## reset file shutil.move( dep_dir+".XXX", dep_dir) @@ -456,7 +456,7 @@ def test_installApplicationFailures_recdep_bad_dir(self): dep_spd=scatest.getSdrPath()+"/dom/deps/cpp_dep2/cpp_dep2.spd.xml" shutil.copy( dep_spd+".TEST.bad.dir", dep_spd) # code's localfile not checked during install - self._domMgr.installApplication(sadfile) + self.assertRaises(CF.DomainManager.ApplicationInstallationError, self._domMgr.installApplication, sadfile) ## reset file shutil.copy(dep_spd+".ORIG", dep_spd) @@ -641,7 +641,7 @@ def test_createApplicationFailures_dep_missing_dep_dir(self): dep_dir=scatest.getSdrPath()+"/dom/deps/cpp_dep1/cpp" self.dep_dir = dep_dir shutil.move(dep_dir, dep_dir+".XXX") - self.assertRaises( CF.ApplicationFactory.CreateApplicationError, self._domMgr.createApplication, sadfile, "", [], []) + self.assertRaises( CF.InvalidProfile, self._domMgr.createApplication, sadfile, "", [], []) ## reset file shutil.move( dep_dir+".XXX", dep_dir) @@ -693,7 +693,7 @@ def test_createApplicationFailures_recdep_bad_dir(self): dep_spd=scatest.getSdrPath()+"/dom/deps/cpp_dep2/cpp_dep2.spd.xml" shutil.copy( dep_spd+".TEST.bad.dir", dep_spd) - self.assertRaises( CF.ApplicationFactory.CreateApplicationError, self._domMgr.createApplication, sadfile, "", [], []) + self.assertRaises( CF.InvalidProfile, self._domMgr.createApplication, sadfile, "", [], []) ## reset file shutil.copy(dep_spd+".ORIG", dep_spd) From bcc411f19b52cf6f23bb62ab8f6f252b68b7da0c Mon Sep 17 00:00:00 2001 From: Ryan Bauman Date: Tue, 15 Nov 2016 14:06:57 -0500 Subject: [PATCH 0522/1644] RELENG-488 - updated frontendInterfaces version for next minor version release --- frontendInterfaces/build.sh | 6 +++--- frontendInterfaces/configure.ac | 8 ++++---- frontendInterfaces/frontendInterfaces.spec | 10 +++++----- frontendInterfaces/libsrc/setup.py | 2 +- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/frontendInterfaces/build.sh b/frontendInterfaces/build.sh index 1e881a508..f557d1f9a 100755 --- a/frontendInterfaces/build.sh +++ b/frontendInterfaces/build.sh @@ -25,9 +25,9 @@ elif [ "$1" = "rpm" ]; then # A very simplistic RPM build scenario mydir=`dirname $0` tmpdir=`mktemp -d` - cp -r ${mydir} ${tmpdir}/frontendInterfaces-2.3.4 - tar czf ${tmpdir}/frontendInterfaces-2.3.4.tar.gz --exclude=".svn" -C ${tmpdir} frontendInterfaces-2.3.4 - rpmbuild -ta ${tmpdir}/frontendInterfaces-2.3.4.tar.gz + cp -r ${mydir} ${tmpdir}/frontendInterfaces-2.4.0 + tar czf ${tmpdir}/frontendInterfaces-2.4.0.tar.gz --exclude=".svn" -C ${tmpdir} frontendInterfaces-2.4.0 + rpmbuild -ta ${tmpdir}/frontendInterfaces-2.4.0.tar.gz rm -rf $tmpdir else # Checks if build is newer than makefile (based on modification time) diff --git a/frontendInterfaces/configure.ac b/frontendInterfaces/configure.ac index ebdbc7020..fa9d81ecb 100644 --- a/frontendInterfaces/configure.ac +++ b/frontendInterfaces/configure.ac @@ -18,7 +18,7 @@ # along with this program. If not, see http://www.gnu.org/licenses/. # -AC_INIT(frontendInterfaces, 2.3.4) +AC_INIT(frontendInterfaces, 2.4.0) AM_INIT_AUTOMAKE(nostdinc) AC_PROG_CC @@ -41,16 +41,16 @@ if test "$IDL" = no; then fi AC_LANG_PUSH([C++]) PKG_CHECK_MODULES([OMNIORB], [omniORB4 >= 4.1.0]) -PKG_CHECK_MODULES([OSSIE], [ossie >= 2.0.0]) +PKG_CHECK_MODULES([OSSIE], [ossie >= 2.1.0]) RH_PKG_IDLDIR([OSSIE], [ossie]) # If you depend on other IDL modules, such as CF or BULKIO add them here -PKG_CHECK_MODULES([BULKIO], [bulkioInterfaces >= 2.0]) +PKG_CHECK_MODULES([BULKIO], [bulkioInterfaces >= 2.1]) AC_CHECK_PYMODULE(bulkio.bulkioInterfaces, [], [AC_MSG_ERROR([the python bulkio.bulkioInterfaces module is required])]) RH_PKG_IDLDIR([BULKIO], [bulkioInterfaces]) AC_SUBST([FRONTEND_SO_VERSION],[0:0:0]) -AC_SUBST([FRONTEND_API_VERSION],[2.3]) +AC_SUBST([FRONTEND_API_VERSION],[2.4]) AX_BOOST_BASE([1.41]) AX_BOOST_THREAD diff --git a/frontendInterfaces/frontendInterfaces.spec b/frontendInterfaces/frontendInterfaces.spec index dd4d75b56..8f97a8fa5 100644 --- a/frontendInterfaces/frontendInterfaces.spec +++ b/frontendInterfaces/frontendInterfaces.spec @@ -34,7 +34,7 @@ Prefix: %{_prefix} Summary: The frontend library for REDHAWK Name: frontendInterfaces -Version: 2.3.4 +Version: 2.4.0 Release: 1%{?dist} License: LGPLv3+ Group: REDHAWK/Interfaces @@ -43,10 +43,10 @@ Vendor: REDHAWK BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot -Requires: redhawk >= 2.0.0 -Requires: bulkioInterfaces >= 2.0.0 -BuildRequires: redhawk-devel >= 2.0.0 -BuildRequires: bulkioInterfaces >= 2.0.0 +Requires: redhawk >= 2.1.0 +Requires: bulkioInterfaces >= 2.1.0 +BuildRequires: redhawk-devel >= 2.1.0 +BuildRequires: bulkioInterfaces >= 2.1.0 %description Libraries and interface definitions for frontend. diff --git a/frontendInterfaces/libsrc/setup.py b/frontendInterfaces/libsrc/setup.py index d7b29bf80..d032a902c 100644 --- a/frontendInterfaces/libsrc/setup.py +++ b/frontendInterfaces/libsrc/setup.py @@ -29,7 +29,7 @@ # replaces it (i.e. a developer does a command-line build), use 1.X.X version='__VERSION__' if version.find('__') == 0: - version = '2.3.4' + version = '2.4.0' setup( name='frontend', From 29fed00b2a238d6038138a6768f61124ac83f186 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 16 Nov 2016 09:23:27 -0500 Subject: [PATCH 0523/1644] CF-348 Add a --header option to redhawk-codegen to allow inserting a legal header (or other arbitrary text) as a comment at the top of generated files --- redhawk-codegen/redhawk-codegen | 21 ++++++++-- .../redhawk/codegen/jinja/cpp/template.py | 4 ++ .../redhawk/codegen/jinja/generator.py | 41 ++++++++++++++++--- .../redhawk/codegen/jinja/java/template.py | 4 ++ .../redhawk/codegen/jinja/template.py | 22 ++++++++++ 5 files changed, 83 insertions(+), 9 deletions(-) diff --git a/redhawk-codegen/redhawk-codegen b/redhawk-codegen/redhawk-codegen index 6fd97c058..d279fb14f 100755 --- a/redhawk-codegen/redhawk-codegen +++ b/redhawk-codegen/redhawk-codegen @@ -90,7 +90,8 @@ if __name__ == '__main__': # Deprecated options shortopts += 'm:' - longopts = ['help', 'template=', 'impl=', 'impldir=', 'lang=', 'variant=', 'check-template=', 'version'] + longopts = ['help', 'template=', 'impl=', 'impldir=', 'lang=', 'variant=', + 'check-template=', 'header=', 'version'] # add predefined template settings a full word options longopts.extend(TemplateSetup.keys()) # Deprecated options @@ -106,6 +107,7 @@ if __name__ == '__main__': resource_type=None language=None variant="" + headerFile = None checkSupport = False for key, value in opts: if key == '--help': @@ -135,6 +137,8 @@ if __name__ == '__main__': break elif key == '--variant': variant = value + elif key == '--header': + headerFile = value elif key == '-l': action = Function.LIST elif key == '-f': @@ -271,6 +275,15 @@ if __name__ == '__main__': else: projectTemplate = 'redhawk.codegen.jinja.project.component' + + header = None + if headerFile: + try: + with open(headerFile, 'r') as fp: + header = fp.read().rstrip() + except Exception as exc: + raise SystemExit("Unable to read license header file '%s': %s" % (header_file, exc.strerror)) + try: package = importTemplate(projectTemplate) except: @@ -279,13 +292,14 @@ if __name__ == '__main__': outputdir='', overwrite=overwrite, crcs=toplevelCRCs, - variant=variant) + variant=variant, + header=header) generators.append(('Component '+softpkg.name(), projectGenerator)) if softpkg.type() != ComponentTypes.SHAREDPACKAGE: # Generate unit tests from redhawk.codegen.jinja.unitTests.resource import sca - generator = sca.factory(outputdir='tests', overwrite=overwrite) + generator = sca.factory(outputdir='tests', overwrite=overwrite, header=header) generators.append(('Tests '+softpkg.name(), generator)) # Set up generation for each requested implementation. @@ -376,6 +390,7 @@ if __name__ == '__main__': overwrite = overwrite, crcs = implSettings.generatedFileCRCs, variant = variant, + header = header, **implSettings.properties) # Add this generator to the top-level project generator, so that it can diff --git a/redhawk-codegen/redhawk/codegen/jinja/cpp/template.py b/redhawk-codegen/redhawk/codegen/jinja/cpp/template.py index fa61f1b68..c1a5f4b99 100644 --- a/redhawk-codegen/redhawk/codegen/jinja/cpp/template.py +++ b/redhawk-codegen/redhawk/codegen/jinja/cpp/template.py @@ -23,6 +23,10 @@ from redhawk.codegen.jinja.template import TemplateFile class CppTemplate(TemplateFile): + COMMENT_START = '/*' + COMMENT_LINE = ' *' + COMMENT_END = ' */' + def options(self): return { 'trim_blocks': True, diff --git a/redhawk-codegen/redhawk/codegen/jinja/generator.py b/redhawk-codegen/redhawk/codegen/jinja/generator.py index 30a159290..62b648185 100644 --- a/redhawk-codegen/redhawk/codegen/jinja/generator.py +++ b/redhawk-codegen/redhawk/codegen/jinja/generator.py @@ -35,6 +35,7 @@ def __init__( overwrite=False, crcs={}, variant="", + header=None, **options): self.outputdir = outputdir @@ -73,6 +74,9 @@ def __init__( else: self.crcs[filename] = crcs[filename] + # Save the header (if given) + self.header = header + def parseopts(self): """ Parse additional options passed to the constructor. Subclasses should @@ -145,6 +149,10 @@ def fileinfo(self, softpkg): return files + def _addHeader(self, gen, header): + """ + """ + def generate(self, softpkg, *filenames): loader = self.loader(softpkg) @@ -189,8 +197,7 @@ def generate(self, softpkg, *filenames): env = CodegenEnvironment(loader=loader, **template.options()) env.filters.update(template.filters()) tmpl = env.get_template(template.template) - outfile = open(filename, 'w') - try: + with open(filename, 'w') as outfile: # Start with the template-specific context, then add the mapped # component and a reference to this generator with known names. context = template.context() @@ -199,8 +206,32 @@ def generate(self, softpkg, *filenames): context['versions'] = versions # Evaluate the template in streaming mode (rather than all at - # once), dumping to the output file. - tmpl.stream(**context).dump(outfile) + # once) + gen = tmpl.generate(**context) + if self.header: + # Define a generator function to insert the header at the + # top of the file + def generate(gen, header): + first = True + for chunk in gen: + if first: + # Take "shebang" into account for executable + # scripts + if chunk.startswith('#!'): + line, chunk = chunk.split('\n', 1) + yield line + '\n' + yield header + first = False + yield chunk + + # Wrap the template's generator with the header insertion + # generator + gen = generate(gen, template.comment(self.header)) + + # Write the stream to the output file + for chunk in gen: + outfile.write(chunk) + # Add a trailing newline to work around a Jinja bug. outfile.write('\n') @@ -209,8 +240,6 @@ def generate(self, softpkg, *filenames): fd = outfile.fileno() st = os.fstat(fd) os.chmod(filename, st.st_mode|stat.S_IEXEC) - finally: - outfile.close() generated.append((template.filename, action)) diff --git a/redhawk-codegen/redhawk/codegen/jinja/java/template.py b/redhawk-codegen/redhawk/codegen/jinja/java/template.py index 9cc65c920..778cd9e88 100644 --- a/redhawk-codegen/redhawk/codegen/jinja/java/template.py +++ b/redhawk-codegen/redhawk/codegen/jinja/java/template.py @@ -23,6 +23,10 @@ from redhawk.codegen.jinja.template import TemplateFile class JavaTemplate(TemplateFile): + COMMENT_START = '/*' + COMMENT_LINE = ' *' + COMMENT_END = ' */' + def __init__(self, template, filename=None, userfile=False, package=None, context={}): super(JavaTemplate,self).__init__(template, filename, userfile=userfile) self.package = package diff --git a/redhawk-codegen/redhawk/codegen/jinja/template.py b/redhawk-codegen/redhawk/codegen/jinja/template.py index fbcd11361..0e53bf96b 100644 --- a/redhawk-codegen/redhawk/codegen/jinja/template.py +++ b/redhawk-codegen/redhawk/codegen/jinja/template.py @@ -21,6 +21,12 @@ import os class TemplateFile(object): + # Most file types that we generate use hash for comment lines, but + # subclasses can override if needed + COMMENT_START = '#' + COMMENT_LINE = '#' + COMMENT_END = '#' + def __init__(self, template, filename=None, executable=False, userfile=False): self.template = template if filename: @@ -38,3 +44,19 @@ def filters(self): def context(self): return {} + + def comment(self, text): + """ + Generates a comment block from 'text' suitable for this template type. + """ + def generate(t): + yield self.COMMENT_START + for line in t.split('\n'): + # Add a space between the comment marker and the line, but only + # if the line is non-empty + if line: + line = ' ' + line + yield self.COMMENT_LINE + line + yield self.COMMENT_END + yield '' + return '\n'.join(generate(text)) From 53e30472a1b84b84729527a652e283c063eaeb8f Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 16 Nov 2016 10:33:03 -0500 Subject: [PATCH 0524/1644] CF-1383 Write code generator template output to a temporary file, copying to the target file on success --- .../redhawk/codegen/jinja/generator.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/redhawk-codegen/redhawk/codegen/jinja/generator.py b/redhawk-codegen/redhawk/codegen/jinja/generator.py index 62b648185..6036fb9fb 100644 --- a/redhawk-codegen/redhawk/codegen/jinja/generator.py +++ b/redhawk-codegen/redhawk/codegen/jinja/generator.py @@ -21,8 +21,9 @@ import os import sys import stat +import tempfile +import shutil -from redhawk.codegen.lang.idl import IDLInterface from redhawk.codegen import utils from redhawk.codegen import versions @@ -197,7 +198,10 @@ def generate(self, softpkg, *filenames): env = CodegenEnvironment(loader=loader, **template.options()) env.filters.update(template.filters()) tmpl = env.get_template(template.template) - with open(filename, 'w') as outfile: + + # Initially, write the output to a temporary file to avoid trashing + # the original file if the template is malformed + with tempfile.NamedTemporaryFile() as outfile: # Start with the template-specific context, then add the mapped # component and a reference to this generator with known names. context = template.context() @@ -235,10 +239,15 @@ def generate(gen, header): # Add a trailing newline to work around a Jinja bug. outfile.write('\n') + # Now that generation has succeeded, flush the temporary file + # to ensure the contents are completer, and copy to the target + # location + outfile.file.flush() + shutil.copy(outfile.name, filename) + # Set the executable bit, if requested by the template. if template.executable: - fd = outfile.fileno() - st = os.fstat(fd) + st = os.stat(filename) os.chmod(filename, st.st_mode|stat.S_IEXEC) generated.append((template.filename, action)) From e40798b1911d2249c66c3b9e7e51f17cd550ccf9 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 16 Nov 2016 11:34:58 -0500 Subject: [PATCH 0525/1644] Fix bad variable reference in error message --- redhawk-codegen/redhawk-codegen | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/redhawk-codegen/redhawk-codegen b/redhawk-codegen/redhawk-codegen index d279fb14f..42e2b1892 100755 --- a/redhawk-codegen/redhawk-codegen +++ b/redhawk-codegen/redhawk-codegen @@ -282,7 +282,7 @@ if __name__ == '__main__': with open(headerFile, 'r') as fp: header = fp.read().rstrip() except Exception as exc: - raise SystemExit("Unable to read license header file '%s': %s" % (header_file, exc.strerror)) + raise SystemExit("Unable to read license header file '%s': %s" % (headerFile, exc.strerror)) try: package = importTemplate(projectTemplate) From 7116ad0f0d064893e2b2c1ed3aae1108c51911e0 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 16 Nov 2016 14:12:56 -0500 Subject: [PATCH 0526/1644] Release reference instead of deleting ports in generated C++ component destructor --- .../jinja/cpp/component/pull/templates/resource_base.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/redhawk-codegen/redhawk/codegen/jinja/cpp/component/pull/templates/resource_base.cpp b/redhawk-codegen/redhawk/codegen/jinja/cpp/component/pull/templates/resource_base.cpp index e6e21c140..8e85dc112 100644 --- a/redhawk-codegen/redhawk/codegen/jinja/cpp/component/pull/templates/resource_base.cpp +++ b/redhawk-codegen/redhawk/codegen/jinja/cpp/component/pull/templates/resource_base.cpp @@ -122,7 +122,7 @@ { /*{% block destructorBody %}*/ /*{% for port in component.ports %}*/ - delete ${port.cppname}; + ${port.cppname}->_remove_ref(); ${port.cppname} = 0; /*{% endfor %}*/ /*{% endblock %}*/ From 3a937daa11ada12dee9feb043a5fba42fdc19b7b Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 16 Nov 2016 14:26:08 -0500 Subject: [PATCH 0527/1644] Fix indentation --- redhawk/src/base/include/ossie/Port_impl.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/redhawk/src/base/include/ossie/Port_impl.h b/redhawk/src/base/include/ossie/Port_impl.h index 692711f2a..234f2d41e 100644 --- a/redhawk/src/base/include/ossie/Port_impl.h +++ b/redhawk/src/base/include/ossie/Port_impl.h @@ -273,7 +273,7 @@ class PortBase virtual void setDescription(const std::string& desc) { - description = desc; + description = desc; } virtual void startPort () @@ -297,13 +297,13 @@ class PortBase // Return the Port description virtual std::string getDescription () { - return description; + return description; } // Return the interface that this Port supports virtual std::string getRepid () const { - return "IDL:CORBA/Object:1.0"; + return "IDL:CORBA/Object:1.0"; } // Return the direction (uses/provides) for this Port From 75c3bbf5be358df047ee16634b9e077efdcf340e Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 16 Nov 2016 16:11:52 -0500 Subject: [PATCH 0528/1644] Use an enumeration with a succession of states instead of individual boolean flags to track end-of-stream in InputStream class --- .../libsrc/cpp/bulkio_in_stream.cpp | 45 +++++++++++-------- 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp index a48dbac1c..d80b30045 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp @@ -34,12 +34,17 @@ class InputStream::Impl { typedef typename PortTraits::SharedBufferType SharedBufferType; typedef DataBlock DataBlockType; + enum EosState { + EOS_NONE, + EOS_RECEIVED, + EOS_REACHED, + EOS_REPORTED + }; + Impl(const BULKIO::StreamSRI& sri, InPortType* port) : _streamID(sri.streamID), _sri(sri), - _eosReceived(false), - _eosReached(false), - _eosReported(false), + _eosState(EOS_NONE), _port(port), _queue(), _pending(0), @@ -73,14 +78,16 @@ class InputStream::Impl { // state again _fetchPacket(false); } - if (_eosReached && !_eosReported) { + if (_eosState == EOS_REACHED) { // This is the first time end-of-stream has been checked since it was // reached; remove the stream from the port now, since the caller knows // that the stream ended _port->removeStream(_streamID); - _eosReported = true; + _eosState = EOS_REPORTED; } - return _eosReached; + // At this point, if end-of-stream has been reached, the state is reported + // (it gets set above), so the checking for the latter is sufficient + return (_eosState == EOS_REPORTED); } size_t samplesAvailable() @@ -130,13 +137,13 @@ class InputStream::Impl { if (!sri) { // No SRI retreived implies no data will be retrieved, either due to end- // of-stream or because it would block - if (_eosReached && !_eosReported) { + if (_eosState == EOS_REACHED) { // If this is the first time end-of-stream could be reported, remove // the stream from the port; since the returned data block is invalid, // that's a cue for the caller to check end-of-stream, but they don't // have to _port->removeStream(_streamID); - _eosReported = true; + _eosState = EOS_REPORTED; } return DataBlockType(); } @@ -172,7 +179,7 @@ class InputStream::Impl { // Non-blocking: return a null block if there's not currently a break in // the data, under the assumption that a future read might return the // full amount - if (!blocking && !_pending && !_eosReceived) { + if (!blocking && !_pending && (_eosState == EOS_NONE)) { return DataBlockType(); } // Otherwise, consume all remaining data @@ -247,14 +254,14 @@ class InputStream::Impl { // Unless end-of-stream has been received by the port (meaning any further // packets with this stream ID are for a different instance), purge any // packets for this stream from the port's queue - if (!_eosReceived) { + if (_eosState == EOS_NONE) { _port->discardPacketsForStream(_streamID); } } bool hasBufferedData() const { - if (_eosReached && !_eosReported) { + if (_eosState == EOS_REACHED) { // Technically, there is no data to report; however, to nudge the caller // to check end-of-stream, return true return true; @@ -288,7 +295,9 @@ class InputStream::Impl { void _consumePacket() { // Acknowledge any end-of-stream flag and delete the packet - _eosReached = _queue.front().EOS; + if (_queue.front().EOS) { + _eosState = EOS_REACHED; + } _queue.pop_front(); // If the queue is empty, move the pending packet onto the queue @@ -407,7 +416,7 @@ class InputStream::Impl { } // Any future packets with this stream ID belong to another InputStream - if (_eosReceived) { + if (_eosState != EOS_NONE) { return false; } @@ -417,7 +426,9 @@ class InputStream::Impl { return false; } - _eosReceived = packet->EOS; + if (packet->EOS) { + _eosState = EOS_RECEIVED; + } if (_queue.empty() || _canBridge(packet)) { _queuePacket(packet); return true; @@ -434,7 +445,7 @@ class InputStream::Impl { // SRI changes, and queue flushes are irrelevant at this point) if (_queue.empty()) { // No queued packets, read pointer has reached end-of-stream - _eosReached = true; + _eosState = EOS_REACHED; } else { // Assign the end-of-stream flag to the last packet in the queue so // that it is handled on read @@ -457,9 +468,7 @@ class InputStream::Impl { const std::string _streamID; BULKIO::StreamSRI _sri; - bool _eosReceived; - bool _eosReached; - bool _eosReported; + EosState _eosState; InPortType* _port; boost::ptr_deque _queue; PacketType* _pending; From 36770ac19efdf35bb452c330510d2b032cd8810a Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 16 Nov 2016 16:15:57 -0500 Subject: [PATCH 0529/1644] Clarify how the packet gets deleted to avoid confusion --- bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp index d80b30045..d222cf572 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp @@ -294,7 +294,8 @@ class InputStream::Impl { void _consumePacket() { - // Acknowledge any end-of-stream flag and delete the packet + // Acknowledge any end-of-stream flag and delete the packet (the queue will + // automatically delete it when it's removed) if (_queue.front().EOS) { _eosState = EOS_REACHED; } From 305323ce3f2993487badc9755181c55b1d188fb9 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 17 Nov 2016 10:16:34 -0500 Subject: [PATCH 0530/1644] Use indent of 4 for new code --- .../libsrc/cpp/bulkio_connection.hpp | 472 +++++++++--------- 1 file changed, 236 insertions(+), 236 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp b/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp index c9f77a8cc..b99f274c2 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp @@ -1,278 +1,278 @@ namespace bulkio { - template - class PortConnection - { - public: - typedef typename PortTraits::PortType::_ptr_type PortPtrType; - typedef typename PortTraits::NativeType NativeType; - typedef typename PortTraits::SharedBufferType SharedBufferType; - - PortConnection(const std::string& name) : - stats(name, sizeof(NativeType)) + template + class PortConnection { - } + public: + typedef typename PortTraits::PortType::_ptr_type PortPtrType; + typedef typename PortTraits::NativeType NativeType; + typedef typename PortTraits::SharedBufferType SharedBufferType; + + PortConnection(const std::string& name) : + stats(name, sizeof(NativeType)) + { + } - virtual ~PortConnection() { }; + virtual ~PortConnection() { }; - virtual void pushSRI(const BULKIO::StreamSRI& sri) = 0; + virtual void pushSRI(const BULKIO::StreamSRI& sri) = 0; - virtual void pushPacket(const SharedBufferType& data, - const BULKIO::PrecisionUTCTime& T, - bool EOS, - const BULKIO::StreamSRI& sri) - { - const std::string streamID(sri.streamID); - this->_pushPacket(data, T, EOS, streamID); - stats.update(this->_dataLength(data), 0, EOS, streamID); - } - - // - // Sends an end-of-stream packet for the given stream to a particular port, - // for use when disconnecting; enables XML and File specialization for - // consistent end-of-stream behavior - // - void sendEOS(const std::string& streamID) - { - this->_pushPacket(SharedBufferType(), bulkio::time::utils::notSet(), true, streamID); - } + virtual void pushPacket(const SharedBufferType& data, + const BULKIO::PrecisionUTCTime& T, + bool EOS, + const BULKIO::StreamSRI& sri) + { + const std::string streamID(sri.streamID); + this->_pushPacket(data, T, EOS, streamID); + stats.update(this->_dataLength(data), 0, EOS, streamID); + } - virtual PortPtrType objref() = 0; + // + // Sends an end-of-stream packet for the given stream to a particular port, + // for use when disconnecting; enables XML and File specialization for + // consistent end-of-stream behavior + // + void sendEOS(const std::string& streamID) + { + this->_pushPacket(SharedBufferType(), bulkio::time::utils::notSet(), true, streamID); + } - bool reportConnectionErrors() - { - return stats.connectionErrors(1) < 11; - } + virtual PortPtrType objref() = 0; - linkStatistics stats; + bool reportConnectionErrors() + { + return stats.connectionErrors(1) < 11; + } - protected: - virtual void _pushPacket(const SharedBufferType& data, - const BULKIO::PrecisionUTCTime& T, - bool EOS, - const std::string& streamID) = 0; + linkStatistics stats; + + protected: + virtual void _pushPacket(const SharedBufferType& data, + const BULKIO::PrecisionUTCTime& T, + bool EOS, + const std::string& streamID) = 0; + + // + // Returns the total number of elements of data in a pushPacket call, for + // statistical tracking; enables XML and File specialization, which have + // different notions of size + // + size_t _dataLength(const SharedBufferType& data) + { + return data.size(); + } + }; - // - // Returns the total number of elements of data in a pushPacket call, for - // statistical tracking; enables XML and File specialization, which have - // different notions of size - // - size_t _dataLength(const SharedBufferType& data) - { - return data.size(); - } - }; - - template <> - size_t PortConnection::_dataLength(const std::string& /*unused*/) - { - return 1; - } - - template - class RemoteConnection : public PortConnection - { - public: - typedef typename PortTraits::PortVarType PortVarType; - typedef typename PortTraits::PortType PortType; - typedef typename PortType::_ptr_type PortPtrType; - typedef typename PortTraits::SharedBufferType SharedBufferType; - typedef typename PortTraits::SequenceType PortSequenceType; - typedef typename PortTraits::TransportType TransportType; - - RemoteConnection(const std::string& name, PortPtrType port) : - PortConnection(name), - _port(PortType::_duplicate(port)) + template <> + size_t PortConnection::_dataLength(const std::string& /*unused*/) { + return 1; } - virtual void pushSRI(const BULKIO::StreamSRI& sri) + template + class RemoteConnection : public PortConnection { - _port->pushSRI(sri); - } + public: + typedef typename PortTraits::PortVarType PortVarType; + typedef typename PortTraits::PortType PortType; + typedef typename PortType::_ptr_type PortPtrType; + typedef typename PortTraits::SharedBufferType SharedBufferType; + typedef typename PortTraits::SequenceType PortSequenceType; + typedef typename PortTraits::TransportType TransportType; + + RemoteConnection(const std::string& name, PortPtrType port) : + PortConnection(name), + _port(PortType::_duplicate(port)) + { + } - virtual PortPtrType objref() - { - return PortType::_duplicate(_port); - } + virtual void pushSRI(const BULKIO::StreamSRI& sri) + { + _port->pushSRI(sri); + } + + virtual PortPtrType objref() + { + return PortType::_duplicate(_port); + } + + protected: + virtual void _pushPacket(const SharedBufferType& data, + const BULKIO::PrecisionUTCTime& T, + bool EOS, + const std::string& streamID) + { + const TransportType* ptr = reinterpret_cast(data.data()); + const PortSequenceType buffer(data.size(), data.size(), const_cast(ptr), false); + _port->pushPacket(buffer, T, EOS, streamID.c_str()); + } + + PortVarType _port; + }; - protected: - virtual void _pushPacket(const SharedBufferType& data, - const BULKIO::PrecisionUTCTime& T, - bool EOS, - const std::string& streamID) + template <> + void RemoteConnection::_pushPacket(const std::string& data, + const BULKIO::PrecisionUTCTime& T, + bool EOS, + const std::string& streamID) { - const TransportType* ptr = reinterpret_cast(data.data()); - const PortSequenceType buffer(data.size(), data.size(), const_cast(ptr), false); - _port->pushPacket(buffer, T, EOS, streamID.c_str()); + _port->pushPacket(data.c_str(), T, EOS, streamID.c_str()); } - PortVarType _port; - }; - - template <> - void RemoteConnection::_pushPacket(const std::string& data, - const BULKIO::PrecisionUTCTime& T, - bool EOS, - const std::string& streamID) - { - _port->pushPacket(data.c_str(), T, EOS, streamID.c_str()); - } - - template <> - void RemoteConnection::_pushPacket(const std::string& data, - const BULKIO::PrecisionUTCTime& /* unused */, - bool EOS, - const std::string& streamID) - { - _port->pushPacket(data.c_str(), EOS, streamID.c_str()); - } - - template - class ChunkingConnection : public RemoteConnection - { - public: - typedef typename PortTraits::PortType PortType; - typedef typename PortType::_ptr_type PortPtrType; - typedef typename PortTraits::TransportType TransportType; - typedef typename PortTraits::SharedBufferType SharedBufferType; - - ChunkingConnection(const std::string& name, PortPtrType port) : - RemoteConnection(name, port) + template <> + void RemoteConnection::_pushPacket(const std::string& data, + const BULKIO::PrecisionUTCTime& /* unused */, + bool EOS, + const std::string& streamID) { - // Multiply by some number < 1 to leave some margin for the CORBA header - const size_t maxPayloadSize = (size_t) (bulkio::Const::MaxTransferBytes() * .9); - maxSamplesPerPush = maxPayloadSize/sizeof(TransportType); + _port->pushPacket(data.c_str(), EOS, streamID.c_str()); } - /* - * Push a packet whose payload may not fit within the CORBA limit. The - * packet is broken down into sub-packets and sent via multiple pushPacket - * calls. The EOS is set to false for all of the sub-packets, except for - * the last sub-packet, which uses the input EOS argument. - */ - virtual void pushPacket(const SharedBufferType& data, - const BULKIO::PrecisionUTCTime& T, - bool EOS, - const BULKIO::StreamSRI& sri) + template + class ChunkingConnection : public RemoteConnection { - double xdelta = sri.xdelta; - size_t itemSize = sri.mode?2:1; - size_t frameSize = itemSize; - if (sri.subsize > 0) { - frameSize *= sri.subsize; - } - // Quantize the push size (in terms of scalars) to the nearest frame, - // which takes both the complex mode and subsize into account - const size_t maxPushSize = (maxSamplesPerPush/frameSize) * frameSize; - - // Always do at least one push (may be empty), ensuring that all samples - // are pushed - size_t first = 0; - size_t samplesRemaining = data.size(); - - // Initialize time of first subpacket - BULKIO::PrecisionUTCTime packetTime = T; - - do { - // Don't send more samples than are remaining - const size_t pushSize = std::min(samplesRemaining, maxPushSize); - samplesRemaining -= pushSize; - - // Send end-of-stream as false for all sub-packets except for the - // last one (when there are no samples remaining after this push), - // which gets the input EOS. - bool packetEOS = false; - if (samplesRemaining == 0) { - packetEOS = EOS; + public: + typedef typename PortTraits::PortType PortType; + typedef typename PortType::_ptr_type PortPtrType; + typedef typename PortTraits::TransportType TransportType; + typedef typename PortTraits::SharedBufferType SharedBufferType; + + ChunkingConnection(const std::string& name, PortPtrType port) : + RemoteConnection(name, port) + { + // Multiply by some number < 1 to leave some margin for the CORBA header + const size_t maxPayloadSize = (size_t) (bulkio::Const::MaxTransferBytes() * .9); + maxSamplesPerPush = maxPayloadSize/sizeof(TransportType); } - // Take the next slice of the input buffer. - SharedBufferType subPacket = data.slice(first, first + pushSize); - RemoteConnection::pushPacket(subPacket, packetTime, packetEOS, sri); - - // Synthesize the next packet timestamp - if (packetTime.tcstatus == BULKIO::TCS_VALID) { - packetTime += (pushSize/itemSize)* xdelta; + /* + * Push a packet whose payload may not fit within the CORBA limit. The + * packet is broken down into sub-packets and sent via multiple pushPacket + * calls. The EOS is set to false for all of the sub-packets, except for + * the last sub-packet, which uses the input EOS argument. + */ + virtual void pushPacket(const SharedBufferType& data, + const BULKIO::PrecisionUTCTime& T, + bool EOS, + const BULKIO::StreamSRI& sri) + { + double xdelta = sri.xdelta; + size_t itemSize = sri.mode?2:1; + size_t frameSize = itemSize; + if (sri.subsize > 0) { + frameSize *= sri.subsize; + } + // Quantize the push size (in terms of scalars) to the nearest frame, + // which takes both the complex mode and subsize into account + const size_t maxPushSize = (maxSamplesPerPush/frameSize) * frameSize; + + // Always do at least one push (may be empty), ensuring that all samples + // are pushed + size_t first = 0; + size_t samplesRemaining = data.size(); + + // Initialize time of first subpacket + BULKIO::PrecisionUTCTime packetTime = T; + + do { + // Don't send more samples than are remaining + const size_t pushSize = std::min(samplesRemaining, maxPushSize); + samplesRemaining -= pushSize; + + // Send end-of-stream as false for all sub-packets except for the + // last one (when there are no samples remaining after this push), + // which gets the input EOS. + bool packetEOS = false; + if (samplesRemaining == 0) { + packetEOS = EOS; + } + + // Take the next slice of the input buffer. + SharedBufferType subPacket = data.slice(first, first + pushSize); + RemoteConnection::pushPacket(subPacket, packetTime, packetEOS, sri); + + // Synthesize the next packet timestamp + if (packetTime.tcstatus == BULKIO::TCS_VALID) { + packetTime += (pushSize/itemSize)* xdelta; + } + + // Advance buffer to next sub-packet boundary + first += pushSize; + } while (samplesRemaining > 0); } - // Advance buffer to next sub-packet boundary - first += pushSize; - } while (samplesRemaining > 0); - } + private: + size_t maxSamplesPerPush; + }; - private: - size_t maxSamplesPerPush; - }; + template + class LocalConnection : public PortConnection + { + public: + typedef typename PortTraits::PortType PortType; + typedef typename PortType::_ptr_type PortPtrType; + typedef typename LocalTraits::InPortType LocalPortType; + typedef typename PortTraits::SharedBufferType SharedBufferType; + + LocalConnection(const std::string& name, LocalPortType* port) : + PortConnection(name), + _port(port) + { + _port->_add_ref(); + } - template - class LocalConnection : public PortConnection - { - public: - typedef typename PortTraits::PortType PortType; - typedef typename PortType::_ptr_type PortPtrType; - typedef typename LocalTraits::InPortType LocalPortType; - typedef typename PortTraits::SharedBufferType SharedBufferType; + ~LocalConnection() + { + _port->_remove_ref(); + } - LocalConnection(const std::string& name, LocalPortType* port) : - PortConnection(name), - _port(port) - { - _port->_add_ref(); - } + virtual void pushSRI(const BULKIO::StreamSRI& sri) + { + _port->pushSRI(sri); + } - ~LocalConnection() - { - _port->_remove_ref(); - } + virtual PortPtrType objref() + { + return _port->_this(); + } - virtual void pushSRI(const BULKIO::StreamSRI& sri) - { - _port->pushSRI(sri); - } + protected: + virtual void _pushPacket(const SharedBufferType& data, + const BULKIO::PrecisionUTCTime& T, + bool EOS, + const std::string& streamID) + { + if (data.transient()) { + // The data comes from a non-shared source (a vector or raw pointer), + // so we need to make a copy. This could be optimized for the fanout + // case by making the copy at a higher level, but only if there's at + // least one local connection. + _port->pushPacket(data.copy(), T, EOS, streamID); + } else { + _port->pushPacket(data, T, EOS, streamID); + } + } - virtual PortPtrType objref() - { - return _port->_this(); - } + LocalPortType* _port; + }; - protected: - virtual void _pushPacket(const SharedBufferType& data, - const BULKIO::PrecisionUTCTime& T, - bool EOS, - const std::string& streamID) + template <> + void LocalConnection::_pushPacket(const std::string& data, + const BULKIO::PrecisionUTCTime& T, + bool EOS, + const std::string& streamID) { - if (data.transient()) { - // The data comes from a non-shared source (a vector or raw pointer), - // so we need to make a copy. This could be optimized for the fanout - // case by making the copy at a higher level, but only if there's at - // least one local connection. - _port->pushPacket(data.copy(), T, EOS, streamID); - } else { _port->pushPacket(data, T, EOS, streamID); - } } - LocalPortType* _port; - }; - - template <> - void LocalConnection::_pushPacket(const std::string& data, - const BULKIO::PrecisionUTCTime& T, - bool EOS, - const std::string& streamID) - { - _port->pushPacket(data, T, EOS, streamID); - } - - template <> - void LocalConnection::_pushPacket(const std::string& data, - const BULKIO::PrecisionUTCTime& /*unused*/, - bool EOS, - const std::string& streamID) - { - _port->pushPacket(data, EOS, streamID); - } + template <> + void LocalConnection::_pushPacket(const std::string& data, + const BULKIO::PrecisionUTCTime& /*unused*/, + bool EOS, + const std::string& streamID) + { + _port->pushPacket(data, EOS, streamID); + } } From 74e57d6df2c03cb7b9856c8ef4055c90060e4ff7 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 17 Nov 2016 11:16:30 -0500 Subject: [PATCH 0531/1644] Create REDHAWK-specific transport exceptions to support consistent exception handling for ports irrespective of whether they are using local or CORBA transport --- .../libsrc/cpp/bulkio_connection.hpp | 18 +++++++++- .../libsrc/cpp/bulkio_out_port.cpp | 35 +++++-------------- bulkioInterfaces/libsrc/cpp/bulkio_out_port.h | 5 --- redhawk/src/base/include/ossie/Port_impl.h | 20 +++++++++++ 4 files changed, 46 insertions(+), 32 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp b/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp index b99f274c2..5c5c7c8cc 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp @@ -88,7 +88,11 @@ namespace bulkio { virtual void pushSRI(const BULKIO::StreamSRI& sri) { - _port->pushSRI(sri); + try { + _port->pushSRI(sri); + } catch (const CORBA::SystemException& exc) { + throw redhawk::FatalTransportError(ossie::corba::describeException(exc)); + } } virtual PortPtrType objref() @@ -96,6 +100,18 @@ namespace bulkio { return PortType::_duplicate(_port); } + virtual void pushPacket(const SharedBufferType& data, + const BULKIO::PrecisionUTCTime& T, + bool EOS, + const BULKIO::StreamSRI& sri) + { + try { + PortConnection::pushPacket(data, T, EOS, sri); + } catch (const CORBA::SystemException& exc) { + throw redhawk::FatalTransportError(ossie::corba::describeException(exc)); + } + } + protected: virtual void _pushPacket(const SharedBufferType& data, const BULKIO::PrecisionUTCTime& T, diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp index c29f847fe..0aeb866ab 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp @@ -130,9 +130,9 @@ namespace bulkio { try { port->second->pushSRI(H); sri_iter->second.connections.insert(port->first); - } catch (const CORBA::SystemException& exc) { + } catch (const redhawk::FatalTransportError& err) { if (port->second->reportConnectionErrors()) { - LOG_ERROR(logger, "PUSH-SRI FAILED " << ossie::corba::describeException(exc) + LOG_ERROR(logger, "PUSH-SRI FAILED " << err.what() << " PORT/CONNECTION: " << name << "/" << port->first); } } @@ -200,15 +200,16 @@ namespace bulkio { continue; } - if (sri_iter->second.connections.count(port->first) == 0) { - this->_pushSRI(port, sri_iter->second); - } - try { + if (sri_iter->second.connections.count(port->first) == 0) { + port->second->pushSRI(sri_iter->second.sri); + sri_iter->second.connections.insert(port->first); + } + port->second->pushPacket(data, T, EOS, sri_iter->second.sri); - } catch (const CORBA::SystemException& exc) { + } catch (const redhawk::FatalTransportError& err) { if (port->second->reportConnectionErrors()) { - LOG_ERROR(logger, "PUSH-PACKET FAILED " << ossie::corba::describeException(exc) + LOG_ERROR(logger, "PUSH-PACKET FAILED " << err.what() << " PORT/CONNECTION: " << name << "/" << port->first); } } @@ -372,24 +373,6 @@ namespace bulkio { TRACE_EXIT(logger, "OutPort::disconnectPort" ); } - template < typename PortTraits > - void OutPortBase< PortTraits >::_pushSRI(typename TransportMap::iterator connPair, SriMapStruct &sri_ctx) - { - TRACE_ENTER(logger, "OutPort::_pushSRI"); - // push SRI over port instance - try { - connPair->second->pushSRI(sri_ctx.sri); - sri_ctx.connections.insert(connPair->first); - LOG_TRACE(logger, "_pushSRI() connection_id/streamID " << connPair->first << "/" << sri_ctx.sri.streamID); - } catch (const CORBA::SystemException& exc) { - if (connPair->second->reportConnectionErrors()) { - LOG_ERROR(logger, "_pushSRI() PUSH-SRI FAILED " << ossie::corba::describeException(exc) - << ", PORT/CONNECTION: " << name << "/" << connPair->first); - } - } - TRACE_EXIT(logger, "OutPort::_pushSRI"); - } - template < typename PortTraits > bulkio::SriMap OutPortBase< PortTraits >::getCurrentSRI() { diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h index 047034a87..782cc8686 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h @@ -308,11 +308,6 @@ namespace bulkio { typedef std::map TransportMap; TransportMap _transportMap; - // - // _pushSRI - method to push given SRI to a specific connections - // - void _pushSRI(typename TransportMap::iterator connPair, SriMapStruct &sri_ctx); - LOGGER_PTR logger; std::vector filterTable; boost::shared_ptr< ConnectionEventListener > _connectCB; diff --git a/redhawk/src/base/include/ossie/Port_impl.h b/redhawk/src/base/include/ossie/Port_impl.h index 234f2d41e..20c6187a1 100644 --- a/redhawk/src/base/include/ossie/Port_impl.h +++ b/redhawk/src/base/include/ossie/Port_impl.h @@ -112,6 +112,26 @@ template } } // namespace _seqVector +namespace redhawk { + class TransportError : public std::runtime_error + { + public: + TransportError(const std::string& message) : + std::runtime_error(message) + { + } + }; + + class FatalTransportError : public TransportError + { + public: + FatalTransportError(const std::string& message) : + TransportError(message) + { + } + }; +} + class Port_impl #ifdef BEGIN_AUTOCOMPLETE_IGNORE From 4a5564776f4dbbdd73c7e2b508ed2ac62bf84318 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 17 Nov 2016 11:24:46 -0500 Subject: [PATCH 0532/1644] Remove duplicate local variable --- .../libsrc/cpp/bulkio_out_port.cpp | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp index 0aeb866ab..a0eaa09f6 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp @@ -172,23 +172,21 @@ namespace bulkio { bool EOS, const std::string& streamID) { - const std::string stream_id(streamID); - // don't want to process while command information is coming in SCOPED_LOCK lock(this->updatingPortsLock); // grab SRI context - typename OutPortSriMap::iterator sri_iter = currentSRIs.find(stream_id); + typename OutPortSriMap::iterator sri_iter = currentSRIs.find(streamID); if (sri_iter == currentSRIs.end()) { - LOG_TRACE(logger, "Creating new stream '" << stream_id << "' with default SRI"); + LOG_TRACE(logger, "Creating new stream '" << streamID << "' with default SRI"); // No SRI associated with the stream ID, create a default one and add // it to the list; it will get pushed to downstream connections below - SriMapStruct sri_ctx(bulkio::sri::create(stream_id)); + SriMapStruct sri_ctx(bulkio::sri::create(streamID)); // need to use insert since we do not have default CTOR for SriMapStruct - sri_iter = currentSRIs.insert(std::make_pair(stream_id, sri_ctx)).first; + sri_iter = currentSRIs.insert(std::make_pair(streamID, sri_ctx)).first; - addStream(stream_id, sri_iter->second.sri); + addStream(streamID, sri_iter->second.sri); } if (active) { @@ -196,7 +194,7 @@ namespace bulkio { for (port = _transportMap.begin(); port != _transportMap.end(); ++port) { // Check whether filtering is enabled and if this connection should // receive the stream - if (!_isStreamRoutedToConnection(stream_id, port->first)) { + if (!_isStreamRoutedToConnection(streamID, port->first)) { continue; } @@ -218,8 +216,8 @@ namespace bulkio { // if we have end of stream removed old sri if (EOS) { - currentSRIs.erase(stream_id); - removeStream(stream_id); + currentSRIs.erase(streamID); + removeStream(streamID); } } From 7f1dc1344e60cbb3a20aaeb91b9e4bf84585ae89 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 17 Nov 2016 14:03:02 -0500 Subject: [PATCH 0533/1644] Mark BulkIO connections as no longer alive when they throw a fatal transport error --- .../libsrc/cpp/bulkio_connection.hpp | 75 ++++++++++--------- .../libsrc/cpp/bulkio_out_port.cpp | 70 +++++++++-------- bulkioInterfaces/libsrc/cpp/bulkio_out_port.h | 3 +- 3 files changed, 80 insertions(+), 68 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp b/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp index 5c5c7c8cc..e1ea51d44 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp @@ -4,17 +4,31 @@ namespace bulkio { class PortConnection { public: - typedef typename PortTraits::PortType::_ptr_type PortPtrType; + typedef typename PortTraits::PortType PortType; + typedef typename PortType::_var_type PortVarType; + typedef typename PortType::_ptr_type PortPtrType; typedef typename PortTraits::NativeType NativeType; typedef typename PortTraits::SharedBufferType SharedBufferType; - PortConnection(const std::string& name) : - stats(name, sizeof(NativeType)) + PortConnection(const std::string& name, PortPtrType objref) : + stats(name, sizeof(NativeType)), + _alive(true), + _port(PortType::_duplicate(objref)) { } virtual ~PortConnection() { }; + bool isAlive() const + { + return _alive; + } + + void setAlive(bool alive) + { + _alive = alive; + } + virtual void pushSRI(const BULKIO::StreamSRI& sri) = 0; virtual void pushPacket(const SharedBufferType& data, @@ -37,11 +51,13 @@ namespace bulkio { this->_pushPacket(SharedBufferType(), bulkio::time::utils::notSet(), true, streamID); } - virtual PortPtrType objref() = 0; - - bool reportConnectionErrors() + PortPtrType objref() { - return stats.connectionErrors(1) < 11; + if (isAlive()) { + return PortType::_duplicate(_port); + } else { + return PortType::_nil(); + } } linkStatistics stats; @@ -61,6 +77,9 @@ namespace bulkio { { return data.size(); } + + bool _alive; + PortVarType _port; }; template <> @@ -73,7 +92,6 @@ namespace bulkio { class RemoteConnection : public PortConnection { public: - typedef typename PortTraits::PortVarType PortVarType; typedef typename PortTraits::PortType PortType; typedef typename PortType::_ptr_type PortPtrType; typedef typename PortTraits::SharedBufferType SharedBufferType; @@ -81,25 +99,19 @@ namespace bulkio { typedef typename PortTraits::TransportType TransportType; RemoteConnection(const std::string& name, PortPtrType port) : - PortConnection(name), - _port(PortType::_duplicate(port)) + PortConnection(name, port) { } virtual void pushSRI(const BULKIO::StreamSRI& sri) { try { - _port->pushSRI(sri); + this->_port->pushSRI(sri); } catch (const CORBA::SystemException& exc) { throw redhawk::FatalTransportError(ossie::corba::describeException(exc)); } } - virtual PortPtrType objref() - { - return PortType::_duplicate(_port); - } - virtual void pushPacket(const SharedBufferType& data, const BULKIO::PrecisionUTCTime& T, bool EOS, @@ -120,10 +132,8 @@ namespace bulkio { { const TransportType* ptr = reinterpret_cast(data.data()); const PortSequenceType buffer(data.size(), data.size(), const_cast(ptr), false); - _port->pushPacket(buffer, T, EOS, streamID.c_str()); + this->_port->pushPacket(buffer, T, EOS, streamID.c_str()); } - - PortVarType _port; }; template <> @@ -231,26 +241,21 @@ namespace bulkio { typedef typename LocalTraits::InPortType LocalPortType; typedef typename PortTraits::SharedBufferType SharedBufferType; - LocalConnection(const std::string& name, LocalPortType* port) : - PortConnection(name), - _port(port) + LocalConnection(const std::string& name, LocalPortType* localPort, PortPtrType port) : + PortConnection(name, port), + _localPort(localPort) { - _port->_add_ref(); + _localPort->_add_ref(); } ~LocalConnection() { - _port->_remove_ref(); + _localPort->_remove_ref(); } virtual void pushSRI(const BULKIO::StreamSRI& sri) { - _port->pushSRI(sri); - } - - virtual PortPtrType objref() - { - return _port->_this(); + _localPort->pushSRI(sri); } protected: @@ -264,13 +269,13 @@ namespace bulkio { // so we need to make a copy. This could be optimized for the fanout // case by making the copy at a higher level, but only if there's at // least one local connection. - _port->pushPacket(data.copy(), T, EOS, streamID); + _localPort->pushPacket(data.copy(), T, EOS, streamID); } else { - _port->pushPacket(data, T, EOS, streamID); + _localPort->pushPacket(data, T, EOS, streamID); } } - LocalPortType* _port; + LocalPortType* _localPort; }; template <> @@ -279,7 +284,7 @@ namespace bulkio { bool EOS, const std::string& streamID) { - _port->pushPacket(data, T, EOS, streamID); + _localPort->pushPacket(data, T, EOS, streamID); } template <> @@ -288,7 +293,7 @@ namespace bulkio { bool EOS, const std::string& streamID) { - _port->pushPacket(data, EOS, streamID); + _localPort->pushPacket(data, EOS, streamID); } } diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp index a0eaa09f6..9f7833455 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp @@ -118,25 +118,26 @@ namespace bulkio { } if (active) { - typename TransportMap::iterator port; - - for (port = _transportMap.begin(); port != _transportMap.end(); ++port) { - if (!_isStreamRoutedToConnection(sid, port->first)) { - continue; - } + typedef typename TransportMap::iterator TransportIterator; + for (TransportIterator port = _transportMap.begin(); port != _transportMap.end(); ++port) { + // Skip ports known to be dead + if (!port->second->isAlive()) { + continue; + } + if (!_isStreamRoutedToConnection(sid, port->first)) { + continue; + } - LOG_DEBUG(logger,"pushSRI - PORT:" << name << " CONNECTION:" << port->first << " SRI streamID:" - << H.streamID << " Mode:" << H.mode << " XDELTA:" << 1.0/H.xdelta); - try { - port->second->pushSRI(H); - sri_iter->second.connections.insert(port->first); - } catch (const redhawk::FatalTransportError& err) { - if (port->second->reportConnectionErrors()) { + LOG_DEBUG(logger,"pushSRI - PORT:" << name << " CONNECTION:" << port->first << " SRI streamID:" + << H.streamID << " Mode:" << H.mode << " XDELTA:" << 1.0/H.xdelta); + try { + port->second->pushSRI(H); + sri_iter->second.connections.insert(port->first); + } catch (const redhawk::FatalTransportError& err) { LOG_ERROR(logger, "PUSH-SRI FAILED " << err.what() << " PORT/CONNECTION: " << name << "/" << port->first); } } - } } TRACE_EXIT(logger, "OutPort::pushSRI"); @@ -190,28 +191,32 @@ namespace bulkio { } if (active) { - typename TransportMap::iterator port; - for (port = _transportMap.begin(); port != _transportMap.end(); ++port) { - // Check whether filtering is enabled and if this connection should - // receive the stream - if (!_isStreamRoutedToConnection(streamID, port->first)) { - continue; - } + typedef typename TransportMap::iterator TransportIterator; + for (TransportIterator port = _transportMap.begin(); port != _transportMap.end(); ++port) { + // Skip ports known to be dead + if (!port->second->isAlive()) { + continue; + } - try { - if (sri_iter->second.connections.count(port->first) == 0) { - port->second->pushSRI(sri_iter->second.sri); - sri_iter->second.connections.insert(port->first); + // Check whether filtering is enabled and if this connection should + // receive the stream + if (!_isStreamRoutedToConnection(streamID, port->first)) { + continue; } - port->second->pushPacket(data, T, EOS, sri_iter->second.sri); - } catch (const redhawk::FatalTransportError& err) { - if (port->second->reportConnectionErrors()) { + try { + if (sri_iter->second.connections.count(port->first) == 0) { + port->second->pushSRI(sri_iter->second.sri); + sri_iter->second.connections.insert(port->first); + } + + port->second->pushPacket(data, T, EOS, sri_iter->second.sri); + } catch (const redhawk::FatalTransportError& err) { LOG_ERROR(logger, "PUSH-PACKET FAILED " << err.what() << " PORT/CONNECTION: " << name << "/" << port->first); + port->second->setAlive(false); } } - } } // if we have end of stream removed old sri @@ -293,7 +298,7 @@ namespace bulkio { if (local_port) { LOG_DEBUG(logger, "Using local connection to port " << local_port->getName() << " for connection " << connectionId); - _transportMap[connectionId] = _createLocalConnection(local_port, connectionId); + _transportMap[connectionId] = _createLocalConnection(port, local_port, connectionId); } else { _transportMap[connectionId] = _createRemoteConnection(port, connectionId); } @@ -319,9 +324,10 @@ namespace bulkio { template < typename PortTraits > typename OutPortBase< PortTraits >::PortConnectionType* - OutPortBase< PortTraits >::_createLocalConnection(LocalPortType* port, const std::string& connectionId) + OutPortBase< PortTraits >::_createLocalConnection(PortPtrType port, LocalPortType* localPort, + const std::string& connectionId) { - return new LocalConnection(name, port); + return new LocalConnection(name, localPort, port); } diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h index 782cc8686..059033dee 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h @@ -303,7 +303,8 @@ namespace bulkio { typedef PortConnection PortConnectionType; virtual PortConnectionType* _createRemoteConnection(PortPtrType port, const std::string& connectionId); - virtual PortConnectionType* _createLocalConnection(LocalPortType* port, const std::string& connectionId); + virtual PortConnectionType* _createLocalConnection(PortPtrType port, LocalPortType* localPort, + const std::string& connectionId); typedef std::map TransportMap; TransportMap _transportMap; From 09e5d1edf479c501fa9a396c34bd63f549787b95 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Thu, 17 Nov 2016 14:15:06 -0500 Subject: [PATCH 0534/1644] Refs CF-1433. Extended map exceptions for CentOS 6 --- .../src/testing/tests/test_13_RedhawkModule.py | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/redhawk/src/testing/tests/test_13_RedhawkModule.py b/redhawk/src/testing/tests/test_13_RedhawkModule.py index 22a4cfc9e..8fe08e5c0 100644 --- a/redhawk/src/testing/tests/test_13_RedhawkModule.py +++ b/redhawk/src/testing/tests/test_13_RedhawkModule.py @@ -52,9 +52,9 @@ def preconditions(self): def test_API_remap(self): orig_api = dir(self._rhDom.ref) remap_api = dir(self._rhDom) - not_remap = ['__getattribute__','__getstate__','__hash__','__setattr__','__setstate__','__weakref__', - '_duplicate','_dynamic_op','_hash','_is_a','_is_equivalent','_narrow','_nil','_obj', - '_release','_unchecked_narrow'] + not_remap = ['_NP_RepositoryId','_Object__release','__getattribute__','__getstate__','__hash__','__setattr__','__setstate__','__weakref__', + '__methods__','_duplicate','_dynamic_op','_hash','_is_a','_is_equivalent','_narrow','_nil','_obj', + '__del__','__omni_obj','_release','_unchecked_narrow', '_non_existent'] for entry in orig_api: if entry in not_remap: continue @@ -62,9 +62,6 @@ def test_API_remap(self): orig_api = dir(self._rhDom.devMgrs[0].ref) remap_api = dir(self._rhDom.devMgrs[0]) - not_remap = ['__getattribute__','__getstate__','__hash__','__setattr__','__setstate__','__weakref__', - '_duplicate','_dynamic_op','_hash','_is_a','_is_equivalent','_narrow','_nil','_obj', - '_release','_unchecked_narrow'] for entry in orig_api: if entry in not_remap: continue @@ -77,9 +74,6 @@ def test_API_remap(self): orig_api = dir(self._rhDom.apps[0].comps[0].ref) remap_api = dir(self._rhDom.apps[0].comps[0]) - not_remap = ['_NP_RepositoryId','__getattribute__','__getstate__','__hash__','__setattr__','__setstate__','__weakref__', - '_duplicate','_dynamic_op','_hash','_is_a','_is_equivalent','_narrow','_nil','_obj', - '_release','_unchecked_narrow', '_non_existent'] for entry in orig_api: if entry in not_remap: continue @@ -87,9 +81,6 @@ def test_API_remap(self): orig_api = dir(self._rhDom.apps[0].ref) remap_api = dir(self._rhDom.apps[0]) - not_remap = ['_NP_RepositoryId','__getattribute__','__getstate__','__hash__','__setattr__','__setstate__','__weakref__', - '_duplicate','_dynamic_op','_hash','_is_a','_is_equivalent','_narrow','_nil','_obj', - '_release','_unchecked_narrow', '_non_existent'] for entry in orig_api: if entry in not_remap: continue @@ -97,9 +88,6 @@ def test_API_remap(self): orig_api = dir(self._rhDom.devMgrs[0].devs[0].ref) remap_api = dir(self._rhDom.devMgrs[0].devs[0]) - not_remap = ['_NP_RepositoryId','__getattribute__','__getstate__','__hash__','__setattr__','__setstate__','__weakref__', - '_duplicate','_dynamic_op','_hash','_is_a','_is_equivalent','_narrow','_nil','_obj', - '_release','_unchecked_narrow', '_non_existent'] for entry in orig_api: if entry in not_remap: continue From fe3554bccf427561b53567932f7a45aede23fb25 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 17 Nov 2016 15:15:13 -0500 Subject: [PATCH 0535/1644] Rename BulkIO PortConnection classes to PortTransport --- .../libsrc/cpp/bulkio_connection.hpp | 64 +++++++++---------- .../libsrc/cpp/bulkio_out_port.cpp | 12 ++-- bulkioInterfaces/libsrc/cpp/bulkio_out_port.h | 16 ++--- 3 files changed, 46 insertions(+), 46 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp b/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp index e1ea51d44..0ad9efd8c 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp @@ -1,7 +1,7 @@ namespace bulkio { template - class PortConnection + class PortTransport { public: typedef typename PortTraits::PortType PortType; @@ -10,14 +10,14 @@ namespace bulkio { typedef typename PortTraits::NativeType NativeType; typedef typename PortTraits::SharedBufferType SharedBufferType; - PortConnection(const std::string& name, PortPtrType objref) : + PortTransport(const std::string& name, PortPtrType objref) : stats(name, sizeof(NativeType)), _alive(true), _port(PortType::_duplicate(objref)) { } - virtual ~PortConnection() { }; + virtual ~PortTransport() { }; bool isAlive() const { @@ -83,13 +83,13 @@ namespace bulkio { }; template <> - size_t PortConnection::_dataLength(const std::string& /*unused*/) + size_t PortTransport::_dataLength(const std::string& /*unused*/) { return 1; } template - class RemoteConnection : public PortConnection + class RemoteTransport : public PortTransport { public: typedef typename PortTraits::PortType PortType; @@ -98,8 +98,8 @@ namespace bulkio { typedef typename PortTraits::SequenceType PortSequenceType; typedef typename PortTraits::TransportType TransportType; - RemoteConnection(const std::string& name, PortPtrType port) : - PortConnection(name, port) + RemoteTransport(const std::string& name, PortPtrType port) : + PortTransport(name, port) { } @@ -118,7 +118,7 @@ namespace bulkio { const BULKIO::StreamSRI& sri) { try { - PortConnection::pushPacket(data, T, EOS, sri); + PortTransport::pushPacket(data, T, EOS, sri); } catch (const CORBA::SystemException& exc) { throw redhawk::FatalTransportError(ossie::corba::describeException(exc)); } @@ -137,25 +137,25 @@ namespace bulkio { }; template <> - void RemoteConnection::_pushPacket(const std::string& data, - const BULKIO::PrecisionUTCTime& T, - bool EOS, - const std::string& streamID) + void RemoteTransport::_pushPacket(const std::string& data, + const BULKIO::PrecisionUTCTime& T, + bool EOS, + const std::string& streamID) { _port->pushPacket(data.c_str(), T, EOS, streamID.c_str()); } template <> - void RemoteConnection::_pushPacket(const std::string& data, - const BULKIO::PrecisionUTCTime& /* unused */, - bool EOS, - const std::string& streamID) + void RemoteTransport::_pushPacket(const std::string& data, + const BULKIO::PrecisionUTCTime& /* unused */, + bool EOS, + const std::string& streamID) { _port->pushPacket(data.c_str(), EOS, streamID.c_str()); } template - class ChunkingConnection : public RemoteConnection + class ChunkingTransport : public RemoteTransport { public: typedef typename PortTraits::PortType PortType; @@ -163,8 +163,8 @@ namespace bulkio { typedef typename PortTraits::TransportType TransportType; typedef typename PortTraits::SharedBufferType SharedBufferType; - ChunkingConnection(const std::string& name, PortPtrType port) : - RemoteConnection(name, port) + ChunkingTransport(const std::string& name, PortPtrType port) : + RemoteTransport(name, port) { // Multiply by some number < 1 to leave some margin for the CORBA header const size_t maxPayloadSize = (size_t) (bulkio::Const::MaxTransferBytes() * .9); @@ -215,7 +215,7 @@ namespace bulkio { // Take the next slice of the input buffer. SharedBufferType subPacket = data.slice(first, first + pushSize); - RemoteConnection::pushPacket(subPacket, packetTime, packetEOS, sri); + RemoteTransport::pushPacket(subPacket, packetTime, packetEOS, sri); // Synthesize the next packet timestamp if (packetTime.tcstatus == BULKIO::TCS_VALID) { @@ -233,7 +233,7 @@ namespace bulkio { template - class LocalConnection : public PortConnection + class LocalTransport : public PortTransport { public: typedef typename PortTraits::PortType PortType; @@ -241,14 +241,14 @@ namespace bulkio { typedef typename LocalTraits::InPortType LocalPortType; typedef typename PortTraits::SharedBufferType SharedBufferType; - LocalConnection(const std::string& name, LocalPortType* localPort, PortPtrType port) : - PortConnection(name, port), + LocalTransport(const std::string& name, LocalPortType* localPort, PortPtrType port) : + PortTransport(name, port), _localPort(localPort) { _localPort->_add_ref(); } - ~LocalConnection() + ~LocalTransport() { _localPort->_remove_ref(); } @@ -279,19 +279,19 @@ namespace bulkio { }; template <> - void LocalConnection::_pushPacket(const std::string& data, - const BULKIO::PrecisionUTCTime& T, - bool EOS, - const std::string& streamID) + void LocalTransport::_pushPacket(const std::string& data, + const BULKIO::PrecisionUTCTime& T, + bool EOS, + const std::string& streamID) { _localPort->pushPacket(data, T, EOS, streamID); } template <> - void LocalConnection::_pushPacket(const std::string& data, - const BULKIO::PrecisionUTCTime& /*unused*/, - bool EOS, - const std::string& streamID) + void LocalTransport::_pushPacket(const std::string& data, + const BULKIO::PrecisionUTCTime& /*unused*/, + bool EOS, + const std::string& streamID) { _localPort->pushPacket(data, EOS, streamID); } diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp index 9f7833455..4f7d09194 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp @@ -315,19 +315,19 @@ namespace bulkio { template < typename PortTraits > - typename OutPortBase< PortTraits >::PortConnectionType* + typename OutPortBase< PortTraits >::PortTransportType* OutPortBase< PortTraits >::_createRemoteConnection(PortPtrType port, const std::string& connectionId) { - return new RemoteConnection(name, port); + return new RemoteTransport(name, port); } template < typename PortTraits > - typename OutPortBase< PortTraits >::PortConnectionType* + typename OutPortBase< PortTraits >::PortTransportType* OutPortBase< PortTraits >::_createLocalConnection(PortPtrType port, LocalPortType* localPort, const std::string& connectionId) { - return new LocalConnection(name, localPort, port); + return new LocalTransport(name, localPort, port); } @@ -494,10 +494,10 @@ namespace bulkio { template - typename OutPort::PortConnectionType* + typename OutPort::PortTransportType* OutPort::_createRemoteConnection(PortPtrType port, const std::string& connectionId) { - return new ChunkingConnection(this->name, port); + return new ChunkingTransport(this->name, port); } diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h index 059033dee..11343526c 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h @@ -60,7 +60,7 @@ namespace bulkio { typedef InXMLPort InPortType; }; - template class PortConnection; + template class PortTransport; // // OutPortBase @@ -300,13 +300,13 @@ namespace bulkio { // Lookup table for connections to input ports in the same process space // typedef typename LocalTraits::InPortType LocalPortType; - typedef PortConnection PortConnectionType; + typedef PortTransport PortTransportType; - virtual PortConnectionType* _createRemoteConnection(PortPtrType port, const std::string& connectionId); - virtual PortConnectionType* _createLocalConnection(PortPtrType port, LocalPortType* localPort, - const std::string& connectionId); + virtual PortTransportType* _createRemoteConnection(PortPtrType port, const std::string& connectionId); + virtual PortTransportType* _createLocalConnection(PortPtrType port, LocalPortType* localPort, + const std::string& connectionId); - typedef std::map TransportMap; + typedef std::map TransportMap; TransportMap _transportMap; LOGGER_PTR logger; @@ -477,7 +477,7 @@ namespace bulkio { protected: using OutPortBase::logger; typedef typename OutPortBase::PortPtrType PortPtrType; - typedef typename OutPortBase::PortConnectionType PortConnectionType; + typedef typename OutPortBase::PortTransportType PortTransportType; virtual void addStream(const std::string& streamID, const BULKIO::StreamSRI& sri); virtual void removeStream(const std::string& streamID); @@ -486,7 +486,7 @@ namespace bulkio { StreamMap streams; boost::mutex streamsMutex; - virtual PortConnectionType* _createRemoteConnection(PortPtrType port, const std::string& connectionId); + virtual PortTransportType* _createRemoteConnection(PortPtrType port, const std::string& connectionId); }; // From eb17b8fd1d2d9c8d87b4ace3366070e1aa1bc33e Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 17 Nov 2016 17:15:12 -0500 Subject: [PATCH 0536/1644] Pull some generic uses port management out of templatized BulkIO classes --- .../libsrc/cpp/bulkio_connection.hpp | 15 +- .../libsrc/cpp/bulkio_out_port.cpp | 188 ++++++++++-------- bulkioInterfaces/libsrc/cpp/bulkio_out_port.h | 80 ++++++-- 3 files changed, 177 insertions(+), 106 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp b/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp index 0ad9efd8c..2ed49ccc8 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp @@ -1,7 +1,7 @@ namespace bulkio { template - class PortTransport + class PortTransport : public redhawk::BasicTransport { public: typedef typename PortTraits::PortType PortType; @@ -11,24 +11,14 @@ namespace bulkio { typedef typename PortTraits::SharedBufferType SharedBufferType; PortTransport(const std::string& name, PortPtrType objref) : + redhawk::BasicTransport(objref), stats(name, sizeof(NativeType)), - _alive(true), _port(PortType::_duplicate(objref)) { } virtual ~PortTransport() { }; - bool isAlive() const - { - return _alive; - } - - void setAlive(bool alive) - { - _alive = alive; - } - virtual void pushSRI(const BULKIO::StreamSRI& sri) = 0; virtual void pushPacket(const SharedBufferType& data, @@ -78,7 +68,6 @@ namespace bulkio { return data.size(); } - bool _alive; PortVarType _port; }; diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp index 4f7d09194..bc60ba90f 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp @@ -31,6 +31,42 @@ // Suppress warnings for access to "deprecated" currentSRI member--it's the // public access that's deprecated, not the member itself #pragma GCC diagnostic ignored "-Wdeprecated-declarations" +namespace redhawk { + QueryableUsesPort::QueryableUsesPort(const std::string& name) : + Port_Uses_base_impl(name) + { + } + + ExtendedCF::UsesConnectionSequence* QueryableUsesPort::connections() + { + boost::mutex::scoped_lock lock(updatingPortsLock); // don't want to process while command information is coming in + ExtendedCF::UsesConnectionSequence_var retVal = new ExtendedCF::UsesConnectionSequence(); + for (transport_list::iterator port = _transports.begin(); port != _transports.end(); ++port) { + ExtendedCF::UsesConnection conn; + conn.connectionId = port->first.c_str(); + conn.port = port->second->objref(); + ossie::corba::push_back(retVal, conn); + } + return retVal._retn(); + } + + QueryableUsesPort::transport_list::iterator QueryableUsesPort::_findTransportEntry(const std::string& connectionId) + { + transport_list::iterator entry = _transports.begin(); + for (; entry != _transports.end(); ++entry) { + if (entry->first == connectionId) { + return entry; + } + } + return entry; + } + + void QueryableUsesPort::_addTransportEntry(const std::string& connectionId, BasicTransport* transport) + { + _transports.push_back(transport_entry(connectionId, transport)); + } +} + namespace bulkio { /* @@ -44,7 +80,7 @@ namespace bulkio { LOGGER_PTR logger, ConnectionEventListener *connectCB, ConnectionEventListener *disconnectCB ) : - Port_Uses_base_impl(port_name), + QueryableUsesPort(port_name), logger(logger) { @@ -71,7 +107,7 @@ namespace bulkio { OutPortBase< PortTraits >::OutPortBase(std::string port_name, ConnectionEventListener *connectCB, ConnectionEventListener *disconnectCB ) : - Port_Uses_base_impl(port_name), + QueryableUsesPort(port_name), logger() { @@ -118,24 +154,24 @@ namespace bulkio { } if (active) { - typedef typename TransportMap::iterator TransportIterator; - for (TransportIterator port = _transportMap.begin(); port != _transportMap.end(); ++port) { + for (transport_list::iterator iter = _transports.begin(); iter != _transports.end(); ++iter) { + PortTransportType* port = static_cast(iter->second); // Skip ports known to be dead - if (!port->second->isAlive()) { + if (!port->isAlive()) { continue; } - if (!_isStreamRoutedToConnection(sid, port->first)) { + if (!_isStreamRoutedToConnection(sid, iter->first)) { continue; } - LOG_DEBUG(logger,"pushSRI - PORT:" << name << " CONNECTION:" << port->first << " SRI streamID:" + LOG_DEBUG(logger,"pushSRI - PORT:" << name << " CONNECTION:" << iter->first << " SRI streamID:" << H.streamID << " Mode:" << H.mode << " XDELTA:" << 1.0/H.xdelta); try { - port->second->pushSRI(H); - sri_iter->second.connections.insert(port->first); + port->pushSRI(H); + sri_iter->second.connections.insert(iter->first); } catch (const redhawk::FatalTransportError& err) { LOG_ERROR(logger, "PUSH-SRI FAILED " << err.what() - << " PORT/CONNECTION: " << name << "/" << port->first); + << " PORT/CONNECTION: " << name << "/" << iter->first); } } } @@ -191,30 +227,30 @@ namespace bulkio { } if (active) { - typedef typename TransportMap::iterator TransportIterator; - for (TransportIterator port = _transportMap.begin(); port != _transportMap.end(); ++port) { + for (transport_list::iterator iter = _transports.begin(); iter != _transports.end(); ++iter) { + PortTransportType* port = static_cast(iter->second); // Skip ports known to be dead - if (!port->second->isAlive()) { + if (!port->isAlive()) { continue; } // Check whether filtering is enabled and if this connection should // receive the stream - if (!_isStreamRoutedToConnection(streamID, port->first)) { + if (!_isStreamRoutedToConnection(streamID, iter->first)) { continue; } try { - if (sri_iter->second.connections.count(port->first) == 0) { - port->second->pushSRI(sri_iter->second.sri); - sri_iter->second.connections.insert(port->first); + if (sri_iter->second.connections.count(iter->first) == 0) { + port->pushSRI(sri_iter->second.sri); + sri_iter->second.connections.insert(iter->first); } - port->second->pushPacket(data, T, EOS, sri_iter->second.sri); + port->pushPacket(data, T, EOS, sri_iter->second.sri); } catch (const redhawk::FatalTransportError& err) { LOG_ERROR(logger, "PUSH-PACKET FAILED " << err.what() - << " PORT/CONNECTION: " << name << "/" << port->first); - port->second->setAlive(false); + << " PORT/CONNECTION: " << name << "/" << iter->first); + port->setAlive(false); } } } @@ -230,22 +266,23 @@ namespace bulkio { template < typename PortTraits > BULKIO::UsesPortStatisticsSequence* OutPortBase< PortTraits >::statistics() { - SCOPED_LOCK lock(updatingPortsLock); - BULKIO::UsesPortStatisticsSequence_var recStat = new BULKIO::UsesPortStatisticsSequence(); - for (typename TransportMap::iterator port = _transportMap.begin(); port != _transportMap.end(); ++port) { - BULKIO::UsesPortStatistics stat; - stat.connectionId = port->first.c_str(); - stat.statistics = port->second->stats.retrieve(); - ossie::corba::push_back(recStat, stat); - } - return recStat._retn(); + SCOPED_LOCK lock(updatingPortsLock); + BULKIO::UsesPortStatisticsSequence_var recStat = new BULKIO::UsesPortStatisticsSequence(); + for (transport_list::iterator iter = _transports.begin(); iter != _transports.end(); ++iter) { + PortTransportType* port = static_cast(iter->second); + BULKIO::UsesPortStatistics stat; + stat.connectionId = iter->first.c_str(); + stat.statistics = port->stats.retrieve(); + ossie::corba::push_back(recStat, stat); + } + return recStat._retn(); } template < typename PortTraits > BULKIO::PortUsageType OutPortBase< PortTraits >::state() { SCOPED_LOCK lock(updatingPortsLock); - if (_transportMap.empty()) { + if (_transports.empty()) { return BULKIO::IDLE; } else { return BULKIO::ACTIVE; @@ -255,27 +292,14 @@ namespace bulkio { template < typename PortTraits > void OutPortBase< PortTraits >::enableStats(bool enable) { - SCOPED_LOCK lock(updatingPortsLock); - for (typename TransportMap::iterator port = _transportMap.begin(); port != _transportMap.end(); ++port) { - port->second->stats.setEnabled(enable); - } + SCOPED_LOCK lock(updatingPortsLock); + for (transport_list::iterator iter = _transports.begin(); iter != _transports.end(); ++iter) { + PortTransportType* port = static_cast(iter->second); + port->stats.setEnabled(enable); + } } - template < typename PortTraits > - ExtendedCF::UsesConnectionSequence * OutPortBase< PortTraits >::connections() - { - SCOPED_LOCK lock(updatingPortsLock); // don't want to process while command information is coming in - ExtendedCF::UsesConnectionSequence_var retVal = new ExtendedCF::UsesConnectionSequence(); - for (typename TransportMap::iterator port = _transportMap.begin(); port != _transportMap.end(); ++port) { - ExtendedCF::UsesConnection conn; - conn.connectionId = port->first.c_str(); - conn.port = port->second->objref(); - ossie::corba::push_back(retVal, conn); - } - return retVal._retn(); - } - template < typename PortTraits > void OutPortBase< PortTraits >::connectPort(CORBA::Object_ptr connection, const char* connectionId) { @@ -295,13 +319,15 @@ namespace bulkio { } LocalPortType* local_port = ossie::corba::getLocalServant(port); + PortTransportType* transport; if (local_port) { LOG_DEBUG(logger, "Using local connection to port " << local_port->getName() << " for connection " << connectionId); - _transportMap[connectionId] = _createLocalConnection(port, local_port, connectionId); + transport = _createLocalConnection(port, local_port, connectionId); } else { - _transportMap[connectionId] = _createRemoteConnection(port, connectionId); + transport = _createRemoteConnection(port, connectionId); } + _addTransportEntry(connectionId, transport); active = true; @@ -336,39 +362,40 @@ namespace bulkio { { TRACE_ENTER(logger, "OutPort::disconnectPort" ); { - SCOPED_LOCK lock(updatingPortsLock); // don't want to process while command information is coming in + SCOPED_LOCK lock(updatingPortsLock); // don't want to process while command information is coming in + + const std::string cid(connectionId); + transport_list::iterator iter = _findTransportEntry(connectionId); + if (iter != _transports.end()) { + PortTransportType* port = static_cast(iter->second); + + // Send an EOS for every connection that's listed for this SRI + for (typename OutPortSriMap::iterator cSRIs = currentSRIs.begin(); cSRIs!=currentSRIs.end(); cSRIs++) { + const std::string stream_id(cSRIs->second.sri.streamID); + + // Check if we have sent out sri/data to the connection + if (cSRIs->second.connections.count( cid ) != 0) { + if (_isStreamRoutedToConnection(stream_id, cid)) { + try { + port->sendEOS(stream_id); + } catch (...) { + // Ignore all exceptions; the receiver may be dead + } + } + } - const std::string cid(connectionId); - typename TransportMap::iterator port = _transportMap.find(connectionId); - if (port != _transportMap.end()) { - // Send an EOS for every connection that's listed for this SRI - for (typename OutPortSriMap::iterator cSRIs = currentSRIs.begin(); cSRIs!=currentSRIs.end(); cSRIs++) { - const std::string stream_id(cSRIs->second.sri.streamID); - - // Check if we have sent out sri/data to the connection - if (cSRIs->second.connections.count( cid ) != 0) { - if (_isStreamRoutedToConnection(stream_id, cid)) { - try { - port->second->sendEOS(stream_id); - } catch (...) { - // Ignore all exceptions; the receiver may be dead - } + // remove connection id from sri connections list + cSRIs->second.connections.erase(connectionId); } - } - - // remove connection id from sri connections list - cSRIs->second.connections.erase( cid ); - } - - LOG_DEBUG( logger, "DISCONNECT, PORT/CONNECTION: " << name << "/" << connectionId ); - delete port->second; - _transportMap.erase(port); + LOG_DEBUG( logger, "DISCONNECT, PORT/CONNECTION: " << name << "/" << connectionId ); + delete port; + _transports.erase(iter); - if (_transportMap.empty()) { - active = false; + if (_transports.empty()) { + active = false; + } } - } } if (_disconnectCB) { (*_disconnectCB)(connectionId); @@ -408,8 +435,9 @@ namespace bulkio { SCOPED_LOCK lock(updatingPortsLock); // restrict access till method completes ConnectionsList outConnections; - for (typename TransportMap::iterator port = _transportMap.begin(); port != _transportMap.end(); ++port) { - outConnections.push_back(std::make_pair(port->second->objref(), port->first)); + for (transport_list::iterator iter = _transports.begin(); iter != _transports.end(); ++iter) { + PortTransportType* port = static_cast(iter->second); + outConnections.push_back(std::make_pair(port->objref(), iter->first)); } return outConnections; diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h index 11343526c..3be19f9bf 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h @@ -36,6 +36,70 @@ #include "bulkio_callbacks.h" #include "bulkio_out_stream.h" +namespace redhawk { + class BasicTransport + { + public: + BasicTransport(CORBA::Object_ptr objref) : + _objref(CORBA::Object::_duplicate(objref)), + _alive(true) + { + } + + virtual ~BasicTransport() + { + } + + bool isAlive() const + { + return _alive; + } + + void setAlive(bool alive) + { + _alive = alive; + } + + CORBA::Object_var objref() + { + if (isAlive()) { + return CORBA::Object::_duplicate(_objref); + } else { + return CORBA::Object::_nil(); + } + } + + private: + CORBA::Object_var _objref; + bool _alive; + }; + + class QueryableUsesPort : public Port_Uses_base_impl +#ifdef BEGIN_AUTOCOMPLETE_IGNORE + , public virtual POA_BULKIO::UsesPortStatisticsProvider +#endif + { + public: + QueryableUsesPort(const std::string& name); + + // + // connections - Return a list of connection objects and identifiers for each connection made by connectPort + // + // @return ExtendedCF::UsesConnectionSequence* List of connection objects and identifiers + // + virtual ExtendedCF::UsesConnectionSequence* connections(); + + protected: + typedef std::pair transport_entry; + typedef std::vector transport_list; + + transport_list::iterator _findTransportEntry(const std::string& connectionId); + void _addTransportEntry(const std::string& connectionId, BasicTransport* transport); + + transport_list _transports; + }; +} + namespace bulkio { template class InPort; @@ -71,10 +135,7 @@ namespace bulkio { // // template < typename PortTraits > - class OutPortBase : public Port_Uses_base_impl -#ifdef BEGIN_AUTOCOMPLETE_IGNORE - , public virtual POA_BULKIO::UsesPortStatisticsProvider -#endif + class OutPortBase : public redhawk::QueryableUsesPort { public: @@ -148,13 +209,6 @@ namespace bulkio { // Interface used by framework to connect/disconnect ports together and introspection of connection states // - // - // connections - Return a list of connection objects and identifiers for each connection made by connectPort - // - // @return ExtendedCF::UsesConnectionSequence * List of connection objects and identifiers - // - virtual ExtendedCF::UsesConnectionSequence * connections(); - // // connectPort - Called by the framework to connect this port to a Provides port object, the connection is established // via the association and identified by the connectionId string, no formal "type capatablity" or "bukio interface support" @@ -306,8 +360,8 @@ namespace bulkio { virtual PortTransportType* _createLocalConnection(PortPtrType port, LocalPortType* localPort, const std::string& connectionId); - typedef std::map TransportMap; - TransportMap _transportMap; + //typedef std::map TransportMap; + //TransportMap _transportMap; LOGGER_PTR logger; std::vector filterTable; From 5cf8e40b630d19a7ba74a8e0b0eb0025a24ac2c1 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 17 Nov 2016 17:43:36 -0500 Subject: [PATCH 0537/1644] Move generic uses port class from BulkIO to core --- .../libsrc/cpp/bulkio_out_port.cpp | 101 ++++-------------- bulkioInterfaces/libsrc/cpp/bulkio_out_port.h | 79 ++------------ redhawk/src/base/framework/Makefile.am | 3 +- redhawk/src/base/framework/UsesPort.cpp | 68 ++++++++++++ redhawk/src/base/include/ossie/Makefile.am | 3 +- redhawk/src/base/include/ossie/UsesPort.h | 76 +++++++++++++ 6 files changed, 178 insertions(+), 152 deletions(-) create mode 100644 redhawk/src/base/framework/UsesPort.cpp create mode 100644 redhawk/src/base/include/ossie/UsesPort.h diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp index bc60ba90f..2b192583a 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp @@ -31,42 +31,6 @@ // Suppress warnings for access to "deprecated" currentSRI member--it's the // public access that's deprecated, not the member itself #pragma GCC diagnostic ignored "-Wdeprecated-declarations" -namespace redhawk { - QueryableUsesPort::QueryableUsesPort(const std::string& name) : - Port_Uses_base_impl(name) - { - } - - ExtendedCF::UsesConnectionSequence* QueryableUsesPort::connections() - { - boost::mutex::scoped_lock lock(updatingPortsLock); // don't want to process while command information is coming in - ExtendedCF::UsesConnectionSequence_var retVal = new ExtendedCF::UsesConnectionSequence(); - for (transport_list::iterator port = _transports.begin(); port != _transports.end(); ++port) { - ExtendedCF::UsesConnection conn; - conn.connectionId = port->first.c_str(); - conn.port = port->second->objref(); - ossie::corba::push_back(retVal, conn); - } - return retVal._retn(); - } - - QueryableUsesPort::transport_list::iterator QueryableUsesPort::_findTransportEntry(const std::string& connectionId) - { - transport_list::iterator entry = _transports.begin(); - for (; entry != _transports.end(); ++entry) { - if (entry->first == connectionId) { - return entry; - } - } - return entry; - } - - void QueryableUsesPort::_addTransportEntry(const std::string& connectionId, BasicTransport* transport) - { - _transports.push_back(transport_entry(connectionId, transport)); - } -} - namespace bulkio { /* @@ -80,7 +44,7 @@ namespace bulkio { LOGGER_PTR logger, ConnectionEventListener *connectCB, ConnectionEventListener *disconnectCB ) : - QueryableUsesPort(port_name), + redhawk::UsesPort(port_name), logger(logger) { @@ -107,7 +71,7 @@ namespace bulkio { OutPortBase< PortTraits >::OutPortBase(std::string port_name, ConnectionEventListener *connectCB, ConnectionEventListener *disconnectCB ) : - QueryableUsesPort(port_name), + UsesPort(port_name), logger() { @@ -358,50 +322,31 @@ namespace bulkio { template < typename PortTraits > - void OutPortBase< PortTraits >::disconnectPort(const char* connectionId) + void OutPortBase< PortTraits >::_transportDisconnected(const std::string& connectionId, + redhawk::BasicTransport* transport) { - TRACE_ENTER(logger, "OutPort::disconnectPort" ); - { - SCOPED_LOCK lock(updatingPortsLock); // don't want to process while command information is coming in - - const std::string cid(connectionId); - transport_list::iterator iter = _findTransportEntry(connectionId); - if (iter != _transports.end()) { - PortTransportType* port = static_cast(iter->second); + TRACE_ENTER(logger, "OutPort::disconnectPort" ); + PortTransportType* port = static_cast(transport); - // Send an EOS for every connection that's listed for this SRI - for (typename OutPortSriMap::iterator cSRIs = currentSRIs.begin(); cSRIs!=currentSRIs.end(); cSRIs++) { - const std::string stream_id(cSRIs->second.sri.streamID); - - // Check if we have sent out sri/data to the connection - if (cSRIs->second.connections.count( cid ) != 0) { - if (_isStreamRoutedToConnection(stream_id, cid)) { - try { - port->sendEOS(stream_id); - } catch (...) { - // Ignore all exceptions; the receiver may be dead - } - } - } - - // remove connection id from sri connections list - cSRIs->second.connections.erase(connectionId); - } + // Send an EOS for every connection that's listed for this SRI + for (typename OutPortSriMap::iterator cSRIs = currentSRIs.begin(); cSRIs!=currentSRIs.end(); cSRIs++) { + const std::string stream_id(cSRIs->second.sri.streamID); - LOG_DEBUG( logger, "DISCONNECT, PORT/CONNECTION: " << name << "/" << connectionId ); - delete port; - _transports.erase(iter); + // Check if we have sent out sri/data to the connection + if (cSRIs->second.connections.count(connectionId) != 0) { + if (port->isAlive() && _isStreamRoutedToConnection(stream_id, connectionId)) { + try { + port->sendEOS(stream_id); + } catch (...) { + // Ignore all exceptions; the receiver may be dead + } + } + } - if (_transports.empty()) { - active = false; - } - } - } - if (_disconnectCB) { - (*_disconnectCB)(connectionId); - } - - TRACE_EXIT(logger, "OutPort::disconnectPort" ); + // remove connection id from sri connections list + cSRIs->second.connections.erase(connectionId); + } + TRACE_EXIT(logger, "OutPort::disconnectPort" ); } template < typename PortTraits > diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h index 3be19f9bf..81abed927 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h @@ -30,76 +30,13 @@ #include #include +#include #include "bulkio_base.h" #include "bulkio_traits.h" #include "bulkio_callbacks.h" #include "bulkio_out_stream.h" -namespace redhawk { - class BasicTransport - { - public: - BasicTransport(CORBA::Object_ptr objref) : - _objref(CORBA::Object::_duplicate(objref)), - _alive(true) - { - } - - virtual ~BasicTransport() - { - } - - bool isAlive() const - { - return _alive; - } - - void setAlive(bool alive) - { - _alive = alive; - } - - CORBA::Object_var objref() - { - if (isAlive()) { - return CORBA::Object::_duplicate(_objref); - } else { - return CORBA::Object::_nil(); - } - } - - private: - CORBA::Object_var _objref; - bool _alive; - }; - - class QueryableUsesPort : public Port_Uses_base_impl -#ifdef BEGIN_AUTOCOMPLETE_IGNORE - , public virtual POA_BULKIO::UsesPortStatisticsProvider -#endif - { - public: - QueryableUsesPort(const std::string& name); - - // - // connections - Return a list of connection objects and identifiers for each connection made by connectPort - // - // @return ExtendedCF::UsesConnectionSequence* List of connection objects and identifiers - // - virtual ExtendedCF::UsesConnectionSequence* connections(); - - protected: - typedef std::pair transport_entry; - typedef std::vector transport_list; - - transport_list::iterator _findTransportEntry(const std::string& connectionId); - void _addTransportEntry(const std::string& connectionId, BasicTransport* transport); - - transport_list _transports; - }; -} - namespace bulkio { template class InPort; @@ -135,7 +72,10 @@ namespace bulkio { // // template < typename PortTraits > - class OutPortBase : public redhawk::QueryableUsesPort + class OutPortBase : public redhawk::UsesPort +#ifdef BEGIN_AUTOCOMPLETE_IGNORE + , public virtual POA_BULKIO::UsesPortStatisticsProvider +#endif { public: @@ -219,13 +159,6 @@ namespace bulkio { // virtual void connectPort(CORBA::Object_ptr connection, const char* connectionId); - // - // disconnectPort - Called by the framework to disconnect this port from the Provides port object. The port basicall removes - // the association to the provides port that was established with the connectionId. - // - // @param connectionsId identifer for this connection, allows for external users to reference the connection association - virtual void disconnectPort(const char* connectionId); - void updateConnectionFilter(const std::vector &_filterTable) { SCOPED_LOCK lock(updatingPortsLock); // don't want to process while command information is coming in filterTable = _filterTable; @@ -382,6 +315,8 @@ namespace bulkio { bool EOS, const std::string& streamID); + virtual void _transportDisconnected(const std::string& connectionId, redhawk::BasicTransport* transport); + virtual void addStream(const std::string& streamID, const BULKIO::StreamSRI& sri); virtual void removeStream(const std::string& streamID); }; diff --git a/redhawk/src/base/framework/Makefile.am b/redhawk/src/base/framework/Makefile.am index 3d22d8cec..7c4703e19 100644 --- a/redhawk/src/base/framework/Makefile.am +++ b/redhawk/src/base/framework/Makefile.am @@ -57,7 +57,8 @@ libossiecf_la_SOURCES = AggregateDevice_impl.cpp \ PropertyType.cpp \ PropertyMap.cpp \ Versions.cpp \ - ExecutorService.cpp + ExecutorService.cpp \ + UsesPort.cpp libossiecf_la_CXXFLAGS = -Wall $(BOOST_CPPFLAGS) $(OMNICOS_CFLAGS) $(OMNIORB_CFLAGS) $(LOG4CXX_FLAGS) # Include the omniORB internal directory, otherwise CorbaUtils will not build diff --git a/redhawk/src/base/framework/UsesPort.cpp b/redhawk/src/base/framework/UsesPort.cpp new file mode 100644 index 000000000..04c027cc9 --- /dev/null +++ b/redhawk/src/base/framework/UsesPort.cpp @@ -0,0 +1,68 @@ +#include +#include + +namespace redhawk { + + UsesPort::UsesPort(const std::string& name) : + Port_Uses_base_impl(name) + { + } + + void UsesPort::disconnectPort(const char* connectionId) + { + //TRACE_ENTER(logger, "OutPort::disconnectPort" ); + { + boost::mutex::scoped_lock lock(updatingPortsLock); + + transport_list::iterator iter = _findTransportEntry(connectionId); + if (iter != _transports.end()) { + _transportDisconnected(iter->first, iter->second); + } + + //LOG_DEBUG( logger, "DISCONNECT, PORT/CONNECTION: " << name << "/" << connectionId ); + delete iter->second; + _transports.erase(iter); + + if (_transports.empty()) { + active = false; + } + } + //if (_disconnectCB) { + // (*_disconnectCB)(connectionId); + //} + //TRACE_EXIT(logger, "OutPort::disconnectPort" ); + } + + ExtendedCF::UsesConnectionSequence* UsesPort::connections() + { + boost::mutex::scoped_lock lock(updatingPortsLock); // don't want to process while command information is coming in + ExtendedCF::UsesConnectionSequence_var retVal = new ExtendedCF::UsesConnectionSequence(); + for (transport_list::iterator port = _transports.begin(); port != _transports.end(); ++port) { + ExtendedCF::UsesConnection conn; + conn.connectionId = port->first.c_str(); + conn.port = port->second->objref(); + ossie::corba::push_back(retVal, conn); + } + return retVal._retn(); + } + + UsesPort::transport_list::iterator UsesPort::_findTransportEntry(const std::string& connectionId) + { + transport_list::iterator entry = _transports.begin(); + for (; entry != _transports.end(); ++entry) { + if (entry->first == connectionId) { + return entry; + } + } + return entry; + } + + void UsesPort::_addTransportEntry(const std::string& connectionId, BasicTransport* transport) + { + _transports.push_back(transport_entry(connectionId, transport)); + } + + void UsesPort::_transportDisconnected(const std::string& connectionId, BasicTransport* transport) + { + } +} diff --git a/redhawk/src/base/include/ossie/Makefile.am b/redhawk/src/base/include/ossie/Makefile.am index 73739e95f..06deb89df 100644 --- a/redhawk/src/base/include/ossie/Makefile.am +++ b/redhawk/src/base/include/ossie/Makefile.am @@ -63,7 +63,8 @@ pkginclude_HEADERS = AggregateDevice_impl.h \ Autocomplete.h \ Versions.h \ shared_buffer.h \ - ExecutorService.h + ExecutorService.h \ + UsesPort.h nobase_pkginclude_HEADERS = internal/equals.h \ logging/rh_logger.h \ diff --git a/redhawk/src/base/include/ossie/UsesPort.h b/redhawk/src/base/include/ossie/UsesPort.h new file mode 100644 index 000000000..e20898cac --- /dev/null +++ b/redhawk/src/base/include/ossie/UsesPort.h @@ -0,0 +1,76 @@ +#ifndef OSSIE_USESPORT_H +#define OSSIE_USESPORT_H + +#include +#include + +#include + +#include "CF/QueryablePort.h" +#include "Autocomplete.h" +#include "Port_impl.h" + +namespace redhawk { + class BasicTransport + { + public: + BasicTransport(CORBA::Object_ptr objref) : + _objref(CORBA::Object::_duplicate(objref)), + _alive(true) + { + } + + virtual ~BasicTransport() + { + } + + bool isAlive() const + { + return _alive; + } + + void setAlive(bool alive) + { + _alive = alive; + } + + CORBA::Object_var objref() + { + if (isAlive()) { + return CORBA::Object::_duplicate(_objref); + } else { + return CORBA::Object::_nil(); + } + } + + private: + CORBA::Object_var _objref; + bool _alive; + }; + + class UsesPort : public Port_Uses_base_impl +#ifdef BEGIN_AUTOCOMPLETE_IGNORE + , public virtual POA_ExtendedCF::QueryablePort +#endif + { + public: + UsesPort(const std::string& name); + + virtual void disconnectPort(const char* connectionId); + + virtual ExtendedCF::UsesConnectionSequence* connections(); + + protected: + typedef std::pair transport_entry; + typedef std::vector transport_list; + + transport_list::iterator _findTransportEntry(const std::string& connectionId); + void _addTransportEntry(const std::string& connectionId, BasicTransport* transport); + + virtual void _transportDisconnected(const std::string& connectionId, BasicTransport* transport); + + transport_list _transports; + }; +} + +#endif // OSSIE_USESPORT_H From 65b21784ce949a3922859bc82a40cf71a48adaac Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 17 Nov 2016 18:34:47 -0500 Subject: [PATCH 0538/1644] Move most of connectPort from BulkIO to generic uses port class --- .../libsrc/cpp/bulkio_out_port.cpp | 59 ++++++++++--------- bulkioInterfaces/libsrc/cpp/bulkio_out_port.h | 21 ++----- redhawk/src/base/framework/UsesPort.cpp | 53 ++++++++++++++++- redhawk/src/base/include/ossie/UsesPort.h | 51 ++++++++++++++++ 4 files changed, 137 insertions(+), 47 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp index 2b192583a..8dc1e4c7c 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp @@ -57,10 +57,12 @@ namespace bulkio { if ( connectCB ) { _connectCB = boost::shared_ptr< ConnectionEventListener >( connectCB, null_deleter() ); } + addConnectListener(this, &OutPortBase::_connectListenerAdapter); if ( disconnectCB ) { _disconnectCB = boost::shared_ptr< ConnectionEventListener >( disconnectCB, null_deleter() ); } + addDisconnectListener(this, &OutPortBase::_disconnectListenerAdapter); LOG_DEBUG( logger, "bulkio::OutPort::CTOR port:" << name ); @@ -81,10 +83,12 @@ namespace bulkio { if ( connectCB ) { _connectCB = boost::shared_ptr< ConnectionEventListener >( connectCB, null_deleter() ); } + addConnectListener(this, &OutPortBase::_connectListenerAdapter); if ( disconnectCB ) { _disconnectCB = boost::shared_ptr< ConnectionEventListener >( disconnectCB, null_deleter() ); } + addDisconnectListener(this, &OutPortBase::_disconnectListenerAdapter); } @@ -144,6 +148,21 @@ namespace bulkio { return; } + template < typename PortTraits > + void OutPortBase< PortTraits >::_connectListenerAdapter(const std::string& connectionId) + { + if (_connectCB) { + (*_connectCB)(connectionId.c_str()); + } + } + + template < typename PortTraits > + void OutPortBase< PortTraits >::_disconnectListenerAdapter(const std::string& connectionId) + { + if (_disconnectCB) { + (*_disconnectCB)(connectionId.c_str()); + } + } template < typename PortTraits > bool OutPortBase< PortTraits >::_isStreamRoutedToConnection( @@ -265,42 +284,28 @@ namespace bulkio { template < typename PortTraits > - void OutPortBase< PortTraits >::connectPort(CORBA::Object_ptr connection, const char* connectionId) + redhawk::BasicTransport* + OutPortBase< PortTraits >::_createTransport(CORBA::Object_ptr object, const std::string& connectionId) { - TRACE_ENTER(logger, "OutPort::connectPort" ); - { - SCOPED_LOCK lock(updatingPortsLock); // don't want to process while command information is coming in PortVarType port; try { - port = PortType::_narrow(connection); - if (CORBA::is_nil(port)) { - throw CF::Port::InvalidPort(1, "Unable to narrow"); - } - } - catch(...) { - LOG_ERROR( logger, "CONNECT FAILED: UNABLE TO NARROW ENDPOINT, USES PORT:" << name ); - throw CF::Port::InvalidPort(1, "Unable to narrow"); + port = PortType::_narrow(object); + if (CORBA::is_nil(port)) { + throw CF::Port::InvalidPort(1, "Unable to narrow"); + } + } catch (const CORBA::SystemException&) { + LOG_ERROR( logger, "CONNECT FAILED: UNABLE TO NARROW ENDPOINT, USES PORT:" << name ); + throw CF::Port::InvalidPort(1, "Unable to narrow"); } LocalPortType* local_port = ossie::corba::getLocalServant(port); - PortTransportType* transport; if (local_port) { - LOG_DEBUG(logger, "Using local connection to port " << local_port->getName() - << " for connection " << connectionId); - transport = _createLocalConnection(port, local_port, connectionId); + LOG_DEBUG(logger, "Using local connection to port " << local_port->getName() + << " for connection " << connectionId); + return _createLocalConnection(port, local_port, connectionId); } else { - transport = _createRemoteConnection(port, connectionId); + return _createRemoteConnection(port, connectionId); } - _addTransportEntry(connectionId, transport); - - active = true; - - LOG_DEBUG( logger, "CONNECTION ESTABLISHED, PORT/CONNECTION_ID:" << name << "/" << connectionId ); - - } - if (_connectCB) (*_connectCB)(connectionId); - - TRACE_EXIT(logger, "OutPort::connectPort" ); } diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h index 81abed927..36e8aa202 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h @@ -145,20 +145,6 @@ namespace bulkio { // virtual ~OutPortBase(); - // - // Interface used by framework to connect/disconnect ports together and introspection of connection states - // - - // - // connectPort - Called by the framework to connect this port to a Provides port object, the connection is established - // via the association and identified by the connectionId string, no formal "type capatablity" or "bukio interface support" - // is resolved at this time. All data flow occurs from point A to B via the pushPacket/pushSRI interface. - // - // @param CORBA::Object_ptr pointer to an instance of a Provides port - // @param connectionsId identifer for this connection, allows for external users to reference the connection association - // - virtual void connectPort(CORBA::Object_ptr connection, const char* connectionId); - void updateConnectionFilter(const std::vector &_filterTable) { SCOPED_LOCK lock(updatingPortsLock); // don't want to process while command information is coming in filterTable = _filterTable; @@ -289,18 +275,19 @@ namespace bulkio { typedef typename LocalTraits::InPortType LocalPortType; typedef PortTransport PortTransportType; + virtual redhawk::BasicTransport* _createTransport(CORBA::Object_ptr object, const std::string& connectionId); virtual PortTransportType* _createRemoteConnection(PortPtrType port, const std::string& connectionId); virtual PortTransportType* _createLocalConnection(PortPtrType port, LocalPortType* localPort, const std::string& connectionId); - //typedef std::map TransportMap; - //TransportMap _transportMap; - LOGGER_PTR logger; std::vector filterTable; boost::shared_ptr< ConnectionEventListener > _connectCB; boost::shared_ptr< ConnectionEventListener > _disconnectCB; + void _connectListenerAdapter(const std::string& connectionId); + void _disconnectListenerAdapter(const std::string& connectionId); + // // Returns true if the given connection should receive SRI updates and data // for the given stream diff --git a/redhawk/src/base/framework/UsesPort.cpp b/redhawk/src/base/framework/UsesPort.cpp index 04c027cc9..23e0e8b09 100644 --- a/redhawk/src/base/framework/UsesPort.cpp +++ b/redhawk/src/base/framework/UsesPort.cpp @@ -8,6 +8,49 @@ namespace redhawk { { } + void UsesPort::connectPort(CORBA::Object_ptr connection, const char* connectionId) + { + // Give a specific exception message for nil + if (CORBA::is_nil(connection)) { + throw CF::Port::InvalidPort(1, "Nil object reference"); + } + + // Attempt to check the type of the remote object to reject invalid + // types; note this does not require the lock + const std::string rep_id = getRepid(); + bool valid; + try { + valid = connection->_is_a(rep_id.c_str()); + } catch (...) { + // If _is_a throws an exception, assume the remote object is + // unreachable (e.g., dead) + throw CF::Port::InvalidPort(1, "Object unreachable"); + } + + if (!valid) { + std::string message = "Object does not support " + rep_id; + throw CF::Port::InvalidPort(1, message.c_str()); + } + + const std::string connection_id(connectionId); + { + // Acquire the state lock before modifying the container + boost::mutex::scoped_lock lock(updatingPortsLock); + + transport_list::iterator entry = _findTransportEntry(connection_id); + if (entry == _transports.end()) { + BasicTransport* transport = _createTransport(connection, connection_id); + _addTransportEntry(connection_id, transport); + } else { + // TODO: Replace the object reference + } + + active = true; + } + + _portConnected(connectionId); + } + void UsesPort::disconnectPort(const char* connectionId) { //TRACE_ENTER(logger, "OutPort::disconnectPort" ); @@ -27,9 +70,8 @@ namespace redhawk { active = false; } } - //if (_disconnectCB) { - // (*_disconnectCB)(connectionId); - //} + + _portDisconnected(connectionId); //TRACE_EXIT(logger, "OutPort::disconnectPort" ); } @@ -62,6 +104,11 @@ namespace redhawk { _transports.push_back(transport_entry(connectionId, transport)); } + BasicTransport* UsesPort::_createTransport(CORBA::Object_ptr object, const std::string& connectionId) + { + return new BasicTransport(object); + } + void UsesPort::_transportDisconnected(const std::string& connectionId, BasicTransport* transport) { } diff --git a/redhawk/src/base/include/ossie/UsesPort.h b/redhawk/src/base/include/ossie/UsesPort.h index e20898cac..a37191936 100644 --- a/redhawk/src/base/include/ossie/UsesPort.h +++ b/redhawk/src/base/include/ossie/UsesPort.h @@ -7,8 +7,10 @@ #include #include "CF/QueryablePort.h" + #include "Autocomplete.h" #include "Port_impl.h" +#include "callback.h" namespace redhawk { class BasicTransport @@ -56,6 +58,50 @@ namespace redhawk { public: UsesPort(const std::string& name); + // Register the member function 'func' to be called on class instance + // 'target' when a new connection is made. The function receives one + // argument, the connection ID: + // + // void Target::func(const std::string&); + // + template + void addConnectListener (Target target, Func func) + { + _portConnected.add(target, func); + } + + // Unregister the member function 'func' on class instance 'target' + // from further connection notifications. If the pair has not been + // registered previously, it is ignored. + template + void removeConnectListener (Target target, Func func) + { + _portConnected.remove(target, func); + } + + // Register the member function 'func' to be called on class instance + // 'target' when an existing connection is broken. The function + // receives one argument, the connection ID: + // + // void Target::func(const std::string&); + // + template + void addDisconnectListener (Target target, Func func) + { + _portDisconnected.add(target, func); + } + + // Unregister the member function 'func' on class instance 'target' + // from further disconnection notifications. If the pair has not been + // registered previously, it is ignored. + template + void removeDisconnectListener (Target target, Func func) + { + _portDisconnected.remove(target, func); + } + + virtual void connectPort(CORBA::Object_ptr connection, const char* connectionId); + virtual void disconnectPort(const char* connectionId); virtual ExtendedCF::UsesConnectionSequence* connections(); @@ -67,9 +113,14 @@ namespace redhawk { transport_list::iterator _findTransportEntry(const std::string& connectionId); void _addTransportEntry(const std::string& connectionId, BasicTransport* transport); + virtual BasicTransport* _createTransport(CORBA::Object_ptr object, const std::string& connectionId); virtual void _transportDisconnected(const std::string& connectionId, BasicTransport* transport); transport_list _transports; + + private: + ossie::notification _portConnected; + ossie::notification _portDisconnected; }; } From 137c34ccb30528c6dd0dbde03af3f1c69b8c0b4a Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 18 Nov 2016 09:50:09 -0500 Subject: [PATCH 0539/1644] Re-implement C++ MessageSupplier as a subclass of generic UsesPort class --- .../src/base/framework/MessageInterface.cpp | 92 +++++++++---------- redhawk/src/base/framework/UsesPort.cpp | 33 ++++--- .../src/base/include/ossie/MessageInterface.h | 20 ++-- redhawk/src/base/include/ossie/UsesPort.h | 2 + 4 files changed, 68 insertions(+), 79 deletions(-) diff --git a/redhawk/src/base/framework/MessageInterface.cpp b/redhawk/src/base/framework/MessageInterface.cpp index e909f7c9c..5eb92dc92 100644 --- a/redhawk/src/base/framework/MessageInterface.cpp +++ b/redhawk/src/base/framework/MessageInterface.cpp @@ -222,10 +222,11 @@ std::string MessageConsumerPort::getDirection() const } -class MessageSupplierPort::MessageTransport +class MessageSupplierPort::MessageTransport : public redhawk::BasicTransport { public: MessageTransport(CosEventChannelAdmin::EventChannel_ptr channel) : + redhawk::BasicTransport(channel), _channel(CosEventChannelAdmin::EventChannel::_duplicate(channel)) { } @@ -242,11 +243,6 @@ class MessageSupplierPort::MessageTransport virtual void disconnect() = 0; - CosEventChannelAdmin::EventChannel_ptr objref() - { - return CosEventChannelAdmin::EventChannel::_narrow(_channel); - } - private: CosEventChannelAdmin::EventChannel_var _channel; }; @@ -403,69 +399,60 @@ class MessageSupplierPort::LocalTransport : public MessageSupplierPort::MessageT }; MessageSupplierPort::MessageSupplierPort (std::string port_name) : - Port_Uses_base_impl(port_name) + UsesPort(port_name) { } MessageSupplierPort::~MessageSupplierPort (void) { - for (TransportMap::iterator connection = _connections.begin(); connection != _connections.end(); ++connection) { - delete connection->second; - } } -void MessageSupplierPort::connectPort(CORBA::Object_ptr connection, const char* connectionId) +void MessageSupplierPort::_validatePort(CORBA::Object_ptr object) { - CosEventChannelAdmin::EventChannel_var channel = ossie::corba::_narrowSafe(connection); - if (CORBA::is_nil(channel)) { - throw CF::Port::InvalidPort(0, "The object provided did not narrow to a CosEventChannelAdmin::EventChannel type"); + const std::string rep_id(CosEventChannelAdmin::EventChannel::_PD_repoId); + bool valid; + try { + valid = object->_is_a(rep_id.c_str()); + } catch (...) { + // If _is_a throws an exception, assume the remote object is + // unreachable (e.g., dead) + throw CF::Port::InvalidPort(1, "Object unreachable"); } - { - boost::mutex::scoped_lock lock(updatingPortsLock); - MessageTransport* transport; - MessageConsumerPort* local_port = ossie::corba::getLocalServant(channel); - if (local_port) { - transport = new LocalTransport(local_port, channel); - } else { - transport = new RemoteTransport(channel); - } - _connections[connectionId] = transport; + if (!valid) { + std::string message = "Object does not support " + rep_id; + throw CF::Port::InvalidPort(1, message.c_str()); } } -void MessageSupplierPort::disconnectPort(const char* connectionId) +redhawk::BasicTransport* MessageSupplierPort::_createTransport(CORBA::Object_ptr object, const std::string& connectionId) { - boost::mutex::scoped_lock lock(updatingPortsLock); - TransportMap::iterator connection = _connections.find(connectionId); - if (connection == _connections.end()) { - return; + CosEventChannelAdmin::EventChannel_var channel = ossie::corba::_narrowSafe(object); + if (CORBA::is_nil(channel)) { + throw CF::Port::InvalidPort(0, "The object provided did not narrow to a CosEventChannelAdmin::EventChannel type"); + } + + MessageConsumerPort* local_port = ossie::corba::getLocalServant(channel); + if (local_port) { + return new LocalTransport(local_port, channel); + } else { + return new RemoteTransport(channel); } - connection->second->disconnect(); - delete connection->second; - _connections.erase(connection); } -ExtendedCF::UsesConnectionSequence* MessageSupplierPort::connections() +void MessageSupplierPort::_transportDisconnected(redhawk::BasicTransport* transport) { - ExtendedCF::UsesConnectionSequence_var result = new ExtendedCF::UsesConnectionSequence(); - boost::mutex::scoped_lock lock(updatingPortsLock); - result->length(_connections.size()); - CORBA::ULong index = 0; - for (TransportMap::iterator connection = _connections.begin(); connection != _connections.end(); ++connection) { - result[index].connectionId = connection->first.c_str(); - result[index].port = connection->second->objref(); - ++index; - } - return result._retn(); + MessageTransport* message_transport = static_cast(transport); + message_transport->disconnect(); } void MessageSupplierPort::push(const CORBA::Any& data) { boost::mutex::scoped_lock lock(updatingPortsLock); - for (TransportMap::iterator connection = _connections.begin(); connection != _connections.end(); ++connection) { + for (transport_list::iterator iter = _transports.begin(); iter != _transports.end(); ++iter) { + MessageTransport* transport = static_cast(iter->second); try { - connection->second->push(data); + transport->push(data); } catch ( ... ) { } } @@ -478,16 +465,18 @@ std::string MessageSupplierPort::getRepid() const void MessageSupplierPort::_beginMessageQueue(size_t count) { - for (TransportMap::iterator connection = _connections.begin(); connection != _connections.end(); ++connection) { - connection->second->beginQueue(count); + for (transport_list::iterator iter = _transports.begin(); iter != _transports.end(); ++iter) { + MessageTransport* transport = static_cast(iter->second); + transport->beginQueue(count); } } void MessageSupplierPort::_queueMessage(const std::string& msgId, const char* format, const void* msgData, SerializerFunc serializer) { - for (TransportMap::iterator connection = _connections.begin(); connection != _connections.end(); ++connection) { + for (transport_list::iterator iter = _transports.begin(); iter != _transports.end(); ++iter) { + MessageTransport* transport = static_cast(iter->second); try { - connection->second->queueMessage(msgId, format, msgData, serializer); + transport->queueMessage(msgId, format, msgData, serializer); } catch ( ... ) { } } @@ -495,7 +484,8 @@ void MessageSupplierPort::_queueMessage(const std::string& msgId, const char* fo void MessageSupplierPort::_sendMessageQueue() { - for (TransportMap::iterator connection = _connections.begin(); connection != _connections.end(); ++connection) { - connection->second->sendMessages(); + for (transport_list::iterator iter = _transports.begin(); iter != _transports.end(); ++iter) { + MessageTransport* transport = static_cast(iter->second); + transport->sendMessages(); } } diff --git a/redhawk/src/base/framework/UsesPort.cpp b/redhawk/src/base/framework/UsesPort.cpp index 23e0e8b09..825f56ab4 100644 --- a/redhawk/src/base/framework/UsesPort.cpp +++ b/redhawk/src/base/framework/UsesPort.cpp @@ -17,20 +17,7 @@ namespace redhawk { // Attempt to check the type of the remote object to reject invalid // types; note this does not require the lock - const std::string rep_id = getRepid(); - bool valid; - try { - valid = connection->_is_a(rep_id.c_str()); - } catch (...) { - // If _is_a throws an exception, assume the remote object is - // unreachable (e.g., dead) - throw CF::Port::InvalidPort(1, "Object unreachable"); - } - - if (!valid) { - std::string message = "Object does not support " + rep_id; - throw CF::Port::InvalidPort(1, message.c_str()); - } + _validatePort(connection); const std::string connection_id(connectionId); { @@ -88,6 +75,24 @@ namespace redhawk { return retVal._retn(); } + void UsesPort::_validatePort(CORBA::Object_ptr object) + { + const std::string rep_id = getRepid(); + bool valid; + try { + valid = object->_is_a(rep_id.c_str()); + } catch (...) { + // If _is_a throws an exception, assume the remote object is + // unreachable (e.g., dead) + throw CF::Port::InvalidPort(1, "Object unreachable"); + } + + if (!valid) { + std::string message = "Object does not support " + rep_id; + throw CF::Port::InvalidPort(1, message.c_str()); + } + } + UsesPort::transport_list::iterator UsesPort::_findTransportEntry(const std::string& connectionId) { transport_list::iterator entry = _transports.begin(); diff --git a/redhawk/src/base/include/ossie/MessageInterface.h b/redhawk/src/base/include/ossie/MessageInterface.h index 2c0a31bb8..c132a46e6 100644 --- a/redhawk/src/base/include/ossie/MessageInterface.h +++ b/redhawk/src/base/include/ossie/MessageInterface.h @@ -267,24 +267,14 @@ class MessageConsumerPort : public Port_Provides_base_impl /************************************************************************************ Message producer ************************************************************************************/ - -class MessageSupplierPort : public Port_Uses_base_impl -#ifdef BEGIN_AUTOCOMPLETE_IGNORE -, public virtual POA_ExtendedCF::QueryablePort -#endif +#include "UsesPort.h" +class MessageSupplierPort : public redhawk::UsesPort { public: MessageSupplierPort (std::string port_name); virtual ~MessageSupplierPort (void); - // CF::Port methods - void connectPort(CORBA::Object_ptr connection, const char* connectionId); - void disconnectPort(const char* connectionId); - - // ExtendedCF::QueryablePort methods - ExtendedCF::UsesConnectionSequence* connections(); - void push(const CORBA::Any& data); // Send a single message @@ -316,6 +306,10 @@ class MessageSupplierPort : public Port_Uses_base_impl std::string getRepid() const; protected: + virtual void _validatePort(CORBA::Object_ptr object); + virtual redhawk::BasicTransport* _createTransport(CORBA::Object_ptr object, const std::string& connectionId); + virtual void _transportDisconnected(redhawk::BasicTransport* transport); + template inline void _queueMessage(const Message& message) { @@ -341,8 +335,6 @@ class MessageSupplierPort : public Port_Uses_base_impl class MessageTransport; class RemoteTransport; class LocalTransport; - typedef std::map TransportMap; - TransportMap _connections; }; #endif // MESSAGEINTERFACE_H diff --git a/redhawk/src/base/include/ossie/UsesPort.h b/redhawk/src/base/include/ossie/UsesPort.h index a37191936..d8bf2a706 100644 --- a/redhawk/src/base/include/ossie/UsesPort.h +++ b/redhawk/src/base/include/ossie/UsesPort.h @@ -110,6 +110,8 @@ namespace redhawk { typedef std::pair transport_entry; typedef std::vector transport_list; + virtual void _validatePort(CORBA::Object_ptr object); + transport_list::iterator _findTransportEntry(const std::string& connectionId); void _addTransportEntry(const std::string& connectionId, BasicTransport* transport); From 7527fd4f6dbf1f38bc7c2c12acc86b3f64f5ba7f Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 18 Nov 2016 10:36:48 -0500 Subject: [PATCH 0540/1644] Move BasicTransport implementation to .cpp file; return a non-owning pointer and set nil for dead endpoints in connections() --- redhawk/src/base/framework/UsesPort.cpp | 28 +++++++++++++++++++- redhawk/src/base/include/ossie/UsesPort.h | 31 ++++------------------- 2 files changed, 32 insertions(+), 27 deletions(-) diff --git a/redhawk/src/base/framework/UsesPort.cpp b/redhawk/src/base/framework/UsesPort.cpp index 825f56ab4..47b9ddee8 100644 --- a/redhawk/src/base/framework/UsesPort.cpp +++ b/redhawk/src/base/framework/UsesPort.cpp @@ -2,6 +2,28 @@ #include namespace redhawk { + + BasicTransport::BasicTransport(CORBA::Object_ptr objref) : + _objref(CORBA::Object::_duplicate(objref)), + _alive(true) + { + } + + bool BasicTransport::isAlive() const + { + return _alive; + } + + void BasicTransport::setAlive(bool alive) + { + _alive = alive; + } + + CORBA::Object_ptr BasicTransport::objref() const + { + return _objref; + } + UsesPort::UsesPort(const std::string& name) : Port_Uses_base_impl(name) @@ -69,7 +91,11 @@ namespace redhawk { for (transport_list::iterator port = _transports.begin(); port != _transports.end(); ++port) { ExtendedCF::UsesConnection conn; conn.connectionId = port->first.c_str(); - conn.port = port->second->objref(); + if (port->second->isAlive()) { + conn.port = CORBA::Object::_duplicate(port->second->objref()); + } else { + conn.port = CORBA::Object::_nil(); + } ossie::corba::push_back(retVal, conn); } return retVal._retn(); diff --git a/redhawk/src/base/include/ossie/UsesPort.h b/redhawk/src/base/include/ossie/UsesPort.h index d8bf2a706..fb5d8f3f3 100644 --- a/redhawk/src/base/include/ossie/UsesPort.h +++ b/redhawk/src/base/include/ossie/UsesPort.h @@ -16,34 +16,13 @@ namespace redhawk { class BasicTransport { public: - BasicTransport(CORBA::Object_ptr objref) : - _objref(CORBA::Object::_duplicate(objref)), - _alive(true) - { - } - - virtual ~BasicTransport() - { - } - - bool isAlive() const - { - return _alive; - } + BasicTransport(CORBA::Object_ptr objref); + virtual ~BasicTransport() { } - void setAlive(bool alive) - { - _alive = alive; - } + bool isAlive() const; + void setAlive(bool alive); - CORBA::Object_var objref() - { - if (isAlive()) { - return CORBA::Object::_duplicate(_objref); - } else { - return CORBA::Object::_nil(); - } - } + CORBA::Object_ptr objref() const; private: CORBA::Object_var _objref; From 45e34d4a01481456e01bf7c58ba49a376b12d6c9 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 18 Nov 2016 11:15:39 -0500 Subject: [PATCH 0541/1644] Move connection ID into BasicTransport --- .../libsrc/cpp/bulkio_connection.hpp | 31 +++++------ .../libsrc/cpp/bulkio_out_port.cpp | 51 ++++++++++--------- bulkioInterfaces/libsrc/cpp/bulkio_out_port.h | 2 +- .../src/base/framework/MessageInterface.cpp | 27 +++++----- redhawk/src/base/framework/UsesPort.cpp | 40 ++++++++------- .../src/base/include/ossie/MessageInterface.h | 2 +- redhawk/src/base/include/ossie/UsesPort.h | 15 +++--- 7 files changed, 90 insertions(+), 78 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp b/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp index 2ed49ccc8..c421f00ff 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp @@ -5,13 +5,13 @@ namespace bulkio { { public: typedef typename PortTraits::PortType PortType; - typedef typename PortType::_var_type PortVarType; - typedef typename PortType::_ptr_type PortPtrType; + typedef typename PortType::_var_type VarType; + typedef typename PortType::_ptr_type PtrType; typedef typename PortTraits::NativeType NativeType; typedef typename PortTraits::SharedBufferType SharedBufferType; - PortTransport(const std::string& name, PortPtrType objref) : - redhawk::BasicTransport(objref), + PortTransport(const std::string& connectionId, const std::string& name, PtrType objref) : + redhawk::BasicTransport(connectionId, objref), stats(name, sizeof(NativeType)), _port(PortType::_duplicate(objref)) { @@ -41,7 +41,7 @@ namespace bulkio { this->_pushPacket(SharedBufferType(), bulkio::time::utils::notSet(), true, streamID); } - PortPtrType objref() + PtrType objref() { if (isAlive()) { return PortType::_duplicate(_port); @@ -68,7 +68,7 @@ namespace bulkio { return data.size(); } - PortVarType _port; + VarType _port; }; template <> @@ -82,13 +82,13 @@ namespace bulkio { { public: typedef typename PortTraits::PortType PortType; - typedef typename PortType::_ptr_type PortPtrType; + typedef typename PortType::_ptr_type PtrType; typedef typename PortTraits::SharedBufferType SharedBufferType; typedef typename PortTraits::SequenceType PortSequenceType; typedef typename PortTraits::TransportType TransportType; - RemoteTransport(const std::string& name, PortPtrType port) : - PortTransport(name, port) + RemoteTransport(const std::string& connectionId, const std::string& name, PtrType port) : + PortTransport(connectionId, name, port) { } @@ -148,12 +148,12 @@ namespace bulkio { { public: typedef typename PortTraits::PortType PortType; - typedef typename PortType::_ptr_type PortPtrType; + typedef typename PortType::_ptr_type PtrType; typedef typename PortTraits::TransportType TransportType; typedef typename PortTraits::SharedBufferType SharedBufferType; - ChunkingTransport(const std::string& name, PortPtrType port) : - RemoteTransport(name, port) + ChunkingTransport(const std::string& connectionId, const std::string& name, PtrType port) : + RemoteTransport(connectionId, name, port) { // Multiply by some number < 1 to leave some margin for the CORBA header const size_t maxPayloadSize = (size_t) (bulkio::Const::MaxTransferBytes() * .9); @@ -226,12 +226,13 @@ namespace bulkio { { public: typedef typename PortTraits::PortType PortType; - typedef typename PortType::_ptr_type PortPtrType; + typedef typename PortType::_ptr_type PtrType; typedef typename LocalTraits::InPortType LocalPortType; typedef typename PortTraits::SharedBufferType SharedBufferType; - LocalTransport(const std::string& name, LocalPortType* localPort, PortPtrType port) : - PortTransport(name, port), + LocalTransport(const std::string& connectionId, const std::string& name, + LocalPortType* localPort, PtrType port) : + PortTransport(connectionId, name, port), _localPort(localPort) { _localPort->_add_ref(); diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp index 8dc1e4c7c..9f45e0480 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp @@ -123,23 +123,24 @@ namespace bulkio { if (active) { for (transport_list::iterator iter = _transports.begin(); iter != _transports.end(); ++iter) { - PortTransportType* port = static_cast(iter->second); + PortTransportType* port = static_cast(*iter); + const std::string& connection_id = port->connectionId(); // Skip ports known to be dead if (!port->isAlive()) { continue; } - if (!_isStreamRoutedToConnection(sid, iter->first)) { + if (!_isStreamRoutedToConnection(sid, connection_id)) { continue; } - LOG_DEBUG(logger,"pushSRI - PORT:" << name << " CONNECTION:" << iter->first << " SRI streamID:" + LOG_DEBUG(logger,"pushSRI - PORT:" << name << " CONNECTION:" << connection_id << " SRI streamID:" << H.streamID << " Mode:" << H.mode << " XDELTA:" << 1.0/H.xdelta); try { port->pushSRI(H); - sri_iter->second.connections.insert(iter->first); + sri_iter->second.connections.insert(connection_id); } catch (const redhawk::FatalTransportError& err) { LOG_ERROR(logger, "PUSH-SRI FAILED " << err.what() - << " PORT/CONNECTION: " << name << "/" << iter->first); + << " PORT/CONNECTION: " << name << "/" << connection_id); } } } @@ -211,7 +212,9 @@ namespace bulkio { if (active) { for (transport_list::iterator iter = _transports.begin(); iter != _transports.end(); ++iter) { - PortTransportType* port = static_cast(iter->second); + PortTransportType* port = static_cast(*iter); + const std::string& connection_id = port->connectionId(); + // Skip ports known to be dead if (!port->isAlive()) { continue; @@ -219,20 +222,20 @@ namespace bulkio { // Check whether filtering is enabled and if this connection should // receive the stream - if (!_isStreamRoutedToConnection(streamID, iter->first)) { + if (!_isStreamRoutedToConnection(streamID, connection_id)) { continue; } try { - if (sri_iter->second.connections.count(iter->first) == 0) { + if (sri_iter->second.connections.count(connection_id) == 0) { port->pushSRI(sri_iter->second.sri); - sri_iter->second.connections.insert(iter->first); + sri_iter->second.connections.insert(connection_id); } port->pushPacket(data, T, EOS, sri_iter->second.sri); } catch (const redhawk::FatalTransportError& err) { LOG_ERROR(logger, "PUSH-PACKET FAILED " << err.what() - << " PORT/CONNECTION: " << name << "/" << iter->first); + << " PORT/CONNECTION: " << name << "/" << connection_id); port->setAlive(false); } } @@ -252,9 +255,9 @@ namespace bulkio { SCOPED_LOCK lock(updatingPortsLock); BULKIO::UsesPortStatisticsSequence_var recStat = new BULKIO::UsesPortStatisticsSequence(); for (transport_list::iterator iter = _transports.begin(); iter != _transports.end(); ++iter) { - PortTransportType* port = static_cast(iter->second); + PortTransportType* port = static_cast(*iter); BULKIO::UsesPortStatistics stat; - stat.connectionId = iter->first.c_str(); + stat.connectionId = port->connectionId().c_str(); stat.statistics = port->stats.retrieve(); ossie::corba::push_back(recStat, stat); } @@ -277,7 +280,7 @@ namespace bulkio { { SCOPED_LOCK lock(updatingPortsLock); for (transport_list::iterator iter = _transports.begin(); iter != _transports.end(); ++iter) { - PortTransportType* port = static_cast(iter->second); + PortTransportType* port = static_cast(*iter); port->stats.setEnabled(enable); } } @@ -313,7 +316,7 @@ namespace bulkio { typename OutPortBase< PortTraits >::PortTransportType* OutPortBase< PortTraits >::_createRemoteConnection(PortPtrType port, const std::string& connectionId) { - return new RemoteTransport(name, port); + return new RemoteTransport(connectionId, name, port); } @@ -322,24 +325,24 @@ namespace bulkio { OutPortBase< PortTraits >::_createLocalConnection(PortPtrType port, LocalPortType* localPort, const std::string& connectionId) { - return new LocalTransport(name, localPort, port); + return new LocalTransport(connectionId, name, localPort, port); } template < typename PortTraits > - void OutPortBase< PortTraits >::_transportDisconnected(const std::string& connectionId, - redhawk::BasicTransport* transport) + void OutPortBase< PortTraits >::_disconnectTransport(redhawk::BasicTransport* transport) { TRACE_ENTER(logger, "OutPort::disconnectPort" ); PortTransportType* port = static_cast(transport); // Send an EOS for every connection that's listed for this SRI + const std::string& connection_id = transport->connectionId(); for (typename OutPortSriMap::iterator cSRIs = currentSRIs.begin(); cSRIs!=currentSRIs.end(); cSRIs++) { - const std::string stream_id(cSRIs->second.sri.streamID); + const std::string& stream_id = cSRIs->first; // Check if we have sent out sri/data to the connection - if (cSRIs->second.connections.count(connectionId) != 0) { - if (port->isAlive() && _isStreamRoutedToConnection(stream_id, connectionId)) { + if (cSRIs->second.connections.count(connection_id) != 0) { + if (port->isAlive() && _isStreamRoutedToConnection(stream_id, connection_id)) { try { port->sendEOS(stream_id); } catch (...) { @@ -349,7 +352,7 @@ namespace bulkio { } // remove connection id from sri connections list - cSRIs->second.connections.erase(connectionId); + cSRIs->second.connections.erase(connection_id); } TRACE_EXIT(logger, "OutPort::disconnectPort" ); } @@ -386,8 +389,8 @@ namespace bulkio { ConnectionsList outConnections; for (transport_list::iterator iter = _transports.begin(); iter != _transports.end(); ++iter) { - PortTransportType* port = static_cast(iter->second); - outConnections.push_back(std::make_pair(port->objref(), iter->first)); + PortTransportType* port = static_cast(*iter); + outConnections.push_back(std::make_pair(port->objref(), port->connectionId())); } return outConnections; @@ -475,7 +478,7 @@ namespace bulkio { typename OutPort::PortTransportType* OutPort::_createRemoteConnection(PortPtrType port, const std::string& connectionId) { - return new ChunkingTransport(this->name, port); + return new ChunkingTransport(connectionId, this->name, port); } diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h index 36e8aa202..7f5cdaca0 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h @@ -302,7 +302,7 @@ namespace bulkio { bool EOS, const std::string& streamID); - virtual void _transportDisconnected(const std::string& connectionId, redhawk::BasicTransport* transport); + virtual void _disconnectTransport(redhawk::BasicTransport* transport); virtual void addStream(const std::string& streamID, const BULKIO::StreamSRI& sri); virtual void removeStream(const std::string& streamID); diff --git a/redhawk/src/base/framework/MessageInterface.cpp b/redhawk/src/base/framework/MessageInterface.cpp index 5eb92dc92..07a95f5cb 100644 --- a/redhawk/src/base/framework/MessageInterface.cpp +++ b/redhawk/src/base/framework/MessageInterface.cpp @@ -225,8 +225,8 @@ std::string MessageConsumerPort::getDirection() const class MessageSupplierPort::MessageTransport : public redhawk::BasicTransport { public: - MessageTransport(CosEventChannelAdmin::EventChannel_ptr channel) : - redhawk::BasicTransport(channel), + MessageTransport(const std::string& connectionId, CosEventChannelAdmin::EventChannel_ptr channel) : + redhawk::BasicTransport(connectionId, channel), _channel(CosEventChannelAdmin::EventChannel::_duplicate(channel)) { } @@ -250,8 +250,8 @@ class MessageSupplierPort::MessageTransport : public redhawk::BasicTransport class MessageSupplierPort::RemoteTransport : public MessageSupplierPort::MessageTransport { public: - RemoteTransport(CosEventChannelAdmin::EventChannel_ptr channel) : - MessageTransport(channel) + RemoteTransport(const std::string& connectionId, CosEventChannelAdmin::EventChannel_ptr channel) : + MessageTransport(connectionId, channel) { CosEventChannelAdmin::SupplierAdmin_var supplier_admin = channel->for_suppliers(); _consumer = supplier_admin->obtain_push_consumer(); @@ -306,8 +306,9 @@ class MessageSupplierPort::RemoteTransport : public MessageSupplierPort::Message class MessageSupplierPort::LocalTransport : public MessageSupplierPort::MessageTransport { public: - LocalTransport(MessageConsumerPort* consumer, CosEventChannelAdmin::EventChannel_ptr channel) : - MessageTransport(channel), + LocalTransport(const std::string& connectionId, MessageConsumerPort* consumer, + CosEventChannelAdmin::EventChannel_ptr channel) : + MessageTransport(connectionId, channel), _consumer(consumer) { } @@ -434,13 +435,13 @@ redhawk::BasicTransport* MessageSupplierPort::_createTransport(CORBA::Object_ptr MessageConsumerPort* local_port = ossie::corba::getLocalServant(channel); if (local_port) { - return new LocalTransport(local_port, channel); + return new LocalTransport(connectionId, local_port, channel); } else { - return new RemoteTransport(channel); + return new RemoteTransport(connectionId, channel); } } -void MessageSupplierPort::_transportDisconnected(redhawk::BasicTransport* transport) +void MessageSupplierPort::_disconnectTransport(redhawk::BasicTransport* transport) { MessageTransport* message_transport = static_cast(transport); message_transport->disconnect(); @@ -450,7 +451,7 @@ void MessageSupplierPort::push(const CORBA::Any& data) { boost::mutex::scoped_lock lock(updatingPortsLock); for (transport_list::iterator iter = _transports.begin(); iter != _transports.end(); ++iter) { - MessageTransport* transport = static_cast(iter->second); + MessageTransport* transport = static_cast(*iter); try { transport->push(data); } catch ( ... ) { @@ -466,7 +467,7 @@ std::string MessageSupplierPort::getRepid() const void MessageSupplierPort::_beginMessageQueue(size_t count) { for (transport_list::iterator iter = _transports.begin(); iter != _transports.end(); ++iter) { - MessageTransport* transport = static_cast(iter->second); + MessageTransport* transport = static_cast(*iter); transport->beginQueue(count); } } @@ -474,7 +475,7 @@ void MessageSupplierPort::_beginMessageQueue(size_t count) void MessageSupplierPort::_queueMessage(const std::string& msgId, const char* format, const void* msgData, SerializerFunc serializer) { for (transport_list::iterator iter = _transports.begin(); iter != _transports.end(); ++iter) { - MessageTransport* transport = static_cast(iter->second); + MessageTransport* transport = static_cast(*iter); try { transport->queueMessage(msgId, format, msgData, serializer); } catch ( ... ) { @@ -485,7 +486,7 @@ void MessageSupplierPort::_queueMessage(const std::string& msgId, const char* fo void MessageSupplierPort::_sendMessageQueue() { for (transport_list::iterator iter = _transports.begin(); iter != _transports.end(); ++iter) { - MessageTransport* transport = static_cast(iter->second); + MessageTransport* transport = static_cast(*iter); transport->sendMessages(); } } diff --git a/redhawk/src/base/framework/UsesPort.cpp b/redhawk/src/base/framework/UsesPort.cpp index 47b9ddee8..c43d476b8 100644 --- a/redhawk/src/base/framework/UsesPort.cpp +++ b/redhawk/src/base/framework/UsesPort.cpp @@ -3,12 +3,18 @@ namespace redhawk { - BasicTransport::BasicTransport(CORBA::Object_ptr objref) : + BasicTransport::BasicTransport(const std::string& connectionId, CORBA::Object_ptr objref) : + _connectionId(connectionId), _objref(CORBA::Object::_duplicate(objref)), _alive(true) { } + const std::string& BasicTransport::connectionId() const + { + return _connectionId; + } + bool BasicTransport::isAlive() const { return _alive; @@ -49,7 +55,7 @@ namespace redhawk { transport_list::iterator entry = _findTransportEntry(connection_id); if (entry == _transports.end()) { BasicTransport* transport = _createTransport(connection, connection_id); - _addTransportEntry(connection_id, transport); + _addTransportEntry(transport); } else { // TODO: Replace the object reference } @@ -66,14 +72,14 @@ namespace redhawk { { boost::mutex::scoped_lock lock(updatingPortsLock); - transport_list::iterator iter = _findTransportEntry(connectionId); - if (iter != _transports.end()) { - _transportDisconnected(iter->first, iter->second); - } + transport_list::iterator transport = _findTransportEntry(connectionId); + if (transport != _transports.end()) { + _disconnectTransport(*transport); - //LOG_DEBUG( logger, "DISCONNECT, PORT/CONNECTION: " << name << "/" << connectionId ); - delete iter->second; - _transports.erase(iter); + //LOG_DEBUG( logger, "DISCONNECT, PORT/CONNECTION: " << name << "/" << connectionId ); + delete (*transport); + _transports.erase(transport); + } if (_transports.empty()) { active = false; @@ -90,9 +96,9 @@ namespace redhawk { ExtendedCF::UsesConnectionSequence_var retVal = new ExtendedCF::UsesConnectionSequence(); for (transport_list::iterator port = _transports.begin(); port != _transports.end(); ++port) { ExtendedCF::UsesConnection conn; - conn.connectionId = port->first.c_str(); - if (port->second->isAlive()) { - conn.port = CORBA::Object::_duplicate(port->second->objref()); + conn.connectionId = (*port)->connectionId().c_str(); + if ((*port)->isAlive()) { + conn.port = CORBA::Object::_duplicate((*port)->objref()); } else { conn.port = CORBA::Object::_nil(); } @@ -123,24 +129,24 @@ namespace redhawk { { transport_list::iterator entry = _transports.begin(); for (; entry != _transports.end(); ++entry) { - if (entry->first == connectionId) { + if ((*entry)->connectionId() == connectionId) { return entry; } } return entry; } - void UsesPort::_addTransportEntry(const std::string& connectionId, BasicTransport* transport) + void UsesPort::_addTransportEntry(BasicTransport* transport) { - _transports.push_back(transport_entry(connectionId, transport)); + _transports.push_back(transport); } BasicTransport* UsesPort::_createTransport(CORBA::Object_ptr object, const std::string& connectionId) { - return new BasicTransport(object); + return new BasicTransport(connectionId, object); } - void UsesPort::_transportDisconnected(const std::string& connectionId, BasicTransport* transport) + void UsesPort::_disconnectTransport(BasicTransport* transport) { } } diff --git a/redhawk/src/base/include/ossie/MessageInterface.h b/redhawk/src/base/include/ossie/MessageInterface.h index c132a46e6..95c5da33b 100644 --- a/redhawk/src/base/include/ossie/MessageInterface.h +++ b/redhawk/src/base/include/ossie/MessageInterface.h @@ -308,7 +308,7 @@ class MessageSupplierPort : public redhawk::UsesPort protected: virtual void _validatePort(CORBA::Object_ptr object); virtual redhawk::BasicTransport* _createTransport(CORBA::Object_ptr object, const std::string& connectionId); - virtual void _transportDisconnected(redhawk::BasicTransport* transport); + virtual void _disconnectTransport(redhawk::BasicTransport* transport); template inline void _queueMessage(const Message& message) diff --git a/redhawk/src/base/include/ossie/UsesPort.h b/redhawk/src/base/include/ossie/UsesPort.h index fb5d8f3f3..dadfe337f 100644 --- a/redhawk/src/base/include/ossie/UsesPort.h +++ b/redhawk/src/base/include/ossie/UsesPort.h @@ -16,15 +16,17 @@ namespace redhawk { class BasicTransport { public: - BasicTransport(CORBA::Object_ptr objref); + BasicTransport(const std::string& connectionId, CORBA::Object_ptr objref); virtual ~BasicTransport() { } + const std::string& connectionId() const; + CORBA::Object_ptr objref() const; + bool isAlive() const; void setAlive(bool alive); - CORBA::Object_ptr objref() const; - private: + const std::string _connectionId; CORBA::Object_var _objref; bool _alive; }; @@ -86,16 +88,15 @@ namespace redhawk { virtual ExtendedCF::UsesConnectionSequence* connections(); protected: - typedef std::pair transport_entry; - typedef std::vector transport_list; + typedef std::vector transport_list; virtual void _validatePort(CORBA::Object_ptr object); transport_list::iterator _findTransportEntry(const std::string& connectionId); - void _addTransportEntry(const std::string& connectionId, BasicTransport* transport); + void _addTransportEntry(BasicTransport* transport); virtual BasicTransport* _createTransport(CORBA::Object_ptr object, const std::string& connectionId); - virtual void _transportDisconnected(const std::string& connectionId, BasicTransport* transport); + virtual void _disconnectTransport(BasicTransport* transport); transport_list _transports; From 3cbf61390c3eddda79e29cc745b73a634ba7172b Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 18 Nov 2016 11:29:39 -0500 Subject: [PATCH 0542/1644] Use typedef name that is more consistent with rest of code --- bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp | 10 +++++----- redhawk/src/base/framework/MessageInterface.cpp | 8 ++++---- redhawk/src/base/framework/UsesPort.cpp | 10 +++++----- redhawk/src/base/include/ossie/UsesPort.h | 6 +++--- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp index 9f45e0480..920347c21 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp @@ -122,7 +122,7 @@ namespace bulkio { } if (active) { - for (transport_list::iterator iter = _transports.begin(); iter != _transports.end(); ++iter) { + for (TransportList::iterator iter = _transports.begin(); iter != _transports.end(); ++iter) { PortTransportType* port = static_cast(*iter); const std::string& connection_id = port->connectionId(); // Skip ports known to be dead @@ -211,7 +211,7 @@ namespace bulkio { } if (active) { - for (transport_list::iterator iter = _transports.begin(); iter != _transports.end(); ++iter) { + for (TransportList::iterator iter = _transports.begin(); iter != _transports.end(); ++iter) { PortTransportType* port = static_cast(*iter); const std::string& connection_id = port->connectionId(); @@ -254,7 +254,7 @@ namespace bulkio { { SCOPED_LOCK lock(updatingPortsLock); BULKIO::UsesPortStatisticsSequence_var recStat = new BULKIO::UsesPortStatisticsSequence(); - for (transport_list::iterator iter = _transports.begin(); iter != _transports.end(); ++iter) { + for (TransportList::iterator iter = _transports.begin(); iter != _transports.end(); ++iter) { PortTransportType* port = static_cast(*iter); BULKIO::UsesPortStatistics stat; stat.connectionId = port->connectionId().c_str(); @@ -279,7 +279,7 @@ namespace bulkio { void OutPortBase< PortTraits >::enableStats(bool enable) { SCOPED_LOCK lock(updatingPortsLock); - for (transport_list::iterator iter = _transports.begin(); iter != _transports.end(); ++iter) { + for (TransportList::iterator iter = _transports.begin(); iter != _transports.end(); ++iter) { PortTransportType* port = static_cast(*iter); port->stats.setEnabled(enable); } @@ -388,7 +388,7 @@ namespace bulkio { SCOPED_LOCK lock(updatingPortsLock); // restrict access till method completes ConnectionsList outConnections; - for (transport_list::iterator iter = _transports.begin(); iter != _transports.end(); ++iter) { + for (TransportList::iterator iter = _transports.begin(); iter != _transports.end(); ++iter) { PortTransportType* port = static_cast(*iter); outConnections.push_back(std::make_pair(port->objref(), port->connectionId())); } diff --git a/redhawk/src/base/framework/MessageInterface.cpp b/redhawk/src/base/framework/MessageInterface.cpp index 07a95f5cb..6173cb987 100644 --- a/redhawk/src/base/framework/MessageInterface.cpp +++ b/redhawk/src/base/framework/MessageInterface.cpp @@ -450,7 +450,7 @@ void MessageSupplierPort::_disconnectTransport(redhawk::BasicTransport* transpor void MessageSupplierPort::push(const CORBA::Any& data) { boost::mutex::scoped_lock lock(updatingPortsLock); - for (transport_list::iterator iter = _transports.begin(); iter != _transports.end(); ++iter) { + for (TransportList::iterator iter = _transports.begin(); iter != _transports.end(); ++iter) { MessageTransport* transport = static_cast(*iter); try { transport->push(data); @@ -466,7 +466,7 @@ std::string MessageSupplierPort::getRepid() const void MessageSupplierPort::_beginMessageQueue(size_t count) { - for (transport_list::iterator iter = _transports.begin(); iter != _transports.end(); ++iter) { + for (TransportList::iterator iter = _transports.begin(); iter != _transports.end(); ++iter) { MessageTransport* transport = static_cast(*iter); transport->beginQueue(count); } @@ -474,7 +474,7 @@ void MessageSupplierPort::_beginMessageQueue(size_t count) void MessageSupplierPort::_queueMessage(const std::string& msgId, const char* format, const void* msgData, SerializerFunc serializer) { - for (transport_list::iterator iter = _transports.begin(); iter != _transports.end(); ++iter) { + for (TransportList::iterator iter = _transports.begin(); iter != _transports.end(); ++iter) { MessageTransport* transport = static_cast(*iter); try { transport->queueMessage(msgId, format, msgData, serializer); @@ -485,7 +485,7 @@ void MessageSupplierPort::_queueMessage(const std::string& msgId, const char* fo void MessageSupplierPort::_sendMessageQueue() { - for (transport_list::iterator iter = _transports.begin(); iter != _transports.end(); ++iter) { + for (TransportList::iterator iter = _transports.begin(); iter != _transports.end(); ++iter) { MessageTransport* transport = static_cast(*iter); transport->sendMessages(); } diff --git a/redhawk/src/base/framework/UsesPort.cpp b/redhawk/src/base/framework/UsesPort.cpp index c43d476b8..9cf552465 100644 --- a/redhawk/src/base/framework/UsesPort.cpp +++ b/redhawk/src/base/framework/UsesPort.cpp @@ -52,7 +52,7 @@ namespace redhawk { // Acquire the state lock before modifying the container boost::mutex::scoped_lock lock(updatingPortsLock); - transport_list::iterator entry = _findTransportEntry(connection_id); + TransportList::iterator entry = _findTransportEntry(connection_id); if (entry == _transports.end()) { BasicTransport* transport = _createTransport(connection, connection_id); _addTransportEntry(transport); @@ -72,7 +72,7 @@ namespace redhawk { { boost::mutex::scoped_lock lock(updatingPortsLock); - transport_list::iterator transport = _findTransportEntry(connectionId); + TransportList::iterator transport = _findTransportEntry(connectionId); if (transport != _transports.end()) { _disconnectTransport(*transport); @@ -94,7 +94,7 @@ namespace redhawk { { boost::mutex::scoped_lock lock(updatingPortsLock); // don't want to process while command information is coming in ExtendedCF::UsesConnectionSequence_var retVal = new ExtendedCF::UsesConnectionSequence(); - for (transport_list::iterator port = _transports.begin(); port != _transports.end(); ++port) { + for (TransportList::iterator port = _transports.begin(); port != _transports.end(); ++port) { ExtendedCF::UsesConnection conn; conn.connectionId = (*port)->connectionId().c_str(); if ((*port)->isAlive()) { @@ -125,9 +125,9 @@ namespace redhawk { } } - UsesPort::transport_list::iterator UsesPort::_findTransportEntry(const std::string& connectionId) + UsesPort::TransportList::iterator UsesPort::_findTransportEntry(const std::string& connectionId) { - transport_list::iterator entry = _transports.begin(); + TransportList::iterator entry = _transports.begin(); for (; entry != _transports.end(); ++entry) { if ((*entry)->connectionId() == connectionId) { return entry; diff --git a/redhawk/src/base/include/ossie/UsesPort.h b/redhawk/src/base/include/ossie/UsesPort.h index dadfe337f..c79f7ff4a 100644 --- a/redhawk/src/base/include/ossie/UsesPort.h +++ b/redhawk/src/base/include/ossie/UsesPort.h @@ -88,17 +88,17 @@ namespace redhawk { virtual ExtendedCF::UsesConnectionSequence* connections(); protected: - typedef std::vector transport_list; + typedef std::vector TransportList; virtual void _validatePort(CORBA::Object_ptr object); - transport_list::iterator _findTransportEntry(const std::string& connectionId); + TransportList::iterator _findTransportEntry(const std::string& connectionId); void _addTransportEntry(BasicTransport* transport); virtual BasicTransport* _createTransport(CORBA::Object_ptr object, const std::string& connectionId); virtual void _disconnectTransport(BasicTransport* transport); - transport_list _transports; + TransportList _transports; private: ossie::notification _portConnected; From c496b6d47779657ca53c953a5274d0891c5463d8 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 18 Nov 2016 12:28:43 -0500 Subject: [PATCH 0543/1644] Convert BurstIO output ports to use base UsesPort class --- .../src/cpp/include/burstio/OutPortDecl.h | 22 +++++------ burstioInterfaces/src/cpp/lib/OutPortImpl.h | 38 ++++++++++--------- 2 files changed, 29 insertions(+), 31 deletions(-) diff --git a/burstioInterfaces/src/cpp/include/burstio/OutPortDecl.h b/burstioInterfaces/src/cpp/include/burstio/OutPortDecl.h index 7d166239c..875d87b96 100644 --- a/burstioInterfaces/src/cpp/include/burstio/OutPortDecl.h +++ b/burstioInterfaces/src/cpp/include/burstio/OutPortDecl.h @@ -30,8 +30,8 @@ #include #include +#include -#include "UsesPort.h" #include "BurstStatistics.h" #include "PortTraits.h" #include "utils.h" @@ -57,16 +57,17 @@ namespace burstio { }; template - class BurstTransport : public BasicTransport + class BurstTransport : public redhawk::BasicTransport { public: - typedef BasicTransport super; typedef typename Traits::PortType PortType; + typedef typename PortType::_var_type VarType; typedef typename Traits::BurstSequenceType BurstSequenceType; typedef typename Traits::ElementType ElementType; BurstTransport(typename PortType::_ptr_type port, const std::string& connectionId, const std::string& name) : - super(port, connectionId), + redhawk::BasicTransport(connectionId, port), + port_(PortType::_duplicate(port)), stats_(name, sizeof(ElementType) * 8) { } @@ -83,17 +84,16 @@ namespace burstio { virtual bool modifiesBursts () const = 0; protected: + VarType port_; SenderStatistics stats_; }; template - class OutPort : public UsesPort >, - public virtual POA_BULKIO::UsesPortStatisticsProvider + class OutPort : public redhawk::UsesPort, public virtual POA_BULKIO::UsesPortStatisticsProvider { ENABLE_INSTANCE_LOGGING; public: - typedef UsesPort > super; typedef typename Traits::PortType PortType; typedef typename Traits::BurstType BurstType; typedef typename Traits::BurstSequenceType BurstSequenceType; @@ -265,8 +265,7 @@ namespace burstio { friend class Queue; - typedef typename super::ConnectionMap ConnectionMap; - typedef typename super::transport_type TransportType; + typedef BurstTransport TransportType; typedef std::map QueueMap; @@ -281,7 +280,7 @@ namespace burstio { void queueBurst (SequenceType& data, const BURSTIO::BurstSRI& sri, const BULKIO::PrecisionUTCTime& timestamp, bool eos, bool isComplex); - virtual TransportType* _createConnection(typename PortType::_ptr_type port, const std::string& connectionId); + virtual redhawk::BasicTransport* _createTransport(const std::string& connectionId, CORBA::Object_ptr object); const Queue& getQueueForStream (const std::string& streamID) const; Queue& getQueueForStream (const std::string& streamID); @@ -296,9 +295,6 @@ namespace burstio { RouteTable routes_; redhawk::ExecutorService monitor_; - - using super::updatingPortsLock; - using super::connections_; }; typedef OutPort BurstByteOut; diff --git a/burstioInterfaces/src/cpp/lib/OutPortImpl.h b/burstioInterfaces/src/cpp/lib/OutPortImpl.h index bb875d030..2d546be20 100644 --- a/burstioInterfaces/src/cpp/lib/OutPortImpl.h +++ b/burstioInterfaces/src/cpp/lib/OutPortImpl.h @@ -60,16 +60,16 @@ namespace burstio { if (bursts.length() > 1) { partitionBursts(bursts, startTime, queueDepth); } else { - RH_ERROR(parent_->__logger, "pushBursts to " << this->connectionId_ << " failed because the burst size is too long"); + RH_ERROR(parent_->__logger, "pushBursts to " << this->connectionId() << " failed because the burst size is too long"); } } catch (const CORBA::Exception& ex) { if (alive_) { - RH_ERROR(parent_->__logger, "pushBursts to " << this->connectionId_ << " failed: CORBA::" << ex._name()); + RH_ERROR(parent_->__logger, "pushBursts to " << this->connectionId() << " failed: CORBA::" << ex._name()); } alive_ = false; } catch (...) { if (alive_) { - RH_ERROR(parent_->__logger, "pushBursts to " << this->connectionId_ << " failed"); + RH_ERROR(parent_->__logger, "pushBursts to " << this->connectionId() << " failed"); } alive_ = false; } @@ -149,9 +149,9 @@ namespace burstio { this->stats_.record(total_bursts, total_elements, queueDepth, delay.total_microseconds() * 1e-6); } catch (const CORBA::Exception& ex) { - RH_ERROR(parent_->__logger, "pushBursts to " << this->connectionId_ << " failed: CORBA::" << ex._name()); + RH_ERROR(parent_->__logger, "pushBursts to " << this->connectionId() << " failed: CORBA::" << ex._name()); } catch (...) { - RH_ERROR(parent_->__logger, "pushBursts to " << this->connectionId_ << " failed"); + RH_ERROR(parent_->__logger, "pushBursts to " << this->connectionId() << " failed"); } } @@ -310,7 +310,7 @@ namespace burstio { template OutPort::OutPort(std::string port_name) : - super(port_name), + UsesPort(port_name), __logger(__classlogger), defaultQueue_(this, "(default)", DEFAULT_MAX_BURSTS, omniORB::giopMaxMsgSize() * 0.9, DEFAULT_LATENCY_THRESHOLD), streamQueues_(), @@ -459,7 +459,7 @@ namespace burstio { BULKIO::PortUsageType OutPort::state () { boost::mutex::scoped_lock lock(updatingPortsLock); - if (connections_.empty()) { + if (_transports.empty()) { return BULKIO::IDLE; } else { return BULKIO::ACTIVE; @@ -497,11 +497,10 @@ namespace burstio { LOG_INSTANCE_TRACE("Sending " << bursts.length() << " bursts"); std::vector deferred_ports; boost::mutex::scoped_lock lock(updatingPortsLock); - for (typename ConnectionMap::iterator ii = connections_.begin(); ii != connections_.end(); ++ii) { - const std::string& connectionId = ii->first; - TransportType* connection = ii->second; + for (TransportList::iterator ii = _transports.begin(); ii != _transports.end(); ++ii) { + TransportType* connection = static_cast(*ii); - if (!isStreamRoutedToConnection(streamID, connectionId)) { + if (!isStreamRoutedToConnection(streamID, connection->connectionId())) { continue; } @@ -554,14 +553,15 @@ namespace burstio { { boost::mutex::scoped_lock lock(updatingPortsLock); BULKIO::UsesPortStatisticsSequence_var retval = new BULKIO::UsesPortStatisticsSequence(); - retval->length(connections_.size()); + retval->length(_transports.size()); CORBA::ULong index = 0; - for (typename ConnectionMap::iterator ii = connections_.begin(); ii != connections_.end(); ++ii, ++index) { - retval[index].connectionId = ii->first.c_str(); - BULKIO::PortStatistics_var stats = ii->second->getStatistics(); + for (TransportList::iterator ii = _transports.begin(); ii != _transports.end(); ++ii, ++index) { + TransportType* transport = static_cast(*ii); + retval[index].connectionId = transport->connectionId().c_str(); + BULKIO::PortStatistics_var stats = transport->getStatistics(); for (typename QueueMap::iterator jj = streamQueues_.begin(); jj != streamQueues_.end(); ++jj) { const std::string& streamID = jj->first; - if (isStreamRoutedToConnection(streamID, ii->first)) { + if (isStreamRoutedToConnection(streamID, transport->connectionId())) { burstio::utils::push_back(stats->streamIDs, jj->first.c_str()); } } @@ -586,9 +586,11 @@ namespace burstio { } template - typename OutPort::TransportType* OutPort::_createConnection (typename PortType::_ptr_type port, - const std::string& connectionId) + redhawk::BasicTransport* OutPort::_createTransport (const std::string& connectionId, + CORBA::Object_ptr object) { + typedef typename PortType::_var_type var_type; + var_type port = ossie::corba::_narrowSafe(object); InPort* local_port = ossie::corba::getLocalServant >(port); if (local_port) { LOG_INSTANCE_DEBUG("Using local connection to port " << local_port->getName() From 9ef50e90b3f8157bc94e702e8ee6d2633e090e2d Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 18 Nov 2016 12:37:08 -0500 Subject: [PATCH 0544/1644] Throw an exception in C++ uses port base class when disconnecting an invalid connection ID --- redhawk/src/base/framework/UsesPort.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/redhawk/src/base/framework/UsesPort.cpp b/redhawk/src/base/framework/UsesPort.cpp index 9cf552465..259002f51 100644 --- a/redhawk/src/base/framework/UsesPort.cpp +++ b/redhawk/src/base/framework/UsesPort.cpp @@ -73,14 +73,17 @@ namespace redhawk { boost::mutex::scoped_lock lock(updatingPortsLock); TransportList::iterator transport = _findTransportEntry(connectionId); - if (transport != _transports.end()) { - _disconnectTransport(*transport); - - //LOG_DEBUG( logger, "DISCONNECT, PORT/CONNECTION: " << name << "/" << connectionId ); - delete (*transport); - _transports.erase(transport); + if (transport == _transports.end()) { + std::string message = std::string("No connection ") + connectionId; + throw CF::Port::InvalidPort(2, message.c_str()); } + _disconnectTransport(*transport); + + //LOG_DEBUG( logger, "DISCONNECT, PORT/CONNECTION: " << name << "/" << connectionId ); + delete (*transport); + _transports.erase(transport); + if (_transports.empty()) { active = false; } From d3031e35d4a7b841267b6138d69d785ac670f93b Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 18 Nov 2016 13:21:28 -0500 Subject: [PATCH 0545/1644] Move per-instance C++ logger into base UsesPort class --- .../libsrc/cpp/bulkio_out_port.cpp | 16 ++----- bulkioInterfaces/libsrc/cpp/bulkio_out_port.h | 5 +- .../src/cpp/include/burstio/OutPortDecl.h | 6 +-- burstioInterfaces/src/cpp/lib/OutPortImpl.h | 48 ++++++++----------- redhawk/src/base/framework/UsesPort.cpp | 7 ++- redhawk/src/base/include/ossie/UsesPort.h | 5 ++ 6 files changed, 37 insertions(+), 50 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp index 920347c21..8b7489fb9 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp @@ -44,14 +44,13 @@ namespace bulkio { LOGGER_PTR logger, ConnectionEventListener *connectCB, ConnectionEventListener *disconnectCB ) : - redhawk::UsesPort(port_name), - logger(logger) + redhawk::UsesPort(port_name) { if ( !logger ) { std::string pname("redhawk.bulkio.outport."); pname = pname + port_name; - logger = rh_logger::Logger::getLogger(pname); + setLogger(rh_logger::Logger::getLogger(pname)); } if ( connectCB ) { @@ -73,13 +72,12 @@ namespace bulkio { OutPortBase< PortTraits >::OutPortBase(std::string port_name, ConnectionEventListener *connectCB, ConnectionEventListener *disconnectCB ) : - UsesPort(port_name), - logger() + UsesPort(port_name) { std::string pname("redhawk.bulkio.outport."); pname = pname + port_name; - logger = rh_logger::Logger::getLogger(pname); + setLogger(rh_logger::Logger::getLogger(pname)); if ( connectCB ) { _connectCB = boost::shared_ptr< ConnectionEventListener >( connectCB, null_deleter() ); } @@ -421,12 +419,6 @@ namespace bulkio { _disconnectCB = boost::make_shared< StaticConnectionListener >( newListener ); } - template < typename PortTraits > - void OutPortBase< PortTraits >::setLogger(LOGGER_PTR newLogger) - { - logger = newLogger; - } - template < typename PortTraits > std::string OutPortBase< PortTraits >::getRepid() const { return PortType::_PD_repoId; diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h index 7f5cdaca0..4a1118c6a 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h @@ -254,9 +254,7 @@ namespace bulkio { return getConnections(); } - void setLogger( LOGGER_PTR newLogger ); - - std::string getRepid () const; + std::string getRepid () const; // // List of SRIs sent out by this port @@ -280,7 +278,6 @@ namespace bulkio { virtual PortTransportType* _createLocalConnection(PortPtrType port, LocalPortType* localPort, const std::string& connectionId); - LOGGER_PTR logger; std::vector filterTable; boost::shared_ptr< ConnectionEventListener > _connectCB; boost::shared_ptr< ConnectionEventListener > _disconnectCB; diff --git a/burstioInterfaces/src/cpp/include/burstio/OutPortDecl.h b/burstioInterfaces/src/cpp/include/burstio/OutPortDecl.h index 875d87b96..981980007 100644 --- a/burstioInterfaces/src/cpp/include/burstio/OutPortDecl.h +++ b/burstioInterfaces/src/cpp/include/burstio/OutPortDecl.h @@ -91,8 +91,6 @@ namespace burstio { template class OutPort : public redhawk::UsesPort, public virtual POA_BULKIO::UsesPortStatisticsProvider { - ENABLE_INSTANCE_LOGGING; - public: typedef typename Traits::PortType PortType; typedef typename Traits::BurstType BurstType; @@ -107,8 +105,6 @@ namespace burstio { OutPort(std::string port_name); ~OutPort(); - void setLogger (LoggerPtr logger); - // Sets how streams are routed to connections: // ROUTE_ALL_INTERLEAVED - All connections receive all streams; // streams are interleaved in one buffer @@ -245,7 +241,7 @@ namespace burstio { void sendBursts_ (); OutPort* port_; - LoggerPtr& __logger; + LoggerPtr& logger; mutable boost::mutex mutex_; diff --git a/burstioInterfaces/src/cpp/lib/OutPortImpl.h b/burstioInterfaces/src/cpp/lib/OutPortImpl.h index 2d546be20..ed216c017 100644 --- a/burstioInterfaces/src/cpp/lib/OutPortImpl.h +++ b/burstioInterfaces/src/cpp/lib/OutPortImpl.h @@ -60,16 +60,16 @@ namespace burstio { if (bursts.length() > 1) { partitionBursts(bursts, startTime, queueDepth); } else { - RH_ERROR(parent_->__logger, "pushBursts to " << this->connectionId() << " failed because the burst size is too long"); + RH_ERROR(parent_->logger, "pushBursts to " << this->connectionId() << " failed because the burst size is too long"); } } catch (const CORBA::Exception& ex) { if (alive_) { - RH_ERROR(parent_->__logger, "pushBursts to " << this->connectionId() << " failed: CORBA::" << ex._name()); + RH_ERROR(parent_->logger, "pushBursts to " << this->connectionId() << " failed: CORBA::" << ex._name()); } alive_ = false; } catch (...) { if (alive_) { - RH_ERROR(parent_->__logger, "pushBursts to " << this->connectionId() << " failed"); + RH_ERROR(parent_->logger, "pushBursts to " << this->connectionId() << " failed"); } alive_ = false; } @@ -149,9 +149,9 @@ namespace burstio { this->stats_.record(total_bursts, total_elements, queueDepth, delay.total_microseconds() * 1e-6); } catch (const CORBA::Exception& ex) { - RH_ERROR(parent_->__logger, "pushBursts to " << this->connectionId() << " failed: CORBA::" << ex._name()); + RH_ERROR(parent_->logger, "pushBursts to " << this->connectionId() << " failed: CORBA::" << ex._name()); } catch (...) { - RH_ERROR(parent_->__logger, "pushBursts to " << this->connectionId() << " failed"); + RH_ERROR(parent_->logger, "pushBursts to " << this->connectionId() << " failed"); } } @@ -163,7 +163,7 @@ namespace burstio { template OutPort::Queue::Queue(OutPort* port, const std::string& streamID, size_t maxBursts, size_t thresholdBytes, long thresholdLatency) : port_(port), - __logger(port->__logger), + logger(port->logger), maxBursts_(maxBursts), thresholdBytes_(thresholdBytes), thresholdLatency_(boost::posix_time::microseconds(thresholdLatency)), @@ -185,7 +185,7 @@ namespace burstio { boost::mutex::scoped_lock lock(mutex_); maxBursts_ = count; if (bursts_.length() >= maxBursts_) { - LOG_INSTANCE_DEBUG("New max bursts " << maxBursts_ << " triggering push"); + RH_DEBUG(logger, "New max bursts " << maxBursts_ << " triggering push"); executeThreadedFlush(); } } @@ -203,7 +203,7 @@ namespace burstio { boost::mutex::scoped_lock lock(mutex_); thresholdBytes_ = bytes; if (bytes_ >= thresholdBytes_) { - LOG_INSTANCE_DEBUG("New byte threshold " << thresholdBytes_ << " triggering push"); + RH_DEBUG(logger, "New byte threshold " << thresholdBytes_ << " triggering push"); executeThreadedFlush(); } } @@ -234,7 +234,7 @@ namespace burstio { // If this is the first burst, mark the time for latency guarantees if (bursts_.length() == 0) { startTime_ = boost::get_system_time(); - LOG_INSTANCE_TRACE("Scheduling latency check on monitor thread after " << thresholdLatency_.total_microseconds() << " usec"); + RH_TRACE(logger, "Scheduling latency check on monitor thread after " << thresholdLatency_.total_microseconds() << " usec"); port_->scheduleCheck(startTime_ + thresholdLatency_); } @@ -248,10 +248,10 @@ namespace burstio { burst.EOS = eos; bytes_ += burst.data.length() * sizeof(ElementType); - LOG_INSTANCE_TRACE("Queue size: " << bursts_.length() << " bursts / " << bytes_ << " bytes"); + RH_TRACE(logger, "Queue size: " << bursts_.length() << " bursts / " << bytes_ << " bytes"); if (shouldFlush()) { - LOG_INSTANCE_DEBUG("Queued burst exceeded threshold, flushing queue"); + RH_DEBUG(logger, "Queued burst exceeded threshold, flushing queue"); sendBursts_(); } } @@ -311,7 +311,6 @@ namespace burstio { template OutPort::OutPort(std::string port_name) : UsesPort(port_name), - __logger(__classlogger), defaultQueue_(this, "(default)", DEFAULT_MAX_BURSTS, omniORB::giopMaxMsgSize() * 0.9, DEFAULT_LATENCY_THRESHOLD), streamQueues_(), routingMode_(ROUTE_ALL_INTERLEAVED) @@ -329,12 +328,6 @@ namespace burstio { } } - template - void OutPort::setLogger (LoggerPtr logger) - { - __logger = logger; - } - template size_t OutPort::getMaxBursts () const { @@ -404,7 +397,7 @@ namespace burstio { template void OutPort::addConnectionFilter (const std::string& streamID, const std::string& connectionID) { - LOG_INSTANCE_DEBUG("Routing stream " << streamID << " to connection " << connectionID); + RH_DEBUG(logger, "Routing stream " << streamID << " to connection " << connectionID); boost::mutex::scoped_lock lock(updatingPortsLock); routes_[streamID].insert(connectionID); } @@ -412,7 +405,7 @@ namespace burstio { template void OutPort::removeConnectionFilter (const std::string& streamID, const std::string& connectionID) { - LOG_INSTANCE_DEBUG("Unrouting stream " << streamID << " from connection " << connectionID); + RH_DEBUG(logger, "Unrouting stream " << streamID << " from connection " << connectionID); boost::mutex::scoped_lock lock(updatingPortsLock); RouteTable::iterator route = routes_.find(streamID); if (route != routes_.end()) { @@ -494,7 +487,7 @@ namespace burstio { template void OutPort::sendBursts(const BurstSequenceType& bursts, boost::system_time startTime, float queueDepth, const std::string& streamID) { - LOG_INSTANCE_TRACE("Sending " << bursts.length() << " bursts"); + RH_TRACE(logger, "Sending " << bursts.length() << " bursts"); std::vector deferred_ports; boost::mutex::scoped_lock lock(updatingPortsLock); for (TransportList::iterator ii = _transports.begin(); ii != _transports.end(); ++ii) { @@ -540,7 +533,7 @@ namespace burstio { queue.queueBurst(data, sri, timestamp, eos, isComplex); if (eos) { if (ROUTE_ALL_INTERLEAVED != routingMode_) { - LOG_INSTANCE_DEBUG("Flushing '" << streamID << " on EOS"); + RH_DEBUG(logger, "Flushing '" << streamID << " on EOS"); queue.flush(); delete streamQueues_[streamID]; } @@ -575,10 +568,10 @@ namespace burstio { { boost::mutex::scoped_lock lock(queueMutex_); if (ROUTE_ALL_INTERLEAVED == routingMode_) { - LOG_INSTANCE_DEBUG("Forcing flush of default queue"); + RH_DEBUG(logger, "Forcing flush of default queue"); defaultQueue_.flush(); } else { - LOG_INSTANCE_DEBUG("Forcing flush of all queues"); + RH_DEBUG(logger, "Forcing flush of all queues"); for (typename QueueMap::iterator queue = streamQueues_.begin(); queue != streamQueues_.end(); ++queue) { queue->second->flush(); } @@ -593,8 +586,8 @@ namespace burstio { var_type port = ossie::corba::_narrowSafe(object); InPort* local_port = ossie::corba::getLocalServant >(port); if (local_port) { - LOG_INSTANCE_DEBUG("Using local connection to port " << local_port->getName() - << " for connection " << connectionId); + RH_DEBUG(logger, "Using local connection to port " << local_port->getName() + << " for connection " << connectionId); return new LocalTransport(this, local_port, port, connectionId); } else { return new RemoteTransport(this, port, connectionId); @@ -643,7 +636,7 @@ namespace burstio { streamQueues_[streamID] = &defaultQueue_; return defaultQueue_; } else { - LOG_INSTANCE_TRACE("Creating new queue for stream " << streamID); + RH_TRACE(logger, "Creating new queue for stream " << streamID); // Propagate the default queue's settings size_t max_bursts = defaultQueue_.getMaxBursts(); size_t byte_threshold = defaultQueue_.getByteThreshold(); @@ -669,7 +662,6 @@ namespace burstio { } #define INSTANTIATE_TEMPLATE(traits, name) \ - PREPARE_CLASS_LOGGING(name); \ template class OutPort; #endif diff --git a/redhawk/src/base/framework/UsesPort.cpp b/redhawk/src/base/framework/UsesPort.cpp index 259002f51..6753558e3 100644 --- a/redhawk/src/base/framework/UsesPort.cpp +++ b/redhawk/src/base/framework/UsesPort.cpp @@ -78,9 +78,9 @@ namespace redhawk { throw CF::Port::InvalidPort(2, message.c_str()); } + RH_DEBUG(logger, "Disconnecting connection '" << connectionId << "'"); _disconnectTransport(*transport); - //LOG_DEBUG( logger, "DISCONNECT, PORT/CONNECTION: " << name << "/" << connectionId ); delete (*transport); _transports.erase(transport); @@ -110,6 +110,11 @@ namespace redhawk { return retVal._retn(); } + void UsesPort::setLogger(LOGGER newLogger) + { + logger = newLogger; + } + void UsesPort::_validatePort(CORBA::Object_ptr object) { const std::string rep_id = getRepid(); diff --git a/redhawk/src/base/include/ossie/UsesPort.h b/redhawk/src/base/include/ossie/UsesPort.h index c79f7ff4a..c93333487 100644 --- a/redhawk/src/base/include/ossie/UsesPort.h +++ b/redhawk/src/base/include/ossie/UsesPort.h @@ -11,6 +11,7 @@ #include "Autocomplete.h" #include "Port_impl.h" #include "callback.h" +#include "debug.h" namespace redhawk { class BasicTransport @@ -87,6 +88,8 @@ namespace redhawk { virtual ExtendedCF::UsesConnectionSequence* connections(); + void setLogger(LOGGER newLogger); + protected: typedef std::vector TransportList; @@ -98,6 +101,8 @@ namespace redhawk { virtual BasicTransport* _createTransport(CORBA::Object_ptr object, const std::string& connectionId); virtual void _disconnectTransport(BasicTransport* transport); + LOGGER logger; + TransportList _transports; private: From 360dfc0453d3abef2068cdfc2f4649ecbf856ace Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 18 Nov 2016 13:36:21 -0500 Subject: [PATCH 0546/1644] Move MessageSupplier into its own source file --- redhawk/src/base/framework/Makefile.am | 1 + .../src/base/framework/MessageInterface.cpp | 270 ---------------- .../src/base/framework/MessageSupplier.cpp | 291 ++++++++++++++++++ redhawk/src/base/include/ossie/Makefile.am | 1 + .../src/base/include/ossie/MessageInterface.h | 76 +---- .../src/base/include/ossie/MessageSupplier.h | 104 +++++++ 6 files changed, 398 insertions(+), 345 deletions(-) create mode 100644 redhawk/src/base/framework/MessageSupplier.cpp create mode 100644 redhawk/src/base/include/ossie/MessageSupplier.h diff --git a/redhawk/src/base/framework/Makefile.am b/redhawk/src/base/framework/Makefile.am index 7c4703e19..8c7ad8f57 100644 --- a/redhawk/src/base/framework/Makefile.am +++ b/redhawk/src/base/framework/Makefile.am @@ -41,6 +41,7 @@ libossiecf_la_SOURCES = AggregateDevice_impl.cpp \ CorbaUtils.cpp \ prop_helpers.cpp \ MessageInterface.cpp \ + MessageSupplier.cpp \ PropertyInterface.cpp \ Service_impl.cpp \ type_traits.cpp \ diff --git a/redhawk/src/base/framework/MessageInterface.cpp b/redhawk/src/base/framework/MessageInterface.cpp index 6173cb987..020dabb9e 100644 --- a/redhawk/src/base/framework/MessageInterface.cpp +++ b/redhawk/src/base/framework/MessageInterface.cpp @@ -220,273 +220,3 @@ std::string MessageConsumerPort::getDirection() const { return CF::PortSet::DIRECTION_BIDIR; } - - -class MessageSupplierPort::MessageTransport : public redhawk::BasicTransport -{ -public: - MessageTransport(const std::string& connectionId, CosEventChannelAdmin::EventChannel_ptr channel) : - redhawk::BasicTransport(connectionId, channel), - _channel(CosEventChannelAdmin::EventChannel::_duplicate(channel)) - { - } - - virtual ~MessageTransport() - { - } - - virtual void push(const CORBA::Any& data) = 0; - - virtual void beginQueue(size_t count) = 0; - virtual void queueMessage(const std::string& msgId, const char* format, const void* msgData, MessageSupplierPort::SerializerFunc serializer) = 0; - virtual void sendMessages() = 0; - - virtual void disconnect() = 0; - -private: - CosEventChannelAdmin::EventChannel_var _channel; -}; - -class MessageSupplierPort::RemoteTransport : public MessageSupplierPort::MessageTransport -{ -public: - RemoteTransport(const std::string& connectionId, CosEventChannelAdmin::EventChannel_ptr channel) : - MessageTransport(connectionId, channel) - { - CosEventChannelAdmin::SupplierAdmin_var supplier_admin = channel->for_suppliers(); - _consumer = supplier_admin->obtain_push_consumer(); - _consumer->connect_push_supplier(CosEventComm::PushSupplier::_nil()); - } - - void push(const CORBA::Any& data) - { - _consumer->push(data); - } - - void beginQueue(size_t count) - { - // Pre-allocate enough space to hold the entire queue - if (_queue.maximum() < count) { - _queue.replace(count, 0, CF::Properties::allocbuf(count), true); - } else { - _queue.length(0); - } - } - - void queueMessage(const std::string& msgId, const char* /*unused*/, const void* msgData, MessageSupplierPort::SerializerFunc serializer) - { - CORBA::ULong index = _queue.length(); - _queue.length(index+1); - CF::DataType& message = _queue[index]; - message.id = msgId.c_str(); - serializer(message.value, msgData); - } - - void sendMessages() - { - CORBA::Any data; - data <<= _queue; - push(data); - } - - void disconnect() - { - try { - _consumer->disconnect_push_consumer(); - } catch (...) { - // Ignore errors on disconnect - } - } - -private: - CosEventChannelAdmin::ProxyPushConsumer_var _consumer; - CF::Properties _queue; -}; - -class MessageSupplierPort::LocalTransport : public MessageSupplierPort::MessageTransport -{ -public: - LocalTransport(const std::string& connectionId, MessageConsumerPort* consumer, - CosEventChannelAdmin::EventChannel_ptr channel) : - MessageTransport(connectionId, channel), - _consumer(consumer) - { - } - - void push(const CORBA::Any& data) - { - CF::Properties* temp; - if (!(data >>= temp)) { - return; - } - const redhawk::PropertyMap& props = redhawk::PropertyMap::cast(*temp); - for (redhawk::PropertyMap::const_iterator msg = props.begin(); msg != props.end(); ++msg) { - _consumer->fireCallback(msg->getId(), msg->getValue()); - } - } - - void beginQueue(size_t /*unused*/) - { - } - - void queueMessage(const std::string& msgId, const char* format, const void* msgData, MessageSupplierPort::SerializerFunc serializer) - { - CallbackEntry* entry = getCallback(msgId, format); - if (entry) { - // There is a message-specific callback registered; use direct - // dispatch if available, otherwise fall back to CORBA Any - if (entry->direct) { - entry->callback->dispatch(msgId, msgData); - } else { - CORBA::Any data; - serializer(data, msgData); - entry->callback->dispatch(msgId, data); - } - } - - // If the receiver has any generic callbacks registered, serialize the - // message to a CORBA Any (which, technically speaking, may have also - // been done above if the message format differed) and send it along. - // By serializing only when it's required, the best case of direct - // message dispatch runs significantly faster. - if (_consumer->hasGenericCallbacks()) { - CORBA::Any data; - serializer(data, msgData); - _consumer->dispatchGeneric(msgId, data); - } - } - - void sendMessages() - { - } - - void disconnect() - { - } - -private: - struct CallbackEntry { - MessageConsumerPort::MessageCallback* callback; - bool direct; - }; - - typedef std::map CallbackTable; - - CallbackEntry* getCallback(const std::string& msgId, const char* format) - { - CallbackTable::iterator callback = _callbacks.find(msgId); - if (callback != _callbacks.end()) { - // The callback has already been found and negotiated - return &(callback->second); - } - - // No callback has been found yet; ask the consumer for its callback, - // and if it has one, negotiate whether we can use direct dispatch via - // void* - CallbackEntry entry; - entry.callback = _consumer->getMessageCallback(msgId); - if (entry.callback) { - entry.direct = entry.callback->isCompatible(format); - callback = _callbacks.insert(std::make_pair(msgId, entry)).first; - return &(callback->second); - } - - // There is no callback registered for the given message - return 0; - } - - MessageConsumerPort* _consumer; - CallbackTable _callbacks; -}; - -MessageSupplierPort::MessageSupplierPort (std::string port_name) : - UsesPort(port_name) -{ -} - -MessageSupplierPort::~MessageSupplierPort (void) -{ -} - -void MessageSupplierPort::_validatePort(CORBA::Object_ptr object) -{ - const std::string rep_id(CosEventChannelAdmin::EventChannel::_PD_repoId); - bool valid; - try { - valid = object->_is_a(rep_id.c_str()); - } catch (...) { - // If _is_a throws an exception, assume the remote object is - // unreachable (e.g., dead) - throw CF::Port::InvalidPort(1, "Object unreachable"); - } - - if (!valid) { - std::string message = "Object does not support " + rep_id; - throw CF::Port::InvalidPort(1, message.c_str()); - } -} - -redhawk::BasicTransport* MessageSupplierPort::_createTransport(CORBA::Object_ptr object, const std::string& connectionId) -{ - CosEventChannelAdmin::EventChannel_var channel = ossie::corba::_narrowSafe(object); - if (CORBA::is_nil(channel)) { - throw CF::Port::InvalidPort(0, "The object provided did not narrow to a CosEventChannelAdmin::EventChannel type"); - } - - MessageConsumerPort* local_port = ossie::corba::getLocalServant(channel); - if (local_port) { - return new LocalTransport(connectionId, local_port, channel); - } else { - return new RemoteTransport(connectionId, channel); - } -} - -void MessageSupplierPort::_disconnectTransport(redhawk::BasicTransport* transport) -{ - MessageTransport* message_transport = static_cast(transport); - message_transport->disconnect(); -} - -void MessageSupplierPort::push(const CORBA::Any& data) -{ - boost::mutex::scoped_lock lock(updatingPortsLock); - for (TransportList::iterator iter = _transports.begin(); iter != _transports.end(); ++iter) { - MessageTransport* transport = static_cast(*iter); - try { - transport->push(data); - } catch ( ... ) { - } - } -} - -std::string MessageSupplierPort::getRepid() const -{ - return ExtendedEvent::MessageEvent::_PD_repoId; -} - -void MessageSupplierPort::_beginMessageQueue(size_t count) -{ - for (TransportList::iterator iter = _transports.begin(); iter != _transports.end(); ++iter) { - MessageTransport* transport = static_cast(*iter); - transport->beginQueue(count); - } -} - -void MessageSupplierPort::_queueMessage(const std::string& msgId, const char* format, const void* msgData, SerializerFunc serializer) -{ - for (TransportList::iterator iter = _transports.begin(); iter != _transports.end(); ++iter) { - MessageTransport* transport = static_cast(*iter); - try { - transport->queueMessage(msgId, format, msgData, serializer); - } catch ( ... ) { - } - } -} - -void MessageSupplierPort::_sendMessageQueue() -{ - for (TransportList::iterator iter = _transports.begin(); iter != _transports.end(); ++iter) { - MessageTransport* transport = static_cast(*iter); - transport->sendMessages(); - } -} diff --git a/redhawk/src/base/framework/MessageSupplier.cpp b/redhawk/src/base/framework/MessageSupplier.cpp new file mode 100644 index 000000000..2af24aefc --- /dev/null +++ b/redhawk/src/base/framework/MessageSupplier.cpp @@ -0,0 +1,291 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK core. + * + * REDHAWK core is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +#include +#include + +class MessageSupplierPort::MessageTransport : public redhawk::BasicTransport +{ +public: + MessageTransport(const std::string& connectionId, CosEventChannelAdmin::EventChannel_ptr channel) : + redhawk::BasicTransport(connectionId, channel), + _channel(CosEventChannelAdmin::EventChannel::_duplicate(channel)) + { + } + + virtual ~MessageTransport() + { + } + + virtual void push(const CORBA::Any& data) = 0; + + virtual void beginQueue(size_t count) = 0; + virtual void queueMessage(const std::string& msgId, const char* format, const void* msgData, MessageSupplierPort::SerializerFunc serializer) = 0; + virtual void sendMessages() = 0; + + virtual void disconnect() = 0; + +private: + CosEventChannelAdmin::EventChannel_var _channel; +}; + +class MessageSupplierPort::RemoteTransport : public MessageSupplierPort::MessageTransport +{ +public: + RemoteTransport(const std::string& connectionId, CosEventChannelAdmin::EventChannel_ptr channel) : + MessageTransport(connectionId, channel) + { + CosEventChannelAdmin::SupplierAdmin_var supplier_admin = channel->for_suppliers(); + _consumer = supplier_admin->obtain_push_consumer(); + _consumer->connect_push_supplier(CosEventComm::PushSupplier::_nil()); + } + + void push(const CORBA::Any& data) + { + _consumer->push(data); + } + + void beginQueue(size_t count) + { + // Pre-allocate enough space to hold the entire queue + if (_queue.maximum() < count) { + _queue.replace(count, 0, CF::Properties::allocbuf(count), true); + } else { + _queue.length(0); + } + } + + void queueMessage(const std::string& msgId, const char* /*unused*/, const void* msgData, MessageSupplierPort::SerializerFunc serializer) + { + CORBA::ULong index = _queue.length(); + _queue.length(index+1); + CF::DataType& message = _queue[index]; + message.id = msgId.c_str(); + serializer(message.value, msgData); + } + + void sendMessages() + { + CORBA::Any data; + data <<= _queue; + push(data); + } + + void disconnect() + { + try { + _consumer->disconnect_push_consumer(); + } catch (...) { + // Ignore errors on disconnect + } + } + +private: + CosEventChannelAdmin::ProxyPushConsumer_var _consumer; + CF::Properties _queue; +}; + +class MessageSupplierPort::LocalTransport : public MessageSupplierPort::MessageTransport +{ +public: + LocalTransport(const std::string& connectionId, MessageConsumerPort* consumer, + CosEventChannelAdmin::EventChannel_ptr channel) : + MessageTransport(connectionId, channel), + _consumer(consumer) + { + } + + void push(const CORBA::Any& data) + { + CF::Properties* temp; + if (!(data >>= temp)) { + return; + } + const redhawk::PropertyMap& props = redhawk::PropertyMap::cast(*temp); + for (redhawk::PropertyMap::const_iterator msg = props.begin(); msg != props.end(); ++msg) { + _consumer->fireCallback(msg->getId(), msg->getValue()); + } + } + + void beginQueue(size_t /*unused*/) + { + } + + void queueMessage(const std::string& msgId, const char* format, const void* msgData, MessageSupplierPort::SerializerFunc serializer) + { + CallbackEntry* entry = getCallback(msgId, format); + if (entry) { + // There is a message-specific callback registered; use direct + // dispatch if available, otherwise fall back to CORBA Any + if (entry->direct) { + entry->callback->dispatch(msgId, msgData); + } else { + CORBA::Any data; + serializer(data, msgData); + entry->callback->dispatch(msgId, data); + } + } + + // If the receiver has any generic callbacks registered, serialize the + // message to a CORBA Any (which, technically speaking, may have also + // been done above if the message format differed) and send it along. + // By serializing only when it's required, the best case of direct + // message dispatch runs significantly faster. + if (_consumer->hasGenericCallbacks()) { + CORBA::Any data; + serializer(data, msgData); + _consumer->dispatchGeneric(msgId, data); + } + } + + void sendMessages() + { + } + + void disconnect() + { + } + +private: + struct CallbackEntry { + MessageConsumerPort::MessageCallback* callback; + bool direct; + }; + + typedef std::map CallbackTable; + + CallbackEntry* getCallback(const std::string& msgId, const char* format) + { + CallbackTable::iterator callback = _callbacks.find(msgId); + if (callback != _callbacks.end()) { + // The callback has already been found and negotiated + return &(callback->second); + } + + // No callback has been found yet; ask the consumer for its callback, + // and if it has one, negotiate whether we can use direct dispatch via + // void* + CallbackEntry entry; + entry.callback = _consumer->getMessageCallback(msgId); + if (entry.callback) { + entry.direct = entry.callback->isCompatible(format); + callback = _callbacks.insert(std::make_pair(msgId, entry)).first; + return &(callback->second); + } + + // There is no callback registered for the given message + return 0; + } + + MessageConsumerPort* _consumer; + CallbackTable _callbacks; +}; + +MessageSupplierPort::MessageSupplierPort (const std::string& name) : + UsesPort(name) +{ +} + +MessageSupplierPort::~MessageSupplierPort (void) +{ +} + +void MessageSupplierPort::_validatePort(CORBA::Object_ptr object) +{ + const std::string rep_id(CosEventChannelAdmin::EventChannel::_PD_repoId); + bool valid; + try { + valid = object->_is_a(rep_id.c_str()); + } catch (...) { + // If _is_a throws an exception, assume the remote object is + // unreachable (e.g., dead) + throw CF::Port::InvalidPort(1, "Object unreachable"); + } + + if (!valid) { + std::string message = "Object does not support " + rep_id; + throw CF::Port::InvalidPort(1, message.c_str()); + } +} + +redhawk::BasicTransport* MessageSupplierPort::_createTransport(CORBA::Object_ptr object, const std::string& connectionId) +{ + CosEventChannelAdmin::EventChannel_var channel = ossie::corba::_narrowSafe(object); + if (CORBA::is_nil(channel)) { + throw CF::Port::InvalidPort(0, "The object provided did not narrow to a CosEventChannelAdmin::EventChannel type"); + } + + MessageConsumerPort* local_port = ossie::corba::getLocalServant(channel); + if (local_port) { + return new LocalTransport(connectionId, local_port, channel); + } else { + return new RemoteTransport(connectionId, channel); + } +} + +void MessageSupplierPort::_disconnectTransport(redhawk::BasicTransport* transport) +{ + MessageTransport* message_transport = static_cast(transport); + message_transport->disconnect(); +} + +void MessageSupplierPort::push(const CORBA::Any& data) +{ + boost::mutex::scoped_lock lock(updatingPortsLock); + for (TransportList::iterator iter = _transports.begin(); iter != _transports.end(); ++iter) { + MessageTransport* transport = static_cast(*iter); + try { + transport->push(data); + } catch ( ... ) { + } + } +} + +std::string MessageSupplierPort::getRepid() const +{ + return ExtendedEvent::MessageEvent::_PD_repoId; +} + +void MessageSupplierPort::_beginMessageQueue(size_t count) +{ + for (TransportList::iterator iter = _transports.begin(); iter != _transports.end(); ++iter) { + MessageTransport* transport = static_cast(*iter); + transport->beginQueue(count); + } +} + +void MessageSupplierPort::_queueMessage(const std::string& msgId, const char* format, const void* msgData, SerializerFunc serializer) +{ + for (TransportList::iterator iter = _transports.begin(); iter != _transports.end(); ++iter) { + MessageTransport* transport = static_cast(*iter); + try { + transport->queueMessage(msgId, format, msgData, serializer); + } catch ( ... ) { + } + } +} + +void MessageSupplierPort::_sendMessageQueue() +{ + for (TransportList::iterator iter = _transports.begin(); iter != _transports.end(); ++iter) { + MessageTransport* transport = static_cast(*iter); + transport->sendMessages(); + } +} diff --git a/redhawk/src/base/include/ossie/Makefile.am b/redhawk/src/base/include/ossie/Makefile.am index 06deb89df..e88da5b93 100644 --- a/redhawk/src/base/include/ossie/Makefile.am +++ b/redhawk/src/base/include/ossie/Makefile.am @@ -44,6 +44,7 @@ pkginclude_HEADERS = AggregateDevice_impl.h \ ComplexProperties.h \ Service_impl.h \ MessageInterface.h \ + MessageSupplier.h \ type_traits.h \ AnyUtils.h \ RedhawkDefs.h \ diff --git a/redhawk/src/base/include/ossie/MessageInterface.h b/redhawk/src/base/include/ossie/MessageInterface.h index 95c5da33b..8d1e0f8ad 100644 --- a/redhawk/src/base/include/ossie/MessageInterface.h +++ b/redhawk/src/base/include/ossie/MessageInterface.h @@ -37,8 +37,6 @@ #include - - /************************************************************************************ Message consumer ************************************************************************************/ @@ -263,78 +261,6 @@ class MessageConsumerPort : public Port_Provides_base_impl SupplierTable suppliers_; }; - -/************************************************************************************ - Message producer -************************************************************************************/ -#include "UsesPort.h" -class MessageSupplierPort : public redhawk::UsesPort -{ - -public: - MessageSupplierPort (std::string port_name); - virtual ~MessageSupplierPort (void); - - void push(const CORBA::Any& data); - - // Send a single message - template - void sendMessage(const Message& message) { - const Message* begin(&message); - const Message* end(&begin[1]); - sendMessages(begin, end); - } - - // Send a sequence of messages - template - void sendMessages(const Sequence& messages) { - sendMessages(messages.begin(), messages.end()); - } - - // Send a set of messages from an iterable set - template - void sendMessages(Iterator first, Iterator last) - { - boost::mutex::scoped_lock lock(updatingPortsLock); - _beginMessageQueue(std::distance(first, last)); - for (; first != last; ++first) { - _queueMessage(*first); - } - _sendMessageQueue(); - } - - std::string getRepid() const; - -protected: - virtual void _validatePort(CORBA::Object_ptr object); - virtual redhawk::BasicTransport* _createTransport(CORBA::Object_ptr object, const std::string& connectionId); - virtual void _disconnectTransport(redhawk::BasicTransport* transport); - - template - inline void _queueMessage(const Message& message) - { - // Workaround for older components whose structs have a non-const, - // non-static member function getId(): const_cast the value - const std::string messageId = const_cast(message).getId(); - const char* format = ::internal::message_traits::format(); - _queueMessage(messageId, format, &message, &MessageSupplierPort::_serializeMessage); - } - - template - static void _serializeMessage(CORBA::Any& any, const void* data) - { - any <<= *(reinterpret_cast(data)); - } - - typedef boost::function SerializerFunc; - - void _beginMessageQueue(size_t count); - void _queueMessage(const std::string& msgId, const char* format, const void* msgData, SerializerFunc serializer); - void _sendMessageQueue(); - - class MessageTransport; - class RemoteTransport; - class LocalTransport; -}; +#include "MessageSupplier.h" #endif // MESSAGEINTERFACE_H diff --git a/redhawk/src/base/include/ossie/MessageSupplier.h b/redhawk/src/base/include/ossie/MessageSupplier.h new file mode 100644 index 000000000..1b4a250d0 --- /dev/null +++ b/redhawk/src/base/include/ossie/MessageSupplier.h @@ -0,0 +1,104 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK core. + * + * REDHAWK core is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +#ifndef MESSAGESUPPLIER_H +#define MESSAGESUPPLIER_H + +#include + +#include + +#include + +#include "UsesPort.h" + +/************************************************************************************ + Message producer +************************************************************************************/ +class MessageSupplierPort : public redhawk::UsesPort +{ + +public: + MessageSupplierPort (const std::string& name); + virtual ~MessageSupplierPort (void); + + void push(const CORBA::Any& data); + + // Send a single message + template + void sendMessage(const Message& message) { + const Message* begin(&message); + const Message* end(&begin[1]); + sendMessages(begin, end); + } + + // Send a sequence of messages + template + void sendMessages(const Sequence& messages) { + sendMessages(messages.begin(), messages.end()); + } + + // Send a set of messages from an iterable set + template + void sendMessages(Iterator first, Iterator last) + { + boost::mutex::scoped_lock lock(updatingPortsLock); + _beginMessageQueue(std::distance(first, last)); + for (; first != last; ++first) { + _queueMessage(*first); + } + _sendMessageQueue(); + } + + std::string getRepid() const; + +protected: + virtual void _validatePort(CORBA::Object_ptr object); + virtual redhawk::BasicTransport* _createTransport(CORBA::Object_ptr object, const std::string& connectionId); + virtual void _disconnectTransport(redhawk::BasicTransport* transport); + + template + inline void _queueMessage(const Message& message) + { + // Workaround for older components whose structs have a non-const, + // non-static member function getId(): const_cast the value + const std::string messageId = const_cast(message).getId(); + const char* format = ::internal::message_traits::format(); + _queueMessage(messageId, format, &message, &MessageSupplierPort::_serializeMessage); + } + + template + static void _serializeMessage(CORBA::Any& any, const void* data) + { + any <<= *(reinterpret_cast(data)); + } + + typedef boost::function SerializerFunc; + + void _beginMessageQueue(size_t count); + void _queueMessage(const std::string& msgId, const char* format, const void* msgData, SerializerFunc serializer); + void _sendMessageQueue(); + + class MessageTransport; + class RemoteTransport; + class LocalTransport; +}; + +#endif // MESSAGESUPPLIER_H From c4996eb4ff1afedb6aac0f342107a807811fdda1 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 18 Nov 2016 13:47:04 -0500 Subject: [PATCH 0547/1644] Move disconnect() up into BasicTransport --- redhawk/src/base/framework/MessageSupplier.cpp | 12 ------------ redhawk/src/base/framework/UsesPort.cpp | 1 + redhawk/src/base/include/ossie/MessageSupplier.h | 1 - redhawk/src/base/include/ossie/UsesPort.h | 2 ++ 4 files changed, 3 insertions(+), 13 deletions(-) diff --git a/redhawk/src/base/framework/MessageSupplier.cpp b/redhawk/src/base/framework/MessageSupplier.cpp index 2af24aefc..be5de1468 100644 --- a/redhawk/src/base/framework/MessageSupplier.cpp +++ b/redhawk/src/base/framework/MessageSupplier.cpp @@ -40,8 +40,6 @@ class MessageSupplierPort::MessageTransport : public redhawk::BasicTransport virtual void queueMessage(const std::string& msgId, const char* format, const void* msgData, MessageSupplierPort::SerializerFunc serializer) = 0; virtual void sendMessages() = 0; - virtual void disconnect() = 0; - private: CosEventChannelAdmin::EventChannel_var _channel; }; @@ -159,10 +157,6 @@ class MessageSupplierPort::LocalTransport : public MessageSupplierPort::MessageT { } - void disconnect() - { - } - private: struct CallbackEntry { MessageConsumerPort::MessageCallback* callback; @@ -240,12 +234,6 @@ redhawk::BasicTransport* MessageSupplierPort::_createTransport(CORBA::Object_ptr } } -void MessageSupplierPort::_disconnectTransport(redhawk::BasicTransport* transport) -{ - MessageTransport* message_transport = static_cast(transport); - message_transport->disconnect(); -} - void MessageSupplierPort::push(const CORBA::Any& data) { boost::mutex::scoped_lock lock(updatingPortsLock); diff --git a/redhawk/src/base/framework/UsesPort.cpp b/redhawk/src/base/framework/UsesPort.cpp index 6753558e3..ee6effe97 100644 --- a/redhawk/src/base/framework/UsesPort.cpp +++ b/redhawk/src/base/framework/UsesPort.cpp @@ -79,6 +79,7 @@ namespace redhawk { } RH_DEBUG(logger, "Disconnecting connection '" << connectionId << "'"); + (*transport)->disconnect(); _disconnectTransport(*transport); delete (*transport); diff --git a/redhawk/src/base/include/ossie/MessageSupplier.h b/redhawk/src/base/include/ossie/MessageSupplier.h index 1b4a250d0..0ca4d20c6 100644 --- a/redhawk/src/base/include/ossie/MessageSupplier.h +++ b/redhawk/src/base/include/ossie/MessageSupplier.h @@ -72,7 +72,6 @@ class MessageSupplierPort : public redhawk::UsesPort protected: virtual void _validatePort(CORBA::Object_ptr object); virtual redhawk::BasicTransport* _createTransport(CORBA::Object_ptr object, const std::string& connectionId); - virtual void _disconnectTransport(redhawk::BasicTransport* transport); template inline void _queueMessage(const Message& message) diff --git a/redhawk/src/base/include/ossie/UsesPort.h b/redhawk/src/base/include/ossie/UsesPort.h index c93333487..4b6457b8e 100644 --- a/redhawk/src/base/include/ossie/UsesPort.h +++ b/redhawk/src/base/include/ossie/UsesPort.h @@ -26,6 +26,8 @@ namespace redhawk { bool isAlive() const; void setAlive(bool alive); + virtual void disconnect() { } + private: const std::string _connectionId; CORBA::Object_var _objref; From 869e84554bc0505ca94dd8c1ff33f3fa329a04a6 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Sat, 19 Nov 2016 10:13:58 -0500 Subject: [PATCH 0548/1644] Refs CF-884. Allow more control over the working and cache directories for loadable and executable devices --- GPP/GPP.prf.xml | 14 + GPP/build.sh | 10 + GPP/cpp/GPP.cpp | 22 +- GPP/cpp/GPP_base.cpp | 16 ++ GPP/cpp/GPP_base.h | 4 + .../DeviceManager.dcd.xml | 48 ++++ .../DeviceManager.dcd.xml | 48 ++++ .../test_VarCache_node/DeviceManager.dcd.xml | 49 ++++ .../components/check_cwd/check_cwd.prf.xml | 8 + .../components/check_cwd/check_cwd.scd.xml | 45 ++++ .../components/check_cwd/check_cwd.spd.xml | 25 ++ .../components/check_cwd/python/check_cwd.py | 157 +++++++++++ .../check_cwd/python/check_cwd_base.py | 69 +++++ .../check_cwd_cpp/check_cwd_cpp.prf.xml | 8 + .../check_cwd_cpp/check_cwd_cpp.scd.xml | 45 ++++ .../check_cwd_cpp/check_cwd_cpp.spd.xml | 27 ++ .../components/check_cwd_cpp/cpp/Makefile.am | 40 +++ .../dom/components/check_cwd_cpp/cpp/build.sh | 19 ++ .../check_cwd_cpp/cpp/check_cwd_cpp.cpp | 255 ++++++++++++++++++ .../check_cwd_cpp/cpp/check_cwd_cpp.h | 18 ++ .../check_cwd_cpp/cpp/check_cwd_cpp_base.cpp | 66 +++++ .../check_cwd_cpp/cpp/check_cwd_cpp_base.h | 30 +++ .../components/check_cwd_cpp/cpp/configure.ac | 25 ++ .../dom/components/check_cwd_cpp/cpp/main.cpp | 11 + .../dom/components/check_cwd_cpp/cpp/reconf | 6 + .../check_cwd_java/check_cwd_java.prf.xml | 8 + .../check_cwd_java/check_cwd_java.scd.xml | 45 ++++ .../check_cwd_java/check_cwd_java.spd.xml | 26 ++ .../check_cwd_java/java/Makefile.am | 37 +++ .../check_cwd_java/java/check_cwd_java.java | 253 +++++++++++++++++ .../java/check_cwd_java_base.java | 102 +++++++ .../check_cwd_java/java/startJava.sh | 30 +++ .../check_cwd_cpp_w/check_cwd_cpp_w.sad.xml | 23 ++ .../check_cwd_java_w/check_cwd_java_w.sad.xml | 23 ++ .../waveforms/check_cwd_w/check_cwd_w.sad.xml | 23 ++ GPP/tests/test_GPP.py | 207 ++++++++++++-- .../base/framework/ExecutableDevice_impl.cpp | 2 + .../base/framework/LoadableDevice_impl.cpp | 60 +++-- .../base/include/ossie/LoadableDevice_impl.h | 4 +- .../control/sdr/devmgr/DeviceManager_impl.cpp | 226 +++++++++------- .../control/sdr/devmgr/DeviceManager_impl.h | 15 +- 41 files changed, 2016 insertions(+), 133 deletions(-) create mode 100644 GPP/tests/sdr/dev/nodes/test_VarCWDOnly_node/DeviceManager.dcd.xml create mode 100644 GPP/tests/sdr/dev/nodes/test_VarCacheOnly_node/DeviceManager.dcd.xml create mode 100644 GPP/tests/sdr/dev/nodes/test_VarCache_node/DeviceManager.dcd.xml create mode 100644 GPP/tests/sdr/dom/components/check_cwd/check_cwd.prf.xml create mode 100644 GPP/tests/sdr/dom/components/check_cwd/check_cwd.scd.xml create mode 100644 GPP/tests/sdr/dom/components/check_cwd/check_cwd.spd.xml create mode 100755 GPP/tests/sdr/dom/components/check_cwd/python/check_cwd.py create mode 100644 GPP/tests/sdr/dom/components/check_cwd/python/check_cwd_base.py create mode 100644 GPP/tests/sdr/dom/components/check_cwd_cpp/check_cwd_cpp.prf.xml create mode 100644 GPP/tests/sdr/dom/components/check_cwd_cpp/check_cwd_cpp.scd.xml create mode 100644 GPP/tests/sdr/dom/components/check_cwd_cpp/check_cwd_cpp.spd.xml create mode 100644 GPP/tests/sdr/dom/components/check_cwd_cpp/cpp/Makefile.am create mode 100755 GPP/tests/sdr/dom/components/check_cwd_cpp/cpp/build.sh create mode 100644 GPP/tests/sdr/dom/components/check_cwd_cpp/cpp/check_cwd_cpp.cpp create mode 100644 GPP/tests/sdr/dom/components/check_cwd_cpp/cpp/check_cwd_cpp.h create mode 100644 GPP/tests/sdr/dom/components/check_cwd_cpp/cpp/check_cwd_cpp_base.cpp create mode 100644 GPP/tests/sdr/dom/components/check_cwd_cpp/cpp/check_cwd_cpp_base.h create mode 100644 GPP/tests/sdr/dom/components/check_cwd_cpp/cpp/configure.ac create mode 100644 GPP/tests/sdr/dom/components/check_cwd_cpp/cpp/main.cpp create mode 100755 GPP/tests/sdr/dom/components/check_cwd_cpp/cpp/reconf create mode 100644 GPP/tests/sdr/dom/components/check_cwd_java/check_cwd_java.prf.xml create mode 100644 GPP/tests/sdr/dom/components/check_cwd_java/check_cwd_java.scd.xml create mode 100644 GPP/tests/sdr/dom/components/check_cwd_java/check_cwd_java.spd.xml create mode 100644 GPP/tests/sdr/dom/components/check_cwd_java/java/Makefile.am create mode 100644 GPP/tests/sdr/dom/components/check_cwd_java/java/src/check_cwd_java/java/check_cwd_java.java create mode 100644 GPP/tests/sdr/dom/components/check_cwd_java/java/src/check_cwd_java/java/check_cwd_java_base.java create mode 100755 GPP/tests/sdr/dom/components/check_cwd_java/java/startJava.sh create mode 100644 GPP/tests/sdr/dom/waveforms/check_cwd_cpp_w/check_cwd_cpp_w.sad.xml create mode 100644 GPP/tests/sdr/dom/waveforms/check_cwd_java_w/check_cwd_java_w.sad.xml create mode 100644 GPP/tests/sdr/dom/waveforms/check_cwd_w/check_cwd_w.sad.xml diff --git a/GPP/GPP.prf.xml b/GPP/GPP.prf.xml index e7cd2e79a..325410240 100644 --- a/GPP/GPP.prf.xml +++ b/GPP/GPP.prf.xml @@ -346,6 +346,20 @@ THRESHOLD_NOT_EXCEEDED: The measured value no longer exceeds the configured thr + + Select a cache directory other than the default. + + + + + + + Select a working directory other than the default. + + + + + The thresholds that cause a failure for allocations diff --git a/GPP/build.sh b/GPP/build.sh index 97ddf098c..2c86df2d8 100755 --- a/GPP/build.sh +++ b/GPP/build.sh @@ -45,4 +45,14 @@ else cp GPP ../tests/sdr/dev/devices/GPP/cpp/ cd - done + cd tests/sdr/dom/components/check_cwd_cpp/cpp + if [ -e build.sh ]; then + ./build.sh $* + fi + cd - + cd tests/sdr/dom/components/check_cwd_java + if [ -e build.sh ]; then + ./build.sh $* + fi + cd - fi diff --git a/GPP/cpp/GPP.cpp b/GPP/cpp/GPP.cpp index 0e9e443b7..bc1f2b9fe 100644 --- a/GPP/cpp/GPP.cpp +++ b/GPP/cpp/GPP.cpp @@ -470,7 +470,12 @@ void GPP_i::_init() { cpu.subscribed = 0; cpu.maximum = 0; utilization.push_back(cpu); - + + char *cwd = getcwd(NULL, 1024); + if (cwd != NULL) { + free(cwd); + } + setPropertyQueryImpl(this->component_monitor, this, &GPP_i::get_component_monitor); // tie allocation modifier callbacks to identifiers @@ -1121,10 +1126,17 @@ CF::ExecutableDevice::ProcessID_Type GPP_i::do_execute (const char* name, const } // retrieve current working directory - tmp = getcwd(NULL, 200); - if (tmp != NULL) { - path = std::string(tmp); - free(tmp); + if (this->cacheDirectory.empty()) { + tmp = getcwd(NULL, 200); + if (tmp != NULL) { + path = std::string(tmp); + free(tmp); + } + } else { + path = this->cacheDirectory; + if (!path.compare(path.length()-1, 1, "/")) { + path = path.erase(path.length()-1); + } } // append relative path of the executable diff --git a/GPP/cpp/GPP_base.cpp b/GPP/cpp/GPP_base.cpp index abde01d52..7abcda736 100644 --- a/GPP/cpp/GPP_base.cpp +++ b/GPP/cpp/GPP_base.cpp @@ -356,6 +356,22 @@ void GPP_base::loadProperties() "external", "property"); + addProperty(cacheDirectory, + "cacheDirectory", + "", + "readonly", + "", + "external", + "property"); + + addProperty(workingDirectory, + "workingDirectory", + "", + "readonly", + "", + "external", + "property"); + addProperty(thresholds, thresholds_struct(), "thresholds", diff --git a/GPP/cpp/GPP_base.h b/GPP/cpp/GPP_base.h index 5809f2c19..0189bbc53 100644 --- a/GPP/cpp/GPP_base.h +++ b/GPP/cpp/GPP_base.h @@ -80,6 +80,10 @@ class GPP_base : public ExecutableDevice_impl, protected ThreadedComponent thresholds_struct thresholds; /// Property to annotate why the system is busy std::string busy_reason; + /// Property to select a cache directory other than the default + std::string cacheDirectory; + /// Property to select a working directory other than the default + std::string workingDirectory; // time between cycles to refresh threshold metrics CORBA::ULong threshold_cycle_time; // ulimits for the GPP process diff --git a/GPP/tests/sdr/dev/nodes/test_VarCWDOnly_node/DeviceManager.dcd.xml b/GPP/tests/sdr/dev/nodes/test_VarCWDOnly_node/DeviceManager.dcd.xml new file mode 100644 index 000000000..7dfb969fa --- /dev/null +++ b/GPP/tests/sdr/dev/nodes/test_VarCWDOnly_node/DeviceManager.dcd.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + GPP_1 + + + + + + + + + + + + diff --git a/GPP/tests/sdr/dev/nodes/test_VarCacheOnly_node/DeviceManager.dcd.xml b/GPP/tests/sdr/dev/nodes/test_VarCacheOnly_node/DeviceManager.dcd.xml new file mode 100644 index 000000000..5608e3351 --- /dev/null +++ b/GPP/tests/sdr/dev/nodes/test_VarCacheOnly_node/DeviceManager.dcd.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + GPP_1 + + + + + + + + + + + + diff --git a/GPP/tests/sdr/dev/nodes/test_VarCache_node/DeviceManager.dcd.xml b/GPP/tests/sdr/dev/nodes/test_VarCache_node/DeviceManager.dcd.xml new file mode 100644 index 000000000..0b68eb0d9 --- /dev/null +++ b/GPP/tests/sdr/dev/nodes/test_VarCache_node/DeviceManager.dcd.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + GPP_1 + + + + + + + + + + + + + diff --git a/GPP/tests/sdr/dom/components/check_cwd/check_cwd.prf.xml b/GPP/tests/sdr/dom/components/check_cwd/check_cwd.prf.xml new file mode 100644 index 000000000..38b330346 --- /dev/null +++ b/GPP/tests/sdr/dom/components/check_cwd/check_cwd.prf.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/GPP/tests/sdr/dom/components/check_cwd/check_cwd.scd.xml b/GPP/tests/sdr/dom/components/check_cwd/check_cwd.scd.xml new file mode 100644 index 000000000..df94ceaf5 --- /dev/null +++ b/GPP/tests/sdr/dom/components/check_cwd/check_cwd.scd.xml @@ -0,0 +1,45 @@ + + + + 2.2 + + resource + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/GPP/tests/sdr/dom/components/check_cwd/check_cwd.spd.xml b/GPP/tests/sdr/dom/components/check_cwd/check_cwd.spd.xml new file mode 100644 index 000000000..b349f8c49 --- /dev/null +++ b/GPP/tests/sdr/dom/components/check_cwd/check_cwd.spd.xml @@ -0,0 +1,25 @@ + + + + + + null + + + + + + + + + The implementation contains descriptive information about the template for a software resource. + + + python/check_cwd.py + + + + + + + diff --git a/GPP/tests/sdr/dom/components/check_cwd/python/check_cwd.py b/GPP/tests/sdr/dom/components/check_cwd/python/check_cwd.py new file mode 100755 index 000000000..0e29d6ee4 --- /dev/null +++ b/GPP/tests/sdr/dom/components/check_cwd/python/check_cwd.py @@ -0,0 +1,157 @@ +#!/usr/bin/env python +# +# +# AUTO-GENERATED +# +# Source: check_cwd.spd.xml +from ossie.resource import start_component +import os +import logging + +from check_cwd_base import * + +class check_cwd_i(check_cwd_base): + """""" + def constructor(self): + """ + This is called by the framework immediately after your component registers with the system. + + In general, you should add customization here and not in the __init__ constructor. If you have + a custom port implementation you can override the specific implementation here with a statement + similar to the following: + self.some_port = MyPortImplementation() + + """ + self.cwd = os.getcwd() + + def process(self): + """ + Basic functionality: + + The process method should process a single "chunk" of data and then return. This method + will be called from the processing thread again, and again, and again until it returns + FINISH or stop() is called on the component. If no work is performed, then return NOOP. + + StreamSRI: + To create a StreamSRI object, use the following code (this generates a normalized SRI that does not flush the queue when full): + sri = bulkio.sri.create("my_stream_id") + + PrecisionUTCTime: + To create a PrecisionUTCTime object, use the following code: + tstamp = bulkio.timestamp.now() + + Ports: + + Each port instance is accessed through members of the following form: self.port_ + + Data is obtained in the process function through the getPacket call (BULKIO only) on a + provides port member instance. The optional argument is a timeout value, in seconds. + A zero value is non-blocking, while a negative value is blocking. Constants have been + defined for these values, bulkio.const.BLOCKING and bulkio.const.NON_BLOCKING. If no + timeout is given, it defaults to non-blocking. + + The return value is a named tuple with the following fields: + - dataBuffer + - T + - EOS + - streamID + - SRI + - sriChanged + - inputQueueFlushed + If no data is available due to a timeout, all fields are None. + + To send data, call the appropriate function in the port directly. In the case of BULKIO, + convenience functions have been added in the port classes that aid in output. + + Interactions with non-BULKIO ports are left up to the component developer's discretion. + + Messages: + + To receive a message, you need (1) an input port of type MessageEvent, (2) a message prototype described + as a structure property of kind message, (3) a callback to service the message, and (4) to register the callback + with the input port. + + Assuming a property of type message is declared called "my_msg", an input port called "msg_input" is declared of + type MessageEvent, create the following code: + + def msg_callback(self, msg_id, msg_value): + print msg_id, msg_value + + Register the message callback onto the input port with the following form: + self.port_input.registerMessage("my_msg", check_cwd_i.MyMsg, self.msg_callback) + + To send a message, you need to (1) create a message structure, and (2) send the message over the port. + + Assuming a property of type message is declared called "my_msg", an output port called "msg_output" is declared of + type MessageEvent, create the following code: + + msg_out = check_cwd_i.MyMsg() + this.port_msg_output.sendMessage(msg_out) + + Accessing the Device Manager and Domain Manager: + + Both the Device Manager hosting this Device and the Domain Manager hosting + the Device Manager are available to the Device. + + To access the Domain Manager: + dommgr = self.getDomainManager().getRef(); + To access the Device Manager: + devmgr = self.getDeviceManager().getRef(); + Properties: + + Properties are accessed directly as member variables. If the property name is baudRate, + then accessing it (for reading or writing) is achieved in the following way: self.baudRate. + + To implement a change callback notification for a property, create a callback function with the following form: + + def mycallback(self, id, old_value, new_value): + pass + + where id is the property id, old_value is the previous value, and new_value is the updated value. + + The callback is then registered on the component as: + self.addPropertyChangeListener('baudRate', self.mycallback) + + + Example: + + # This example assumes that the component has two ports: + # - A provides (input) port of type bulkio.InShortPort called dataShort_in + # - A uses (output) port of type bulkio.OutFloatPort called dataFloat_out + # The mapping between the port and the class if found in the component + # base class. + # This example also makes use of the following Properties: + # - A float value called amplitude + # - A boolean called increaseAmplitude + + packet = self.port_dataShort_in.getPacket() + + if packet.dataBuffer is None: + return NOOP + + outData = range(len(packet.dataBuffer)) + for i in range(len(packet.dataBuffer)): + if self.increaseAmplitude: + outData[i] = float(packet.dataBuffer[i]) * self.amplitude + else: + outData[i] = float(packet.dataBuffer[i]) + + # NOTE: You must make at least one valid pushSRI call + if packet.sriChanged: + self.port_dataFloat_out.pushSRI(packet.SRI); + + self.port_dataFloat_out.pushPacket(outData, packet.T, packet.EOS, packet.streamID) + return NORMAL + + """ + + # TODO fill in your code here + self._log.debug("process() example log message") + return NOOP + + +if __name__ == '__main__': + logging.getLogger().setLevel(logging.INFO) + logging.debug("Starting Component") + start_component(check_cwd_i) + diff --git a/GPP/tests/sdr/dom/components/check_cwd/python/check_cwd_base.py b/GPP/tests/sdr/dom/components/check_cwd/python/check_cwd_base.py new file mode 100644 index 000000000..be16cd5e6 --- /dev/null +++ b/GPP/tests/sdr/dom/components/check_cwd/python/check_cwd_base.py @@ -0,0 +1,69 @@ +#!/usr/bin/env python +# +# AUTO-GENERATED CODE. DO NOT MODIFY! +# +# Source: check_cwd.spd.xml +from ossie.cf import CF +from ossie.cf import CF__POA +from ossie.utils import uuid + +from ossie.component import Component +from ossie.threadedcomponent import * +from ossie.properties import simple_property + +import Queue, copy, time, threading + +class check_cwd_base(CF__POA.Resource, Component, ThreadedComponent): + # These values can be altered in the __init__ of your derived class + + PAUSE = 0.0125 # The amount of time to sleep if process return NOOP + TIMEOUT = 5.0 # The amount of time to wait for the process thread to die when stop() is called + DEFAULT_QUEUE_SIZE = 100 # The number of BulkIO packets that can be in the queue before pushPacket will block + + def __init__(self, identifier, execparams): + loggerName = (execparams['NAME_BINDING'].replace('/', '.')).rsplit("_", 1)[0] + Component.__init__(self, identifier, execparams, loggerName=loggerName) + ThreadedComponent.__init__(self) + + # self.auto_start is deprecated and is only kept for API compatibility + # with 1.7.X and 1.8.0 components. This variable may be removed + # in future releases + self.auto_start = False + # Instantiate the default implementations for all ports on this component + + def start(self): + Component.start(self) + ThreadedComponent.startThread(self, pause=self.PAUSE) + + def stop(self): + Component.stop(self) + if not ThreadedComponent.stopThread(self, self.TIMEOUT): + raise CF.Resource.StopError(CF.CF_NOTSET, "Processing thread did not die") + + def releaseObject(self): + try: + self.stop() + except Exception: + self._log.exception("Error stopping") + Component.releaseObject(self) + + ###################################################################### + # PORTS + # + # DO NOT ADD NEW PORTS HERE. You can add ports in your derived class, in the SCD xml file, + # or via the IDE. + + ###################################################################### + # PROPERTIES + # + # DO NOT ADD NEW PROPERTIES HERE. You can add properties in your derived class, in the PRF xml file + # or by using the IDE. + cwd = simple_property(id_="cwd", + type_="string", + mode="readonly", + action="external", + kinds=("property",)) + + + + diff --git a/GPP/tests/sdr/dom/components/check_cwd_cpp/check_cwd_cpp.prf.xml b/GPP/tests/sdr/dom/components/check_cwd_cpp/check_cwd_cpp.prf.xml new file mode 100644 index 000000000..38b330346 --- /dev/null +++ b/GPP/tests/sdr/dom/components/check_cwd_cpp/check_cwd_cpp.prf.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/GPP/tests/sdr/dom/components/check_cwd_cpp/check_cwd_cpp.scd.xml b/GPP/tests/sdr/dom/components/check_cwd_cpp/check_cwd_cpp.scd.xml new file mode 100644 index 000000000..df94ceaf5 --- /dev/null +++ b/GPP/tests/sdr/dom/components/check_cwd_cpp/check_cwd_cpp.scd.xml @@ -0,0 +1,45 @@ + + + + 2.2 + + resource + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/GPP/tests/sdr/dom/components/check_cwd_cpp/check_cwd_cpp.spd.xml b/GPP/tests/sdr/dom/components/check_cwd_cpp/check_cwd_cpp.spd.xml new file mode 100644 index 000000000..d33ba93d1 --- /dev/null +++ b/GPP/tests/sdr/dom/components/check_cwd_cpp/check_cwd_cpp.spd.xml @@ -0,0 +1,27 @@ + + + + + + null + + + + + + + + + The implementation contains descriptive information about the template for a software resource. + + + cpp/check_cwd_cpp + + + + + + + + + diff --git a/GPP/tests/sdr/dom/components/check_cwd_cpp/cpp/Makefile.am b/GPP/tests/sdr/dom/components/check_cwd_cpp/cpp/Makefile.am new file mode 100644 index 000000000..a30cce08b --- /dev/null +++ b/GPP/tests/sdr/dom/components/check_cwd_cpp/cpp/Makefile.am @@ -0,0 +1,40 @@ +# +# This file is protected by Copyright. Please refer to the COPYRIGHT file +# distributed with this source distribution. +# +# This file is part of REDHAWK core. +# +# REDHAWK core is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation, either version 3 of the License, or (at your option) any +# later version. +# +# REDHAWK core is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +# details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/. +# +noinst_PROGRAMS = check_cwd_cpp +ACLOCAL_AMFLAGS = -I m4 -I${OSSIEHOME}/share/aclocal/ossie + +distclean-local: + rm -rf m4 + rm -f config.* + rm -rf autom4te.cache + rm -f acinclude.m4 + rm -f aclocal.m4 + rm -f configure + rm -f depcomp + rm -f install-sh + rm -f ltmain.sh + rm -f Makefile.in + rm -f missing + rm -rf .deps + +check_cwd_cpp_SOURCES = check_cwd_cpp.cpp check_cwd_cpp.h check_cwd_cpp_base.cpp check_cwd_cpp_base.h main.cpp +check_cwd_cpp_CXXFLAGS = -Wall $(PROJECTDEPS_CFLAGS) -I. $(BOOST_CPPFLAGS) $(INTERFACEDEPS_CFLAGS) $(redhawk_INCLUDES_auto) +check_cwd_cpp_LDADD = $(PROJECTDEPS_LIBS) $(BOOST_LDFLAGS) $(BOOST_THREAD_LIB) $(BOOST_REGEX_LIB) $(BOOST_FILESYSTEM_LIB) $(BOOST_SYSTEM_LIB) -lboost_iostreams $(INTERFACEDEPS_LIBS) $(redhawk_LDADD_auto) +check_cwd_cpp_LDFLAGS = -Wall $(redhawk_LDFLAGS_auto) diff --git a/GPP/tests/sdr/dom/components/check_cwd_cpp/cpp/build.sh b/GPP/tests/sdr/dom/components/check_cwd_cpp/cpp/build.sh new file mode 100755 index 000000000..cbc414459 --- /dev/null +++ b/GPP/tests/sdr/dom/components/check_cwd_cpp/cpp/build.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +# Create the Makefile if necessary +if [ ! -e Makefile ]; then + ./reconf + ./configure +fi + +if [ $# == 1 ]; then + if [ $1 == 'clean' ]; then + make distclean + else + make -j $* + fi +else + make -j $* +fi + +exit $? diff --git a/GPP/tests/sdr/dom/components/check_cwd_cpp/cpp/check_cwd_cpp.cpp b/GPP/tests/sdr/dom/components/check_cwd_cpp/cpp/check_cwd_cpp.cpp new file mode 100644 index 000000000..b3a250ea0 --- /dev/null +++ b/GPP/tests/sdr/dom/components/check_cwd_cpp/cpp/check_cwd_cpp.cpp @@ -0,0 +1,255 @@ +/************************************************************************** + + This is the component code. This file contains the child class where + custom functionality can be added to the component. Custom + functionality to the base class can be extended here. Access to + the ports can also be done from this class + +**************************************************************************/ + +#include "check_cwd_cpp.h" + +PREPARE_LOGGING(check_cwd_cpp_i) + +check_cwd_cpp_i::check_cwd_cpp_i(const char *uuid, const char *label) : + check_cwd_cpp_base(uuid, label) +{ + // Avoid placing constructor code here. Instead, use the "constructor" function. + +} + +check_cwd_cpp_i::~check_cwd_cpp_i() +{ +} + +void check_cwd_cpp_i::constructor() +{ + /*********************************************************************************** + This is the RH constructor. All properties are properly initialized before this function is called + ***********************************************************************************/ + char *tmp = getcwd(NULL, 200); + if (tmp != NULL) { + this->cwd = std::string(tmp); + free(tmp); + } + +} + +/*********************************************************************************************** + + Basic functionality: + + The service function is called by the serviceThread object (of type ProcessThread). + This call happens immediately after the previous call if the return value for + the previous call was NORMAL. + If the return value for the previous call was NOOP, then the serviceThread waits + an amount of time defined in the serviceThread's constructor. + + SRI: + To create a StreamSRI object, use the following code: + std::string stream_id = "testStream"; + BULKIO::StreamSRI sri = bulkio::sri::create(stream_id); + + Time: + To create a PrecisionUTCTime object, use the following code: + BULKIO::PrecisionUTCTime tstamp = bulkio::time::utils::now(); + + + Ports: + + Data is passed to the serviceFunction through by reading from input streams + (BulkIO only). The input stream class is a port-specific class, so each port + implementing the BulkIO interface will have its own type-specific input stream. + UDP multicast (dataSDDS and dataVITA49) and string-based (dataString, dataXML and + dataFile) do not support streams. + + The input stream from which to read can be requested with the getCurrentStream() + method. The optional argument to getCurrentStream() is a floating point number that + specifies the time to wait in seconds. A zero value is non-blocking. A negative value + is blocking. Constants have been defined for these values, bulkio::Const::BLOCKING and + bulkio::Const::NON_BLOCKING. + + More advanced uses of input streams are possible; refer to the REDHAWK documentation + for more details. + + Input streams return data blocks that automatically manage the memory for the data + and include the SRI that was in effect at the time the data was received. It is not + necessary to delete the block; it will be cleaned up when it goes out of scope. + + To send data using a BulkIO interface, create an output stream and write the + data to it. When done with the output stream, the close() method sends and end-of- + stream flag and cleans up. + + NOTE: If you have a BULKIO dataSDDS or dataVITA49 port, you must manually call + "port->updateStats()" to update the port statistics when appropriate. + + Example: + // This example assumes that the component has two ports: + // An input (provides) port of type bulkio::InShortPort called dataShort_in + // An output (uses) port of type bulkio::OutFloatPort called dataFloat_out + // The mapping between the port and the class is found + // in the component base class header file + // The component class must have an output stream member; add to + // check_cwd_cpp.h: + // bulkio::OutFloatStream outputStream; + + bulkio::InShortStream inputStream = dataShort_in->getCurrentStream(); + if (!inputStream) { // No streams are available + return NOOP; + } + + bulkio::ShortDataBlock block = inputStream.read(); + if (!block) { // No data available + // Propagate end-of-stream + if (inputStream.eos()) { + outputStream.close(); + } + return NOOP; + } + + short* inputData = block.data(); + std::vector outputData; + outputData.resize(block.size()); + for (size_t index = 0; index < block.size(); ++index) { + outputData[index] = (float) inputData[index]; + } + + // If there is no output stream open, create one + if (!outputStream) { + outputStream = dataFloat_out->createStream(block.sri()); + } else if (block.sriChanged()) { + // Update output SRI + outputStream.sri(block.sri()); + } + + // Write to the output stream + outputStream.write(outputData, block.getTimestamps()); + + // Propagate end-of-stream + if (inputStream.eos()) { + outputStream.close(); + } + + return NORMAL; + + If working with complex data (i.e., the "mode" on the SRI is set to + true), the data block's complex() method will return true. Data blocks + provide functions that return the correct interpretation of the data + buffer and number of complex elements: + + if (block.complex()) { + std::complex* data = block.cxdata(); + for (size_t index = 0; index < block.cxsize(); ++index) { + data[index] = std::abs(data[index]); + } + outputStream.write(data, block.cxsize(), bulkio::time::utils::now()); + } + + Interactions with non-BULKIO ports are left up to the component developer's discretion + + Messages: + + To receive a message, you need (1) an input port of type MessageEvent, (2) a message prototype described + as a structure property of kind message, (3) a callback to service the message, and (4) to register the callback + with the input port. + + Assuming a property of type message is declared called "my_msg", an input port called "msg_input" is declared of + type MessageEvent, create the following code: + + void check_cwd_cpp_i::my_message_callback(const std::string& id, const my_msg_struct &msg){ + } + + Register the message callback onto the input port with the following form: + this->msg_input->registerMessage("my_msg", this, &check_cwd_cpp_i::my_message_callback); + + To send a message, you need to (1) create a message structure, (2) a message prototype described + as a structure property of kind message, and (3) send the message over the port. + + Assuming a property of type message is declared called "my_msg", an output port called "msg_output" is declared of + type MessageEvent, create the following code: + + ::my_msg_struct msg_out; + this->msg_output->sendMessage(msg_out); + + Accessing the Application and Domain Manager: + + Both the Application hosting this Component and the Domain Manager hosting + the Application are available to the Component. + + To access the Domain Manager: + CF::DomainManager_ptr dommgr = this->getDomainManager()->getRef(); + To access the Application: + CF::Application_ptr app = this->getApplication()->getRef(); + + Properties: + + Properties are accessed directly as member variables. For example, if the + property name is "baudRate", it may be accessed within member functions as + "baudRate". Unnamed properties are given the property id as its name. + Property types are mapped to the nearest C++ type, (e.g. "string" becomes + "std::string"). All generated properties are declared in the base class + (check_cwd_cpp_base). + + Simple sequence properties are mapped to "std::vector" of the simple type. + Struct properties, if used, are mapped to C++ structs defined in the + generated file "struct_props.h". Field names are taken from the name in + the properties file; if no name is given, a generated name of the form + "field_n" is used, where "n" is the ordinal number of the field. + + Example: + // This example makes use of the following Properties: + // - A float value called scaleValue + // - A boolean called scaleInput + + if (scaleInput) { + dataOut[i] = dataIn[i] * scaleValue; + } else { + dataOut[i] = dataIn[i]; + } + + Callback methods can be associated with a property so that the methods are + called each time the property value changes. This is done by calling + addPropertyListener(, this, &check_cwd_cpp_i::) + in the constructor. + + The callback method receives two arguments, the old and new values, and + should return nothing (void). The arguments can be passed by value, + receiving a copy (preferred for primitive types), or by const reference + (preferred for strings, structs and vectors). + + Example: + // This example makes use of the following Properties: + // - A float value called scaleValue + // - A struct property called status + + //Add to check_cwd_cpp.cpp + check_cwd_cpp_i::check_cwd_cpp_i(const char *uuid, const char *label) : + check_cwd_cpp_base(uuid, label) + { + addPropertyListener(scaleValue, this, &check_cwd_cpp_i::scaleChanged); + addPropertyListener(status, this, &check_cwd_cpp_i::statusChanged); + } + + void check_cwd_cpp_i::scaleChanged(float oldValue, float newValue) + { + LOG_DEBUG(check_cwd_cpp_i, "scaleValue changed from" << oldValue << " to " << newValue); + } + + void check_cwd_cpp_i::statusChanged(const status_struct& oldValue, const status_struct& newValue) + { + LOG_DEBUG(check_cwd_cpp_i, "status changed"); + } + + //Add to check_cwd_cpp.h + void scaleChanged(float oldValue, float newValue); + void statusChanged(const status_struct& oldValue, const status_struct& newValue); + + +************************************************************************************************/ +int check_cwd_cpp_i::serviceFunction() +{ + LOG_DEBUG(check_cwd_cpp_i, "serviceFunction() example log message"); + + return NOOP; +} + diff --git a/GPP/tests/sdr/dom/components/check_cwd_cpp/cpp/check_cwd_cpp.h b/GPP/tests/sdr/dom/components/check_cwd_cpp/cpp/check_cwd_cpp.h new file mode 100644 index 000000000..b7e3abff0 --- /dev/null +++ b/GPP/tests/sdr/dom/components/check_cwd_cpp/cpp/check_cwd_cpp.h @@ -0,0 +1,18 @@ +#ifndef CHECK_CWD_CPP_I_IMPL_H +#define CHECK_CWD_CPP_I_IMPL_H + +#include "check_cwd_cpp_base.h" + +class check_cwd_cpp_i : public check_cwd_cpp_base +{ + ENABLE_LOGGING + public: + check_cwd_cpp_i(const char *uuid, const char *label); + ~check_cwd_cpp_i(); + + void constructor(); + + int serviceFunction(); +}; + +#endif // CHECK_CWD_CPP_I_IMPL_H diff --git a/GPP/tests/sdr/dom/components/check_cwd_cpp/cpp/check_cwd_cpp_base.cpp b/GPP/tests/sdr/dom/components/check_cwd_cpp/cpp/check_cwd_cpp_base.cpp new file mode 100644 index 000000000..16a06a88d --- /dev/null +++ b/GPP/tests/sdr/dom/components/check_cwd_cpp/cpp/check_cwd_cpp_base.cpp @@ -0,0 +1,66 @@ +#include "check_cwd_cpp_base.h" + +/******************************************************************************************* + + AUTO-GENERATED CODE. DO NOT MODIFY + + The following class functions are for the base class for the component class. To + customize any of these functions, do not modify them here. Instead, overload them + on the child class + +******************************************************************************************/ + +check_cwd_cpp_base::check_cwd_cpp_base(const char *uuid, const char *label) : + Component(uuid, label), + ThreadedComponent() +{ + loadProperties(); +} + +check_cwd_cpp_base::~check_cwd_cpp_base() +{ +} + +/******************************************************************************************* + Framework-level functions + These functions are generally called by the framework to perform housekeeping. +*******************************************************************************************/ +void check_cwd_cpp_base::start() throw (CORBA::SystemException, CF::Resource::StartError) +{ + Component::start(); + ThreadedComponent::startThread(); +} + +void check_cwd_cpp_base::stop() throw (CORBA::SystemException, CF::Resource::StopError) +{ + Component::stop(); + if (!ThreadedComponent::stopThread()) { + throw CF::Resource::StopError(CF::CF_NOTSET, "Processing thread did not die"); + } +} + +void check_cwd_cpp_base::releaseObject() throw (CORBA::SystemException, CF::LifeCycle::ReleaseError) +{ + // This function clears the component running condition so main shuts down everything + try { + stop(); + } catch (CF::Resource::StopError& ex) { + // TODO - this should probably be logged instead of ignored + } + + Component::releaseObject(); +} + +void check_cwd_cpp_base::loadProperties() +{ + addProperty(cwd, + "cwd", + "", + "readonly", + "", + "external", + "property"); + +} + + diff --git a/GPP/tests/sdr/dom/components/check_cwd_cpp/cpp/check_cwd_cpp_base.h b/GPP/tests/sdr/dom/components/check_cwd_cpp/cpp/check_cwd_cpp_base.h new file mode 100644 index 000000000..d7bea05ce --- /dev/null +++ b/GPP/tests/sdr/dom/components/check_cwd_cpp/cpp/check_cwd_cpp_base.h @@ -0,0 +1,30 @@ +#ifndef CHECK_CWD_CPP_BASE_IMPL_BASE_H +#define CHECK_CWD_CPP_BASE_IMPL_BASE_H + +#include +#include +#include + + +class check_cwd_cpp_base : public Component, protected ThreadedComponent +{ + public: + check_cwd_cpp_base(const char *uuid, const char *label); + ~check_cwd_cpp_base(); + + void start() throw (CF::Resource::StartError, CORBA::SystemException); + + void stop() throw (CF::Resource::StopError, CORBA::SystemException); + + void releaseObject() throw (CF::LifeCycle::ReleaseError, CORBA::SystemException); + + void loadProperties(); + + protected: + // Member variables exposed as properties + /// Property: cwd + std::string cwd; + + private: +}; +#endif // CHECK_CWD_CPP_BASE_IMPL_BASE_H diff --git a/GPP/tests/sdr/dom/components/check_cwd_cpp/cpp/configure.ac b/GPP/tests/sdr/dom/components/check_cwd_cpp/cpp/configure.ac new file mode 100644 index 000000000..c885f8772 --- /dev/null +++ b/GPP/tests/sdr/dom/components/check_cwd_cpp/cpp/configure.ac @@ -0,0 +1,25 @@ +AC_INIT(check_cwd_cpp, 1.0.0) +AM_INIT_AUTOMAKE([nostdinc foreign]) +AC_CONFIG_MACRO_DIR([m4]) + +AC_PROG_CC +AC_PROG_CXX +AC_PROG_INSTALL + +AC_CORBA_ORB +OSSIE_CHECK_OSSIE +OSSIE_SDRROOT_AS_PREFIX + +m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) + +# Dependencies +PKG_CHECK_MODULES([PROJECTDEPS], [ossie >= 2.0 omniORB4 >= 4.1.0]) +OSSIE_ENABLE_LOG4CXX +AX_BOOST_BASE([1.41]) +AX_BOOST_SYSTEM +AX_BOOST_THREAD +AX_BOOST_REGEX + +AC_CONFIG_FILES([Makefile]) +AC_OUTPUT + diff --git a/GPP/tests/sdr/dom/components/check_cwd_cpp/cpp/main.cpp b/GPP/tests/sdr/dom/components/check_cwd_cpp/cpp/main.cpp new file mode 100644 index 000000000..c9d2c1335 --- /dev/null +++ b/GPP/tests/sdr/dom/components/check_cwd_cpp/cpp/main.cpp @@ -0,0 +1,11 @@ +#include +#include "ossie/ossieSupport.h" + +#include "check_cwd_cpp.h" +int main(int argc, char* argv[]) +{ + check_cwd_cpp_i* check_cwd_cpp_servant; + Component::start_component(check_cwd_cpp_servant, argc, argv); + return 0; +} + diff --git a/GPP/tests/sdr/dom/components/check_cwd_cpp/cpp/reconf b/GPP/tests/sdr/dom/components/check_cwd_cpp/cpp/reconf new file mode 100755 index 000000000..8ff01d431 --- /dev/null +++ b/GPP/tests/sdr/dom/components/check_cwd_cpp/cpp/reconf @@ -0,0 +1,6 @@ +#!/bin/sh + +rm -f config.cache +[ -d m4 ] || mkdir m4 +autoreconf -i + diff --git a/GPP/tests/sdr/dom/components/check_cwd_java/check_cwd_java.prf.xml b/GPP/tests/sdr/dom/components/check_cwd_java/check_cwd_java.prf.xml new file mode 100644 index 000000000..38b330346 --- /dev/null +++ b/GPP/tests/sdr/dom/components/check_cwd_java/check_cwd_java.prf.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/GPP/tests/sdr/dom/components/check_cwd_java/check_cwd_java.scd.xml b/GPP/tests/sdr/dom/components/check_cwd_java/check_cwd_java.scd.xml new file mode 100644 index 000000000..df94ceaf5 --- /dev/null +++ b/GPP/tests/sdr/dom/components/check_cwd_java/check_cwd_java.scd.xml @@ -0,0 +1,45 @@ + + + + 2.2 + + resource + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/GPP/tests/sdr/dom/components/check_cwd_java/check_cwd_java.spd.xml b/GPP/tests/sdr/dom/components/check_cwd_java/check_cwd_java.spd.xml new file mode 100644 index 000000000..7dd9f6026 --- /dev/null +++ b/GPP/tests/sdr/dom/components/check_cwd_java/check_cwd_java.spd.xml @@ -0,0 +1,26 @@ + + + + + + null + + + + + + + + + The implementation contains descriptive information about the template for a software resource. + + + java/startJava.sh + + + + + + + + diff --git a/GPP/tests/sdr/dom/components/check_cwd_java/java/Makefile.am b/GPP/tests/sdr/dom/components/check_cwd_java/java/Makefile.am new file mode 100644 index 000000000..a14a9b923 --- /dev/null +++ b/GPP/tests/sdr/dom/components/check_cwd_java/java/Makefile.am @@ -0,0 +1,37 @@ +# +# This file is protected by Copyright. Please refer to the COPYRIGHT file +# distributed with this source distribution. +# +# This file is part of REDHAWK core. +# +# REDHAWK core is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation, either version 3 of the License, or (at your option) any +# later version. +# +# REDHAWK core is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +# details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/. +# +ACLOCAL_AMFLAGS = -I m4 -I${OSSIEHOME}/share/aclocal/ossie +AUTOMAKE_OPTIONS = subdir-objects + +check_cwd_java_jar_CLASSPATH = $(SOFTPKG_CLASSPATH):$(REDHAWK_CLASSPATH): + +check_cwd_java.jar$(EXEEXT): $(check_cwd_java_jar_SOURCES) + mkdir -p bin + $(JAVAC) -cp $(check_cwd_java_jar_CLASSPATH) -g -d bin $(check_cwd_java_jar_SOURCES) + $(JAR) cf ./check_cwd_java.jar -C bin . + $(JAR) uf ./check_cwd_java.jar -C src . + +clean-local: + rm -rf bin + +check_cwd_java_jar_SOURCES := $(shell find ./src -name "*.java") + +ossieName = check_cwd_java +noinst_PROGRAMS = check_cwd_java.jar diff --git a/GPP/tests/sdr/dom/components/check_cwd_java/java/src/check_cwd_java/java/check_cwd_java.java b/GPP/tests/sdr/dom/components/check_cwd_java/java/src/check_cwd_java/java/check_cwd_java.java new file mode 100644 index 000000000..7bcfdb3d7 --- /dev/null +++ b/GPP/tests/sdr/dom/components/check_cwd_java/java/src/check_cwd_java/java/check_cwd_java.java @@ -0,0 +1,253 @@ +package check_cwd_java.java; + +import java.util.Properties; + +/** + * This is the component code. This file contains the derived class where custom + * functionality can be added to the component. You may add methods and code to + * this class to handle property changes, respond to incoming data, and perform + * general component housekeeping + * + * Source: check_cwd_java.spd.xml + */ +public class check_cwd_java extends check_cwd_java_base { + /** + * This is the component constructor. In this method, you may add + * additional functionality to properties such as listening for changes + * or handling allocation, register message handlers and set up internal + * state for your component. + * + * A component may listen for external changes to properties (i.e., by a + * call to configure) using the PropertyListener interface. Listeners are + * registered by calling addChangeListener() on the property instance + * with an object that implements the PropertyListener interface for that + * data type (e.g., "PropertyListener" for a float property). More + * than one listener can be connected to a property. + * + * Example: + * // This example makes use of the following properties: + * // - A float value called scaleValue + * // The file must import "org.ossie.properties.PropertyListener" + * // Add the following import to the top of the file: + * import org.ossie.properties.PropertyListener; + * + * //Add the following to the class constructor: + * this.scaleValue.addChangeListener(new PropertyListener() { + * public void valueChanged(Float oldValue, Float newValue) { + * scaleValueChanged(oldValue, newValue); + * } + * }); + * + * //Add the following method to the class: + * private void scaleValueChanged(Float oldValue, Float newValue) + * { + * logger.debug("Changed scaleValue " + oldValue + " to " + newValue); + * } + * + * The recommended practice is for the implementation of valueChanged() to + * contain only glue code to dispatch the call to a private method on the + * component class. + * Accessing the Application and Domain Manager: + * + * Both the Application hosting this Component and the Domain Manager hosting + * the Application are available to the Component. + * + * To access the Domain Manager: + * CF.DomainManager dommgr = this.getDomainManager().getRef(); + * To access the Application: + * CF.Application app = this.getApplication().getRef(); + * + * Messages: + * + * To send or receive messages, you must have at least one message + * prototype described as a struct property of kind "message." + * + * Receiving: + * + * To receive a message, you must have an input port of type MessageEvent + * (marked as "bi-dir" in the Ports editor). For each message type the + * component supports, you must register a message handler callback with + * the message input port. Message handlers implement the MessageListener + * interface. + * + * A callback is registered by calling registerMessage() on the message + * input port with the message ID, the message struct's Class object and + * an object that implements the MessageListener interface for that + * message struct (e.g., "MessageListener" for a + * message named "my_message"). + * + * Example: + * // Assume the component has a message type called "my_message" and + * // an input MessageEvent port called "message_in". + * // Add the following to the top of the file: + * import org.ossie.events.MessageListener; + * + * // Register the callback in the class constructor: + * this.message_in.registerMessage("my_message", my_message_struct.class, new MessageListener() { + * public void messageReceived(String messageId, my_message_struct messageData) { + * my_message_received(messageData); + * } + * }); + * + * // Implement the message handler method: + * private void my_message_received(my_message_struct messageData) { + * // Respond to the message + * } + * + * The recommended practice is for the implementation of messageReceived() + * to contain only glue code to dispatch the call to a private method on + * the component class. + * + * Sending: + * + * To send a message, you must have an output port of type MessageEvent. + * Create an instance of the message struct type and call sendMessage() + * to send a single message. + * + * Example: + * // Assume the component has a message type called "my_message" and + * // an output MessageEvent port called "message_out". + * my_message_struct message = new my_message_struct(); + * this.message_out.sendMessage(message); + * + * You may also send a batch of messages at once with the sendMessages() + * method. + */ + + public check_cwd_java() + { + super(); + } + + public void constructor() + { + this.cwd.setValue(this.getClass().getClassLoader().getResource("").getPath()); + } + + + /** + * + * Main processing function + * + * General functionality: + * + * The serviceFunction() is called repeatedly by the component's processing + * thread, which runs independently of the main thread. Each invocation + * should perform a single unit of work, such as reading and processing one + * data packet. + * + * The return status of serviceFunction() determines how soon the next + * invocation occurs: + * - NORMAL: the next call happens immediately + * - NOOP: the next call happens after a pre-defined delay (100 ms) + * - FINISH: no more calls occur + * + * StreamSRI: + * To create a StreamSRI object, use the following code: + * String stream_id = "testStream"; + * BULKIO.StreamSRI sri = new BULKIO.StreamSRI(); + * sri.mode = 0; + * sri.xdelta = 0.0; + * sri.ydelta = 1.0; + * sri.subsize = 0; + * sri.xunits = 1; // TIME_S + * sri.streamID = (stream_id != null) ? stream_id : ""; + * + * PrecisionUTCTime: + * To create a PrecisionUTCTime object, use the following code: + * BULKIO.PrecisionUTCTime tstamp = bulkio.time.utils.now(); + * + * Ports: + * + * Each port instance is accessed through members of the following form: + * + * this.port_ + * + * Input BULKIO data is obtained by calling getPacket on the provides + * port. The getPacket method takes one argument: the time to wait for + * data to arrive, in milliseconds. A timeout of 0 causes getPacket to + * return immediately, while a negative timeout indicates an indefinite + * wait. If no data is queued and no packet arrives during the waiting + * period, getPacket returns null. + * + * Output BULKIO data is sent by calling pushPacket on the uses port. In + * the case of numeric data, the pushPacket method takes a primitive + * array (e.g., "float[]"), a timestamp, an end-of-stream flag and a + * stream ID. You must make at least one call to pushSRI to associate a + * StreamSRI with the stream ID before calling pushPacket, or receivers + * may drop the data. + * + * When all processing on a stream is complete, a call should be made to + * pushPacket with the end-of-stream flag set to "true". + * + * Interactions with non-BULKIO ports are left up to the discretion of + * the component developer. + * + * Properties: + * + * Properties are accessed through members of the same name; characters + * that are invalid for a Java identifier are replaced with "_". The + * current value of the property is read with getValue and written with + * setValue: + * + * float val = this.float_prop.getValue(); + * ... + * this.float_prop.setValue(1.5f); + * + * Primitive data types are stored using the corresponding Java object + * wrapper class. For example, a property of type "float" is stored as a + * Float. Java will automatically box and unbox primitive types where + * appropriate. + * + * Numeric properties support assignment via setValue from any numeric + * type. The standard Java type coercion rules apply (e.g., truncation + * of floating point values when converting to integer types). + * + * Example: + * + * This example assumes that the component has two ports: + * - A bulkio.InShortPort provides (input) port called dataShort_in + * - A bulkio.OutFloatPort uses (output) port called dataFloat_out + * The mapping between the port and the class is found in the component + * base class file. + * This example also makes use of the following Properties: + * - A float value called amplitude with a default value of 2.0 + * - A boolean called increaseAmplitude with a default value of true + * + * bulkio.InShortPort.Packet data = this.port_dataShort_in.getPacket(125); + * + * if (data != null) { + * float[] outData = new float[data.getData().length]; + * for (int i = 0; i < data.getData().length; i++) { + * if (this.increaseAmplitude.getValue()) { + * outData[i] = (float)data.getData()[i] * this.amplitude.getValue(); + * } else { + * outData[i] = (float)data.getData()[i]; + * } + * } + * + * // NOTE: You must make at least one valid pushSRI call + * if (data.sriChanged()) { + * this.port_dataFloat_out.pushSRI(data.getSRI()); + * } + * this.port_dataFloat_out.pushPacket(outData, data.getTime(), data.getEndOfStream(), data.getStreamID()); + * } + * + */ + protected int serviceFunction() { + logger.debug("serviceFunction() example log message"); + + return NOOP; + } + + /** + * Set additional options for ORB startup. For example: + * + * orbProps.put("com.sun.CORBA.giop.ORBFragmentSize", Integer.toString(fragSize)); + * + * @param orbProps + */ + public static void configureOrb(final Properties orbProps) { + } + +} diff --git a/GPP/tests/sdr/dom/components/check_cwd_java/java/src/check_cwd_java/java/check_cwd_java_base.java b/GPP/tests/sdr/dom/components/check_cwd_java/java/src/check_cwd_java/java/check_cwd_java_base.java new file mode 100644 index 000000000..bdb70fc22 --- /dev/null +++ b/GPP/tests/sdr/dom/components/check_cwd_java/java/src/check_cwd_java/java/check_cwd_java_base.java @@ -0,0 +1,102 @@ +package check_cwd_java.java; + + +import java.util.Properties; + +import org.apache.log4j.Logger; + +import org.omg.CosNaming.NamingContextPackage.CannotProceed; +import org.omg.CosNaming.NamingContextPackage.InvalidName; +import org.omg.CosNaming.NamingContextPackage.NotFound; +import org.omg.PortableServer.POAPackage.ServantNotActive; +import org.omg.PortableServer.POAPackage.WrongPolicy; + +import CF.InvalidObjectReference; + +import org.ossie.component.*; +import org.ossie.properties.*; + + +/** + * This is the component code. This file contains all the access points + * you need to use to be able to access all input and output ports, + * respond to incoming data, and perform general component housekeeping + * + * Source: check_cwd_java.spd.xml + * + * @generated + */ + +public abstract class check_cwd_java_base extends Component { + /** + * @generated + */ + public final static Logger logger = Logger.getLogger(check_cwd_java_base.class.getName()); + + /** + * The property cwd + * If the meaning of this property isn't clear, a description should be added. + * + * @generated + */ + public final StringProperty cwd = + new StringProperty( + "cwd", //id + null, //name + null, //default value + Mode.READONLY, //mode + Action.EXTERNAL, //action + new Kind[] {Kind.PROPERTY} + ); + + /** + * @generated + */ + public check_cwd_java_base() + { + super(); + + setLogger( logger, check_cwd_java_base.class.getName() ); + + + // Properties + addProperty(cwd); + + } + + + + /** + * The main function of your component. If no args are provided, then the + * CORBA object is not bound to an SCA Domain or NamingService and can + * be run as a standard Java application. + * + * @param args + * @generated + */ + public static void main(String[] args) + { + final Properties orbProps = new Properties(); + check_cwd_java.configureOrb(orbProps); + + try { + Component.start_component(check_cwd_java.class, args, orbProps); + } catch (InvalidObjectReference e) { + e.printStackTrace(); + } catch (NotFound e) { + e.printStackTrace(); + } catch (CannotProceed e) { + e.printStackTrace(); + } catch (InvalidName e) { + e.printStackTrace(); + } catch (ServantNotActive e) { + e.printStackTrace(); + } catch (WrongPolicy e) { + e.printStackTrace(); + } catch (InstantiationException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + } +} diff --git a/GPP/tests/sdr/dom/components/check_cwd_java/java/startJava.sh b/GPP/tests/sdr/dom/components/check_cwd_java/java/startJava.sh new file mode 100755 index 000000000..440a4cfdc --- /dev/null +++ b/GPP/tests/sdr/dom/components/check_cwd_java/java/startJava.sh @@ -0,0 +1,30 @@ +#!/bin/sh +myDir=`dirname $0` + +# Setup the OSSIEHOME Lib jars on the classpath +libDir=$OSSIEHOME/lib +libFiles=`ls -1 $libDir/*.jar` +for file in $libFiles +do + if [ x"$CLASSPATH" = "x" ] + then + export CLASSPATH=$file + else + export CLASSPATH=$file:$CLASSPATH + fi +done + +# Path for Java +if test -x $JAVA_HOME/bin/java; then + JAVA=$JAVA_HOME/bin/java +else + JAVA=java +fi + +# NOTE: the $@ must be quoted "$@" for arguments to be passed correctly + +#Sun ORB start line +exec $JAVA -cp :$myDir/check_cwd_java.jar:$myDir/bin:$CLASSPATH check_cwd_java.java.check_cwd_java "$@" + +#JacORB start lines +#exec $JAVA -cp :$myDir/jacorb.jar:$myDir/antlr.jar:$myDir/avalon-framework.jar:$myDir/backport-util-concurrent.jar:$myDir/logkit.jar:$myDir/check_cwd_java.jar:$myDir/bin:$CLASSPATH check_cwd_java.java.check_cwd_java "$@" diff --git a/GPP/tests/sdr/dom/waveforms/check_cwd_cpp_w/check_cwd_cpp_w.sad.xml b/GPP/tests/sdr/dom/waveforms/check_cwd_cpp_w/check_cwd_cpp_w.sad.xml new file mode 100644 index 000000000..a630277e0 --- /dev/null +++ b/GPP/tests/sdr/dom/waveforms/check_cwd_cpp_w/check_cwd_cpp_w.sad.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + check_cwd_cpp_1 + + + + + + + + + + diff --git a/GPP/tests/sdr/dom/waveforms/check_cwd_java_w/check_cwd_java_w.sad.xml b/GPP/tests/sdr/dom/waveforms/check_cwd_java_w/check_cwd_java_w.sad.xml new file mode 100644 index 000000000..739289191 --- /dev/null +++ b/GPP/tests/sdr/dom/waveforms/check_cwd_java_w/check_cwd_java_w.sad.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + check_cwd_java_1 + + + + + + + + + + diff --git a/GPP/tests/sdr/dom/waveforms/check_cwd_w/check_cwd_w.sad.xml b/GPP/tests/sdr/dom/waveforms/check_cwd_w/check_cwd_w.sad.xml new file mode 100644 index 000000000..b926c6a8f --- /dev/null +++ b/GPP/tests/sdr/dom/waveforms/check_cwd_w/check_cwd_w.sad.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + check_cwd_1 + + + + + + + + + + diff --git a/GPP/tests/test_GPP.py b/GPP/tests/test_GPP.py index f80b021bd..025922867 100755 --- a/GPP/tests/test_GPP.py +++ b/GPP/tests/test_GPP.py @@ -41,6 +41,7 @@ import ossie.utils.testing from shutil import copyfile import os +import shutil # numa layout: node 0 cpus, node 1 cpus, node 0 cpus sans cpuid=0 @@ -904,8 +905,7 @@ def testFloorReservation(self): time.sleep(2) self.assertEquals(self.comp._get_usageState(),CF.Device.BUSY) - -class ComponentTests_SystemReservations(ossie.utils.testing.ScaComponentTestCase): +class DomainSupport(ossie.utils.testing.ScaComponentTestCase): """Test for all component implementations in test""" child_pids = [] dom = None @@ -915,6 +915,7 @@ class ComponentTests_SystemReservations(ossie.utils.testing.ScaComponentTestCase _deviceLock = threading.Lock() _deviceBooters = [] _deviceManagers = [] + sdrroot = '' def _getDeviceManager(self, domMgr, id): for devMgr in domMgr._get_deviceManagers(): @@ -946,14 +947,15 @@ def terminateChild(self, child, signals=(signal.SIGINT, signal.SIGTERM)): finally: pass - def launchDomainManager(self, dmdFile="", domain_name = '', *args, **kwargs): + def launchDomainManager(self, dmdFile="", domain_name = '', sdrroot=os.getcwd()+'/sdr', *args, **kwargs): # Only allow one DomainManager, although this isn't a hard requirement. # If it has exited, allow a relaunch. if self._domainBooter and self._domainBooter.poll() == None: return (self._domainBooter, self._domainManager) + self.sdrroot = sdrroot # Launch the nodebooter. - self._domainBooter = spawnNodeBooter(dmdFile=dmdFile, domainname = domain_name, *args, **kwargs) + self._domainBooter = spawnNodeBooter(dmdFile=dmdFile, domainname = domain_name, sdrroot=sdrroot, *args, **kwargs) number_attempts = 0 while self._domainBooter.poll() == None: try: @@ -987,17 +989,18 @@ def _addDeviceManager(self, devMgr): finally: self._deviceLock.release() - def launchDeviceManager(self, dcdFile, domainManager=None, wait=True, *args, **kwargs): - if not os.path.isfile(os.getcwd()+'/'+dcdFile): + def launchDeviceManager(self, dcdFile, domainManager=None, wait=True, sdrroot=os.getcwd()+'/sdr', *args, **kwargs): + if not os.path.isfile(sdrroot+'/dev'+dcdFile): print "ERROR: Invalid DCD path provided to launchDeviceManager ", dcdFile return (None, None) + self.sdrroot = sdrroot # Launch the nodebooter. if domainManager == None: name = None else: name = domainManager._get_name() - devBooter = spawnNodeBooter(dcdFile=os.getcwd()+'/'+dcdFile, domainname=name, *args, **kwargs) + devBooter = spawnNodeBooter(dcdFile=sdrroot+'/dev'+dcdFile, domainname=name, sdrroot=sdrroot, *args, **kwargs) self._addDeviceBooter(devBooter) if wait: @@ -1009,7 +1012,7 @@ def launchDeviceManager(self, dcdFile, domainManager=None, wait=True, *args, **k def waitDeviceManager(self, devBooter, dcdFile, domainManager=None): try: - dcdPath = os.getcwd()+'/'+dcdFile + dcdPath = self.sdrroot+'/dev'+dcdFile except IOError: print "ERROR: Invalid DCD path provided to waitDeviceManager", dcdFile return None @@ -1054,7 +1057,7 @@ def _waitRegisteredDevices(self, devMgr, numDevices, timeout=5.0, pause=0.1): return False def setUp(self): - super(ComponentTests_SystemReservations,self).setUp() + super(DomainSupport,self).setUp() self.child_pids=[] self._domainBooter = None self._domainManager = None @@ -1072,10 +1075,10 @@ def setUp(self): os.makedirs('sdr/dev/devices/GPP/cpp') copyfile('../cpp/GPP', 'sdr/dev/devices/GPP/cpp/GPP') os.chmod('sdr/dev/devices/GPP/cpp/GPP',0777) - + print 'done staging DomainManager' def tearDown(self): - super(ComponentTests_SystemReservations, self).tearDown() + super(DomainSupport, self).tearDown() try: # kill all busy.py just in case os.system('pkill -9 -f busy.py') @@ -1098,7 +1101,13 @@ def tearDown(self): self.terminateChild(self._deviceBooter) os.putenv('SDRROOT', self.orig_sdrroot) - +class ComponentTests_SystemReservations(DomainSupport): + def setUp(self): + super(ComponentTests_SystemReservations,self).setUp() + + def tearDown(self): + super(ComponentTests_SystemReservations, self).tearDown() + def runGPP(self, execparam_overrides={}, initialize=True): ####################################################################### # Launch the component with the default execparams @@ -1131,7 +1140,7 @@ def testMonitorComponents(self): self.assertEquals(os.path.isfile('sdr/dev/mgr/DeviceManager'),True) self._domainBooter, domMgr = self.launchDomainManager(domain_name='REDHAWK_TEST_'+str(os.getpid())) self.assertNotEquals(domMgr,None) - self._deviceBooter, devMgr = self.launchDeviceManager("sdr/dev/nodes/DevMgr_sample/DeviceManager.dcd.xml", domainManager=self.dom.ref) + self._deviceBooter, devMgr = self.launchDeviceManager("/nodes/DevMgr_sample/DeviceManager.dcd.xml", domainManager=self.dom.ref) self.assertNotEquals(devMgr,None) app_1=self.dom.createApplication('/waveforms/load_comp_w/load_comp_w.sad.xml','load_comp_w',[]) wait_amount = (self.dom.devMgrs[0].devs[0].threshold_cycle_time / 1000.0) * 6 @@ -1158,7 +1167,7 @@ def testDeadlock(self): self.assertEquals(os.path.isfile('sdr/dev/mgr/DeviceManager'),True) self._domainBooter, domMgr = self.launchDomainManager(domain_name='REDHAWK_TEST_'+str(os.getpid())) self.assertNotEquals(domMgr,None) - self._deviceBooter, devMgr = self.launchDeviceManager("sdr/dev/nodes/DevMgr_sample/DeviceManager.dcd.xml", domainManager=self.dom.ref) + self._deviceBooter, devMgr = self.launchDeviceManager("/nodes/DevMgr_sample/DeviceManager.dcd.xml", domainManager=self.dom.ref) self.assertNotEquals(devMgr,None) self.dom.devMgrs[0].devs[0].threshold_cycle_time = 50 count = 0 @@ -1176,7 +1185,7 @@ def testSystemReservation(self): self.assertEquals(os.path.isfile('sdr/dev/mgr/DeviceManager'),True) self._domainBooter, domMgr = self.launchDomainManager(domain_name='REDHAWK_TEST_'+str(os.getpid())) self.assertNotEquals(domMgr,None) - self._deviceBooter, devMgr = self.launchDeviceManager("sdr/dev/nodes/DevMgr_sample/DeviceManager.dcd.xml", domainManager=self.dom.ref) + self._deviceBooter, devMgr = self.launchDeviceManager("/nodes/DevMgr_sample/DeviceManager.dcd.xml", domainManager=self.dom.ref) self.assertNotEquals(devMgr,None) self.comp= self.dom.devMgrs[0].devs[0] cpus = self.dom.devMgrs[0].devs[0].processor_cores @@ -1259,6 +1268,174 @@ def testSystemReservation(self): self.assertEquals(self.float_eq(sub_now_pre, sub_now, eps=.01), True) +class LoadableDeviceVariableDirectoriesTest(DomainSupport): + def setUp(self): + super(LoadableDeviceVariableDirectoriesTest,self).setUp() + self._domainName = 'REDHAWK_TEST_'+str(os.getpid()) + self._domainBooter, self._domMgr = self.launchDomainManager(domain_name=self._domainName) + self._testFiles = [] + self._rhDom = redhawk.attach(self._domainName) + + fp = open('sdr/dev/nodes/test_VarCache_node/DeviceManager.dcd.xml', 'r') + self.original = fp.read() + fp.close() + + cwd = os.getcwd() + self.base_dir = cwd + '/LoadableDeviceVariableDirectoriesTest' + self.cache_dir = self.base_dir+'/cache' + self.cwd_dir = self.base_dir+'/cwd' + modified = self.original.replace('@@@CACHE_DIRECTORY@@@', self.cache_dir) + modified = modified.replace('@@@CURRENT_WORKING_DIRECTORY@@@', self.cwd_dir) + + fp = open('sdr/dev/nodes/test_VarCache_node/DeviceManager.dcd.xml', 'w') + fp.write(modified) + fp.close() + + def tearDown(self): + fp = open('sdr/dev/nodes/test_VarCache_node/DeviceManager.dcd.xml', 'w') + fp.write(self.original) + fp.close() + + super(LoadableDeviceVariableDirectoriesTest, self).tearDown() + for file in self._testFiles: + os.unlink(file) + + shutil.rmtree(self.base_dir) + + def test_PyCompConfigCacheCWD(self): + self.assertNotEqual(self._domMgr, None) + nodebooter, devMgr = self.launchDeviceManager("/nodes/test_VarCache_node/DeviceManager.dcd.xml", domainManager=self.dom.ref) + self.assertNotEqual(devMgr, None) + app = self._rhDom.createApplication('/waveforms/check_cwd_w/check_cwd_w.sad.xml') + self.assertNotEqual(app, None) + self.assertEquals(app.comps[0].cwd, self.cwd_dir) + found_dir = False + for root, dirs, files in os.walk(self.base_dir): + if 'check_cwd.py' in files: + if 'cache/components/check_cwd/python' in root: + found_dir = True + break + self.assertEquals(found_dir, True) + + def test_CppCompConfigCacheCWD(self): + self.assertNotEqual(self._domMgr, None) + nodebooter, devMgr = self.launchDeviceManager("/nodes/test_VarCache_node/DeviceManager.dcd.xml", domainManager=self.dom.ref) + self.assertNotEqual(devMgr, None) + app = self._rhDom.createApplication('/waveforms/check_cwd_cpp_w/check_cwd_cpp_w.sad.xml') + self.assertNotEqual(app, None) + self.assertEquals(app.comps[0].cwd, self.cwd_dir) + found_dir = False + for root, dirs, files in os.walk(self.base_dir): + if 'check_cwd_cpp' in files: + if 'cache/components/check_cwd_cpp/cpp' in root: + found_dir = True + break + self.assertEquals(found_dir, True) + + def test_JavaCompConfigCacheCWD(self): + self.assertNotEqual(self._domMgr, None) + nodebooter, devMgr = self.launchDeviceManager("/nodes/test_VarCache_node/DeviceManager.dcd.xml", domainManager=self.dom.ref) + self.assertNotEqual(devMgr, None) + app = self._rhDom.createApplication('/waveforms/check_cwd_java_w/check_cwd_java_w.sad.xml') + self.assertNotEqual(app, None) + self.assertEquals(app.comps[0].cwd[:-1], self.cwd_dir) + found_dir = False + for root, dirs, files in os.walk(self.base_dir): + if 'check_cwd_java.class' in files: + if 'cache/components/check_cwd_java/java/bin/check_cwd_java/java' in root: + found_dir = True + break + self.assertEquals(found_dir, True) + +class LoadableDeviceVariableCacheDirTest(DomainSupport): + def setUp(self): + super(LoadableDeviceVariableCacheDirTest,self).setUp() + self._domainName = 'REDHAWK_TEST_'+str(os.getpid()) + self._domainBooter, self._domMgr = self.launchDomainManager(domain_name=self._domainName) + self._testFiles = [] + self._rhDom = redhawk.attach(self._domainName) + + fp = open('sdr/dev/nodes/test_VarCacheOnly_node/DeviceManager.dcd.xml', 'r') + self.original = fp.read() + fp.close() + + cwd = os.getcwd() + self.base_dir = cwd + '/LoadableDeviceVariableDirectoriesTest' + self.cache_dir = self.base_dir+'/cache' + self.cwd_dir = self.cache_dir + modified = self.original.replace('@@@CACHE_DIRECTORY@@@', self.cache_dir) + + fp = open('sdr/dev/nodes/test_VarCacheOnly_node/DeviceManager.dcd.xml', 'w') + fp.write(modified) + fp.close() + + def tearDown(self): + fp = open('sdr/dev/nodes/test_VarCacheOnly_node/DeviceManager.dcd.xml', 'w') + fp.write(self.original) + fp.close() + + super(LoadableDeviceVariableCacheDirTest, self).tearDown() + + shutil.rmtree(self.base_dir) + + def test_CompConfigCache(self): + self.assertNotEqual(self._domMgr, None) + nodebooter, devMgr = self.launchDeviceManager("/nodes/test_VarCacheOnly_node/DeviceManager.dcd.xml", domainManager=self.dom.ref) + self.assertNotEqual(devMgr, None) + app = self._rhDom.createApplication('/waveforms/check_cwd_w/check_cwd_w.sad.xml') + self.assertNotEqual(app, None) + self.assertEquals(app.comps[0].cwd, self.cwd_dir) + found_dir = False + for root, dirs, files in os.walk(self.base_dir): + if 'check_cwd.py' in files: + if 'cache/components/check_cwd/python' in root: + found_dir = True + self.assertEquals(found_dir, True) + +class LoadableDeviceVariableCWDTest(DomainSupport): + def setUp(self): + super(LoadableDeviceVariableCWDTest,self).setUp() + self._domainName = 'REDHAWK_TEST_'+str(os.getpid()) + self._domainBooter, self._domMgr = self.launchDomainManager(domain_name=self._domainName) + self._testFiles = [] + self._rhDom = redhawk.attach(self._domainName) + + fp = open('sdr/dev/nodes/test_VarCWDOnly_node/DeviceManager.dcd.xml', 'r') + self.original = fp.read() + fp.close() + + cwd = os.getcwd() + self.base_dir = cwd + '/LoadableDeviceVariableDirectoriesTest' + self.cwd_dir = self.base_dir+'/cwd' + modified = self.original.replace('@@@CURRENT_WORKING_DIRECTORY@@@', self.cwd_dir) + + fp = open('sdr/dev/nodes/test_VarCWDOnly_node/DeviceManager.dcd.xml', 'w') + fp.write(modified) + fp.close() + + def tearDown(self): + fp = open('sdr/dev/nodes/test_VarCWDOnly_node/DeviceManager.dcd.xml', 'w') + fp.write(self.original) + fp.close() + + super(LoadableDeviceVariableCWDTest, self).tearDown() + + shutil.rmtree(self.base_dir) + + def test_CompConfigCWD(self): + self.assertNotEqual(self._domMgr, None) + nodebooter, devMgr = self.launchDeviceManager("/nodes/test_VarCWDOnly_node/DeviceManager.dcd.xml", domainManager=self.dom.ref) + self.assertNotEqual(devMgr, None) + app = self._rhDom.createApplication('/waveforms/check_cwd_w/check_cwd_w.sad.xml') + self.assertNotEqual(app, None) + self.assertEquals(app.comps[0].cwd, self.cwd_dir) + found_dir = False + for root, dirs, files in os.walk(self.base_dir): + if 'check_cwd.py' in files: + if 'cwd/components/check_cwd/python' in root: + found_dir = True + self.assertEquals(found_dir, True) + # TODO Add additional tests here # diff --git a/redhawk/src/base/framework/ExecutableDevice_impl.cpp b/redhawk/src/base/framework/ExecutableDevice_impl.cpp index 46ff68166..bc8a65274 100644 --- a/redhawk/src/base/framework/ExecutableDevice_impl.cpp +++ b/redhawk/src/base/framework/ExecutableDevice_impl.cpp @@ -219,6 +219,8 @@ CF::ExecutableDevice::ProcessID_Type ExecutableDevice_impl::do_execute (const ch CF::Properties invalidOptions; std::string path; char* tmp; + + std::string mod_localPath = prependCacheIfAvailable(name); // throw and error if name does not begin with a / if (strncmp(name, "/", 1) != 0) diff --git a/redhawk/src/base/framework/LoadableDevice_impl.cpp b/redhawk/src/base/framework/LoadableDevice_impl.cpp index 33f81e5ed..1cf29e4b9 100644 --- a/redhawk/src/base/framework/LoadableDevice_impl.cpp +++ b/redhawk/src/base/framework/LoadableDevice_impl.cpp @@ -362,8 +362,22 @@ throw (CORBA::SystemException, CF::Device::InvalidState, // The target file is a file LOG_DEBUG(LoadableDevice_impl, "Loading the file " << fileName); + std::fstream fileStream; + std::ios_base::openmode mode; + mode = std::ios::out; + std::string _relativeFileName = workingFileName; + if (workingFileName[0] == '/') { + _relativeFileName = workingFileName.substr(1); + } + relativeFileName = prependCacheIfAvailable(_relativeFileName); + // Create a local directory to copy the file to - fs::path parentDir = fs::path(workingFileName).parent_path().relative_path(); + fs::path parentDir; + if (relativeFileName == _relativeFileName) { + parentDir = fs::path(relativeFileName).parent_path().relative_path(); + } else { + parentDir = fs::path(relativeFileName).parent_path(); + } try { if ( !parentDir.string().empty() && fs::create_directories(parentDir)) { LOG_DEBUG(LoadableDevice_impl, "Created parent directory " << parentDir.string()); @@ -375,13 +389,6 @@ throw (CORBA::SystemException, CF::Device::InvalidState, // copy the file LOG_DEBUG(LoadableDevice_impl, "Copying " << workingFileName << " to the device's cache") - std::fstream fileStream; - std::ios_base::openmode mode; - mode = std::ios::out; - relativeFileName = workingFileName; - if (workingFileName[0] == '/') { - relativeFileName = workingFileName.substr(1); - } fileStream.open(relativeFileName.c_str(), mode); bool text_file_busy = false; if (!fileStream.is_open()) { @@ -580,12 +587,13 @@ void LoadableDevice_impl::_loadTree(CF::FileSystem_ptr fs, std::string remotePat { LOG_DEBUG(LoadableDevice_impl, "_loadTree " << remotePath << " " << localPath) + fs::path mod_localPath = prependCacheIfAvailable(localPath.string()); CF::FileSystem::FileInformationSequence_var fis = fs->list(remotePath.c_str()); for (unsigned int i = 0; i < fis->length(); i++) { if (fis[i].kind == CF::FileSystem::PLAIN) { std::string fileName(fis[i].name); - fs::path localFile(localPath / fileName); + fs::path localFile(mod_localPath / fileName); if (*(remotePath.end() - 1) == '/') { LOG_DEBUG(LoadableDevice_impl, "_copyFile " << remotePath + fileName << " " << localFile) _copyFile(fs, remotePath + fileName, localFile.string(), fileKey); @@ -601,8 +609,8 @@ void LoadableDevice_impl::_loadTree(CF::FileSystem_ptr fs, std::string remotePat } } else if (fis[i].kind == CF::FileSystem::DIRECTORY) { std::string directoryName(fis[i].name); - fs::path localDirectory(localPath / directoryName); - LOG_DEBUG(LoadableDevice_impl, "Making directory " << directoryName << " in " << localPath) + fs::path localDirectory(mod_localPath / directoryName); + LOG_DEBUG(LoadableDevice_impl, "Making directory " << directoryName << " in " << mod_localPath) copiedFiles.insert(copiedFiles_type::value_type(fileKey, localDirectory.string())); bool dexists = false; try { @@ -617,7 +625,7 @@ void LoadableDevice_impl::_loadTree(CF::FileSystem_ptr fs, std::string remotePat } if (*(remotePath.end() - 1) == '/') { LOG_DEBUG(LoadableDevice_impl, "There") - _loadTree(fs, remotePath + std::string("/") + directoryName, localPath, fileKey); + _loadTree(fs, remotePath + std::string("/") + directoryName, mod_localPath, fileKey); } else { LOG_DEBUG(LoadableDevice_impl, "Here") _loadTree(fs, remotePath + std::string("/"), localDirectory, fileKey); @@ -670,8 +678,26 @@ bool LoadableDevice_impl::_treeIntact(const std::string &fileKey) return true; } +std::string LoadableDevice_impl::prependCacheIfAvailable(const std::string &localPath) { + std::string mod_localPath = localPath; + if (this->getPropertyFromId("cacheDirectory")) { + std::string cache_dir = ((StringProperty*)this->getPropertyFromId("cacheDirectory"))->getValue(); + if (!cache_dir.empty()) { + if (localPath.find(cache_dir) == std::string::npos) { + if (!cache_dir.compare(cache_dir.length()-1, 1, "/")) { + mod_localPath = cache_dir + mod_localPath; + } else { + mod_localPath = cache_dir + std::string("/") + mod_localPath; + } + } + } + } + return mod_localPath; +} + void LoadableDevice_impl::_copyFile(CF::FileSystem_ptr fs, const std::string &remotePath, const std::string &localPath, const std::string &fileKey) { + std::string mod_localPath(prependCacheIfAvailable(localPath)); CF::File_var fileToLoad = CF::File::_nil(); try { fileToLoad= fs->open(remotePath.c_str(), true); @@ -700,14 +726,14 @@ void LoadableDevice_impl::_copyFile(CF::FileSystem_ptr fs, const std::string &re std::fstream fileStream; std::ios_base::openmode mode; mode = std::ios::out | std::ios::trunc; - fileStream.open(localPath.c_str(), mode); + fileStream.open(mod_localPath.c_str(), mode); if (!fileStream.is_open()) { - LOG_ERROR(LoadableDevice_impl, "Local file " << localPath << " did not open succesfully.") + LOG_ERROR(LoadableDevice_impl, "Local file " << mod_localPath << " did not open succesfully.") } else { - LOG_DEBUG(LoadableDevice_impl, "Local file " << localPath << " opened succesfully.") + LOG_DEBUG(LoadableDevice_impl, "Local file " << mod_localPath << " opened succesfully.") } - copiedFiles.insert(copiedFiles_type::value_type(fileKey, localPath)); + copiedFiles.insert(copiedFiles_type::value_type(fileKey, mod_localPath)); std::size_t fileSize = fileToLoad->sizeOf(); bool fe=false; @@ -717,7 +743,7 @@ void LoadableDevice_impl::_copyFile(CF::FileSystem_ptr fs, const std::string &re toRead = std::min(fileSize, blockTransferSize); fileSize -= toRead; - //LOG_TRACE(LoadableDevice_impl, "READ Local file " << localPath << " length:" << toRead << " filesize/bts " << fileSize << "/" << blockTransferSize ); + //LOG_TRACE(LoadableDevice_impl, "READ Local file " << mod_localPath << " length:" << toRead << " filesize/bts " << fileSize << "/" << blockTransferSize ); try { fileToLoad->read(data, toRead); fileStream.write((const char*)data->get_buffer(), data->length()); diff --git a/redhawk/src/base/include/ossie/LoadableDevice_impl.h b/redhawk/src/base/include/ossie/LoadableDevice_impl.h index 57f104321..38ba03f74 100644 --- a/redhawk/src/base/include/ossie/LoadableDevice_impl.h +++ b/redhawk/src/base/include/ossie/LoadableDevice_impl.h @@ -226,6 +226,7 @@ class LoadableDevice_impl: void update_selected_paths(std::vector &paths); // Transfer size when loading files CORBA::LongLong transferSize; // block transfer size when loading files + std::string prependCacheIfAvailable(const std::string &localPath); private: LoadableDevice_impl(); // No default constructor @@ -238,9 +239,6 @@ class LoadableDevice_impl: void _deleteTree(const std::string &fileKey); bool _treeIntact(const std::string &fileKey); void _copyFile(CF::FileSystem_ptr fs, const std::string &remotePath, const std::string &localPath, const std::string &fileKey); - - - }; #endif diff --git a/redhawk/src/control/sdr/devmgr/DeviceManager_impl.cpp b/redhawk/src/control/sdr/devmgr/DeviceManager_impl.cpp index 08786d5f9..7ea4300eb 100644 --- a/redhawk/src/control/sdr/devmgr/DeviceManager_impl.cpp +++ b/redhawk/src/control/sdr/devmgr/DeviceManager_impl.cpp @@ -671,26 +671,44 @@ bool DeviceManager_impl::getDeviceOrService( void DeviceManager_impl::createDeviceCacheLocation( std::string& devcache, + std::string& devcwd, std::string& usageName, - const ossie::ComponentInstantiation& instantiation) + const ossie::ComponentInstantiation& instantiation, + std::string spdFile) { - // No log messages within this method as it is called between exec and fork - - // create device cache location - std::string baseDevCache = _cacheroot + "/." + _label; if (instantiation.getUsageName() == 0) { // no usage name was given, so create one. By definition, the instantiation id must be unique usageName = instantiation.instantiationId; } else { usageName = instantiation.getUsageName(); } + + cacheAndCwdStruct cacheCwd = getOverloadCacheAndCwd(spdFile, instantiation); + + if (cacheCwd.cache.empty()) { + std::string baseDevCache = _cacheroot + "/." + _label; + devcache = baseDevCache + "/" + usageName; + } else { + devcache = cacheCwd.cache; + } + + devcwd = cacheCwd.cwd; - devcache = baseDevCache + "/" + usageName; + // create device cache location bool retval = this->makeDirectory(devcache); if (not retval) { LOG_ERROR(DeviceManager_impl, "Unable to create the Device cache: " << devcache) exit(-1); } + + // create device cwd location if needed + if (not devcwd.empty()) { + retval = this->makeDirectory(devcwd); + if (not retval) { + LOG_ERROR(DeviceManager_impl, "Unable to create the Device working directory: " << devcwd) + exit(-1); + } + } } /* @@ -709,9 +727,6 @@ void DeviceManager_impl::createDeviceExecStatement( const std::vector& componentPlacements, const std::string& compositeDeviceIOR, const ossie::ComponentPropertyList& instanceprops) { - - // DO not put any LOG calls in this method, as it is called beteen - // fork() and execv(). ossie::ComponentPropertyList::const_iterator iprops_iter; @@ -954,8 +969,9 @@ void DeviceManager_impl::createDeviceThreadAndHandleExceptions( try { std::string devcache; - std::string usageName; - createDeviceCacheLocation(devcache, usageName, instantiation); + std::string devcwd; + std::string usageName; + createDeviceCacheLocation(devcache, devcwd, usageName, instantiation, SPDParser.getSPDFile()); createDeviceThread(componentPlacement, componentType, pOverloadprops, @@ -964,6 +980,7 @@ void DeviceManager_impl::createDeviceThreadAndHandleExceptions( DCDParser, instantiation, devcache, + devcwd, usageName, componentPlacements, compositeDeviceIOR, @@ -996,6 +1013,7 @@ void DeviceManager_impl::createDeviceThread( ossie::DeviceManagerConfiguration& DCDParser, const ossie::ComponentInstantiation& instantiation, const std::string& devcache, + const std::string& devcwd, const std::string& usageName, const std::vector& componentPlacements, const std::string& compositeDeviceIOR, @@ -1152,7 +1170,14 @@ void DeviceManager_impl::createDeviceThread( ////////////////////////////////////////////////////////////// // switch to working directory - chdir(devcache.c_str()); + if (not devcwd.empty()) { + int retval = chdir(devcwd.c_str()); + if (retval) { + LOG_ERROR(DeviceManager_impl, "Unable to change the current working directory to : " << devcwd); + } + } else { + chdir(devcache.c_str()); + } // honor affinity requests try { @@ -1858,6 +1883,92 @@ DeviceManager_impl::registeredServices ()throw (CORBA::SystemException) } +DeviceManager_impl::cacheAndCwdStruct DeviceManager_impl::getOverloadCacheAndCwd(std::string spdFile, const ossie::ComponentInstantiation& instantiation) +{ + ossie::SpdSupport::ResourceInfo spdinfo = this->buildSpdinfo(spdFile, instantiation.instantiationId); + const CF::Properties cprops = spdinfo.getNonNilConstructProperties(); + redhawk::PropertyMap tmpProps = redhawk::PropertyMap::cast(cprops); + cacheAndCwdStruct cacheCwd; + if (tmpProps.find("cacheDirectory")!=tmpProps.end()) { + cacheCwd.cache = tmpProps["cacheDirectory"].toString(); + } + if (tmpProps.find("workingDirectory")!=tmpProps.end()) { + cacheCwd.cwd = tmpProps["workingDirectory"].toString(); + } + return cacheCwd; +} + +ossie::SpdSupport::ResourceInfo DeviceManager_impl::buildSpdinfo(std::string spdFile, std::string device_id) +{ + ossie::SpdSupport::ResourceInfo spdinfo; + try { + ossie::SpdSupport::ResourceInfo::LoadResource(this->_fileSys, spdFile.c_str(), spdinfo); + } + catch(...) { + std::ostringstream eout; + eout << "Loading Device's SPD failed, device:" << device_id; + LOG_ERROR(DeviceManager_impl, eout.str()); + throw(CF::InvalidObjectReference(eout.str().c_str())); + } + std::string spd_name = spdinfo.getName(); + std::string spd_id = spdinfo.getID(); + LOG_INFO(DeviceManager_impl, "Device ID: " << device_id << " SPD loaded: " << spd_name << "' - '" << spd_id ); + + CF::Properties componentProperties; + DeviceManagerConfiguration DCDParser; + try { + File_stream _dcd(this->_fileSys, _deviceConfigurationProfile.c_str()); + DCDParser.load(_dcd); + _dcd.close(); + } catch ( std::exception& ex ) { + std::ostringstream eout; + eout << "The following standard exception occurred: "<label()) << " on Device Manager " << _label); - - CORBA::String_var deviceLabel = registeringDevice->label(); + std::string deviceLabel = ossie::corba::returnString(registeringDevice->label()); + std::string device_id = ossie::corba::returnString(registeringDevice->identifier()); + LOG_INFO(DeviceManager_impl, "Registering device " << deviceLabel << " on Device Manager " << _label); if ( deviceIsRegistered( registeringDevice ) == true ) { std::ostringstream eout; @@ -1900,74 +2011,7 @@ throw (CORBA::SystemException, CF::InvalidObjectReference) // Open the SPD file using the SCA FileSystem LOG_TRACE(DeviceManager_impl, "Building Device Info From SPD File"); - ossie::SpdSupport::ResourceInfo spdinfo; - try { - ossie::SpdSupport::ResourceInfo::LoadResource(_fileSys, spdFile.c_str(), spdinfo); - } - catch(...) { - std::ostringstream eout; - eout << "Loading Device's SPD failed, device:" << ossie::corba::returnString(registeringDevice->label()); - LOG_ERROR(DeviceManager_impl, eout.str()); - throw(CF::InvalidObjectReference(eout.str().c_str())); - } - std::string spd_name = spdinfo.getName(); - std::string spd_id = spdinfo.getID(); - LOG_INFO(DeviceManager_impl, "Device LABEL: " << deviceLabel << " SPD loaded: " << spd_name << "' - '" << spd_id ); - - CF::Properties componentProperties; - DeviceManagerConfiguration DCDParser; - try { - File_stream _dcd(_fileSys, _deviceConfigurationProfile.c_str()); - DCDParser.load(_dcd); - _dcd.close(); - } catch ( std::exception& ex ) { - std::ostringstream eout; - eout << "The following standard exception occurred: "<identifier()); - try { - const ComponentInstantiation& instantiation = DCDParser.getComponentInstantiationById(deviceid); - if (instantiation.getUsageName() != NULL) - std::string tmp_name = instantiation.getUsageName(); // this is here to get rid of a warning - } catch (std::out_of_range& e) { - std::ostringstream eout; - eout << "[DeviceManager::registerDevice] Failed to parse DCD"; - LOG_ERROR(DeviceManager_impl, eout.str()); - throw(CF::InvalidObjectReference(eout.str().c_str())); - } catch ( std::exception& ex ) { - std::ostringstream eout; - eout << "The following standard exception occurred: "<buildSpdinfo(spdFile, device_id); // // call resource's initializeProperties method to handle any properties required for construction @@ -1975,7 +2019,7 @@ throw (CORBA::SystemException, CF::InvalidObjectReference) if (spdinfo.isConfigurable ()) { try { // - LOG_DEBUG(DeviceManager_impl, "Initialize properties for spd/device label: " << spd_name << "/" << deviceLabel); + LOG_DEBUG(DeviceManager_impl, "Initialize properties for spd/device label: " << spdinfo.getName() << "/" << deviceLabel); const CF::Properties cprops = spdinfo.getNonNilConstructProperties(); for (unsigned int j = 0; j < cprops.length (); j++) { LOG_DEBUG(DeviceManager_impl, "initializeProperties prop id " << cprops[j].id ); @@ -1984,13 +2028,13 @@ throw (CORBA::SystemException, CF::InvalidObjectReference) registeringDevice->initializeProperties(cprops); } catch(CF::PropertySet::InvalidConfiguration& e) { std::ostringstream eout; - eout << "Device '" << deviceLabel << "' - '" << spd_id << "' may not have been initialized correctly; " + eout << "Device '" << deviceLabel << "' - '" << spdinfo.getID() << "' may not have been initialized correctly; " << "Call to initializeProperties() resulted in InvalidConfiguration exception. Device registration with Device Manager failed"; LOG_ERROR(DeviceManager_impl, eout.str()); throw(CF::InvalidObjectReference(eout.str().c_str())); } catch(CF::PropertySet::PartialConfiguration& e) { std::ostringstream eout; - eout << "Device '" << deviceLabel << "' - '" << spd_id << "' may not have been configured correctly; " + eout << "Device '" << deviceLabel << "' - '" << spdinfo.getID() << "' may not have been configured correctly; " << "Call to initializeProperties() resulted in PartialConfiguration exception."; LOG_ERROR(DeviceManager_impl, eout.str()); throw(CF::InvalidObjectReference(eout.str().c_str())); @@ -2007,7 +2051,7 @@ throw (CORBA::SystemException, CF::InvalidObjectReference) } catch( ... ) { std::ostringstream eout; eout << "Failed to initialize device properties: '"; - eout << deviceLabel << "' with device id: '" << spd_id; + eout << deviceLabel << "' with device id: '" << spdinfo.getID(); eout << "'initializeProperties' failed with Unknown Exception" << "Device registration with Device Manager failed "; LOG_ERROR(DeviceManager_impl, eout.str()); throw(CF::InvalidObjectReference(eout.str().c_str())); @@ -2046,13 +2090,13 @@ throw (CORBA::SystemException, CF::InvalidObjectReference) registeringDevice->configure (cprops); } catch (CF::PropertySet::PartialConfiguration& ex) { std::ostringstream eout; - eout << "Device '" << deviceLabel << "' - '" << spd_id << "' may not have been configured correctly; " + eout << "Device '" << deviceLabel << "' - '" << spdinfo.getID() << "' may not have been configured correctly; " << "Call to configure() resulted in PartialConfiguration exception."; LOG_ERROR(DeviceManager_impl, eout.str()) throw(CF::InvalidObjectReference(eout.str().c_str())); } catch (CF::PropertySet::InvalidConfiguration& ex) { std::ostringstream eout; - eout << "Device '" << deviceLabel << "' - '" << spd_id << "' may not have been configured correctly; " + eout << "Device '" << deviceLabel << "' - '" << spdinfo.getID() << "' may not have been configured correctly; " << "Call to configure() resulted in InvalidConfiguration exception. Device registration with Device Manager failed"; LOG_ERROR(DeviceManager_impl, eout.str()); throw(CF::InvalidObjectReference(eout.str().c_str())); @@ -2073,7 +2117,7 @@ throw (CORBA::SystemException, CF::InvalidObjectReference) if (!deviceIsRegistered (registeringDevice)) { // if the device is not registered, then add it to the naming context LOG_TRACE(DeviceManager_impl, "Binding device to name " << deviceLabel) - CosNaming::Name_var device_name = ossie::corba::stringToName(static_cast(deviceLabel)); + CosNaming::Name_var device_name = ossie::corba::stringToName(deviceLabel.c_str()); try { devMgrContext->bind(device_name, registeringDevice); } catch ( ... ) { @@ -2114,8 +2158,6 @@ throw (CORBA::SystemException, CF::InvalidObjectReference) } - - //This function returns TRUE if the input serviceName is contained in the _registeredServices list attribute bool DeviceManager_impl::serviceIsRegistered (const char* serviceName) { diff --git a/redhawk/src/control/sdr/devmgr/DeviceManager_impl.h b/redhawk/src/control/sdr/devmgr/DeviceManager_impl.h index dca34ae9a..4da871dc0 100644 --- a/redhawk/src/control/sdr/devmgr/DeviceManager_impl.h +++ b/redhawk/src/control/sdr/devmgr/DeviceManager_impl.h @@ -38,6 +38,7 @@ #include #include #include +#include "spdSupport.h" #include #include @@ -163,6 +164,15 @@ class DeviceManager_impl: CF::FileSystem_var _fileSys; CF::DeviceManager_var myObj; bool checkWriteAccess(std::string &path); + + struct cacheAndCwdStruct{ + std::string cache; + std::string cwd; + }; + + cacheAndCwdStruct getOverloadCacheAndCwd(std::string profile, const ossie::ComponentInstantiation& instantiation); + + ossie::SpdSupport::ResourceInfo buildSpdinfo(std::string spdFile, std::string device_id); enum DevMgrAdmnType { DEVMGR_REGISTERED, @@ -251,8 +261,10 @@ class DeviceManager_impl: void createDeviceCacheLocation( std::string& devcache, + std::string& devcwd, std::string& usageName, - const ossie::ComponentInstantiation& instantiation); + const ossie::ComponentInstantiation& instantiation, + std::string spdFile); void createDeviceExecStatement( std::vector< std::string >& new_argv, @@ -288,6 +300,7 @@ class DeviceManager_impl: ossie::DeviceManagerConfiguration& DCDParser, const ossie::ComponentInstantiation& instantiation, const std::string& devcache, + const std::string& devcwd, const std::string& usageName, const std::vector& componentPlacements, const std::string& compositeDeviceIOR, From 2a361f6cec8b720fd361e4ede0c6a0e38488120a Mon Sep 17 00:00:00 2001 From: Max Robert Date: Sat, 19 Nov 2016 10:16:46 -0500 Subject: [PATCH 0549/1644] Refs CF-884. Testing files --- .../dom/components/check_cwd_java/build.sh | 48 +++++++++++++++++++ .../check_cwd_java/java/configure.ac | 17 +++++++ .../dom/components/check_cwd_java/java/reconf | 6 +++ 3 files changed, 71 insertions(+) create mode 100755 GPP/tests/sdr/dom/components/check_cwd_java/build.sh create mode 100644 GPP/tests/sdr/dom/components/check_cwd_java/java/configure.ac create mode 100755 GPP/tests/sdr/dom/components/check_cwd_java/java/reconf diff --git a/GPP/tests/sdr/dom/components/check_cwd_java/build.sh b/GPP/tests/sdr/dom/components/check_cwd_java/build.sh new file mode 100755 index 000000000..b32ccf78d --- /dev/null +++ b/GPP/tests/sdr/dom/components/check_cwd_java/build.sh @@ -0,0 +1,48 @@ +#!/bin/bash + +if [ "$1" = "rpm" ]; then + # A very simplistic RPM build scenario + if [ -e check_cwd_java.spec ]; then + mydir=`dirname $0` + tmpdir=`mktemp -d` + cp -r ${mydir} ${tmpdir}/check_cwd_java-1.0.0 + tar czf ${tmpdir}/check_cwd_java-1.0.0.tar.gz --exclude=".svn" --exclude=".git" -C ${tmpdir} check_cwd_java-1.0.0 + rpmbuild -ta ${tmpdir}/check_cwd_java-1.0.0.tar.gz + rm -rf $tmpdir + else + echo "Missing RPM spec file in" `pwd` + exit 1 + fi +else + for impl in java ; do + if [ ! -d "$impl" ]; then + echo "Directory '$impl' does not exist...continuing" + continue + fi + cd $impl + if [ -e build.sh ]; then + if [ $# == 1 ]; then + if [ $1 == 'clean' ]; then + rm -f Makefile + rm -f config.* + ./build.sh distclean + else + ./build.sh $* + fi + else + ./build.sh $* + fi + elif [ -e Makefile ] && [ Makefile.am -ot Makefile ]; then + make $* + elif [ -e reconf ]; then + ./reconf && ./configure && make $* + else + echo "No build.sh found for $impl" + fi + retval=$? + if [ $retval != '0' ]; then + exit $retval + fi + cd - + done +fi diff --git a/GPP/tests/sdr/dom/components/check_cwd_java/java/configure.ac b/GPP/tests/sdr/dom/components/check_cwd_java/java/configure.ac new file mode 100644 index 000000000..a5ede76da --- /dev/null +++ b/GPP/tests/sdr/dom/components/check_cwd_java/java/configure.ac @@ -0,0 +1,17 @@ +AC_INIT(check_cwd_java, 1.0.0) +AM_INIT_AUTOMAKE([nostdinc foreign]) +AC_CONFIG_MACRO_DIR([m4]) + +OSSIE_CHECK_OSSIE +OSSIE_SDRROOT_AS_PREFIX + +PKG_CHECK_MODULES([OSSIE], [ossie >= 2.1]) + +RH_JAVA_HOME +RH_PROG_JAVAC([1.6]) +RH_PROG_JAR + +RH_PKG_CLASSPATH([REDHAWK], [ossie]) + +AC_CONFIG_FILES([Makefile]) +AC_OUTPUT diff --git a/GPP/tests/sdr/dom/components/check_cwd_java/java/reconf b/GPP/tests/sdr/dom/components/check_cwd_java/java/reconf new file mode 100755 index 000000000..8ff01d431 --- /dev/null +++ b/GPP/tests/sdr/dom/components/check_cwd_java/java/reconf @@ -0,0 +1,6 @@ +#!/bin/sh + +rm -f config.cache +[ -d m4 ] || mkdir m4 +autoreconf -i + From aa5d546ca16497ab87c48265f5a3e2b300881538 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 18 Nov 2016 14:33:30 -0500 Subject: [PATCH 0550/1644] Remove extra constructor in base C++ BulkIO output port --- .../libsrc/cpp/bulkio_out_port.cpp | 29 ++----------------- bulkioInterfaces/libsrc/cpp/bulkio_out_port.h | 5 +--- 2 files changed, 4 insertions(+), 30 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp index 8b7489fb9..b45de30a4 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp @@ -67,29 +67,6 @@ namespace bulkio { } - - template < typename PortTraits > - OutPortBase< PortTraits >::OutPortBase(std::string port_name, - ConnectionEventListener *connectCB, - ConnectionEventListener *disconnectCB ) : - UsesPort(port_name) - { - - std::string pname("redhawk.bulkio.outport."); - pname = pname + port_name; - setLogger(rh_logger::Logger::getLogger(pname)); - if ( connectCB ) { - _connectCB = boost::shared_ptr< ConnectionEventListener >( connectCB, null_deleter() ); - } - addConnectListener(this, &OutPortBase::_connectListenerAdapter); - - if ( disconnectCB ) { - _disconnectCB = boost::shared_ptr< ConnectionEventListener >( disconnectCB, null_deleter() ); - } - addDisconnectListener(this, &OutPortBase::_disconnectListenerAdapter); - - } - template < typename PortTraits > OutPortBase< PortTraits >::~OutPortBase(){ @@ -455,7 +432,7 @@ namespace bulkio { OutPort< PortTraits >::OutPort(std::string port_name, ConnectionEventListener *connectCB, ConnectionEventListener *disconnectCB ) : - OutPortBase(port_name) + OutPortBase(port_name, LOGGER_PTR(), connectCB, disconnectCB) { } @@ -634,7 +611,7 @@ namespace bulkio { OutFilePort::OutFilePort ( std::string name, ConnectionEventListener *connectCB, ConnectionEventListener *disconnectCB ) : - OutPortBase < FilePortTraits >(name,connectCB, disconnectCB ) + OutPortBase < FilePortTraits >(name, LOGGER_PTR(), connectCB, disconnectCB ) { } @@ -673,7 +650,7 @@ namespace bulkio { OutXMLPort::OutXMLPort ( std::string name, ConnectionEventListener *connectCB, ConnectionEventListener *disconnectCB ) : - OutPortBase < XMLPortTraits >(name,connectCB, disconnectCB ) + OutPortBase < XMLPortTraits >(name, LOGGER_PTR(), connectCB, disconnectCB ) { } diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h index 4a1118c6a..a49deea81 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h @@ -127,13 +127,10 @@ namespace bulkio { // OutPortBase Creates a uses port object for publishing data to the framework // // @param port_name name assigned to the port located in scd.xml file + // @param logger logger to receive port logging output // @param connectionCB callback that will be called when the connectPort method is called // @pararm disconnectDB callback that receives notification when a disconnectPort happens // - OutPortBase(std::string port_name, - ConnectionEventListener *connectCB=NULL, - ConnectionEventListener *disconnectCB=NULL ); - OutPortBase(std::string port_name, LOGGER_PTR logger, ConnectionEventListener *connectCB=NULL, From 80f5b5c6744e2b63cce7bee94c110774d419670d Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 18 Nov 2016 14:51:05 -0500 Subject: [PATCH 0551/1644] Remove unused member --- bulkioInterfaces/libsrc/cpp/bulkio_out_port.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h index a49deea81..707dba342 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h @@ -259,11 +259,6 @@ namespace bulkio { OutPortSriMap currentSRIs __attribute__ ((deprecated)); protected: - // - // - // - bool recConnectionsRefresh; - // // Lookup table for connections to input ports in the same process space // From 84b412a4fbcf9e0d70114da8a1215e2ff4ada12c Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 22 Nov 2016 16:49:31 -0500 Subject: [PATCH 0552/1644] Slightly rearrange BulkIO transport classes to make top-level push calls non-virtual --- .../libsrc/cpp/bulkio_connection.hpp | 88 +++++++++++-------- 1 file changed, 52 insertions(+), 36 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp b/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp index c421f00ff..8aa053ec8 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp @@ -19,16 +19,18 @@ namespace bulkio { virtual ~PortTransport() { }; - virtual void pushSRI(const BULKIO::StreamSRI& sri) = 0; + void pushSRI(const BULKIO::StreamSRI& sri) + { + this->_pushSRI(sri); + } - virtual void pushPacket(const SharedBufferType& data, - const BULKIO::PrecisionUTCTime& T, - bool EOS, - const BULKIO::StreamSRI& sri) + void pushPacket(const SharedBufferType& data, + const BULKIO::PrecisionUTCTime& T, + bool EOS, + const BULKIO::StreamSRI& sri) { const std::string streamID(sri.streamID); - this->_pushPacket(data, T, EOS, streamID); - stats.update(this->_dataLength(data), 0, EOS, streamID); + this->_sendPacket(data, T, EOS, streamID, sri); } // @@ -53,6 +55,18 @@ namespace bulkio { linkStatistics stats; protected: + virtual void _pushSRI(const BULKIO::StreamSRI& sri) = 0; + + virtual void _sendPacket(const SharedBufferType& data, + const BULKIO::PrecisionUTCTime& T, + bool EOS, + const std::string& streamID, + const BULKIO::StreamSRI& sri) + { + this->_pushPacket(data, T, EOS, streamID); + stats.update(this->_dataLength(data), 0, EOS, streamID); + } + virtual void _pushPacket(const SharedBufferType& data, const BULKIO::PrecisionUTCTime& T, bool EOS, @@ -92,7 +106,8 @@ namespace bulkio { { } - virtual void pushSRI(const BULKIO::StreamSRI& sri) + protected: + virtual void _pushSRI(const BULKIO::StreamSRI& sri) { try { this->_port->pushSRI(sri); @@ -101,46 +116,46 @@ namespace bulkio { } } - virtual void pushPacket(const SharedBufferType& data, - const BULKIO::PrecisionUTCTime& T, - bool EOS, - const BULKIO::StreamSRI& sri) + virtual void _pushPacket(const SharedBufferType& data, + const BULKIO::PrecisionUTCTime& T, + bool EOS, + const std::string& streamID) { try { - PortTransport::pushPacket(data, T, EOS, sri); + _pushPacketImpl(data, T, EOS, streamID.c_str()); } catch (const CORBA::SystemException& exc) { throw redhawk::FatalTransportError(ossie::corba::describeException(exc)); } } - protected: - virtual void _pushPacket(const SharedBufferType& data, - const BULKIO::PrecisionUTCTime& T, - bool EOS, - const std::string& streamID) + private: + void _pushPacketImpl(const SharedBufferType& data, + const BULKIO::PrecisionUTCTime& T, + bool EOS, + const char* streamID) { const TransportType* ptr = reinterpret_cast(data.data()); const PortSequenceType buffer(data.size(), data.size(), const_cast(ptr), false); - this->_port->pushPacket(buffer, T, EOS, streamID.c_str()); + this->_port->pushPacket(buffer, T, EOS, streamID); } }; template <> - void RemoteTransport::_pushPacket(const std::string& data, - const BULKIO::PrecisionUTCTime& T, - bool EOS, - const std::string& streamID) + void RemoteTransport::_pushPacketImpl(const std::string& data, + const BULKIO::PrecisionUTCTime& T, + bool EOS, + const char* streamID) { - _port->pushPacket(data.c_str(), T, EOS, streamID.c_str()); + _port->pushPacket(data.c_str(), T, EOS, streamID); } template <> - void RemoteTransport::_pushPacket(const std::string& data, - const BULKIO::PrecisionUTCTime& /* unused */, - bool EOS, - const std::string& streamID) + void RemoteTransport::_pushPacketImpl(const std::string& data, + const BULKIO::PrecisionUTCTime& /* unused */, + bool EOS, + const char* streamID) { - _port->pushPacket(data.c_str(), EOS, streamID.c_str()); + _port->pushPacket(data.c_str(), EOS, streamID); } template @@ -166,10 +181,11 @@ namespace bulkio { * calls. The EOS is set to false for all of the sub-packets, except for * the last sub-packet, which uses the input EOS argument. */ - virtual void pushPacket(const SharedBufferType& data, - const BULKIO::PrecisionUTCTime& T, - bool EOS, - const BULKIO::StreamSRI& sri) + virtual void _sendPacket(const SharedBufferType& data, + const BULKIO::PrecisionUTCTime& T, + bool EOS, + const std::string& streamID, + const BULKIO::StreamSRI& sri) { double xdelta = sri.xdelta; size_t itemSize = sri.mode?2:1; @@ -204,7 +220,7 @@ namespace bulkio { // Take the next slice of the input buffer. SharedBufferType subPacket = data.slice(first, first + pushSize); - RemoteTransport::pushPacket(subPacket, packetTime, packetEOS, sri); + RemoteTransport::_sendPacket(subPacket, packetTime, packetEOS, streamID, sri); // Synthesize the next packet timestamp if (packetTime.tcstatus == BULKIO::TCS_VALID) { @@ -243,12 +259,12 @@ namespace bulkio { _localPort->_remove_ref(); } - virtual void pushSRI(const BULKIO::StreamSRI& sri) + protected: + virtual void _pushSRI(const BULKIO::StreamSRI& sri) { _localPort->pushSRI(sri); } - protected: virtual void _pushPacket(const SharedBufferType& data, const BULKIO::PrecisionUTCTime& T, bool EOS, From bebc1d6aac8b096eee65fac3144264a61400d2e6 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 23 Nov 2016 09:04:08 -0500 Subject: [PATCH 0553/1644] Track active streams in the BulkIO transport objects and use that to send EOS on disconnect; pass the stream ID as an additional argument to pushSRI/pushPacket methods to reduce creation of temporary strings --- .../libsrc/cpp/bulkio_connection.hpp | 28 ++++++++------- .../libsrc/cpp/bulkio_out_port.cpp | 34 ++----------------- bulkioInterfaces/libsrc/cpp/bulkio_out_port.h | 2 -- 3 files changed, 19 insertions(+), 45 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp b/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp index 8aa053ec8..063eb2f63 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp @@ -19,28 +19,31 @@ namespace bulkio { virtual ~PortTransport() { }; - void pushSRI(const BULKIO::StreamSRI& sri) + virtual void disconnect() { + // Send an end-of-stream for all active streams + for (std::set::iterator stream = _streams.begin(); stream != _streams.end(); ++stream) { + this->_pushPacket(SharedBufferType(), bulkio::time::utils::notSet(), true, *stream); + } + _streams.clear(); + } + + void pushSRI(const std::string& streamID, const BULKIO::StreamSRI& sri) + { + _streams.insert(streamID); this->_pushSRI(sri); } void pushPacket(const SharedBufferType& data, const BULKIO::PrecisionUTCTime& T, bool EOS, + const std::string& streamID, const BULKIO::StreamSRI& sri) { - const std::string streamID(sri.streamID); this->_sendPacket(data, T, EOS, streamID, sri); - } - - // - // Sends an end-of-stream packet for the given stream to a particular port, - // for use when disconnecting; enables XML and File specialization for - // consistent end-of-stream behavior - // - void sendEOS(const std::string& streamID) - { - this->_pushPacket(SharedBufferType(), bulkio::time::utils::notSet(), true, streamID); + if (EOS) { + _streams.erase(streamID); + } } PtrType objref() @@ -83,6 +86,7 @@ namespace bulkio { } VarType _port; + std::set _streams; }; template <> diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp index b45de30a4..565ada9d1 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp @@ -111,7 +111,7 @@ namespace bulkio { LOG_DEBUG(logger,"pushSRI - PORT:" << name << " CONNECTION:" << connection_id << " SRI streamID:" << H.streamID << " Mode:" << H.mode << " XDELTA:" << 1.0/H.xdelta); try { - port->pushSRI(H); + port->pushSRI(sid, H); sri_iter->second.connections.insert(connection_id); } catch (const redhawk::FatalTransportError& err) { LOG_ERROR(logger, "PUSH-SRI FAILED " << err.what() @@ -203,11 +203,11 @@ namespace bulkio { try { if (sri_iter->second.connections.count(connection_id) == 0) { - port->pushSRI(sri_iter->second.sri); + port->pushSRI(streamID, sri_iter->second.sri); sri_iter->second.connections.insert(connection_id); } - port->pushPacket(data, T, EOS, sri_iter->second.sri); + port->pushPacket(data, T, EOS, streamID, sri_iter->second.sri); } catch (const redhawk::FatalTransportError& err) { LOG_ERROR(logger, "PUSH-PACKET FAILED " << err.what() << " PORT/CONNECTION: " << name << "/" << connection_id); @@ -304,34 +304,6 @@ namespace bulkio { } - template < typename PortTraits > - void OutPortBase< PortTraits >::_disconnectTransport(redhawk::BasicTransport* transport) - { - TRACE_ENTER(logger, "OutPort::disconnectPort" ); - PortTransportType* port = static_cast(transport); - - // Send an EOS for every connection that's listed for this SRI - const std::string& connection_id = transport->connectionId(); - for (typename OutPortSriMap::iterator cSRIs = currentSRIs.begin(); cSRIs!=currentSRIs.end(); cSRIs++) { - const std::string& stream_id = cSRIs->first; - - // Check if we have sent out sri/data to the connection - if (cSRIs->second.connections.count(connection_id) != 0) { - if (port->isAlive() && _isStreamRoutedToConnection(stream_id, connection_id)) { - try { - port->sendEOS(stream_id); - } catch (...) { - // Ignore all exceptions; the receiver may be dead - } - } - } - - // remove connection id from sri connections list - cSRIs->second.connections.erase(connection_id); - } - TRACE_EXIT(logger, "OutPort::disconnectPort" ); - } - template < typename PortTraits > bulkio::SriMap OutPortBase< PortTraits >::getCurrentSRI() { diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h index 707dba342..5ac481a0b 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h @@ -291,8 +291,6 @@ namespace bulkio { bool EOS, const std::string& streamID); - virtual void _disconnectTransport(redhawk::BasicTransport* transport); - virtual void addStream(const std::string& streamID, const BULKIO::StreamSRI& sri); virtual void removeStream(const std::string& streamID); }; From d85bbabe37921769b078a79a816f56b21c1d55cd Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 23 Nov 2016 09:17:41 -0500 Subject: [PATCH 0554/1644] Use newer trace enter/exit macros in C++ UsesPort --- redhawk/src/base/framework/UsesPort.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/redhawk/src/base/framework/UsesPort.cpp b/redhawk/src/base/framework/UsesPort.cpp index ee6effe97..6cf894bda 100644 --- a/redhawk/src/base/framework/UsesPort.cpp +++ b/redhawk/src/base/framework/UsesPort.cpp @@ -38,6 +38,8 @@ namespace redhawk { void UsesPort::connectPort(CORBA::Object_ptr connection, const char* connectionId) { + RH_TRACE_ENTER(logger); + // Give a specific exception message for nil if (CORBA::is_nil(connection)) { throw CF::Port::InvalidPort(1, "Nil object reference"); @@ -64,11 +66,12 @@ namespace redhawk { } _portConnected(connectionId); + RH_TRACE_EXIT(logger); } void UsesPort::disconnectPort(const char* connectionId) { - //TRACE_ENTER(logger, "OutPort::disconnectPort" ); + RH_TRACE_ENTER(logger); { boost::mutex::scoped_lock lock(updatingPortsLock); @@ -91,7 +94,7 @@ namespace redhawk { } _portDisconnected(connectionId); - //TRACE_EXIT(logger, "OutPort::disconnectPort" ); + RH_TRACE_EXIT(logger); } ExtendedCF::UsesConnectionSequence* UsesPort::connections() From be9ac36f7884b602a56a5fee79faa6c56c3b2032 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 23 Nov 2016 09:17:53 -0500 Subject: [PATCH 0555/1644] Move TransportError classes to UsesPort header --- redhawk/src/base/include/ossie/Port_impl.h | 20 -------------------- redhawk/src/base/include/ossie/UsesPort.h | 18 ++++++++++++++++++ 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/redhawk/src/base/include/ossie/Port_impl.h b/redhawk/src/base/include/ossie/Port_impl.h index 20c6187a1..234f2d41e 100644 --- a/redhawk/src/base/include/ossie/Port_impl.h +++ b/redhawk/src/base/include/ossie/Port_impl.h @@ -112,26 +112,6 @@ template } } // namespace _seqVector -namespace redhawk { - class TransportError : public std::runtime_error - { - public: - TransportError(const std::string& message) : - std::runtime_error(message) - { - } - }; - - class FatalTransportError : public TransportError - { - public: - FatalTransportError(const std::string& message) : - TransportError(message) - { - } - }; -} - class Port_impl #ifdef BEGIN_AUTOCOMPLETE_IGNORE diff --git a/redhawk/src/base/include/ossie/UsesPort.h b/redhawk/src/base/include/ossie/UsesPort.h index 4b6457b8e..0fb79ad81 100644 --- a/redhawk/src/base/include/ossie/UsesPort.h +++ b/redhawk/src/base/include/ossie/UsesPort.h @@ -14,6 +14,24 @@ #include "debug.h" namespace redhawk { + class TransportError : public std::runtime_error + { + public: + TransportError(const std::string& message) : + std::runtime_error(message) + { + } + }; + + class FatalTransportError : public TransportError + { + public: + FatalTransportError(const std::string& message) : + TransportError(message) + { + } + }; + class BasicTransport { public: From 47f1ff873a71f0d339735b0cbd187cc52c847b2c Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 23 Nov 2016 09:20:05 -0500 Subject: [PATCH 0556/1644] Add copyright header to new files --- redhawk/src/base/framework/UsesPort.cpp | 20 ++++++++++++++++++++ redhawk/src/base/include/ossie/UsesPort.h | 20 ++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/redhawk/src/base/framework/UsesPort.cpp b/redhawk/src/base/framework/UsesPort.cpp index 6cf894bda..b0aafc3a0 100644 --- a/redhawk/src/base/framework/UsesPort.cpp +++ b/redhawk/src/base/framework/UsesPort.cpp @@ -1,3 +1,23 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK GPP. + * + * REDHAWK GPP is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK GPP is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + #include #include diff --git a/redhawk/src/base/include/ossie/UsesPort.h b/redhawk/src/base/include/ossie/UsesPort.h index 0fb79ad81..a2ef76cfe 100644 --- a/redhawk/src/base/include/ossie/UsesPort.h +++ b/redhawk/src/base/include/ossie/UsesPort.h @@ -1,3 +1,23 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK GPP. + * + * REDHAWK GPP is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK GPP is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + #ifndef OSSIE_USESPORT_H #define OSSIE_USESPORT_H From 691a6a6375c33d46501be6de6de51b72d3dc0ce9 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 23 Nov 2016 09:25:49 -0500 Subject: [PATCH 0557/1644] Remove virtual method _disconnectTransport() which has been superseded by BasicTransport::disconnect() --- redhawk/src/base/framework/UsesPort.cpp | 5 ----- redhawk/src/base/include/ossie/UsesPort.h | 1 - 2 files changed, 6 deletions(-) diff --git a/redhawk/src/base/framework/UsesPort.cpp b/redhawk/src/base/framework/UsesPort.cpp index b0aafc3a0..c14ab5f4d 100644 --- a/redhawk/src/base/framework/UsesPort.cpp +++ b/redhawk/src/base/framework/UsesPort.cpp @@ -103,7 +103,6 @@ namespace redhawk { RH_DEBUG(logger, "Disconnecting connection '" << connectionId << "'"); (*transport)->disconnect(); - _disconnectTransport(*transport); delete (*transport); _transports.erase(transport); @@ -177,8 +176,4 @@ namespace redhawk { { return new BasicTransport(connectionId, object); } - - void UsesPort::_disconnectTransport(BasicTransport* transport) - { - } } diff --git a/redhawk/src/base/include/ossie/UsesPort.h b/redhawk/src/base/include/ossie/UsesPort.h index a2ef76cfe..0bdbadc4c 100644 --- a/redhawk/src/base/include/ossie/UsesPort.h +++ b/redhawk/src/base/include/ossie/UsesPort.h @@ -139,7 +139,6 @@ namespace redhawk { void _addTransportEntry(BasicTransport* transport); virtual BasicTransport* _createTransport(CORBA::Object_ptr object, const std::string& connectionId); - virtual void _disconnectTransport(BasicTransport* transport); LOGGER logger; From ce37e8a734f14dac0add62cd5c0af71d7cd15408 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 23 Nov 2016 09:50:35 -0500 Subject: [PATCH 0558/1644] Rename and simplify BulkIO transport method to get the remote port reference --- bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp | 8 ++------ bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp | 2 +- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp b/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp index 063eb2f63..e16d95204 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp @@ -46,13 +46,9 @@ namespace bulkio { } } - PtrType objref() + PtrType port() { - if (isAlive()) { - return PortType::_duplicate(_port); - } else { - return PortType::_nil(); - } + return _port; } linkStatistics stats; diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp index 565ada9d1..e51e68294 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp @@ -337,7 +337,7 @@ namespace bulkio { for (TransportList::iterator iter = _transports.begin(); iter != _transports.end(); ++iter) { PortTransportType* port = static_cast(*iter); - outConnections.push_back(std::make_pair(port->objref(), port->connectionId())); + outConnections.push_back(std::make_pair(PortType::_duplicate(port->port()), port->connectionId())); } return outConnections; From a84c9c0f46f4499c8569d085fb38a378a4369a79 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 23 Nov 2016 10:31:56 -0500 Subject: [PATCH 0559/1644] Create an iterator adapter class for C++ UsesPort transport list that handles the static_cast to the known transport type --- .../libsrc/cpp/bulkio_out_port.cpp | 21 ++++----- bulkioInterfaces/libsrc/cpp/bulkio_out_port.h | 2 + .../src/cpp/include/burstio/OutPortDecl.h | 1 + burstioInterfaces/src/cpp/lib/OutPortImpl.h | 8 ++-- .../src/base/framework/MessageSupplier.cpp | 20 ++++---- .../src/base/include/ossie/MessageSupplier.h | 2 + redhawk/src/base/include/ossie/UsesPort.h | 46 +++++++++++++++++++ 7 files changed, 73 insertions(+), 27 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp index e51e68294..20303d6ec 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp @@ -97,8 +97,8 @@ namespace bulkio { } if (active) { - for (TransportList::iterator iter = _transports.begin(); iter != _transports.end(); ++iter) { - PortTransportType* port = static_cast(*iter); + for (TransportIterator iter = _transports.begin(); iter != _transports.end(); ++iter) { + PortTransportType* port = *iter; const std::string& connection_id = port->connectionId(); // Skip ports known to be dead if (!port->isAlive()) { @@ -186,8 +186,8 @@ namespace bulkio { } if (active) { - for (TransportList::iterator iter = _transports.begin(); iter != _transports.end(); ++iter) { - PortTransportType* port = static_cast(*iter); + for (TransportIterator iter = _transports.begin(); iter != _transports.end(); ++iter) { + PortTransportType* port = *iter; const std::string& connection_id = port->connectionId(); // Skip ports known to be dead @@ -229,8 +229,8 @@ namespace bulkio { { SCOPED_LOCK lock(updatingPortsLock); BULKIO::UsesPortStatisticsSequence_var recStat = new BULKIO::UsesPortStatisticsSequence(); - for (TransportList::iterator iter = _transports.begin(); iter != _transports.end(); ++iter) { - PortTransportType* port = static_cast(*iter); + for (TransportIterator iter = _transports.begin(); iter != _transports.end(); ++iter) { + PortTransportType* port = *iter; BULKIO::UsesPortStatistics stat; stat.connectionId = port->connectionId().c_str(); stat.statistics = port->stats.retrieve(); @@ -254,9 +254,8 @@ namespace bulkio { void OutPortBase< PortTraits >::enableStats(bool enable) { SCOPED_LOCK lock(updatingPortsLock); - for (TransportList::iterator iter = _transports.begin(); iter != _transports.end(); ++iter) { - PortTransportType* port = static_cast(*iter); - port->stats.setEnabled(enable); + for (TransportIterator port = _transports.begin(); port != _transports.end(); ++port) { + (*port)->stats.setEnabled(enable); } } @@ -335,8 +334,8 @@ namespace bulkio { SCOPED_LOCK lock(updatingPortsLock); // restrict access till method completes ConnectionsList outConnections; - for (TransportList::iterator iter = _transports.begin(); iter != _transports.end(); ++iter) { - PortTransportType* port = static_cast(*iter); + for (TransportIterator iter = _transports.begin(); iter != _transports.end(); ++iter) { + PortTransportType* port = *iter; outConnections.push_back(std::make_pair(PortType::_duplicate(port->port()), port->connectionId())); } diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h index 5ac481a0b..9e6c1b3cd 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h @@ -270,6 +270,8 @@ namespace bulkio { virtual PortTransportType* _createLocalConnection(PortPtrType port, LocalPortType* localPort, const std::string& connectionId); + typedef redhawk::UsesPort::TransportIteratorAdapter TransportIterator; + std::vector filterTable; boost::shared_ptr< ConnectionEventListener > _connectCB; boost::shared_ptr< ConnectionEventListener > _disconnectCB; diff --git a/burstioInterfaces/src/cpp/include/burstio/OutPortDecl.h b/burstioInterfaces/src/cpp/include/burstio/OutPortDecl.h index 981980007..52cc14a5c 100644 --- a/burstioInterfaces/src/cpp/include/burstio/OutPortDecl.h +++ b/burstioInterfaces/src/cpp/include/burstio/OutPortDecl.h @@ -262,6 +262,7 @@ namespace burstio { friend class Queue; typedef BurstTransport TransportType; + typedef redhawk::UsesPort::TransportIteratorAdapter TransportIterator; typedef std::map QueueMap; diff --git a/burstioInterfaces/src/cpp/lib/OutPortImpl.h b/burstioInterfaces/src/cpp/lib/OutPortImpl.h index ed216c017..2380d4ea5 100644 --- a/burstioInterfaces/src/cpp/lib/OutPortImpl.h +++ b/burstioInterfaces/src/cpp/lib/OutPortImpl.h @@ -490,8 +490,8 @@ namespace burstio { RH_TRACE(logger, "Sending " << bursts.length() << " bursts"); std::vector deferred_ports; boost::mutex::scoped_lock lock(updatingPortsLock); - for (TransportList::iterator ii = _transports.begin(); ii != _transports.end(); ++ii) { - TransportType* connection = static_cast(*ii); + for (TransportIterator ii = _transports.begin(); ii != _transports.end(); ++ii) { + TransportType* connection = *ii; if (!isStreamRoutedToConnection(streamID, connection->connectionId())) { continue; @@ -548,8 +548,8 @@ namespace burstio { BULKIO::UsesPortStatisticsSequence_var retval = new BULKIO::UsesPortStatisticsSequence(); retval->length(_transports.size()); CORBA::ULong index = 0; - for (TransportList::iterator ii = _transports.begin(); ii != _transports.end(); ++ii, ++index) { - TransportType* transport = static_cast(*ii); + for (TransportIterator ii = _transports.begin(); ii != _transports.end(); ++ii, ++index) { + TransportType* transport = *ii; retval[index].connectionId = transport->connectionId().c_str(); BULKIO::PortStatistics_var stats = transport->getStatistics(); for (typename QueueMap::iterator jj = streamQueues_.begin(); jj != streamQueues_.end(); ++jj) { diff --git a/redhawk/src/base/framework/MessageSupplier.cpp b/redhawk/src/base/framework/MessageSupplier.cpp index be5de1468..0de8f6616 100644 --- a/redhawk/src/base/framework/MessageSupplier.cpp +++ b/redhawk/src/base/framework/MessageSupplier.cpp @@ -237,10 +237,9 @@ redhawk::BasicTransport* MessageSupplierPort::_createTransport(CORBA::Object_ptr void MessageSupplierPort::push(const CORBA::Any& data) { boost::mutex::scoped_lock lock(updatingPortsLock); - for (TransportList::iterator iter = _transports.begin(); iter != _transports.end(); ++iter) { - MessageTransport* transport = static_cast(*iter); + for (TransportIterator transport = _transports.begin(); transport != _transports.end(); ++transport) { try { - transport->push(data); + (*transport)->push(data); } catch ( ... ) { } } @@ -253,18 +252,16 @@ std::string MessageSupplierPort::getRepid() const void MessageSupplierPort::_beginMessageQueue(size_t count) { - for (TransportList::iterator iter = _transports.begin(); iter != _transports.end(); ++iter) { - MessageTransport* transport = static_cast(*iter); - transport->beginQueue(count); + for (TransportIterator transport = _transports.begin(); transport != _transports.end(); ++transport) { + (*transport)->beginQueue(count); } } void MessageSupplierPort::_queueMessage(const std::string& msgId, const char* format, const void* msgData, SerializerFunc serializer) { - for (TransportList::iterator iter = _transports.begin(); iter != _transports.end(); ++iter) { - MessageTransport* transport = static_cast(*iter); + for (TransportIterator transport = _transports.begin(); transport != _transports.end(); ++transport) { try { - transport->queueMessage(msgId, format, msgData, serializer); + (*transport)->queueMessage(msgId, format, msgData, serializer); } catch ( ... ) { } } @@ -272,8 +269,7 @@ void MessageSupplierPort::_queueMessage(const std::string& msgId, const char* fo void MessageSupplierPort::_sendMessageQueue() { - for (TransportList::iterator iter = _transports.begin(); iter != _transports.end(); ++iter) { - MessageTransport* transport = static_cast(*iter); - transport->sendMessages(); + for (TransportIterator transport = _transports.begin(); transport != _transports.end(); ++transport) { + (*transport)->sendMessages(); } } diff --git a/redhawk/src/base/include/ossie/MessageSupplier.h b/redhawk/src/base/include/ossie/MessageSupplier.h index 0ca4d20c6..711cbd0bf 100644 --- a/redhawk/src/base/include/ossie/MessageSupplier.h +++ b/redhawk/src/base/include/ossie/MessageSupplier.h @@ -98,6 +98,8 @@ class MessageSupplierPort : public redhawk::UsesPort class MessageTransport; class RemoteTransport; class LocalTransport; + + typedef redhawk::UsesPort::TransportIteratorAdapter TransportIterator; }; #endif // MESSAGESUPPLIER_H diff --git a/redhawk/src/base/include/ossie/UsesPort.h b/redhawk/src/base/include/ossie/UsesPort.h index 0bdbadc4c..b3d59823e 100644 --- a/redhawk/src/base/include/ossie/UsesPort.h +++ b/redhawk/src/base/include/ossie/UsesPort.h @@ -133,6 +133,52 @@ namespace redhawk { protected: typedef std::vector TransportList; + template + class TransportIteratorAdapter { + public: + typedef TransportList::iterator IteratorType; + + TransportIteratorAdapter() + { + } + + TransportIteratorAdapter(IteratorType iter) : + _iterator(iter) + { + } + + inline TransportType* operator*() + { + return static_cast(*_iterator); + } + + inline TransportIteratorAdapter& operator++() + { + ++_iterator; + return *this; + } + + inline TransportIteratorAdapter operator++(int) + { + TransportIteratorAdapter result(*this); + ++(*this); + return result; + } + + inline bool operator==(const TransportIteratorAdapter& other) const + { + return (_iterator == other._iterator); + } + + inline bool operator!=(const TransportIteratorAdapter& other) const + { + return (_iterator != other._iterator); + } + + private: + IteratorType _iterator; + }; + virtual void _validatePort(CORBA::Object_ptr object); TransportList::iterator _findTransportEntry(const std::string& connectionId); From 6f6d0eaa97782c060aa80072d918fbeb73769eb7 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 23 Nov 2016 15:02:44 -0500 Subject: [PATCH 0560/1644] Use shared pointers instead of copies to manage BULKIO::StreamSRI objects in input ports, streams and data blocks --- .../libsrc/cpp/bulkio_datablock.cpp | 27 ++++++--- .../libsrc/cpp/bulkio_datablock.h | 1 + .../libsrc/cpp/bulkio_in_port.cpp | 56 ++++++++++--------- bulkioInterfaces/libsrc/cpp/bulkio_in_port.h | 13 +++-- .../libsrc/cpp/bulkio_in_stream.cpp | 16 +++--- .../libsrc/cpp/bulkio_in_stream.h | 2 +- 6 files changed, 65 insertions(+), 50 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_datablock.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_datablock.cpp index 20c62f04a..db68889b5 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_datablock.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_datablock.cpp @@ -33,8 +33,13 @@ using bulkio::DataBlock; template struct DataBlock::Impl { + Impl(const boost::shared_ptr& sri) : + sri(sri) + { + } + redhawk::shared_buffer data; - BULKIO::StreamSRI sri; + boost::shared_ptr sri; std::list timestamps; int sriChangeFlags; bool inputQueueFlushed; @@ -46,12 +51,18 @@ DataBlock::DataBlock() : { } +template +DataBlock::DataBlock(const boost::shared_ptr& sri, size_t size) : + _impl(boost::make_shared(sri)) +{ + _impl->data = redhawk::buffer(size); +} + template DataBlock::DataBlock(const BULKIO::StreamSRI& sri, size_t size) : - _impl(boost::make_shared()) + _impl(boost::make_shared(boost::make_shared(sri))) { _impl->data = redhawk::buffer(size); - _impl->sri = sri; } template @@ -67,13 +78,13 @@ DataBlock DataBlock::copy() const template const BULKIO::StreamSRI& DataBlock::sri() const { - return _impl->sri; + return *(_impl->sri); } template double DataBlock::xdelta() const { - return _impl->sri.xdelta; + return _impl->sri->xdelta; } template @@ -104,7 +115,7 @@ void DataBlock::resize(size_t count) template bool DataBlock::complex() const { - return (_impl->sri.mode != 0); + return (_impl->sri->mode != 0); } template @@ -177,7 +188,7 @@ double DataBlock::getNetTimeDrift() const const std::list& timestamps = _impl->timestamps; validate_timestamps(timestamps); - return get_drift(timestamps.front(), timestamps.back(), _impl->sri.xdelta); + return get_drift(timestamps.front(), timestamps.back(), _impl->sri->xdelta); } template @@ -191,7 +202,7 @@ double DataBlock::getMaxTimeDrift() const std::list::const_iterator next = current; ++next; for (; next != timestamps.end(); ++current, ++next) { - double drift = get_drift(*current, *next, _impl->sri.xdelta); + double drift = get_drift(*current, *next, _impl->sri->xdelta); if (std::abs(drift) > std::abs(max)) { max = drift; } diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_datablock.h b/bulkioInterfaces/libsrc/cpp/bulkio_datablock.h index eba0a0a4b..028fb7e95 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_datablock.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_datablock.h @@ -56,6 +56,7 @@ namespace bulkio { typedef redhawk::shared_buffer ComplexBuffer; DataBlock(); + explicit DataBlock(const boost::shared_ptr& sri, size_t size=0); DataBlock(const BULKIO::StreamSRI& sri, size_t size=0); DataBlock copy() const; diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp index 115f49edc..c98727cf1 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp @@ -126,8 +126,8 @@ namespace bulkio { { SCOPED_LOCK lock(sriUpdateLock); BULKIO::StreamSRISequence_var retSRI = new BULKIO::StreamSRISequence(); - for (SriMap::iterator currH = currentHs.begin(); currH != currentHs.end(); ++currH) { - ossie::corba::push_back(retSRI, currH->second.first); + for (SriTable::iterator currH = currentHs.begin(); currH != currentHs.end(); ++currH) { + ossie::corba::push_back(retSRI, *(currH->second.first)); } // NOTE: You must delete the object that this function returns! @@ -169,21 +169,22 @@ namespace bulkio { LOG_TRACE(logger,"pushSRI - FIND- PORT:" << name << " NEW SRI:" << streamID << " Mode:" << H.mode << " XDELTA:" << 1.0/H.xdelta ); SCOPED_LOCK lock(sriUpdateLock); - SriMap::iterator currH = currentHs.find(streamID); + SriTable::iterator currH = currentHs.find(streamID); if (currH == currentHs.end()) { LOG_DEBUG(logger,"pushSRI PORT:" << name << " NEW SRI:" << streamID << " Mode:" << H.mode ); - BULKIO::StreamSRI tmpH = H; // mutable copy for callbacks + boost::shared_ptr sri = boost::make_shared(H); if (newStreamCallback) { - newStreamCallback(tmpH); + newStreamCallback(*sri); } - currentHs[streamID] = std::make_pair(tmpH, true); + currentHs[streamID] = std::make_pair(sri, true); lock.unlock(); - createStream(streamID, tmpH); + createStream(streamID, sri); } else { - if ( sri_cmp && !sri_cmp(H, currH->second.first)) { + if (sri_cmp && !sri_cmp(H, *(currH->second.first))) { LOG_DEBUG(logger,"pushSRI PORT:" << name << " SAME SRI:" << streamID << " Mode:" << H.mode ); - currentHs[streamID] = std::make_pair(H, true); + currH->second.first = boost::make_shared(H); + currH->second.second = true; } } TRACE_EXIT( logger, "InPort::pushSRI" ); @@ -200,31 +201,30 @@ namespace bulkio { return; } - BULKIO::StreamSRI* sri; + boost::shared_ptr sri; bool sriChanged = false; { SCOPED_LOCK lock(sriUpdateLock); - SriMap::iterator currH = currentHs.find(streamID); + SriTable::iterator currH = currentHs.find(streamID); if (currH != currentHs.end()) { - sri = &currH->second.first; + sri = currH->second.first; sriChanged = currH->second.second; - currentHs[streamID].second = false; + currH->second.second = false; } else { // Unknown stream ID, register a new default SRI following the logic in pushSRI, // and set the SRI changed flag LOG_WARN(logger, "InPort::pushPacket received data for stream '" << streamID << "' with no SRI"); sriChanged = true; - BULKIO::StreamSRI tmpH = {1, 0.0, 1.0, 1, 0, 0.0, 0.0, 0, 0, streamID.c_str(), false, 0}; + sri = boost::make_shared(bulkio::sri::create(streamID)); if (newStreamCallback) { - newStreamCallback(tmpH); + newStreamCallback(*sri); } - currentHs[streamID] = std::make_pair(tmpH, false); - sri = &(currentHs[streamID].first); + currentHs[streamID] = std::make_pair(sri, false); lock.unlock(); - createStream(streamID, *sri); + createStream(streamID, sri); } } @@ -265,7 +265,7 @@ namespace bulkio { LOG_TRACE(logger, "bulkio::InPort pushPacket NEW PACKET (QUEUE" << packetQueue.size()+1 << ")"); stats->update(length, (float)(packetQueue.size()+1)/(float)maxQueue, EOS, streamID, false); - Packet *tmpIn = new Packet(data, T, EOS, *sri, sriChanged, flushToReport); + Packet *tmpIn = new Packet(data, T, EOS, sri, sriChanged, flushToReport); packetQueue.push_back(tmpIn); dataAvailable.notify_all(); } @@ -363,7 +363,7 @@ namespace bulkio { DataTransferType* transfer = 0; boost::scoped_ptr packet(nextPacket(timeout, streamID)); if (packet) { - transfer = new DataTransferType(PortSequenceType(), packet->T, packet->EOS, packet->streamID.c_str(), packet->SRI, packet->sriChanged, packet->inputQueueFlushed); + transfer = new DataTransferType(PortSequenceType(), packet->T, packet->EOS, packet->streamID.c_str(), *(packet->SRI), packet->sriChanged, packet->inputQueueFlushed); transfer->dataBuffer.assign(packet->buffer.begin(), packet->buffer.end()); } return transfer; @@ -417,15 +417,15 @@ namespace bulkio { bool turnOffBlocking = false; if (packet->EOS) { SCOPED_LOCK lock2(sriUpdateLock); - SriMap::iterator target = currentHs.find(packet->streamID); + SriTable::iterator target = currentHs.find(packet->streamID); if (target != currentHs.end()) { - bool sriBlocking = target->second.first.blocking; + bool sriBlocking = target->second.first->blocking; currentHs.erase(target); if (sriBlocking) { turnOffBlocking = true; - SriMap::iterator currH; + SriTable::iterator currH; for (currH = currentHs.begin(); currH != currentHs.end(); currH++) { - if (currH->second.first.blocking) { + if (currH->second.first->blocking) { turnOffBlocking = false; break; } @@ -469,7 +469,8 @@ namespace bulkio { } template < typename PortTraits > - void InPortBase< PortTraits >::createStream(const std::string& /*unused*/, const BULKIO::StreamSRI& /*unused*/) + void InPortBase< PortTraits >::createStream(const std::string& /*unused*/, + const boost::shared_ptr& /*unused*/) { } @@ -540,7 +541,7 @@ namespace bulkio { if (!firstPacket) break; } firstPacket = false; - if (packet->SRI.mode) { + if (packet->SRI->mode) { item_size = 2; } samples += packet->buffer.size(); @@ -740,7 +741,8 @@ namespace bulkio { } template < typename PortTraits > - void InPort< PortTraits >::createStream(const std::string& streamID, const BULKIO::StreamSRI& sri) + void InPort< PortTraits >::createStream(const std::string& streamID, + const boost::shared_ptr& sri) { StreamType stream(sri, this); boost::mutex::scoped_lock lock(streamsMutex); diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h index edf634ca9..1d8a3c1c2 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h @@ -238,21 +238,21 @@ namespace bulkio { SriListener *newStreamCB = NULL ); struct Packet { - Packet(const SharedBufferType& buffer, const BULKIO::PrecisionUTCTime& T, bool EOS, const BULKIO::StreamSRI& SRI, bool sriChanged, bool inputQueueFlushed) : + Packet(const SharedBufferType& buffer, const BULKIO::PrecisionUTCTime& T, bool EOS, const boost::shared_ptr& SRI, bool sriChanged, bool inputQueueFlushed) : buffer(buffer), T(T), EOS(EOS), SRI(SRI), sriChanged(sriChanged), inputQueueFlushed(inputQueueFlushed), - streamID(SRI.streamID) + streamID(SRI->streamID) { } SharedBufferType buffer; BULKIO::PrecisionUTCTime T; bool EOS; - BULKIO::StreamSRI SRI; + boost::shared_ptr SRI; bool sriChanged; bool inputQueueFlushed; std::string streamID; @@ -277,7 +277,8 @@ namespace bulkio { // // List of SRI objects managed by StreamID // - SriMap currentHs; + typedef std::map,bool> > SriTable; + SriTable currentHs; // // synchronizes access to the workQueue member @@ -332,7 +333,7 @@ namespace bulkio { // Packet* peekPacket(float timeout, boost::unique_lock& lock); - virtual void createStream(const std::string& streamID, const BULKIO::StreamSRI& sri); + virtual void createStream(const std::string& streamID, const boost::shared_ptr& sri); Packet* fetchPacket(const std::string& streamID); @@ -478,7 +479,7 @@ namespace bulkio { // Override of base class queuePacket to add stream-related behavior void queuePacket(const SharedBufferType& data, const BULKIO::PrecisionUTCTime& T, CORBA::Boolean EOS, const std::string& streamID); - virtual void createStream(const std::string& streamID, const BULKIO::StreamSRI& sri); + virtual void createStream(const std::string& streamID, const boost::shared_ptr& sri); void removeStream(const std::string& streamID); bool isStreamActive(const std::string& streamID); diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp index d222cf572..5ef1bd783 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp @@ -41,8 +41,8 @@ class InputStream::Impl { EOS_REPORTED }; - Impl(const BULKIO::StreamSRI& sri, InPortType* port) : - _streamID(sri.streamID), + Impl(const boost::shared_ptr& sri, InPortType* port) : + _streamID(sri->streamID), _sri(sri), _eosState(EOS_NONE), _port(port), @@ -66,7 +66,7 @@ class InputStream::Impl { const BULKIO::StreamSRI& sri() const { - return _sri; + return *_sri; } bool eos() @@ -96,7 +96,7 @@ class InputStream::Impl { size_t queued = _samplesQueued; if (queued > 0) { // Adjust number of samples to account for complex data, if necessary - const BULKIO::StreamSRI& sri = _queue.front().SRI; + const BULKIO::StreamSRI& sri = *(_queue.front().SRI); if (sri.mode) { queued /= 2; } @@ -314,7 +314,7 @@ class InputStream::Impl { PacketType& front = _queue.front(); int sriChangeFlags = bulkio::sri::NONE; if (front.sriChanged) { - sriChangeFlags = bulkio::sri::compareFields(_sri, front.SRI); + sriChangeFlags = bulkio::sri::compareFields(*_sri, *(front.SRI)); front.sriChanged = false; _sri = front.SRI; } @@ -406,7 +406,7 @@ class InputStream::Impl { } } - return &(_queue.front().SRI); + return _queue.front().SRI.get(); } bool _fetchPacket(bool blocking) @@ -468,7 +468,7 @@ class InputStream::Impl { } const std::string _streamID; - BULKIO::StreamSRI _sri; + boost::shared_ptr _sri; EosState _eosState; InPortType* _port; boost::ptr_deque _queue; @@ -486,7 +486,7 @@ InputStream::InputStream() : } template -InputStream::InputStream(const BULKIO::StreamSRI& sri, InPortType* port) : +InputStream::InputStream(const boost::shared_ptr& sri, InPortType* port) : _impl(new Impl(sri, port)) { } diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.h b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.h index 816f488fb..a40ee15c6 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.h @@ -71,7 +71,7 @@ namespace bulkio { private: friend class InPort; typedef InPort InPortType; - InputStream(const BULKIO::StreamSRI&, InPortType*); + InputStream(const boost::shared_ptr&, InPortType*); bool hasBufferedData(); From fbe8fd5a3407d0d14f418a31911d4da86d555b8c Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 23 Nov 2016 15:34:17 -0500 Subject: [PATCH 0561/1644] Move lookup of SriMapStruct into its own function --- .../libsrc/cpp/bulkio_out_port.cpp | 36 +++++++++++-------- bulkioInterfaces/libsrc/cpp/bulkio_out_port.h | 2 ++ 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp index 20303d6ec..d66ec1218 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp @@ -162,17 +162,9 @@ namespace bulkio { template < typename PortTraits > - void OutPortBase< PortTraits >::_sendPacket( - const SharedBufferType& data, - const BULKIO::PrecisionUTCTime& T, - bool EOS, - const std::string& streamID) + SriMapStruct& OutPortBase< PortTraits >::_getSriMapStruct(const std::string& streamID) { - // don't want to process while command information is coming in - SCOPED_LOCK lock(this->updatingPortsLock); - - // grab SRI context - typename OutPortSriMap::iterator sri_iter = currentSRIs.find(streamID); + OutPortSriMap::iterator sri_iter = currentSRIs.find(streamID); if (sri_iter == currentSRIs.end()) { LOG_TRACE(logger, "Creating new stream '" << streamID << "' with default SRI"); @@ -184,6 +176,22 @@ namespace bulkio { addStream(streamID, sri_iter->second.sri); } + return sri_iter->second; + } + + + template < typename PortTraits > + void OutPortBase< PortTraits >::_sendPacket( + const SharedBufferType& data, + const BULKIO::PrecisionUTCTime& T, + bool EOS, + const std::string& streamID) + { + // don't want to process while command information is coming in + SCOPED_LOCK lock(this->updatingPortsLock); + + // grab SRI context + SriMapStruct& sri = _getSriMapStruct(streamID); if (active) { for (TransportIterator iter = _transports.begin(); iter != _transports.end(); ++iter) { @@ -202,12 +210,12 @@ namespace bulkio { } try { - if (sri_iter->second.connections.count(connection_id) == 0) { - port->pushSRI(streamID, sri_iter->second.sri); - sri_iter->second.connections.insert(connection_id); + if (sri.connections.count(connection_id) == 0) { + port->pushSRI(streamID, sri.sri); + sri.connections.insert(connection_id); } - port->pushPacket(data, T, EOS, streamID, sri_iter->second.sri); + port->pushPacket(data, T, EOS, streamID, sri.sri); } catch (const redhawk::FatalTransportError& err) { LOG_ERROR(logger, "PUSH-PACKET FAILED " << err.what() << " PORT/CONNECTION: " << name << "/" << connection_id); diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h index 9e6c1b3cd..425dd489c 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h @@ -285,6 +285,8 @@ namespace bulkio { // bool _isStreamRoutedToConnection(const std::string& connectionID, const std::string& streamID); + SriMapStruct& _getSriMapStruct(const std::string& streamID); + // // Sends data and metadata to all connections enabled for the given stream // From e5db392686c380d727a8c6558f05ae4502e5dd1c Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 28 Nov 2016 11:42:29 -0500 Subject: [PATCH 0562/1644] Track last SRI version on a per-connection/transport basis, and use that to determine whether to push out an updated SRI --- .../libsrc/cpp/bulkio_connection.hpp | 23 ++- .../libsrc/cpp/bulkio_out_port.cpp | 136 ++++++++---------- bulkioInterfaces/libsrc/cpp/bulkio_out_port.h | 22 ++- 3 files changed, 98 insertions(+), 83 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp b/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp index e16d95204..fa7b147f0 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp @@ -22,15 +22,23 @@ namespace bulkio { virtual void disconnect() { // Send an end-of-stream for all active streams - for (std::set::iterator stream = _streams.begin(); stream != _streams.end(); ++stream) { - this->_pushPacket(SharedBufferType(), bulkio::time::utils::notSet(), true, *stream); + for (VersionMap::iterator stream = _sriVersions.begin(); stream != _sriVersions.end(); ++stream) { + this->_pushPacket(SharedBufferType(), bulkio::time::utils::notSet(), true, stream->first); } - _streams.clear(); + _sriVersions.clear(); } - void pushSRI(const std::string& streamID, const BULKIO::StreamSRI& sri) + void pushSRI(const std::string& streamID, const BULKIO::StreamSRI& sri, int version) { - _streams.insert(streamID); + VersionMap::iterator existing = _sriVersions.find(streamID); + if (existing != _sriVersions.end()) { + if (version == existing->second) { + return; + } + existing->second = version; + } else { + _sriVersions[streamID] = version; + } this->_pushSRI(sri); } @@ -42,7 +50,7 @@ namespace bulkio { { this->_sendPacket(data, T, EOS, streamID, sri); if (EOS) { - _streams.erase(streamID); + _sriVersions.erase(streamID); } } @@ -82,7 +90,8 @@ namespace bulkio { } VarType _port; - std::set _streams; + typedef std::map VersionMap; + VersionMap _sriVersions; }; template <> diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp index d66ec1218..920a07d48 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp @@ -28,8 +28,9 @@ #include "bulkio_connection.hpp" -// Suppress warnings for access to "deprecated" currentSRI member--it's the -// public access that's deprecated, not the member itself +// Suppress warnings for access to deprecated currentSRI member (on gcc 4.4, at +// least, the implicit destructor call from OutPortBase's destructor emits a +// warning) #pragma GCC diagnostic ignored "-Wdeprecated-declarations" namespace bulkio { @@ -74,54 +75,48 @@ namespace bulkio { template < typename PortTraits > - void OutPortBase< PortTraits >::pushSRI(const BULKIO::StreamSRI& H) { - - - TRACE_ENTER(logger, "OutPort::pushSRI" ); - - - SCOPED_LOCK lock(updatingPortsLock); // don't want to process while command information is coming in - - const std::string sid(H.streamID); - typename OutPortSriMap::iterator sri_iter = currentSRIs.find(sid); - if (sri_iter == currentSRIs.end()) { - // need to use insert since we do not have default CTOR for SriMapStruct - sri_iter = currentSRIs.insert(OutPortSriMap::value_type(sid, SriMapStruct(H))).first; - addStream(sid, sri_iter->second.sri); - } else { - // overwrite the SRI - sri_iter->second.sri = H; - - // reset connections list to be empty - sri_iter->second.connections.clear(); - } - - if (active) { - for (TransportIterator iter = _transports.begin(); iter != _transports.end(); ++iter) { - PortTransportType* port = *iter; - const std::string& connection_id = port->connectionId(); - // Skip ports known to be dead - if (!port->isAlive()) { - continue; - } - if (!_isStreamRoutedToConnection(sid, connection_id)) { - continue; - } + void OutPortBase< PortTraits >::pushSRI(const BULKIO::StreamSRI& H) + { + TRACE_ENTER(logger, "OutPort::pushSRI" ); - LOG_DEBUG(logger,"pushSRI - PORT:" << name << " CONNECTION:" << connection_id << " SRI streamID:" - << H.streamID << " Mode:" << H.mode << " XDELTA:" << 1.0/H.xdelta); - try { - port->pushSRI(sid, H); - sri_iter->second.connections.insert(connection_id); - } catch (const redhawk::FatalTransportError& err) { - LOG_ERROR(logger, "PUSH-SRI FAILED " << err.what() - << " PORT/CONNECTION: " << name << "/" << connection_id); - } - } - } + const std::string sid(H.streamID); + SCOPED_LOCK lock(updatingPortsLock); // don't want to process while command information is coming in + SriTable::iterator existing = _currentSRIs.find(sid); + if (existing == _currentSRIs.end()) { + // Insert new SRI + existing = _currentSRIs.insert(std::make_pair(sid, StreamDescriptor(H))).first; + addStream(sid, existing->second.sri); + } else { + // Overwrite existing SRI + existing->second.sri = H; + existing->second.version++; + } + const StreamDescriptor& stream = existing->second; + + if (active) { + for (TransportIterator iter = _transports.begin(); iter != _transports.end(); ++iter) { + PortTransportType* port = *iter; + const std::string& connection_id = port->connectionId(); + // Skip ports known to be dead + if (!port->isAlive()) { + continue; + } + if (!_isStreamRoutedToConnection(sid, connection_id)) { + continue; + } + + LOG_DEBUG(logger,"pushSRI - PORT:" << name << " CONNECTION:" << connection_id << " SRI streamID:" + << stream.sri.streamID << " Mode:" << stream.sri.mode << " XDELTA:" << 1.0/stream.sri.xdelta); + try { + port->pushSRI(sid, stream.sri, stream.version); + } catch (const redhawk::FatalTransportError& err) { + LOG_ERROR(logger, "PUSH-SRI FAILED " << err.what() + << " PORT/CONNECTION: " << name << "/" << connection_id); + } + } + } - TRACE_EXIT(logger, "OutPort::pushSRI"); - return; + TRACE_EXIT(logger, "OutPort::pushSRI"); } template < typename PortTraits > @@ -162,21 +157,18 @@ namespace bulkio { template < typename PortTraits > - SriMapStruct& OutPortBase< PortTraits >::_getSriMapStruct(const std::string& streamID) + const StreamDescriptor& OutPortBase< PortTraits >::_getSRI(const std::string& streamID) { - OutPortSriMap::iterator sri_iter = currentSRIs.find(streamID); - if (sri_iter == currentSRIs.end()) { - LOG_TRACE(logger, "Creating new stream '" << streamID << "' with default SRI"); + SriTable::iterator sri_iter = _currentSRIs.find(streamID); + if (sri_iter == _currentSRIs.end()) { + LOG_TRACE(logger, "Creating new stream '" << streamID << "' with default SRI"); - // No SRI associated with the stream ID, create a default one and add - // it to the list; it will get pushed to downstream connections below - SriMapStruct sri_ctx(bulkio::sri::create(streamID)); - // need to use insert since we do not have default CTOR for SriMapStruct - sri_iter = currentSRIs.insert(std::make_pair(streamID, sri_ctx)).first; - - addStream(streamID, sri_iter->second.sri); - } - return sri_iter->second; + // No SRI associated with the stream ID, create a default one and add + // it to the list; it will get pushed to downstream connections below + sri_iter = _currentSRIs.insert(std::make_pair(streamID, StreamDescriptor(streamID))).first; + addStream(streamID, sri_iter->second.sri); + } + return sri_iter->second; } @@ -191,7 +183,7 @@ namespace bulkio { SCOPED_LOCK lock(this->updatingPortsLock); // grab SRI context - SriMapStruct& sri = _getSriMapStruct(streamID); + const StreamDescriptor& stream = _getSRI(streamID); if (active) { for (TransportIterator iter = _transports.begin(); iter != _transports.end(); ++iter) { @@ -210,12 +202,8 @@ namespace bulkio { } try { - if (sri.connections.count(connection_id) == 0) { - port->pushSRI(streamID, sri.sri); - sri.connections.insert(connection_id); - } - - port->pushPacket(data, T, EOS, streamID, sri.sri); + port->pushSRI(streamID, stream.sri, stream.version); + port->pushPacket(data, T, EOS, streamID, stream.sri); } catch (const redhawk::FatalTransportError& err) { LOG_ERROR(logger, "PUSH-PACKET FAILED " << err.what() << " PORT/CONNECTION: " << name << "/" << connection_id); @@ -226,7 +214,7 @@ namespace bulkio { // if we have end of stream removed old sri if (EOS) { - currentSRIs.erase(streamID); + _currentSRIs.erase(streamID); removeStream(streamID); } } @@ -316,9 +304,8 @@ namespace bulkio { { bulkio::SriMap ret; SCOPED_LOCK lock(updatingPortsLock); // restrict access till method completes - typename OutPortSriMap::iterator cSri = currentSRIs.begin(); - for ( ; cSri != currentSRIs.end(); cSri++ ) { - ret[cSri->first] = std::make_pair< BULKIO::StreamSRI, bool >( cSri->second.sri, false ); + for (SriTable::iterator cSri = _currentSRIs.begin() ; cSri != _currentSRIs.end(); ++cSri) { + ret[cSri->first] = std::make_pair(cSri->second.sri, false); } return ret; } @@ -328,9 +315,8 @@ namespace bulkio { { bulkio::SriList ret; SCOPED_LOCK lock(updatingPortsLock); // restrict access till method completes - typename OutPortSriMap::iterator cSri = currentSRIs.begin(); - for ( ; cSri != currentSRIs.end(); cSri++ ) { - ret.push_back( cSri->second.sri ); + for (SriTable::iterator cSri = _currentSRIs.begin() ; cSri != _currentSRIs.end(); ++cSri) { + ret.push_back(cSri->second.sri); } return ret; } diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h index 425dd489c..034523f77 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h @@ -63,6 +63,23 @@ namespace bulkio { template class PortTransport; + struct StreamDescriptor { + StreamDescriptor(const std::string& streamID) : + sri(bulkio::sri::create(streamID)), + version(1) + { + } + + StreamDescriptor(const BULKIO::StreamSRI& sri) : + sri(sri), + version(1) + { + } + + BULKIO::StreamSRI sri; + int version; + }; + // // OutPortBase // @@ -259,6 +276,9 @@ namespace bulkio { OutPortSriMap currentSRIs __attribute__ ((deprecated)); protected: + typedef std::map SriTable; + SriTable _currentSRIs; + // // Lookup table for connections to input ports in the same process space // @@ -285,7 +305,7 @@ namespace bulkio { // bool _isStreamRoutedToConnection(const std::string& connectionID, const std::string& streamID); - SriMapStruct& _getSriMapStruct(const std::string& streamID); + const StreamDescriptor& _getSRI(const std::string& streamID); // // Sends data and metadata to all connections enabled for the given stream From 69373a1118a22be949a402c0b56eeafa3406d6f4 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 28 Nov 2016 13:52:23 -0500 Subject: [PATCH 0563/1644] Start unifying stream-based and non-stream-based C++ BulkIO out ports --- .../libsrc/cpp/bulkio_out_port.cpp | 50 ++++++++++--------- bulkioInterfaces/libsrc/cpp/bulkio_out_port.h | 49 ++++++++++++++---- .../libsrc/cpp/bulkio_out_stream.cpp | 25 +++------- .../libsrc/cpp/bulkio_out_stream.h | 4 ++ 4 files changed, 77 insertions(+), 51 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp index 920a07d48..fee676747 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp @@ -81,17 +81,17 @@ namespace bulkio { const std::string sid(H.streamID); SCOPED_LOCK lock(updatingPortsLock); // don't want to process while command information is coming in + boost::shared_ptr stream; SriTable::iterator existing = _currentSRIs.find(sid); if (existing == _currentSRIs.end()) { // Insert new SRI - existing = _currentSRIs.insert(std::make_pair(sid, StreamDescriptor(H))).first; - addStream(sid, existing->second.sri); + stream = _addStream(sid, H); } else { - // Overwrite existing SRI - existing->second.sri = H; - existing->second.version++; + // Overwrite existing SRI + stream = existing->second; + stream->setSRI(H); } - const StreamDescriptor& stream = existing->second; + const BULKIO::StreamSRI& sri = stream->sri(); if (active) { for (TransportIterator iter = _transports.begin(); iter != _transports.end(); ++iter) { @@ -106,9 +106,9 @@ namespace bulkio { } LOG_DEBUG(logger,"pushSRI - PORT:" << name << " CONNECTION:" << connection_id << " SRI streamID:" - << stream.sri.streamID << " Mode:" << stream.sri.mode << " XDELTA:" << 1.0/stream.sri.xdelta); + << stream->streamID() << " Mode:" << sri.mode << " XDELTA:" << 1.0/sri.xdelta); try { - port->pushSRI(sid, stream.sri, stream.version); + port->pushSRI(sid, sri, stream->version()); } catch (const redhawk::FatalTransportError& err) { LOG_ERROR(logger, "PUSH-SRI FAILED " << err.what() << " PORT/CONNECTION: " << name << "/" << connection_id); @@ -157,18 +157,19 @@ namespace bulkio { template < typename PortTraits > - const StreamDescriptor& OutPortBase< PortTraits >::_getSRI(const std::string& streamID) + boost::shared_ptr OutPortBase< PortTraits >::_getStream(const std::string& streamID) { - SriTable::iterator sri_iter = _currentSRIs.find(streamID); - if (sri_iter == _currentSRIs.end()) { + SriTable::iterator existing = _currentSRIs.find(streamID); + if (existing == _currentSRIs.end()) { LOG_TRACE(logger, "Creating new stream '" << streamID << "' with default SRI"); // No SRI associated with the stream ID, create a default one and add // it to the list; it will get pushed to downstream connections below - sri_iter = _currentSRIs.insert(std::make_pair(streamID, StreamDescriptor(streamID))).first; - addStream(streamID, sri_iter->second.sri); + _currentSRIs[streamID] = _addStream(streamID, bulkio::sri::create(streamID)); + return _currentSRIs[streamID]; + } else { + return existing->second; } - return sri_iter->second; } @@ -183,7 +184,7 @@ namespace bulkio { SCOPED_LOCK lock(this->updatingPortsLock); // grab SRI context - const StreamDescriptor& stream = _getSRI(streamID); + boost::shared_ptr stream = _getStream(streamID); if (active) { for (TransportIterator iter = _transports.begin(); iter != _transports.end(); ++iter) { @@ -202,8 +203,8 @@ namespace bulkio { } try { - port->pushSRI(streamID, stream.sri, stream.version); - port->pushPacket(data, T, EOS, streamID, stream.sri); + port->pushSRI(streamID, stream->sri(), stream->version()); + port->pushPacket(data, T, EOS, streamID, stream->sri()); } catch (const redhawk::FatalTransportError& err) { LOG_ERROR(logger, "PUSH-PACKET FAILED " << err.what() << " PORT/CONNECTION: " << name << "/" << connection_id); @@ -305,7 +306,7 @@ namespace bulkio { bulkio::SriMap ret; SCOPED_LOCK lock(updatingPortsLock); // restrict access till method completes for (SriTable::iterator cSri = _currentSRIs.begin() ; cSri != _currentSRIs.end(); ++cSri) { - ret[cSri->first] = std::make_pair(cSri->second.sri, false); + ret[cSri->first] = std::make_pair(cSri->second->sri(), false); } return ret; } @@ -316,7 +317,7 @@ namespace bulkio { bulkio::SriList ret; SCOPED_LOCK lock(updatingPortsLock); // restrict access till method completes for (SriTable::iterator cSri = _currentSRIs.begin() ; cSri != _currentSRIs.end(); ++cSri) { - ret.push_back(cSri->second.sri); + ret.push_back(cSri->second->sri()); } return ret; } @@ -368,8 +369,9 @@ namespace bulkio { } template < typename PortTraits > - void OutPortBase< PortTraits >::addStream(const std::string& streamID, const BULKIO::StreamSRI& sri) + boost::shared_ptr OutPortBase< PortTraits >::_addStream(const std::string& streamID, const BULKIO::StreamSRI& sri) { + return boost::make_shared(sri); } template < typename PortTraits > @@ -510,15 +512,17 @@ namespace bulkio { } template < typename PortTraits > - void OutPort< PortTraits >::addStream(const std::string& streamID, const BULKIO::StreamSRI& sri) + boost::shared_ptr OutPort< PortTraits >::_addStream(const std::string& streamID, const BULKIO::StreamSRI& sri) { boost::mutex::scoped_lock lock(streamsMutex); - if (streams.count(streamID) == 0) { + typename StreamMap::iterator existing = streams.find(streamID); + if (existing == streams.end()) { // Only create a new stream if one doesn't already exist; when a stream // is created via createStream (the preferred method), its first call // to pushSRI will end up calling this method - streams.insert(std::make_pair(streamID, StreamType(sri, this))); + existing = streams.insert(std::make_pair(streamID, StreamType(sri, this))).first; } + return existing->second.getDescriptor(); } template < typename PortTraits > diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h index 034523f77..e8c7aab63 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h @@ -65,19 +65,46 @@ namespace bulkio { struct StreamDescriptor { StreamDescriptor(const std::string& streamID) : - sri(bulkio::sri::create(streamID)), - version(1) + _streamID(streamID), + _sri(bulkio::sri::create(streamID)), + _version(1) { } StreamDescriptor(const BULKIO::StreamSRI& sri) : - sri(sri), - version(1) + _streamID(sri.streamID), + _sri(sri), + _version(1) { } - BULKIO::StreamSRI sri; - int version; + const std::string& streamID() const + { + return _streamID; + } + + const BULKIO::StreamSRI& sri() const + { + return _sri; + } + + void setSRI(const BULKIO::StreamSRI& sri) + { + // Copy the new SRI, except for the stream ID, which is immutable + _sri = sri; + _sri.streamID = _streamID.c_str(); + ++_version; + } + + int version() const + { + return _version; + } + + protected: + const std::string _streamID; + BULKIO::StreamSRI _sri; + int _version; }; // @@ -276,7 +303,7 @@ namespace bulkio { OutPortSriMap currentSRIs __attribute__ ((deprecated)); protected: - typedef std::map SriTable; + typedef std::map > SriTable; SriTable _currentSRIs; // @@ -305,8 +332,7 @@ namespace bulkio { // bool _isStreamRoutedToConnection(const std::string& connectionID, const std::string& streamID); - const StreamDescriptor& _getSRI(const std::string& streamID); - + // // Sends data and metadata to all connections enabled for the given stream // @@ -315,7 +341,8 @@ namespace bulkio { bool EOS, const std::string& streamID); - virtual void addStream(const std::string& streamID, const BULKIO::StreamSRI& sri); + boost::shared_ptr _getStream(const std::string& streamID); + virtual boost::shared_ptr _addStream(const std::string& streamID, const BULKIO::StreamSRI& sri); virtual void removeStream(const std::string& streamID); }; @@ -466,7 +493,7 @@ namespace bulkio { typedef typename OutPortBase::PortPtrType PortPtrType; typedef typename OutPortBase::PortTransportType PortTransportType; - virtual void addStream(const std::string& streamID, const BULKIO::StreamSRI& sri); + virtual boost::shared_ptr _addStream(const std::string& streamID, const BULKIO::StreamSRI& sri); virtual void removeStream(const std::string& streamID); typedef std::map StreamMap; diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp index 774b2bde2..0969ee46d 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp @@ -26,38 +26,24 @@ using bulkio::OutputStream; template -class OutputStream::Impl { +class OutputStream::Impl : public bulkio::StreamDescriptor { public: typedef typename OutputStream::ScalarBuffer ScalarBuffer; typedef typename OutputStream::ComplexBuffer ComplexBuffer; Impl(const BULKIO::StreamSRI& sri, OutPortType* port) : - _streamID(sri.streamID), + bulkio::StreamDescriptor(sri), _port(port), - _sri(sri), _sriUpdated(true), _bufferSize(0), _bufferOffset(0) { } - const std::string& streamID() const - { - return _streamID; - } - - const BULKIO::StreamSRI& sri() const - { - return _sri; - } - void setSRI(const BULKIO::StreamSRI& sri) { _markDirtySRI(); - - // Copy the new SRI, except for the stream ID, which is immutable - _sri = sri; - _sri.streamID = _streamID.c_str(); + bulkio::StreamDescriptor::setSRI(sri); } void setXDelta(double delta) @@ -194,6 +180,11 @@ class OutputStream::Impl { { // Flush buffered data still using the old SRI flush(); + + // Increment the SRI version if this is the first change + if (!_sriUpdated) { + ++_version; + } _sriUpdated = true; } diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h index 0c879aafe..b9da24d35 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h @@ -37,6 +37,8 @@ namespace bulkio { template class OutPort; + class StreamDescriptor; + template class OutputStream { public: @@ -160,6 +162,8 @@ namespace bulkio { typedef OutPort OutPortType; OutputStream(const BULKIO::StreamSRI& sri, OutPortType* port); + boost::shared_ptr getDescriptor(); + class Impl; boost::shared_ptr _impl; From f3db847dc4cfd1a3a33925522e7e70cc8b484c86 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 29 Nov 2016 10:24:40 -0500 Subject: [PATCH 0564/1644] Expand StreamDescriptor and factor non-type-specific code out of OutStream template; use standard REDHAWK indent of 4 for restructured code --- bulkioInterfaces/libsrc/Makefile.am | 2 + bulkioInterfaces/libsrc/cpp/bulkio_out_port.h | 44 --- .../libsrc/cpp/bulkio_out_stream.cpp | 174 +---------- .../libsrc/cpp/bulkio_out_stream.h | 269 ++++++++---------- bulkioInterfaces/libsrc/cpp/bulkio_stream.cpp | 91 ++++++ bulkioInterfaces/libsrc/cpp/bulkio_stream.h | 186 ++++++++++++ 6 files changed, 403 insertions(+), 363 deletions(-) create mode 100644 bulkioInterfaces/libsrc/cpp/bulkio_stream.cpp create mode 100644 bulkioInterfaces/libsrc/cpp/bulkio_stream.h diff --git a/bulkioInterfaces/libsrc/Makefile.am b/bulkioInterfaces/libsrc/Makefile.am index af6f1cace..f5b0bd176 100644 --- a/bulkioInterfaces/libsrc/Makefile.am +++ b/bulkioInterfaces/libsrc/Makefile.am @@ -40,6 +40,7 @@ libbulkio_@BULKIO_API_VERSION@_la_SOURCES = \ cpp/bulkio_in_stream.cpp \ cpp/bulkio_out_port.cpp \ cpp/bulkio_out_stream.cpp \ + cpp/bulkio_stream.cpp \ cpp/bulkio_attachable_port.cpp \ cpp/bulkio_sri_helpers.cpp \ cpp/bulkio_time_helpers.cpp \ @@ -59,6 +60,7 @@ library_include_HEADERS = cpp/bulkio.h \ cpp/bulkio_in_stream.h \ cpp/bulkio_out_port.h \ cpp/bulkio_out_stream.h \ + cpp/bulkio_stream.h \ cpp/bulkio_attachable_base.h \ cpp/bulkio_time_operators.h \ cpp/bulkio_datablock.h \ diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h index e8c7aab63..868e5f26b 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h @@ -63,50 +63,6 @@ namespace bulkio { template class PortTransport; - struct StreamDescriptor { - StreamDescriptor(const std::string& streamID) : - _streamID(streamID), - _sri(bulkio::sri::create(streamID)), - _version(1) - { - } - - StreamDescriptor(const BULKIO::StreamSRI& sri) : - _streamID(sri.streamID), - _sri(sri), - _version(1) - { - } - - const std::string& streamID() const - { - return _streamID; - } - - const BULKIO::StreamSRI& sri() const - { - return _sri; - } - - void setSRI(const BULKIO::StreamSRI& sri) - { - // Copy the new SRI, except for the stream ID, which is immutable - _sri = sri; - _sri.streamID = _streamID.c_str(); - ++_version; - } - - int version() const - { - return _version; - } - - protected: - const std::string _streamID; - BULKIO::StreamSRI _sri; - int _version; - }; - // // OutPortBase // diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp index 0969ee46d..5a6da230e 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp @@ -26,66 +26,21 @@ using bulkio::OutputStream; template -class OutputStream::Impl : public bulkio::StreamDescriptor { +class OutputStream::Impl : public bulkio::StreamBase::Impl { public: typedef typename OutputStream::ScalarBuffer ScalarBuffer; typedef typename OutputStream::ComplexBuffer ComplexBuffer; Impl(const BULKIO::StreamSRI& sri, OutPortType* port) : - bulkio::StreamDescriptor(sri), + bulkio::StreamBase::Impl(sri), _port(port), - _sriUpdated(true), _bufferSize(0), _bufferOffset(0) { } - void setSRI(const BULKIO::StreamSRI& sri) - { - _markDirtySRI(); - bulkio::StreamDescriptor::setSRI(sri); - } - - void setXDelta(double delta) - { - _setStreamMetadata(_sri.xdelta, delta); - } - - void setComplex(bool mode) - { - _setStreamMetadata(_sri.mode, mode?1:0); - } - - void setBlocking(bool blocking) - { - _setStreamMetadata(_sri.blocking, blocking?1:0); - } - - void setKeywords(const _CORBA_Unbounded_Sequence& properties) - { - _markDirtySRI(); - _sri.keywords = properties; - } - - void setKeyword(const std::string& name, const CORBA::Any& value) - { - _markDirtySRI(); - redhawk::PropertyMap::cast(_sri.keywords)[name] = value; - } - - void eraseKeyword(const std::string& name) - { - _markDirtySRI(); - redhawk::PropertyMap::cast(_sri.keywords).erase(name); - } - void write(const ScalarBuffer& data, const BULKIO::PrecisionUTCTime& time) { - if (_sriUpdated) { - _port->pushSRI(_sri); - _sriUpdated = false; - } - // If buffering is disabled, or the buffer is empty and the input data is // large enough for a full buffer, send it immediately if ((_bufferSize == 0) || (_bufferOffset == 0 && (data.size() >= _bufferSize))) { @@ -176,33 +131,11 @@ class OutputStream::Impl : public bulkio::StreamDescriptor { } private: - void _markDirtySRI() - { - // Flush buffered data still using the old SRI - flush(); - - // Increment the SRI version if this is the first change - if (!_sriUpdated) { - ++_version; - } - _sriUpdated = true; - } - void _send(const ScalarBuffer& data, const BULKIO::PrecisionUTCTime& time, bool eos) { _port->pushPacket(data, time, eos, _streamID); } - template - void _setStreamMetadata(Field& field, Value value) - { - _markDirtySRI(); - if (field == value) { - return; - } - field = value; - } - void _flush(bool eos) { // Push out all buffered data, which must be less than the full allocated @@ -239,10 +172,7 @@ class OutputStream::Impl : public bulkio::StreamDescriptor { } } - const std::string _streamID; OutPortType* _port; - BULKIO::StreamSRI _sri; - bool _sriUpdated; redhawk::buffer _buffer; BULKIO::PrecisionUTCTime _bufferTime; @@ -252,68 +182,14 @@ class OutputStream::Impl : public bulkio::StreamDescriptor { template OutputStream::OutputStream() : - _impl() + StreamBase() { } template OutputStream::OutputStream(const BULKIO::StreamSRI& sri, OutPortType* port) : - _impl(new Impl(sri, port)) -{ -} - -template -const std::string& OutputStream::streamID() const -{ - return _impl->streamID(); -} - -template -const BULKIO::StreamSRI& OutputStream::sri() const -{ - return _impl->sri(); -} - -template -void OutputStream::sri(const BULKIO::StreamSRI& sri) -{ - _impl->setSRI(sri); -} - -template -double OutputStream::xdelta() const + StreamBase(boost::make_shared(sri, port)) { - return _impl->sri().xdelta; -} - -template -void OutputStream::xdelta(double delta) -{ - _impl->setXDelta(delta); -} - -template -bool OutputStream::complex() const -{ - return (_impl->sri().mode != 0); -} - -template -void OutputStream::complex(bool mode) -{ - _impl->setComplex(mode); -} - -template -bool OutputStream::blocking() const -{ - return _impl->sri().blocking; -} - -template -void OutputStream::blocking(bool mode) -{ - _impl->setBlocking(mode); } template @@ -334,48 +210,6 @@ void OutputStream::flush() _impl->flush(); } -template -const redhawk::PropertyMap& OutputStream::keywords() const -{ - return redhawk::PropertyMap::cast(_impl->sri().keywords); -} - -template -void OutputStream::keywords(const _CORBA_Unbounded_Sequence& props) -{ - _impl->setKeywords(props); -} - -template -bool OutputStream::hasKeyword(const std::string& name) const -{ - return keywords().contains(name); -} - -template -const redhawk::Value& OutputStream::getKeyword(const std::string& name) const -{ - return keywords()[name]; -} - -template -void OutputStream::setKeyword(const std::string& name, const CORBA::Any& value) -{ - _impl->setKeyword(name, value); -} - -template -void OutputStream::setKeyword(const std::string& name, const redhawk::Value& value) -{ - _impl->setKeyword(name, value); -} - -template -void OutputStream::eraseKeyword(const std::string& name) -{ - _impl->eraseKeyword(name); -} - template void OutputStream::write(const ScalarBuffer& data, const BULKIO::PrecisionUTCTime& time) { diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h index b9da24d35..6c334ce0f 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h @@ -31,158 +31,129 @@ #include "bulkio_traits.h" #include "bulkio_datablock.h" +#include "bulkio_stream.h" namespace bulkio { - template - class OutPort; - - class StreamDescriptor; - - template - class OutputStream { - public: - typedef typename PortTraits::DataTransferTraits::NativeDataType ScalarType; - typedef std::complex ComplexType; - - typedef redhawk::shared_buffer ScalarBuffer; - typedef redhawk::shared_buffer ComplexBuffer; - - OutputStream(); - - const std::string& streamID() const; - - const BULKIO::StreamSRI& sri() const; - void sri(const BULKIO::StreamSRI& sri); - - double xdelta() const; - void xdelta(double delta); - - bool complex() const; - void complex(bool mode); - - bool blocking() const; - void blocking(bool mode); - - const redhawk::PropertyMap& keywords() const; - void keywords(const _CORBA_Unbounded_Sequence& props); - - bool hasKeyword(const std::string& name) const; - const redhawk::Value& getKeyword(const std::string& name) const; - void setKeyword(const std::string& name, const CORBA::Any& value); - void setKeyword(const std::string& name, const redhawk::Value& value); - template - void setKeyword(const std::string& name, const T& value) - { - setKeyword(name, redhawk::Value(value)); - } - void eraseKeyword(const std::string& name); - - /** - * @brief Returns the internal buffer size. - * - * A buffer size of 0 indicates that buffering is disabled. - */ - size_t bufferSize() const; - - /** - * @brief Sets the internal buffer size. - * @param samples Number of samples to buffer (0 disables buffering). - */ - void setBufferSize(size_t samples); - - /** - * Send all currently buffered data. - */ - void flush(); - - template - void write(const std::vector& data, const BULKIO::PrecisionUTCTime& time) - { - write(&data[0], data.size(), time); - } - - template - void write(const std::vector& data, const std::list& times) - { - write(&data[0], data.size(), times); - } - - /** - * @brief Write scalar data to the stream. - * @param data The %read_buffer to write. - * @param time The timestamp of the first sample. - */ - void write(const ScalarBuffer& data, const BULKIO::PrecisionUTCTime& time); - - /** - * @brief Write scalar data to the stream. - * @param data The %read_buffer to write. - * @param times A list of sample timestamps. Sample offsets must be in - * increasing order, starting at 0. - * - * Writes a buffer of data with multiple timestamps, breaking up the data - * into chunks at the SampleTimestamp offsets. - */ - void write(const ScalarBuffer& data, const std::list& times); - - /** - * @brief Write complex data to the stream. - * @param data The %read_buffer to write. - * @param time The timestamp of the first sample. - */ - void write(const ComplexBuffer& data, const BULKIO::PrecisionUTCTime& time); - - /** - * @brief Write complex data to the stream. - * @param data The %read_buffer to write. - * @param times A list of sample timestamps. Sample offsets must be in - * increasing order, starting at 0. - * - * Writes a buffer of data with multiple timestamps, breaking up the data - * into chunks at the SampleTimestamp offsets. - */ - void write(const ComplexBuffer& data, const std::list& times); - - void write(const ScalarType* data, size_t count, const BULKIO::PrecisionUTCTime& time); - void write(const ScalarType* data, size_t count, const std::list& times); - - void write(const ComplexType* data, size_t count, const BULKIO::PrecisionUTCTime& time); - void write(const ComplexType* data, size_t count, const std::list& times); - - void close(); - - bool operator! () const - { - return !_impl; - } - - private: - friend class OutPort; - typedef OutPort OutPortType; - OutputStream(const BULKIO::StreamSRI& sri, OutPortType* port); - - boost::shared_ptr getDescriptor(); - - class Impl; - boost::shared_ptr _impl; - - typedef boost::shared_ptr OutputStream::*unspecified_bool_type; - - public: - operator unspecified_bool_type() const; - }; - - typedef OutputStream OutCharStream; - typedef OutputStream OutOctetStream; - typedef OutputStream OutShortStream; - typedef OutputStream OutUShortStream; - typedef OutputStream OutLongStream; - typedef OutputStream OutULongStream; - typedef OutputStream OutLongLongStream; - typedef OutputStream OutULongLongStream; - typedef OutputStream OutFloatStream; - typedef OutputStream OutDoubleStream; + template + class OutPort; + + template + class OutputStream : public StreamBase { + public: + typedef typename PortTraits::DataTransferTraits::NativeDataType ScalarType; + typedef std::complex ComplexType; + + typedef redhawk::shared_buffer ScalarBuffer; + typedef redhawk::shared_buffer ComplexBuffer; + + OutputStream(); + + /** + * @brief Returns the internal buffer size. + * + * A buffer size of 0 indicates that buffering is disabled. + */ + size_t bufferSize() const; + + /** + * @brief Sets the internal buffer size. + * @param samples Number of samples to buffer (0 disables buffering). + */ + void setBufferSize(size_t samples); + + /** + * Send all currently buffered data. + */ + void flush(); + + template + void write(const std::vector& data, const BULKIO::PrecisionUTCTime& time) + { + write(&data[0], data.size(), time); + } + + template + void write(const std::vector& data, const std::list& times) + { + write(&data[0], data.size(), times); + } + + /** + * @brief Write scalar data to the stream. + * @param data The %read_buffer to write. + * @param time The timestamp of the first sample. + */ + void write(const ScalarBuffer& data, const BULKIO::PrecisionUTCTime& time); + + /** + * @brief Write scalar data to the stream. + * @param data The %read_buffer to write. + * @param times A list of sample timestamps. Sample offsets must be in + * increasing order, starting at 0. + * + * Writes a buffer of data with multiple timestamps, breaking up the data + * into chunks at the SampleTimestamp offsets. + */ + void write(const ScalarBuffer& data, const std::list& times); + + /** + * @brief Write complex data to the stream. + * @param data The %read_buffer to write. + * @param time The timestamp of the first sample. + */ + void write(const ComplexBuffer& data, const BULKIO::PrecisionUTCTime& time); + + /** + * @brief Write complex data to the stream. + * @param data The %read_buffer to write. + * @param times A list of sample timestamps. Sample offsets must be in + * increasing order, starting at 0. + * + * Writes a buffer of data with multiple timestamps, breaking up the data + * into chunks at the SampleTimestamp offsets. + */ + void write(const ComplexBuffer& data, const std::list& times); + + void write(const ScalarType* data, size_t count, const BULKIO::PrecisionUTCTime& time); + void write(const ScalarType* data, size_t count, const std::list& times); + + void write(const ComplexType* data, size_t count, const BULKIO::PrecisionUTCTime& time); + void write(const ComplexType* data, size_t count, const std::list& times); + + void close(); + + bool operator! () const + { + return !_impl; + } + + private: + friend class OutPort; + typedef OutPort OutPortType; + OutputStream(const BULKIO::StreamSRI& sri, OutPortType* port); + + boost::shared_ptr getDescriptor(); + + class Impl; + boost::shared_ptr _impl; + + typedef boost::shared_ptr OutputStream::*unspecified_bool_type; + + public: + operator unspecified_bool_type() const; + }; + + typedef OutputStream OutCharStream; + typedef OutputStream OutOctetStream; + typedef OutputStream OutShortStream; + typedef OutputStream OutUShortStream; + typedef OutputStream OutLongStream; + typedef OutputStream OutULongStream; + typedef OutputStream OutLongLongStream; + typedef OutputStream OutULongLongStream; + typedef OutputStream OutFloatStream; + typedef OutputStream OutDoubleStream; } // end of bulkio namespace diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_stream.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_stream.cpp new file mode 100644 index 000000000..893cccca0 --- /dev/null +++ b/bulkioInterfaces/libsrc/cpp/bulkio_stream.cpp @@ -0,0 +1,91 @@ +#include "bulkio_stream.h" + +using bulkio::StreamBase; + +const std::string& StreamBase::streamID() const +{ + return _impl->streamID(); +} + +const BULKIO::StreamSRI& StreamBase::sri() const +{ + return _impl->sri(); +} + +void StreamBase::sri(const BULKIO::StreamSRI& sri) +{ + _impl->flush(); + _impl->setSRI(sri); +} + +double StreamBase::xdelta() const +{ + return _impl->xdelta(); +} + +void StreamBase::xdelta(double delta) +{ + _impl->flush(); + _impl->xdelta(delta); +} + +bool StreamBase::complex() const +{ + return _impl->complex(); +} + +void StreamBase::complex(bool mode) +{ + _impl->flush(); + _impl->complex(mode); +} + +bool StreamBase::blocking() const +{ + return _impl->sri().blocking; +} + +void StreamBase::blocking(bool mode) +{ + _impl->flush(); + _impl->blocking(mode); +} + +const redhawk::PropertyMap& StreamBase::keywords() const +{ + return _impl->keywords(); +} + +bool StreamBase::hasKeyword(const std::string& name) const +{ + return keywords().contains(name); +} + +const redhawk::Value& StreamBase::getKeyword(const std::string& name) const +{ + return keywords()[name]; +} + +void StreamBase::keywords(const _CORBA_Unbounded_Sequence& props) +{ + _impl->flush(); + _impl->keywords(props); +} + +void StreamBase::setKeyword(const std::string& name, const CORBA::Any& value) +{ + _impl->flush(); + _impl->setKeyword(name, value); +} + +void StreamBase::setKeyword(const std::string& name, const redhawk::Value& value) +{ + _impl->flush(); + _impl->setKeyword(name, value); +} + +void StreamBase::eraseKeyword(const std::string& name) +{ + _impl->flush(); + _impl->eraseKeyword(name); +} diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_stream.h b/bulkioInterfaces/libsrc/cpp/bulkio_stream.h new file mode 100644 index 000000000..2c8e74dc5 --- /dev/null +++ b/bulkioInterfaces/libsrc/cpp/bulkio_stream.h @@ -0,0 +1,186 @@ +#ifndef __bulkio_stream_h +#define __bulkio_stream_h + +#include + +#include + +#include + +#include "bulkio_base.h" + +namespace bulkio { + + struct StreamDescriptor { + StreamDescriptor(const std::string& streamID) : + _streamID(streamID), + _sri(bulkio::sri::create(streamID)), + _version(1) + { + } + + StreamDescriptor(const BULKIO::StreamSRI& sri) : + _streamID(sri.streamID), + _sri(sri), + _version(1) + { + } + + const std::string& streamID() const + { + return _streamID; + } + + const BULKIO::StreamSRI& sri() const + { + return _sri; + } + + double xdelta() const + { + return _sri.xdelta; + } + + void xdelta(double delta) + { + _setStreamMetadata(_sri.xdelta, delta); + } + + bool complex() const + { + return _sri.mode != 0; + } + + void complex(bool mode) + { + _setStreamMetadata(_sri.mode, mode?1:0); + } + + bool blocking() const + { + return _sri.blocking; + } + + void blocking(bool mode) + { + _setStreamMetadata(_sri.blocking, mode?1:0); + } + + const redhawk::PropertyMap& keywords() const + { + return redhawk::PropertyMap::cast(_sri.keywords); + } + + void keywords(const _CORBA_Unbounded_Sequence& properties) + { + _sri.keywords = properties; + ++_version; + } + + + void setKeyword(const std::string& name, const CORBA::Any& value) + { + redhawk::PropertyMap::cast(_sri.keywords)[name] = value; + ++_version; + } + + void setKeyword(const std::string& name, const redhawk::Value& value) + { + setKeyword(name, static_cast(value)); + } + + void eraseKeyword(const std::string& name) + { + redhawk::PropertyMap::cast(_sri.keywords).erase(name); + ++_version; + } + + void setSRI(const BULKIO::StreamSRI& sri) + { + // Copy the new SRI, except for the stream ID, which is immutable + _sri = sri; + _sri.streamID = _streamID.c_str(); + ++_version; + } + + int version() const + { + return _version; + } + + protected: + template + void _setStreamMetadata(Field& field, Value value) + { + if (field != value) { + field = value; + ++_version; + } + } + + const std::string _streamID; + BULKIO::StreamSRI _sri; + int _version; + }; + + class StreamBase { + public: + const std::string& streamID() const; + + const BULKIO::StreamSRI& sri() const; + void sri(const BULKIO::StreamSRI& sri); + + double xdelta() const; + void xdelta(double xdelta); + + bool complex() const; + void complex(bool mode); + + bool blocking() const; + void blocking(bool mode); + + const redhawk::PropertyMap& keywords() const; + bool hasKeyword(const std::string& name) const; + const redhawk::Value& getKeyword(const std::string& name) const; + + void keywords(const _CORBA_Unbounded_Sequence& props); + void setKeyword(const std::string& name, const CORBA::Any& value); + void setKeyword(const std::string& name, const redhawk::Value& value); + template + void setKeyword(const std::string& name, const T& value) + { + setKeyword(name, redhawk::Value(value)); + } + void eraseKeyword(const std::string& name); + + protected: + class Impl; + + StreamBase() : + _impl() + { + } + + StreamBase(boost::shared_ptr impl) : + _impl(impl) + { + } + + boost::shared_ptr _impl; + + class Impl : public StreamDescriptor { + public: + Impl(const BULKIO::StreamSRI& sri) : + StreamDescriptor(sri) + { + } + + virtual void flush() + { + } + }; + }; + +} + +#endif // __bulkio_stream_h From 90c02bba8fddb3f58a78e1ec2f1f22672da532d3 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 29 Nov 2016 11:32:57 -0500 Subject: [PATCH 0565/1644] Implement output streams for XML and file --- .../libsrc/cpp/bulkio_out_stream.cpp | 155 ++++++++++++++++-- .../libsrc/cpp/bulkio_out_stream.h | 70 +++++++- bulkioInterfaces/libsrc/cpp/bulkio_stream.cpp | 7 + bulkioInterfaces/libsrc/cpp/bulkio_stream.h | 15 ++ 4 files changed, 222 insertions(+), 25 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp index 5a6da230e..e910c9f80 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp @@ -118,7 +118,7 @@ class OutputStream::Impl : public bulkio::StreamBase::Impl { _flush(false); } - void close() + virtual void close() { if (_bufferOffset > 0) { // Add the end-of-stream marker to the buffered data and its timestamp @@ -195,80 +195,203 @@ OutputStream::OutputStream(const BULKIO::StreamSRI& sri, OutPortType template size_t OutputStream::bufferSize() const { - return _impl->bufferSize(); + return impl().bufferSize(); } template void OutputStream::setBufferSize(size_t samples) { - _impl->setBufferSize(samples); + impl().setBufferSize(samples); } template void OutputStream::flush() { - _impl->flush(); + impl().flush(); } template void OutputStream::write(const ScalarBuffer& data, const BULKIO::PrecisionUTCTime& time) { - _impl->write(data, time); + impl().write(data, time); } template void OutputStream::write(const ScalarBuffer& data, const std::list& times) { - _impl->write(data, times); + impl().write(data, times); } template void OutputStream::write(const ComplexBuffer& data, const BULKIO::PrecisionUTCTime& time) { - _impl->write(data, time); + impl().write(data, time); } template void OutputStream::write(const ComplexBuffer& data, const std::list& times) { - _impl->write(data, times); + impl().write(data, times); } template void OutputStream::write(const ScalarType* data, size_t count, const BULKIO::PrecisionUTCTime& time) { - _impl->write(ScalarBuffer::make_transient(data, count), time); + impl().write(ScalarBuffer::make_transient(data, count), time); } template void OutputStream::write(const ScalarType* data, size_t count, const std::list& times) { - _impl->write(ScalarBuffer::make_transient(data, count), times); + impl().write(ScalarBuffer::make_transient(data, count), times); } template void OutputStream::write(const ComplexType* data, size_t count, const BULKIO::PrecisionUTCTime& time) { - _impl->write(ComplexBuffer::make_transient(data, count), time); + impl().write(ComplexBuffer::make_transient(data, count), time); } template void OutputStream::write(const ComplexType* data, size_t count, const std::list& times) { - _impl->write(ComplexBuffer::make_transient(data, count), times); + impl().write(ComplexBuffer::make_transient(data, count), times); } template -void OutputStream::close() +typename OutputStream::Impl& OutputStream::impl() { - _impl->close(); - _impl.reset(); + return static_cast(*_impl); +} + +template +const typename OutputStream::Impl& OutputStream::impl() const +{ + return static_cast(*_impl); } template OutputStream::operator unspecified_bool_type() const { - return _impl?&OutputStream::_impl:0; + return _impl?static_cast(&OutputStream::impl):0; +} + + +// +// XML +// +using bulkio::XMLPortTraits; + +class OutputStream::Impl : public bulkio::StreamBase::Impl { +public: + Impl(const BULKIO::StreamSRI& sri, OutXMLPort* port) : + bulkio::StreamBase::Impl(sri), + _port(port) + { + } + + void write(const std::string& data) + { + _send(data, false); + } + + virtual void close() + { + // Send an empty packet with an end-of-stream marker + _send(std::string(), true); + } + +private: + void _send(const std::string& data, bool eos) + { + _port->pushPacket(data, true, _streamID); + } + + OutXMLPort* _port; +}; + +OutputStream::OutputStream() : + StreamBase() +{ +} + +OutputStream::OutputStream(const BULKIO::StreamSRI& sri, OutXMLPort* port) : + StreamBase(boost::make_shared(sri, port)) +{ +} + +void OutputStream::write(const std::string& xmlString) +{ + impl().write(xmlString); +} + +OutputStream::Impl& OutputStream::impl() +{ + return static_cast(*_impl); +} + +OutputStream::operator unspecified_bool_type() const +{ + return _impl?&OutputStream::impl:0; +} + +// +// File +// +using bulkio::FilePortTraits; + +class OutputStream::Impl : public bulkio::StreamBase::Impl { +public: + Impl(const BULKIO::StreamSRI& sri, OutFilePort* port) : + bulkio::StreamBase::Impl(sri), + _port(port) + { + } + + void write(const std::string& data, const BULKIO::PrecisionUTCTime& time) + { + _send(data, time, false); + } + + virtual void close() + { + // Send an empty packet with an end-of-stream marker; since there is no + // sample data, the timestamp does not matter + _send(std::string(), bulkio::time::utils::notSet(), true); + } + +private: + void _send(const std::string& data, const BULKIO::PrecisionUTCTime& time, bool eos) + { + _port->pushPacket(data, time, true, _streamID); + } + + OutFilePort* _port; +}; + +OutputStream::OutputStream() : + StreamBase() +{ +} + +OutputStream::OutputStream(const BULKIO::StreamSRI& sri, OutFilePort* port) : + StreamBase(boost::make_shared(sri, port)) +{ +} + +void OutputStream::write(const std::string& URL, const BULKIO::PrecisionUTCTime& time) +{ + impl().write(URL, time); +} + +OutputStream::Impl& OutputStream::impl() +{ + return static_cast(*_impl); +} + +OutputStream::operator unspecified_bool_type() const +{ + return _impl?&OutputStream::impl:0; } template class OutputStream; diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h index 6c334ce0f..dd7f0bb04 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h @@ -121,13 +121,6 @@ namespace bulkio { void write(const ComplexType* data, size_t count, const BULKIO::PrecisionUTCTime& time); void write(const ComplexType* data, size_t count, const std::list& times); - void close(); - - bool operator! () const - { - return !_impl; - } - private: friend class OutPort; typedef OutPort OutPortType; @@ -136,9 +129,66 @@ namespace bulkio { boost::shared_ptr getDescriptor(); class Impl; - boost::shared_ptr _impl; + Impl& impl(); + const Impl& impl() const; + + typedef const OutputStream::Impl& (OutputStream::*unspecified_bool_type)() const; + + public: + operator unspecified_bool_type() const; + }; + + + class OutXMLPort; + + template <> + class OutputStream : public StreamBase { + public: + OutputStream(); + + /** + * @brief Write XML data to the stream. + * @param xmlString The XML string to write. + */ + void write(const std::string& xmlString); + + private: + OutputStream(const BULKIO::StreamSRI& sri, OutXMLPort* port); + + boost::shared_ptr getDescriptor(); + + class Impl; + Impl& impl(); + + typedef OutputStream::Impl& (OutputStream::*unspecified_bool_type)(); + + public: + operator unspecified_bool_type() const; + }; + + + class OutFilePort; + + template <> + class OutputStream : public StreamBase { + public: + OutputStream(); + + /** + * @brief Write a file URI to the stream. + * @param data The file URI to write. + */ + void write(const std::string& URL, const BULKIO::PrecisionUTCTime& time); + + private: + OutputStream(const BULKIO::StreamSRI& sri, OutFilePort* port); + + boost::shared_ptr getDescriptor(); + + class Impl; + Impl& impl(); - typedef boost::shared_ptr OutputStream::*unspecified_bool_type; + typedef OutputStream::Impl& (OutputStream::*unspecified_bool_type)(); public: operator unspecified_bool_type() const; @@ -154,6 +204,8 @@ namespace bulkio { typedef OutputStream OutULongLongStream; typedef OutputStream OutFloatStream; typedef OutputStream OutDoubleStream; + typedef OutputStream OutXMLStream; + typedef OutputStream OutFileStream; } // end of bulkio namespace diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_stream.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_stream.cpp index 893cccca0..d64535330 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_stream.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_stream.cpp @@ -89,3 +89,10 @@ void StreamBase::eraseKeyword(const std::string& name) _impl->flush(); _impl->eraseKeyword(name); } + +void StreamBase::close() +{ + _impl->close(); + _impl.reset(); +} + diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_stream.h b/bulkioInterfaces/libsrc/cpp/bulkio_stream.h index 2c8e74dc5..717520f4e 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_stream.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_stream.h @@ -153,6 +153,13 @@ namespace bulkio { } void eraseKeyword(const std::string& name); + void close(); + + bool operator! () const + { + return !_impl; + } + protected: class Impl; @@ -175,9 +182,17 @@ namespace bulkio { { } + virtual ~Impl() + { + } + virtual void flush() { } + + virtual void close() + { + } }; }; From bfb0c2a2d16d2c2100849b9cc168065e6708d0cb Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 29 Nov 2016 16:44:32 -0500 Subject: [PATCH 0566/1644] Unify stream handling for all BulkIO out data types, removing redundant data structures and adding stream API to File and XML ports --- .../libsrc/cpp/bulkio_out_port.cpp | 234 ++++++++---------- bulkioInterfaces/libsrc/cpp/bulkio_out_port.h | 95 +++---- .../libsrc/cpp/bulkio_out_stream.cpp | 12 +- .../libsrc/cpp/bulkio_out_stream.h | 22 +- bulkioInterfaces/libsrc/cpp/bulkio_stream.h | 5 + 5 files changed, 160 insertions(+), 208 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp index fee676747..331cd3875 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp @@ -81,17 +81,18 @@ namespace bulkio { const std::string sid(H.streamID); SCOPED_LOCK lock(updatingPortsLock); // don't want to process while command information is coming in - boost::shared_ptr stream; - SriTable::iterator existing = _currentSRIs.find(sid); - if (existing == _currentSRIs.end()) { + StreamType stream; + typename StreamMap::iterator existing = streams.find(sid); + if (existing == streams.end()) { // Insert new SRI - stream = _addStream(sid, H); + stream = StreamType(H, static_cast*>(this)); + streams[sid] = stream; } else { // Overwrite existing SRI stream = existing->second; - stream->setSRI(H); + stream.sri(H); } - const BULKIO::StreamSRI& sri = stream->sri(); + const BULKIO::StreamSRI& sri = stream.sri(); if (active) { for (TransportIterator iter = _transports.begin(); iter != _transports.end(); ++iter) { @@ -106,9 +107,9 @@ namespace bulkio { } LOG_DEBUG(logger,"pushSRI - PORT:" << name << " CONNECTION:" << connection_id << " SRI streamID:" - << stream->streamID() << " Mode:" << sri.mode << " XDELTA:" << 1.0/sri.xdelta); + << stream.streamID() << " Mode:" << sri.mode << " XDELTA:" << 1.0/sri.xdelta); try { - port->pushSRI(sid, sri, stream->version()); + port->pushSRI(sid, sri, stream.modcount()); } catch (const redhawk::FatalTransportError& err) { LOG_ERROR(logger, "PUSH-SRI FAILED " << err.what() << " PORT/CONNECTION: " << name << "/" << connection_id); @@ -157,16 +158,17 @@ namespace bulkio { template < typename PortTraits > - boost::shared_ptr OutPortBase< PortTraits >::_getStream(const std::string& streamID) + typename OutPortBase::StreamType OutPortBase< PortTraits >::_getStream(const std::string& streamID) { - SriTable::iterator existing = _currentSRIs.find(streamID); - if (existing == _currentSRIs.end()) { + typename StreamMap::iterator existing = streams.find(streamID); + if (existing == streams.end()) { LOG_TRACE(logger, "Creating new stream '" << streamID << "' with default SRI"); // No SRI associated with the stream ID, create a default one and add // it to the list; it will get pushed to downstream connections below - _currentSRIs[streamID] = _addStream(streamID, bulkio::sri::create(streamID)); - return _currentSRIs[streamID]; + StreamType stream(bulkio::sri::create(streamID), static_cast*>(this)); + streams[streamID] = stream; + return stream; } else { return existing->second; } @@ -184,7 +186,7 @@ namespace bulkio { SCOPED_LOCK lock(this->updatingPortsLock); // grab SRI context - boost::shared_ptr stream = _getStream(streamID); + StreamType stream = _getStream(streamID); if (active) { for (TransportIterator iter = _transports.begin(); iter != _transports.end(); ++iter) { @@ -203,8 +205,8 @@ namespace bulkio { } try { - port->pushSRI(streamID, stream->sri(), stream->version()); - port->pushPacket(data, T, EOS, streamID, stream->sri()); + port->pushSRI(streamID, stream.sri(), stream.modcount()); + port->pushPacket(data, T, EOS, streamID, stream.sri()); } catch (const redhawk::FatalTransportError& err) { LOG_ERROR(logger, "PUSH-PACKET FAILED " << err.what() << " PORT/CONNECTION: " << name << "/" << connection_id); @@ -215,8 +217,7 @@ namespace bulkio { // if we have end of stream removed old sri if (EOS) { - _currentSRIs.erase(streamID); - removeStream(streamID); + streams.erase(streamID); } } @@ -300,13 +301,65 @@ namespace bulkio { } + template + typename OutPortBase::StreamType OutPortBase::getStream(const std::string& streamID) + { + boost::mutex::scoped_lock lock(updatingPortsLock); + typename StreamMap::iterator stream = streams.find(streamID); + if (stream != streams.end()) { + return stream->second; + } else { + return StreamType(); + } + } + + template + typename OutPortBase::StreamList OutPortBase::getStreams() + { + StreamList result; + boost::mutex::scoped_lock lock(updatingPortsLock); + for (typename StreamMap::const_iterator stream = streams.begin(); stream != streams.end(); ++stream) { + result.push_back(stream->second); + } + return result; + } + + template < typename PortTraits > + typename OutPortBase< PortTraits >::StreamType OutPortBase< PortTraits >::createStream(const std::string& streamID) + { + boost::mutex::scoped_lock lock(updatingPortsLock); + typename StreamMap::iterator existing = streams.find(streamID); + if (existing != streams.end()) { + return existing->second; + } + StreamType stream(bulkio::sri::create(streamID), static_cast*>(this)); + streams[streamID] = stream; + return stream; + } + + template < typename PortTraits > + typename OutPortBase< PortTraits >::StreamType OutPortBase< PortTraits >::createStream(const BULKIO::StreamSRI& sri) + { + boost::mutex::scoped_lock lock(updatingPortsLock); + const std::string streamID(sri.streamID); + typename StreamMap::iterator existing = streams.find(streamID); + if (existing != streams.end()) { + // Update the stream's SRI from the argument + existing->second.sri(sri); + return existing->second; + } + StreamType stream(sri, static_cast*>(this)); + streams[streamID] = stream; + return stream; + } + template < typename PortTraits > bulkio::SriMap OutPortBase< PortTraits >::getCurrentSRI() { bulkio::SriMap ret; SCOPED_LOCK lock(updatingPortsLock); // restrict access till method completes - for (SriTable::iterator cSri = _currentSRIs.begin() ; cSri != _currentSRIs.end(); ++cSri) { - ret[cSri->first] = std::make_pair(cSri->second->sri(), false); + for (typename StreamMap::iterator stream = streams.begin() ; stream != streams.end(); ++stream) { + ret[stream->first] = std::make_pair(stream->second.sri(), false); } return ret; } @@ -316,8 +369,8 @@ namespace bulkio { { bulkio::SriList ret; SCOPED_LOCK lock(updatingPortsLock); // restrict access till method completes - for (SriTable::iterator cSri = _currentSRIs.begin() ; cSri != _currentSRIs.end(); ++cSri) { - ret.push_back(cSri->second->sri()); + for (typename StreamMap::iterator stream = streams.begin() ; stream != streams.end(); ++stream) { + ret.push_back(stream->second.sri()); } return ret; } @@ -368,17 +421,6 @@ namespace bulkio { //return "IDL:CORBA/Object:1.0"; } - template < typename PortTraits > - boost::shared_ptr OutPortBase< PortTraits >::_addStream(const std::string& streamID, const BULKIO::StreamSRI& sri) - { - return boost::make_shared(sri); - } - - template < typename PortTraits > - void OutPortBase< PortTraits >::removeStream(const std::string& streamID) - { - } - /* OutPort Constructor @@ -459,80 +501,6 @@ namespace bulkio { this->_sendPacket(data, T, EOS, streamID); } - template < typename PortTraits > - typename OutPort< PortTraits >::StreamType OutPort< PortTraits >::createStream(const std::string& streamID) - { - boost::mutex::scoped_lock lock(streamsMutex); - typename StreamMap::iterator existing = streams.find(streamID); - if (existing != streams.end()) { - return existing->second; - } - StreamType stream(bulkio::sri::create(streamID), this); - streams[streamID] = stream; - return stream; - } - - template < typename PortTraits > - typename OutPort< PortTraits >::StreamType OutPort< PortTraits >::createStream(const BULKIO::StreamSRI& sri) - { - boost::mutex::scoped_lock lock(streamsMutex); - const std::string streamID(sri.streamID); - typename StreamMap::iterator existing = streams.find(streamID); - if (existing != streams.end()) { - // Update the stream's SRI from the argument - existing->second.sri(sri); - return existing->second; - } - StreamType stream(sri, this); - streams[streamID] = stream; - return stream; - } - - template < typename PortTraits > - typename OutPort< PortTraits >::StreamType OutPort< PortTraits >::getStream(const std::string& streamID) - { - boost::mutex::scoped_lock lock(streamsMutex); - typename StreamMap::iterator stream = streams.find(streamID); - if (stream != streams.end()) { - return stream->second; - } else { - return StreamType(); - } - } - - template < typename PortTraits > - typename OutPort< PortTraits >::StreamList OutPort< PortTraits >::getStreams() - { - StreamList result; - boost::mutex::scoped_lock lock(streamsMutex); - for (typename StreamMap::const_iterator stream = streams.begin(); stream != streams.end(); ++stream) { - result.push_back(stream->second); - } - return result; - } - - template < typename PortTraits > - boost::shared_ptr OutPort< PortTraits >::_addStream(const std::string& streamID, const BULKIO::StreamSRI& sri) - { - boost::mutex::scoped_lock lock(streamsMutex); - typename StreamMap::iterator existing = streams.find(streamID); - if (existing == streams.end()) { - // Only create a new stream if one doesn't already exist; when a stream - // is created via createStream (the preferred method), its first call - // to pushSRI will end up calling this method - existing = streams.insert(std::make_pair(streamID, StreamType(sri, this))).first; - } - return existing->second.getDescriptor(); - } - - template < typename PortTraits > - void OutPort< PortTraits >::removeStream(const std::string& streamID) - { - boost::mutex::scoped_lock lock(streamsMutex); - streams.erase(streamID); - } - - OutCharPort::OutCharPort( std::string name, ConnectionEventListener *connectCB, ConnectionEventListener *disconnectCB ): @@ -577,31 +545,29 @@ namespace bulkio { } - OutFilePort::OutFilePort ( std::string name, - ConnectionEventListener *connectCB, - ConnectionEventListener *disconnectCB ) : - OutPortBase < FilePortTraits >(name, LOGGER_PTR(), connectCB, disconnectCB ) + OutPort::OutPort (const std::string& name, + ConnectionEventListener *connectCB, + ConnectionEventListener *disconnectCB) : + OutPortBase (name, LOGGER_PTR(), connectCB, disconnectCB) { - } - OutFilePort::OutFilePort( std::string name, - LOGGER_PTR logger, - ConnectionEventListener *connectCB, - ConnectionEventListener *disconnectCB ) : - OutPortBase < FilePortTraits >(name,logger,connectCB, disconnectCB ) + OutPort::OutPort (const std::string& name, + LOGGER_PTR logger, + ConnectionEventListener *connectCB, + ConnectionEventListener *disconnectCB) : + OutPortBase(name,logger, connectCB, disconnectCB) { - } - void OutFilePort::pushPacket(const std::string& URL, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID) + void OutPort::pushPacket(const std::string& URL, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID) { _sendPacket(URL, T, EOS, streamID); } - void OutFilePort::pushPacket(const char* URL, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID) + void OutPort::pushPacket(const char* URL, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID) { std::string url_out; if (URL) { @@ -610,32 +576,30 @@ namespace bulkio { this->pushPacket(url_out, T, EOS, streamID); } - void OutFilePort::pushPacket(const char *data, bool EOS, const std::string& streamID) + void OutPort::pushPacket(const char *data, bool EOS, const std::string& streamID) { this->pushPacket(data, bulkio::time::utils::now(), EOS, streamID); } - OutXMLPort::OutXMLPort ( std::string name, - ConnectionEventListener *connectCB, - ConnectionEventListener *disconnectCB ) : - OutPortBase < XMLPortTraits >(name, LOGGER_PTR(), connectCB, disconnectCB ) + OutPort::OutPort (const std::string& name, + ConnectionEventListener *connectCB, + ConnectionEventListener *disconnectCB) : + OutPortBase(name, LOGGER_PTR(), connectCB, disconnectCB) { - } - OutXMLPort::OutXMLPort( std::string name, - LOGGER_PTR logger, - ConnectionEventListener *connectCB, - ConnectionEventListener *disconnectCB ) : - OutPortBase < XMLPortTraits >(name,logger,connectCB, disconnectCB ) + OutPort::OutPort(const std::string& name, + LOGGER_PTR logger, + ConnectionEventListener *connectCB, + ConnectionEventListener *disconnectCB) : + OutPortBase(name,logger,connectCB, disconnectCB) { - } - void OutXMLPort::pushPacket(const char *data, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID) + void OutPort::pushPacket(const char *data, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID) { std::string data_out; if (data) { @@ -645,7 +609,7 @@ namespace bulkio { } - void OutXMLPort::pushPacket(const std::string& data, bool EOS, const std::string& streamID) + void OutPort::pushPacket(const std::string& data, bool EOS, const std::string& streamID) { // The time argument is never dereferenced for dataXML, so it is safe to // pass a null @@ -653,7 +617,7 @@ namespace bulkio { _sendPacket(data, *time, EOS, streamID); } - void OutXMLPort::pushPacket(const char* data, bool EOS, const std::string& streamID) + void OutPort::pushPacket(const char* data, bool EOS, const std::string& streamID) { std::string data_out; if (data) { diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h index 868e5f26b..c0af95116 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h @@ -112,6 +112,11 @@ namespace bulkio { // typedef typename Traits::NativeType NativeType; + // + // OutputStream class + // + typedef OutputStream StreamType; + // // ConnectionList Definition // @@ -217,6 +222,17 @@ namespace bulkio { // virtual BULKIO::PortUsageType state(); + typedef std::list StreamList; + StreamList getStreams(); + + StreamType getStream(const std::string& streamID); + + // Create a new stream based on a stream ID + StreamType createStream(const std::string& streamID); + + // Create a new stream based on an SRI instance + StreamType createStream(const BULKIO::StreamSRI& sri); + // // turn on/off the port monitoring capability // @@ -259,9 +275,6 @@ namespace bulkio { OutPortSriMap currentSRIs __attribute__ ((deprecated)); protected: - typedef std::map > SriTable; - SriTable _currentSRIs; - // // Lookup table for connections to input ports in the same process space // @@ -275,6 +288,9 @@ namespace bulkio { typedef redhawk::UsesPort::TransportIteratorAdapter TransportIterator; + typedef std::map StreamMap; + StreamMap streams; + std::vector filterTable; boost::shared_ptr< ConnectionEventListener > _connectCB; boost::shared_ptr< ConnectionEventListener > _disconnectCB; @@ -297,9 +313,7 @@ namespace bulkio { bool EOS, const std::string& streamID); - boost::shared_ptr _getStream(const std::string& streamID); - virtual boost::shared_ptr _addStream(const std::string& streamID, const BULKIO::StreamSRI& sri); - virtual void removeStream(const std::string& streamID); + StreamType _getStream(const std::string& streamID); }; @@ -354,11 +368,6 @@ namespace bulkio { // typedef std::map< std::string, SriMapStruct > OutPortSriMap; - // - // OutputStream class - // - typedef OutputStream StreamType; - typedef typename Traits::SharedBufferType SharedBufferType; // @@ -433,29 +442,13 @@ namespace bulkio { void pushPacket(const SharedBufferType& data, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID); - // Create a new stream based on a stream ID - StreamType createStream(const std::string& streamID); - // Create a new stream based on an SRI instance - StreamType createStream(const BULKIO::StreamSRI& sri); using OutPortBase::currentSRIs; - StreamType getStream(const std::string& streamID); - - typedef std::list StreamList; - StreamList getStreams(); - protected: using OutPortBase::logger; typedef typename OutPortBase::PortPtrType PortPtrType; typedef typename OutPortBase::PortTransportType PortTransportType; - virtual boost::shared_ptr _addStream(const std::string& streamID, const BULKIO::StreamSRI& sri); - virtual void removeStream(const std::string& streamID); - - typedef std::map StreamMap; - StreamMap streams; - boost::mutex streamsMutex; - virtual PortTransportType* _createRemoteConnection(PortPtrType port, const std::string& connectionId); }; @@ -476,9 +469,6 @@ namespace bulkio { ConnectionEventListener *connectCB=NULL, ConnectionEventListener *disconnectCB=NULL ); - - virtual ~OutCharPort() {}; - // Push a vector of Int8 data void pushPacket(const std::vector< Int8 >& data, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID); @@ -500,7 +490,8 @@ namespace bulkio { // This class defines the pushPacket interface for file URL data. // // - class OutFilePort : public OutPortBase < FilePortTraits > { + template <> + class OutPort : public OutPortBase { public: @@ -537,19 +528,15 @@ namespace bulkio { typedef Traits::NativeType NativeType; - OutFilePort( std::string pname, - ConnectionEventListener *connectCB=NULL, - ConnectionEventListener *disconnectCB=NULL ); - - - OutFilePort( std::string port_name, - LOGGER_PTR logger, - ConnectionEventListener *connectCB=NULL, - ConnectionEventListener *disconnectCB=NULL ); - + OutPort(const std::string& name, + ConnectionEventListener *connectCB=NULL, + ConnectionEventListener *disconnectCB=NULL ); - virtual ~OutFilePort() {}; + OutPort(const std::string& name, + LOGGER_PTR logger, + ConnectionEventListener *connectCB=NULL, + ConnectionEventListener *disconnectCB=NULL ); /* * pushPacket @@ -597,7 +584,8 @@ namespace bulkio { // This class defines the pushPacket interface for XML data. // // - class OutXMLPort : public OutPortBase < XMLPortTraits > { + template <> + class OutPort : public OutPortBase { public: @@ -636,19 +624,15 @@ namespace bulkio { typedef Traits::NativeType NativeType; - OutXMLPort( std::string pname, - ConnectionEventListener *connectCB=NULL, - ConnectionEventListener *disconnectCB=NULL ); - - - OutXMLPort( std::string port_name, - LOGGER_PTR logger, - ConnectionEventListener *connectCB=NULL, - ConnectionEventListener *disconnectCB=NULL ); - + OutPort(const std::string& name, + ConnectionEventListener *connectCB=NULL, + ConnectionEventListener *disconnectCB=NULL); - virtual ~OutXMLPort() {}; + OutPort(const std::string& name, + LOGGER_PTR logger, + ConnectionEventListener *connectCB=NULL, + ConnectionEventListener *disconnectCB=NULL); /* * DEPRECATED: maps to dataFile BULKIO method call for passing strings of data @@ -715,7 +699,10 @@ namespace bulkio { // Bulkio double output typedef OutPort< DoublePortTraits > OutDoublePort; // Bulkio URL output + typedef OutPort OutFilePort; typedef OutFilePort OutURLPort; + // Bulkio XML output + typedef OutPort OutXMLPort; } // end of bulkio namespace diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp index e910c9f80..6ae1b934d 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp @@ -284,7 +284,7 @@ using bulkio::XMLPortTraits; class OutputStream::Impl : public bulkio::StreamBase::Impl { public: - Impl(const BULKIO::StreamSRI& sri, OutXMLPort* port) : + Impl(const BULKIO::StreamSRI& sri, OutPortType* port) : bulkio::StreamBase::Impl(sri), _port(port) { @@ -307,7 +307,7 @@ class OutputStream::Impl : public bulkio::StreamBase::Impl { _port->pushPacket(data, true, _streamID); } - OutXMLPort* _port; + OutPortType* _port; }; OutputStream::OutputStream() : @@ -315,7 +315,7 @@ OutputStream::OutputStream() : { } -OutputStream::OutputStream(const BULKIO::StreamSRI& sri, OutXMLPort* port) : +OutputStream::OutputStream(const BULKIO::StreamSRI& sri, OutPortType* port) : StreamBase(boost::make_shared(sri, port)) { } @@ -342,7 +342,7 @@ using bulkio::FilePortTraits; class OutputStream::Impl : public bulkio::StreamBase::Impl { public: - Impl(const BULKIO::StreamSRI& sri, OutFilePort* port) : + Impl(const BULKIO::StreamSRI& sri, OutPortType* port) : bulkio::StreamBase::Impl(sri), _port(port) { @@ -366,7 +366,7 @@ class OutputStream::Impl : public bulkio::StreamBase::Impl { _port->pushPacket(data, time, true, _streamID); } - OutFilePort* _port; + OutPortType* _port; }; OutputStream::OutputStream() : @@ -374,7 +374,7 @@ OutputStream::OutputStream() : { } -OutputStream::OutputStream(const BULKIO::StreamSRI& sri, OutFilePort* port) : +OutputStream::OutputStream(const BULKIO::StreamSRI& sri, OutPortType* port) : StreamBase(boost::make_shared(sri, port)) { } diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h index dd7f0bb04..52c71a2d1 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h @@ -35,6 +35,8 @@ namespace bulkio { + template + class OutPortBase; template class OutPort; @@ -122,12 +124,10 @@ namespace bulkio { void write(const ComplexType* data, size_t count, const std::list& times); private: - friend class OutPort; + friend class OutPortBase; typedef OutPort OutPortType; OutputStream(const BULKIO::StreamSRI& sri, OutPortType* port); - boost::shared_ptr getDescriptor(); - class Impl; Impl& impl(); const Impl& impl() const; @@ -139,8 +139,6 @@ namespace bulkio { }; - class OutXMLPort; - template <> class OutputStream : public StreamBase { public: @@ -153,9 +151,9 @@ namespace bulkio { void write(const std::string& xmlString); private: - OutputStream(const BULKIO::StreamSRI& sri, OutXMLPort* port); - - boost::shared_ptr getDescriptor(); + friend class OutPortBase; + typedef OutPort OutPortType; + OutputStream(const BULKIO::StreamSRI& sri, OutPortType* port); class Impl; Impl& impl(); @@ -167,8 +165,6 @@ namespace bulkio { }; - class OutFilePort; - template <> class OutputStream : public StreamBase { public: @@ -181,9 +177,9 @@ namespace bulkio { void write(const std::string& URL, const BULKIO::PrecisionUTCTime& time); private: - OutputStream(const BULKIO::StreamSRI& sri, OutFilePort* port); - - boost::shared_ptr getDescriptor(); + friend class OutPortBase; + typedef OutPort OutPortType; + OutputStream(const BULKIO::StreamSRI& sri, OutPortType* port); class Impl; Impl& impl(); diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_stream.h b/bulkioInterfaces/libsrc/cpp/bulkio_stream.h index 717520f4e..02bcbd769 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_stream.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_stream.h @@ -160,6 +160,11 @@ namespace bulkio { return !_impl; } + int modcount() const + { + return _impl->version(); + } + protected: class Impl; From 19c7fad1025f12325bfa061d9e6ddc05691f111b Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 30 Nov 2016 08:46:47 -0500 Subject: [PATCH 0567/1644] Simplify relationship between C++ BulkIO output ports and streams by using _sendPacket() directly; remove pushPacket() interface that takes shared buffers to reduce API clutter --- bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp | 17 ++++------------- bulkioInterfaces/libsrc/cpp/bulkio_out_port.h | 3 +-- .../libsrc/cpp/bulkio_out_stream.cpp | 10 +++++++--- bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h | 8 +++----- 4 files changed, 15 insertions(+), 23 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp index 331cd3875..4e62ef1c6 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp @@ -85,7 +85,7 @@ namespace bulkio { typename StreamMap::iterator existing = streams.find(sid); if (existing == streams.end()) { // Insert new SRI - stream = StreamType(H, static_cast*>(this)); + stream = StreamType(H, this); streams[sid] = stream; } else { // Overwrite existing SRI @@ -166,7 +166,7 @@ namespace bulkio { // No SRI associated with the stream ID, create a default one and add // it to the list; it will get pushed to downstream connections below - StreamType stream(bulkio::sri::create(streamID), static_cast*>(this)); + StreamType stream(bulkio::sri::create(streamID), this); streams[streamID] = stream; return stream; } else { @@ -332,7 +332,7 @@ namespace bulkio { if (existing != streams.end()) { return existing->second; } - StreamType stream(bulkio::sri::create(streamID), static_cast*>(this)); + StreamType stream(bulkio::sri::create(streamID), this); streams[streamID] = stream; return stream; } @@ -348,7 +348,7 @@ namespace bulkio { existing->second.sri(sri); return existing->second; } - StreamType stream(sri, static_cast*>(this)); + StreamType stream(sri, this); streams[streamID] = stream; return stream; } @@ -492,15 +492,6 @@ namespace bulkio { this->_sendPacket(SharedBufferType::make_transient(ptr, size), T, EOS, streamID); } - template < typename PortTraits > - void OutPort< PortTraits >::pushPacket(const SharedBufferType& data, - const BULKIO::PrecisionUTCTime& T, - bool EOS, - const std::string& streamID) - { - this->_sendPacket(data, T, EOS, streamID); - } - OutCharPort::OutCharPort( std::string name, ConnectionEventListener *connectCB, ConnectionEventListener *disconnectCB ): diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h index c0af95116..5382b76c5 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h @@ -308,6 +308,7 @@ namespace bulkio { // // Sends data and metadata to all connections enabled for the given stream // + friend class OutputStream; void _sendPacket(const SharedBufferType& data, const BULKIO::PrecisionUTCTime& T, bool EOS, @@ -440,8 +441,6 @@ namespace bulkio { */ void pushPacket( const DataBufferType & data, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID); - void pushPacket(const SharedBufferType& data, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID); - using OutPortBase::currentSRIs; protected: diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp index 6ae1b934d..df03b89a7 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp @@ -133,7 +133,7 @@ class OutputStream::Impl : public bulkio::StreamBase::Impl { private: void _send(const ScalarBuffer& data, const BULKIO::PrecisionUTCTime& time, bool eos) { - _port->pushPacket(data, time, eos, _streamID); + _port->_sendPacket(data, time, eos, _streamID); } void _flush(bool eos) @@ -304,7 +304,11 @@ class OutputStream::Impl : public bulkio::StreamBase::Impl { private: void _send(const std::string& data, bool eos) { - _port->pushPacket(data, true, _streamID); + // Because it's templatized, the port's interface requires a timestamp; + // however, since it's not used for XML ports, creating a method-static + // instance is sufficient + static BULKIO::PrecisionUTCTime unused; + _port->_sendPacket(data, unused, true, _streamID); } OutPortType* _port; @@ -363,7 +367,7 @@ class OutputStream::Impl : public bulkio::StreamBase::Impl { private: void _send(const std::string& data, const BULKIO::PrecisionUTCTime& time, bool eos) { - _port->pushPacket(data, time, true, _streamID); + _port->_sendPacket(data, time, true, _streamID); } OutPortType* _port; diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h index 52c71a2d1..0a5da295e 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h @@ -37,8 +37,6 @@ namespace bulkio { template class OutPortBase; - template - class OutPort; template class OutputStream : public StreamBase { @@ -125,7 +123,7 @@ namespace bulkio { private: friend class OutPortBase; - typedef OutPort OutPortType; + typedef OutPortBase OutPortType; OutputStream(const BULKIO::StreamSRI& sri, OutPortType* port); class Impl; @@ -152,7 +150,7 @@ namespace bulkio { private: friend class OutPortBase; - typedef OutPort OutPortType; + typedef OutPortBase OutPortType; OutputStream(const BULKIO::StreamSRI& sri, OutPortType* port); class Impl; @@ -178,7 +176,7 @@ namespace bulkio { private: friend class OutPortBase; - typedef OutPort OutPortType; + typedef OutPortBase OutPortType; OutputStream(const BULKIO::StreamSRI& sri, OutPortType* port); class Impl; From cf8b9f1e17f9d7267e18cc486511b1a264aa1beb Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 30 Nov 2016 11:17:07 -0500 Subject: [PATCH 0568/1644] Combine StreamDescriptor and base stream class --- bulkioInterfaces/libsrc/cpp/bulkio_stream.cpp | 16 +- bulkioInterfaces/libsrc/cpp/bulkio_stream.h | 221 ++++++++---------- 2 files changed, 100 insertions(+), 137 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_stream.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_stream.cpp index d64535330..603de40f9 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_stream.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_stream.cpp @@ -20,40 +20,40 @@ void StreamBase::sri(const BULKIO::StreamSRI& sri) double StreamBase::xdelta() const { - return _impl->xdelta(); + return sri().xdelta; } void StreamBase::xdelta(double delta) { _impl->flush(); - _impl->xdelta(delta); + _impl->setXDelta(delta); } bool StreamBase::complex() const { - return _impl->complex(); + return (sri().mode != 0); } void StreamBase::complex(bool mode) { _impl->flush(); - _impl->complex(mode); + _impl->setComplex(mode); } bool StreamBase::blocking() const { - return _impl->sri().blocking; + return sri().blocking; } void StreamBase::blocking(bool mode) { _impl->flush(); - _impl->blocking(mode); + _impl->setBlocking(mode); } const redhawk::PropertyMap& StreamBase::keywords() const { - return _impl->keywords(); + return redhawk::PropertyMap::cast(sri().keywords); } bool StreamBase::hasKeyword(const std::string& name) const @@ -69,7 +69,7 @@ const redhawk::Value& StreamBase::getKeyword(const std::string& name) const void StreamBase::keywords(const _CORBA_Unbounded_Sequence& props) { _impl->flush(); - _impl->keywords(props); + _impl->setKeywords(props); } void StreamBase::setKeyword(const std::string& name, const CORBA::Any& value) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_stream.h b/bulkioInterfaces/libsrc/cpp/bulkio_stream.h index 02bcbd769..3dd1ac739 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_stream.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_stream.h @@ -11,118 +11,6 @@ namespace bulkio { - struct StreamDescriptor { - StreamDescriptor(const std::string& streamID) : - _streamID(streamID), - _sri(bulkio::sri::create(streamID)), - _version(1) - { - } - - StreamDescriptor(const BULKIO::StreamSRI& sri) : - _streamID(sri.streamID), - _sri(sri), - _version(1) - { - } - - const std::string& streamID() const - { - return _streamID; - } - - const BULKIO::StreamSRI& sri() const - { - return _sri; - } - - double xdelta() const - { - return _sri.xdelta; - } - - void xdelta(double delta) - { - _setStreamMetadata(_sri.xdelta, delta); - } - - bool complex() const - { - return _sri.mode != 0; - } - - void complex(bool mode) - { - _setStreamMetadata(_sri.mode, mode?1:0); - } - - bool blocking() const - { - return _sri.blocking; - } - - void blocking(bool mode) - { - _setStreamMetadata(_sri.blocking, mode?1:0); - } - - const redhawk::PropertyMap& keywords() const - { - return redhawk::PropertyMap::cast(_sri.keywords); - } - - void keywords(const _CORBA_Unbounded_Sequence& properties) - { - _sri.keywords = properties; - ++_version; - } - - - void setKeyword(const std::string& name, const CORBA::Any& value) - { - redhawk::PropertyMap::cast(_sri.keywords)[name] = value; - ++_version; - } - - void setKeyword(const std::string& name, const redhawk::Value& value) - { - setKeyword(name, static_cast(value)); - } - - void eraseKeyword(const std::string& name) - { - redhawk::PropertyMap::cast(_sri.keywords).erase(name); - ++_version; - } - - void setSRI(const BULKIO::StreamSRI& sri) - { - // Copy the new SRI, except for the stream ID, which is immutable - _sri = sri; - _sri.streamID = _streamID.c_str(); - ++_version; - } - - int version() const - { - return _version; - } - - protected: - template - void _setStreamMetadata(Field& field, Value value) - { - if (field != value) { - field = value; - ++_version; - } - } - - const std::string _streamID; - BULKIO::StreamSRI _sri; - int _version; - }; - class StreamBase { public: const std::string& streamID() const; @@ -162,28 +50,16 @@ namespace bulkio { int modcount() const { - return _impl->version(); + return _impl->modcount(); } protected: - class Impl; - - StreamBase() : - _impl() - { - } - - StreamBase(boost::shared_ptr impl) : - _impl(impl) - { - } - - boost::shared_ptr _impl; - - class Impl : public StreamDescriptor { + class Impl { public: Impl(const BULKIO::StreamSRI& sri) : - StreamDescriptor(sri) + _streamID(sri.streamID), + _sri(sri), + _modcount(0) { } @@ -198,7 +74,94 @@ namespace bulkio { virtual void close() { } + + const std::string& streamID() const + { + return _streamID; + } + + const BULKIO::StreamSRI& sri() const + { + return _sri; + } + + void setXDelta(double delta) + { + _setStreamMetadata(_sri.xdelta, delta); + } + + void setComplex(bool mode) + { + _setStreamMetadata(_sri.mode, mode?1:0); + } + + void setBlocking(bool mode) + { + _setStreamMetadata(_sri.blocking, mode?1:0); + } + + void setKeywords(const _CORBA_Unbounded_Sequence& properties) + { + _sri.keywords = properties; + ++_modcount; + } + + void setKeyword(const std::string& name, const CORBA::Any& value) + { + redhawk::PropertyMap::cast(_sri.keywords)[name] = value; + ++_modcount; + } + + void setKeyword(const std::string& name, const redhawk::Value& value) + { + setKeyword(name, static_cast(value)); + } + + void eraseKeyword(const std::string& name) + { + redhawk::PropertyMap::cast(_sri.keywords).erase(name); + ++_modcount; + } + + void setSRI(const BULKIO::StreamSRI& sri) + { + // Copy the new SRI, except for the stream ID, which is immutable + _sri = sri; + _sri.streamID = _streamID.c_str(); + ++_modcount; + } + + int modcount() const + { + return _modcount; + } + + protected: + template + void _setStreamMetadata(Field& field, Value value) + { + if (field != value) { + field = value; + ++_modcount; + } + } + + const std::string _streamID; + BULKIO::StreamSRI _sri; + int _modcount; }; + + StreamBase() : + _impl() + { + } + + StreamBase(boost::shared_ptr impl) : + _impl(impl) + { + } + + boost::shared_ptr _impl; }; } From 9bd72778833f1b20f959832e42b9d84961313d48 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 30 Nov 2016 11:54:53 -0500 Subject: [PATCH 0569/1644] Rename StreamBase to more accurate OutputStreamBase and move it into the output stream .h and .cpp files, allowing the implementation to be opaque to users of the API. --- bulkioInterfaces/libsrc/Makefile.am | 2 - .../libsrc/cpp/bulkio_out_stream.cpp | 233 +++++++++++++++++- .../libsrc/cpp/bulkio_out_stream.h | 55 ++++- bulkioInterfaces/libsrc/cpp/bulkio_stream.cpp | 98 -------- bulkioInterfaces/libsrc/cpp/bulkio_stream.h | 169 ------------- 5 files changed, 272 insertions(+), 285 deletions(-) delete mode 100644 bulkioInterfaces/libsrc/cpp/bulkio_stream.cpp delete mode 100644 bulkioInterfaces/libsrc/cpp/bulkio_stream.h diff --git a/bulkioInterfaces/libsrc/Makefile.am b/bulkioInterfaces/libsrc/Makefile.am index f5b0bd176..af6f1cace 100644 --- a/bulkioInterfaces/libsrc/Makefile.am +++ b/bulkioInterfaces/libsrc/Makefile.am @@ -40,7 +40,6 @@ libbulkio_@BULKIO_API_VERSION@_la_SOURCES = \ cpp/bulkio_in_stream.cpp \ cpp/bulkio_out_port.cpp \ cpp/bulkio_out_stream.cpp \ - cpp/bulkio_stream.cpp \ cpp/bulkio_attachable_port.cpp \ cpp/bulkio_sri_helpers.cpp \ cpp/bulkio_time_helpers.cpp \ @@ -60,7 +59,6 @@ library_include_HEADERS = cpp/bulkio.h \ cpp/bulkio_in_stream.h \ cpp/bulkio_out_port.h \ cpp/bulkio_out_stream.h \ - cpp/bulkio_stream.h \ cpp/bulkio_attachable_base.h \ cpp/bulkio_time_operators.h \ cpp/bulkio_datablock.h \ diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp index df03b89a7..2b12d91a4 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp @@ -23,16 +23,225 @@ #include "bulkio_time_operators.h" #include "bulkio_p.h" +using bulkio::OutputStreamBase; + +class OutputStreamBase::Impl { +public: + Impl(const BULKIO::StreamSRI& sri) : + _streamID(sri.streamID), + _sri(sri), + _modcount(0) + { + } + + virtual ~Impl() + { + } + + virtual void flush() + { + } + + virtual void close() + { + } + + const std::string& streamID() const + { + return _streamID; + } + + const BULKIO::StreamSRI& sri() const + { + return _sri; + } + + void setXDelta(double delta) + { + _setStreamMetadata(_sri.xdelta, delta); + } + + void setComplex(bool mode) + { + _setStreamMetadata(_sri.mode, mode?1:0); + } + + void setBlocking(bool mode) + { + _setStreamMetadata(_sri.blocking, mode?1:0); + } + + void setKeywords(const _CORBA_Unbounded_Sequence& properties) + { + _sri.keywords = properties; + ++_modcount; + } + + void setKeyword(const std::string& name, const CORBA::Any& value) + { + redhawk::PropertyMap::cast(_sri.keywords)[name] = value; + ++_modcount; + } + + void setKeyword(const std::string& name, const redhawk::Value& value) + { + setKeyword(name, static_cast(value)); + } + + void eraseKeyword(const std::string& name) + { + redhawk::PropertyMap::cast(_sri.keywords).erase(name); + ++_modcount; + } + + void setSRI(const BULKIO::StreamSRI& sri) + { + // Copy the new SRI, except for the stream ID, which is immutable + _sri = sri; + _sri.streamID = _streamID.c_str(); + ++_modcount; + } + + int modcount() const + { + return _modcount; + } + +protected: + template + void _setStreamMetadata(Field& field, Value value) + { + if (field != value) { + field = value; + ++_modcount; + } + } + + const std::string _streamID; + BULKIO::StreamSRI _sri; + int _modcount; +}; + +OutputStreamBase::OutputStreamBase() : + _impl() +{ +} + +OutputStreamBase::OutputStreamBase(boost::shared_ptr impl) : + _impl(impl) +{ +} + +const std::string& OutputStreamBase::streamID() const +{ + return _impl->streamID(); +} + +const BULKIO::StreamSRI& OutputStreamBase::sri() const +{ + return _impl->sri(); +} + +void OutputStreamBase::sri(const BULKIO::StreamSRI& sri) +{ + _impl->flush(); + _impl->setSRI(sri); +} + +double OutputStreamBase::xdelta() const +{ + return sri().xdelta; +} + +void OutputStreamBase::xdelta(double delta) +{ + _impl->flush(); + _impl->setXDelta(delta); +} + +bool OutputStreamBase::complex() const +{ + return (sri().mode != 0); +} + +void OutputStreamBase::complex(bool mode) +{ + _impl->flush(); + _impl->setComplex(mode); +} + +bool OutputStreamBase::blocking() const +{ + return sri().blocking; +} + +void OutputStreamBase::blocking(bool mode) +{ + _impl->flush(); + _impl->setBlocking(mode); +} + +const redhawk::PropertyMap& OutputStreamBase::keywords() const +{ + return redhawk::PropertyMap::cast(sri().keywords); +} + +bool OutputStreamBase::hasKeyword(const std::string& name) const +{ + return keywords().contains(name); +} + +const redhawk::Value& OutputStreamBase::getKeyword(const std::string& name) const +{ + return keywords()[name]; +} + +void OutputStreamBase::keywords(const _CORBA_Unbounded_Sequence& props) +{ + _impl->flush(); + _impl->setKeywords(props); +} + +void OutputStreamBase::setKeyword(const std::string& name, const CORBA::Any& value) +{ + _impl->flush(); + _impl->setKeyword(name, value); +} + +void OutputStreamBase::setKeyword(const std::string& name, const redhawk::Value& value) +{ + _impl->flush(); + _impl->setKeyword(name, value); +} + +void OutputStreamBase::eraseKeyword(const std::string& name) +{ + _impl->flush(); + _impl->eraseKeyword(name); +} + +void OutputStreamBase::close() +{ + _impl->close(); + _impl.reset(); +} + +int OutputStreamBase::modcount() const +{ + return _impl->modcount(); +} + + using bulkio::OutputStream; template -class OutputStream::Impl : public bulkio::StreamBase::Impl { +class OutputStream::Impl : public OutputStreamBase::Impl { public: typedef typename OutputStream::ScalarBuffer ScalarBuffer; typedef typename OutputStream::ComplexBuffer ComplexBuffer; Impl(const BULKIO::StreamSRI& sri, OutPortType* port) : - bulkio::StreamBase::Impl(sri), + OutputStreamBase::Impl(sri), _port(port), _bufferSize(0), _bufferOffset(0) @@ -182,13 +391,13 @@ class OutputStream::Impl : public bulkio::StreamBase::Impl { template OutputStream::OutputStream() : - StreamBase() + OutputStreamBase() { } template OutputStream::OutputStream(const BULKIO::StreamSRI& sri, OutPortType* port) : - StreamBase(boost::make_shared(sri, port)) + OutputStreamBase(boost::make_shared(sri, port)) { } @@ -282,10 +491,10 @@ OutputStream::operator unspecified_bool_type() const // using bulkio::XMLPortTraits; -class OutputStream::Impl : public bulkio::StreamBase::Impl { +class OutputStream::Impl : public OutputStreamBase::Impl { public: Impl(const BULKIO::StreamSRI& sri, OutPortType* port) : - bulkio::StreamBase::Impl(sri), + OutputStreamBase::Impl(sri), _port(port) { } @@ -315,12 +524,12 @@ class OutputStream::Impl : public bulkio::StreamBase::Impl { }; OutputStream::OutputStream() : - StreamBase() + OutputStreamBase() { } OutputStream::OutputStream(const BULKIO::StreamSRI& sri, OutPortType* port) : - StreamBase(boost::make_shared(sri, port)) + OutputStreamBase(boost::make_shared(sri, port)) { } @@ -344,10 +553,10 @@ OutputStream::operator unspecified_bool_type() const // using bulkio::FilePortTraits; -class OutputStream::Impl : public bulkio::StreamBase::Impl { +class OutputStream::Impl : public OutputStreamBase::Impl { public: Impl(const BULKIO::StreamSRI& sri, OutPortType* port) : - bulkio::StreamBase::Impl(sri), + OutputStreamBase::Impl(sri), _port(port) { } @@ -374,12 +583,12 @@ class OutputStream::Impl : public bulkio::StreamBase::Impl { }; OutputStream::OutputStream() : - StreamBase() + OutputStreamBase() { } OutputStream::OutputStream(const BULKIO::StreamSRI& sri, OutPortType* port) : - StreamBase(boost::make_shared(sri, port)) + OutputStreamBase(boost::make_shared(sri, port)) { } diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h index 0a5da295e..4b55ee540 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h @@ -31,15 +31,62 @@ #include "bulkio_traits.h" #include "bulkio_datablock.h" -#include "bulkio_stream.h" namespace bulkio { template class OutPortBase; + class OutputStreamBase { + public: + const std::string& streamID() const; + + const BULKIO::StreamSRI& sri() const; + void sri(const BULKIO::StreamSRI& sri); + + double xdelta() const; + void xdelta(double xdelta); + + bool complex() const; + void complex(bool mode); + + bool blocking() const; + void blocking(bool mode); + + const redhawk::PropertyMap& keywords() const; + bool hasKeyword(const std::string& name) const; + const redhawk::Value& getKeyword(const std::string& name) const; + + void keywords(const _CORBA_Unbounded_Sequence& props); + void setKeyword(const std::string& name, const CORBA::Any& value); + void setKeyword(const std::string& name, const redhawk::Value& value); + template + void setKeyword(const std::string& name, const T& value) + { + setKeyword(name, redhawk::Value(value)); + } + void eraseKeyword(const std::string& name); + + void close(); + + bool operator! () const + { + return !_impl; + } + + int modcount() const; + + protected: + class Impl; + + OutputStreamBase(); + OutputStreamBase(boost::shared_ptr impl); + + boost::shared_ptr _impl; + }; + template - class OutputStream : public StreamBase { + class OutputStream : public OutputStreamBase { public: typedef typename PortTraits::DataTransferTraits::NativeDataType ScalarType; typedef std::complex ComplexType; @@ -138,7 +185,7 @@ namespace bulkio { template <> - class OutputStream : public StreamBase { + class OutputStream : public OutputStreamBase { public: OutputStream(); @@ -164,7 +211,7 @@ namespace bulkio { template <> - class OutputStream : public StreamBase { + class OutputStream : public OutputStreamBase { public: OutputStream(); diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_stream.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_stream.cpp deleted file mode 100644 index 603de40f9..000000000 --- a/bulkioInterfaces/libsrc/cpp/bulkio_stream.cpp +++ /dev/null @@ -1,98 +0,0 @@ -#include "bulkio_stream.h" - -using bulkio::StreamBase; - -const std::string& StreamBase::streamID() const -{ - return _impl->streamID(); -} - -const BULKIO::StreamSRI& StreamBase::sri() const -{ - return _impl->sri(); -} - -void StreamBase::sri(const BULKIO::StreamSRI& sri) -{ - _impl->flush(); - _impl->setSRI(sri); -} - -double StreamBase::xdelta() const -{ - return sri().xdelta; -} - -void StreamBase::xdelta(double delta) -{ - _impl->flush(); - _impl->setXDelta(delta); -} - -bool StreamBase::complex() const -{ - return (sri().mode != 0); -} - -void StreamBase::complex(bool mode) -{ - _impl->flush(); - _impl->setComplex(mode); -} - -bool StreamBase::blocking() const -{ - return sri().blocking; -} - -void StreamBase::blocking(bool mode) -{ - _impl->flush(); - _impl->setBlocking(mode); -} - -const redhawk::PropertyMap& StreamBase::keywords() const -{ - return redhawk::PropertyMap::cast(sri().keywords); -} - -bool StreamBase::hasKeyword(const std::string& name) const -{ - return keywords().contains(name); -} - -const redhawk::Value& StreamBase::getKeyword(const std::string& name) const -{ - return keywords()[name]; -} - -void StreamBase::keywords(const _CORBA_Unbounded_Sequence& props) -{ - _impl->flush(); - _impl->setKeywords(props); -} - -void StreamBase::setKeyword(const std::string& name, const CORBA::Any& value) -{ - _impl->flush(); - _impl->setKeyword(name, value); -} - -void StreamBase::setKeyword(const std::string& name, const redhawk::Value& value) -{ - _impl->flush(); - _impl->setKeyword(name, value); -} - -void StreamBase::eraseKeyword(const std::string& name) -{ - _impl->flush(); - _impl->eraseKeyword(name); -} - -void StreamBase::close() -{ - _impl->close(); - _impl.reset(); -} - diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_stream.h b/bulkioInterfaces/libsrc/cpp/bulkio_stream.h deleted file mode 100644 index 3dd1ac739..000000000 --- a/bulkioInterfaces/libsrc/cpp/bulkio_stream.h +++ /dev/null @@ -1,169 +0,0 @@ -#ifndef __bulkio_stream_h -#define __bulkio_stream_h - -#include - -#include - -#include - -#include "bulkio_base.h" - -namespace bulkio { - - class StreamBase { - public: - const std::string& streamID() const; - - const BULKIO::StreamSRI& sri() const; - void sri(const BULKIO::StreamSRI& sri); - - double xdelta() const; - void xdelta(double xdelta); - - bool complex() const; - void complex(bool mode); - - bool blocking() const; - void blocking(bool mode); - - const redhawk::PropertyMap& keywords() const; - bool hasKeyword(const std::string& name) const; - const redhawk::Value& getKeyword(const std::string& name) const; - - void keywords(const _CORBA_Unbounded_Sequence& props); - void setKeyword(const std::string& name, const CORBA::Any& value); - void setKeyword(const std::string& name, const redhawk::Value& value); - template - void setKeyword(const std::string& name, const T& value) - { - setKeyword(name, redhawk::Value(value)); - } - void eraseKeyword(const std::string& name); - - void close(); - - bool operator! () const - { - return !_impl; - } - - int modcount() const - { - return _impl->modcount(); - } - - protected: - class Impl { - public: - Impl(const BULKIO::StreamSRI& sri) : - _streamID(sri.streamID), - _sri(sri), - _modcount(0) - { - } - - virtual ~Impl() - { - } - - virtual void flush() - { - } - - virtual void close() - { - } - - const std::string& streamID() const - { - return _streamID; - } - - const BULKIO::StreamSRI& sri() const - { - return _sri; - } - - void setXDelta(double delta) - { - _setStreamMetadata(_sri.xdelta, delta); - } - - void setComplex(bool mode) - { - _setStreamMetadata(_sri.mode, mode?1:0); - } - - void setBlocking(bool mode) - { - _setStreamMetadata(_sri.blocking, mode?1:0); - } - - void setKeywords(const _CORBA_Unbounded_Sequence& properties) - { - _sri.keywords = properties; - ++_modcount; - } - - void setKeyword(const std::string& name, const CORBA::Any& value) - { - redhawk::PropertyMap::cast(_sri.keywords)[name] = value; - ++_modcount; - } - - void setKeyword(const std::string& name, const redhawk::Value& value) - { - setKeyword(name, static_cast(value)); - } - - void eraseKeyword(const std::string& name) - { - redhawk::PropertyMap::cast(_sri.keywords).erase(name); - ++_modcount; - } - - void setSRI(const BULKIO::StreamSRI& sri) - { - // Copy the new SRI, except for the stream ID, which is immutable - _sri = sri; - _sri.streamID = _streamID.c_str(); - ++_modcount; - } - - int modcount() const - { - return _modcount; - } - - protected: - template - void _setStreamMetadata(Field& field, Value value) - { - if (field != value) { - field = value; - ++_modcount; - } - } - - const std::string _streamID; - BULKIO::StreamSRI _sri; - int _modcount; - }; - - StreamBase() : - _impl() - { - } - - StreamBase(boost::shared_ptr impl) : - _impl(impl) - { - } - - boost::shared_ptr _impl; - }; - -} - -#endif // __bulkio_stream_h From e3d51237827cb4a94244e68608c80e05ebe6376f Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 30 Nov 2016 12:21:58 -0500 Subject: [PATCH 0570/1644] Rename flush() to _modifyingStreamMetadata() in output stream implementation, and override it to dispatch to flush() for numeric streams; remove unneeded method overload --- .../libsrc/cpp/bulkio_out_stream.cpp | 33 +++++++++---------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp index 2b12d91a4..447e2395c 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp @@ -38,10 +38,6 @@ class OutputStreamBase::Impl { { } - virtual void flush() - { - } - virtual void close() { } @@ -73,29 +69,28 @@ class OutputStreamBase::Impl { void setKeywords(const _CORBA_Unbounded_Sequence& properties) { + _modifyingStreamMetadata(); _sri.keywords = properties; ++_modcount; } void setKeyword(const std::string& name, const CORBA::Any& value) { + _modifyingStreamMetadata(); redhawk::PropertyMap::cast(_sri.keywords)[name] = value; ++_modcount; } - void setKeyword(const std::string& name, const redhawk::Value& value) - { - setKeyword(name, static_cast(value)); - } - void eraseKeyword(const std::string& name) { + _modifyingStreamMetadata(); redhawk::PropertyMap::cast(_sri.keywords).erase(name); ++_modcount; } void setSRI(const BULKIO::StreamSRI& sri) { + _modifyingStreamMetadata(); // Copy the new SRI, except for the stream ID, which is immutable _sri = sri; _sri.streamID = _streamID.c_str(); @@ -108,10 +103,16 @@ class OutputStreamBase::Impl { } protected: + virtual void _modifyingStreamMetadata() + { + // By default, do nothing + } + template void _setStreamMetadata(Field& field, Value value) { if (field != value) { + _modifyingStreamMetadata(); field = value; ++_modcount; } @@ -144,7 +145,6 @@ const BULKIO::StreamSRI& OutputStreamBase::sri() const void OutputStreamBase::sri(const BULKIO::StreamSRI& sri) { - _impl->flush(); _impl->setSRI(sri); } @@ -155,7 +155,6 @@ double OutputStreamBase::xdelta() const void OutputStreamBase::xdelta(double delta) { - _impl->flush(); _impl->setXDelta(delta); } @@ -166,7 +165,6 @@ bool OutputStreamBase::complex() const void OutputStreamBase::complex(bool mode) { - _impl->flush(); _impl->setComplex(mode); } @@ -177,7 +175,6 @@ bool OutputStreamBase::blocking() const void OutputStreamBase::blocking(bool mode) { - _impl->flush(); _impl->setBlocking(mode); } @@ -198,25 +195,21 @@ const redhawk::Value& OutputStreamBase::getKeyword(const std::string& name) cons void OutputStreamBase::keywords(const _CORBA_Unbounded_Sequence& props) { - _impl->flush(); _impl->setKeywords(props); } void OutputStreamBase::setKeyword(const std::string& name, const CORBA::Any& value) { - _impl->flush(); _impl->setKeyword(name, value); } void OutputStreamBase::setKeyword(const std::string& name, const redhawk::Value& value) { - _impl->flush(); _impl->setKeyword(name, value); } void OutputStreamBase::eraseKeyword(const std::string& name) { - _impl->flush(); _impl->eraseKeyword(name); } @@ -345,6 +338,12 @@ class OutputStream::Impl : public OutputStreamBase::Impl { _port->_sendPacket(data, time, eos, _streamID); } + virtual void _modifyingStreamMetadata() + { + // Flush any data queued with the old SRI + flush(); + } + void _flush(bool eos) { // Push out all buffered data, which must be less than the full allocated From c22a1e936b83660fb86f1ea4960b4e11b7696cee Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 30 Nov 2016 13:18:45 -0500 Subject: [PATCH 0571/1644] Make OutputStreamBase::modcount() protected, since it's only intended to be used by the OutPort --- bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h index 4b55ee540..314bcc668 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h @@ -74,14 +74,14 @@ namespace bulkio { return !_impl; } - int modcount() const; - protected: class Impl; OutputStreamBase(); OutputStreamBase(boost::shared_ptr impl); + int modcount() const; + boost::shared_ptr _impl; }; From c0cb1bea1883fcc82a463a12cdf9b8d8418597c5 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 30 Nov 2016 14:06:39 -0500 Subject: [PATCH 0572/1644] Rename C++ BulkIO outport classes to reflect that the base OutPort provides a complete stream-based interface, and the more specific types just add old-style pushPacket() API on top; XML and File out ports go back to being non-templatized so that Eclipse autocomplete provides the full set of methods (also, their stream classes no longer depend on the more specific class) --- .../libsrc/cpp/bulkio_out_port.cpp | 212 +++++++++--------- bulkioInterfaces/libsrc/cpp/bulkio_out_port.h | 126 +++++------ .../libsrc/cpp/bulkio_out_stream.h | 14 +- 3 files changed, 172 insertions(+), 180 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp index 4e62ef1c6..e31b52904 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp @@ -29,7 +29,7 @@ #include "bulkio_connection.hpp" // Suppress warnings for access to deprecated currentSRI member (on gcc 4.4, at -// least, the implicit destructor call from OutPortBase's destructor emits a +// least, the implicit destructor call from OutPort's destructor emits a // warning) #pragma GCC diagnostic ignored "-Wdeprecated-declarations" @@ -41,41 +41,41 @@ namespace bulkio { */ template < typename PortTraits > - OutPortBase< PortTraits >::OutPortBase(std::string port_name, - LOGGER_PTR logger, - ConnectionEventListener *connectCB, - ConnectionEventListener *disconnectCB ) : - redhawk::UsesPort(port_name) + OutPort< PortTraits >::OutPort(const std::string& name, + LOGGER_PTR logger, + ConnectionEventListener *connectCB, + ConnectionEventListener *disconnectCB) : + redhawk::UsesPort(name) { if ( !logger ) { std::string pname("redhawk.bulkio.outport."); - pname = pname + port_name; + pname = pname + name; setLogger(rh_logger::Logger::getLogger(pname)); } if ( connectCB ) { _connectCB = boost::shared_ptr< ConnectionEventListener >( connectCB, null_deleter() ); } - addConnectListener(this, &OutPortBase::_connectListenerAdapter); + addConnectListener(this, &OutPort::_connectListenerAdapter); if ( disconnectCB ) { _disconnectCB = boost::shared_ptr< ConnectionEventListener >( disconnectCB, null_deleter() ); } - addDisconnectListener(this, &OutPortBase::_disconnectListenerAdapter); + addDisconnectListener(this, &OutPort::_disconnectListenerAdapter); LOG_DEBUG( logger, "bulkio::OutPort::CTOR port:" << name ); } template < typename PortTraits > - OutPortBase< PortTraits >::~OutPortBase(){ + OutPort< PortTraits >::~OutPort(){ } template < typename PortTraits > - void OutPortBase< PortTraits >::pushSRI(const BULKIO::StreamSRI& H) + void OutPort< PortTraits >::pushSRI(const BULKIO::StreamSRI& H) { TRACE_ENTER(logger, "OutPort::pushSRI" ); @@ -121,7 +121,7 @@ namespace bulkio { } template < typename PortTraits > - void OutPortBase< PortTraits >::_connectListenerAdapter(const std::string& connectionId) + void OutPort< PortTraits >::_connectListenerAdapter(const std::string& connectionId) { if (_connectCB) { (*_connectCB)(connectionId.c_str()); @@ -129,7 +129,7 @@ namespace bulkio { } template < typename PortTraits > - void OutPortBase< PortTraits >::_disconnectListenerAdapter(const std::string& connectionId) + void OutPort< PortTraits >::_disconnectListenerAdapter(const std::string& connectionId) { if (_disconnectCB) { (*_disconnectCB)(connectionId.c_str()); @@ -137,7 +137,7 @@ namespace bulkio { } template < typename PortTraits > - bool OutPortBase< PortTraits >::_isStreamRoutedToConnection( + bool OutPort< PortTraits >::_isStreamRoutedToConnection( const std::string& streamID, const std::string& connectionID) { @@ -158,7 +158,7 @@ namespace bulkio { template < typename PortTraits > - typename OutPortBase::StreamType OutPortBase< PortTraits >::_getStream(const std::string& streamID) + typename OutPort::StreamType OutPort< PortTraits >::_getStream(const std::string& streamID) { typename StreamMap::iterator existing = streams.find(streamID); if (existing == streams.end()) { @@ -176,7 +176,7 @@ namespace bulkio { template < typename PortTraits > - void OutPortBase< PortTraits >::_sendPacket( + void OutPort< PortTraits >::_sendPacket( const SharedBufferType& data, const BULKIO::PrecisionUTCTime& T, bool EOS, @@ -223,7 +223,7 @@ namespace bulkio { template < typename PortTraits > - BULKIO::UsesPortStatisticsSequence* OutPortBase< PortTraits >::statistics() + BULKIO::UsesPortStatisticsSequence* OutPort< PortTraits >::statistics() { SCOPED_LOCK lock(updatingPortsLock); BULKIO::UsesPortStatisticsSequence_var recStat = new BULKIO::UsesPortStatisticsSequence(); @@ -238,7 +238,7 @@ namespace bulkio { } template < typename PortTraits > - BULKIO::PortUsageType OutPortBase< PortTraits >::state() + BULKIO::PortUsageType OutPort< PortTraits >::state() { SCOPED_LOCK lock(updatingPortsLock); if (_transports.empty()) { @@ -249,7 +249,7 @@ namespace bulkio { } template < typename PortTraits > - void OutPortBase< PortTraits >::enableStats(bool enable) + void OutPort< PortTraits >::enableStats(bool enable) { SCOPED_LOCK lock(updatingPortsLock); for (TransportIterator port = _transports.begin(); port != _transports.end(); ++port) { @@ -260,7 +260,7 @@ namespace bulkio { template < typename PortTraits > redhawk::BasicTransport* - OutPortBase< PortTraits >::_createTransport(CORBA::Object_ptr object, const std::string& connectionId) + OutPort< PortTraits >::_createTransport(CORBA::Object_ptr object, const std::string& connectionId) { PortVarType port; try { @@ -285,16 +285,16 @@ namespace bulkio { template < typename PortTraits > - typename OutPortBase< PortTraits >::PortTransportType* - OutPortBase< PortTraits >::_createRemoteConnection(PortPtrType port, const std::string& connectionId) + typename OutPort< PortTraits >::PortTransportType* + OutPort< PortTraits >::_createRemoteConnection(PortPtrType port, const std::string& connectionId) { return new RemoteTransport(connectionId, name, port); } template < typename PortTraits > - typename OutPortBase< PortTraits >::PortTransportType* - OutPortBase< PortTraits >::_createLocalConnection(PortPtrType port, LocalPortType* localPort, + typename OutPort< PortTraits >::PortTransportType* + OutPort< PortTraits >::_createLocalConnection(PortPtrType port, LocalPortType* localPort, const std::string& connectionId) { return new LocalTransport(connectionId, name, localPort, port); @@ -302,7 +302,7 @@ namespace bulkio { template - typename OutPortBase::StreamType OutPortBase::getStream(const std::string& streamID) + typename OutPort::StreamType OutPort::getStream(const std::string& streamID) { boost::mutex::scoped_lock lock(updatingPortsLock); typename StreamMap::iterator stream = streams.find(streamID); @@ -314,7 +314,7 @@ namespace bulkio { } template - typename OutPortBase::StreamList OutPortBase::getStreams() + typename OutPort::StreamList OutPort::getStreams() { StreamList result; boost::mutex::scoped_lock lock(updatingPortsLock); @@ -325,7 +325,7 @@ namespace bulkio { } template < typename PortTraits > - typename OutPortBase< PortTraits >::StreamType OutPortBase< PortTraits >::createStream(const std::string& streamID) + typename OutPort< PortTraits >::StreamType OutPort< PortTraits >::createStream(const std::string& streamID) { boost::mutex::scoped_lock lock(updatingPortsLock); typename StreamMap::iterator existing = streams.find(streamID); @@ -338,7 +338,7 @@ namespace bulkio { } template < typename PortTraits > - typename OutPortBase< PortTraits >::StreamType OutPortBase< PortTraits >::createStream(const BULKIO::StreamSRI& sri) + typename OutPort< PortTraits >::StreamType OutPort< PortTraits >::createStream(const BULKIO::StreamSRI& sri) { boost::mutex::scoped_lock lock(updatingPortsLock); const std::string streamID(sri.streamID); @@ -354,7 +354,7 @@ namespace bulkio { } template < typename PortTraits > - bulkio::SriMap OutPortBase< PortTraits >::getCurrentSRI() + bulkio::SriMap OutPort< PortTraits >::getCurrentSRI() { bulkio::SriMap ret; SCOPED_LOCK lock(updatingPortsLock); // restrict access till method completes @@ -365,7 +365,7 @@ namespace bulkio { } template < typename PortTraits > - bulkio::SriList OutPortBase< PortTraits >::getActiveSRIs() + bulkio::SriList OutPort< PortTraits >::getActiveSRIs() { bulkio::SriList ret; SCOPED_LOCK lock(updatingPortsLock); // restrict access till method completes @@ -377,7 +377,7 @@ namespace bulkio { template < typename PortTraits > - typename OutPortBase< PortTraits >::ConnectionsList OutPortBase< PortTraits >::getConnections() + typename OutPort< PortTraits >::ConnectionsList OutPort< PortTraits >::getConnections() { SCOPED_LOCK lock(updatingPortsLock); // restrict access till method completes ConnectionsList outConnections; @@ -392,31 +392,31 @@ namespace bulkio { template < typename PortTraits > - void OutPortBase< PortTraits >::setNewConnectListener(ConnectionEventListener *newListener) + void OutPort< PortTraits >::setNewConnectListener(ConnectionEventListener *newListener) { _connectCB = boost::shared_ptr< ConnectionEventListener >(newListener, null_deleter()); } template < typename PortTraits > - void OutPortBase< PortTraits >::setNewConnectListener(ConnectionEventCallbackFn newListener) + void OutPort< PortTraits >::setNewConnectListener(ConnectionEventCallbackFn newListener) { _connectCB = boost::make_shared< StaticConnectionListener >( newListener ); } template < typename PortTraits > - void OutPortBase< PortTraits >::setNewDisconnectListener(ConnectionEventListener *newListener) + void OutPort< PortTraits >::setNewDisconnectListener(ConnectionEventListener *newListener) { _disconnectCB = boost::shared_ptr< ConnectionEventListener >(newListener, null_deleter()); } template < typename PortTraits > - void OutPortBase< PortTraits >::setNewDisconnectListener(ConnectionEventCallbackFn newListener) + void OutPort< PortTraits >::setNewDisconnectListener(ConnectionEventCallbackFn newListener) { _disconnectCB = boost::make_shared< StaticConnectionListener >( newListener ); } template < typename PortTraits > - std::string OutPortBase< PortTraits >::getRepid() const { + std::string OutPort< PortTraits >::getRepid() const { return PortType::_PD_repoId; //return "IDL:CORBA/Object:1.0"; } @@ -428,40 +428,40 @@ namespace bulkio { */ template < typename PortTraits > - OutPort< PortTraits >::OutPort(std::string port_name, - LOGGER_PTR logger, - ConnectionEventListener *connectCB, - ConnectionEventListener *disconnectCB ) : - OutPortBase(port_name, logger, connectCB, disconnectCB) + OutNumericPort< PortTraits >::OutNumericPort(const std::string& name, + LOGGER_PTR logger, + ConnectionEventListener *connectCB, + ConnectionEventListener *disconnectCB ) : + OutPort(name, logger, connectCB, disconnectCB) { } template < typename PortTraits > - OutPort< PortTraits >::OutPort(std::string port_name, - ConnectionEventListener *connectCB, - ConnectionEventListener *disconnectCB ) : - OutPortBase(port_name, LOGGER_PTR(), connectCB, disconnectCB) + OutNumericPort< PortTraits >::OutNumericPort(const std::string& name, + ConnectionEventListener *connectCB, + ConnectionEventListener *disconnectCB) : + OutPort(name, LOGGER_PTR(), connectCB, disconnectCB) { } template < typename PortTraits > - OutPort< PortTraits >::~OutPort() + OutNumericPort< PortTraits >::~OutNumericPort() { } template - typename OutPort::PortTransportType* - OutPort::_createRemoteConnection(PortPtrType port, const std::string& connectionId) + typename OutNumericPort::PortTransportType* + OutNumericPort::_createRemoteConnection(PortPtrType port, const std::string& connectionId) { return new ChunkingTransport(connectionId, this->name, port); } template < typename PortTraits > - void OutPort< PortTraits >::pushPacket( + void OutNumericPort< PortTraits >::pushPacket( NativeSequenceType & data, const BULKIO::PrecisionUTCTime& T, bool EOS, @@ -471,7 +471,7 @@ namespace bulkio { } template < typename PortTraits > - void OutPort< PortTraits >::pushPacket( + void OutNumericPort< PortTraits >::pushPacket( const DataBufferType & data, const BULKIO::PrecisionUTCTime& T, bool EOS, @@ -481,7 +481,7 @@ namespace bulkio { } template < typename PortTraits > - void OutPort< PortTraits >::pushPacket( + void OutNumericPort< PortTraits >::pushPacket( const TransportType* data, size_t size, const BULKIO::PrecisionUTCTime& T, @@ -492,20 +492,20 @@ namespace bulkio { this->_sendPacket(SharedBufferType::make_transient(ptr, size), T, EOS, streamID); } - OutCharPort::OutCharPort( std::string name, - ConnectionEventListener *connectCB, - ConnectionEventListener *disconnectCB ): - OutPort < CharPortTraits >(name,connectCB, disconnectCB) + OutCharPort::OutCharPort(const std::string& name, + ConnectionEventListener *connectCB, + ConnectionEventListener *disconnectCB): + OutNumericPort(name,connectCB, disconnectCB) { } - OutCharPort::OutCharPort( std::string name, - LOGGER_PTR logger, - ConnectionEventListener *connectCB, - ConnectionEventListener *disconnectCB ) : - OutPort < CharPortTraits >(name, logger, connectCB, disconnectCB ) + OutCharPort::OutCharPort(const std::string& name, + LOGGER_PTR logger, + ConnectionEventListener *connectCB, + ConnectionEventListener *disconnectCB) : + OutNumericPort(name, logger, connectCB, disconnectCB) { } @@ -513,52 +513,52 @@ namespace bulkio { void OutCharPort::pushPacket(const Int8* buffer, size_t size, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID) { const TransportType* data = reinterpret_cast(buffer); - OutPort::pushPacket(data, size, T, EOS, streamID); + OutNumericPort::pushPacket(data, size, T, EOS, streamID); } void OutCharPort::pushPacket(const char* buffer, size_t size, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID) { const TransportType* data = reinterpret_cast(buffer); - OutPort::pushPacket(data, size, T, EOS, streamID); + OutNumericPort::pushPacket(data, size, T, EOS, streamID); } void OutCharPort::pushPacket(const std::vector< Int8 >& data, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID) { const TransportType* buffer = reinterpret_cast(&data[0]); - OutPort::pushPacket(buffer, data.size(), T, EOS, streamID); + OutNumericPort::pushPacket(buffer, data.size(), T, EOS, streamID); } void OutCharPort::pushPacket(const std::vector< Char >& data, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID) { const TransportType* buffer = reinterpret_cast(&data[0]); - OutPort::pushPacket(buffer, data.size(), T, EOS, streamID); + OutNumericPort::pushPacket(buffer, data.size(), T, EOS, streamID); } - OutPort::OutPort (const std::string& name, - ConnectionEventListener *connectCB, - ConnectionEventListener *disconnectCB) : - OutPortBase (name, LOGGER_PTR(), connectCB, disconnectCB) + OutFilePort::OutFilePort(const std::string& name, + ConnectionEventListener *connectCB, + ConnectionEventListener *disconnectCB) : + OutPort(name, LOGGER_PTR(), connectCB, disconnectCB) { } - OutPort::OutPort (const std::string& name, - LOGGER_PTR logger, - ConnectionEventListener *connectCB, - ConnectionEventListener *disconnectCB) : - OutPortBase(name,logger, connectCB, disconnectCB) + OutFilePort::OutFilePort(const std::string& name, + LOGGER_PTR logger, + ConnectionEventListener *connectCB, + ConnectionEventListener *disconnectCB) : + OutPort(name,logger, connectCB, disconnectCB) { } - void OutPort::pushPacket(const std::string& URL, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID) + void OutFilePort::pushPacket(const std::string& URL, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID) { _sendPacket(URL, T, EOS, streamID); } - void OutPort::pushPacket(const char* URL, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID) + void OutFilePort::pushPacket(const char* URL, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID) { std::string url_out; if (URL) { @@ -567,30 +567,30 @@ namespace bulkio { this->pushPacket(url_out, T, EOS, streamID); } - void OutPort::pushPacket(const char *data, bool EOS, const std::string& streamID) + void OutFilePort::pushPacket(const char *data, bool EOS, const std::string& streamID) { this->pushPacket(data, bulkio::time::utils::now(), EOS, streamID); } - OutPort::OutPort (const std::string& name, - ConnectionEventListener *connectCB, - ConnectionEventListener *disconnectCB) : - OutPortBase(name, LOGGER_PTR(), connectCB, disconnectCB) + OutXMLPort::OutXMLPort(const std::string& name, + ConnectionEventListener *connectCB, + ConnectionEventListener *disconnectCB) : + OutPort(name, LOGGER_PTR(), connectCB, disconnectCB) { } - OutPort::OutPort(const std::string& name, - LOGGER_PTR logger, - ConnectionEventListener *connectCB, - ConnectionEventListener *disconnectCB) : - OutPortBase(name,logger,connectCB, disconnectCB) + OutXMLPort::OutXMLPort(const std::string& name, + LOGGER_PTR logger, + ConnectionEventListener *connectCB, + ConnectionEventListener *disconnectCB) : + OutPort(name,logger,connectCB, disconnectCB) { } - void OutPort::pushPacket(const char *data, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID) + void OutXMLPort::pushPacket(const char *data, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID) { std::string data_out; if (data) { @@ -600,7 +600,7 @@ namespace bulkio { } - void OutPort::pushPacket(const std::string& data, bool EOS, const std::string& streamID) + void OutXMLPort::pushPacket(const std::string& data, bool EOS, const std::string& streamID) { // The time argument is never dereferenced for dataXML, so it is safe to // pass a null @@ -608,7 +608,7 @@ namespace bulkio { _sendPacket(data, *time, EOS, streamID); } - void OutPort::pushPacket(const char* data, bool EOS, const std::string& streamID) + void OutXMLPort::pushPacket(const char* data, bool EOS, const std::string& streamID) { std::string data_out; if (data) { @@ -625,24 +625,24 @@ namespace bulkio { // link against the template. // -#define INSTANTIATE_BASE_TEMPLATE(x) \ - template class OutPortBase; - #define INSTANTIATE_TEMPLATE(x) \ - INSTANTIATE_BASE_TEMPLATE(x); template class OutPort; - - INSTANTIATE_TEMPLATE(CharPortTraits); - INSTANTIATE_TEMPLATE(OctetPortTraits); - INSTANTIATE_TEMPLATE(ShortPortTraits); - INSTANTIATE_TEMPLATE(UShortPortTraits); - INSTANTIATE_TEMPLATE(LongPortTraits); - INSTANTIATE_TEMPLATE(ULongPortTraits); - INSTANTIATE_TEMPLATE(LongLongPortTraits); - INSTANTIATE_TEMPLATE(ULongLongPortTraits); - INSTANTIATE_TEMPLATE(FloatPortTraits); - INSTANTIATE_TEMPLATE(DoublePortTraits); - - INSTANTIATE_BASE_TEMPLATE(FilePortTraits); - INSTANTIATE_BASE_TEMPLATE(XMLPortTraits); + template class OutPort; + +#define INSTANTIATE_NUMERIC_TEMPLATE(x) \ + INSTANTIATE_TEMPLATE(x); template class OutNumericPort; + + INSTANTIATE_NUMERIC_TEMPLATE(CharPortTraits); + INSTANTIATE_NUMERIC_TEMPLATE(OctetPortTraits); + INSTANTIATE_NUMERIC_TEMPLATE(ShortPortTraits); + INSTANTIATE_NUMERIC_TEMPLATE(UShortPortTraits); + INSTANTIATE_NUMERIC_TEMPLATE(LongPortTraits); + INSTANTIATE_NUMERIC_TEMPLATE(ULongPortTraits); + INSTANTIATE_NUMERIC_TEMPLATE(LongLongPortTraits); + INSTANTIATE_NUMERIC_TEMPLATE(ULongLongPortTraits); + INSTANTIATE_NUMERIC_TEMPLATE(FloatPortTraits); + INSTANTIATE_NUMERIC_TEMPLATE(DoublePortTraits); + + INSTANTIATE_TEMPLATE(FilePortTraits); + INSTANTIATE_TEMPLATE(XMLPortTraits); } // end of bulkio namespace diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h index 5382b76c5..3b4fdf676 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h @@ -64,7 +64,7 @@ namespace bulkio { template class PortTransport; // - // OutPortBase + // OutPort // // Base template for data transfers between BULKIO ports. This class is defined by 2 trait classes // PortTraits - This template provides the context for the port's middleware transport classes and they base data types @@ -72,7 +72,7 @@ namespace bulkio { // // template < typename PortTraits > - class OutPortBase : public redhawk::UsesPort + class OutPort : public redhawk::UsesPort #ifdef BEGIN_AUTOCOMPLETE_IGNORE , public virtual POA_BULKIO::UsesPortStatisticsProvider #endif @@ -129,23 +129,23 @@ namespace bulkio { // - // OutPortBase Creates a uses port object for publishing data to the framework + // OutPort Creates a uses port object for publishing data to the framework // - // @param port_name name assigned to the port located in scd.xml file + // @param name name assigned to the port located in scd.xml file // @param logger logger to receive port logging output // @param connectionCB callback that will be called when the connectPort method is called // @pararm disconnectDB callback that receives notification when a disconnectPort happens // - OutPortBase(std::string port_name, - LOGGER_PTR logger, - ConnectionEventListener *connectCB=NULL, - ConnectionEventListener *disconnectCB=NULL ); + OutPort(const std::string& name, + LOGGER_PTR logger, + ConnectionEventListener *connectCB=NULL, + ConnectionEventListener *disconnectCB=NULL); // // virtual destructor to clean up resources // - virtual ~OutPortBase(); + virtual ~OutPort(); void updateConnectionFilter(const std::vector &_filterTable) { SCOPED_LOCK lock(updatingPortsLock); // don't want to process while command information is coming in @@ -319,7 +319,7 @@ namespace bulkio { template < typename PortTraits > - class OutPort : public OutPortBase< PortTraits > { + class OutNumericPort : public OutPort< PortTraits > { public: typedef PortTraits Traits; @@ -372,25 +372,25 @@ namespace bulkio { typedef typename Traits::SharedBufferType SharedBufferType; // - // OutPort Creates a uses port object for publishing data to the framework + // OutNumericPort Creates a uses port object for publishing data to the framework // // @param port_name name assigned to the port located in scd.xml file // @param connectionCB callback that will be called when the connectPort method is called // @pararm disconnectDB callback that receives notification when a disconnectPort happens // - OutPort(std::string port_name, - ConnectionEventListener *connectCB=NULL, - ConnectionEventListener *disconnectCB=NULL ); + OutNumericPort(const std::string& name, + ConnectionEventListener *connectCB=NULL, + ConnectionEventListener *disconnectCB=NULL); - OutPort(std::string port_name, - LOGGER_PTR logger, - ConnectionEventListener *connectCB=NULL, - ConnectionEventListener *disconnectCB=NULL ); + OutNumericPort(const std::string& name, + LOGGER_PTR logger, + ConnectionEventListener *connectCB=NULL, + ConnectionEventListener *disconnectCB=NULL); // // virtual destructor to clean up resources // - virtual ~OutPort(); + virtual ~OutNumericPort(); /* * pushPacket @@ -441,12 +441,10 @@ namespace bulkio { */ void pushPacket( const DataBufferType & data, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID); - using OutPortBase::currentSRIs; - protected: - using OutPortBase::logger; - typedef typename OutPortBase::PortPtrType PortPtrType; - typedef typename OutPortBase::PortTransportType PortTransportType; + using OutPort::logger; + typedef typename OutPort::PortPtrType PortPtrType; + typedef typename OutPort::PortTransportType PortTransportType; virtual PortTransportType* _createRemoteConnection(PortPtrType port, const std::string& connectionId); }; @@ -457,13 +455,13 @@ namespace bulkio { // This class overrides the pushPacket method to support Int8 and char data types // // Output port for Int8 and char data types - class OutCharPort : public OutPort < CharPortTraits > { + class OutCharPort : public OutNumericPort < CharPortTraits > { public: - OutCharPort(std::string port_name, + OutCharPort(const std::string& name, ConnectionEventListener *connectCB=NULL, ConnectionEventListener *disconnectCB=NULL ); - OutCharPort(std::string port_name, + OutCharPort(const std::string& name, LOGGER_PTR logger, ConnectionEventListener *connectCB=NULL, ConnectionEventListener *disconnectCB=NULL ); @@ -489,8 +487,7 @@ namespace bulkio { // This class defines the pushPacket interface for file URL data. // // - template <> - class OutPort : public OutPortBase { + class OutFilePort : public OutPort { public: @@ -527,15 +524,15 @@ namespace bulkio { typedef Traits::NativeType NativeType; - OutPort(const std::string& name, - ConnectionEventListener *connectCB=NULL, - ConnectionEventListener *disconnectCB=NULL ); + OutFilePort(const std::string& name, + ConnectionEventListener *connectCB=NULL, + ConnectionEventListener *disconnectCB=NULL); - OutPort(const std::string& name, - LOGGER_PTR logger, - ConnectionEventListener *connectCB=NULL, - ConnectionEventListener *disconnectCB=NULL ); + OutFilePort(const std::string& name, + LOGGER_PTR logger, + ConnectionEventListener *connectCB=NULL, + ConnectionEventListener *disconnectCB=NULL); /* * pushPacket @@ -583,14 +580,13 @@ namespace bulkio { // This class defines the pushPacket interface for XML data. // // - template <> - class OutPort : public OutPortBase { + class OutXMLPort : public OutPort { public: typedef XMLPortTraits Traits; - typedef OutPortBase Base; + typedef OutPort Base; // // Port Variable Definition @@ -623,15 +619,15 @@ namespace bulkio { typedef Traits::NativeType NativeType; - OutPort(const std::string& name, - ConnectionEventListener *connectCB=NULL, - ConnectionEventListener *disconnectCB=NULL); + OutXMLPort(const std::string& name, + ConnectionEventListener *connectCB=NULL, + ConnectionEventListener *disconnectCB=NULL); - OutPort(const std::string& name, - LOGGER_PTR logger, - ConnectionEventListener *connectCB=NULL, - ConnectionEventListener *disconnectCB=NULL); + OutXMLPort(const std::string& name, + LOGGER_PTR logger, + ConnectionEventListener *connectCB=NULL, + ConnectionEventListener *disconnectCB=NULL); /* * DEPRECATED: maps to dataFile BULKIO method call for passing strings of data @@ -666,43 +662,39 @@ namespace bulkio { * */ // Bulkio octet (UInt8) output - typedef OutPort< OctetPortTraits > OutOctetPort; + typedef OutNumericPort OutOctetPort; // Bulkio UInt8 output - typedef OutOctetPort OutUInt8Port; + typedef OutOctetPort OutUInt8Port; // Bulkio short output - typedef OutPort< ShortPortTraits > OutShortPort; + typedef OutNumericPort OutShortPort; // Bulkio unsigned short output - typedef OutPort< UShortPortTraits > OutUShortPort; + typedef OutNumericPort OutUShortPort; // Bulkio Int16 output - typedef OutShortPort OutInt16Port; + typedef OutShortPort OutInt16Port; // Bulkio UInt16 output - typedef OutUShortPort OutUInt16Port; + typedef OutUShortPort OutUInt16Port; // Bulkio long output - typedef OutPort< LongPortTraits > OutLongPort; + typedef OutNumericPort OutLongPort; // Bulkio unsigned long output - typedef OutPort< ULongPortTraits > OutULongPort; + typedef OutNumericPort OutULongPort; // Bulkio Int32 output - typedef OutLongPort OutInt32Port; + typedef OutLongPort OutInt32Port; // Bulkio UInt32 output - typedef OutULongPort OutUInt32Port; + typedef OutULongPort OutUInt32Port; // Bulkio long long output - typedef OutPort< LongLongPortTraits > OutLongLongPort; + typedef OutNumericPort OutLongLongPort; // Bulkio unsigned long long output - typedef OutPort< ULongLongPortTraits > OutULongLongPort; + typedef OutNumericPort OutULongLongPort; // Bulkio Int64 output - typedef OutLongLongPort OutInt64Port; + typedef OutLongLongPort OutInt64Port; // Bulkio UInt64 output - typedef OutULongLongPort OutUInt64Port; + typedef OutULongLongPort OutUInt64Port; // Bulkio float output - typedef OutPort< FloatPortTraits > OutFloatPort; + typedef OutNumericPort OutFloatPort; // Bulkio double output - typedef OutPort< DoublePortTraits > OutDoublePort; + typedef OutNumericPort OutDoublePort; // Bulkio URL output - typedef OutPort OutFilePort; - typedef OutFilePort OutURLPort; - // Bulkio XML output - typedef OutPort OutXMLPort; - + typedef OutFilePort OutURLPort; } // end of bulkio namespace inline bool operator>>= (const CORBA::Any& a, bulkio::connection_descriptor_struct& s) { diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h index 314bcc668..455ca3dcb 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h @@ -35,7 +35,7 @@ namespace bulkio { template - class OutPortBase; + class OutPort; class OutputStreamBase { public: @@ -169,8 +169,8 @@ namespace bulkio { void write(const ComplexType* data, size_t count, const std::list& times); private: - friend class OutPortBase; - typedef OutPortBase OutPortType; + friend class OutPort; + typedef OutPort OutPortType; OutputStream(const BULKIO::StreamSRI& sri, OutPortType* port); class Impl; @@ -196,8 +196,8 @@ namespace bulkio { void write(const std::string& xmlString); private: - friend class OutPortBase; - typedef OutPortBase OutPortType; + friend class OutPort; + typedef OutPort OutPortType; OutputStream(const BULKIO::StreamSRI& sri, OutPortType* port); class Impl; @@ -222,8 +222,8 @@ namespace bulkio { void write(const std::string& URL, const BULKIO::PrecisionUTCTime& time); private: - friend class OutPortBase; - typedef OutPortBase OutPortType; + friend class OutPort; + typedef OutPort OutPortType; OutputStream(const BULKIO::StreamSRI& sri, OutPortType* port); class Impl; From 140a818f6e95aec2aa32fe6524c02a949bb1ee4f Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 30 Nov 2016 15:44:27 -0500 Subject: [PATCH 0573/1644] Rename C++ BulkIO in port classes following out port example; move most stream functionality (still missing for File and XML) into the base class --- .../libsrc/cpp/bulkio_in_port.cpp | 383 +++++++++--------- bulkioInterfaces/libsrc/cpp/bulkio_in_port.h | 186 +++++---- bulkioInterfaces/libsrc/cpp/bulkio_out_port.h | 4 +- 3 files changed, 280 insertions(+), 293 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp index c98727cf1..07a9f91e7 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp @@ -31,7 +31,7 @@ namespace bulkio { // ---------------------------------------------------------------------------------------- template < typename PortTraits > - InPortBase< PortTraits >::InPortBase(std::string port_name, + InPort< PortTraits >::InPort(std::string port_name, LOGGER_PTR logger, bulkio::sri::Compare sriCmp, SriListener *newStreamCB): @@ -72,7 +72,7 @@ namespace bulkio { template < typename PortTraits > - InPortBase< PortTraits >::~InPortBase() + InPort< PortTraits >::~InPort() { TRACE_ENTER( logger, "InPort::DTOR" ); @@ -96,7 +96,7 @@ namespace bulkio { template < typename PortTraits > - BULKIO::PortStatistics * InPortBase< PortTraits >::statistics() + BULKIO::PortStatistics * InPort< PortTraits >::statistics() { SCOPED_LOCK lock(dataBufferLock); BULKIO::PortStatistics_var recStat = new BULKIO::PortStatistics(stats->retrieve()); @@ -106,7 +106,7 @@ namespace bulkio { template < typename PortTraits > - BULKIO::PortUsageType InPortBase< PortTraits >::state() + BULKIO::PortUsageType InPort< PortTraits >::state() { SCOPED_LOCK lock(dataBufferLock); if (packetQueue.size() == maxQueue) { @@ -122,7 +122,7 @@ namespace bulkio { template < typename PortTraits > - BULKIO::StreamSRISequence * InPortBase< PortTraits >::activeSRIs() + BULKIO::StreamSRISequence * InPort< PortTraits >::activeSRIs() { SCOPED_LOCK lock(sriUpdateLock); BULKIO::StreamSRISequence_var retSRI = new BULKIO::StreamSRISequence(); @@ -135,28 +135,28 @@ namespace bulkio { } template < typename PortTraits > - int InPortBase< PortTraits >::getMaxQueueDepth() + int InPort< PortTraits >::getMaxQueueDepth() { SCOPED_LOCK lock(dataBufferLock); return maxQueue; } template < typename PortTraits > - int InPortBase< PortTraits >::getCurrentQueueDepth() + int InPort< PortTraits >::getCurrentQueueDepth() { SCOPED_LOCK lock(dataBufferLock); return packetQueue.size(); } template < typename PortTraits > - void InPortBase< PortTraits >::setMaxQueueDepth(int newDepth) + void InPort< PortTraits >::setMaxQueueDepth(int newDepth) { SCOPED_LOCK lock(dataBufferLock); maxQueue = newDepth; } template < typename PortTraits > - void InPortBase< PortTraits >::pushSRI(const BULKIO::StreamSRI& H) + void InPort< PortTraits >::pushSRI(const BULKIO::StreamSRI& H) { TRACE_ENTER( logger, "InPort::pushSRI" ); @@ -192,10 +192,19 @@ namespace bulkio { template < typename PortTraits > - void InPortBase< PortTraits >::queuePacket(const SharedBufferType& data, const BULKIO::PrecisionUTCTime& T, CORBA::Boolean EOS, const std::string& streamID) + void InPort< PortTraits >::queuePacket(const SharedBufferType& data, const BULKIO::PrecisionUTCTime& T, CORBA::Boolean EOS, const std::string& streamID) { - TRACE_ENTER( logger, "InPort::pushPacket" ); + // Discard packets for disabled streams + if (!isStreamEnabled(streamID)) { + if (EOS) { + // Acknowledge the end-of-stream by removing the disabled stream + // before discarding the packet + removeStream(streamID); + } + return; + } + if (maxQueue == 0) { TRACE_EXIT( logger, "InPort::pushPacket" ); return; @@ -270,12 +279,14 @@ namespace bulkio { dataAvailable.notify_all(); } + packetWaiters.notify(streamID); + TRACE_EXIT( logger, "InPort::pushPacket" ); } template < typename PortTraits > - typename InPortBase< PortTraits >::Packet* InPortBase< PortTraits >::peekPacket(float timeout, + typename InPort< PortTraits >::Packet* InPort< PortTraits >::peekPacket(float timeout, boost::unique_lock& lock) { uint64_t secs = (unsigned long)(trunc(timeout)); @@ -301,7 +312,7 @@ namespace bulkio { } template < typename PortTraits > - void InPortBase< PortTraits >::enableStats( bool enable ) + void InPort< PortTraits >::enableStats( bool enable ) { if (stats ) { stats->setEnabled(enable); @@ -310,7 +321,7 @@ namespace bulkio { template < typename PortTraits > - void InPortBase< PortTraits >::block() + void InPort< PortTraits >::block() { TRACE_ENTER( logger, "InPort::block" ); breakBlock = true; @@ -320,29 +331,76 @@ namespace bulkio { } template < typename PortTraits > - void InPortBase< PortTraits >::unblock() + void InPort< PortTraits >::unblock() { breakBlock = false; } template < typename PortTraits > - void InPortBase< PortTraits >::stopPort() + void InPort< PortTraits >::stopPort() { block(); } template < typename PortTraits > - void InPortBase< PortTraits >::startPort() + void InPort< PortTraits >::startPort() { unblock(); } template < typename PortTraits > - bool InPortBase< PortTraits >::blocked() + bool InPort< PortTraits >::blocked() { return breakBlock; } + template < typename PortTraits > + typename InPort< PortTraits >::StreamType InPort< PortTraits >::getCurrentStream(float timeout) + { + // Prefer a stream that already has buffered data + { + boost::mutex::scoped_lock lock(streamsMutex); + for (typename StreamMap::iterator stream = streams.begin(); stream != streams.end(); ++stream) { + if (stream->second.hasBufferedData()) { + return stream->second; + } + } + } + + // Otherwise, return the stream that owns the next packet on the queue, + // potentially waiting for one to be received + boost::mutex::scoped_lock lock(this->dataBufferLock); + Packet* packet = this->peekPacket(timeout, lock); + if (packet) { + return getStream(packet->streamID); + } + + return StreamType(); + } + + template < typename PortTraits > + typename InPort< PortTraits >::StreamType InPort< PortTraits >::getStream(const std::string& streamID) + { + boost::mutex::scoped_lock lock(streamsMutex); + typename StreamMap::iterator stream = streams.find(streamID); + if (stream != streams.end()) { + return stream->second; + } else { + return StreamType(); + } + } + + template < typename PortTraits > + typename InPort< PortTraits >::StreamList InPort< PortTraits >::getStreams() + { + StreamList result; + boost::mutex::scoped_lock lock(streamsMutex); + for (typename StreamMap::const_iterator stream = streams.begin(); stream != streams.end(); ++stream) { + result.push_back(stream->second); + } + return result; + } + /* * getPacket * description: retrieve data from the provides (input) port @@ -351,14 +409,14 @@ namespace bulkio { * Use 0.0 for non-blocking and -1 for blocking. */ template < typename PortTraits > - typename InPortBase< PortTraits >::DataTransferType * InPortBase< PortTraits >::getPacket(float timeout) + typename InPort< PortTraits >::DataTransferType * InPort< PortTraits >::getPacket(float timeout) { return getPacket(timeout, ""); } template < typename PortTraits > - typename InPortBase< PortTraits >::DataTransferType * InPortBase< PortTraits >::getPacket(float timeout, const std::string& streamID) + typename InPort< PortTraits >::DataTransferType * InPort< PortTraits >::getPacket(float timeout, const std::string& streamID) { DataTransferType* transfer = 0; boost::scoped_ptr packet(nextPacket(timeout, streamID)); @@ -371,7 +429,7 @@ namespace bulkio { template - typename InPortBase::Packet* InPortBase::nextPacket(float timeout, const std::string& streamID) + typename InPort::Packet* InPort::nextPacket(float timeout, const std::string& streamID) { TRACE_ENTER(logger, "InPort::nextPacket"); if (breakBlock) { @@ -469,13 +527,28 @@ namespace bulkio { } template < typename PortTraits > - void InPortBase< PortTraits >::createStream(const std::string& /*unused*/, - const boost::shared_ptr& /*unused*/) + void InPort< PortTraits >::createStream(const std::string& streamID, + const boost::shared_ptr& sri) { + StreamType stream(sri, this); + boost::mutex::scoped_lock lock(streamsMutex); + if (streams.count(streamID) == 0) { + // New stream + LOG_DEBUG(logger, "Creating new stream " << streamID); + streams.insert(std::make_pair(streamID, stream)); + lock.unlock(); + + streamAdded(stream); + } else { + // An active stream has the same stream ID; add this new stream to the + // pending list + LOG_DEBUG(logger, "Creating pending stream " << streamID); + pendingStreams.insert(std::make_pair(streamID, stream)); + } } template < typename PortTraits > - typename InPortBase< PortTraits >::Packet * InPortBase< PortTraits >::fetchPacket(const std::string &streamID) + typename InPort< PortTraits >::Packet * InPort< PortTraits >::fetchPacket(const std::string &streamID) { if (streamID.empty()) { if (packetQueue.empty()) { @@ -497,7 +570,7 @@ namespace bulkio { } template < typename PortTraits > - void InPortBase< PortTraits >::discardPacketsForStream(const std::string& streamID) + void InPort< PortTraits >::discardPacketsForStream(const std::string& streamID) { SCOPED_LOCK lock(dataBufferLock); for (typename PacketQueue::iterator ii = packetQueue.begin(); ii != packetQueue.end();) { @@ -516,18 +589,18 @@ namespace bulkio { } template < typename PortTraits > - std::string InPortBase< PortTraits >::getRepid() const { + std::string InPort< PortTraits >::getRepid() const { return PortType::_PD_repoId; } template < typename PortTraits > - int InPortBase< PortTraits >::_getElementLength(const SharedBufferType& data) + int InPort< PortTraits >::_getElementLength(const SharedBufferType& data) { return data.size(); } template < typename PortTraits > - size_t InPortBase< PortTraits >::samplesAvailable (const std::string& streamID, bool firstPacket) + size_t InPort< PortTraits >::samplesAvailable (const std::string& streamID, bool firstPacket) { size_t samples = 0; size_t item_size = 1; @@ -549,6 +622,53 @@ namespace bulkio { return samples / item_size; } + template < typename PortTraits > + void InPort< PortTraits >::removeStream(const std::string& streamID) + { + LOG_DEBUG(logger, "Removing stream " << streamID); + boost::mutex::scoped_lock lock(streamsMutex); + streams.erase(streamID); + typename std::multimap::iterator next = pendingStreams.find(streamID); + if (next != pendingStreams.end()) { + LOG_DEBUG(logger, "Moving pending stream " << streamID << " to active"); + StreamType stream = next->second; + streams.insert(*next); + pendingStreams.erase(next); + lock.unlock(); + + streamAdded(stream); + } + } + + template < typename PortTraits > + bool InPort< PortTraits >::isStreamActive(const std::string& streamID) + { + SCOPED_LOCK lock(streamsMutex); + if (pendingStreams.count(streamID) > 0) { + // The current stream has received an EOS + return false; + } else if (streams.count(streamID) == 0) { + // Unknown stream, presumably no SRI was received + return false; + } + return true; + } + + template < typename PortTraits > + bool InPort< PortTraits >::isStreamEnabled(const std::string& streamID) + { + SCOPED_LOCK lock(streamsMutex); + if (pendingStreams.count(streamID) == 0) { + typename StreamMap::iterator stream = streams.find(streamID); + if (stream != streams.end()) { + if (!stream->second.enabled()) { + return false; + } + } + } + return true; + } + namespace { template inline bool is_ready(StreamType& stream, size_t size) @@ -578,37 +698,37 @@ namespace bulkio { */ template <> - int InPortBase< FilePortTraits >::_getElementLength(const std::string& /*unused*/) + int InPort< FilePortTraits >::_getElementLength(const std::string& /*unused*/) { return 1; } // template < typename PortTraits > - InPort< PortTraits >::InPort(std::string port_name, + InNumericPort< PortTraits >::InNumericPort(std::string port_name, LOGGER_PTR logger, bulkio::sri::Compare compareSri, SriListener *newStreamCB ) : - InPortBase(port_name, logger, compareSri, newStreamCB) + InPort(port_name, logger, compareSri, newStreamCB) { } template < typename PortTraits > - InPort< PortTraits >::InPort(std::string port_name, + InNumericPort< PortTraits >::InNumericPort(std::string port_name, bulkio::sri::Compare compareSri, SriListener *newStreamCB ) : - InPortBase(port_name, LOGGER_PTR(), compareSri, newStreamCB) + InPort(port_name, LOGGER_PTR(), compareSri, newStreamCB) { } template < typename PortTraits > - InPort< PortTraits >::InPort(std::string port_name, void* /*unused*/) : - InPortBase(port_name, LOGGER_PTR()) + InNumericPort< PortTraits >::InNumericPort(std::string port_name, void* /*unused*/) : + InPort(port_name, LOGGER_PTR()) { } template < typename PortTraits > - void InPort< PortTraits >::pushPacket(const PortSequenceType& data, const BULKIO::PrecisionUTCTime& T, CORBA::Boolean EOS, const char* streamID) + void InNumericPort< PortTraits >::pushPacket(const PortSequenceType& data, const BULKIO::PrecisionUTCTime& T, CORBA::Boolean EOS, const char* streamID) { size_t size = data.length(); TransportType* ptr = const_cast(data).get_buffer(1); @@ -616,72 +736,25 @@ namespace bulkio { } template < typename PortTraits > - void InPort< PortTraits >::pushPacket(const SharedBufferType& data, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID) + void InNumericPort< PortTraits >::pushPacket(const SharedBufferType& data, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID) { this->queuePacket(data, T, EOS, streamID); } template < typename PortTraits > - typename InPort< PortTraits >::StreamType InPort< PortTraits >::getCurrentStream(float timeout) - { - // Prefer a stream that already has buffered data - { - boost::mutex::scoped_lock lock(streamsMutex); - for (typename StreamMap::iterator stream = streams.begin(); stream != streams.end(); ++stream) { - if (stream->second.hasBufferedData()) { - return stream->second; - } - } - } - - // Otherwise, return the stream that owns the next packet on the queue, - // potentially waiting for one to be received - boost::mutex::scoped_lock lock(this->dataBufferLock); - Packet* packet = this->peekPacket(timeout, lock); - if (packet) { - return getStream(packet->streamID); - } - - return StreamType(); - } - - template < typename PortTraits > - typename InPort< PortTraits >::StreamType InPort< PortTraits >::getStream(const std::string& streamID) - { - boost::mutex::scoped_lock lock(streamsMutex); - typename StreamMap::iterator stream = streams.find(streamID); - if (stream != streams.end()) { - return stream->second; - } else { - return StreamType(); - } - } - - template < typename PortTraits > - typename InPort< PortTraits >::StreamList InPort< PortTraits >::getStreams() - { - StreamList result; - boost::mutex::scoped_lock lock(streamsMutex); - for (typename StreamMap::const_iterator stream = streams.begin(); stream != streams.end(); ++stream) { - result.push_back(stream->second); - } - return result; - } - - template < typename PortTraits > - typename InPort< PortTraits >::StreamList InPort< PortTraits >::pollStreams(float timeout) + typename InNumericPort< PortTraits >::StreamList InNumericPort< PortTraits >::pollStreams(float timeout) { return pollStreams(0, timeout); } template < typename PortTraits > - typename InPort< PortTraits >::StreamList InPort< PortTraits >::pollStreams(StreamList& pollset, float timeout) + typename InNumericPort< PortTraits >::StreamList InNumericPort< PortTraits >::pollStreams(StreamList& pollset, float timeout) { return pollStreams(pollset, 0, timeout); } template < typename PortTraits > - typename InPort< PortTraits >::StreamList InPort< PortTraits >::pollStreams(size_t samples, float timeout) + typename InNumericPort< PortTraits >::StreamList InNumericPort< PortTraits >::pollStreams(size_t samples, float timeout) { redhawk::signal::waiter waiter(&packetWaiters, timeout); @@ -700,7 +773,7 @@ namespace bulkio { } template < typename PortTraits > - typename InPort< PortTraits >::StreamList InPort< PortTraits >::pollStreams(StreamList& pollset, size_t samples, float timeout) + typename InNumericPort< PortTraits >::StreamList InNumericPort< PortTraits >::pollStreams(StreamList& pollset, size_t samples, float timeout) { redhawk::signal::waiter waiter(&packetWaiters, timeout); @@ -725,91 +798,7 @@ namespace bulkio { } template < typename PortTraits > - void InPort< PortTraits >::queuePacket(const SharedBufferType& data, const BULKIO::PrecisionUTCTime& T, CORBA::Boolean EOS, const std::string& streamID) - { - if (isStreamEnabled(streamID)) { - super::queuePacket(data, T, EOS, streamID); - - if (isStreamActive(streamID)) { - packetWaiters.notify(streamID); - } - } else if (EOS) { - // Acknowledge the end-of-stream by removing the disabled stream before - // discarding the packet - removeStream(streamID); - } - } - - template < typename PortTraits > - void InPort< PortTraits >::createStream(const std::string& streamID, - const boost::shared_ptr& sri) - { - StreamType stream(sri, this); - boost::mutex::scoped_lock lock(streamsMutex); - if (streams.count(streamID) == 0) { - // New stream - LOG_DEBUG(logger, "Creating new stream " << streamID); - streams.insert(std::make_pair(streamID, stream)); - lock.unlock(); - - streamAdded(stream); - } else { - // An active stream has the same stream ID; add this new stream to the - // pending list - LOG_DEBUG(logger, "Creating pending stream " << streamID); - pendingStreams.insert(std::make_pair(streamID, stream)); - } - } - - template < typename PortTraits > - void InPort< PortTraits >::removeStream(const std::string& streamID) - { - LOG_DEBUG(logger, "Removing stream " << streamID); - boost::mutex::scoped_lock lock(streamsMutex); - streams.erase(streamID); - typename std::multimap::iterator next = pendingStreams.find(streamID); - if (next != pendingStreams.end()) { - LOG_DEBUG(logger, "Moving pending stream " << streamID << " to active"); - StreamType stream = next->second; - streams.insert(*next); - pendingStreams.erase(next); - lock.unlock(); - - streamAdded(stream); - } - } - - template < typename PortTraits > - bool InPort< PortTraits >::isStreamActive(const std::string& streamID) - { - SCOPED_LOCK lock(streamsMutex); - if (pendingStreams.count(streamID) > 0) { - // The current stream has received an EOS - return false; - } else if (streams.count(streamID) == 0) { - // Unknown stream, presumably no SRI was received - return false; - } - return true; - } - - template < typename PortTraits > - bool InPort< PortTraits >::isStreamEnabled(const std::string& streamID) - { - SCOPED_LOCK lock(streamsMutex); - if (pendingStreams.count(streamID) == 0) { - typename StreamMap::iterator stream = streams.find(streamID); - if (stream != streams.end()) { - if (!stream->second.enabled()) { - return false; - } - } - } - return true; - } - - template < typename PortTraits > - typename InPort< PortTraits >::StreamList InPort< PortTraits >::getReadyStreams(size_t samples) + typename InNumericPort< PortTraits >::StreamList InNumericPort< PortTraits >::getReadyStreams(size_t samples) { StreamList result; boost::mutex::scoped_lock lock(streamsMutex); @@ -829,7 +818,7 @@ namespace bulkio { LOGGER_PTR logger, bulkio::sri::Compare compareSri, SriListener *newStreamCB) : - InPortBase(port_name, logger, compareSri, newStreamCB) + InPort(port_name, logger, compareSri, newStreamCB) { } @@ -837,12 +826,12 @@ namespace bulkio { InFilePort::InFilePort(std::string port_name, bulkio::sri::Compare compareSri, SriListener *newStreamCB) : - InPortBase(port_name, LOGGER_PTR(), compareSri, newStreamCB) + InPort(port_name, LOGGER_PTR(), compareSri, newStreamCB) { } InFilePort::InFilePort(std::string port_name, void* /*unused*/) : - InPortBase(port_name, LOGGER_PTR()) + InPort(port_name, LOGGER_PTR()) { } @@ -865,7 +854,7 @@ namespace bulkio { LOGGER_PTR logger, bulkio::sri::Compare compareSri, SriListener* newStreamCB) : - InPortBase(name, logger, compareSri, newStreamCB) + InPort(name, logger, compareSri, newStreamCB) { } @@ -873,12 +862,12 @@ namespace bulkio { InXMLPort::InXMLPort(std::string name, bulkio::sri::Compare compareSri, SriListener* newStreamCB) : - InPortBase(name, LOGGER_PTR(), compareSri, newStreamCB) + InPort(name, LOGGER_PTR(), compareSri, newStreamCB) { } InXMLPort::InXMLPort(std::string name, void* /*unused*/) : - InPortBase(name, LOGGER_PTR()) + InPort(name, LOGGER_PTR()) { } @@ -912,24 +901,24 @@ namespace bulkio { // link against the template. // -#define INSTANTIATE_BASE_TEMPLATE(x) \ - template class InPortBase; - #define INSTANTIATE_TEMPLATE(x) \ - INSTANTIATE_BASE_TEMPLATE(x); template class InPort; - - INSTANTIATE_TEMPLATE(CharPortTraits); - INSTANTIATE_TEMPLATE(OctetPortTraits); - INSTANTIATE_TEMPLATE(ShortPortTraits); - INSTANTIATE_TEMPLATE(UShortPortTraits); - INSTANTIATE_TEMPLATE(LongPortTraits); - INSTANTIATE_TEMPLATE(ULongPortTraits); - INSTANTIATE_TEMPLATE(LongLongPortTraits); - INSTANTIATE_TEMPLATE(ULongLongPortTraits); - INSTANTIATE_TEMPLATE(FloatPortTraits); - INSTANTIATE_TEMPLATE(DoublePortTraits); - - INSTANTIATE_BASE_TEMPLATE(FilePortTraits); - INSTANTIATE_BASE_TEMPLATE(XMLPortTraits); + template class InPort; + +#define INSTANTIATE_NUMERIC_TEMPLATE(x) \ + INSTANTIATE_TEMPLATE(x); template class InNumericPort; + + INSTANTIATE_NUMERIC_TEMPLATE(CharPortTraits); + INSTANTIATE_NUMERIC_TEMPLATE(OctetPortTraits); + INSTANTIATE_NUMERIC_TEMPLATE(ShortPortTraits); + INSTANTIATE_NUMERIC_TEMPLATE(UShortPortTraits); + INSTANTIATE_NUMERIC_TEMPLATE(LongPortTraits); + INSTANTIATE_NUMERIC_TEMPLATE(ULongPortTraits); + INSTANTIATE_NUMERIC_TEMPLATE(LongLongPortTraits); + INSTANTIATE_NUMERIC_TEMPLATE(ULongLongPortTraits); + INSTANTIATE_NUMERIC_TEMPLATE(FloatPortTraits); + INSTANTIATE_NUMERIC_TEMPLATE(DoublePortTraits); + + INSTANTIATE_TEMPLATE(FilePortTraits); + INSTANTIATE_TEMPLATE(XMLPortTraits); } // end of bulkio namespace diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h index 1d8a3c1c2..bfa2a28c2 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h @@ -37,14 +37,14 @@ namespace bulkio { // - // InPortBase + // InPort // Base template for data transfers between BULKIO ports. This class is defined by 2 trait classes // DataTransferTraits: This template trait defines the DataTranfer object that is returned by the getPacket method // PortTraits - This template provides the context for the port's middleware transport classes and they base data types // passed between port objects // template < typename PortTraits > - class InPortBase : public PortTraits::POAPortType, public Port_Provides_base_impl + class InPort : public PortTraits::POAPortType, public Port_Provides_base_impl { public: @@ -67,11 +67,17 @@ namespace bulkio { typedef DataTransfer< typename Traits::DataTransferTraits > DataTransferType; typedef typename Traits::SharedBufferType SharedBufferType; + + // Input stream interface used by this port + typedef InputStream StreamType; + + // List type for input streams provided by this port + typedef std::list StreamList; // - // ~InPortBase - call the virtual destructor to remove all allocated memebers + // ~InPort - call the virtual destructor to remove all allocated memebers // - virtual ~InPortBase(); + virtual ~InPort(); /* * getPacket - interface used by components to grab data from the port's internal queue object for processing. The timeout parameter allows @@ -200,7 +206,25 @@ namespace bulkio { * @return bool returns state of breakBlock variable used to release any upstream blocking pushPacket calls */ virtual bool blocked(); - + + template + void addStreamListener(Target target, Func func) { + streamAdded.add(target, func); + } + + template + void removeStreamListener(Target target, Func func) { + streamAdded.remove(target, func); + } + + // Returns the stream that should be used for the next basic read + StreamType getCurrentStream(float timeout=bulkio::Const::BLOCKING); + + // Returns the current stream with the given stream ID, if available + StreamType getStream(const std::string& streamID); + + StreamList getStreams(); + /* * Assign a callback for notification when a new SRI StreamId is received */ @@ -226,13 +250,13 @@ namespace bulkio { protected: // - // InPortBase - creates a provides port that can accept data vectors from a source + // InPort - creates a provides port that can accept data vectors from a source // // @param port_name name of the port taken from .scd.xml file // @param sriCmp comparator function that accepts to StreamSRI objects and compares their contents, // if all members match then return true, otherwise false. This is used during the pushSRI method // @param newStreamCB interface that is called when new SRI.streamID is received - InPortBase(std::string port_name, + InPort(std::string port_name, LOGGER_PTR logger, bulkio::sri::Compare sriCmp = bulkio::sri::DefaultComparator, SriListener *newStreamCB = NULL ); @@ -315,6 +339,22 @@ namespace bulkio { // redhawk::signal packetWaiters; + // + // Notification for new stream creation + // + ossie::notification streamAdded; + + // + // Streams that are currently active + // + typedef std::map StreamMap; + StreamMap streams; + boost::mutex streamsMutex; + + // Streams that have the same stream ID as an active stream, when an + // end-of-stream has been queued but not yet read + std::multimap pendingStreams; + // // Queues a packet received via pushPacket; in most cases, this method maps // exactly to pushPacket, except for dataFile @@ -333,8 +373,6 @@ namespace bulkio { // Packet* peekPacket(float timeout, boost::unique_lock& lock); - virtual void createStream(const std::string& streamID, const boost::shared_ptr& sri); - Packet* fetchPacket(const std::string& streamID); // Discard currently queued packets for the given stream ID, up to the @@ -344,6 +382,12 @@ namespace bulkio { friend class InputStream; size_t samplesAvailable(const std::string& streamID, bool firstPacket); + void createStream(const std::string& streamID, const boost::shared_ptr& sri); + void removeStream(const std::string& streamID); + + bool isStreamActive(const std::string& streamID); + bool isStreamEnabled(const std::string& streamID); + // // Returns the total number of elements of data in a pushPacket call, for // statistical tracking; enables XML and File specialization, which have @@ -353,7 +397,7 @@ namespace bulkio { }; template < typename PortTraits > - class InPort : public InPortBase + class InNumericPort : public InPort { public: typedef PortTraits Traits; @@ -385,29 +429,27 @@ namespace bulkio { // backwards compatible definition typedef DataTransferType dataTransfer; - // Input stream interface used by this port - typedef InputStream StreamType; + typedef typename InPort::StreamType StreamType; - // List type for input streams provided by this port - typedef std::list StreamList; + typedef typename InPort::StreamList StreamList; // - // InPort - creates a provides port that can accept data vectors from a source + // InNumericPort - creates a provides port that can accept data vectors from a source // // @param port_name name of the port taken from .scd.xml file // @param sriCmp comparator function that accepts to StreamSRI objects and compares their contents, // if all members match then return true, otherwise false. This is used during the pushSRI method // @param newStreamCB interface that is called when new SRI.streamID is received - InPort(std::string port_name, - LOGGER_PTR logger, - bulkio::sri::Compare sriCmp = bulkio::sri::DefaultComparator, - SriListener *newStreamCB = NULL ); - - InPort(std::string port_name, - bulkio::sri::Compare sriCmp = bulkio::sri::DefaultComparator, - SriListener *newStreamCB = NULL ); + InNumericPort(std::string port_name, + LOGGER_PTR logger, + bulkio::sri::Compare sriCmp = bulkio::sri::DefaultComparator, + SriListener *newStreamCB = NULL); + + InNumericPort(std::string port_name, + bulkio::sri::Compare sriCmp = bulkio::sri::DefaultComparator, + SriListener *newStreamCB = NULL); - InPort(std::string port_name, void *); + InNumericPort(std::string port_name, void *); // // pushPacket called by the source component when pushing a vector of data into a component. This method will save off the data @@ -426,65 +468,21 @@ namespace bulkio { // Stream-based input API // - // Returns the stream that should be used for the next basic read - StreamType getCurrentStream(float timeout=bulkio::Const::BLOCKING); - - // Returns the current stream with the given stream ID, if available - StreamType getStream(const std::string& streamID); - - StreamList getStreams(); - StreamList pollStreams(float timeout); StreamList pollStreams(StreamList& pollset, float timeout); StreamList pollStreams(size_t samples, float timeout); StreamList pollStreams(StreamList& pollset, size_t samples, float timeout); - template - void addStreamListener(Target target, Func func) { - streamAdded.add(target, func); - } - - template - void removeStreamListener(Target target, Func func) { - streamAdded.remove(target, func); - } - protected: - typedef InPortBase super; + typedef InPort super; using super::packetWaiters; using super::logger; + typedef typename super::StreamMap StreamMap; + using super::streams; + using super::streamsMutex; typedef typename super::Packet Packet; - // Allow the input stream type friend access so it can call removeStream() - // when it acknowledges an end-of-stream - friend class InputStream; - - // - // Notification for new stream creation - // - ossie::notification streamAdded; - - // - // Streams that are currently active - // - typedef std::map StreamMap; - StreamMap streams; - boost::mutex streamsMutex; - - // Streams that have the same stream ID as an active stream, when an - // end-of-stream has been queued but not yet read - std::multimap pendingStreams; - - // Override of base class queuePacket to add stream-related behavior - void queuePacket(const SharedBufferType& data, const BULKIO::PrecisionUTCTime& T, CORBA::Boolean EOS, const std::string& streamID); - - virtual void createStream(const std::string& streamID, const boost::shared_ptr& sri); - void removeStream(const std::string& streamID); - - bool isStreamActive(const std::string& streamID); - bool isStreamEnabled(const std::string& streamID); - StreamList getReadyStreams(size_t samples); }; @@ -500,10 +498,10 @@ namespace bulkio { // - class InFilePort : public InPortBase + class InFilePort : public InPort { public: - typedef InPortBase::DataTransferType DataTransferType; + typedef InPort::DataTransferType DataTransferType; typedef DataTransferType dataTransfer; // @@ -540,10 +538,10 @@ namespace bulkio { }; - class InXMLPort : public InPortBase + class InXMLPort : public InPort { public: - typedef InPortBase::DataTransferType DataTransferType; + typedef InPort::DataTransferType DataTransferType; typedef DataTransferType dataTransfer; InXMLPort(std::string port_name, LOGGER_PTR logger, @@ -577,41 +575,41 @@ namespace bulkio { * */ // Bulkio char (Int8) input - typedef InPort< CharPortTraits > InCharPort; + typedef InNumericPort InCharPort; // Bulkio octet (UInt8) input - typedef InPort< OctetPortTraits > InOctetPort; + typedef InNumericPort InOctetPort; // Bulkio Int8 input - typedef InCharPort InInt8Port; + typedef InCharPort InInt8Port; // Bulkio UInt8 input - typedef InOctetPort InUInt8Port; + typedef InOctetPort InUInt8Port; // Bulkio short (Int16) input - typedef InPort< ShortPortTraits > InShortPort; + typedef InNumericPort InShortPort; // Bulkio unsigned short (UInt16) input - typedef InPort< UShortPortTraits > InUShortPort; + typedef InNumericPort InUShortPort; // Bulkio Int16 input - typedef InShortPort InInt16Port; + typedef InShortPort InInt16Port; // Bulkio UInt16 input - typedef InUShortPort InUInt16Port; + typedef InUShortPort InUInt16Port; // Bulkio long (Int32) input - typedef InPort< LongPortTraits > InLongPort; + typedef InNumericPort InLongPort; // Bulkio unsigned long (UInt32) input - typedef InPort< ULongPortTraits > InULongPort; + typedef InNumericPort InULongPort; // Bulkio Int32 input - typedef InLongPort InInt32Port; + typedef InLongPort InInt32Port; // Bulkio UInt32 input - typedef InULongPort InUInt32Port; + typedef InULongPort InUInt32Port; // Bulkio long long (Int64) input - typedef InPort< LongLongPortTraits > InLongLongPort; + typedef InNumericPort InLongLongPort; // Bulkio unsigned long long (UInt64) input - typedef InPort< ULongLongPortTraits > InULongLongPort; + typedef InNumericPort InULongLongPort; // Bulkio Int64 input - typedef InLongLongPort InInt64Port; + typedef InLongLongPort InInt64Port; // Bulkio UInt64 input - typedef InULongLongPort InUInt64Port; + typedef InULongLongPort InUInt64Port; // Bulkio float input - typedef InPort< FloatPortTraits > InFloatPort; + typedef InNumericPort InFloatPort; // Bulkio double input - typedef InPort< DoublePortTraits > InDoublePort; + typedef InNumericPort InDoublePort; // Maintained for backwards compatibility typedef InFilePort InURLPort; diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h index 3b4fdf676..2fc855131 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h @@ -39,14 +39,14 @@ namespace bulkio { - template class InPort; + template class InNumericPort; class InFilePort; class InXMLPort; template struct LocalTraits { - typedef InPort InPortType; + typedef InNumericPort InPortType; }; template <> From 13ced8bd0165c7e242041f2f9ed10cb244d5817a Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 1 Dec 2016 09:20:11 -0500 Subject: [PATCH 0574/1644] Initial implementation of XML and File input streams and data blocks --- .../libsrc/cpp/bulkio_datablock.cpp | 100 ++++++ .../libsrc/cpp/bulkio_datablock.h | 40 +++ .../libsrc/cpp/bulkio_in_stream.cpp | 329 +++++++++++++----- .../libsrc/cpp/bulkio_in_stream.h | 75 +++- 4 files changed, 446 insertions(+), 98 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_datablock.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_datablock.cpp index db68889b5..0f4b6bd8e 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_datablock.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_datablock.cpp @@ -286,3 +286,103 @@ template class DataBlock; template class DataBlock; template class DataBlock; template class DataBlock; + + +// +// XML +// +using bulkio::XMLDataBlock; + +struct XMLDataBlock::Impl { + Impl(const boost::shared_ptr& sri) : + sri(sri) + { + } + + std::string data; + boost::shared_ptr sri; + int sriChangeFlags; + bool inputQueueFlushed; +}; + + +XMLDataBlock::XMLDataBlock() : + _impl() +{ +} + +XMLDataBlock::XMLDataBlock(const boost::shared_ptr& sri, const std::string& data) : + _impl(boost::make_shared(sri)) +{ + _impl->data = data; +} + +const BULKIO::StreamSRI& XMLDataBlock::sri() const +{ + return *(_impl->sri); +} + +const std::string& XMLDataBlock::data() const +{ + return _impl->data; +} + +bool XMLDataBlock::operator! () const +{ + return !_impl; +} + +XMLDataBlock::operator unspecified_bool_type() const +{ + return _impl?&XMLDataBlock::_impl:0; +} + + +// +// File +// +using bulkio::FileDataBlock; + +struct FileDataBlock::Impl { + Impl(const boost::shared_ptr& sri) : + sri(sri) + { + } + + std::string data; + boost::shared_ptr sri; + int sriChangeFlags; + bool inputQueueFlushed; +}; + + +FileDataBlock::FileDataBlock() : + _impl() +{ +} + +FileDataBlock::FileDataBlock(const boost::shared_ptr& sri, const std::string& data) : + _impl(boost::make_shared(sri)) +{ + _impl->data = data; +} + +const BULKIO::StreamSRI& FileDataBlock::sri() const +{ + return *(_impl->sri); +} + +const std::string& FileDataBlock::data() const +{ + return _impl->data; +} + +bool FileDataBlock::operator! () const +{ + return !_impl; +} + +FileDataBlock::operator unspecified_bool_type() const +{ + return _impl?&FileDataBlock::_impl:0; +} diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_datablock.h b/bulkioInterfaces/libsrc/cpp/bulkio_datablock.h index 028fb7e95..23b013af5 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_datablock.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_datablock.h @@ -108,6 +108,46 @@ namespace bulkio { operator unspecified_bool_type() const; }; + class XMLDataBlock { + public: + XMLDataBlock(); + XMLDataBlock(const boost::shared_ptr& sri, const std::string& data); + + const BULKIO::StreamSRI& sri() const; + const std::string& data() const; + + bool operator! () const; + + private: + struct Impl; + boost::shared_ptr _impl; + + typedef boost::shared_ptr XMLDataBlock::*unspecified_bool_type; + + public: + operator unspecified_bool_type() const; + }; + + class FileDataBlock { + public: + FileDataBlock(); + FileDataBlock(const boost::shared_ptr& sri, const std::string& data); + + const BULKIO::StreamSRI& sri() const; + const std::string& data() const; + + bool operator! () const; + + private: + struct Impl; + boost::shared_ptr _impl; + + typedef boost::shared_ptr FileDataBlock::*unspecified_bool_type; + + public: + operator unspecified_bool_type() const; + }; + typedef DataBlock CharDataBlock; typedef DataBlock OctetDataBlock; typedef DataBlock ShortDataBlock; diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp index 5ef1bd783..be5de15f3 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp @@ -22,53 +22,117 @@ #include "bulkio_time_operators.h" #include "bulkio_in_port.h" +#include +#include #include +using bulkio::InputStreamBase; + +class InputStreamBase::Impl { +public: + enum EosState { + EOS_NONE, + EOS_RECEIVED, + EOS_REACHED, + EOS_REPORTED + }; + + Impl(const boost::shared_ptr& sri) : + _streamID(sri->streamID), + _sri(sri), + _eosState(EOS_NONE), + _enabled(true) + { + } + + const std::string& streamID() const + { + return _streamID; + } + + const BULKIO::StreamSRI& sri() const + { + return *_sri; + } + + bool enabled() const + { + return _enabled; + } + + void enable() + { + _enabled = true; + } + +protected: + const std::string _streamID; + boost::shared_ptr _sri; + EosState _eosState; + bool _enabled; +}; + +InputStreamBase::InputStreamBase() : + _impl() +{ +} + +InputStreamBase::InputStreamBase(const boost::shared_ptr& impl) : + _impl(impl) +{ +} + +const std::string& InputStreamBase::streamID() const +{ + return _impl->streamID(); +} + +const BULKIO::StreamSRI& InputStreamBase::sri() const +{ + return _impl->sri(); +} + +bool InputStreamBase::enabled() const +{ + return _impl->enabled(); +} + +void InputStreamBase::enable() +{ + _impl->enable(); +} + +bool InputStreamBase::operator!() const +{ + return !_impl; +} + + using bulkio::InputStream; template -class InputStream::Impl { +class InputStream::Impl : public InputStreamBase::Impl { public: - typedef typename InPortType::Packet PacketType; - typedef typename PortTraits::NativeType NativeType; - typedef typename PortTraits::SharedBufferType SharedBufferType; - typedef DataBlock DataBlockType; - - enum EosState { - EOS_NONE, - EOS_RECEIVED, - EOS_REACHED, - EOS_REPORTED - }; - - Impl(const boost::shared_ptr& sri, InPortType* port) : - _streamID(sri->streamID), - _sri(sri), - _eosState(EOS_NONE), - _port(port), - _queue(), - _pending(0), - _samplesQueued(0), - _sampleOffset(0), - _enabled(true) - { - } + typedef typename InPortType::Packet PacketType; + typedef typename PortTraits::NativeType NativeType; + typedef typename PortTraits::SharedBufferType SharedBufferType; + typedef DataBlock DataBlockType; + + Impl(const boost::shared_ptr& sri, InPortType* port) : + InputStreamBase::Impl(sri), + _port(port), + _queue(), + _pending(0), + _samplesQueued(0), + _sampleOffset(0) + { + } ~Impl() { delete _pending; } - const std::string& streamID() const - { - return _streamID; - } - - const BULKIO::StreamSRI& sri() const - { - return *_sri; - } - bool eos() { if (_queue.empty()) { @@ -228,16 +292,6 @@ class InputStream::Impl { } } - bool enabled() const - { - return _enabled; - } - - void enable() - { - _enabled = true; - } - void disable() { _enabled = false; @@ -467,142 +521,237 @@ class InputStream::Impl { return !(packet->sriChanged || packet->inputQueueFlushed); } - const std::string _streamID; - boost::shared_ptr _sri; - EosState _eosState; InPortType* _port; boost::ptr_deque _queue; PacketType* _pending; size_t _samplesQueued; size_t _sampleOffset; - bool _enabled; }; template InputStream::InputStream() : - _impl() + InputStreamBase() { } template InputStream::InputStream(const boost::shared_ptr& sri, InPortType* port) : - _impl(new Impl(sri, port)) -{ -} - -template -const std::string& InputStream::streamID() const + InputStreamBase(boost::make_shared(sri, port)) { - return _impl->streamID(); -} - -template -const BULKIO::StreamSRI& InputStream::sri() const -{ - return _impl->sri(); } template bool InputStream::eos() { - return _impl->eos(); + return impl().eos(); } template typename InputStream::DataBlockType InputStream::read() { - return _impl->readPacket(true); + return impl().readPacket(true); } template typename InputStream::DataBlockType InputStream::read(size_t count) { - return _impl->read(count, count, true); + return impl().read(count, count, true); } template typename InputStream::DataBlockType InputStream::read(size_t count, size_t consume) { - return _impl->read(count, consume, true); + return impl().read(count, consume, true); } template typename InputStream::DataBlockType InputStream::tryread() { - return _impl->readPacket(false); + return impl().readPacket(false); } template typename InputStream::DataBlockType InputStream::tryread(size_t count) { - return _impl->read(count, count, false); + return impl().read(count, count, false); } template typename InputStream::DataBlockType InputStream::tryread(size_t count, size_t consume) { - return _impl->read(count, consume, false); + return impl().read(count, consume, false); } template size_t InputStream::skip(size_t count) { - return _impl->skip(count); + return impl().skip(count); } template -bool InputStream::enabled() const +void InputStream::disable() { - return _impl->enabled(); + impl().disable(); } template -void InputStream::enable() +size_t InputStream::samplesAvailable() { - _impl->enable(); + return impl().samplesAvailable(); } template -void InputStream::disable() +InputStream::operator unspecified_bool_type() const { - _impl->disable(); + //return _impl?&InputStream::_impl:0; + return 0; } template -size_t InputStream::samplesAvailable() +bool InputStream::operator==(const InputStream& other) const { - return _impl->samplesAvailable(); + return _impl.get() == other._impl.get(); } template -InputStream::operator unspecified_bool_type() const +bool InputStream::ready() { - return _impl?&InputStream::_impl:0; + return impl().ready(); } template -bool InputStream::operator!() const +bool InputStream::hasBufferedData() { - return !_impl; + return impl().hasBufferedData(); } template -bool InputStream::operator==(const InputStream& other) const +typename InputStream::Impl& InputStream::impl() { - return _impl.get() == other._impl.get(); + return static_cast(*_impl); } template -bool InputStream::ready() +const typename InputStream::Impl& InputStream::impl() const { - return _impl->ready(); + return static_cast(*_impl); } -template -bool InputStream::hasBufferedData() + +// +// XML +// +using bulkio::XMLPortTraits; +class InputStream::Impl : public InputStreamBase::Impl { +public: + typedef InPortType::Packet PacketType; + + Impl(const boost::shared_ptr& sri, InPortType* port) : + InputStreamBase::Impl(sri), + _port(port) + { + } + + XMLDataBlock read() + { + boost::scoped_ptr packet(_port->nextPacket(bulkio::Const::BLOCKING, _streamID)); + if (!packet) { + return XMLDataBlock(); + } + return XMLDataBlock(packet->SRI, packet->buffer); + } + +private: + InPortType* _port; +}; + +InputStream::InputStream() : + InputStreamBase() +{ +} + +InputStream::InputStream(const boost::shared_ptr& sri, InPortType* port) : + InputStreamBase(boost::make_shared(sri, port)) +{ +} + +bulkio::XMLDataBlock InputStream::read() +{ + return impl().read(); +} + +bool InputStream::hasBufferedData() +{ + return false; +} + +InputStream::Impl& InputStream::impl() +{ + return static_cast(*_impl); +} + +const InputStream::Impl& InputStream::impl() const +{ + return static_cast(*_impl); +} + +// +// File +// +using bulkio::FilePortTraits; +class InputStream::Impl : public InputStreamBase::Impl { +public: + typedef InPortType::Packet PacketType; + + Impl(const boost::shared_ptr& sri, InPortType* port) : + InputStreamBase::Impl(sri), + _port(port) + { + } + + FileDataBlock read() + { + boost::scoped_ptr packet(_port->nextPacket(bulkio::Const::BLOCKING, _streamID)); + if (!packet) { + return FileDataBlock(); + } + FileDataBlock block(packet->SRI, packet->buffer); + return block; + } + +private: + InPortType* _port; +}; + +InputStream::InputStream() : + InputStreamBase() +{ +} + +InputStream::InputStream(const boost::shared_ptr& sri, InPortType* port) : + InputStreamBase(boost::make_shared(sri, port)) +{ +} + +bulkio::FileDataBlock InputStream::read() +{ + return impl().read(); +} + +bool InputStream::hasBufferedData() +{ + return false; +} + +InputStream::Impl& InputStream::impl() +{ + return static_cast(*_impl); +} + +const InputStream::Impl& InputStream::impl() const { - return _impl->hasBufferedData(); + return static_cast(*_impl); } template class InputStream; diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.h b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.h index a40ee15c6..2e873c367 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.h @@ -34,17 +34,34 @@ namespace bulkio { template class InPort; + class InputStreamBase { + public: + const std::string& streamID() const; + const BULKIO::StreamSRI& sri() const; + + bool enabled() const; + void enable(); + + bool operator! () const; + + protected: + class Impl; + + InputStreamBase(); + InputStreamBase(const boost::shared_ptr& impl); + + boost::shared_ptr _impl; + }; + + template - class InputStream { + class InputStream : public InputStreamBase { public: InputStream(); typedef typename PortTraits::DataTransferTraits::NativeDataType NativeType; typedef DataBlock DataBlockType; - const std::string& streamID() const; - const BULKIO::StreamSRI& sri() const; - bool eos(); DataBlockType read(); @@ -57,13 +74,10 @@ namespace bulkio { size_t skip(size_t count); - bool enabled() const; - void enable(); void disable(); size_t samplesAvailable(); - bool operator! () const; bool operator== (const InputStream& other) const; bool ready(); @@ -76,7 +90,8 @@ namespace bulkio { bool hasBufferedData(); class Impl; - boost::shared_ptr _impl; + Impl& impl(); + const Impl& impl() const; typedef boost::shared_ptr InputStream::*unspecified_bool_type; @@ -84,6 +99,48 @@ namespace bulkio { operator unspecified_bool_type() const; }; + template <> + class InputStream : public InputStreamBase { + public: + typedef XMLDataBlock DataBlockType; + + InputStream(); + + XMLDataBlock read(); + + private: + friend class InPort; + typedef InPort InPortType; + InputStream(const boost::shared_ptr&, InPortType*); + + bool hasBufferedData(); + + class Impl; + Impl& impl(); + const Impl& impl() const; + }; + + template <> + class InputStream : public InputStreamBase { + public: + typedef FileDataBlock DataBlockType; + + InputStream(); + + FileDataBlock read(); + + private: + friend class InPort; + typedef InPort InPortType; + InputStream(const boost::shared_ptr&, InPortType*); + + bool hasBufferedData(); + + class Impl; + Impl& impl(); + const Impl& impl() const; + }; + typedef InputStream InCharStream; typedef InputStream InOctetStream; typedef InputStream InShortStream; @@ -94,6 +151,8 @@ namespace bulkio { typedef InputStream InULongLongStream; typedef InputStream InFloatStream; typedef InputStream InDoubleStream; + typedef InputStream InXMLStream; + typedef InputStream InFileStream; } // end of bulkio namespace From 3980b639fc7c55c2b55d62b89b5ef66f182fe52e Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 1 Dec 2016 12:16:20 -0500 Subject: [PATCH 0575/1644] Move common input stream/port interaction into base stream class --- bulkioInterfaces/libsrc/cpp/bulkio_in_port.h | 1 + .../libsrc/cpp/bulkio_in_stream.cpp | 304 ++++++++++-------- .../libsrc/cpp/bulkio_in_stream.h | 36 +-- 3 files changed, 193 insertions(+), 148 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h index bfa2a28c2..5c88f986d 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h @@ -379,6 +379,7 @@ namespace bulkio { // first end-of-stream void discardPacketsForStream(const std::string& streamID); + friend class InputStreamBase; friend class InputStream; size_t samplesAvailable(const std::string& streamID, bool firstPacket); diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp index be5de15f3..1e8d7175c 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp @@ -28,8 +28,11 @@ using bulkio::InputStreamBase; -class InputStreamBase::Impl { +template +class InputStreamBase::Impl { public: + typedef typename InPortType::Packet PacketType; + enum EosState { EOS_NONE, EOS_RECEIVED, @@ -37,9 +40,10 @@ class InputStreamBase::Impl { EOS_REPORTED }; - Impl(const boost::shared_ptr& sri) : + Impl(const boost::shared_ptr& sri, InPortType* port) : _streamID(sri->streamID), _sri(sri), + _port(port), _eosState(EOS_NONE), _enabled(true) { @@ -65,62 +69,160 @@ class InputStreamBase::Impl { _enabled = true; } + virtual void disable() + { + _enabled = false; + + // Unless end-of-stream has been received by the port (meaning any further + // packets with this stream ID are for a different instance), purge any + // packets for this stream from the port's queue + if (_eosState == EOS_NONE) { + _port->discardPacketsForStream(_streamID); + } + } + + virtual bool eos() + { + if (_eosState == EOS_REACHED) { + // This is the first time end-of-stream has been checked since it + // was reached; remove the stream from the port now, since the + // caller knows that the stream ended + _reportEOS(); + } + // At this point, if end-of-stream has been reached, the state is + // reported (it gets set above), so the checking for the latter is + // sufficient + return (_eosState == EOS_REPORTED); + } + + virtual bool hasBufferedData() const + { + // For the base class, there is no data to report; however, to nudge + // the check end-of-stream, return true if it has been reached but not + // reported + return (_eosState == EOS_REACHED); + } + protected: + PacketType* _fetchPacket(bool blocking) + { + // Any future packets with this stream ID belong to another InputStream + if (_eosState != EOS_NONE) { + return 0; + } + + float timeout = blocking?bulkio::Const::BLOCKING:bulkio::Const::NON_BLOCKING; + PacketType* packet = _port->nextPacket(timeout, _streamID); + if (packet && packet->EOS) { + _eosState = EOS_RECEIVED; + } + return packet; + } + + void _reportEOS() + { + _port->removeStream(_streamID); + _eosState = EOS_REPORTED; + } + const std::string _streamID; boost::shared_ptr _sri; + InPortType* _port; EosState _eosState; bool _enabled; }; -InputStreamBase::InputStreamBase() : +template +InputStreamBase::InputStreamBase() : _impl() { } -InputStreamBase::InputStreamBase(const boost::shared_ptr& impl) : +template +InputStreamBase::InputStreamBase(const boost::shared_ptr& impl) : _impl(impl) { } -const std::string& InputStreamBase::streamID() const +template +const std::string& InputStreamBase::streamID() const { return _impl->streamID(); } -const BULKIO::StreamSRI& InputStreamBase::sri() const +template +const BULKIO::StreamSRI& InputStreamBase::sri() const { return _impl->sri(); } -bool InputStreamBase::enabled() const +template +bool InputStreamBase::enabled() const { return _impl->enabled(); } -void InputStreamBase::enable() +template +void InputStreamBase::enable() { _impl->enable(); } -bool InputStreamBase::operator!() const +template +void InputStreamBase::disable() { - return !_impl; + _impl->disable(); +} + +template +bool InputStreamBase::eos() +{ + return _impl->eos(); +} + +template +bool InputStreamBase::operator!() const +{ + return !_impl; +} + +template +InputStreamBase::operator unspecified_bool_type() const +{ + return _impl?&InputStreamBase::_impl:0; +} + +template +bool InputStreamBase::hasBufferedData() +{ + return _impl->hasBufferedData(); } using bulkio::InputStream; template -class InputStream::Impl : public InputStreamBase::Impl { +class InputStream::Impl : public Base::Impl { public: + typedef typename Base::Impl ImplBase; + typedef typename InPortType::Packet PacketType; typedef typename PortTraits::NativeType NativeType; typedef typename PortTraits::SharedBufferType SharedBufferType; typedef DataBlock DataBlockType; - Impl(const boost::shared_ptr& sri, InPortType* port) : - InputStreamBase::Impl(sri), - _port(port), + using ImplBase::EOS_NONE; + using ImplBase::EOS_RECEIVED; + using ImplBase::EOS_REACHED; + using ImplBase::EOS_REPORTED; + using ImplBase::_eosState; + using ImplBase::_enabled; + using ImplBase::_port; + using ImplBase::_streamID; + using ImplBase::_sri; + + Impl(const boost::shared_ptr& sri, InPortType* port) : + ImplBase(sri, port), _queue(), _pending(0), _samplesQueued(0), @@ -133,7 +235,7 @@ class InputStream::Impl : public InputStreamBase::Impl { delete _pending; } - bool eos() + virtual bool eos() { if (_queue.empty()) { // Try a non-blocking fetch to see if there's an empty end-of-stream @@ -142,16 +244,7 @@ class InputStream::Impl : public InputStreamBase::Impl { // state again _fetchPacket(false); } - if (_eosState == EOS_REACHED) { - // This is the first time end-of-stream has been checked since it was - // reached; remove the stream from the port now, since the caller knows - // that the stream ended - _port->removeStream(_streamID); - _eosState = EOS_REPORTED; - } - // At this point, if end-of-stream has been reached, the state is reported - // (it gets set above), so the checking for the latter is sufficient - return (_eosState == EOS_REPORTED); + return ImplBase::eos(); } size_t samplesAvailable() @@ -206,8 +299,7 @@ class InputStream::Impl : public InputStreamBase::Impl { // the stream from the port; since the returned data block is invalid, // that's a cue for the caller to check end-of-stream, but they don't // have to - _port->removeStream(_streamID); - _eosState = EOS_REPORTED; + this->_reportEOS(); } return DataBlockType(); } @@ -292,37 +384,21 @@ class InputStream::Impl : public InputStreamBase::Impl { } } - void disable() + virtual void disable() { - _enabled = false; - - // Clear queued packets, which implicitly deletes them - _queue.clear(); - - // Explicitly delete pending packet - if (_pending) { - delete _pending; - _pending = 0; - } + ImplBase::disable(); - // Unless end-of-stream has been received by the port (meaning any further - // packets with this stream ID are for a different instance), purge any - // packets for this stream from the port's queue - if (_eosState == EOS_NONE) { - _port->discardPacketsForStream(_streamID); - } + // Clear queued packets, which implicitly deletes them + _queue.clear(); } bool hasBufferedData() const { - if (_eosState == EOS_REACHED) { - // Technically, there is no data to report; however, to nudge the caller - // to check end-of-stream, return true - return true; - } else { - // Return true if either there are queued or pending packets - return !_queue.empty() || _pending; - } + if (!_queue.empty() || _pending) { + // Return true if either there are queued or pending packets + return true; + } + return ImplBase::hasBufferedData(); } private: @@ -470,20 +546,11 @@ class InputStream::Impl : public InputStreamBase::Impl { return false; } - // Any future packets with this stream ID belong to another InputStream - if (_eosState != EOS_NONE) { - return false; - } - - float timeout = blocking?bulkio::Const::BLOCKING:bulkio::Const::NON_BLOCKING; - PacketType* packet = _port->nextPacket(timeout, _streamID); + PacketType* packet = ImplBase::_fetchPacket(blocking); if (!packet) { return false; } - if (packet->EOS) { - _eosState = EOS_RECEIVED; - } if (_queue.empty() || _canBridge(packet)) { _queuePacket(packet); return true; @@ -521,7 +588,6 @@ class InputStream::Impl : public InputStreamBase::Impl { return !(packet->sriChanged || packet->inputQueueFlushed); } - InPortType* _port; boost::ptr_deque _queue; PacketType* _pending; size_t _samplesQueued; @@ -531,22 +597,16 @@ class InputStream::Impl : public InputStreamBase::Impl { template InputStream::InputStream() : - InputStreamBase() + Base() { } template InputStream::InputStream(const boost::shared_ptr& sri, InPortType* port) : - InputStreamBase(boost::make_shared(sri, port)) + Base(boost::make_shared(sri, port)) { } -template -bool InputStream::eos() -{ - return impl().eos(); -} - template typename InputStream::DataBlockType InputStream::read() { @@ -589,25 +649,12 @@ size_t InputStream::skip(size_t count) return impl().skip(count); } -template -void InputStream::disable() -{ - impl().disable(); -} - template size_t InputStream::samplesAvailable() { return impl().samplesAvailable(); } -template -InputStream::operator unspecified_bool_type() const -{ - //return _impl?&InputStream::_impl:0; - return 0; -} - template bool InputStream::operator==(const InputStream& other) const { @@ -620,12 +667,6 @@ bool InputStream::ready() return impl().ready(); } -template -bool InputStream::hasBufferedData() -{ - return impl().hasBufferedData(); -} - template typename InputStream::Impl& InputStream::impl() { @@ -643,36 +684,38 @@ const typename InputStream::Impl& InputStream::impl() co // XML // using bulkio::XMLPortTraits; -class InputStream::Impl : public InputStreamBase::Impl { +class InputStream::Impl : public InputStreamBase::Impl { public: typedef InPortType::Packet PacketType; Impl(const boost::shared_ptr& sri, InPortType* port) : - InputStreamBase::Impl(sri), - _port(port) + InputStreamBase::Impl(sri, port) { } XMLDataBlock read() { - boost::scoped_ptr packet(_port->nextPacket(bulkio::Const::BLOCKING, _streamID)); + boost::scoped_ptr packet(_fetchPacket(true)); + if (_eosState == EOS_RECEIVED) { + _eosState = EOS_REACHED; + } if (!packet) { + if (_eosState == EOS_REACHED) { + _reportEOS(); + } return XMLDataBlock(); } return XMLDataBlock(packet->SRI, packet->buffer); } - -private: - InPortType* _port; }; InputStream::InputStream() : - InputStreamBase() + InputStreamBase() { } InputStream::InputStream(const boost::shared_ptr& sri, InPortType* port) : - InputStreamBase(boost::make_shared(sri, port)) + InputStreamBase(boost::make_shared(sri, port)) { } @@ -681,11 +724,6 @@ bulkio::XMLDataBlock InputStream::read() return impl().read(); } -bool InputStream::hasBufferedData() -{ - return false; -} - InputStream::Impl& InputStream::impl() { return static_cast(*_impl); @@ -700,37 +738,40 @@ const InputStream::Impl& InputStream::impl() const // File // using bulkio::FilePortTraits; -class InputStream::Impl : public InputStreamBase::Impl { +class InputStream::Impl : public InputStreamBase::Impl { public: typedef InPortType::Packet PacketType; Impl(const boost::shared_ptr& sri, InPortType* port) : - InputStreamBase::Impl(sri), - _port(port) + InputStreamBase::Impl(sri, port) { } FileDataBlock read() { - boost::scoped_ptr packet(_port->nextPacket(bulkio::Const::BLOCKING, _streamID)); + boost::scoped_ptr packet(_fetchPacket(true)); + if (_eosState == EOS_RECEIVED) { + _eosState = EOS_REACHED; + } if (!packet) { + if (_eosState == EOS_REACHED) { + _reportEOS(); + } return FileDataBlock(); } FileDataBlock block(packet->SRI, packet->buffer); + // TODO: Add timestamp return block; } - -private: - InPortType* _port; }; InputStream::InputStream() : - InputStreamBase() + InputStreamBase() { } InputStream::InputStream(const boost::shared_ptr& sri, InPortType* port) : - InputStreamBase(boost::make_shared(sri, port)) + InputStreamBase(boost::make_shared(sri, port)) { } @@ -739,28 +780,31 @@ bulkio::FileDataBlock InputStream::read() return impl().read(); } -bool InputStream::hasBufferedData() -{ - return false; -} - InputStream::Impl& InputStream::impl() { - return static_cast(*_impl); + return static_cast(*this->_impl); } const InputStream::Impl& InputStream::impl() const { - return static_cast(*_impl); + return static_cast(*this->_impl); } -template class InputStream; -template class InputStream; -template class InputStream; -template class InputStream; -template class InputStream; -template class InputStream; -template class InputStream; -template class InputStream; -template class InputStream; -template class InputStream; +#define INSTANTIATE_TEMPLATE(x) \ + template class InputStreamBase; + +#define INSTANTIATE_NUMERIC_TEMPLATE(x) \ + INSTANTIATE_TEMPLATE(x); template class InputStream; + +INSTANTIATE_NUMERIC_TEMPLATE(bulkio::CharPortTraits); +INSTANTIATE_NUMERIC_TEMPLATE(bulkio::OctetPortTraits); +INSTANTIATE_NUMERIC_TEMPLATE(bulkio::ShortPortTraits); +INSTANTIATE_NUMERIC_TEMPLATE(bulkio::UShortPortTraits); +INSTANTIATE_NUMERIC_TEMPLATE(bulkio::LongPortTraits); +INSTANTIATE_NUMERIC_TEMPLATE(bulkio::ULongPortTraits); +INSTANTIATE_NUMERIC_TEMPLATE(bulkio::LongLongPortTraits); +INSTANTIATE_NUMERIC_TEMPLATE(bulkio::ULongLongPortTraits); +INSTANTIATE_NUMERIC_TEMPLATE(bulkio::FloatPortTraits); +INSTANTIATE_NUMERIC_TEMPLATE(bulkio::DoublePortTraits); +INSTANTIATE_TEMPLATE(bulkio::XMLPortTraits); +INSTANTIATE_TEMPLATE(bulkio::FilePortTraits); diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.h b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.h index 2e873c367..7a1d76f61 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.h @@ -34,6 +34,7 @@ namespace bulkio { template class InPort; + template class InputStreamBase { public: const std::string& streamID() const; @@ -41,29 +42,38 @@ namespace bulkio { bool enabled() const; void enable(); + void disable(); + + bool eos(); bool operator! () const; protected: + typedef InPort InPortType; + class Impl; + typedef boost::shared_ptr InputStreamBase::*unspecified_bool_type; InputStreamBase(); InputStreamBase(const boost::shared_ptr& impl); + bool hasBufferedData(); + boost::shared_ptr _impl; + + public: + operator unspecified_bool_type() const; }; template - class InputStream : public InputStreamBase { + class InputStream : public InputStreamBase { public: InputStream(); typedef typename PortTraits::DataTransferTraits::NativeDataType NativeType; typedef DataBlock DataBlockType; - bool eos(); - DataBlockType read(); DataBlockType read(size_t count); DataBlockType read(size_t count, size_t consume); @@ -74,8 +84,6 @@ namespace bulkio { size_t skip(size_t count); - void disable(); - size_t samplesAvailable(); bool operator== (const InputStream& other) const; @@ -83,24 +91,20 @@ namespace bulkio { bool ready(); private: + typedef InputStreamBase Base; + using Base::_impl; + friend class InPort; typedef InPort InPortType; InputStream(const boost::shared_ptr&, InPortType*); - bool hasBufferedData(); - class Impl; Impl& impl(); const Impl& impl() const; - - typedef boost::shared_ptr InputStream::*unspecified_bool_type; - - public: - operator unspecified_bool_type() const; }; template <> - class InputStream : public InputStreamBase { + class InputStream : public InputStreamBase { public: typedef XMLDataBlock DataBlockType; @@ -113,15 +117,13 @@ namespace bulkio { typedef InPort InPortType; InputStream(const boost::shared_ptr&, InPortType*); - bool hasBufferedData(); - class Impl; Impl& impl(); const Impl& impl() const; }; template <> - class InputStream : public InputStreamBase { + class InputStream : public InputStreamBase { public: typedef FileDataBlock DataBlockType; @@ -134,8 +136,6 @@ namespace bulkio { typedef InPort InPortType; InputStream(const boost::shared_ptr&, InPortType*); - bool hasBufferedData(); - class Impl; Impl& impl(); const Impl& impl() const; From ec44e3ac7d46aa20a239f325bf02b6860c7da0f0 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 1 Dec 2016 12:25:25 -0500 Subject: [PATCH 0576/1644] Move all input port interaction to base input stream class --- bulkioInterfaces/libsrc/cpp/bulkio_in_port.h | 1 - .../libsrc/cpp/bulkio_in_stream.cpp | 29 ++++++++++++------- .../libsrc/cpp/bulkio_in_stream.h | 4 +++ 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h index 5c88f986d..4b1b053a6 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h @@ -380,7 +380,6 @@ namespace bulkio { void discardPacketsForStream(const std::string& streamID); friend class InputStreamBase; - friend class InputStream; size_t samplesAvailable(const std::string& streamID, bool firstPacket); void createStream(const std::string& streamID, const boost::shared_ptr& sri); diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp index 1e8d7175c..07ffdb8c5 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp @@ -125,6 +125,11 @@ class InputStreamBase::Impl { _eosState = EOS_REPORTED; } + size_t _samplesAvailable(bool first) + { + return _port->samplesAvailable(_streamID, first); + } + const std::string _streamID; boost::shared_ptr _sri; InPortType* _port; @@ -206,7 +211,7 @@ class InputStream::Impl : public Base::Impl { public: typedef typename Base::Impl ImplBase; - typedef typename InPortType::Packet PacketType; + typedef typename ImplBase::PacketType PacketType; typedef typename PortTraits::NativeType NativeType; typedef typename PortTraits::SharedBufferType SharedBufferType; typedef DataBlock DataBlockType; @@ -266,7 +271,7 @@ class InputStream::Impl : public Base::Impl { // search can go past the first packet if the SRI change or queue flush // flag is set) bool first = _queue.empty(); - queued += _port->samplesAvailable(_streamID, first); + queued += ImplBase::_samplesAvailable(first); } return queued; @@ -684,9 +689,10 @@ const typename InputStream::Impl& InputStream::impl() co // XML // using bulkio::XMLPortTraits; -class InputStream::Impl : public InputStreamBase::Impl { +class InputStream::Impl : public Base::Impl { public: - typedef InPortType::Packet PacketType; + typedef Base::Impl BaseImpl; + typedef BaseImpl::PacketType PacketType; Impl(const boost::shared_ptr& sri, InPortType* port) : InputStreamBase::Impl(sri, port) @@ -710,12 +716,12 @@ class InputStream::Impl : public InputStreamBase:: }; InputStream::InputStream() : - InputStreamBase() + Base() { } InputStream::InputStream(const boost::shared_ptr& sri, InPortType* port) : - InputStreamBase(boost::make_shared(sri, port)) + Base(boost::make_shared(sri, port)) { } @@ -738,12 +744,13 @@ const InputStream::Impl& InputStream::impl() const // File // using bulkio::FilePortTraits; -class InputStream::Impl : public InputStreamBase::Impl { +class InputStream::Impl : public Base::Impl { public: - typedef InPortType::Packet PacketType; + typedef Base::Impl BaseImpl; + typedef BaseImpl::PacketType PacketType; Impl(const boost::shared_ptr& sri, InPortType* port) : - InputStreamBase::Impl(sri, port) + BaseImpl(sri, port) { } @@ -766,12 +773,12 @@ class InputStream::Impl : public InputStreamBase }; InputStream::InputStream() : - InputStreamBase() + Base() { } InputStream::InputStream(const boost::shared_ptr& sri, InPortType* port) : - InputStreamBase(boost::make_shared(sri, port)) + Base(boost::make_shared(sri, port)) { } diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.h b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.h index 7a1d76f61..2409d92b0 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.h @@ -113,6 +113,8 @@ namespace bulkio { XMLDataBlock read(); private: + typedef InputStreamBase Base; + friend class InPort; typedef InPort InPortType; InputStream(const boost::shared_ptr&, InPortType*); @@ -132,6 +134,8 @@ namespace bulkio { FileDataBlock read(); private: + typedef InputStreamBase Base; + friend class InPort; typedef InPort InPortType; InputStream(const boost::shared_ptr&, InPortType*); From fc8cfc08548929c34039a51a9baacccf7415d03e Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 1 Dec 2016 13:46:36 -0500 Subject: [PATCH 0577/1644] Move basic read functionality into InputStreamBase, so XML and File streams are just thin subclasses; implement SRI change and input queue flush flags in XML and File blocks --- .../libsrc/cpp/bulkio_datablock.cpp | 83 ++++++++++- .../libsrc/cpp/bulkio_datablock.h | 15 ++ .../libsrc/cpp/bulkio_in_stream.cpp | 141 ++++++------------ .../libsrc/cpp/bulkio_in_stream.h | 36 +++-- 4 files changed, 161 insertions(+), 114 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_datablock.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_datablock.cpp index 0f4b6bd8e..c0aac6335 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_datablock.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_datablock.cpp @@ -34,7 +34,18 @@ template struct DataBlock::Impl { Impl(const boost::shared_ptr& sri) : - sri(sri) + data(), + sri(sri), + sriChangeFlags(bulkio::sri::NONE), + inputQueueFlushed(false) + { + } + + Impl(const boost::shared_ptr& sri, const ScalarBuffer& buffer) : + data(buffer), + sri(sri), + sriChangeFlags(bulkio::sri::NONE), + inputQueueFlushed(false) { } @@ -53,16 +64,20 @@ DataBlock::DataBlock() : template DataBlock::DataBlock(const boost::shared_ptr& sri, size_t size) : - _impl(boost::make_shared(sri)) + _impl(boost::make_shared(sri, redhawk::buffer(size))) +{ +} + +template +DataBlock::DataBlock(const boost::shared_ptr& sri, const ScalarBuffer& buffer) : + _impl(boost::make_shared(sri, buffer)) { - _impl->data = redhawk::buffer(size); } template DataBlock::DataBlock(const BULKIO::StreamSRI& sri, size_t size) : - _impl(boost::make_shared(boost::make_shared(sri))) + _impl(boost::make_shared(boost::make_shared(sri), redhawk::buffer(size))) { - _impl->data = redhawk::buffer(size); } template @@ -295,7 +310,9 @@ using bulkio::XMLDataBlock; struct XMLDataBlock::Impl { Impl(const boost::shared_ptr& sri) : - sri(sri) + sri(sri), + sriChangeFlags(bulkio::sri::NONE), + inputQueueFlushed(false) { } @@ -327,6 +344,31 @@ const std::string& XMLDataBlock::data() const return _impl->data; } +bool XMLDataBlock::sriChanged() const +{ + return sriChangeFlags() != bulkio::sri::NONE; +} + +int XMLDataBlock::sriChangeFlags() const +{ + return _impl->sriChangeFlags; +} + +void XMLDataBlock::sriChangeFlags(int flags) +{ + _impl->sriChangeFlags = flags; +} + +bool XMLDataBlock::inputQueueFlushed() const +{ + return _impl->inputQueueFlushed; +} + +void XMLDataBlock::inputQueueFlushed(bool flushed) +{ + _impl->inputQueueFlushed = flushed; +} + bool XMLDataBlock::operator! () const { return !_impl; @@ -345,7 +387,9 @@ using bulkio::FileDataBlock; struct FileDataBlock::Impl { Impl(const boost::shared_ptr& sri) : - sri(sri) + sri(sri), + sriChangeFlags(bulkio::sri::NONE), + inputQueueFlushed(false) { } @@ -377,6 +421,31 @@ const std::string& FileDataBlock::data() const return _impl->data; } +bool FileDataBlock::sriChanged() const +{ + return sriChangeFlags() != bulkio::sri::NONE; +} + +int FileDataBlock::sriChangeFlags() const +{ + return _impl->sriChangeFlags; +} + +void FileDataBlock::sriChangeFlags(int flags) +{ + _impl->sriChangeFlags = flags; +} + +bool FileDataBlock::inputQueueFlushed() const +{ + return _impl->inputQueueFlushed; +} + +void FileDataBlock::inputQueueFlushed(bool flushed) +{ + _impl->inputQueueFlushed = flushed; +} + bool FileDataBlock::operator! () const { return !_impl; diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_datablock.h b/bulkioInterfaces/libsrc/cpp/bulkio_datablock.h index 23b013af5..83ac834f8 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_datablock.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_datablock.h @@ -57,6 +57,7 @@ namespace bulkio { DataBlock(); explicit DataBlock(const boost::shared_ptr& sri, size_t size=0); + DataBlock(const boost::shared_ptr& sri, const ScalarBuffer& buffer); DataBlock(const BULKIO::StreamSRI& sri, size_t size=0); DataBlock copy() const; @@ -116,6 +117,13 @@ namespace bulkio { const BULKIO::StreamSRI& sri() const; const std::string& data() const; + bool sriChanged() const; + int sriChangeFlags() const; + void sriChangeFlags(int flags); + + bool inputQueueFlushed() const; + void inputQueueFlushed(bool flush); + bool operator! () const; private: @@ -136,6 +144,13 @@ namespace bulkio { const BULKIO::StreamSRI& sri() const; const std::string& data() const; + bool sriChanged() const; + int sriChangeFlags() const; + void sriChangeFlags(int flags); + + bool inputQueueFlushed() const; + void inputQueueFlushed(bool flush); + bool operator! () const; private: diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp index 07ffdb8c5..491ca85ca 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp @@ -59,6 +59,24 @@ class InputStreamBase::Impl { return *_sri; } + DataBlockType readPacket(bool blocking) + { + boost::scoped_ptr packet(_fetchPacket(blocking)); + if (_eosState == EOS_RECEIVED) { + _eosState = EOS_REACHED; + } + if (!packet) { + if (_eosState == EOS_REACHED) { + _reportEOS(); + } + return DataBlockType(); + } + DataBlockType block(packet->SRI, packet->buffer); + _setBlockFlags(block, *packet); + _sri = packet->SRI; + return block; + } + bool enabled() const { return _enabled; @@ -130,6 +148,19 @@ class InputStreamBase::Impl { return _port->samplesAvailable(_streamID, first); } + void _setBlockFlags(DataBlockType& block, PacketType& packet) + { + // Allocate empty data block and propagate the SRI change and input + // queue flush flags + if (packet.sriChanged) { + int flags = bulkio::sri::compareFields(*_sri, *(packet.SRI)); + block.sriChangeFlags(flags); + } + if (packet.inputQueueFlushed) { + block.inputQueueFlushed(true); + } + } + const std::string _streamID; boost::shared_ptr _sri; InPortType* _port; @@ -161,6 +192,18 @@ const BULKIO::StreamSRI& InputStreamBase::sri() const return _impl->sri(); } +template +typename InputStreamBase::DataBlockType InputStreamBase::read() +{ + return _impl->readPacket(true); +} + +template +typename InputStreamBase::DataBlockType InputStreamBase::tryread() +{ + return _impl->readPacket(false); +} + template bool InputStreamBase::enabled() const { @@ -447,21 +490,15 @@ class InputStream::Impl : public Base::Impl { { // Acknowledge pending SRI change PacketType& front = _queue.front(); - int sriChangeFlags = bulkio::sri::NONE; - if (front.sriChanged) { - sriChangeFlags = bulkio::sri::compareFields(*_sri, *(front.SRI)); - front.sriChanged = false; - _sri = front.SRI; - } // Allocate empty data block and propagate the SRI change and input queue // flush flags DataBlockType data(_sri); - data.sriChangeFlags(sriChangeFlags); - if (front.inputQueueFlushed) { - data.inputQueueFlushed(true); - front.inputQueueFlushed = false; - } + this->_setBlockFlags(data, front); + + // Clear flags from packet, since they've been reported + front.sriChanged = false; + front.inputQueueFlushed = false; size_t last_offset = _sampleOffset + count; if (last_offset <= front.buffer.size()) { @@ -689,31 +726,6 @@ const typename InputStream::Impl& InputStream::impl() co // XML // using bulkio::XMLPortTraits; -class InputStream::Impl : public Base::Impl { -public: - typedef Base::Impl BaseImpl; - typedef BaseImpl::PacketType PacketType; - - Impl(const boost::shared_ptr& sri, InPortType* port) : - InputStreamBase::Impl(sri, port) - { - } - - XMLDataBlock read() - { - boost::scoped_ptr packet(_fetchPacket(true)); - if (_eosState == EOS_RECEIVED) { - _eosState = EOS_REACHED; - } - if (!packet) { - if (_eosState == EOS_REACHED) { - _reportEOS(); - } - return XMLDataBlock(); - } - return XMLDataBlock(packet->SRI, packet->buffer); - } -}; InputStream::InputStream() : Base() @@ -725,52 +737,10 @@ InputStream::InputStream(const boost::shared_ptr::read() -{ - return impl().read(); -} - -InputStream::Impl& InputStream::impl() -{ - return static_cast(*_impl); -} - -const InputStream::Impl& InputStream::impl() const -{ - return static_cast(*_impl); -} - // // File // using bulkio::FilePortTraits; -class InputStream::Impl : public Base::Impl { -public: - typedef Base::Impl BaseImpl; - typedef BaseImpl::PacketType PacketType; - - Impl(const boost::shared_ptr& sri, InPortType* port) : - BaseImpl(sri, port) - { - } - - FileDataBlock read() - { - boost::scoped_ptr packet(_fetchPacket(true)); - if (_eosState == EOS_RECEIVED) { - _eosState = EOS_REACHED; - } - if (!packet) { - if (_eosState == EOS_REACHED) { - _reportEOS(); - } - return FileDataBlock(); - } - FileDataBlock block(packet->SRI, packet->buffer); - // TODO: Add timestamp - return block; - } -}; InputStream::InputStream() : Base() @@ -782,21 +752,6 @@ InputStream::InputStream(const boost::shared_ptr::read() -{ - return impl().read(); -} - -InputStream::Impl& InputStream::impl() -{ - return static_cast(*this->_impl); -} - -const InputStream::Impl& InputStream::impl() const -{ - return static_cast(*this->_impl); -} - #define INSTANTIATE_TEMPLATE(x) \ template class InputStreamBase; diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.h b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.h index 2409d92b0..beb318e09 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.h @@ -34,12 +34,33 @@ namespace bulkio { template class InPort; + template + struct BlockTraits { + typedef DataBlock DataBlockType; + }; + + template <> + struct BlockTraits { + typedef XMLDataBlock DataBlockType; + }; + + template <> + struct BlockTraits { + typedef FileDataBlock DataBlockType; + }; + template class InputStreamBase { public: + typedef typename BlockTraits::DataBlockType DataBlockType; + const std::string& streamID() const; const BULKIO::StreamSRI& sri() const; + DataBlockType read(); + + DataBlockType tryread(); + bool enabled() const; void enable(); void disable(); @@ -71,8 +92,7 @@ namespace bulkio { public: InputStream(); - typedef typename PortTraits::DataTransferTraits::NativeDataType NativeType; - typedef DataBlock DataBlockType; + typedef typename InputStreamBase::DataBlockType DataBlockType; DataBlockType read(); DataBlockType read(size_t count); @@ -110,18 +130,12 @@ namespace bulkio { InputStream(); - XMLDataBlock read(); - private: typedef InputStreamBase Base; friend class InPort; typedef InPort InPortType; InputStream(const boost::shared_ptr&, InPortType*); - - class Impl; - Impl& impl(); - const Impl& impl() const; }; template <> @@ -131,18 +145,12 @@ namespace bulkio { InputStream(); - FileDataBlock read(); - private: typedef InputStreamBase Base; friend class InPort; typedef InPort InPortType; InputStream(const boost::shared_ptr&, InPortType*); - - class Impl; - Impl& impl(); - const Impl& impl() const; }; typedef InputStream InCharStream; From 0fd50f57d6c4565e50eb5401c744f8082ede4e7b Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 1 Dec 2016 14:16:44 -0500 Subject: [PATCH 0578/1644] Use another set of traits class to bind the input stream type to the port, and remove need for XML and File stream subclasses --- bulkioInterfaces/libsrc/cpp/bulkio_in_port.h | 2 +- .../libsrc/cpp/bulkio_in_stream.cpp | 38 +++---------- .../libsrc/cpp/bulkio_in_stream.h | 53 ++++++++----------- 3 files changed, 29 insertions(+), 64 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h index 4b1b053a6..154abf73f 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h @@ -69,7 +69,7 @@ namespace bulkio { typedef typename Traits::SharedBufferType SharedBufferType; // Input stream interface used by this port - typedef InputStream StreamType; + typedef typename StreamTraits::InStreamType StreamType; // List type for input streams provided by this port typedef std::list StreamList; diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp index 491ca85ca..4f3b3286b 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp @@ -174,6 +174,13 @@ InputStreamBase::InputStreamBase() : { } +template +InputStreamBase::InputStreamBase(const boost::shared_ptr& sri, + InPortType* port) : + _impl(boost::make_shared(sri, port)) +{ +} + template InputStreamBase::InputStreamBase(const boost::shared_ptr& impl) : _impl(impl) @@ -721,37 +728,6 @@ const typename InputStream::Impl& InputStream::impl() co return static_cast(*_impl); } - -// -// XML -// -using bulkio::XMLPortTraits; - -InputStream::InputStream() : - Base() -{ -} - -InputStream::InputStream(const boost::shared_ptr& sri, InPortType* port) : - Base(boost::make_shared(sri, port)) -{ -} - -// -// File -// -using bulkio::FilePortTraits; - -InputStream::InputStream() : - Base() -{ -} - -InputStream::InputStream(const boost::shared_ptr& sri, InPortType* port) : - Base(boost::make_shared(sri, port)) -{ -} - #define INSTANTIATE_TEMPLATE(x) \ template class InputStreamBase; diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.h b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.h index beb318e09..81cda2ede 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.h @@ -78,6 +78,10 @@ namespace bulkio { InputStreamBase(); InputStreamBase(const boost::shared_ptr& impl); + // Allow matching InPort class to create instances of this stream type + friend class InPort; + InputStreamBase(const boost::shared_ptr& sri, InPortType* port); + bool hasBufferedData(); boost::shared_ptr _impl; @@ -123,36 +127,6 @@ namespace bulkio { const Impl& impl() const; }; - template <> - class InputStream : public InputStreamBase { - public: - typedef XMLDataBlock DataBlockType; - - InputStream(); - - private: - typedef InputStreamBase Base; - - friend class InPort; - typedef InPort InPortType; - InputStream(const boost::shared_ptr&, InPortType*); - }; - - template <> - class InputStream : public InputStreamBase { - public: - typedef FileDataBlock DataBlockType; - - InputStream(); - - private: - typedef InputStreamBase Base; - - friend class InPort; - typedef InPort InPortType; - InputStream(const boost::shared_ptr&, InPortType*); - }; - typedef InputStream InCharStream; typedef InputStream InOctetStream; typedef InputStream InShortStream; @@ -163,8 +137,23 @@ namespace bulkio { typedef InputStream InULongLongStream; typedef InputStream InFloatStream; typedef InputStream InDoubleStream; - typedef InputStream InXMLStream; - typedef InputStream InFileStream; + typedef InputStreamBase InXMLStream; + typedef InputStreamBase InFileStream; + + template + struct StreamTraits { + typedef InputStream InStreamType; + }; + + template <> + struct StreamTraits { + typedef InXMLStream InStreamType; + }; + + template <> + struct StreamTraits { + typedef InFileStream InStreamType; + }; } // end of bulkio namespace From 22a066fa193ba92214adb5530e7a296ae6b906be Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 1 Dec 2016 14:24:05 -0500 Subject: [PATCH 0579/1644] Clean up extra typedefs and using statements --- .../libsrc/cpp/bulkio_in_stream.cpp | 23 +++++-------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp index 4f3b3286b..f790e2632 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp @@ -264,17 +264,6 @@ class InputStream::Impl : public Base::Impl { typedef typename ImplBase::PacketType PacketType; typedef typename PortTraits::NativeType NativeType; typedef typename PortTraits::SharedBufferType SharedBufferType; - typedef DataBlock DataBlockType; - - using ImplBase::EOS_NONE; - using ImplBase::EOS_RECEIVED; - using ImplBase::EOS_REACHED; - using ImplBase::EOS_REPORTED; - using ImplBase::_eosState; - using ImplBase::_enabled; - using ImplBase::_port; - using ImplBase::_streamID; - using ImplBase::_sri; Impl(const boost::shared_ptr& sri, InPortType* port) : ImplBase(sri, port), @@ -349,7 +338,7 @@ class InputStream::Impl : public Base::Impl { if (!sri) { // No SRI retreived implies no data will be retrieved, either due to end- // of-stream or because it would block - if (_eosState == EOS_REACHED) { + if (this->_eosState == ImplBase::EOS_REACHED) { // If this is the first time end-of-stream could be reported, remove // the stream from the port; since the returned data block is invalid, // that's a cue for the caller to check end-of-stream, but they don't @@ -390,7 +379,7 @@ class InputStream::Impl : public Base::Impl { // Non-blocking: return a null block if there's not currently a break in // the data, under the assumption that a future read might return the // full amount - if (!blocking && !_pending && (_eosState == EOS_NONE)) { + if (!blocking && !_pending && (this->_eosState == ImplBase::EOS_NONE)) { return DataBlockType(); } // Otherwise, consume all remaining data @@ -430,7 +419,7 @@ class InputStream::Impl : public Base::Impl { bool ready() { - if (!_enabled) { + if (!this->_enabled) { return false; } else if (_samplesQueued) { return true; @@ -482,7 +471,7 @@ class InputStream::Impl : public Base::Impl { // Acknowledge any end-of-stream flag and delete the packet (the queue will // automatically delete it when it's removed) if (_queue.front().EOS) { - _eosState = EOS_REACHED; + this->_eosState = ImplBase::EOS_REACHED; } _queue.pop_front(); @@ -500,7 +489,7 @@ class InputStream::Impl : public Base::Impl { // Allocate empty data block and propagate the SRI change and input queue // flush flags - DataBlockType data(_sri); + DataBlockType data(this->_sri); this->_setBlockFlags(data, front); // Clear flags from packet, since they've been reported @@ -616,7 +605,7 @@ class InputStream::Impl : public Base::Impl { // SRI changes, and queue flushes are irrelevant at this point) if (_queue.empty()) { // No queued packets, read pointer has reached end-of-stream - _eosState = EOS_REACHED; + this->_eosState = ImplBase::EOS_REACHED; } else { // Assign the end-of-stream flag to the last packet in the queue so // that it is handled on read From 27276c86f7b17eb65a25f304ec7bec1e843afadc Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 1 Dec 2016 14:41:36 -0500 Subject: [PATCH 0580/1644] Push data directly to InPort class in local transport, removing need for local traits class --- .../libsrc/cpp/bulkio_connection.hpp | 12 ++++----- bulkioInterfaces/libsrc/cpp/bulkio_in_port.h | 6 +++++ .../libsrc/cpp/bulkio_out_port.cpp | 9 ++++--- bulkioInterfaces/libsrc/cpp/bulkio_out_port.h | 25 ++----------------- 4 files changed, 19 insertions(+), 33 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp b/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp index fa7b147f0..f5cb0c89b 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp @@ -252,7 +252,7 @@ namespace bulkio { public: typedef typename PortTraits::PortType PortType; typedef typename PortType::_ptr_type PtrType; - typedef typename LocalTraits::InPortType LocalPortType; + typedef InPort LocalPortType; typedef typename PortTraits::SharedBufferType SharedBufferType; LocalTransport(const std::string& connectionId, const std::string& name, @@ -284,9 +284,9 @@ namespace bulkio { // so we need to make a copy. This could be optimized for the fanout // case by making the copy at a higher level, but only if there's at // least one local connection. - _localPort->pushPacket(data.copy(), T, EOS, streamID); + _localPort->queuePacket(data.copy(), T, EOS, streamID); } else { - _localPort->pushPacket(data, T, EOS, streamID); + _localPort->queuePacket(data, T, EOS, streamID); } } @@ -299,16 +299,16 @@ namespace bulkio { bool EOS, const std::string& streamID) { - _localPort->pushPacket(data, T, EOS, streamID); + _localPort->queuePacket(data, T, EOS, streamID); } template <> void LocalTransport::_pushPacket(const std::string& data, - const BULKIO::PrecisionUTCTime& /*unused*/, + const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID) { - _localPort->pushPacket(data, EOS, streamID); + _localPort->queuePacket(data, T, EOS, streamID); } } diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h index 154abf73f..5f338869f 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h @@ -36,6 +36,9 @@ namespace bulkio { + template + class LocalTransport; + // // InPort // Base template for data transfers between BULKIO ports. This class is defined by 2 trait classes @@ -361,6 +364,9 @@ namespace bulkio { // void queuePacket(const SharedBufferType& data, const BULKIO::PrecisionUTCTime& T, CORBA::Boolean EOS, const std::string& streamID); + // Allow local transport classes to directly queue packets + friend class LocalTransport; + // // Fetches the next packet for the given stream ID, blocking for up to // timeout seconds for one to be available diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp index e31b52904..a534b1975 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp @@ -602,10 +602,11 @@ namespace bulkio { void OutXMLPort::pushPacket(const std::string& data, bool EOS, const std::string& streamID) { - // The time argument is never dereferenced for dataXML, so it is safe to - // pass a null - BULKIO::PrecisionUTCTime* time = 0; - _sendPacket(data, *time, EOS, streamID); + // Because it's templatized, the port's interface requires a timestamp; + // however, since it's not used for XML ports, creating a method-static + // instance is sufficient + static BULKIO::PrecisionUTCTime time; + _sendPacket(data, time, EOS, streamID); } void OutXMLPort::pushPacket(const char* data, bool EOS, const std::string& streamID) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h index 2fc855131..98470a536 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h @@ -39,28 +39,7 @@ namespace bulkio { - template class InNumericPort; - class InFilePort; - class InXMLPort; - - template - struct LocalTraits - { - typedef InNumericPort InPortType; - }; - - template <> - struct LocalTraits - { - typedef InFilePort InPortType; - }; - - template <> - struct LocalTraits - { - typedef InXMLPort InPortType; - }; - + template class InPort; template class PortTransport; // @@ -278,7 +257,7 @@ namespace bulkio { // // Lookup table for connections to input ports in the same process space // - typedef typename LocalTraits::InPortType LocalPortType; + typedef InPort LocalPortType; typedef PortTransport PortTransportType; virtual redhawk::BasicTransport* _createTransport(CORBA::Object_ptr object, const std::string& connectionId); From 0b6bb563856a68b327d9d0a10fb5e29d63e2b340 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 1 Dec 2016 14:49:29 -0500 Subject: [PATCH 0581/1644] Remove unneeded virtual qualifier on methods that are not used as such --- bulkioInterfaces/libsrc/cpp/bulkio_in_port.h | 18 +++++++++--------- bulkioInterfaces/libsrc/cpp/bulkio_out_port.h | 10 +++++----- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h index 5f338869f..2fb90d165 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h @@ -92,7 +92,7 @@ namespace bulkio { * @return dataTranfer * pointer to a data transfer object from the port's work queue * @return NULL - no data available */ - virtual DataTransferType *getPacket(float timeout); + DataTransferType *getPacket(float timeout); /* * getPacket - interface used by components to grab data from the port's internal queue object for a specified streamID @@ -104,7 +104,7 @@ namespace bulkio { * @return dataTranfer * pointer to a data transfer object from the port's work queue * @return NULL - no data available */ - virtual DataTransferType *getPacket(float timeout, const std::string &streamID); + DataTransferType *getPacket(float timeout, const std::string& streamID); // // BULKIO IDL interface for pushing Floating Point vectors between components @@ -125,7 +125,7 @@ namespace bulkio { /* * turn on/off the port monitoring capability */ - virtual void enableStats(bool enable); + void enableStats(bool enable); // // state - returns the current state of the port as follows: @@ -167,31 +167,31 @@ namespace bulkio { * * @return int - number of items in the queue */ - virtual int getCurrentQueueDepth(); + int getCurrentQueueDepth(); /* * getMaxQueueDepth - returns the maximum size of the queue , if this water mark is reached the queue will be purged, and the * component of the port will be notified in getPacket method * @return int - maximum size the queue can reach before purging occurs */ - virtual int getMaxQueueDepth(); + int getMaxQueueDepth(); /* * setMaxQueueDepth - allow users of this port to modify the maximum number of allowable vectors on the queue. */ - virtual void setMaxQueueDepth(int newDepth); + void setMaxQueueDepth(int newDepth); // // Allow the component to control the flow of data from the port to the component. Block will restrict the flow of data back into the // component. Call in component's stop method // - virtual void block(); + void block(); // // Allow the component to control the flow of data from the port to the component. Unblock will release the flow of data back into the // component. Called in component's start method. // - virtual void unblock(); + void unblock(); // // Support function for automatic component-managed start. Calls unblock. @@ -208,7 +208,7 @@ namespace bulkio { * * @return bool returns state of breakBlock variable used to release any upstream blocking pushPacket calls */ - virtual bool blocked(); + bool blocked(); template void addStreamListener(Target target, Func func) { diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h index 98470a536..6936f95f1 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h @@ -215,22 +215,22 @@ namespace bulkio { // // turn on/off the port monitoring capability // - virtual void enableStats(bool enable); + void enableStats(bool enable); // // Return map of streamID/SRI objects // - virtual bulkio::SriMap getCurrentSRI(); + bulkio::SriMap getCurrentSRI(); // // Return list of SRI objects // - virtual bulkio::SriList getActiveSRIs(); + bulkio::SriList getActiveSRIs(); // // Return a ConnectionsList for the current ports and connections ids establish via connectPort method // - virtual ConnectionsList getConnections(); + ConnectionsList getConnections(); // // Deprecation Warning @@ -242,7 +242,7 @@ namespace bulkio { // // Allow access to the port's connection list // - virtual ConnectionsList __attribute__ ((deprecated)) _getConnections() { + ConnectionsList __attribute__ ((deprecated)) _getConnections() { return getConnections(); } From f89b1bfc15a00416e19e327ce456b9c4baeefee6 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 1 Dec 2016 15:46:26 -0500 Subject: [PATCH 0582/1644] Compile BulkIO transport template classes in their own file --- bulkioInterfaces/libsrc/Makefile.am | 5 +- .../libsrc/cpp/bulkio_out_port.cpp | 40 +-- bulkioInterfaces/libsrc/cpp/bulkio_out_port.h | 12 - ...io_connection.hpp => bulkio_transport.cpp} | 240 ++++++++++++------ .../libsrc/cpp/bulkio_transport.h | 89 +++++++ 5 files changed, 260 insertions(+), 126 deletions(-) rename bulkioInterfaces/libsrc/cpp/{bulkio_connection.hpp => bulkio_transport.cpp} (57%) create mode 100644 bulkioInterfaces/libsrc/cpp/bulkio_transport.h diff --git a/bulkioInterfaces/libsrc/Makefile.am b/bulkioInterfaces/libsrc/Makefile.am index af6f1cace..772cb84af 100644 --- a/bulkioInterfaces/libsrc/Makefile.am +++ b/bulkioInterfaces/libsrc/Makefile.am @@ -40,13 +40,14 @@ libbulkio_@BULKIO_API_VERSION@_la_SOURCES = \ cpp/bulkio_in_stream.cpp \ cpp/bulkio_out_port.cpp \ cpp/bulkio_out_stream.cpp \ - cpp/bulkio_attachable_port.cpp \ + cpp/bulkio_attachable_port.cpp \ cpp/bulkio_sri_helpers.cpp \ cpp/bulkio_time_helpers.cpp \ cpp/bulkio_time_operators.cpp \ cpp/bulkio_datablock.cpp \ cpp/bulkio_p.h \ - cpp/bulkio_connection.hpp + cpp/bulkio_transport.h \ + cpp/bulkio_transport.cpp ## Define the list of public header files and their install location. library_includedir = $(includedir)/bulkio diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp index a534b1975..bb69e282a 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp @@ -23,10 +23,7 @@ *******************************************************************************************/ #include "bulkio_out_port.h" #include "bulkio_p.h" -#include "bulkio_time_operators.h" -#include "bulkio_in_port.h" - -#include "bulkio_connection.hpp" +#include "bulkio_transport.h" // Suppress warnings for access to deprecated currentSRI member (on gcc 4.4, at // least, the implicit destructor call from OutPort's destructor emits a @@ -273,34 +270,16 @@ namespace bulkio { throw CF::Port::InvalidPort(1, "Unable to narrow"); } - LocalPortType* local_port = ossie::corba::getLocalServant(port); - if (local_port) { + PortTransportType* transport = PortTransportType::Factory(connectionId, name, port); + if (transport->isLocal()) { + PortBase* local_port = ossie::corba::getLocalServant(port); LOG_DEBUG(logger, "Using local connection to port " << local_port->getName() << " for connection " << connectionId); - return _createLocalConnection(port, local_port, connectionId); - } else { - return _createRemoteConnection(port, connectionId); } + return transport; } - template < typename PortTraits > - typename OutPort< PortTraits >::PortTransportType* - OutPort< PortTraits >::_createRemoteConnection(PortPtrType port, const std::string& connectionId) - { - return new RemoteTransport(connectionId, name, port); - } - - - template < typename PortTraits > - typename OutPort< PortTraits >::PortTransportType* - OutPort< PortTraits >::_createLocalConnection(PortPtrType port, LocalPortType* localPort, - const std::string& connectionId) - { - return new LocalTransport(connectionId, name, localPort, port); - } - - template typename OutPort::StreamType OutPort::getStream(const std::string& streamID) { @@ -451,15 +430,6 @@ namespace bulkio { { } - - template - typename OutNumericPort::PortTransportType* - OutNumericPort::_createRemoteConnection(PortPtrType port, const std::string& connectionId) - { - return new ChunkingTransport(connectionId, this->name, port); - } - - template < typename PortTraits > void OutNumericPort< PortTraits >::pushPacket( NativeSequenceType & data, diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h index 6936f95f1..c2f7f78a4 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h @@ -39,7 +39,6 @@ namespace bulkio { - template class InPort; template class PortTransport; // @@ -257,13 +256,9 @@ namespace bulkio { // // Lookup table for connections to input ports in the same process space // - typedef InPort LocalPortType; typedef PortTransport PortTransportType; virtual redhawk::BasicTransport* _createTransport(CORBA::Object_ptr object, const std::string& connectionId); - virtual PortTransportType* _createRemoteConnection(PortPtrType port, const std::string& connectionId); - virtual PortTransportType* _createLocalConnection(PortPtrType port, LocalPortType* localPort, - const std::string& connectionId); typedef redhawk::UsesPort::TransportIteratorAdapter TransportIterator; @@ -419,13 +414,6 @@ namespace bulkio { * streamID: stream identifier */ void pushPacket( const DataBufferType & data, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID); - - protected: - using OutPort::logger; - typedef typename OutPort::PortPtrType PortPtrType; - typedef typename OutPort::PortTransportType PortTransportType; - - virtual PortTransportType* _createRemoteConnection(PortPtrType port, const std::string& connectionId); }; // diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp b/bulkioInterfaces/libsrc/cpp/bulkio_transport.cpp similarity index 57% rename from bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp rename to bulkioInterfaces/libsrc/cpp/bulkio_transport.cpp index f5cb0c89b..d13f8d098 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_connection.hpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_transport.cpp @@ -1,98 +1,131 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK bulkioInterfaces. + * + * REDHAWK bulkioInterfaces is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK bulkioInterfaces is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +#include "bulkio_transport.h" +#include "bulkio_traits.h" +#include "bulkio_time_operators.h" +#include "bulkio_in_port.h" + namespace bulkio { + template + class LocalTransport; template - class PortTransport : public redhawk::BasicTransport - { - public: - typedef typename PortTraits::PortType PortType; - typedef typename PortType::_var_type VarType; - typedef typename PortType::_ptr_type PtrType; - typedef typename PortTraits::NativeType NativeType; - typedef typename PortTraits::SharedBufferType SharedBufferType; + class RemoteTransport; - PortTransport(const std::string& connectionId, const std::string& name, PtrType objref) : - redhawk::BasicTransport(connectionId, objref), - stats(name, sizeof(NativeType)), - _port(PortType::_duplicate(objref)) - { + template + class ChunkingTransport; + + template + PortTransport* PortTransport::Factory(const std::string& connectionId, + const std::string& name, + PtrType port) + { + typedef InPort LocalPortType; + LocalPortType* local_port = ossie::corba::getLocalServant(port); + if (local_port) { + return LocalTransport::Factory(connectionId, name, local_port, port); + } else { + return RemoteTransport::Factory(connectionId, name, port); } + } - virtual ~PortTransport() { }; + template + PortTransport::PortTransport(const std::string& connectionId, const std::string& name, PtrType objref) : + redhawk::BasicTransport(connectionId, objref), + stats(name, sizeof(NativeType)), + _port(PortType::_duplicate(objref)) + { + } - virtual void disconnect() - { - // Send an end-of-stream for all active streams - for (VersionMap::iterator stream = _sriVersions.begin(); stream != _sriVersions.end(); ++stream) { - this->_pushPacket(SharedBufferType(), bulkio::time::utils::notSet(), true, stream->first); - } - _sriVersions.clear(); - } + template + PortTransport::~PortTransport() + { + } - void pushSRI(const std::string& streamID, const BULKIO::StreamSRI& sri, int version) - { - VersionMap::iterator existing = _sriVersions.find(streamID); - if (existing != _sriVersions.end()) { - if (version == existing->second) { - return; - } - existing->second = version; - } else { - _sriVersions[streamID] = version; - } - this->_pushSRI(sri); + template + void PortTransport::disconnect() + { + // Send an end-of-stream for all active streams + for (VersionMap::iterator stream = _sriVersions.begin(); stream != _sriVersions.end(); ++stream) { + this->_pushPacket(SharedBufferType(), bulkio::time::utils::notSet(), true, stream->first); } + _sriVersions.clear(); + } - void pushPacket(const SharedBufferType& data, - const BULKIO::PrecisionUTCTime& T, - bool EOS, - const std::string& streamID, - const BULKIO::StreamSRI& sri) - { - this->_sendPacket(data, T, EOS, streamID, sri); - if (EOS) { - _sriVersions.erase(streamID); + template + void PortTransport::pushSRI(const std::string& streamID, const BULKIO::StreamSRI& sri, int version) + { + VersionMap::iterator existing = _sriVersions.find(streamID); + if (existing != _sriVersions.end()) { + if (version == existing->second) { + return; } + existing->second = version; + } else { + _sriVersions[streamID] = version; } + this->_pushSRI(sri); + } - PtrType port() - { - return _port; + template + void PortTransport::pushPacket(const SharedBufferType& data, + const BULKIO::PrecisionUTCTime& T, + bool EOS, + const std::string& streamID, + const BULKIO::StreamSRI& sri) + { + this->_sendPacket(data, T, EOS, streamID, sri); + if (EOS) { + _sriVersions.erase(streamID); } + } - linkStatistics stats; - - protected: - virtual void _pushSRI(const BULKIO::StreamSRI& sri) = 0; + template + typename PortTransport::PtrType PortTransport::port() + { + return _port; + } - virtual void _sendPacket(const SharedBufferType& data, - const BULKIO::PrecisionUTCTime& T, - bool EOS, - const std::string& streamID, - const BULKIO::StreamSRI& sri) - { - this->_pushPacket(data, T, EOS, streamID); - stats.update(this->_dataLength(data), 0, EOS, streamID); - } + template + bool PortTransport::isLocal() const + { + return false; + } - virtual void _pushPacket(const SharedBufferType& data, - const BULKIO::PrecisionUTCTime& T, - bool EOS, - const std::string& streamID) = 0; - - // - // Returns the total number of elements of data in a pushPacket call, for - // statistical tracking; enables XML and File specialization, which have - // different notions of size - // - size_t _dataLength(const SharedBufferType& data) - { - return data.size(); - } + template + void PortTransport::_sendPacket(const SharedBufferType& data, + const BULKIO::PrecisionUTCTime& T, + bool EOS, + const std::string& streamID, + const BULKIO::StreamSRI& sri) + { + this->_pushPacket(data, T, EOS, streamID); + stats.update(this->_dataLength(data), 0, EOS, streamID); + } - VarType _port; - typedef std::map VersionMap; - VersionMap _sriVersions; - }; + template + size_t PortTransport::_dataLength(const SharedBufferType& data) + { + return data.size(); + } template <> size_t PortTransport::_dataLength(const std::string& /*unused*/) @@ -110,6 +143,11 @@ namespace bulkio { typedef typename PortTraits::SequenceType PortSequenceType; typedef typename PortTraits::TransportType TransportType; + static RemoteTransport* Factory(const std::string& connectionId, const std::string& name, PtrType port) + { + return new ChunkingTransport(connectionId, name, port); + } + RemoteTransport(const std::string& connectionId, const std::string& name, PtrType port) : PortTransport(connectionId, name, port) { @@ -149,6 +187,14 @@ namespace bulkio { } }; + template <> + RemoteTransport* RemoteTransport::Factory(const std::string& connectionId, + const std::string& name, + PtrType port) + { + return new RemoteTransport(connectionId, name, port); + } + template <> void RemoteTransport::_pushPacketImpl(const std::string& data, const BULKIO::PrecisionUTCTime& T, @@ -158,6 +204,14 @@ namespace bulkio { _port->pushPacket(data.c_str(), T, EOS, streamID); } + template <> + RemoteTransport* RemoteTransport::Factory(const std::string& connectionId, + const std::string& name, + PtrType port) + { + return new RemoteTransport(connectionId, name, port); + } + template <> void RemoteTransport::_pushPacketImpl(const std::string& data, const BULKIO::PrecisionUTCTime& /* unused */, @@ -255,6 +309,12 @@ namespace bulkio { typedef InPort LocalPortType; typedef typename PortTraits::SharedBufferType SharedBufferType; + static LocalTransport* Factory(const std::string& connectionId, const std::string& name, + LocalPortType* localPort, PtrType port) + { + return new LocalTransport(connectionId, name, localPort, port); + } + LocalTransport(const std::string& connectionId, const std::string& name, LocalPortType* localPort, PtrType port) : PortTransport(connectionId, name, port), @@ -268,6 +328,11 @@ namespace bulkio { _localPort->_remove_ref(); } + virtual bool isLocal() const + { + return true; + } + protected: virtual void _pushSRI(const BULKIO::StreamSRI& sri) { @@ -311,4 +376,25 @@ namespace bulkio { _localPort->queuePacket(data, T, EOS, streamID); } +#define INSTANTIATE_TEMPLATE(x) \ + template class PortTransport; \ + template class LocalTransport; \ + template class RemoteTransport; \ + +#define INSTANTIATE_NUMERIC_TEMPLATE(x) \ + INSTANTIATE_TEMPLATE(x); template class ChunkingTransport; + + INSTANTIATE_NUMERIC_TEMPLATE(CharPortTraits); + INSTANTIATE_NUMERIC_TEMPLATE(OctetPortTraits); + INSTANTIATE_NUMERIC_TEMPLATE(ShortPortTraits); + INSTANTIATE_NUMERIC_TEMPLATE(UShortPortTraits); + INSTANTIATE_NUMERIC_TEMPLATE(LongPortTraits); + INSTANTIATE_NUMERIC_TEMPLATE(ULongPortTraits); + INSTANTIATE_NUMERIC_TEMPLATE(LongLongPortTraits); + INSTANTIATE_NUMERIC_TEMPLATE(ULongLongPortTraits); + INSTANTIATE_NUMERIC_TEMPLATE(FloatPortTraits); + INSTANTIATE_NUMERIC_TEMPLATE(DoublePortTraits); + + INSTANTIATE_TEMPLATE(FilePortTraits); + INSTANTIATE_TEMPLATE(XMLPortTraits); } diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_transport.h b/bulkioInterfaces/libsrc/cpp/bulkio_transport.h new file mode 100644 index 000000000..4a971c4a3 --- /dev/null +++ b/bulkioInterfaces/libsrc/cpp/bulkio_transport.h @@ -0,0 +1,89 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK bulkioInterfaces. + * + * REDHAWK bulkioInterfaces is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK bulkioInterfaces is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ +#ifndef __bulkio_transport_h +#define __bulkio_transport_h + +#include + +#include "bulkio_base.h" + +namespace bulkio { + + template + class PortTransport : public redhawk::BasicTransport + { + public: + typedef typename PortTraits::PortType PortType; + typedef typename PortType::_var_type VarType; + typedef typename PortType::_ptr_type PtrType; + typedef typename PortTraits::NativeType NativeType; + typedef typename PortTraits::SharedBufferType SharedBufferType; + + static PortTransport* Factory(const std::string& connectionId, const std::string& name, PtrType port); + + PortTransport(const std::string& connectionId, const std::string& name, PtrType objref); + + virtual ~PortTransport(); + + virtual void disconnect(); + + void pushSRI(const std::string& streamID, const BULKIO::StreamSRI& sri, int version); + + void pushPacket(const SharedBufferType& data, + const BULKIO::PrecisionUTCTime& T, + bool EOS, + const std::string& streamID, + const BULKIO::StreamSRI& sri); + + PtrType port(); + + virtual bool isLocal() const; + + linkStatistics stats; + + protected: + virtual void _pushSRI(const BULKIO::StreamSRI& sri) = 0; + + virtual void _sendPacket(const SharedBufferType& data, + const BULKIO::PrecisionUTCTime& T, + bool EOS, + const std::string& streamID, + const BULKIO::StreamSRI& sri); + + virtual void _pushPacket(const SharedBufferType& data, + const BULKIO::PrecisionUTCTime& T, + bool EOS, + const std::string& streamID) = 0; + + // + // Returns the total number of elements of data in a pushPacket call, for + // statistical tracking; enables XML and File specialization, which have + // different notions of size + // + size_t _dataLength(const SharedBufferType& data); + + VarType _port; + typedef std::map VersionMap; + VersionMap _sriVersions; + }; + +} + +#endif // __bulkio_transport_h From 912dae84875dc87486f724a86c90fd89ed22cc02 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 1 Dec 2016 16:43:24 -0500 Subject: [PATCH 0583/1644] Remove added methods on BulkIO input ports for shared buffer passing (must use streams) --- bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp | 17 +---------------- bulkioInterfaces/libsrc/cpp/bulkio_in_port.h | 9 --------- 2 files changed, 1 insertion(+), 25 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp index 07a9f91e7..d39caa01e 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp @@ -735,12 +735,6 @@ namespace bulkio { this->queuePacket(SharedBufferType(reinterpret_cast(ptr), size), T, EOS, streamID); } - template < typename PortTraits > - void InNumericPort< PortTraits >::pushPacket(const SharedBufferType& data, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID) - { - this->queuePacket(data, T, EOS, streamID); - } - template < typename PortTraits > typename InNumericPort< PortTraits >::StreamList InNumericPort< PortTraits >::pollStreams(float timeout) { @@ -844,11 +838,6 @@ namespace bulkio { } } - void InFilePort::pushPacket(const std::string& data, const BULKIO::PrecisionUTCTime& T, CORBA::Boolean EOS, const std::string& streamID) - { - this->queuePacket(data, T, EOS, streamID); - } - InXMLPort::InXMLPort(std::string name, LOGGER_PTR logger, @@ -877,7 +866,7 @@ namespace bulkio { if (data) { buffer = data; } - this->pushPacket(buffer, EOS, streamID); + this->queuePacket(buffer, BULKIO::PrecisionUTCTime(), EOS, streamID); } void InXMLPort::pushPacket(const char* data, const BULKIO::PrecisionUTCTime& T, CORBA::Boolean EOS, const char* streamID) @@ -889,10 +878,6 @@ namespace bulkio { this->queuePacket(buffer, T, EOS, streamID); } - void InXMLPort::pushPacket(const std::string& data, CORBA::Boolean EOS, const std::string& streamID) - { - this->queuePacket(data, BULKIO::PrecisionUTCTime(), EOS, streamID); - } // // Required for Template Instantion for the compilation unit. diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h index 2fb90d165..7e7d8ccf8 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h @@ -467,9 +467,6 @@ namespace bulkio { // @param streamID - name of the stream the vector and stream context data are associated with virtual void pushPacket(const PortSequenceType& data, const BULKIO::PrecisionUTCTime& T, CORBA::Boolean EOS, const char* streamID); - // Local non-copying transfer - void pushPacket(const SharedBufferType& data, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID); - // // Stream-based input API // @@ -538,9 +535,6 @@ namespace bulkio { // @param EOS - indicator that the stream has ended, (stream is identified by streamID) // @param streamID - name of the stream the vector and stream context data are associated with virtual void pushPacket(const char *data, const BULKIO::PrecisionUTCTime& T, CORBA::Boolean EOS, const char* streamID); - - // Local push version - void pushPacket(const std::string& data, const BULKIO::PrecisionUTCTime& T, CORBA::Boolean EOS, const std::string& streamID); }; @@ -570,9 +564,6 @@ namespace bulkio { virtual void pushPacket(const char *data, CORBA::Boolean EOS, const char* streamID); void pushPacket(const char* data, const BULKIO::PrecisionUTCTime& T, CORBA::Boolean EOS, const char* streamID) __attribute__ ((deprecated)); - - // Local push version - void pushPacket(const std::string& data, CORBA::Boolean EOS, const std::string& streamID); }; From fae63527bf28890ca1b02986022aa1a11d5eec65 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 1 Dec 2016 17:24:01 -0500 Subject: [PATCH 0584/1644] Fix bug in XML and File output streams that always set end-of-stream to true on write --- bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp index 447e2395c..23b0b90e5 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp @@ -516,7 +516,7 @@ class OutputStream::Impl : public OutputStreamBase::Impl { // however, since it's not used for XML ports, creating a method-static // instance is sufficient static BULKIO::PrecisionUTCTime unused; - _port->_sendPacket(data, unused, true, _streamID); + _port->_sendPacket(data, unused, eos, _streamID); } OutPortType* _port; @@ -575,7 +575,7 @@ class OutputStream::Impl : public OutputStreamBase::Impl { private: void _send(const std::string& data, const BULKIO::PrecisionUTCTime& time, bool eos) { - _port->_sendPacket(data, time, true, _streamID); + _port->_sendPacket(data, time, eos, _streamID); } OutPortType* _port; From b1a407ac315168ca98e4894c1f0f82ce9f7d65bf Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 1 Dec 2016 17:30:49 -0500 Subject: [PATCH 0585/1644] In base input stream readPacket(), return a null DataBlock if the packet is empty and the stream ended --- bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp index f790e2632..7a3e06895 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp @@ -65,7 +65,7 @@ class InputStreamBase::Impl { if (_eosState == EOS_RECEIVED) { _eosState = EOS_REACHED; } - if (!packet) { + if (!packet || (packet->EOS && packet->buffer.empty())) { if (_eosState == EOS_REACHED) { _reportEOS(); } From 5abf263bc2437f8bb07e8ca6089aabf45bb3c52c Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 1 Dec 2016 17:40:15 -0500 Subject: [PATCH 0586/1644] Rename input stream classes to reflect that the base is a complete class on its own, and the derived class adds buffering; update to REDHAWK standard 4-space indent --- bulkioInterfaces/libsrc/cpp/bulkio_in_port.h | 2 +- .../libsrc/cpp/bulkio_in_stream.cpp | 720 +++++++++--------- .../libsrc/cpp/bulkio_in_stream.h | 180 ++--- 3 files changed, 451 insertions(+), 451 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h index 7e7d8ccf8..12c67da6f 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h @@ -385,7 +385,7 @@ namespace bulkio { // first end-of-stream void discardPacketsForStream(const std::string& streamID); - friend class InputStreamBase; + friend class InputStream; size_t samplesAvailable(const std::string& streamID, bool firstPacket); void createStream(const std::string& streamID, const boost::shared_ptr& sri); diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp index 7a3e06895..aa182965a 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp @@ -26,10 +26,10 @@ #include #include -using bulkio::InputStreamBase; +using bulkio::InputStream; template -class InputStreamBase::Impl { +class InputStream::Impl { public: typedef typename InPortType::Packet PacketType; @@ -169,95 +169,95 @@ class InputStreamBase::Impl { }; template -InputStreamBase::InputStreamBase() : +InputStream::InputStream() : _impl() { } template -InputStreamBase::InputStreamBase(const boost::shared_ptr& sri, - InPortType* port) : +InputStream::InputStream(const boost::shared_ptr& sri, + InPortType* port) : _impl(boost::make_shared(sri, port)) { } template -InputStreamBase::InputStreamBase(const boost::shared_ptr& impl) : +InputStream::InputStream(const boost::shared_ptr& impl) : _impl(impl) { } template -const std::string& InputStreamBase::streamID() const +const std::string& InputStream::streamID() const { return _impl->streamID(); } template -const BULKIO::StreamSRI& InputStreamBase::sri() const +const BULKIO::StreamSRI& InputStream::sri() const { return _impl->sri(); } template -typename InputStreamBase::DataBlockType InputStreamBase::read() +typename InputStream::DataBlockType InputStream::read() { return _impl->readPacket(true); } template -typename InputStreamBase::DataBlockType InputStreamBase::tryread() +typename InputStream::DataBlockType InputStream::tryread() { return _impl->readPacket(false); } template -bool InputStreamBase::enabled() const +bool InputStream::enabled() const { return _impl->enabled(); } template -void InputStreamBase::enable() +void InputStream::enable() { _impl->enable(); } template -void InputStreamBase::disable() +void InputStream::disable() { _impl->disable(); } template -bool InputStreamBase::eos() +bool InputStream::eos() { return _impl->eos(); } template -bool InputStreamBase::operator!() const +bool InputStream::operator!() const { return !_impl; } template -InputStreamBase::operator unspecified_bool_type() const +InputStream::operator unspecified_bool_type() const { - return _impl?&InputStreamBase::_impl:0; + return _impl?&InputStream::_impl:0; } template -bool InputStreamBase::hasBufferedData() +bool InputStream::hasBufferedData() { - return _impl->hasBufferedData(); + return _impl->hasBufferedData(); } -using bulkio::InputStream; +using bulkio::BufferedInputStream; template -class InputStream::Impl : public Base::Impl { +class BufferedInputStream::Impl : public Base::Impl { public: typedef typename Base::Impl ImplBase; @@ -274,454 +274,454 @@ class InputStream::Impl : public Base::Impl { { } - ~Impl() - { - delete _pending; - } - - virtual bool eos() - { - if (_queue.empty()) { - // Try a non-blocking fetch to see if there's an empty end-of-stream - // packet waiting; this helps with the case where the last read consumes - // exactly the remaining data, and the stream will never report a ready - // state again - _fetchPacket(false); - } - return ImplBase::eos(); - } - - size_t samplesAvailable() - { - // Start with the samples already in the queue - size_t queued = _samplesQueued; - if (queued > 0) { - // Adjust number of samples to account for complex data, if necessary - const BULKIO::StreamSRI& sri = *(_queue.front().SRI); - if (sri.mode) { - queued /= 2; - } + ~Impl() + { + delete _pending; } - // Only search the port's queue if there is no SRI change or input queue - // flush pending - if (!_pending) { - // If the queue is empty, this is the first read of a segment (i.e., - // search can go past the first packet if the SRI change or queue flush - // flag is set) - bool first = _queue.empty(); - queued += ImplBase::_samplesAvailable(first); + virtual bool eos() + { + if (_queue.empty()) { + // Try a non-blocking fetch to see if there's an empty end-of-stream + // packet waiting; this helps with the case where the last read consumes + // exactly the remaining data, and the stream will never report a ready + // state again + _fetchPacket(false); + } + return ImplBase::eos(); } - return queued; - } + size_t samplesAvailable() + { + // Start with the samples already in the queue + size_t queued = _samplesQueued; + if (queued > 0) { + // Adjust number of samples to account for complex data, if necessary + const BULKIO::StreamSRI& sri = *(_queue.front().SRI); + if (sri.mode) { + queued /= 2; + } + } - DataBlockType readPacket(bool blocking) - { - if (_samplesQueued == 0) { - _fetchPacket(blocking); - } + // Only search the port's queue if there is no SRI change or input queue + // flush pending + if (!_pending) { + // If the queue is empty, this is the first read of a segment (i.e., + // search can go past the first packet if the SRI change or queue flush + // flag is set) + bool first = _queue.empty(); + queued += ImplBase::_samplesAvailable(first); + } - if (_samplesQueued == 0) { - return DataBlockType(); - } - // Only read up to the end of the first packet in the queue - const size_t samples = _queue.front().buffer.size() - _sampleOffset; - return _readData(samples, samples); - } - - DataBlockType read(size_t count, size_t consume, bool blocking) - { - // Try to get the SRI for the upcoming block of data, fetching it from the - // port's input queue if necessary - const BULKIO::StreamSRI* sri = _nextSRI(blocking); - if (!sri) { - // No SRI retreived implies no data will be retrieved, either due to end- - // of-stream or because it would block - if (this->_eosState == ImplBase::EOS_REACHED) { - // If this is the first time end-of-stream could be reported, remove - // the stream from the port; since the returned data block is invalid, - // that's a cue for the caller to check end-of-stream, but they don't - // have to - this->_reportEOS(); - } - return DataBlockType(); + return queued; } - // If the next block of data is complex, double the read and consume size - // (which the lower-level I/O handles in terms of scalars) so that the - // returned block has the right number of samples - if (sri->mode == 1) { - count *= 2; - consume *= 2; - } + DataBlockType readPacket(bool blocking) + { + if (_samplesQueued == 0) { + _fetchPacket(blocking); + } - // Queue up packets from the port until we have enough data to satisfy the - // requested read amount - while (_samplesQueued < count) { - if (!_fetchPacket(blocking)) { - break; - } + if (_samplesQueued == 0) { + return DataBlockType(); + } + // Only read up to the end of the first packet in the queue + const size_t samples = _queue.front().buffer.size() - _sampleOffset; + return _readData(samples, samples); } - if (_samplesQueued == 0) { - return DataBlockType(); - } + DataBlockType read(size_t count, size_t consume, bool blocking) + { + // Try to get the SRI for the upcoming block of data, fetching it from the + // port's input queue if necessary + const BULKIO::StreamSRI* sri = _nextSRI(blocking); + if (!sri) { + // No SRI retreived implies no data will be retrieved, either due to end- + // of-stream or because it would block + if (this->_eosState == ImplBase::EOS_REACHED) { + // If this is the first time end-of-stream could be reported, remove + // the stream from the port; since the returned data block is invalid, + // that's a cue for the caller to check end-of-stream, but they don't + // have to + this->_reportEOS(); + } + return DataBlockType(); + } - // Only read as many samples as are available (e.g., if a new SRI is coming - // or the stream reached the end) - const size_t samples = std::min(count, _samplesQueued); - - // Handle a partial read, which could mean that there's not enough data at - // present (non-blocking), or that the read pointer has reached the end of - // a segment (new SRI, queue flush, end-of-stream) - if (samples < count) { - // Non-blocking: return a null block if there's not currently a break in - // the data, under the assumption that a future read might return the - // full amount - if (!blocking && !_pending && (this->_eosState == ImplBase::EOS_NONE)) { - return DataBlockType(); - } - // Otherwise, consume all remaining data - consume = samples; - } + // If the next block of data is complex, double the read and consume size + // (which the lower-level I/O handles in terms of scalars) so that the + // returned block has the right number of samples + if (sri->mode == 1) { + count *= 2; + consume *= 2; + } - return _readData(samples, consume); - } - - size_t skip(size_t count) - { - // If the next block of data is complex, double the skip size (which the - // lower-level I/O handles in terms of scalars) so that the right number of - // samples is skipped - const BULKIO::StreamSRI* sri = _nextSRI(true); - if (!sri) { - return 0; - } + // Queue up packets from the port until we have enough data to satisfy the + // requested read amount + while (_samplesQueued < count) { + if (!_fetchPacket(blocking)) { + break; + } + } - size_t item_size = sri->mode?2:1; - count *= item_size; + if (_samplesQueued == 0) { + return DataBlockType(); + } - // Queue up packets from the port until we have enough data to satisfy the - // requested read amount - while (_samplesQueued < count) { - if (!_fetchPacket(true)) { - break; - } - } + // Only read as many samples as are available (e.g., if a new SRI is coming + // or the stream reached the end) + const size_t samples = std::min(count, _samplesQueued); + + // Handle a partial read, which could mean that there's not enough data at + // present (non-blocking), or that the read pointer has reached the end of + // a segment (new SRI, queue flush, end-of-stream) + if (samples < count) { + // Non-blocking: return a null block if there's not currently a break in + // the data, under the assumption that a future read might return the + // full amount + if (!blocking && !_pending && (this->_eosState == ImplBase::EOS_NONE)) { + return DataBlockType(); + } + // Otherwise, consume all remaining data + consume = samples; + } - count = std::min(count, _samplesQueued); - _consumeData(count); - - // Convert scalars back to samples - return count / item_size; - } - - bool ready() - { - if (!this->_enabled) { - return false; - } else if (_samplesQueued) { - return true; - } else { - return samplesAvailable() > 0; + return _readData(samples, consume); } - } - virtual void disable() - { - ImplBase::disable(); + size_t skip(size_t count) + { + // If the next block of data is complex, double the skip size (which the + // lower-level I/O handles in terms of scalars) so that the right number of + // samples is skipped + const BULKIO::StreamSRI* sri = _nextSRI(true); + if (!sri) { + return 0; + } - // Clear queued packets, which implicitly deletes them - _queue.clear(); - } + size_t item_size = sri->mode?2:1; + count *= item_size; - bool hasBufferedData() const - { - if (!_queue.empty() || _pending) { - // Return true if either there are queued or pending packets - return true; - } - return ImplBase::hasBufferedData(); - } + // Queue up packets from the port until we have enough data to satisfy the + // requested read amount + while (_samplesQueued < count) { + if (!_fetchPacket(true)) { + break; + } + } -private: - void _consumeData(size_t count) - { - while (count > 0) { - const SharedBufferType& data = _queue.front().buffer; - - const size_t available = data.size() - _sampleOffset; - const size_t pass = std::min(available, count); - - _sampleOffset += pass; - _samplesQueued -= pass; - count -= pass; - - if (_sampleOffset >= data.size()) { - // Read pointer has passed the end of the packet data - _consumePacket(); - _sampleOffset = 0; - } + count = std::min(count, _samplesQueued); + _consumeData(count); + + // Convert scalars back to samples + return count / item_size; } - } - - void _consumePacket() - { - // Acknowledge any end-of-stream flag and delete the packet (the queue will - // automatically delete it when it's removed) - if (_queue.front().EOS) { - this->_eosState = ImplBase::EOS_REACHED; + + bool ready() + { + if (!this->_enabled) { + return false; + } else if (_samplesQueued) { + return true; + } else { + return samplesAvailable() > 0; + } } - _queue.pop_front(); - // If the queue is empty, move the pending packet onto the queue - if (_queue.empty() && _pending) { - _queuePacket(_pending); - _pending = 0; + virtual void disable() + { + ImplBase::disable(); + + // Clear queued packets, which implicitly deletes them + _queue.clear(); } - } - - DataBlockType _readData(size_t count, size_t consume) - { - // Acknowledge pending SRI change - PacketType& front = _queue.front(); - - // Allocate empty data block and propagate the SRI change and input queue - // flush flags - DataBlockType data(this->_sri); - this->_setBlockFlags(data, front); - - // Clear flags from packet, since they've been reported - front.sriChanged = false; - front.inputQueueFlushed = false; - - size_t last_offset = _sampleOffset + count; - if (last_offset <= front.buffer.size()) { - // The requsted sample count can be satisfied from the first packet - _addTimestamp(data, _sampleOffset, 0, front.T); - data.buffer(front.buffer.slice(_sampleOffset, last_offset)); - } else { - // We have to span multiple packets to get the data - redhawk::buffer buffer(count); - data.buffer(buffer); - size_t data_offset = 0; - - // Assemble data spanning several input packets into the output buffer - size_t packet_index = 0; - size_t packet_offset = _sampleOffset; - while (count > 0) { - PacketType& packet = _queue[packet_index]; - const SharedBufferType& input_data = packet.buffer; - - // Add the timestamp for this pass - _addTimestamp(data, packet_offset, data_offset, packet.T); - - // The number of samples copied on this pass may be less than the total - // remaining - const size_t available = input_data.size() - packet_offset; - const size_t pass = std::min(available, count); - - std::copy(&input_data[packet_offset], &input_data[packet_offset+pass], &buffer[data_offset]); - data_offset += pass; - packet_offset += pass; - count -= pass; - - // If all the data from the current packet has been read, move on to - // the next - if (packet_offset >= input_data.size()) { - packet_offset = 0; - ++packet_index; - } - } + + bool hasBufferedData() const + { + if (!_queue.empty() || _pending) { + // Return true if either there are queued or pending packets + return true; + } + return ImplBase::hasBufferedData(); } - // Advance the read pointers - _consumeData(consume); - - return data; - } - - void _addTimestamp(DataBlockType& data, size_t input_offset, size_t output_offset, BULKIO::PrecisionUTCTime time) - { - // Determine the timestamp of this chunk of data; if this is the - // first chunk, the packet offset (number of samples already read) - // must be accounted for, so adjust the timestamp based on the SRI. - // Otherwise, the adjustment is a noop. - double time_offset = input_offset * data.xdelta(); - if (data.complex()) { - // Complex data; each sample is two values - time_offset /= 2.0; - output_offset /= 2; +private: + void _consumeData(size_t count) + { + while (count > 0) { + const SharedBufferType& data = _queue.front().buffer; + + const size_t available = data.size() - _sampleOffset; + const size_t pass = std::min(available, count); + + _sampleOffset += pass; + _samplesQueued -= pass; + count -= pass; + + if (_sampleOffset >= data.size()) { + // Read pointer has passed the end of the packet data + _consumePacket(); + _sampleOffset = 0; + } + } } - // If there is a time offset, apply the adjustment and mark the timestamp - // so that the caller knows it was calculated rather than received - bool synthetic = false; - if (time_offset > 0.0) { - time += time_offset; - synthetic = true; + void _consumePacket() + { + // Acknowledge any end-of-stream flag and delete the packet (the queue will + // automatically delete it when it's removed) + if (_queue.front().EOS) { + this->_eosState = ImplBase::EOS_REACHED; + } + _queue.pop_front(); + + // If the queue is empty, move the pending packet onto the queue + if (_queue.empty() && _pending) { + _queuePacket(_pending); + _pending = 0; + } } - data.addTimestamp(bulkio::SampleTimestamp(time, output_offset, synthetic)); - } + DataBlockType _readData(size_t count, size_t consume) + { + // Acknowledge pending SRI change + PacketType& front = _queue.front(); + + // Allocate empty data block and propagate the SRI change and input queue + // flush flags + DataBlockType data(this->_sri); + this->_setBlockFlags(data, front); + + // Clear flags from packet, since they've been reported + front.sriChanged = false; + front.inputQueueFlushed = false; + + size_t last_offset = _sampleOffset + count; + if (last_offset <= front.buffer.size()) { + // The requsted sample count can be satisfied from the first packet + _addTimestamp(data, _sampleOffset, 0, front.T); + data.buffer(front.buffer.slice(_sampleOffset, last_offset)); + } else { + // We have to span multiple packets to get the data + redhawk::buffer buffer(count); + data.buffer(buffer); + size_t data_offset = 0; + + // Assemble data spanning several input packets into the output buffer + size_t packet_index = 0; + size_t packet_offset = _sampleOffset; + while (count > 0) { + PacketType& packet = _queue[packet_index]; + const SharedBufferType& input_data = packet.buffer; + + // Add the timestamp for this pass + _addTimestamp(data, packet_offset, data_offset, packet.T); + + // The number of samples copied on this pass may be less than the total + // remaining + const size_t available = input_data.size() - packet_offset; + const size_t pass = std::min(available, count); + + std::copy(&input_data[packet_offset], &input_data[packet_offset+pass], &buffer[data_offset]); + data_offset += pass; + packet_offset += pass; + count -= pass; + + // If all the data from the current packet has been read, move on to + // the next + if (packet_offset >= input_data.size()) { + packet_offset = 0; + ++packet_index; + } + } + } - const BULKIO::StreamSRI* _nextSRI(bool blocking) - { - if (_queue.empty()) { - if (!_fetchPacket(blocking)) { - return 0; - } + // Advance the read pointers + _consumeData(consume); + + return data; } - return _queue.front().SRI.get(); - } + void _addTimestamp(DataBlockType& data, size_t input_offset, size_t output_offset, BULKIO::PrecisionUTCTime time) + { + // Determine the timestamp of this chunk of data; if this is the + // first chunk, the packet offset (number of samples already read) + // must be accounted for, so adjust the timestamp based on the SRI. + // Otherwise, the adjustment is a noop. + double time_offset = input_offset * data.xdelta(); + if (data.complex()) { + // Complex data; each sample is two values + time_offset /= 2.0; + output_offset /= 2; + } + + // If there is a time offset, apply the adjustment and mark the timestamp + // so that the caller knows it was calculated rather than received + bool synthetic = false; + if (time_offset > 0.0) { + time += time_offset; + synthetic = true; + } - bool _fetchPacket(bool blocking) - { - if (_pending) { - // Cannot read another packet until non-bridging packet is acknowledged - return false; + data.addTimestamp(bulkio::SampleTimestamp(time, output_offset, synthetic)); } - PacketType* packet = ImplBase::_fetchPacket(blocking); - if (!packet) { - return false; + const BULKIO::StreamSRI* _nextSRI(bool blocking) + { + if (_queue.empty()) { + if (!_fetchPacket(blocking)) { + return 0; + } + } + + return _queue.front().SRI.get(); } - if (_queue.empty() || _canBridge(packet)) { - _queuePacket(packet); - return true; - } else { - _pending = packet; - return false; + bool _fetchPacket(bool blocking) + { + if (_pending) { + // Cannot read another packet until non-bridging packet is acknowledged + return false; + } + + PacketType* packet = ImplBase::_fetchPacket(blocking); + if (!packet) { + return false; + } + + if (_queue.empty() || _canBridge(packet)) { + _queuePacket(packet); + return true; + } else { + _pending = packet; + return false; + } } - } - - void _queuePacket(PacketType* packet) - { - if (packet->EOS && packet->buffer.empty()) { - // Handle end-of-stream packet with no data (assuming that timestamps, - // SRI changes, and queue flushes are irrelevant at this point) - if (_queue.empty()) { - // No queued packets, read pointer has reached end-of-stream - this->_eosState = ImplBase::EOS_REACHED; - } else { - // Assign the end-of-stream flag to the last packet in the queue so - // that it is handled on read - _queue.back().EOS = true; - } - // Explicitly delete the packet, since it isn't being queued - delete packet; - } else { - // Add the packet to the queue, taking ownership; it will be deleted when - // it's consumed - _samplesQueued += packet->buffer.size(); - _queue.push_back(packet); + + void _queuePacket(PacketType* packet) + { + if (packet->EOS && packet->buffer.empty()) { + // Handle end-of-stream packet with no data (assuming that timestamps, + // SRI changes, and queue flushes are irrelevant at this point) + if (_queue.empty()) { + // No queued packets, read pointer has reached end-of-stream + this->_eosState = ImplBase::EOS_REACHED; + } else { + // Assign the end-of-stream flag to the last packet in the queue so + // that it is handled on read + _queue.back().EOS = true; + } + // Explicitly delete the packet, since it isn't being queued + delete packet; + } else { + // Add the packet to the queue, taking ownership; it will be deleted when + // it's consumed + _samplesQueued += packet->buffer.size(); + _queue.push_back(packet); + } } - } - bool _canBridge(PacketType* packet) const - { - return !(packet->sriChanged || packet->inputQueueFlushed); - } + bool _canBridge(PacketType* packet) const + { + return !(packet->sriChanged || packet->inputQueueFlushed); + } - boost::ptr_deque _queue; - PacketType* _pending; - size_t _samplesQueued; - size_t _sampleOffset; + boost::ptr_deque _queue; + PacketType* _pending; + size_t _samplesQueued; + size_t _sampleOffset; }; template -InputStream::InputStream() : +BufferedInputStream::BufferedInputStream() : Base() { } template -InputStream::InputStream(const boost::shared_ptr& sri, InPortType* port) : +BufferedInputStream::BufferedInputStream(const boost::shared_ptr& sri, InPortType* port) : Base(boost::make_shared(sri, port)) { } template -typename InputStream::DataBlockType InputStream::read() +typename BufferedInputStream::DataBlockType BufferedInputStream::read() { - return impl().readPacket(true); + return impl().readPacket(true); } template -typename InputStream::DataBlockType InputStream::read(size_t count) +typename BufferedInputStream::DataBlockType BufferedInputStream::read(size_t count) { - return impl().read(count, count, true); + return impl().read(count, count, true); } template -typename InputStream::DataBlockType InputStream::read(size_t count, size_t consume) +typename BufferedInputStream::DataBlockType BufferedInputStream::read(size_t count, size_t consume) { - return impl().read(count, consume, true); + return impl().read(count, consume, true); } template -typename InputStream::DataBlockType InputStream::tryread() +typename BufferedInputStream::DataBlockType BufferedInputStream::tryread() { - return impl().readPacket(false); + return impl().readPacket(false); } template -typename InputStream::DataBlockType InputStream::tryread(size_t count) +typename BufferedInputStream::DataBlockType BufferedInputStream::tryread(size_t count) { - return impl().read(count, count, false); + return impl().read(count, count, false); } template -typename InputStream::DataBlockType InputStream::tryread(size_t count, size_t consume) +typename BufferedInputStream::DataBlockType BufferedInputStream::tryread(size_t count, size_t consume) { - return impl().read(count, consume, false); + return impl().read(count, consume, false); } template -size_t InputStream::skip(size_t count) +size_t BufferedInputStream::skip(size_t count) { - return impl().skip(count); + return impl().skip(count); } template -size_t InputStream::samplesAvailable() +size_t BufferedInputStream::samplesAvailable() { - return impl().samplesAvailable(); + return impl().samplesAvailable(); } template -bool InputStream::operator==(const InputStream& other) const +bool BufferedInputStream::operator==(const BufferedInputStream& other) const { - return _impl.get() == other._impl.get(); + return _impl.get() == other._impl.get(); } template -bool InputStream::ready() +bool BufferedInputStream::ready() { - return impl().ready(); + return impl().ready(); } template -typename InputStream::Impl& InputStream::impl() +typename BufferedInputStream::Impl& BufferedInputStream::impl() { return static_cast(*_impl); } template -const typename InputStream::Impl& InputStream::impl() const +const typename BufferedInputStream::Impl& BufferedInputStream::impl() const { return static_cast(*_impl); } #define INSTANTIATE_TEMPLATE(x) \ - template class InputStreamBase; + template class InputStream; #define INSTANTIATE_NUMERIC_TEMPLATE(x) \ - INSTANTIATE_TEMPLATE(x); template class InputStream; + INSTANTIATE_TEMPLATE(x); template class BufferedInputStream; INSTANTIATE_NUMERIC_TEMPLATE(bulkio::CharPortTraits); INSTANTIATE_NUMERIC_TEMPLATE(bulkio::OctetPortTraits); diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.h b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.h index 81cda2ede..f4551f9c1 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.h @@ -31,129 +31,129 @@ namespace bulkio { - template - class InPort; + template + class InPort; - template - struct BlockTraits { - typedef DataBlock DataBlockType; - }; + template + struct BlockTraits { + typedef DataBlock DataBlockType; + }; - template <> - struct BlockTraits { - typedef XMLDataBlock DataBlockType; - }; + template <> + struct BlockTraits { + typedef XMLDataBlock DataBlockType; + }; - template <> - struct BlockTraits { - typedef FileDataBlock DataBlockType; - }; + template <> + struct BlockTraits { + typedef FileDataBlock DataBlockType; + }; - template - class InputStreamBase { - public: - typedef typename BlockTraits::DataBlockType DataBlockType; + template + class InputStream { + public: + typedef typename BlockTraits::DataBlockType DataBlockType; - const std::string& streamID() const; - const BULKIO::StreamSRI& sri() const; + const std::string& streamID() const; + const BULKIO::StreamSRI& sri() const; - DataBlockType read(); + DataBlockType read(); - DataBlockType tryread(); + DataBlockType tryread(); - bool enabled() const; - void enable(); - void disable(); + bool enabled() const; + void enable(); + void disable(); - bool eos(); + bool eos(); - bool operator! () const; + bool operator! () const; - protected: - typedef InPort InPortType; + protected: + typedef InPort InPortType; - class Impl; - typedef boost::shared_ptr InputStreamBase::*unspecified_bool_type; + class Impl; + typedef boost::shared_ptr InputStream::*unspecified_bool_type; - InputStreamBase(); - InputStreamBase(const boost::shared_ptr& impl); + InputStream(); + InputStream(const boost::shared_ptr& impl); - // Allow matching InPort class to create instances of this stream type - friend class InPort; - InputStreamBase(const boost::shared_ptr& sri, InPortType* port); + // Allow matching InPort class to create instances of this stream type + friend class InPort; + InputStream(const boost::shared_ptr& sri, InPortType* port); - bool hasBufferedData(); + bool hasBufferedData(); - boost::shared_ptr _impl; + boost::shared_ptr _impl; - public: - operator unspecified_bool_type() const; - }; + public: + operator unspecified_bool_type() const; + }; - template - class InputStream : public InputStreamBase { - public: - InputStream(); + template + class BufferedInputStream : public InputStream { + public: + BufferedInputStream(); - typedef typename InputStreamBase::DataBlockType DataBlockType; + typedef typename InputStream::DataBlockType DataBlockType; - DataBlockType read(); - DataBlockType read(size_t count); - DataBlockType read(size_t count, size_t consume); + DataBlockType read(); + DataBlockType read(size_t count); + DataBlockType read(size_t count, size_t consume); - DataBlockType tryread(); - DataBlockType tryread(size_t count); - DataBlockType tryread(size_t count, size_t consume); + DataBlockType tryread(); + DataBlockType tryread(size_t count); + DataBlockType tryread(size_t count, size_t consume); - size_t skip(size_t count); + size_t skip(size_t count); - size_t samplesAvailable(); + size_t samplesAvailable(); - bool operator== (const InputStream& other) const; + bool operator== (const BufferedInputStream& other) const; - bool ready(); + bool ready(); - private: - typedef InputStreamBase Base; - using Base::_impl; + private: + typedef InputStream Base; + using Base::_impl; - friend class InPort; - typedef InPort InPortType; - InputStream(const boost::shared_ptr&, InPortType*); + friend class InPort; + typedef InPort InPortType; + BufferedInputStream(const boost::shared_ptr&, InPortType*); - class Impl; - Impl& impl(); - const Impl& impl() const; - }; + class Impl; + Impl& impl(); + const Impl& impl() const; + }; - typedef InputStream InCharStream; - typedef InputStream InOctetStream; - typedef InputStream InShortStream; - typedef InputStream InUShortStream; - typedef InputStream InLongStream; - typedef InputStream InULongStream; - typedef InputStream InLongLongStream; - typedef InputStream InULongLongStream; - typedef InputStream InFloatStream; - typedef InputStream InDoubleStream; - typedef InputStreamBase InXMLStream; - typedef InputStreamBase InFileStream; + typedef BufferedInputStream InCharStream; + typedef BufferedInputStream InOctetStream; + typedef BufferedInputStream InShortStream; + typedef BufferedInputStream InUShortStream; + typedef BufferedInputStream InLongStream; + typedef BufferedInputStream InULongStream; + typedef BufferedInputStream InLongLongStream; + typedef BufferedInputStream InULongLongStream; + typedef BufferedInputStream InFloatStream; + typedef BufferedInputStream InDoubleStream; + typedef InputStream InXMLStream; + typedef InputStream InFileStream; - template - struct StreamTraits { - typedef InputStream InStreamType; - }; + template + struct StreamTraits { + typedef BufferedInputStream InStreamType; + }; - template <> - struct StreamTraits { - typedef InXMLStream InStreamType; - }; + template <> + struct StreamTraits { + typedef InXMLStream InStreamType; + }; - template <> - struct StreamTraits { - typedef InFileStream InStreamType; - }; + template <> + struct StreamTraits { + typedef InFileStream InStreamType; + }; } // end of bulkio namespace From 8ac348127eaefc27c8b73c3791fd8426fc17d1b3 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 2 Dec 2016 10:12:05 -0500 Subject: [PATCH 0587/1644] Refactor data block classes to provide a basic implementation that can be used for string, and the extended version for sample data; make XML timestamp handling consistent by always passing "not set" --- .../libsrc/cpp/bulkio_datablock.cpp | 438 ++++++------------ .../libsrc/cpp/bulkio_datablock.h | 222 ++++----- .../libsrc/cpp/bulkio_in_port.cpp | 3 +- .../libsrc/cpp/bulkio_in_stream.cpp | 1 + .../libsrc/cpp/bulkio_in_stream.h | 6 +- .../libsrc/cpp/bulkio_out_port.cpp | 9 +- .../libsrc/cpp/bulkio_out_stream.cpp | 9 +- 7 files changed, 261 insertions(+), 427 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_datablock.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_datablock.cpp index c0aac6335..395e5178e 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_datablock.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_datablock.cpp @@ -27,431 +27,301 @@ #include "bulkio_datablock.h" #include "bulkio_time_operators.h" +namespace bulkio { + namespace { + double get_drift(const SampleTimestamp& begin, const bulkio::SampleTimestamp& end, double xdelta) + { + double real = end.time - begin.time; + double expected = (end.offset - begin.offset)*xdelta; + return real-expected; + } + + void validate_timestamps(const std::list& timestamps) + { + // Validity checks + if (timestamps.empty()) { + throw std::logic_error("block contains no timestamps"); + } else if (timestamps.front().offset != 0) { + throw std::logic_error("no timestamp at offset 0"); + } + } + } +} + using bulkio::SampleTimestamp; using bulkio::DataBlock; template struct DataBlock::Impl { - Impl(const boost::shared_ptr& sri) : - data(), - sri(sri), - sriChangeFlags(bulkio::sri::NONE), - inputQueueFlushed(false) - { - } - - Impl(const boost::shared_ptr& sri, const ScalarBuffer& buffer) : - data(buffer), - sri(sri), - sriChangeFlags(bulkio::sri::NONE), - inputQueueFlushed(false) - { - } - - redhawk::shared_buffer data; - boost::shared_ptr sri; - std::list timestamps; - int sriChangeFlags; - bool inputQueueFlushed; -}; + Impl(const boost::shared_ptr& sri) : + data(), + sri(sri), + sriChangeFlags(bulkio::sri::NONE), + inputQueueFlushed(false) + { + } -template -DataBlock::DataBlock() : - _impl() -{ -} + Impl(const boost::shared_ptr& sri, const T& data) : + data(data), + sri(sri), + sriChangeFlags(bulkio::sri::NONE), + inputQueueFlushed(false) + { + } -template -DataBlock::DataBlock(const boost::shared_ptr& sri, size_t size) : - _impl(boost::make_shared(sri, redhawk::buffer(size))) -{ -} + T data; + boost::shared_ptr sri; + std::list timestamps; + int sriChangeFlags; + bool inputQueueFlushed; +}; template -DataBlock::DataBlock(const boost::shared_ptr& sri, const ScalarBuffer& buffer) : - _impl(boost::make_shared(sri, buffer)) +DataBlock::DataBlock() : + _impl() { } template -DataBlock::DataBlock(const BULKIO::StreamSRI& sri, size_t size) : - _impl(boost::make_shared(boost::make_shared(sri), redhawk::buffer(size))) +DataBlock::DataBlock(const boost::shared_ptr& sri, const T& data) : + _impl(boost::make_shared(sri, data)) { } template DataBlock DataBlock::copy() const { - DataBlock result; - if (_impl) { - result._impl = boost::make_shared(*_impl); - } - return result; + DataBlock result; + if (_impl) { + result._impl = boost::make_shared(*_impl); + } + return result; } template const BULKIO::StreamSRI& DataBlock::sri() const { - return *(_impl->sri); + return *(_impl->sri); } template double DataBlock::xdelta() const { - return _impl->sri->xdelta; -} - -template -T* DataBlock::data() -{ - return const_cast(_impl->data.data()); -} - -template -const T* DataBlock::data() const -{ - return _impl->data.data(); + return _impl->sri->xdelta; } template -size_t DataBlock::size() const +const T& DataBlock::data() const { - return _impl->data.size(); -} - -template -void DataBlock::resize(size_t count) -{ - // TODO: Copy data - _impl->data = redhawk::buffer(count); -} - -template -bool DataBlock::complex() const -{ - return (_impl->sri->mode != 0); -} - -template -std::complex* DataBlock::cxdata() -{ - return reinterpret_cast(data()); -} - -template -const std::complex* DataBlock::cxdata() const -{ - return reinterpret_cast(data()); -} - -template -size_t DataBlock::cxsize() const -{ - return size() / 2; + return _impl->data; } template void DataBlock::addTimestamp(const bulkio::SampleTimestamp& timestamp) { - std::list::iterator pos = _impl->timestamps.begin(); - const std::list::iterator end = _impl->timestamps.end(); - while ((pos != end) && (timestamp.offset >= pos->offset)) { - // TODO: Replace existing - ++pos; - } - _impl->timestamps.insert(pos, timestamp); + std::list::iterator pos = _impl->timestamps.begin(); + const std::list::iterator end = _impl->timestamps.end(); + while ((pos != end) && (timestamp.offset >= pos->offset)) { + // TODO: Replace existing + ++pos; + } + _impl->timestamps.insert(pos, timestamp); } template std::list DataBlock::getTimestamps() const { - return _impl->timestamps; -} - -namespace { - double get_drift(const bulkio::SampleTimestamp& begin, const bulkio::SampleTimestamp& end, double xdelta) - { - double real = end.time - begin.time; - double expected = (end.offset - begin.offset)*xdelta; - return real-expected; - } - - void validate_timestamps(const std::list& timestamps) - { - // Validity checks - if (timestamps.empty()) { - throw std::logic_error("block contains no timestamps"); - } else if (timestamps.front().offset != 0) { - throw std::logic_error("no timestamp at offset 0"); - } - } + return _impl->timestamps; } template const BULKIO::PrecisionUTCTime& DataBlock::getStartTime() const { - const std::list& timestamps = _impl->timestamps; - validate_timestamps(timestamps); + const std::list& timestamps = _impl->timestamps; + validate_timestamps(timestamps); - return _impl->timestamps.front().time; + return _impl->timestamps.front().time; } template double DataBlock::getNetTimeDrift() const { - const std::list& timestamps = _impl->timestamps; - validate_timestamps(timestamps); + const std::list& timestamps = _impl->timestamps; + validate_timestamps(timestamps); - return get_drift(timestamps.front(), timestamps.back(), _impl->sri->xdelta); + return get_drift(timestamps.front(), timestamps.back(), _impl->sri->xdelta); } template double DataBlock::getMaxTimeDrift() const { - const std::list& timestamps = _impl->timestamps; - validate_timestamps(timestamps); - - double max = 0.0; - std::list::const_iterator current = timestamps.begin(); - std::list::const_iterator next = current; - ++next; - for (; next != timestamps.end(); ++current, ++next) { - double drift = get_drift(*current, *next, _impl->sri->xdelta); - if (std::abs(drift) > std::abs(max)) { - max = drift; + const std::list& timestamps = _impl->timestamps; + validate_timestamps(timestamps); + + double max = 0.0; + std::list::const_iterator current = timestamps.begin(); + std::list::const_iterator next = current; + ++next; + for (; next != timestamps.end(); ++current, ++next) { + double drift = get_drift(*current, *next, _impl->sri->xdelta); + if (std::abs(drift) > std::abs(max)) { + max = drift; + } } - } - return max; + return max; } template bool DataBlock::sriChanged() const { - return sriChangeFlags() != bulkio::sri::NONE; + return sriChangeFlags() != bulkio::sri::NONE; } template int DataBlock::sriChangeFlags() const { - return _impl->sriChangeFlags; + return _impl->sriChangeFlags; } template void DataBlock::sriChangeFlags(int flags) { - _impl->sriChangeFlags = flags; + _impl->sriChangeFlags = flags; } template bool DataBlock::inputQueueFlushed() const { - return _impl->inputQueueFlushed; + return _impl->inputQueueFlushed; } template void DataBlock::inputQueueFlushed(bool flushed) { - _impl->inputQueueFlushed = flushed; + _impl->inputQueueFlushed = flushed; } template DataBlock::operator unspecified_bool_type() const { - return _impl?&DataBlock::_impl:0; + return _impl?&DataBlock::_impl:0; } -template -void DataBlock::swap(std::vector& other) -{ - // Copy the vector data into a new shared buffer - ScalarBuffer data = ScalarBuffer::make_transient(&other[0], other.size()).copy(); - // Swap the block's data with the new shared buffer - _impl->data.swap(data); - // Assign the old data to the vector - other.assign(data.begin(), data.end()); -} +using bulkio::SampleDataBlock; template -typename DataBlock::ScalarBuffer DataBlock::buffer() const +SampleDataBlock::SampleDataBlock() : + Base() { - return _impl->data; } template -typename DataBlock::ComplexBuffer DataBlock::cxbuffer() const +SampleDataBlock::SampleDataBlock(const boost::shared_ptr& sri, + const ScalarBuffer& buffer) : + Base(sri, buffer) { - return ComplexBuffer::recast(_impl->data); } template -void DataBlock::buffer(const ScalarBuffer& data) +SampleDataBlock::SampleDataBlock(const BULKIO::StreamSRI& sri, size_t size) : + Base(boost::make_shared(sri), redhawk::buffer(size)) { - _impl->data = data; } -// Instantiate templates for supported types -template class DataBlock; -template class DataBlock; -template class DataBlock; -template class DataBlock; -template class DataBlock; -template class DataBlock; -template class DataBlock; -template class DataBlock; -template class DataBlock; -template class DataBlock; - - -// -// XML -// -using bulkio::XMLDataBlock; - -struct XMLDataBlock::Impl { - Impl(const boost::shared_ptr& sri) : - sri(sri), - sriChangeFlags(bulkio::sri::NONE), - inputQueueFlushed(false) - { - } - - std::string data; - boost::shared_ptr sri; - int sriChangeFlags; - bool inputQueueFlushed; -}; - - -XMLDataBlock::XMLDataBlock() : - _impl() -{ -} - -XMLDataBlock::XMLDataBlock(const boost::shared_ptr& sri, const std::string& data) : - _impl(boost::make_shared(sri)) -{ - _impl->data = data; -} - -const BULKIO::StreamSRI& XMLDataBlock::sri() const -{ - return *(_impl->sri); -} - -const std::string& XMLDataBlock::data() const -{ - return _impl->data; -} - -bool XMLDataBlock::sriChanged() const -{ - return sriChangeFlags() != bulkio::sri::NONE; -} - -int XMLDataBlock::sriChangeFlags() const +template +T* SampleDataBlock::data() { - return _impl->sriChangeFlags; + return const_cast(_impl->data.data()); } -void XMLDataBlock::sriChangeFlags(int flags) +template +const T* SampleDataBlock::data() const { - _impl->sriChangeFlags = flags; + return _impl->data.data(); } -bool XMLDataBlock::inputQueueFlushed() const +template +size_t SampleDataBlock::size() const { - return _impl->inputQueueFlushed; + return _impl->data.size(); } -void XMLDataBlock::inputQueueFlushed(bool flushed) +template +void SampleDataBlock::resize(size_t count) { - _impl->inputQueueFlushed = flushed; + // TODO: Copy data + _impl->data = redhawk::buffer(count); } -bool XMLDataBlock::operator! () const +template +bool SampleDataBlock::complex() const { - return !_impl; + return (_impl->sri->mode != 0); } -XMLDataBlock::operator unspecified_bool_type() const +template +std::complex* SampleDataBlock::cxdata() { - return _impl?&XMLDataBlock::_impl:0; + return reinterpret_cast(data()); } - -// -// File -// -using bulkio::FileDataBlock; - -struct FileDataBlock::Impl { - Impl(const boost::shared_ptr& sri) : - sri(sri), - sriChangeFlags(bulkio::sri::NONE), - inputQueueFlushed(false) - { - } - - std::string data; - boost::shared_ptr sri; - int sriChangeFlags; - bool inputQueueFlushed; -}; - - -FileDataBlock::FileDataBlock() : - _impl() +template +const std::complex* SampleDataBlock::cxdata() const { + return reinterpret_cast(data()); } -FileDataBlock::FileDataBlock(const boost::shared_ptr& sri, const std::string& data) : - _impl(boost::make_shared(sri)) +template +size_t SampleDataBlock::cxsize() const { - _impl->data = data; + return size() / 2; } -const BULKIO::StreamSRI& FileDataBlock::sri() const +template +void SampleDataBlock::swap(std::vector& other) { - return *(_impl->sri); + // Copy the vector data into a new shared buffer + ScalarBuffer data = ScalarBuffer::make_transient(&other[0], other.size()).copy(); + // Swap the block's data with the new shared buffer + _impl->data.swap(data); + // Assign the old data to the vector + other.assign(data.begin(), data.end()); } -const std::string& FileDataBlock::data() const +template +typename SampleDataBlock::ScalarBuffer SampleDataBlock::buffer() const { return _impl->data; } -bool FileDataBlock::sriChanged() const -{ - return sriChangeFlags() != bulkio::sri::NONE; -} - -int FileDataBlock::sriChangeFlags() const -{ - return _impl->sriChangeFlags; -} - -void FileDataBlock::sriChangeFlags(int flags) -{ - _impl->sriChangeFlags = flags; -} - -bool FileDataBlock::inputQueueFlushed() const -{ - return _impl->inputQueueFlushed; -} - -void FileDataBlock::inputQueueFlushed(bool flushed) +template +typename SampleDataBlock::ComplexBuffer SampleDataBlock::cxbuffer() const { - _impl->inputQueueFlushed = flushed; + return ComplexBuffer::recast(_impl->data); } -bool FileDataBlock::operator! () const +template +void SampleDataBlock::buffer(const ScalarBuffer& data) { - return !_impl; + _impl->data = data; } -FileDataBlock::operator unspecified_bool_type() const -{ - return _impl?&FileDataBlock::_impl:0; -} +// Instantiate templates for supported types +#define INSTANTIATE_TEMPLATE(x) \ + template class DataBlock< x >; + +#define INSTANTIATE_NUMERIC_TEMPLATE(x) \ + INSTANTIATE_TEMPLATE(redhawk::shared_buffer); template class SampleDataBlock; + +INSTANTIATE_TEMPLATE(std::string); +INSTANTIATE_NUMERIC_TEMPLATE(int8_t); +INSTANTIATE_NUMERIC_TEMPLATE(CORBA::Octet); +INSTANTIATE_NUMERIC_TEMPLATE(CORBA::Short); +INSTANTIATE_NUMERIC_TEMPLATE(CORBA::UShort); +INSTANTIATE_NUMERIC_TEMPLATE(CORBA::Long); +INSTANTIATE_NUMERIC_TEMPLATE(CORBA::ULong); +INSTANTIATE_NUMERIC_TEMPLATE(CORBA::LongLong); +INSTANTIATE_NUMERIC_TEMPLATE(CORBA::ULongLong); +INSTANTIATE_NUMERIC_TEMPLATE(CORBA::Float); +INSTANTIATE_NUMERIC_TEMPLATE(CORBA::Double); diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_datablock.h b/bulkioInterfaces/libsrc/cpp/bulkio_datablock.h index 83ac834f8..90be45071 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_datablock.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_datablock.h @@ -32,147 +32,111 @@ namespace bulkio { - struct SampleTimestamp - { - SampleTimestamp(const BULKIO::PrecisionUTCTime& time, size_t offset=0, bool synthetic=false) : - time(time), - offset(offset), - synthetic(synthetic) + struct SampleTimestamp { - } - - BULKIO::PrecisionUTCTime time; - size_t offset; - bool synthetic; - }; - - template - class DataBlock - { - public: - typedef T ScalarType; - typedef std::complex ComplexType; - typedef redhawk::shared_buffer ScalarBuffer; - typedef redhawk::shared_buffer ComplexBuffer; - - DataBlock(); - explicit DataBlock(const boost::shared_ptr& sri, size_t size=0); - DataBlock(const boost::shared_ptr& sri, const ScalarBuffer& buffer); - DataBlock(const BULKIO::StreamSRI& sri, size_t size=0); - - DataBlock copy() const; - - const BULKIO::StreamSRI& sri() const; - double xdelta() const; - - ScalarType* data(); - const ScalarType* data() const; - size_t size() const; - void resize(size_t count); - - bool complex() const; - ComplexType* cxdata(); - const ComplexType* cxdata() const; - size_t cxsize() const; - - bool sriChanged() const; - int sriChangeFlags() const; - void sriChangeFlags(int flags); - - bool inputQueueFlushed() const; - void inputQueueFlushed(bool flush); - - void addTimestamp(const SampleTimestamp& timestamp); - const BULKIO::PrecisionUTCTime& getStartTime() const; - std::list getTimestamps() const; - double getNetTimeDrift() const; - double getMaxTimeDrift() const; - - bool operator! () const + SampleTimestamp(const BULKIO::PrecisionUTCTime& time, size_t offset=0, bool synthetic=false) : + time(time), + offset(offset), + synthetic(synthetic) + { + } + + BULKIO::PrecisionUTCTime time; + size_t offset; + bool synthetic; + }; + + template + class DataBlock { - return !_impl; - } + public: + DataBlock(); + DataBlock(const boost::shared_ptr& sri, const T& buffer); + + DataBlock copy() const; - void swap(std::vector& other); + const BULKIO::StreamSRI& sri() const; + double xdelta() const; - ScalarBuffer buffer() const; - ComplexBuffer cxbuffer() const; + const T& data() const; - void buffer(const ScalarBuffer& other); - private: - struct Impl; - boost::shared_ptr _impl; + bool sriChanged() const; + int sriChangeFlags() const; + void sriChangeFlags(int flags); - typedef boost::shared_ptr DataBlock::*unspecified_bool_type; + bool inputQueueFlushed() const; + void inputQueueFlushed(bool flush); - public: - operator unspecified_bool_type() const; - }; + void addTimestamp(const SampleTimestamp& timestamp); + const BULKIO::PrecisionUTCTime& getStartTime() const; + std::list getTimestamps() const; + double getNetTimeDrift() const; + double getMaxTimeDrift() const; - class XMLDataBlock { - public: - XMLDataBlock(); - XMLDataBlock(const boost::shared_ptr& sri, const std::string& data); + bool operator! () const + { + return !_impl; + } - const BULKIO::StreamSRI& sri() const; - const std::string& data() const; + protected: + struct Impl; + boost::shared_ptr _impl; - bool sriChanged() const; - int sriChangeFlags() const; - void sriChangeFlags(int flags); + typedef boost::shared_ptr DataBlock::*unspecified_bool_type; - bool inputQueueFlushed() const; - void inputQueueFlushed(bool flush); + public: + operator unspecified_bool_type() const; + }; - bool operator! () const; - - private: - struct Impl; - boost::shared_ptr _impl; - - typedef boost::shared_ptr XMLDataBlock::*unspecified_bool_type; - - public: - operator unspecified_bool_type() const; - }; - - class FileDataBlock { - public: - FileDataBlock(); - FileDataBlock(const boost::shared_ptr& sri, const std::string& data); - - const BULKIO::StreamSRI& sri() const; - const std::string& data() const; - - bool sriChanged() const; - int sriChangeFlags() const; - void sriChangeFlags(int flags); - - bool inputQueueFlushed() const; - void inputQueueFlushed(bool flush); - - bool operator! () const; - - private: - struct Impl; - boost::shared_ptr _impl; - - typedef boost::shared_ptr FileDataBlock::*unspecified_bool_type; - - public: - operator unspecified_bool_type() const; - }; - - typedef DataBlock CharDataBlock; - typedef DataBlock OctetDataBlock; - typedef DataBlock ShortDataBlock; - typedef DataBlock UShortDataBlock; - typedef DataBlock LongDataBlock; - typedef DataBlock ULongDataBlock; - typedef DataBlock LongLongDataBlock; - typedef DataBlock ULongLongDataBlock; - typedef DataBlock FloatDataBlock; - typedef DataBlock DoubleDataBlock; + template + class SampleDataBlock : public DataBlock > + { + public: + typedef T ScalarType; + typedef std::complex ComplexType; + typedef redhawk::shared_buffer ScalarBuffer; + typedef redhawk::shared_buffer ComplexBuffer; + + SampleDataBlock(); + explicit SampleDataBlock(const boost::shared_ptr& sri, + const ScalarBuffer& buffer=ScalarBuffer()); + SampleDataBlock(const BULKIO::StreamSRI& sri, size_t size=0); + + SampleDataBlock copy() const; + + ScalarType* data(); + const ScalarType* data() const; + size_t size() const; + void resize(size_t count); + + bool complex() const; + ComplexType* cxdata(); + const ComplexType* cxdata() const; + size_t cxsize() const; + + void swap(std::vector& other); + + ScalarBuffer buffer() const; + ComplexBuffer cxbuffer() const; + + void buffer(const ScalarBuffer& other); + + private: + typedef DataBlock Base; + using Base::_impl; + }; + + typedef SampleDataBlock CharDataBlock; + typedef SampleDataBlock OctetDataBlock; + typedef SampleDataBlock ShortDataBlock; + typedef SampleDataBlock UShortDataBlock; + typedef SampleDataBlock LongDataBlock; + typedef SampleDataBlock ULongDataBlock; + typedef SampleDataBlock LongLongDataBlock; + typedef SampleDataBlock ULongLongDataBlock; + typedef SampleDataBlock FloatDataBlock; + typedef SampleDataBlock DoubleDataBlock; + typedef DataBlock StringDataBlock; } // end of bulkio namespace diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp index d39caa01e..b6a5ddaf6 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp @@ -866,7 +866,8 @@ namespace bulkio { if (data) { buffer = data; } - this->queuePacket(buffer, BULKIO::PrecisionUTCTime(), EOS, streamID); + // Use a default timestamp of "not set" for XML + this->queuePacket(buffer, bulkio::time::utils::notSet(), EOS, streamID); } void InXMLPort::pushPacket(const char* data, const BULKIO::PrecisionUTCTime& T, CORBA::Boolean EOS, const char* streamID) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp index aa182965a..8e329874b 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp @@ -72,6 +72,7 @@ class InputStream::Impl { return DataBlockType(); } DataBlockType block(packet->SRI, packet->buffer); + block.addTimestamp(packet->T); _setBlockFlags(block, *packet); _sri = packet->SRI; return block; diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.h b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.h index f4551f9c1..7d5737ddb 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.h @@ -36,17 +36,17 @@ namespace bulkio { template struct BlockTraits { - typedef DataBlock DataBlockType; + typedef SampleDataBlock DataBlockType; }; template <> struct BlockTraits { - typedef XMLDataBlock DataBlockType; + typedef StringDataBlock DataBlockType; }; template <> struct BlockTraits { - typedef FileDataBlock DataBlockType; + typedef StringDataBlock DataBlockType; }; template diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp index bb69e282a..5aa28225d 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp @@ -572,11 +572,10 @@ namespace bulkio { void OutXMLPort::pushPacket(const std::string& data, bool EOS, const std::string& streamID) { - // Because it's templatized, the port's interface requires a timestamp; - // however, since it's not used for XML ports, creating a method-static - // instance is sufficient - static BULKIO::PrecisionUTCTime time; - _sendPacket(data, time, EOS, streamID); + // XML ports do not officially support timestamps, although the port + // implementation includes it (because it's templatized); always pass + // "not set" for consistency + _sendPacket(data, bulkio::time::utils::notSet(), EOS, streamID); } void OutXMLPort::pushPacket(const char* data, bool EOS, const std::string& streamID) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp index 23b0b90e5..fe01ea6c3 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp @@ -512,11 +512,10 @@ class OutputStream::Impl : public OutputStreamBase::Impl { private: void _send(const std::string& data, bool eos) { - // Because it's templatized, the port's interface requires a timestamp; - // however, since it's not used for XML ports, creating a method-static - // instance is sufficient - static BULKIO::PrecisionUTCTime unused; - _port->_sendPacket(data, unused, eos, _streamID); + // XML ports do not officially support timestamps, although the port + // implementation includes it (because it's templatized); always pass + // "not set" for consistency + _port->_sendPacket(data, bulkio::time::utils::notSet(), eos, _streamID); } OutPortType* _port; From 27f1f0cfc4b51bd85dc4fe66e3fb6825e202bcb3 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 2 Dec 2016 11:37:34 -0500 Subject: [PATCH 0588/1644] Move output stream port interaction into the base class (making it templatized); use traits so that XML and File output streams can be regular classes instead of specializations (fixes missing method issue in Eclipse) --- bulkioInterfaces/libsrc/cpp/bulkio_out_port.h | 4 +- .../libsrc/cpp/bulkio_out_stream.cpp | 529 ++++++++---------- .../libsrc/cpp/bulkio_out_stream.h | 71 +-- 3 files changed, 288 insertions(+), 316 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h index c2f7f78a4..5e9d7225e 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h @@ -93,7 +93,7 @@ namespace bulkio { // // OutputStream class // - typedef OutputStream StreamType; + typedef typename OutStreamTraits::OutStreamType StreamType; // // ConnectionList Definition @@ -282,7 +282,7 @@ namespace bulkio { // // Sends data and metadata to all connections enabled for the given stream // - friend class OutputStream; + friend class OutputStreamBase; void _sendPacket(const SharedBufferType& data, const BULKIO::PrecisionUTCTime& T, bool EOS, diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp index fe01ea6c3..e490c4ef2 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp @@ -25,12 +25,16 @@ using bulkio::OutputStreamBase; -class OutputStreamBase::Impl { +template +class OutputStreamBase::Impl { public: - Impl(const BULKIO::StreamSRI& sri) : + typedef typename PortTraits::SharedBufferType SharedBufferType; + + Impl(const BULKIO::StreamSRI& sri, OutPortType* port) : _streamID(sri.streamID), _sri(sri), - _modcount(0) + _modcount(0), + _port(port) { } @@ -40,6 +44,9 @@ class OutputStreamBase::Impl { virtual void close() { + // Send an empty packet with an end-of-stream marker; since there is no + // sample data, the timestamp does not matter + _send(SharedBufferType(), bulkio::time::utils::notSet(), true); } const std::string& streamID() const @@ -97,6 +104,11 @@ class OutputStreamBase::Impl { ++_modcount; } + virtual void write(const SharedBufferType& data, const BULKIO::PrecisionUTCTime& time) + { + _send(data, time, false); + } + int modcount() const { return _modcount; @@ -118,108 +130,140 @@ class OutputStreamBase::Impl { } } + void _send(const SharedBufferType& data, const BULKIO::PrecisionUTCTime& time, bool eos) + { + _port->_sendPacket(data, time, eos, _streamID); + } + const std::string _streamID; BULKIO::StreamSRI _sri; int _modcount; + OutPortType* _port; }; -OutputStreamBase::OutputStreamBase() : +template +OutputStreamBase::OutputStreamBase() : _impl() { } -OutputStreamBase::OutputStreamBase(boost::shared_ptr impl) : +template +OutputStreamBase::OutputStreamBase(boost::shared_ptr impl) : _impl(impl) { } -const std::string& OutputStreamBase::streamID() const +template +const std::string& OutputStreamBase::streamID() const { return _impl->streamID(); } -const BULKIO::StreamSRI& OutputStreamBase::sri() const +template +const BULKIO::StreamSRI& OutputStreamBase::sri() const { return _impl->sri(); } -void OutputStreamBase::sri(const BULKIO::StreamSRI& sri) +template +void OutputStreamBase::sri(const BULKIO::StreamSRI& sri) { _impl->setSRI(sri); } -double OutputStreamBase::xdelta() const +template +double OutputStreamBase::xdelta() const { return sri().xdelta; } -void OutputStreamBase::xdelta(double delta) +template +void OutputStreamBase::xdelta(double delta) { _impl->setXDelta(delta); } -bool OutputStreamBase::complex() const +template +bool OutputStreamBase::complex() const { return (sri().mode != 0); } -void OutputStreamBase::complex(bool mode) +template +void OutputStreamBase::complex(bool mode) { _impl->setComplex(mode); } -bool OutputStreamBase::blocking() const +template +bool OutputStreamBase::blocking() const { return sri().blocking; } -void OutputStreamBase::blocking(bool mode) +template +void OutputStreamBase::blocking(bool mode) { _impl->setBlocking(mode); } -const redhawk::PropertyMap& OutputStreamBase::keywords() const +template +const redhawk::PropertyMap& OutputStreamBase::keywords() const { return redhawk::PropertyMap::cast(sri().keywords); } -bool OutputStreamBase::hasKeyword(const std::string& name) const +template +bool OutputStreamBase::hasKeyword(const std::string& name) const { return keywords().contains(name); } -const redhawk::Value& OutputStreamBase::getKeyword(const std::string& name) const +template +const redhawk::Value& OutputStreamBase::getKeyword(const std::string& name) const { return keywords()[name]; } -void OutputStreamBase::keywords(const _CORBA_Unbounded_Sequence& props) +template +void OutputStreamBase::keywords(const _CORBA_Unbounded_Sequence& props) { _impl->setKeywords(props); } -void OutputStreamBase::setKeyword(const std::string& name, const CORBA::Any& value) +template +void OutputStreamBase::setKeyword(const std::string& name, const CORBA::Any& value) { _impl->setKeyword(name, value); } -void OutputStreamBase::setKeyword(const std::string& name, const redhawk::Value& value) +template +void OutputStreamBase::setKeyword(const std::string& name, const redhawk::Value& value) { _impl->setKeyword(name, value); } -void OutputStreamBase::eraseKeyword(const std::string& name) +template +void OutputStreamBase::eraseKeyword(const std::string& name) { _impl->eraseKeyword(name); } -void OutputStreamBase::close() +template +void OutputStreamBase::close() { _impl->close(); _impl.reset(); } -int OutputStreamBase::modcount() const +template +OutputStreamBase::operator unspecified_bool_type() const +{ + return _impl?&OutputStreamBase::_impl:0; +} + +template +int OutputStreamBase::modcount() const { return _impl->modcount(); } @@ -228,390 +272,311 @@ int OutputStreamBase::modcount() const using bulkio::OutputStream; template -class OutputStream::Impl : public OutputStreamBase::Impl { +class OutputStream::Impl : public Base::Impl { public: - typedef typename OutputStream::ScalarBuffer ScalarBuffer; - typedef typename OutputStream::ComplexBuffer ComplexBuffer; - - Impl(const BULKIO::StreamSRI& sri, OutPortType* port) : - OutputStreamBase::Impl(sri), - _port(port), - _bufferSize(0), - _bufferOffset(0) - { - } - - void write(const ScalarBuffer& data, const BULKIO::PrecisionUTCTime& time) - { - // If buffering is disabled, or the buffer is empty and the input data is - // large enough for a full buffer, send it immediately - if ((_bufferSize == 0) || (_bufferOffset == 0 && (data.size() >= _bufferSize))) { - _send(data, time, false); - } else { - _doBuffer(data, time); + typedef typename Base::Impl ImplBase; + + typedef typename OutputStream::ScalarBuffer ScalarBuffer; + typedef typename OutputStream::ComplexBuffer ComplexBuffer; + + using ImplBase::_sri; + using ImplBase::_streamID; + using ImplBase::_port; + + Impl(const BULKIO::StreamSRI& sri, OutPortType* port) : + ImplBase::Impl(sri, port), + _bufferSize(0), + _bufferOffset(0) + { } - } - void write(const ComplexBuffer& data, const BULKIO::PrecisionUTCTime& time) - { - if (_sri.mode == 0) { - throw std::logic_error("stream mode is not complex"); + void write(const ScalarBuffer& data, const BULKIO::PrecisionUTCTime& time) + { + // If buffering is disabled, or the buffer is empty and the input data is + // large enough for a full buffer, send it immediately + if ((_bufferSize == 0) || (_bufferOffset == 0 && (data.size() >= _bufferSize))) { + ImplBase::write(data, time); + } else { + _doBuffer(data, time); + } } - write(ScalarBuffer::recast(data), time); - } - - template - void write(const redhawk::shared_buffer& data, const std::list& times) - { - std::list::const_iterator timestamp = times.begin(); - if (timestamp == times.end()) { - throw std::logic_error("no timestamps given"); + + void write(const ComplexBuffer& data, const BULKIO::PrecisionUTCTime& time) + { + if (_sri.mode == 0) { + throw std::logic_error("stream mode is not complex"); + } + write(ScalarBuffer::recast(data), time); } - size_t first = 0; - while (first < data.size()) { - size_t last = 0; - const BULKIO::PrecisionUTCTime& when = timestamp->time; - if (++timestamp == times.end()) { - last = data.size(); - } else { - last = timestamp->offset; - } - write(data.slice(first, last), when); - first = last; + template + void write(const redhawk::shared_buffer& data, const std::list& times) + { + std::list::const_iterator timestamp = times.begin(); + if (timestamp == times.end()) { + throw std::logic_error("no timestamps given"); + } + + size_t first = 0; + while (first < data.size()) { + size_t last = 0; + const BULKIO::PrecisionUTCTime& when = timestamp->time; + if (++timestamp == times.end()) { + last = data.size(); + } else { + last = timestamp->offset; + } + write(data.slice(first, last), when); + first = last; + } } - } - - size_t bufferSize() const - { - return _bufferSize; - } - - void setBufferSize(size_t samples) - { - // Avoid needless thrashing - if (samples == _bufferSize) { - return; + + size_t bufferSize() const + { + return _bufferSize; } - _bufferSize = samples; - - // If the new buffer size is less than the currently buffered data, flush - if (_bufferSize < _bufferOffset) { - flush(); - } else if (_bufferSize > _buffer.size()) { - // The buffer size is increasing beyond the existing allocation; allocate - // a new buffer of the desired size and copy existing data - redhawk::buffer new_buffer(_bufferSize); - if (_bufferOffset > 0) { - std::copy(&_buffer[0], &_buffer[_bufferOffset], &new_buffer[0]); - } - - // Replace the old buffer with the new one - _buffer.swap(new_buffer); + + void setBufferSize(size_t samples) + { + // Avoid needless thrashing + if (samples == _bufferSize) { + return; + } + _bufferSize = samples; + + // If the new buffer size is less than the currently buffered data, flush + if (_bufferSize < _bufferOffset) { + flush(); + } else if (_bufferSize > _buffer.size()) { + // The buffer size is increasing beyond the existing allocation; allocate + // a new buffer of the desired size and copy existing data + redhawk::buffer new_buffer(_bufferSize); + if (_bufferOffset > 0) { + std::copy(&_buffer[0], &_buffer[_bufferOffset], &new_buffer[0]); + } + + // Replace the old buffer with the new one + _buffer.swap(new_buffer); + } } - } - void flush() - { - if (_bufferOffset == 0) { - return; + void flush() + { + if (_bufferOffset == 0) { + return; + } + + _flush(false); } - _flush(false); - } - - virtual void close() - { - if (_bufferOffset > 0) { - // Add the end-of-stream marker to the buffered data and its timestamp - _flush(true); - } else { - // Send an empty packet with an end-of-stream marker; since there is no - // sample data, the timestamp does not matter - _send(ScalarBuffer(), bulkio::time::utils::notSet(), true); + virtual void close() + { + if (_bufferOffset > 0) { + // Add the end-of-stream marker to the buffered data and its timestamp + _flush(true); + } else { + ImplBase::close(); + } } - } private: - void _send(const ScalarBuffer& data, const BULKIO::PrecisionUTCTime& time, bool eos) - { - _port->_sendPacket(data, time, eos, _streamID); - } - - virtual void _modifyingStreamMetadata() - { - // Flush any data queued with the old SRI - flush(); - } - - void _flush(bool eos) - { - // Push out all buffered data, which must be less than the full allocated - // size otherwise it would have already been sent - _send(_buffer.slice(0, _bufferOffset), _bufferTime, eos); - - // Allocate a new buffer and reset the offset index - _buffer = redhawk::buffer(_bufferSize); - _bufferOffset = 0; - } - - void _doBuffer(const ScalarBuffer& data, const BULKIO::PrecisionUTCTime& time) - { - // If this is the first data being queued, use its timestamp for the start - // time of the buffered data - if (_bufferOffset == 0) { - _bufferTime = time; + virtual void _modifyingStreamMetadata() + { + // Flush any data queued with the old SRI + flush(); } - // Only buffer up to the currently configured buffer size - size_t count = std::min(data.size(), _bufferSize - _bufferOffset); - std::copy(&data[0], &data[count], &_buffer[_bufferOffset]); + void _flush(bool eos) + { + // Push out all buffered data, which must be less than the full allocated + // size otherwise it would have already been sent + _send(_buffer.slice(0, _bufferOffset), _bufferTime, eos); - // Advance buffer offset, flushing if the buffer is full - _bufferOffset += count; - if (_bufferOffset >= _bufferSize) { - _flush(false); + // Allocate a new buffer and reset the offset index + _buffer = redhawk::buffer(_bufferSize); + _bufferOffset = 0; } - // Handle remaining data - if (count < data.size()) { - BULKIO::PrecisionUTCTime next = time + (_sri.xdelta * count); - _doBuffer(data.slice(count), next); - } - } + void _doBuffer(const ScalarBuffer& data, const BULKIO::PrecisionUTCTime& time) + { + // If this is the first data being queued, use its timestamp for the start + // time of the buffered data + if (_bufferOffset == 0) { + _bufferTime = time; + } + + // Only buffer up to the currently configured buffer size + size_t count = std::min(data.size(), _bufferSize - _bufferOffset); + std::copy(&data[0], &data[count], &_buffer[_bufferOffset]); - OutPortType* _port; + // Advance buffer offset, flushing if the buffer is full + _bufferOffset += count; + if (_bufferOffset >= _bufferSize) { + _flush(false); + } + + // Handle remaining data + if (count < data.size()) { + BULKIO::PrecisionUTCTime next = time + (_sri.xdelta * count); + _doBuffer(data.slice(count), next); + } + } - redhawk::buffer _buffer; - BULKIO::PrecisionUTCTime _bufferTime; - size_t _bufferSize; - size_t _bufferOffset; + redhawk::buffer _buffer; + BULKIO::PrecisionUTCTime _bufferTime; + size_t _bufferSize; + size_t _bufferOffset; }; template OutputStream::OutputStream() : - OutputStreamBase() + Base() { } template OutputStream::OutputStream(const BULKIO::StreamSRI& sri, OutPortType* port) : - OutputStreamBase(boost::make_shared(sri, port)) + Base(boost::make_shared(sri, port)) { } template size_t OutputStream::bufferSize() const { - return impl().bufferSize(); + return impl().bufferSize(); } template void OutputStream::setBufferSize(size_t samples) { - impl().setBufferSize(samples); + impl().setBufferSize(samples); } template void OutputStream::flush() { - impl().flush(); + impl().flush(); } template void OutputStream::write(const ScalarBuffer& data, const BULKIO::PrecisionUTCTime& time) { - impl().write(data, time); + impl().write(data, time); } template void OutputStream::write(const ScalarBuffer& data, const std::list& times) { - impl().write(data, times); + impl().write(data, times); } template void OutputStream::write(const ComplexBuffer& data, const BULKIO::PrecisionUTCTime& time) { - impl().write(data, time); + impl().write(data, time); } template void OutputStream::write(const ComplexBuffer& data, const std::list& times) { - impl().write(data, times); + impl().write(data, times); } template void OutputStream::write(const ScalarType* data, size_t count, const BULKIO::PrecisionUTCTime& time) { - impl().write(ScalarBuffer::make_transient(data, count), time); + impl().write(ScalarBuffer::make_transient(data, count), time); } template void OutputStream::write(const ScalarType* data, size_t count, const std::list& times) { - impl().write(ScalarBuffer::make_transient(data, count), times); + impl().write(ScalarBuffer::make_transient(data, count), times); } template void OutputStream::write(const ComplexType* data, size_t count, const BULKIO::PrecisionUTCTime& time) { - impl().write(ComplexBuffer::make_transient(data, count), time); + impl().write(ComplexBuffer::make_transient(data, count), time); } template void OutputStream::write(const ComplexType* data, size_t count, const std::list& times) { - impl().write(ComplexBuffer::make_transient(data, count), times); + impl().write(ComplexBuffer::make_transient(data, count), times); } template typename OutputStream::Impl& OutputStream::impl() { - return static_cast(*_impl); + return static_cast(*this->_impl); } template const typename OutputStream::Impl& OutputStream::impl() const { - return static_cast(*_impl); -} - -template -OutputStream::operator unspecified_bool_type() const -{ - return _impl?static_cast(&OutputStream::impl):0; + return static_cast(*this->_impl); } // // XML // -using bulkio::XMLPortTraits; - -class OutputStream::Impl : public OutputStreamBase::Impl { -public: - Impl(const BULKIO::StreamSRI& sri, OutPortType* port) : - OutputStreamBase::Impl(sri), - _port(port) - { - } - - void write(const std::string& data) - { - _send(data, false); - } - - virtual void close() - { - // Send an empty packet with an end-of-stream marker - _send(std::string(), true); - } +using bulkio::OutXMLStream; -private: - void _send(const std::string& data, bool eos) - { - // XML ports do not officially support timestamps, although the port - // implementation includes it (because it's templatized); always pass - // "not set" for consistency - _port->_sendPacket(data, bulkio::time::utils::notSet(), eos, _streamID); - } - - OutPortType* _port; -}; - -OutputStream::OutputStream() : - OutputStreamBase() +OutXMLStream::OutXMLStream() : + Base() { } -OutputStream::OutputStream(const BULKIO::StreamSRI& sri, OutPortType* port) : - OutputStreamBase(boost::make_shared(sri, port)) +OutXMLStream::OutXMLStream(const BULKIO::StreamSRI& sri, OutPortType* port) : + Base(sri, port) { } -void OutputStream::write(const std::string& xmlString) +void OutXMLStream::write(const std::string& xmlString) { - impl().write(xmlString); -} - -OutputStream::Impl& OutputStream::impl() -{ - return static_cast(*_impl); -} - -OutputStream::operator unspecified_bool_type() const -{ - return _impl?&OutputStream::impl:0; + // XML ports do not officially support timestamps, although the port + // implementation includes it (because it's templatized); always pass + // "not set" for consistency + _impl->write(xmlString, bulkio::time::utils::notSet()); } // // File // -using bulkio::FilePortTraits; +using bulkio::OutFileStream; -class OutputStream::Impl : public OutputStreamBase::Impl { -public: - Impl(const BULKIO::StreamSRI& sri, OutPortType* port) : - OutputStreamBase::Impl(sri), - _port(port) - { - } - - void write(const std::string& data, const BULKIO::PrecisionUTCTime& time) - { - _send(data, time, false); - } - - virtual void close() - { - // Send an empty packet with an end-of-stream marker; since there is no - // sample data, the timestamp does not matter - _send(std::string(), bulkio::time::utils::notSet(), true); - } - -private: - void _send(const std::string& data, const BULKIO::PrecisionUTCTime& time, bool eos) - { - _port->_sendPacket(data, time, eos, _streamID); - } - - OutPortType* _port; -}; - -OutputStream::OutputStream() : - OutputStreamBase() +OutFileStream::OutFileStream() : + Base() { } -OutputStream::OutputStream(const BULKIO::StreamSRI& sri, OutPortType* port) : - OutputStreamBase(boost::make_shared(sri, port)) +OutFileStream::OutFileStream(const BULKIO::StreamSRI& sri, OutPortType* port) : + Base(sri, port) { } -void OutputStream::write(const std::string& URL, const BULKIO::PrecisionUTCTime& time) +void OutFileStream::write(const std::string& URL, const BULKIO::PrecisionUTCTime& time) { - impl().write(URL, time); + _impl->write(URL, time); } -OutputStream::Impl& OutputStream::impl() -{ - return static_cast(*_impl); -} +#define INSTANTIATE_TEMPLATE(x) \ + template class OutputStreamBase; -OutputStream::operator unspecified_bool_type() const -{ - return _impl?&OutputStream::impl:0; -} +#define INSTANTIATE_NUMERIC_TEMPLATE(x) \ + INSTANTIATE_TEMPLATE(x); template class OutputStream; -template class OutputStream; -template class OutputStream; -template class OutputStream; -template class OutputStream; -template class OutputStream; -template class OutputStream; -template class OutputStream; -template class OutputStream; -template class OutputStream; -template class OutputStream; +INSTANTIATE_NUMERIC_TEMPLATE(bulkio::CharPortTraits); +INSTANTIATE_NUMERIC_TEMPLATE(bulkio::OctetPortTraits); +INSTANTIATE_NUMERIC_TEMPLATE(bulkio::ShortPortTraits); +INSTANTIATE_NUMERIC_TEMPLATE(bulkio::UShortPortTraits); +INSTANTIATE_NUMERIC_TEMPLATE(bulkio::LongPortTraits); +INSTANTIATE_NUMERIC_TEMPLATE(bulkio::ULongPortTraits); +INSTANTIATE_NUMERIC_TEMPLATE(bulkio::LongLongPortTraits); +INSTANTIATE_NUMERIC_TEMPLATE(bulkio::ULongLongPortTraits); +INSTANTIATE_NUMERIC_TEMPLATE(bulkio::FloatPortTraits); +INSTANTIATE_NUMERIC_TEMPLATE(bulkio::DoublePortTraits); +INSTANTIATE_TEMPLATE(bulkio::XMLPortTraits); +INSTANTIATE_TEMPLATE(bulkio::FilePortTraits); diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h index 455ca3dcb..4a2e4437d 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h @@ -37,6 +37,7 @@ namespace bulkio { template class OutPort; + template class OutputStreamBase { public: const std::string& streamID() const; @@ -75,18 +76,27 @@ namespace bulkio { } protected: + typedef OutPort OutPortType; + class Impl; OutputStreamBase(); + OutputStreamBase(const BULKIO::StreamSRI& sri, OutPortType* port); OutputStreamBase(boost::shared_ptr impl); int modcount() const; boost::shared_ptr _impl; + + typedef boost::shared_ptr OutputStreamBase::*unspecified_bool_type; + + public: + operator unspecified_bool_type() const; }; + template - class OutputStream : public OutputStreamBase { + class OutputStream : public OutputStreamBase { public: typedef typename PortTraits::DataTransferTraits::NativeDataType ScalarType; typedef std::complex ComplexType; @@ -169,6 +179,8 @@ namespace bulkio { void write(const ComplexType* data, size_t count, const std::list& times); private: + typedef OutputStreamBase Base; + friend class OutPort; typedef OutPort OutPortType; OutputStream(const BULKIO::StreamSRI& sri, OutPortType* port); @@ -176,18 +188,12 @@ namespace bulkio { class Impl; Impl& impl(); const Impl& impl() const; - - typedef const OutputStream::Impl& (OutputStream::*unspecified_bool_type)() const; - - public: - operator unspecified_bool_type() const; }; - template <> - class OutputStream : public OutputStreamBase { + class OutXMLStream : public OutputStreamBase { public: - OutputStream(); + OutXMLStream(); /** * @brief Write XML data to the stream. @@ -196,24 +202,17 @@ namespace bulkio { void write(const std::string& xmlString); private: + typedef OutputStreamBase Base; + friend class OutPort; typedef OutPort OutPortType; - OutputStream(const BULKIO::StreamSRI& sri, OutPortType* port); - - class Impl; - Impl& impl(); - - typedef OutputStream::Impl& (OutputStream::*unspecified_bool_type)(); - - public: - operator unspecified_bool_type() const; + OutXMLStream(const BULKIO::StreamSRI& sri, OutPortType* port); }; - template <> - class OutputStream : public OutputStreamBase { + class OutFileStream : public OutputStreamBase { public: - OutputStream(); + OutFileStream(); /** * @brief Write a file URI to the stream. @@ -222,17 +221,11 @@ namespace bulkio { void write(const std::string& URL, const BULKIO::PrecisionUTCTime& time); private: + typedef OutputStreamBase Base; + friend class OutPort; typedef OutPort OutPortType; - OutputStream(const BULKIO::StreamSRI& sri, OutPortType* port); - - class Impl; - Impl& impl(); - - typedef OutputStream::Impl& (OutputStream::*unspecified_bool_type)(); - - public: - operator unspecified_bool_type() const; + OutFileStream(const BULKIO::StreamSRI& sri, OutPortType* port); }; typedef OutputStream OutCharStream; @@ -245,8 +238,22 @@ namespace bulkio { typedef OutputStream OutULongLongStream; typedef OutputStream OutFloatStream; typedef OutputStream OutDoubleStream; - typedef OutputStream OutXMLStream; - typedef OutputStream OutFileStream; + + template + struct OutStreamTraits + { + typedef OutputStream OutStreamType; + }; + + template <> + struct OutStreamTraits { + typedef OutXMLStream OutStreamType; + }; + + template <> + struct OutStreamTraits { + typedef OutFileStream OutStreamType; + }; } // end of bulkio namespace From 647457ce7f63f8bcd11ae530cee760c80d71fcc8 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 2 Dec 2016 14:09:49 -0500 Subject: [PATCH 0589/1644] Wrap shared_ptr to BULKIO::StreamSRI objects in a SharedSRI class to avoid exposing shared_ptr in public interfaces; create a derived SRI class that follows that pattern of PropertyMap for extending the API of a CORBA structure --- bulkioInterfaces/libsrc/Makefile.am | 1 + bulkioInterfaces/libsrc/cpp/bulkio.cpp | 2 +- .../libsrc/cpp/bulkio_datablock.cpp | 29 ++--- .../libsrc/cpp/bulkio_datablock.h | 11 +- .../libsrc/cpp/bulkio_in_port.cpp | 18 +-- bulkioInterfaces/libsrc/cpp/bulkio_in_port.h | 9 +- .../libsrc/cpp/bulkio_in_stream.cpp | 24 ++-- .../libsrc/cpp/bulkio_in_stream.h | 4 +- bulkioInterfaces/libsrc/cpp/bulkio_sri.h | 103 ++++++++++++++++++ bulkioInterfaces/libsrc/cpp/bulkio_traits.h | 6 +- 10 files changed, 154 insertions(+), 53 deletions(-) create mode 100644 bulkioInterfaces/libsrc/cpp/bulkio_sri.h diff --git a/bulkioInterfaces/libsrc/Makefile.am b/bulkioInterfaces/libsrc/Makefile.am index 772cb84af..fcf5d8ecd 100644 --- a/bulkioInterfaces/libsrc/Makefile.am +++ b/bulkioInterfaces/libsrc/Makefile.am @@ -61,6 +61,7 @@ library_include_HEADERS = cpp/bulkio.h \ cpp/bulkio_out_port.h \ cpp/bulkio_out_stream.h \ cpp/bulkio_attachable_base.h \ + cpp/bulkio_sri.h \ cpp/bulkio_time_operators.h \ cpp/bulkio_datablock.h \ cpp/bulkio_compat.h diff --git a/bulkioInterfaces/libsrc/cpp/bulkio.cpp b/bulkioInterfaces/libsrc/cpp/bulkio.cpp index 7336576a4..d5693a1b5 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio.cpp @@ -247,7 +247,7 @@ namespace bulkio { template < typename DataTransferTraits > - DataTransfer< DataTransferTraits >::DataTransfer(const PortSequenceType& data, const BULKIO::PrecisionUTCTime &_T, bool _EOS, const char* _streamID, BULKIO::StreamSRI &_H, bool _sriChanged, bool _inputQueueFlushed) : + DataTransfer< DataTransferTraits >::DataTransfer(const PortSequenceType& data, const BULKIO::PrecisionUTCTime &_T, bool _EOS, const char* _streamID, const BULKIO::StreamSRI &_H, bool _sriChanged, bool _inputQueueFlushed) : T(_T), EOS(_EOS), streamID(_streamID), diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_datablock.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_datablock.cpp index 395e5178e..2d23cff19 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_datablock.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_datablock.cpp @@ -25,6 +25,7 @@ #include "bulkio_base.h" #include "bulkio_datablock.h" +#include "bulkio_sri.h" #include "bulkio_time_operators.h" namespace bulkio { @@ -54,15 +55,7 @@ using bulkio::DataBlock; template struct DataBlock::Impl { - Impl(const boost::shared_ptr& sri) : - data(), - sri(sri), - sriChangeFlags(bulkio::sri::NONE), - inputQueueFlushed(false) - { - } - - Impl(const boost::shared_ptr& sri, const T& data) : + Impl(const bulkio::SharedSRI& sri, const T& data) : data(data), sri(sri), sriChangeFlags(bulkio::sri::NONE), @@ -71,7 +64,7 @@ struct DataBlock::Impl } T data; - boost::shared_ptr sri; + bulkio::SharedSRI sri; std::list timestamps; int sriChangeFlags; bool inputQueueFlushed; @@ -84,7 +77,7 @@ DataBlock::DataBlock() : } template -DataBlock::DataBlock(const boost::shared_ptr& sri, const T& data) : +DataBlock::DataBlock(const bulkio::SharedSRI& sri, const T& data) : _impl(boost::make_shared(sri, data)) { } @@ -100,7 +93,7 @@ DataBlock DataBlock::copy() const } template -const BULKIO::StreamSRI& DataBlock::sri() const +const bulkio::SRI& DataBlock::sri() const { return *(_impl->sri); } @@ -108,7 +101,7 @@ const BULKIO::StreamSRI& DataBlock::sri() const template double DataBlock::xdelta() const { - return _impl->sri->xdelta; + return sri().xdelta; } template @@ -150,7 +143,7 @@ double DataBlock::getNetTimeDrift() const const std::list& timestamps = _impl->timestamps; validate_timestamps(timestamps); - return get_drift(timestamps.front(), timestamps.back(), _impl->sri->xdelta); + return get_drift(timestamps.front(), timestamps.back(), xdelta()); } template @@ -164,7 +157,7 @@ double DataBlock::getMaxTimeDrift() const std::list::const_iterator next = current; ++next; for (; next != timestamps.end(); ++current, ++next) { - double drift = get_drift(*current, *next, _impl->sri->xdelta); + double drift = get_drift(*current, *next, xdelta()); if (std::abs(drift) > std::abs(max)) { max = drift; } @@ -217,7 +210,7 @@ SampleDataBlock::SampleDataBlock() : } template -SampleDataBlock::SampleDataBlock(const boost::shared_ptr& sri, +SampleDataBlock::SampleDataBlock(const bulkio::SharedSRI& sri, const ScalarBuffer& buffer) : Base(sri, buffer) { @@ -225,7 +218,7 @@ SampleDataBlock::SampleDataBlock(const boost::shared_ptr& template SampleDataBlock::SampleDataBlock(const BULKIO::StreamSRI& sri, size_t size) : - Base(boost::make_shared(sri), redhawk::buffer(size)) + Base(bulkio::SharedSRI(sri), redhawk::buffer(size)) { } @@ -257,7 +250,7 @@ void SampleDataBlock::resize(size_t count) template bool SampleDataBlock::complex() const { - return (_impl->sri->mode != 0); + return this->sri().complex(); } template diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_datablock.h b/bulkioInterfaces/libsrc/cpp/bulkio_datablock.h index 90be45071..ec51645f9 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_datablock.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_datablock.h @@ -30,8 +30,12 @@ #include + namespace bulkio { + class SRI; + class SharedSRI; + struct SampleTimestamp { SampleTimestamp(const BULKIO::PrecisionUTCTime& time, size_t offset=0, bool synthetic=false) : @@ -51,11 +55,11 @@ namespace bulkio { { public: DataBlock(); - DataBlock(const boost::shared_ptr& sri, const T& buffer); + DataBlock(const SharedSRI& sri, const T& buffer); DataBlock copy() const; - const BULKIO::StreamSRI& sri() const; + const SRI& sri() const; double xdelta() const; const T& data() const; @@ -98,8 +102,7 @@ namespace bulkio { typedef redhawk::shared_buffer ComplexBuffer; SampleDataBlock(); - explicit SampleDataBlock(const boost::shared_ptr& sri, - const ScalarBuffer& buffer=ScalarBuffer()); + explicit SampleDataBlock(const SharedSRI& sri, const ScalarBuffer& buffer=ScalarBuffer()); SampleDataBlock(const BULKIO::StreamSRI& sri, size_t size=0); SampleDataBlock copy() const; diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp index b6a5ddaf6..d5184657a 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp @@ -172,9 +172,10 @@ namespace bulkio { SriTable::iterator currH = currentHs.find(streamID); if (currH == currentHs.end()) { LOG_DEBUG(logger,"pushSRI PORT:" << name << " NEW SRI:" << streamID << " Mode:" << H.mode ); - boost::shared_ptr sri = boost::make_shared(H); + SharedSRI sri(H); if (newStreamCallback) { - newStreamCallback(*sri); + // The callback takes a non-const SRI, so allow access via const_cast + newStreamCallback(const_cast(*sri)); } currentHs[streamID] = std::make_pair(sri, true); lock.unlock(); @@ -183,7 +184,7 @@ namespace bulkio { } else { if (sri_cmp && !sri_cmp(H, *(currH->second.first))) { LOG_DEBUG(logger,"pushSRI PORT:" << name << " SAME SRI:" << streamID << " Mode:" << H.mode ); - currH->second.first = boost::make_shared(H); + currH->second.first = SharedSRI(H); currH->second.second = true; } } @@ -210,7 +211,7 @@ namespace bulkio { return; } - boost::shared_ptr sri; + SharedSRI sri; bool sriChanged = false; { @@ -226,9 +227,10 @@ namespace bulkio { // and set the SRI changed flag LOG_WARN(logger, "InPort::pushPacket received data for stream '" << streamID << "' with no SRI"); sriChanged = true; - sri = boost::make_shared(bulkio::sri::create(streamID)); + sri = SharedSRI(bulkio::sri::create(streamID)); if (newStreamCallback) { - newStreamCallback(*sri); + // The callback takes a non-const SRI, so allow access via const_cast + newStreamCallback(const_cast(*sri)); } currentHs[streamID] = std::make_pair(sri, false); lock.unlock(); @@ -528,7 +530,7 @@ namespace bulkio { template < typename PortTraits > void InPort< PortTraits >::createStream(const std::string& streamID, - const boost::shared_ptr& sri) + const bulkio::SharedSRI& sri) { StreamType stream(sri, this); boost::mutex::scoped_lock lock(streamsMutex); @@ -614,7 +616,7 @@ namespace bulkio { if (!firstPacket) break; } firstPacket = false; - if (packet->SRI->mode) { + if (packet->SRI->complex()) { item_size = 2; } samples += packet->buffer.size(); diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h index 12c67da6f..ae84782f1 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h @@ -32,6 +32,7 @@ #include "bulkio_base.h" #include "bulkio_traits.h" #include "bulkio_in_stream.h" +#include "bulkio_sri.h" #include "bulkio_callbacks.h" namespace bulkio { @@ -265,7 +266,7 @@ namespace bulkio { SriListener *newStreamCB = NULL ); struct Packet { - Packet(const SharedBufferType& buffer, const BULKIO::PrecisionUTCTime& T, bool EOS, const boost::shared_ptr& SRI, bool sriChanged, bool inputQueueFlushed) : + Packet(const SharedBufferType& buffer, const BULKIO::PrecisionUTCTime& T, bool EOS, const SharedSRI& SRI, bool sriChanged, bool inputQueueFlushed) : buffer(buffer), T(T), EOS(EOS), @@ -279,7 +280,7 @@ namespace bulkio { SharedBufferType buffer; BULKIO::PrecisionUTCTime T; bool EOS; - boost::shared_ptr SRI; + SharedSRI SRI; bool sriChanged; bool inputQueueFlushed; std::string streamID; @@ -304,7 +305,7 @@ namespace bulkio { // // List of SRI objects managed by StreamID // - typedef std::map,bool> > SriTable; + typedef std::map > SriTable; SriTable currentHs; // @@ -388,7 +389,7 @@ namespace bulkio { friend class InputStream; size_t samplesAvailable(const std::string& streamID, bool firstPacket); - void createStream(const std::string& streamID, const boost::shared_ptr& sri); + void createStream(const std::string& streamID, const SharedSRI& sri); void removeStream(const std::string& streamID); bool isStreamActive(const std::string& streamID); diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp index 8e329874b..bf7851192 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp @@ -40,7 +40,7 @@ class InputStream::Impl { EOS_REPORTED }; - Impl(const boost::shared_ptr& sri, InPortType* port) : + Impl(const bulkio::SharedSRI& sri, InPortType* port) : _streamID(sri->streamID), _sri(sri), _port(port), @@ -163,7 +163,7 @@ class InputStream::Impl { } const std::string _streamID; - boost::shared_ptr _sri; + bulkio::SharedSRI _sri; InPortType* _port; EosState _eosState; bool _enabled; @@ -176,8 +176,7 @@ InputStream::InputStream() : } template -InputStream::InputStream(const boost::shared_ptr& sri, - InPortType* port) : +InputStream::InputStream(const SharedSRI& sri, InPortType* port) : _impl(boost::make_shared(sri, port)) { } @@ -266,7 +265,7 @@ class BufferedInputStream::Impl : public Base::Impl { typedef typename PortTraits::NativeType NativeType; typedef typename PortTraits::SharedBufferType SharedBufferType; - Impl(const boost::shared_ptr& sri, InPortType* port) : + Impl(const bulkio::SharedSRI& sri, InPortType* port) : ImplBase(sri, port), _queue(), _pending(0), @@ -298,8 +297,7 @@ class BufferedInputStream::Impl : public Base::Impl { size_t queued = _samplesQueued; if (queued > 0) { // Adjust number of samples to account for complex data, if necessary - const BULKIO::StreamSRI& sri = *(_queue.front().SRI); - if (sri.mode) { + if (_queue.front().SRI->complex()) { queued /= 2; } } @@ -335,7 +333,7 @@ class BufferedInputStream::Impl : public Base::Impl { { // Try to get the SRI for the upcoming block of data, fetching it from the // port's input queue if necessary - const BULKIO::StreamSRI* sri = _nextSRI(blocking); + const SRI* sri = _nextSRI(blocking); if (!sri) { // No SRI retreived implies no data will be retrieved, either due to end- // of-stream or because it would block @@ -352,7 +350,7 @@ class BufferedInputStream::Impl : public Base::Impl { // If the next block of data is complex, double the read and consume size // (which the lower-level I/O handles in terms of scalars) so that the // returned block has the right number of samples - if (sri->mode == 1) { + if (sri->complex()) { count *= 2; consume *= 2; } @@ -395,12 +393,12 @@ class BufferedInputStream::Impl : public Base::Impl { // If the next block of data is complex, double the skip size (which the // lower-level I/O handles in terms of scalars) so that the right number of // samples is skipped - const BULKIO::StreamSRI* sri = _nextSRI(true); + const SRI* sri = _nextSRI(true); if (!sri) { return 0; } - size_t item_size = sri->mode?2:1; + size_t item_size = sri->complex()?2:1; count *= item_size; // Queue up packets from the port until we have enough data to satisfy the @@ -567,7 +565,7 @@ class BufferedInputStream::Impl : public Base::Impl { data.addTimestamp(bulkio::SampleTimestamp(time, output_offset, synthetic)); } - const BULKIO::StreamSRI* _nextSRI(bool blocking) + const SRI* _nextSRI(bool blocking) { if (_queue.empty()) { if (!_fetchPacket(blocking)) { @@ -641,7 +639,7 @@ BufferedInputStream::BufferedInputStream() : } template -BufferedInputStream::BufferedInputStream(const boost::shared_ptr& sri, InPortType* port) : +BufferedInputStream::BufferedInputStream(const bulkio::SharedSRI& sri, InPortType* port) : Base(boost::make_shared(sri, port)) { } diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.h b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.h index 7d5737ddb..40bc31979 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.h @@ -80,7 +80,7 @@ namespace bulkio { // Allow matching InPort class to create instances of this stream type friend class InPort; - InputStream(const boost::shared_ptr& sri, InPortType* port); + InputStream(const SharedSRI& sri, InPortType* port); bool hasBufferedData(); @@ -120,7 +120,7 @@ namespace bulkio { friend class InPort; typedef InPort InPortType; - BufferedInputStream(const boost::shared_ptr&, InPortType*); + BufferedInputStream(const SharedSRI&, InPortType*); class Impl; Impl& impl(); diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_sri.h b/bulkioInterfaces/libsrc/cpp/bulkio_sri.h new file mode 100644 index 000000000..ed61deb76 --- /dev/null +++ b/bulkioInterfaces/libsrc/cpp/bulkio_sri.h @@ -0,0 +1,103 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK bulkioInterfaces. + * + * REDHAWK bulkioInterfaces is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK bulkioInterfaces is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +#ifndef __bulkio_sri_h +#define __bulkio_sri_h + +#include +#include + +#include + +#include + +namespace bulkio { + + class SRI : public BULKIO::StreamSRI { + public: + static SRI& cast(BULKIO::StreamSRI& sri) + { + return static_cast(sri); + } + + static const SRI& cast(const BULKIO::StreamSRI& sri) + { + return static_cast(sri); + } + + explicit SRI(const BULKIO::StreamSRI& sri) : + BULKIO::StreamSRI(sri) + { + } + + std::string getStreamID() const + { + return std::string(this->streamID); + } + + bool complex() const + { + return (this->mode != 0); + } + + const redhawk::PropertyMap& getKeywords() const + { + return redhawk::PropertyMap::cast(this->keywords); + } + }; + + class SharedSRI { + public: + SharedSRI() : + _sri() + { + } + + SharedSRI(const BULKIO::StreamSRI& sri) : + _sri(boost::make_shared(sri)) + { + } + + const SRI* get() const + { + return _sri.get(); + } + + const SRI& operator* () const + { + return *_sri; + } + + const SRI* operator-> () const + { + return _sri.get(); + } + + bool operator! () const + { + return !_sri; + } + + private: + boost::shared_ptr _sri; + }; +} + +#endif // __bulkio_sri_h diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_traits.h b/bulkioInterfaces/libsrc/cpp/bulkio_traits.h index 1a6a434e7..d06a08c51 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_traits.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_traits.h @@ -103,7 +103,7 @@ struct DataTransfer { // // Construct a DataTransfer object to be returned from an InPort's getPacket method // - DataTransfer(const PortSequenceType& data, const BULKIO::PrecisionUTCTime &_T, bool _EOS, const char* _streamID, BULKIO::StreamSRI &_H, bool _sriChanged, bool _inputQueueFlushed); + DataTransfer(const PortSequenceType& data, const BULKIO::PrecisionUTCTime &_T, bool _EOS, const char* _streamID, const BULKIO::StreamSRI &_H, bool _sriChanged, bool _inputQueueFlushed); DataBufferType dataBuffer; BULKIO::PrecisionUTCTime T; @@ -132,7 +132,7 @@ struct DataTransfer< StringDataTransferTraits > typedef Traits::PortSequenceType PortSequenceType; typedef Traits::DataBufferType DataBufferType; - DataTransfer(const char *data, const BULKIO::PrecisionUTCTime &_T, bool _EOS, const char* _streamID, BULKIO::StreamSRI &_H, bool _sriChanged, bool _inputQueueFlushed) + DataTransfer(const char *data, const BULKIO::PrecisionUTCTime &_T, bool _EOS, const char* _streamID, const BULKIO::StreamSRI &_H, bool _sriChanged, bool _inputQueueFlushed) { if ( data != NULL ) dataBuffer = data; T = _T; @@ -142,7 +142,7 @@ struct DataTransfer< StringDataTransferTraits > sriChanged = _sriChanged; inputQueueFlushed = _inputQueueFlushed; } - DataTransfer(const char * data, bool _EOS, const char* _streamID, BULKIO::StreamSRI &_H, bool _sriChanged, bool _inputQueueFlushed) + DataTransfer(const char * data, bool _EOS, const char* _streamID, const BULKIO::StreamSRI &_H, bool _sriChanged, bool _inputQueueFlushed) { if ( data != NULL ) dataBuffer = data; EOS = _EOS; From 9327b45e77d68ea81b58568122ee2363d73f1093 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 5 Dec 2016 12:06:19 -0500 Subject: [PATCH 0590/1644] Create a BulkIO StreamBase class that provides common SRI accessor methods for input and output streams --- bulkioInterfaces/libsrc/Makefile.am | 1 + .../libsrc/cpp/bulkio_in_stream.cpp | 69 ++++------ .../libsrc/cpp/bulkio_in_stream.h | 15 +-- .../libsrc/cpp/bulkio_out_stream.cpp | 126 ++++++------------ .../libsrc/cpp/bulkio_out_stream.h | 29 ++-- bulkioInterfaces/libsrc/cpp/bulkio_sri.h | 47 +++++++ bulkioInterfaces/libsrc/cpp/bulkio_stream.cpp | 78 +++++++++++ 7 files changed, 212 insertions(+), 153 deletions(-) create mode 100644 bulkioInterfaces/libsrc/cpp/bulkio_stream.cpp diff --git a/bulkioInterfaces/libsrc/Makefile.am b/bulkioInterfaces/libsrc/Makefile.am index fcf5d8ecd..e7b960c6c 100644 --- a/bulkioInterfaces/libsrc/Makefile.am +++ b/bulkioInterfaces/libsrc/Makefile.am @@ -42,6 +42,7 @@ libbulkio_@BULKIO_API_VERSION@_la_SOURCES = \ cpp/bulkio_out_stream.cpp \ cpp/bulkio_attachable_port.cpp \ cpp/bulkio_sri_helpers.cpp \ + cpp/bulkio_stream.cpp \ cpp/bulkio_time_helpers.cpp \ cpp/bulkio_time_operators.cpp \ cpp/bulkio_datablock.cpp \ diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp index bf7851192..1d3530267 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp @@ -29,8 +29,10 @@ using bulkio::InputStream; template -class InputStream::Impl { +class InputStream::Impl : public StreamBase::Impl { public: + typedef StreamBase::Impl ImplBase; + typedef typename InPortType::Packet PacketType; enum EosState { @@ -41,24 +43,13 @@ class InputStream::Impl { }; Impl(const bulkio::SharedSRI& sri, InPortType* port) : - _streamID(sri->streamID), - _sri(sri), + ImplBase(sri), _port(port), _eosState(EOS_NONE), _enabled(true) { } - const std::string& streamID() const - { - return _streamID; - } - - const BULKIO::StreamSRI& sri() const - { - return *_sri; - } - DataBlockType readPacket(bool blocking) { boost::scoped_ptr packet(_fetchPacket(blocking)); @@ -162,8 +153,6 @@ class InputStream::Impl { } } - const std::string _streamID; - bulkio::SharedSRI _sri; InPortType* _port; EosState _eosState; bool _enabled; @@ -171,86 +160,80 @@ class InputStream::Impl { template InputStream::InputStream() : - _impl() + StreamBase() { } template InputStream::InputStream(const SharedSRI& sri, InPortType* port) : - _impl(boost::make_shared(sri, port)) + StreamBase(boost::make_shared(sri, port)) { } template InputStream::InputStream(const boost::shared_ptr& impl) : - _impl(impl) -{ -} - -template -const std::string& InputStream::streamID() const + StreamBase(impl) { - return _impl->streamID(); -} - -template -const BULKIO::StreamSRI& InputStream::sri() const -{ - return _impl->sri(); } template typename InputStream::DataBlockType InputStream::read() { - return _impl->readPacket(true); + return impl().readPacket(true); } template typename InputStream::DataBlockType InputStream::tryread() { - return _impl->readPacket(false); + return impl().readPacket(false); } template bool InputStream::enabled() const { - return _impl->enabled(); + return impl().enabled(); } template void InputStream::enable() { - _impl->enable(); + impl().enable(); } template void InputStream::disable() { - _impl->disable(); + impl().disable(); } template bool InputStream::eos() { - return _impl->eos(); + return impl().eos(); } template -bool InputStream::operator!() const +InputStream::operator unspecified_bool_type() const { - return !_impl; + return _impl?static_cast(&InputStream::impl):0; } template -InputStream::operator unspecified_bool_type() const +typename InputStream::Impl& InputStream::impl() +{ + return static_cast(*this->_impl); +} + +template +const typename InputStream::Impl& InputStream::impl() const { - return _impl?&InputStream::_impl:0; + return static_cast(*this->_impl); } template bool InputStream::hasBufferedData() { - return _impl->hasBufferedData(); + return impl().hasBufferedData(); } @@ -707,13 +690,13 @@ bool BufferedInputStream::ready() template typename BufferedInputStream::Impl& BufferedInputStream::impl() { - return static_cast(*_impl); + return static_cast(Base::impl()); } template const typename BufferedInputStream::Impl& BufferedInputStream::impl() const { - return static_cast(*_impl); + return static_cast(Base::impl()); } #define INSTANTIATE_TEMPLATE(x) \ diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.h b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.h index 40bc31979..87015e7ed 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.h @@ -28,6 +28,7 @@ #include "bulkio_traits.h" #include "bulkio_datablock.h" +#include "bulkio_sri.h" namespace bulkio { @@ -50,13 +51,10 @@ namespace bulkio { }; template - class InputStream { + class InputStream : public StreamBase { public: typedef typename BlockTraits::DataBlockType DataBlockType; - const std::string& streamID() const; - const BULKIO::StreamSRI& sri() const; - DataBlockType read(); DataBlockType tryread(); @@ -67,13 +65,14 @@ namespace bulkio { bool eos(); - bool operator! () const; - protected: typedef InPort InPortType; class Impl; - typedef boost::shared_ptr InputStream::*unspecified_bool_type; + Impl& impl(); + const Impl& impl() const; + + typedef const Impl& (InputStream::*unspecified_bool_type)() const; InputStream(); InputStream(const boost::shared_ptr& impl); @@ -84,8 +83,6 @@ namespace bulkio { bool hasBufferedData(); - boost::shared_ptr _impl; - public: operator unspecified_bool_type() const; }; diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp index e490c4ef2..db0c76e02 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp @@ -26,13 +26,13 @@ using bulkio::OutputStreamBase; template -class OutputStreamBase::Impl { +class OutputStreamBase::Impl : public StreamBase::Impl { public: + typedef StreamBase::Impl ImplBase; typedef typename PortTraits::SharedBufferType SharedBufferType; Impl(const BULKIO::StreamSRI& sri, OutPortType* port) : - _streamID(sri.streamID), - _sri(sri), + ImplBase(sri), _modcount(0), _port(port) { @@ -49,49 +49,44 @@ class OutputStreamBase::Impl { _send(SharedBufferType(), bulkio::time::utils::notSet(), true); } - const std::string& streamID() const + BULKIO::StreamSRI& sri() { - return _streamID; - } - - const BULKIO::StreamSRI& sri() const - { - return _sri; + return const_cast(*_sri); } void setXDelta(double delta) { - _setStreamMetadata(_sri.xdelta, delta); + _setStreamMetadata(sri().xdelta, delta); } void setComplex(bool mode) { - _setStreamMetadata(_sri.mode, mode?1:0); + _setStreamMetadata(sri().mode, mode?1:0); } void setBlocking(bool mode) { - _setStreamMetadata(_sri.blocking, mode?1:0); + _setStreamMetadata(sri().blocking, mode?1:0); } void setKeywords(const _CORBA_Unbounded_Sequence& properties) { _modifyingStreamMetadata(); - _sri.keywords = properties; + sri().keywords = properties; ++_modcount; } void setKeyword(const std::string& name, const CORBA::Any& value) { _modifyingStreamMetadata(); - redhawk::PropertyMap::cast(_sri.keywords)[name] = value; + redhawk::PropertyMap::cast(sri().keywords)[name] = value; ++_modcount; } void eraseKeyword(const std::string& name) { _modifyingStreamMetadata(); - redhawk::PropertyMap::cast(_sri.keywords).erase(name); + redhawk::PropertyMap::cast(sri().keywords).erase(name); ++_modcount; } @@ -99,8 +94,8 @@ class OutputStreamBase::Impl { { _modifyingStreamMetadata(); // Copy the new SRI, except for the stream ID, which is immutable - _sri = sri; - _sri.streamID = _streamID.c_str(); + this->sri() = sri; + this->sri().streamID = _streamID.c_str(); ++_modcount; } @@ -135,137 +130,105 @@ class OutputStreamBase::Impl { _port->_sendPacket(data, time, eos, _streamID); } - const std::string _streamID; - BULKIO::StreamSRI _sri; int _modcount; OutPortType* _port; }; template OutputStreamBase::OutputStreamBase() : - _impl() + StreamBase() { } template -OutputStreamBase::OutputStreamBase(boost::shared_ptr impl) : - _impl(impl) +OutputStreamBase::OutputStreamBase(const BULKIO::StreamSRI& sri, OutPortType* port) : + StreamBase(boost::make_shared(sri, port)) { } template -const std::string& OutputStreamBase::streamID() const -{ - return _impl->streamID(); -} - -template -const BULKIO::StreamSRI& OutputStreamBase::sri() const +OutputStreamBase::OutputStreamBase(boost::shared_ptr impl) : + StreamBase(impl) { - return _impl->sri(); } template void OutputStreamBase::sri(const BULKIO::StreamSRI& sri) { - _impl->setSRI(sri); -} - -template -double OutputStreamBase::xdelta() const -{ - return sri().xdelta; + impl().setSRI(sri); } template void OutputStreamBase::xdelta(double delta) { - _impl->setXDelta(delta); -} - -template -bool OutputStreamBase::complex() const -{ - return (sri().mode != 0); + impl().setXDelta(delta); } template void OutputStreamBase::complex(bool mode) { - _impl->setComplex(mode); -} - -template -bool OutputStreamBase::blocking() const -{ - return sri().blocking; + impl().setComplex(mode); } template void OutputStreamBase::blocking(bool mode) { - _impl->setBlocking(mode); + impl().setBlocking(mode); } template -const redhawk::PropertyMap& OutputStreamBase::keywords() const -{ - return redhawk::PropertyMap::cast(sri().keywords); -} - -template -bool OutputStreamBase::hasKeyword(const std::string& name) const +void OutputStreamBase::keywords(const _CORBA_Unbounded_Sequence& props) { - return keywords().contains(name); + impl().setKeywords(props); } template -const redhawk::Value& OutputStreamBase::getKeyword(const std::string& name) const +void OutputStreamBase::setKeyword(const std::string& name, const CORBA::Any& value) { - return keywords()[name]; + impl().setKeyword(name, value); } template -void OutputStreamBase::keywords(const _CORBA_Unbounded_Sequence& props) +void OutputStreamBase::setKeyword(const std::string& name, const redhawk::Value& value) { - _impl->setKeywords(props); + impl().setKeyword(name, value); } template -void OutputStreamBase::setKeyword(const std::string& name, const CORBA::Any& value) +void OutputStreamBase::eraseKeyword(const std::string& name) { - _impl->setKeyword(name, value); + impl().eraseKeyword(name); } template -void OutputStreamBase::setKeyword(const std::string& name, const redhawk::Value& value) +void OutputStreamBase::close() { - _impl->setKeyword(name, value); + impl().close(); + _impl.reset(); } template -void OutputStreamBase::eraseKeyword(const std::string& name) +OutputStreamBase::operator unspecified_bool_type() const { - _impl->eraseKeyword(name); + return _impl?static_cast(&OutputStreamBase::impl):0; } template -void OutputStreamBase::close() +typename OutputStreamBase::Impl& OutputStreamBase::impl() { - _impl->close(); - _impl.reset(); + return static_cast(*this->_impl); } template -OutputStreamBase::operator unspecified_bool_type() const +const typename OutputStreamBase::Impl& OutputStreamBase::impl() const { - return _impl?&OutputStreamBase::_impl:0; + return static_cast(*this->_impl); } template int OutputStreamBase::modcount() const { - return _impl->modcount(); + return impl().modcount(); } @@ -281,7 +244,6 @@ class OutputStream::Impl : public Base::Impl { using ImplBase::_sri; using ImplBase::_streamID; - using ImplBase::_port; Impl(const BULKIO::StreamSRI& sri, OutPortType* port) : ImplBase::Impl(sri, port), @@ -303,7 +265,7 @@ class OutputStream::Impl : public Base::Impl { void write(const ComplexBuffer& data, const BULKIO::PrecisionUTCTime& time) { - if (_sri.mode == 0) { + if (_sri->mode == 0) { throw std::logic_error("stream mode is not complex"); } write(ScalarBuffer::recast(data), time); @@ -417,7 +379,7 @@ class OutputStream::Impl : public Base::Impl { // Handle remaining data if (count < data.size()) { - BULKIO::PrecisionUTCTime next = time + (_sri.xdelta * count); + BULKIO::PrecisionUTCTime next = time + (_sri->xdelta * count); _doBuffer(data.slice(count), next); } } @@ -539,7 +501,7 @@ void OutXMLStream::write(const std::string& xmlString) // XML ports do not officially support timestamps, although the port // implementation includes it (because it's templatized); always pass // "not set" for consistency - _impl->write(xmlString, bulkio::time::utils::notSet()); + impl().write(xmlString, bulkio::time::utils::notSet()); } // @@ -559,7 +521,7 @@ OutFileStream::OutFileStream(const BULKIO::StreamSRI& sri, OutPortType* port) : void OutFileStream::write(const std::string& URL, const BULKIO::PrecisionUTCTime& time) { - _impl->write(URL, time); + impl().write(URL, time); } #define INSTANTIATE_TEMPLATE(x) \ diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h index 4a2e4437d..077fc9ac4 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h @@ -31,6 +31,7 @@ #include "bulkio_traits.h" #include "bulkio_datablock.h" +#include "bulkio_sri.h" namespace bulkio { @@ -38,26 +39,21 @@ namespace bulkio { class OutPort; template - class OutputStreamBase { + class OutputStreamBase : public StreamBase { public: - const std::string& streamID() const; - - const BULKIO::StreamSRI& sri() const; + using StreamBase::sri; void sri(const BULKIO::StreamSRI& sri); - double xdelta() const; + using StreamBase::xdelta; void xdelta(double xdelta); - bool complex() const; + using StreamBase::complex; void complex(bool mode); - bool blocking() const; + using StreamBase::blocking; void blocking(bool mode); - const redhawk::PropertyMap& keywords() const; - bool hasKeyword(const std::string& name) const; - const redhawk::Value& getKeyword(const std::string& name) const; - + using StreamBase::keywords; void keywords(const _CORBA_Unbounded_Sequence& props); void setKeyword(const std::string& name, const CORBA::Any& value); void setKeyword(const std::string& name, const redhawk::Value& value); @@ -70,15 +66,12 @@ namespace bulkio { void close(); - bool operator! () const - { - return !_impl; - } - protected: typedef OutPort OutPortType; class Impl; + Impl& impl(); + const Impl& impl() const; OutputStreamBase(); OutputStreamBase(const BULKIO::StreamSRI& sri, OutPortType* port); @@ -86,9 +79,7 @@ namespace bulkio { int modcount() const; - boost::shared_ptr _impl; - - typedef boost::shared_ptr OutputStreamBase::*unspecified_bool_type; + typedef const Impl& (OutputStreamBase::*unspecified_bool_type)() const; public: operator unspecified_bool_type() const; diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_sri.h b/bulkioInterfaces/libsrc/cpp/bulkio_sri.h index ed61deb76..cb0532b58 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_sri.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_sri.h @@ -98,6 +98,53 @@ namespace bulkio { private: boost::shared_ptr _sri; }; + + class StreamBase { + public: + const std::string& streamID() const; + const BULKIO::StreamSRI& sri() const; + + double xdelta() const; + bool complex() const; + bool blocking() const; + + const redhawk::PropertyMap& keywords() const; + bool hasKeyword(const std::string& name) const; + const redhawk::Value& getKeyword(const std::string& name) const; + + bool operator! () const; + + protected: + class Impl { + public: + Impl(const SharedSRI& sri) : + _streamID(sri->streamID), + _sri(sri) + { + } + + const std::string& streamID() const + { + return _streamID; + } + + const BULKIO::StreamSRI& sri() const + { + return *_sri; + } + + virtual ~Impl() { } + + protected: + const std::string _streamID; + SharedSRI _sri; + }; + + StreamBase(); + StreamBase(const boost::shared_ptr& impl); + + boost::shared_ptr _impl; + }; } #endif // __bulkio_sri_h diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_stream.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_stream.cpp new file mode 100644 index 000000000..bd16eda71 --- /dev/null +++ b/bulkioInterfaces/libsrc/cpp/bulkio_stream.cpp @@ -0,0 +1,78 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK bulkioInterfaces. + * + * REDHAWK bulkioInterfaces is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK bulkioInterfaces is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +#include "bulkio_sri.h" + +using bulkio::StreamBase; + +StreamBase::StreamBase() : + _impl() +{ +} + +StreamBase::StreamBase(const boost::shared_ptr& impl) : + _impl(impl) +{ +} + +const std::string& StreamBase::streamID() const +{ + return _impl->streamID(); +} + +const BULKIO::StreamSRI& StreamBase::sri() const +{ + return _impl->sri(); +} + +double StreamBase::xdelta() const +{ + return sri().xdelta; +} + +bool StreamBase::complex() const +{ + return (sri().mode != 0); +} + +bool StreamBase::blocking() const +{ + return sri().blocking; +} + +bool StreamBase::operator!() const +{ + return !_impl; +} + +const redhawk::PropertyMap& StreamBase::keywords() const +{ + return redhawk::PropertyMap::cast(sri().keywords); +} + +bool StreamBase::hasKeyword(const std::string& name) const +{ + return keywords().contains(name); +} + +const redhawk::Value& StreamBase::getKeyword(const std::string& name) const +{ + return keywords()[name]; +} From 8c993dd529323b74348c095c116327015ba714bc Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 5 Dec 2016 14:29:13 -0500 Subject: [PATCH 0591/1644] Use SharedSRI as a common base class for input and output streams to help consolidate implementation; drop no longer needed derived SRI class --- .../libsrc/cpp/bulkio_datablock.cpp | 11 ++-- .../libsrc/cpp/bulkio_datablock.h | 2 +- .../libsrc/cpp/bulkio_in_port.cpp | 10 +-- bulkioInterfaces/libsrc/cpp/bulkio_in_port.h | 2 +- .../libsrc/cpp/bulkio_in_stream.cpp | 15 +++-- .../libsrc/cpp/bulkio_out_stream.cpp | 21 +++--- bulkioInterfaces/libsrc/cpp/bulkio_sri.h | 65 +++++-------------- bulkioInterfaces/libsrc/cpp/bulkio_stream.cpp | 4 +- 8 files changed, 48 insertions(+), 82 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_datablock.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_datablock.cpp index 2d23cff19..4ad843fa1 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_datablock.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_datablock.cpp @@ -53,18 +53,17 @@ using bulkio::SampleTimestamp; using bulkio::DataBlock; template -struct DataBlock::Impl +struct DataBlock::Impl : public SharedSRI { Impl(const bulkio::SharedSRI& sri, const T& data) : + SharedSRI(sri), data(data), - sri(sri), sriChangeFlags(bulkio::sri::NONE), inputQueueFlushed(false) { } T data; - bulkio::SharedSRI sri; std::list timestamps; int sriChangeFlags; bool inputQueueFlushed; @@ -93,9 +92,9 @@ DataBlock DataBlock::copy() const } template -const bulkio::SRI& DataBlock::sri() const +const BULKIO::StreamSRI& DataBlock::sri() const { - return *(_impl->sri); + return _impl->sri(); } template @@ -250,7 +249,7 @@ void SampleDataBlock::resize(size_t count) template bool SampleDataBlock::complex() const { - return this->sri().complex(); + return _impl->complex(); } template diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_datablock.h b/bulkioInterfaces/libsrc/cpp/bulkio_datablock.h index ec51645f9..64b255f3d 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_datablock.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_datablock.h @@ -59,7 +59,7 @@ namespace bulkio { DataBlock copy() const; - const SRI& sri() const; + const BULKIO::StreamSRI& sri() const; double xdelta() const; const T& data() const; diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp index d5184657a..06e45375b 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp @@ -175,7 +175,7 @@ namespace bulkio { SharedSRI sri(H); if (newStreamCallback) { // The callback takes a non-const SRI, so allow access via const_cast - newStreamCallback(const_cast(*sri)); + newStreamCallback(const_cast(*sri)); } currentHs[streamID] = std::make_pair(sri, true); lock.unlock(); @@ -230,7 +230,7 @@ namespace bulkio { sri = SharedSRI(bulkio::sri::create(streamID)); if (newStreamCallback) { // The callback takes a non-const SRI, so allow access via const_cast - newStreamCallback(const_cast(*sri)); + newStreamCallback(const_cast(*sri)); } currentHs[streamID] = std::make_pair(sri, false); lock.unlock(); @@ -479,13 +479,13 @@ namespace bulkio { SCOPED_LOCK lock2(sriUpdateLock); SriTable::iterator target = currentHs.find(packet->streamID); if (target != currentHs.end()) { - bool sriBlocking = target->second.first->blocking; + bool sriBlocking = target->second.first.blocking(); currentHs.erase(target); if (sriBlocking) { turnOffBlocking = true; SriTable::iterator currH; for (currH = currentHs.begin(); currH != currentHs.end(); currH++) { - if (currH->second.first->blocking) { + if (currH->second.first.blocking()) { turnOffBlocking = false; break; } @@ -616,7 +616,7 @@ namespace bulkio { if (!firstPacket) break; } firstPacket = false; - if (packet->SRI->complex()) { + if (packet->SRI.complex()) { item_size = 2; } samples += packet->buffer.size(); diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h index ae84782f1..bb9ed45fe 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h @@ -273,7 +273,7 @@ namespace bulkio { SRI(SRI), sriChanged(sriChanged), inputQueueFlushed(inputQueueFlushed), - streamID(SRI->streamID) + streamID(SRI.streamID()) { } diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp index 1d3530267..eb81ca4e0 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp @@ -65,7 +65,8 @@ class InputStream::Impl : public StreamBase::Impl { DataBlockType block(packet->SRI, packet->buffer); block.addTimestamp(packet->T); _setBlockFlags(block, *packet); - _sri = packet->SRI; + // Update local SRI from packet + SharedSRI::operator=(packet->SRI); return block; } @@ -280,7 +281,7 @@ class BufferedInputStream::Impl : public Base::Impl { size_t queued = _samplesQueued; if (queued > 0) { // Adjust number of samples to account for complex data, if necessary - if (_queue.front().SRI->complex()) { + if (_queue.front().SRI.complex()) { queued /= 2; } } @@ -316,7 +317,7 @@ class BufferedInputStream::Impl : public Base::Impl { { // Try to get the SRI for the upcoming block of data, fetching it from the // port's input queue if necessary - const SRI* sri = _nextSRI(blocking); + const SharedSRI* sri = _nextSRI(blocking); if (!sri) { // No SRI retreived implies no data will be retrieved, either due to end- // of-stream or because it would block @@ -376,7 +377,7 @@ class BufferedInputStream::Impl : public Base::Impl { // If the next block of data is complex, double the skip size (which the // lower-level I/O handles in terms of scalars) so that the right number of // samples is skipped - const SRI* sri = _nextSRI(true); + const SharedSRI* sri = _nextSRI(true); if (!sri) { return 0; } @@ -471,7 +472,7 @@ class BufferedInputStream::Impl : public Base::Impl { // Allocate empty data block and propagate the SRI change and input queue // flush flags - DataBlockType data(this->_sri); + DataBlockType data(*this); this->_setBlockFlags(data, front); // Clear flags from packet, since they've been reported @@ -548,7 +549,7 @@ class BufferedInputStream::Impl : public Base::Impl { data.addTimestamp(bulkio::SampleTimestamp(time, output_offset, synthetic)); } - const SRI* _nextSRI(bool blocking) + const SharedSRI* _nextSRI(bool blocking) { if (_queue.empty()) { if (!_fetchPacket(blocking)) { @@ -556,7 +557,7 @@ class BufferedInputStream::Impl : public Base::Impl { } } - return _queue.front().SRI.get(); + return &(_queue.front().SRI); } bool _fetchPacket(bool blocking) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp index db0c76e02..012e00c62 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp @@ -49,44 +49,39 @@ class OutputStreamBase::Impl : public StreamBase::Impl { _send(SharedBufferType(), bulkio::time::utils::notSet(), true); } - BULKIO::StreamSRI& sri() - { - return const_cast(*_sri); - } - void setXDelta(double delta) { - _setStreamMetadata(sri().xdelta, delta); + _setStreamMetadata(_sri->xdelta, delta); } void setComplex(bool mode) { - _setStreamMetadata(sri().mode, mode?1:0); + _setStreamMetadata(_sri->mode, mode?1:0); } void setBlocking(bool mode) { - _setStreamMetadata(sri().blocking, mode?1:0); + _setStreamMetadata(_sri->blocking, mode?1:0); } void setKeywords(const _CORBA_Unbounded_Sequence& properties) { _modifyingStreamMetadata(); - sri().keywords = properties; + _sri->keywords = properties; ++_modcount; } void setKeyword(const std::string& name, const CORBA::Any& value) { _modifyingStreamMetadata(); - redhawk::PropertyMap::cast(sri().keywords)[name] = value; + redhawk::PropertyMap::cast(_sri->keywords)[name] = value; ++_modcount; } void eraseKeyword(const std::string& name) { _modifyingStreamMetadata(); - redhawk::PropertyMap::cast(sri().keywords).erase(name); + redhawk::PropertyMap::cast(_sri->keywords).erase(name); ++_modcount; } @@ -94,8 +89,8 @@ class OutputStreamBase::Impl : public StreamBase::Impl { { _modifyingStreamMetadata(); // Copy the new SRI, except for the stream ID, which is immutable - this->sri() = sri; - this->sri().streamID = _streamID.c_str(); + *_sri = sri; + _sri->streamID = _streamID.c_str(); ++_modcount; } diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_sri.h b/bulkioInterfaces/libsrc/cpp/bulkio_sri.h index cb0532b58..b5605ac62 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_sri.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_sri.h @@ -30,64 +30,41 @@ namespace bulkio { - class SRI : public BULKIO::StreamSRI { + class SharedSRI { public: - static SRI& cast(BULKIO::StreamSRI& sri) + SharedSRI() : + _sri() { - return static_cast(sri); } - static const SRI& cast(const BULKIO::StreamSRI& sri) + SharedSRI(const BULKIO::StreamSRI& sri) : + _sri(boost::make_shared(sri)) { - return static_cast(sri); } - explicit SRI(const BULKIO::StreamSRI& sri) : - BULKIO::StreamSRI(sri) + std::string streamID() const { + return std::string(_sri->streamID); } - std::string getStreamID() const + bool blocking() const { - return std::string(this->streamID); + return _sri->blocking; } bool complex() const { - return (this->mode != 0); - } - - const redhawk::PropertyMap& getKeywords() const - { - return redhawk::PropertyMap::cast(this->keywords); + return (_sri->mode != 0); } - }; - class SharedSRI { - public: - SharedSRI() : - _sri() - { - } - - SharedSRI(const BULKIO::StreamSRI& sri) : - _sri(boost::make_shared(sri)) - { - } - - const SRI* get() const - { - return _sri.get(); - } - - const SRI& operator* () const + const BULKIO::StreamSRI& sri() { return *_sri; } - const SRI* operator-> () const + const BULKIO::StreamSRI& operator* () const { - return _sri.get(); + return *_sri; } bool operator! () const @@ -95,8 +72,8 @@ namespace bulkio { return !_sri; } - private: - boost::shared_ptr _sri; + protected: + boost::shared_ptr _sri; }; class StreamBase { @@ -115,11 +92,11 @@ namespace bulkio { bool operator! () const; protected: - class Impl { + class Impl : public SharedSRI { public: Impl(const SharedSRI& sri) : - _streamID(sri->streamID), - _sri(sri) + SharedSRI(sri), + _streamID(sri.streamID()) { } @@ -128,16 +105,10 @@ namespace bulkio { return _streamID; } - const BULKIO::StreamSRI& sri() const - { - return *_sri; - } - virtual ~Impl() { } protected: const std::string _streamID; - SharedSRI _sri; }; StreamBase(); diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_stream.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_stream.cpp index bd16eda71..2d1897a40 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_stream.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_stream.cpp @@ -49,12 +49,12 @@ double StreamBase::xdelta() const bool StreamBase::complex() const { - return (sri().mode != 0); + return _impl->complex(); } bool StreamBase::blocking() const { - return sri().blocking; + return _impl->blocking(); } bool StreamBase::operator!() const From bd977f3c693c2598c1c2851f7df1f0052bb9c3bd Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 5 Dec 2016 14:41:24 -0500 Subject: [PATCH 0592/1644] Rename SharedSRI back to StreamDescriptor --- bulkioInterfaces/libsrc/Makefile.am | 2 +- .../libsrc/cpp/bulkio_datablock.cpp | 14 +++++------ .../libsrc/cpp/bulkio_datablock.h | 6 ++--- .../libsrc/cpp/bulkio_in_port.cpp | 20 ++++++++-------- bulkioInterfaces/libsrc/cpp/bulkio_in_port.h | 9 ++++---- .../libsrc/cpp/bulkio_in_stream.cpp | 18 +++++++-------- .../libsrc/cpp/bulkio_in_stream.h | 6 ++--- .../libsrc/cpp/bulkio_out_stream.h | 2 +- bulkioInterfaces/libsrc/cpp/bulkio_stream.cpp | 2 +- .../cpp/{bulkio_sri.h => bulkio_stream.h} | 23 ++++++++----------- 10 files changed, 48 insertions(+), 54 deletions(-) rename bulkioInterfaces/libsrc/cpp/{bulkio_sri.h => bulkio_stream.h} (87%) diff --git a/bulkioInterfaces/libsrc/Makefile.am b/bulkioInterfaces/libsrc/Makefile.am index e7b960c6c..8936e9cac 100644 --- a/bulkioInterfaces/libsrc/Makefile.am +++ b/bulkioInterfaces/libsrc/Makefile.am @@ -62,7 +62,7 @@ library_include_HEADERS = cpp/bulkio.h \ cpp/bulkio_out_port.h \ cpp/bulkio_out_stream.h \ cpp/bulkio_attachable_base.h \ - cpp/bulkio_sri.h \ + cpp/bulkio_stream.h \ cpp/bulkio_time_operators.h \ cpp/bulkio_datablock.h \ cpp/bulkio_compat.h diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_datablock.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_datablock.cpp index 4ad843fa1..79994ffd4 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_datablock.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_datablock.cpp @@ -25,7 +25,7 @@ #include "bulkio_base.h" #include "bulkio_datablock.h" -#include "bulkio_sri.h" +#include "bulkio_stream.h" #include "bulkio_time_operators.h" namespace bulkio { @@ -53,10 +53,10 @@ using bulkio::SampleTimestamp; using bulkio::DataBlock; template -struct DataBlock::Impl : public SharedSRI +struct DataBlock::Impl : public StreamDescriptor { - Impl(const bulkio::SharedSRI& sri, const T& data) : - SharedSRI(sri), + Impl(const bulkio::StreamDescriptor& sri, const T& data) : + StreamDescriptor(sri), data(data), sriChangeFlags(bulkio::sri::NONE), inputQueueFlushed(false) @@ -76,7 +76,7 @@ DataBlock::DataBlock() : } template -DataBlock::DataBlock(const bulkio::SharedSRI& sri, const T& data) : +DataBlock::DataBlock(const bulkio::StreamDescriptor& sri, const T& data) : _impl(boost::make_shared(sri, data)) { } @@ -209,7 +209,7 @@ SampleDataBlock::SampleDataBlock() : } template -SampleDataBlock::SampleDataBlock(const bulkio::SharedSRI& sri, +SampleDataBlock::SampleDataBlock(const bulkio::StreamDescriptor& sri, const ScalarBuffer& buffer) : Base(sri, buffer) { @@ -217,7 +217,7 @@ SampleDataBlock::SampleDataBlock(const bulkio::SharedSRI& sri, template SampleDataBlock::SampleDataBlock(const BULKIO::StreamSRI& sri, size_t size) : - Base(bulkio::SharedSRI(sri), redhawk::buffer(size)) + Base(bulkio::StreamDescriptor(sri), redhawk::buffer(size)) { } diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_datablock.h b/bulkioInterfaces/libsrc/cpp/bulkio_datablock.h index 64b255f3d..187323737 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_datablock.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_datablock.h @@ -34,7 +34,7 @@ namespace bulkio { class SRI; - class SharedSRI; + class StreamDescriptor; struct SampleTimestamp { @@ -55,7 +55,7 @@ namespace bulkio { { public: DataBlock(); - DataBlock(const SharedSRI& sri, const T& buffer); + DataBlock(const StreamDescriptor& sri, const T& buffer); DataBlock copy() const; @@ -102,7 +102,7 @@ namespace bulkio { typedef redhawk::shared_buffer ComplexBuffer; SampleDataBlock(); - explicit SampleDataBlock(const SharedSRI& sri, const ScalarBuffer& buffer=ScalarBuffer()); + explicit SampleDataBlock(const StreamDescriptor& sri, const ScalarBuffer& buffer=ScalarBuffer()); SampleDataBlock(const BULKIO::StreamSRI& sri, size_t size=0); SampleDataBlock copy() const; diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp index 06e45375b..ba88503ff 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp @@ -127,7 +127,7 @@ namespace bulkio { SCOPED_LOCK lock(sriUpdateLock); BULKIO::StreamSRISequence_var retSRI = new BULKIO::StreamSRISequence(); for (SriTable::iterator currH = currentHs.begin(); currH != currentHs.end(); ++currH) { - ossie::corba::push_back(retSRI, *(currH->second.first)); + ossie::corba::push_back(retSRI, currH->second.first.sri()); } // NOTE: You must delete the object that this function returns! @@ -172,19 +172,19 @@ namespace bulkio { SriTable::iterator currH = currentHs.find(streamID); if (currH == currentHs.end()) { LOG_DEBUG(logger,"pushSRI PORT:" << name << " NEW SRI:" << streamID << " Mode:" << H.mode ); - SharedSRI sri(H); + StreamDescriptor sri(H); if (newStreamCallback) { // The callback takes a non-const SRI, so allow access via const_cast - newStreamCallback(const_cast(*sri)); + newStreamCallback(const_cast(sri.sri())); } currentHs[streamID] = std::make_pair(sri, true); lock.unlock(); createStream(streamID, sri); } else { - if (sri_cmp && !sri_cmp(H, *(currH->second.first))) { + if (sri_cmp && !sri_cmp(H, currH->second.first.sri())) { LOG_DEBUG(logger,"pushSRI PORT:" << name << " SAME SRI:" << streamID << " Mode:" << H.mode ); - currH->second.first = SharedSRI(H); + currH->second.first = StreamDescriptor(H); currH->second.second = true; } } @@ -211,7 +211,7 @@ namespace bulkio { return; } - SharedSRI sri; + StreamDescriptor sri; bool sriChanged = false; { @@ -227,10 +227,10 @@ namespace bulkio { // and set the SRI changed flag LOG_WARN(logger, "InPort::pushPacket received data for stream '" << streamID << "' with no SRI"); sriChanged = true; - sri = SharedSRI(bulkio::sri::create(streamID)); + sri = StreamDescriptor(bulkio::sri::create(streamID)); if (newStreamCallback) { // The callback takes a non-const SRI, so allow access via const_cast - newStreamCallback(const_cast(*sri)); + newStreamCallback(const_cast(sri.sri())); } currentHs[streamID] = std::make_pair(sri, false); lock.unlock(); @@ -423,7 +423,7 @@ namespace bulkio { DataTransferType* transfer = 0; boost::scoped_ptr packet(nextPacket(timeout, streamID)); if (packet) { - transfer = new DataTransferType(PortSequenceType(), packet->T, packet->EOS, packet->streamID.c_str(), *(packet->SRI), packet->sriChanged, packet->inputQueueFlushed); + transfer = new DataTransferType(PortSequenceType(), packet->T, packet->EOS, packet->streamID.c_str(), packet->SRI.sri(), packet->sriChanged, packet->inputQueueFlushed); transfer->dataBuffer.assign(packet->buffer.begin(), packet->buffer.end()); } return transfer; @@ -530,7 +530,7 @@ namespace bulkio { template < typename PortTraits > void InPort< PortTraits >::createStream(const std::string& streamID, - const bulkio::SharedSRI& sri) + const bulkio::StreamDescriptor& sri) { StreamType stream(sri, this); boost::mutex::scoped_lock lock(streamsMutex); diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h index bb9ed45fe..ae94595a4 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h @@ -32,7 +32,6 @@ #include "bulkio_base.h" #include "bulkio_traits.h" #include "bulkio_in_stream.h" -#include "bulkio_sri.h" #include "bulkio_callbacks.h" namespace bulkio { @@ -266,7 +265,7 @@ namespace bulkio { SriListener *newStreamCB = NULL ); struct Packet { - Packet(const SharedBufferType& buffer, const BULKIO::PrecisionUTCTime& T, bool EOS, const SharedSRI& SRI, bool sriChanged, bool inputQueueFlushed) : + Packet(const SharedBufferType& buffer, const BULKIO::PrecisionUTCTime& T, bool EOS, const StreamDescriptor& SRI, bool sriChanged, bool inputQueueFlushed) : buffer(buffer), T(T), EOS(EOS), @@ -280,7 +279,7 @@ namespace bulkio { SharedBufferType buffer; BULKIO::PrecisionUTCTime T; bool EOS; - SharedSRI SRI; + StreamDescriptor SRI; bool sriChanged; bool inputQueueFlushed; std::string streamID; @@ -305,7 +304,7 @@ namespace bulkio { // // List of SRI objects managed by StreamID // - typedef std::map > SriTable; + typedef std::map > SriTable; SriTable currentHs; // @@ -389,7 +388,7 @@ namespace bulkio { friend class InputStream; size_t samplesAvailable(const std::string& streamID, bool firstPacket); - void createStream(const std::string& streamID, const SharedSRI& sri); + void createStream(const std::string& streamID, const StreamDescriptor& sri); void removeStream(const std::string& streamID); bool isStreamActive(const std::string& streamID); diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp index eb81ca4e0..5cb48073e 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp @@ -42,7 +42,7 @@ class InputStream::Impl : public StreamBase::Impl { EOS_REPORTED }; - Impl(const bulkio::SharedSRI& sri, InPortType* port) : + Impl(const bulkio::StreamDescriptor& sri, InPortType* port) : ImplBase(sri), _port(port), _eosState(EOS_NONE), @@ -66,7 +66,7 @@ class InputStream::Impl : public StreamBase::Impl { block.addTimestamp(packet->T); _setBlockFlags(block, *packet); // Update local SRI from packet - SharedSRI::operator=(packet->SRI); + StreamDescriptor::operator=(packet->SRI); return block; } @@ -146,7 +146,7 @@ class InputStream::Impl : public StreamBase::Impl { // Allocate empty data block and propagate the SRI change and input // queue flush flags if (packet.sriChanged) { - int flags = bulkio::sri::compareFields(*_sri, *(packet.SRI)); + int flags = bulkio::sri::compareFields(this->sri(), packet.SRI.sri()); block.sriChangeFlags(flags); } if (packet.inputQueueFlushed) { @@ -166,7 +166,7 @@ InputStream::InputStream() : } template -InputStream::InputStream(const SharedSRI& sri, InPortType* port) : +InputStream::InputStream(const StreamDescriptor& sri, InPortType* port) : StreamBase(boost::make_shared(sri, port)) { } @@ -249,7 +249,7 @@ class BufferedInputStream::Impl : public Base::Impl { typedef typename PortTraits::NativeType NativeType; typedef typename PortTraits::SharedBufferType SharedBufferType; - Impl(const bulkio::SharedSRI& sri, InPortType* port) : + Impl(const bulkio::StreamDescriptor& sri, InPortType* port) : ImplBase(sri, port), _queue(), _pending(0), @@ -317,7 +317,7 @@ class BufferedInputStream::Impl : public Base::Impl { { // Try to get the SRI for the upcoming block of data, fetching it from the // port's input queue if necessary - const SharedSRI* sri = _nextSRI(blocking); + const StreamDescriptor* sri = _nextSRI(blocking); if (!sri) { // No SRI retreived implies no data will be retrieved, either due to end- // of-stream or because it would block @@ -377,7 +377,7 @@ class BufferedInputStream::Impl : public Base::Impl { // If the next block of data is complex, double the skip size (which the // lower-level I/O handles in terms of scalars) so that the right number of // samples is skipped - const SharedSRI* sri = _nextSRI(true); + const StreamDescriptor* sri = _nextSRI(true); if (!sri) { return 0; } @@ -549,7 +549,7 @@ class BufferedInputStream::Impl : public Base::Impl { data.addTimestamp(bulkio::SampleTimestamp(time, output_offset, synthetic)); } - const SharedSRI* _nextSRI(bool blocking) + const StreamDescriptor* _nextSRI(bool blocking) { if (_queue.empty()) { if (!_fetchPacket(blocking)) { @@ -623,7 +623,7 @@ BufferedInputStream::BufferedInputStream() : } template -BufferedInputStream::BufferedInputStream(const bulkio::SharedSRI& sri, InPortType* port) : +BufferedInputStream::BufferedInputStream(const bulkio::StreamDescriptor& sri, InPortType* port) : Base(boost::make_shared(sri, port)) { } diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.h b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.h index 87015e7ed..de17aa598 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.h @@ -28,7 +28,7 @@ #include "bulkio_traits.h" #include "bulkio_datablock.h" -#include "bulkio_sri.h" +#include "bulkio_stream.h" namespace bulkio { @@ -79,7 +79,7 @@ namespace bulkio { // Allow matching InPort class to create instances of this stream type friend class InPort; - InputStream(const SharedSRI& sri, InPortType* port); + InputStream(const StreamDescriptor& sri, InPortType* port); bool hasBufferedData(); @@ -117,7 +117,7 @@ namespace bulkio { friend class InPort; typedef InPort InPortType; - BufferedInputStream(const SharedSRI&, InPortType*); + BufferedInputStream(const StreamDescriptor&, InPortType*); class Impl; Impl& impl(); diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h index 077fc9ac4..f6a1fcb9e 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h @@ -31,7 +31,7 @@ #include "bulkio_traits.h" #include "bulkio_datablock.h" -#include "bulkio_sri.h" +#include "bulkio_stream.h" namespace bulkio { diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_stream.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_stream.cpp index 2d1897a40..455a14105 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_stream.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_stream.cpp @@ -18,7 +18,7 @@ * along with this program. If not, see http://www.gnu.org/licenses/. */ -#include "bulkio_sri.h" +#include "bulkio_stream.h" using bulkio::StreamBase; diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_sri.h b/bulkioInterfaces/libsrc/cpp/bulkio_stream.h similarity index 87% rename from bulkioInterfaces/libsrc/cpp/bulkio_sri.h rename to bulkioInterfaces/libsrc/cpp/bulkio_stream.h index b5605ac62..469e747b1 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_sri.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_stream.h @@ -18,8 +18,8 @@ * along with this program. If not, see http://www.gnu.org/licenses/. */ -#ifndef __bulkio_sri_h -#define __bulkio_sri_h +#ifndef __bulkio_stream_h +#define __bulkio_stream_h #include #include @@ -30,14 +30,14 @@ namespace bulkio { - class SharedSRI { + class StreamDescriptor { public: - SharedSRI() : + StreamDescriptor() : _sri() { } - SharedSRI(const BULKIO::StreamSRI& sri) : + StreamDescriptor(const BULKIO::StreamSRI& sri) : _sri(boost::make_shared(sri)) { } @@ -62,11 +62,6 @@ namespace bulkio { return *_sri; } - const BULKIO::StreamSRI& operator* () const - { - return *_sri; - } - bool operator! () const { return !_sri; @@ -92,10 +87,10 @@ namespace bulkio { bool operator! () const; protected: - class Impl : public SharedSRI { + class Impl : public StreamDescriptor { public: - Impl(const SharedSRI& sri) : - SharedSRI(sri), + Impl(const StreamDescriptor& sri) : + StreamDescriptor(sri), _streamID(sri.streamID()) { } @@ -118,4 +113,4 @@ namespace bulkio { }; } -#endif // __bulkio_sri_h +#endif // __bulkio_stream_h From 2bf4c12424bc6b4b1b3bdb6212f643ffaef5b1ef Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 5 Dec 2016 15:12:31 -0500 Subject: [PATCH 0593/1644] Add remaining SRI fields to stream classes --- .../libsrc/cpp/bulkio_out_stream.cpp | 66 +++++++++++++++++++ .../libsrc/cpp/bulkio_out_stream.h | 16 ++++- bulkioInterfaces/libsrc/cpp/bulkio_stream.cpp | 30 +++++++++ bulkioInterfaces/libsrc/cpp/bulkio_stream.h | 9 +++ 4 files changed, 120 insertions(+), 1 deletion(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp index 012e00c62..3d5b37ed5 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp @@ -49,11 +49,41 @@ class OutputStreamBase::Impl : public StreamBase::Impl { _send(SharedBufferType(), bulkio::time::utils::notSet(), true); } + void setXStart(double start) + { + _setStreamMetadata(_sri->xstart, start); + } + void setXDelta(double delta) { _setStreamMetadata(_sri->xdelta, delta); } + void setXUnits(short units) + { + _setStreamMetadata(_sri->xunits, units); + } + + void setSubsize(int size) + { + _setStreamMetadata(_sri->subsize, size); + } + + void setYStart(double start) + { + _setStreamMetadata(_sri->ystart, start); + } + + void setYDelta(double delta) + { + _setStreamMetadata(_sri->ydelta, delta); + } + + void setYUnits(short units) + { + _setStreamMetadata(_sri->yunits, units); + } + void setComplex(bool mode) { _setStreamMetadata(_sri->mode, mode?1:0); @@ -153,12 +183,48 @@ void OutputStreamBase::sri(const BULKIO::StreamSRI& sri) impl().setSRI(sri); } +template +void OutputStreamBase::xstart(double start) +{ + impl().setXStart(start); +} + template void OutputStreamBase::xdelta(double delta) { impl().setXDelta(delta); } +template +void OutputStreamBase::xunits(short units) +{ + impl().setXUnits(units); +} + +template +void OutputStreamBase::subsize(int size) +{ + impl().setSubsize(size); +} + +template +void OutputStreamBase::ystart(double start) +{ + impl().setYStart(start); +} + +template +void OutputStreamBase::ydelta(double delta) +{ + impl().setYDelta(delta); +} + +template +void OutputStreamBase::yunits(short units) +{ + impl().setYUnits(units); +} + template void OutputStreamBase::complex(bool mode) { diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h index f6a1fcb9e..f90154bf7 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h @@ -44,8 +44,22 @@ namespace bulkio { using StreamBase::sri; void sri(const BULKIO::StreamSRI& sri); + using StreamBase::xstart; + void xstart(double start); using StreamBase::xdelta; - void xdelta(double xdelta); + void xdelta(double delta); + using StreamBase::xunits; + void xunits(short units); + + using StreamBase::subsize; + void subsize(int size); + + using StreamBase::ystart; + void ystart(double start); + using StreamBase::ydelta; + void ydelta(double delta); + using StreamBase::yunits; + void yunits(short units); using StreamBase::complex; void complex(bool mode); diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_stream.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_stream.cpp index 455a14105..46a9796a6 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_stream.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_stream.cpp @@ -42,11 +42,41 @@ const BULKIO::StreamSRI& StreamBase::sri() const return _impl->sri(); } +double StreamBase::xstart() const +{ + return sri().xstart; +} + double StreamBase::xdelta() const { return sri().xdelta; } +short StreamBase::xunits() const +{ + return sri().xunits; +} + +int StreamBase::subsize() const +{ + return sri().subsize; +} + +double StreamBase::ystart() const +{ + return sri().ystart; +} + +double StreamBase::ydelta() const +{ + return sri().ydelta; +} + +short StreamBase::yunits() const +{ + return sri().yunits; +} + bool StreamBase::complex() const { return _impl->complex(); diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_stream.h b/bulkioInterfaces/libsrc/cpp/bulkio_stream.h index 469e747b1..9c7aa5ac4 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_stream.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_stream.h @@ -76,7 +76,16 @@ namespace bulkio { const std::string& streamID() const; const BULKIO::StreamSRI& sri() const; + double xstart() const; double xdelta() const; + short xunits() const; + + int subsize() const; + + double ystart() const; + double ydelta() const; + short yunits() const; + bool complex() const; bool blocking() const; From 28518f7f94477fa861c40dc768e93d1662462b55 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 5 Dec 2016 15:23:25 -0500 Subject: [PATCH 0594/1644] Rename output stream classes to match input stream names --- bulkioInterfaces/libsrc/cpp/bulkio_out_port.h | 2 +- .../libsrc/cpp/bulkio_out_stream.cpp | 96 +++++++++---------- .../libsrc/cpp/bulkio_out_stream.h | 48 +++++----- 3 files changed, 73 insertions(+), 73 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h index 5e9d7225e..dac70d392 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h @@ -282,7 +282,7 @@ namespace bulkio { // // Sends data and metadata to all connections enabled for the given stream // - friend class OutputStreamBase; + friend class OutputStream; void _sendPacket(const SharedBufferType& data, const BULKIO::PrecisionUTCTime& T, bool EOS, diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp index 3d5b37ed5..0888d6d89 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp @@ -23,10 +23,10 @@ #include "bulkio_time_operators.h" #include "bulkio_p.h" -using bulkio::OutputStreamBase; +using bulkio::OutputStream; template -class OutputStreamBase::Impl : public StreamBase::Impl { +class OutputStream::Impl : public StreamBase::Impl { public: typedef StreamBase::Impl ImplBase; typedef typename PortTraits::SharedBufferType SharedBufferType; @@ -160,148 +160,148 @@ class OutputStreamBase::Impl : public StreamBase::Impl { }; template -OutputStreamBase::OutputStreamBase() : +OutputStream::OutputStream() : StreamBase() { } template -OutputStreamBase::OutputStreamBase(const BULKIO::StreamSRI& sri, OutPortType* port) : +OutputStream::OutputStream(const BULKIO::StreamSRI& sri, OutPortType* port) : StreamBase(boost::make_shared(sri, port)) { } template -OutputStreamBase::OutputStreamBase(boost::shared_ptr impl) : +OutputStream::OutputStream(boost::shared_ptr impl) : StreamBase(impl) { } template -void OutputStreamBase::sri(const BULKIO::StreamSRI& sri) +void OutputStream::sri(const BULKIO::StreamSRI& sri) { impl().setSRI(sri); } template -void OutputStreamBase::xstart(double start) +void OutputStream::xstart(double start) { impl().setXStart(start); } template -void OutputStreamBase::xdelta(double delta) +void OutputStream::xdelta(double delta) { impl().setXDelta(delta); } template -void OutputStreamBase::xunits(short units) +void OutputStream::xunits(short units) { impl().setXUnits(units); } template -void OutputStreamBase::subsize(int size) +void OutputStream::subsize(int size) { impl().setSubsize(size); } template -void OutputStreamBase::ystart(double start) +void OutputStream::ystart(double start) { impl().setYStart(start); } template -void OutputStreamBase::ydelta(double delta) +void OutputStream::ydelta(double delta) { impl().setYDelta(delta); } template -void OutputStreamBase::yunits(short units) +void OutputStream::yunits(short units) { impl().setYUnits(units); } template -void OutputStreamBase::complex(bool mode) +void OutputStream::complex(bool mode) { impl().setComplex(mode); } template -void OutputStreamBase::blocking(bool mode) +void OutputStream::blocking(bool mode) { impl().setBlocking(mode); } template -void OutputStreamBase::keywords(const _CORBA_Unbounded_Sequence& props) +void OutputStream::keywords(const _CORBA_Unbounded_Sequence& props) { impl().setKeywords(props); } template -void OutputStreamBase::setKeyword(const std::string& name, const CORBA::Any& value) +void OutputStream::setKeyword(const std::string& name, const CORBA::Any& value) { impl().setKeyword(name, value); } template -void OutputStreamBase::setKeyword(const std::string& name, const redhawk::Value& value) +void OutputStream::setKeyword(const std::string& name, const redhawk::Value& value) { impl().setKeyword(name, value); } template -void OutputStreamBase::eraseKeyword(const std::string& name) +void OutputStream::eraseKeyword(const std::string& name) { impl().eraseKeyword(name); } template -void OutputStreamBase::close() +void OutputStream::close() { impl().close(); _impl.reset(); } template -OutputStreamBase::operator unspecified_bool_type() const +OutputStream::operator unspecified_bool_type() const { - return _impl?static_cast(&OutputStreamBase::impl):0; + return _impl?static_cast(&OutputStream::impl):0; } template -typename OutputStreamBase::Impl& OutputStreamBase::impl() +typename OutputStream::Impl& OutputStream::impl() { return static_cast(*this->_impl); } template -const typename OutputStreamBase::Impl& OutputStreamBase::impl() const +const typename OutputStream::Impl& OutputStream::impl() const { return static_cast(*this->_impl); } template -int OutputStreamBase::modcount() const +int OutputStream::modcount() const { return impl().modcount(); } -using bulkio::OutputStream; +using bulkio::BufferedOutputStream; template -class OutputStream::Impl : public Base::Impl { +class BufferedOutputStream::Impl : public Base::Impl { public: typedef typename Base::Impl ImplBase; - typedef typename OutputStream::ScalarBuffer ScalarBuffer; - typedef typename OutputStream::ComplexBuffer ComplexBuffer; + typedef typename BufferedOutputStream::ScalarBuffer ScalarBuffer; + typedef typename BufferedOutputStream::ComplexBuffer ComplexBuffer; using ImplBase::_sri; using ImplBase::_streamID; @@ -452,91 +452,91 @@ class OutputStream::Impl : public Base::Impl { }; template -OutputStream::OutputStream() : +BufferedOutputStream::BufferedOutputStream() : Base() { } template -OutputStream::OutputStream(const BULKIO::StreamSRI& sri, OutPortType* port) : +BufferedOutputStream::BufferedOutputStream(const BULKIO::StreamSRI& sri, OutPortType* port) : Base(boost::make_shared(sri, port)) { } template -size_t OutputStream::bufferSize() const +size_t BufferedOutputStream::bufferSize() const { return impl().bufferSize(); } template -void OutputStream::setBufferSize(size_t samples) +void BufferedOutputStream::setBufferSize(size_t samples) { impl().setBufferSize(samples); } template -void OutputStream::flush() +void BufferedOutputStream::flush() { impl().flush(); } template -void OutputStream::write(const ScalarBuffer& data, const BULKIO::PrecisionUTCTime& time) +void BufferedOutputStream::write(const ScalarBuffer& data, const BULKIO::PrecisionUTCTime& time) { impl().write(data, time); } template -void OutputStream::write(const ScalarBuffer& data, const std::list& times) +void BufferedOutputStream::write(const ScalarBuffer& data, const std::list& times) { impl().write(data, times); } template -void OutputStream::write(const ComplexBuffer& data, const BULKIO::PrecisionUTCTime& time) +void BufferedOutputStream::write(const ComplexBuffer& data, const BULKIO::PrecisionUTCTime& time) { impl().write(data, time); } template -void OutputStream::write(const ComplexBuffer& data, const std::list& times) +void BufferedOutputStream::write(const ComplexBuffer& data, const std::list& times) { impl().write(data, times); } template -void OutputStream::write(const ScalarType* data, size_t count, const BULKIO::PrecisionUTCTime& time) +void BufferedOutputStream::write(const ScalarType* data, size_t count, const BULKIO::PrecisionUTCTime& time) { impl().write(ScalarBuffer::make_transient(data, count), time); } template -void OutputStream::write(const ScalarType* data, size_t count, const std::list& times) +void BufferedOutputStream::write(const ScalarType* data, size_t count, const std::list& times) { impl().write(ScalarBuffer::make_transient(data, count), times); } template -void OutputStream::write(const ComplexType* data, size_t count, const BULKIO::PrecisionUTCTime& time) +void BufferedOutputStream::write(const ComplexType* data, size_t count, const BULKIO::PrecisionUTCTime& time) { impl().write(ComplexBuffer::make_transient(data, count), time); } template -void OutputStream::write(const ComplexType* data, size_t count, const std::list& times) +void BufferedOutputStream::write(const ComplexType* data, size_t count, const std::list& times) { impl().write(ComplexBuffer::make_transient(data, count), times); } template -typename OutputStream::Impl& OutputStream::impl() +typename BufferedOutputStream::Impl& BufferedOutputStream::impl() { return static_cast(*this->_impl); } template -const typename OutputStream::Impl& OutputStream::impl() const +const typename BufferedOutputStream::Impl& BufferedOutputStream::impl() const { return static_cast(*this->_impl); } @@ -585,11 +585,11 @@ void OutFileStream::write(const std::string& URL, const BULKIO::PrecisionUTCTime impl().write(URL, time); } -#define INSTANTIATE_TEMPLATE(x) \ - template class OutputStreamBase; +#define INSTANTIATE_TEMPLATE(x) \ + template class OutputStream; -#define INSTANTIATE_NUMERIC_TEMPLATE(x) \ - INSTANTIATE_TEMPLATE(x); template class OutputStream; +#define INSTANTIATE_NUMERIC_TEMPLATE(x) \ + INSTANTIATE_TEMPLATE(x); template class BufferedOutputStream; INSTANTIATE_NUMERIC_TEMPLATE(bulkio::CharPortTraits); INSTANTIATE_NUMERIC_TEMPLATE(bulkio::OctetPortTraits); diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h index f90154bf7..698188aa2 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h @@ -39,7 +39,7 @@ namespace bulkio { class OutPort; template - class OutputStreamBase : public StreamBase { + class OutputStream : public StreamBase { public: using StreamBase::sri; void sri(const BULKIO::StreamSRI& sri); @@ -87,13 +87,13 @@ namespace bulkio { Impl& impl(); const Impl& impl() const; - OutputStreamBase(); - OutputStreamBase(const BULKIO::StreamSRI& sri, OutPortType* port); - OutputStreamBase(boost::shared_ptr impl); + OutputStream(); + OutputStream(const BULKIO::StreamSRI& sri, OutPortType* port); + OutputStream(boost::shared_ptr impl); int modcount() const; - typedef const Impl& (OutputStreamBase::*unspecified_bool_type)() const; + typedef const Impl& (OutputStream::*unspecified_bool_type)() const; public: operator unspecified_bool_type() const; @@ -101,7 +101,7 @@ namespace bulkio { template - class OutputStream : public OutputStreamBase { + class BufferedOutputStream : public OutputStream { public: typedef typename PortTraits::DataTransferTraits::NativeDataType ScalarType; typedef std::complex ComplexType; @@ -109,7 +109,7 @@ namespace bulkio { typedef redhawk::shared_buffer ScalarBuffer; typedef redhawk::shared_buffer ComplexBuffer; - OutputStream(); + BufferedOutputStream(); /** * @brief Returns the internal buffer size. @@ -184,11 +184,11 @@ namespace bulkio { void write(const ComplexType* data, size_t count, const std::list& times); private: - typedef OutputStreamBase Base; + typedef OutputStream Base; friend class OutPort; typedef OutPort OutPortType; - OutputStream(const BULKIO::StreamSRI& sri, OutPortType* port); + BufferedOutputStream(const BULKIO::StreamSRI& sri, OutPortType* port); class Impl; Impl& impl(); @@ -196,7 +196,7 @@ namespace bulkio { }; - class OutXMLStream : public OutputStreamBase { + class OutXMLStream : public OutputStream { public: OutXMLStream(); @@ -207,7 +207,7 @@ namespace bulkio { void write(const std::string& xmlString); private: - typedef OutputStreamBase Base; + typedef OutputStream Base; friend class OutPort; typedef OutPort OutPortType; @@ -215,7 +215,7 @@ namespace bulkio { }; - class OutFileStream : public OutputStreamBase { + class OutFileStream : public OutputStream { public: OutFileStream(); @@ -226,28 +226,28 @@ namespace bulkio { void write(const std::string& URL, const BULKIO::PrecisionUTCTime& time); private: - typedef OutputStreamBase Base; + typedef OutputStream Base; friend class OutPort; typedef OutPort OutPortType; OutFileStream(const BULKIO::StreamSRI& sri, OutPortType* port); }; - typedef OutputStream OutCharStream; - typedef OutputStream OutOctetStream; - typedef OutputStream OutShortStream; - typedef OutputStream OutUShortStream; - typedef OutputStream OutLongStream; - typedef OutputStream OutULongStream; - typedef OutputStream OutLongLongStream; - typedef OutputStream OutULongLongStream; - typedef OutputStream OutFloatStream; - typedef OutputStream OutDoubleStream; + typedef BufferedOutputStream OutCharStream; + typedef BufferedOutputStream OutOctetStream; + typedef BufferedOutputStream OutShortStream; + typedef BufferedOutputStream OutUShortStream; + typedef BufferedOutputStream OutLongStream; + typedef BufferedOutputStream OutULongStream; + typedef BufferedOutputStream OutLongLongStream; + typedef BufferedOutputStream OutULongLongStream; + typedef BufferedOutputStream OutFloatStream; + typedef BufferedOutputStream OutDoubleStream; template struct OutStreamTraits { - typedef OutputStream OutStreamType; + typedef BufferedOutputStream OutStreamType; }; template <> From d156ae4c41d09cec4d24ab15b04fd50f10121f2f Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 5 Dec 2016 16:03:01 -0500 Subject: [PATCH 0595/1644] Allow conversion from streams to const StreamSRI reference --- bulkioInterfaces/libsrc/cpp/bulkio_stream.cpp | 5 +++++ bulkioInterfaces/libsrc/cpp/bulkio_stream.h | 2 ++ 2 files changed, 7 insertions(+) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_stream.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_stream.cpp index 46a9796a6..07ef14eaf 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_stream.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_stream.cpp @@ -42,6 +42,11 @@ const BULKIO::StreamSRI& StreamBase::sri() const return _impl->sri(); } +StreamBase::operator const BULKIO::StreamSRI& () const +{ + return sri(); +} + double StreamBase::xstart() const { return sri().xstart; diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_stream.h b/bulkioInterfaces/libsrc/cpp/bulkio_stream.h index 9c7aa5ac4..26fe6982c 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_stream.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_stream.h @@ -76,6 +76,8 @@ namespace bulkio { const std::string& streamID() const; const BULKIO::StreamSRI& sri() const; + operator const BULKIO::StreamSRI& () const; + double xstart() const; double xdelta() const; short xunits() const; From 1a1c91f4f2eec2fe24a4c012fc2aa182d8e8df98 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 6 Dec 2016 09:47:44 -0500 Subject: [PATCH 0596/1644] Refactor usage of BulkIO traits classes to reduce symbol length, making it easier to resolve missing symbol problems; new traits classes are simplified to only describe very specific and different aspects of each port type --- bulkioInterfaces/libsrc/Makefile.am | 2 + bulkioInterfaces/libsrc/cpp/bulkio.cpp | 53 ---- .../libsrc/cpp/bulkio_datatransfer.h | 149 +++++++++++ .../libsrc/cpp/bulkio_in_port.cpp | 230 ++++++++--------- bulkioInterfaces/libsrc/cpp/bulkio_in_port.h | 145 +++++------ .../libsrc/cpp/bulkio_in_stream.cpp | 148 +++++------ .../libsrc/cpp/bulkio_in_stream.h | 71 ++---- .../libsrc/cpp/bulkio_out_port.cpp | 184 +++++++------ bulkioInterfaces/libsrc/cpp/bulkio_out_port.h | 241 +++++------------- .../libsrc/cpp/bulkio_out_stream.cpp | 192 +++++++------- .../libsrc/cpp/bulkio_out_stream.h | 72 ++---- bulkioInterfaces/libsrc/cpp/bulkio_traits.h | 110 +------- .../libsrc/cpp/bulkio_transport.cpp | 213 ++++++++-------- .../libsrc/cpp/bulkio_transport.h | 16 +- .../libsrc/cpp/bulkio_typetraits.h | 90 +++++++ 15 files changed, 915 insertions(+), 1001 deletions(-) create mode 100644 bulkioInterfaces/libsrc/cpp/bulkio_datatransfer.h create mode 100644 bulkioInterfaces/libsrc/cpp/bulkio_typetraits.h diff --git a/bulkioInterfaces/libsrc/Makefile.am b/bulkioInterfaces/libsrc/Makefile.am index 8936e9cac..a9544d973 100644 --- a/bulkioInterfaces/libsrc/Makefile.am +++ b/bulkioInterfaces/libsrc/Makefile.am @@ -65,6 +65,8 @@ library_include_HEADERS = cpp/bulkio.h \ cpp/bulkio_stream.h \ cpp/bulkio_time_operators.h \ cpp/bulkio_datablock.h \ + cpp/bulkio_datatransfer.h \ + cpp/bulkio_typetraits.h \ cpp/bulkio_compat.h ## The generated configuration header is installed in its own subdirectory of diff --git a/bulkioInterfaces/libsrc/cpp/bulkio.cpp b/bulkioInterfaces/libsrc/cpp/bulkio.cpp index d5693a1b5..23bddf4fc 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio.cpp @@ -245,57 +245,4 @@ namespace bulkio { return runningStats; } - - template < typename DataTransferTraits > - DataTransfer< DataTransferTraits >::DataTransfer(const PortSequenceType& data, const BULKIO::PrecisionUTCTime &_T, bool _EOS, const char* _streamID, const BULKIO::StreamSRI &_H, bool _sriChanged, bool _inputQueueFlushed) : - T(_T), - EOS(_EOS), - streamID(_streamID), - SRI(_H), - sriChanged(_sriChanged), - inputQueueFlushed(_inputQueueFlushed) - { - const size_t dataLength = data.length(); - - typedef typename std::_Vector_base::_Vector_impl *VectorPtr; - - VectorPtr vectorPtr = (VectorPtr)(&dataBuffer); - - if (data.release()) { - vectorPtr->_M_start = const_cast(&data)->get_buffer(1); - } else { - // Somebody else owns the data; make a copy - vectorPtr->_M_start = vectorPtr->allocate(dataLength); - const void* buffer = data.get_buffer(); - memcpy(vectorPtr->_M_start, buffer, dataLength*sizeof(NativeDataType)); - } - vectorPtr->_M_finish = vectorPtr->_M_start + dataLength; - vectorPtr->_M_end_of_storage = vectorPtr->_M_finish; - } - - - - - - // - // Required for template instantion for the compilation unit. - // Note: we only define those valid types for which Bulkio IDL is defined. Users wanting to - // inherit this functionality will be unable to since they cannot instantiate and - // link against the template. - // - - - template class DataTransfer< CharDataTransferTraits >; - template class DataTransfer< OctetDataTransferTraits >; - template class DataTransfer< ShortDataTransferTraits >; - template class DataTransfer< UShortDataTransferTraits >; - template class DataTransfer< LongDataTransferTraits >; - template class DataTransfer< ULongDataTransferTraits >; - template class DataTransfer< LongLongDataTransferTraits >; - template class DataTransfer< ULongLongDataTransferTraits >; - template class DataTransfer< FloatDataTransferTraits >; - template class DataTransfer< DoubleDataTransferTraits >; - template class DataTransfer< StringDataTransferTraits >; - - } // end of bulkio namespace diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_datatransfer.h b/bulkioInterfaces/libsrc/cpp/bulkio_datatransfer.h new file mode 100644 index 000000000..bdde48195 --- /dev/null +++ b/bulkioInterfaces/libsrc/cpp/bulkio_datatransfer.h @@ -0,0 +1,149 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK bulkioInterfaces. + * + * REDHAWK bulkioInterfaces is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK bulkioInterfaces is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +#ifndef __bulkio_datatransfer_h +#define __bulkio_datatransfer_h + +#include + +#include + +#include + +namespace bulkio { + namespace detail { + template + void assign(Tout& dest, const Tin& src) + { + dest = src; + } + + template + void assign_vector(std::vector& dest, const _CORBA_Sequence& src) + { + if (src.release()) { + _CORBA_Sequence& in = const_cast<_CORBA_Sequence&>(src); + const size_t length = in.length(); + typedef typename std::_Vector_base::_Vector_impl* VectorPtr; + VectorPtr vectorPtr = (VectorPtr)(&dest); + vectorPtr->_M_start = reinterpret_cast(in.get_buffer(1)); + vectorPtr->_M_finish = vectorPtr->_M_start + length; + vectorPtr->_M_end_of_storage = vectorPtr->_M_finish; + } else { + dest.assign(src.get_buffer(), src.get_buffer() + src.length()); + } + } + + template + void assign(std::vector& dest, const Tin& src) + { + assign_vector(dest, src); + } + + inline void assign(std::string& dest, const char* src) + { + if (src) { + dest = src; + } + } + } + + // + // DataTransfer + // + // This is the packet of information returned from an InPort's getPacket method. The DataTransferTraits class + // defines the type context for this structure. + // + // This class tries to implement as efficient as possible data movement from the supplied PortSequenceType object. + // The supplied PortSequenceType's data buffer is used to set the start/end/length attributes of the dataBuffer object that will + // be used by the component. This class takes ownership of the PortSequenceType's memory buffer and assigns it the + // the dataBuffer's start address. The DataBufferType allows developers to use standard + // stl iterators and algorithms against the data in this buffer. + // + // All remaining member variables use each type's assignment/copy methods. It is assumed the + // PrecisionUTCTime and StreamSRI object will perform a "deep" copy. + // + // + template + struct DataTransfer { + // + // Construct a DataTransfer object to be returned from an InPort's getPacket method + // + template + DataTransfer(const Tin& data, const BULKIO::PrecisionUTCTime& T, bool EOS, const char* streamID, + const BULKIO::StreamSRI& H, bool sriChanged, bool inputQueueFlushed) : + T(T), + EOS(EOS), + streamID(streamID), + SRI(H), + sriChanged(sriChanged), + inputQueueFlushed(inputQueueFlushed) + { + detail::assign(dataBuffer, data); + } + + DataBufferType dataBuffer; + BULKIO::PrecisionUTCTime T; + bool EOS; + std::string streamID; + BULKIO::StreamSRI SRI; + bool sriChanged; + bool inputQueueFlushed; + + redhawk::PropertyMap& getKeywords() + { + return redhawk::PropertyMap::cast(SRI.keywords); + } + + const redhawk::PropertyMap& getKeywords() const + { + return redhawk::PropertyMap::cast(SRI.keywords); + } + }; + + + struct StringDataTransfer : public DataTransfer + { + StringDataTransfer(const char* data, const BULKIO::PrecisionUTCTime& T, bool EOS, const char* streamID, + const BULKIO::StreamSRI& H, bool sriChanged, bool inputQueueFlushed) : + DataTransfer(data, T, EOS, streamID, H, sriChanged, inputQueueFlushed) + { + } + + StringDataTransfer(const char* data, bool EOS, const char* streamID, const BULKIO::StreamSRI&H, + bool sriChanged, bool inputQueueFlushed) : + DataTransfer(data, BULKIO::PrecisionUTCTime(), EOS, streamID, H, sriChanged, inputQueueFlushed) + { + } + }; + + typedef DataTransfer > CharDataTransfer; + typedef DataTransfer > OctetDataTransfer; + typedef DataTransfer > ShortDataTransfer; + typedef DataTransfer > UShortDataTransfer; + typedef DataTransfer > LongDataTransfer; + typedef DataTransfer > ULongDataTransfer; + typedef DataTransfer > LongLongDataTransfer; + typedef DataTransfer > ULongLongDataTransfer; + typedef DataTransfer > FloatDataTransfer; + typedef DataTransfer > DoubleDataTransfer; +} + +#endif // __bulkio_datatransfer_h diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp index ba88503ff..064a45251 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp @@ -30,11 +30,11 @@ namespace bulkio { // Source/Input Port Definitions // ---------------------------------------------------------------------------------------- - template < typename PortTraits > - InPort< PortTraits >::InPort(std::string port_name, - LOGGER_PTR logger, - bulkio::sri::Compare sriCmp, - SriListener *newStreamCB): + template + InPort::InPort(std::string port_name, + LOGGER_PTR logger, + bulkio::sri::Compare sriCmp, + SriListener *newStreamCB): Port_Provides_base_impl(port_name), sri_cmp(sriCmp), newStreamCallback(), @@ -71,8 +71,8 @@ namespace bulkio { - template < typename PortTraits > - InPort< PortTraits >::~InPort() + template + InPort::~InPort() { TRACE_ENTER( logger, "InPort::DTOR" ); @@ -95,8 +95,8 @@ namespace bulkio { - template < typename PortTraits > - BULKIO::PortStatistics * InPort< PortTraits >::statistics() + template + BULKIO::PortStatistics * InPort::statistics() { SCOPED_LOCK lock(dataBufferLock); BULKIO::PortStatistics_var recStat = new BULKIO::PortStatistics(stats->retrieve()); @@ -105,8 +105,8 @@ namespace bulkio { } - template < typename PortTraits > - BULKIO::PortUsageType InPort< PortTraits >::state() + template + BULKIO::PortUsageType InPort::state() { SCOPED_LOCK lock(dataBufferLock); if (packetQueue.size() == maxQueue) { @@ -121,8 +121,8 @@ namespace bulkio { } - template < typename PortTraits > - BULKIO::StreamSRISequence * InPort< PortTraits >::activeSRIs() + template + BULKIO::StreamSRISequence * InPort::activeSRIs() { SCOPED_LOCK lock(sriUpdateLock); BULKIO::StreamSRISequence_var retSRI = new BULKIO::StreamSRISequence(); @@ -134,29 +134,29 @@ namespace bulkio { return retSRI._retn(); } - template < typename PortTraits > - int InPort< PortTraits >::getMaxQueueDepth() + template + int InPort::getMaxQueueDepth() { SCOPED_LOCK lock(dataBufferLock); return maxQueue; } - template < typename PortTraits > - int InPort< PortTraits >::getCurrentQueueDepth() + template + int InPort::getCurrentQueueDepth() { SCOPED_LOCK lock(dataBufferLock); return packetQueue.size(); } - template < typename PortTraits > - void InPort< PortTraits >::setMaxQueueDepth(int newDepth) + template + void InPort::setMaxQueueDepth(int newDepth) { SCOPED_LOCK lock(dataBufferLock); maxQueue = newDepth; } - template < typename PortTraits > - void InPort< PortTraits >::pushSRI(const BULKIO::StreamSRI& H) + template + void InPort::pushSRI(const BULKIO::StreamSRI& H) { TRACE_ENTER( logger, "InPort::pushSRI" ); @@ -192,8 +192,8 @@ namespace bulkio { } - template < typename PortTraits > - void InPort< PortTraits >::queuePacket(const SharedBufferType& data, const BULKIO::PrecisionUTCTime& T, CORBA::Boolean EOS, const std::string& streamID) + template + void InPort::queuePacket(const BufferType& data, const BULKIO::PrecisionUTCTime& T, CORBA::Boolean EOS, const std::string& streamID) { TRACE_ENTER( logger, "InPort::pushPacket" ); // Discard packets for disabled streams @@ -287,9 +287,9 @@ namespace bulkio { } - template < typename PortTraits > - typename InPort< PortTraits >::Packet* InPort< PortTraits >::peekPacket(float timeout, - boost::unique_lock& lock) + template + typename InPort::Packet* InPort::peekPacket(float timeout, + boost::unique_lock& lock) { uint64_t secs = (unsigned long)(trunc(timeout)); uint64_t msecs = (unsigned long)((timeout - secs) * 1e6); @@ -313,8 +313,8 @@ namespace bulkio { } } - template < typename PortTraits > - void InPort< PortTraits >::enableStats( bool enable ) + template + void InPort::enableStats( bool enable ) { if (stats ) { stats->setEnabled(enable); @@ -322,8 +322,8 @@ namespace bulkio { } - template < typename PortTraits > - void InPort< PortTraits >::block() + template + void InPort::block() { TRACE_ENTER( logger, "InPort::block" ); breakBlock = true; @@ -332,32 +332,32 @@ namespace bulkio { TRACE_EXIT( logger, "InPort::block" ); } - template < typename PortTraits > - void InPort< PortTraits >::unblock() + template + void InPort::unblock() { breakBlock = false; } - template < typename PortTraits > - void InPort< PortTraits >::stopPort() + template + void InPort::stopPort() { block(); } - template < typename PortTraits > - void InPort< PortTraits >::startPort() + template + void InPort::startPort() { unblock(); } - template < typename PortTraits > - bool InPort< PortTraits >::blocked() + template + bool InPort::blocked() { return breakBlock; } - template < typename PortTraits > - typename InPort< PortTraits >::StreamType InPort< PortTraits >::getCurrentStream(float timeout) + template + typename InPort::StreamType InPort::getCurrentStream(float timeout) { // Prefer a stream that already has buffered data { @@ -380,8 +380,8 @@ namespace bulkio { return StreamType(); } - template < typename PortTraits > - typename InPort< PortTraits >::StreamType InPort< PortTraits >::getStream(const std::string& streamID) + template + typename InPort::StreamType InPort::getStream(const std::string& streamID) { boost::mutex::scoped_lock lock(streamsMutex); typename StreamMap::iterator stream = streams.find(streamID); @@ -392,8 +392,8 @@ namespace bulkio { } } - template < typename PortTraits > - typename InPort< PortTraits >::StreamList InPort< PortTraits >::getStreams() + template + typename InPort::StreamList InPort::getStreams() { StreamList result; boost::mutex::scoped_lock lock(streamsMutex); @@ -410,15 +410,15 @@ namespace bulkio { * timeout: the amount of time to wait for data before a NULL is returned. * Use 0.0 for non-blocking and -1 for blocking. */ - template < typename PortTraits > - typename InPort< PortTraits >::DataTransferType * InPort< PortTraits >::getPacket(float timeout) + template + typename InPort::DataTransferType * InPort::getPacket(float timeout) { return getPacket(timeout, ""); } - template < typename PortTraits > - typename InPort< PortTraits >::DataTransferType * InPort< PortTraits >::getPacket(float timeout, const std::string& streamID) + template + typename InPort::DataTransferType * InPort::getPacket(float timeout, const std::string& streamID) { DataTransferType* transfer = 0; boost::scoped_ptr packet(nextPacket(timeout, streamID)); @@ -430,8 +430,8 @@ namespace bulkio { } - template - typename InPort::Packet* InPort::nextPacket(float timeout, const std::string& streamID) + template + typename InPort::Packet* InPort::nextPacket(float timeout, const std::string& streamID) { TRACE_ENTER(logger, "InPort::nextPacket"); if (breakBlock) { @@ -528,8 +528,8 @@ namespace bulkio { } } - template < typename PortTraits > - void InPort< PortTraits >::createStream(const std::string& streamID, + template + void InPort::createStream(const std::string& streamID, const bulkio::StreamDescriptor& sri) { StreamType stream(sri, this); @@ -549,8 +549,8 @@ namespace bulkio { } } - template < typename PortTraits > - typename InPort< PortTraits >::Packet * InPort< PortTraits >::fetchPacket(const std::string &streamID) + template + typename InPort::Packet * InPort::fetchPacket(const std::string &streamID) { if (streamID.empty()) { if (packetQueue.empty()) { @@ -571,8 +571,8 @@ namespace bulkio { return 0; } - template < typename PortTraits > - void InPort< PortTraits >::discardPacketsForStream(const std::string& streamID) + template + void InPort::discardPacketsForStream(const std::string& streamID) { SCOPED_LOCK lock(dataBufferLock); for (typename PacketQueue::iterator ii = packetQueue.begin(); ii != packetQueue.end();) { @@ -590,19 +590,19 @@ namespace bulkio { } } - template < typename PortTraits > - std::string InPort< PortTraits >::getRepid() const { + template + std::string InPort::getRepid() const { return PortType::_PD_repoId; } - template < typename PortTraits > - int InPort< PortTraits >::_getElementLength(const SharedBufferType& data) + template + int InPort::_getElementLength(const BufferType& data) { return data.size(); } - template < typename PortTraits > - size_t InPort< PortTraits >::samplesAvailable (const std::string& streamID, bool firstPacket) + template + size_t InPort::samplesAvailable (const std::string& streamID, bool firstPacket) { size_t samples = 0; size_t item_size = 1; @@ -624,8 +624,8 @@ namespace bulkio { return samples / item_size; } - template < typename PortTraits > - void InPort< PortTraits >::removeStream(const std::string& streamID) + template + void InPort::removeStream(const std::string& streamID) { LOG_DEBUG(logger, "Removing stream " << streamID); boost::mutex::scoped_lock lock(streamsMutex); @@ -642,8 +642,8 @@ namespace bulkio { } } - template < typename PortTraits > - bool InPort< PortTraits >::isStreamActive(const std::string& streamID) + template + bool InPort::isStreamActive(const std::string& streamID) { SCOPED_LOCK lock(streamsMutex); if (pendingStreams.count(streamID) > 0) { @@ -656,8 +656,8 @@ namespace bulkio { return true; } - template < typename PortTraits > - bool InPort< PortTraits >::isStreamEnabled(const std::string& streamID) + template + bool InPort::isStreamEnabled(const std::string& streamID) { SCOPED_LOCK lock(streamsMutex); if (pendingStreams.count(streamID) == 0) { @@ -700,57 +700,57 @@ namespace bulkio { */ template <> - int InPort< FilePortTraits >::_getElementLength(const std::string& /*unused*/) + int InPort::_getElementLength(const std::string& /*unused*/) { return 1; } // - template < typename PortTraits > - InNumericPort< PortTraits >::InNumericPort(std::string port_name, - LOGGER_PTR logger, - bulkio::sri::Compare compareSri, - SriListener *newStreamCB ) : - InPort(port_name, logger, compareSri, newStreamCB) + template + InNumericPort::InNumericPort(std::string port_name, + LOGGER_PTR logger, + bulkio::sri::Compare compareSri, + SriListener *newStreamCB) : + InPort(port_name, logger, compareSri, newStreamCB) { } - template < typename PortTraits > - InNumericPort< PortTraits >::InNumericPort(std::string port_name, - bulkio::sri::Compare compareSri, - SriListener *newStreamCB ) : - InPort(port_name, LOGGER_PTR(), compareSri, newStreamCB) + template + InNumericPort::InNumericPort(std::string port_name, + bulkio::sri::Compare compareSri, + SriListener *newStreamCB) : + InPort(port_name, LOGGER_PTR(), compareSri, newStreamCB) { } - template < typename PortTraits > - InNumericPort< PortTraits >::InNumericPort(std::string port_name, void* /*unused*/) : - InPort(port_name, LOGGER_PTR()) + template + InNumericPort::InNumericPort(std::string port_name, void* /*unused*/) : + InPort(port_name, LOGGER_PTR()) { } - template < typename PortTraits > - void InNumericPort< PortTraits >::pushPacket(const PortSequenceType& data, const BULKIO::PrecisionUTCTime& T, CORBA::Boolean EOS, const char* streamID) + template + void InNumericPort::pushPacket(const PortSequenceType& data, const BULKIO::PrecisionUTCTime& T, CORBA::Boolean EOS, const char* streamID) { size_t size = data.length(); TransportType* ptr = const_cast(data).get_buffer(1); - this->queuePacket(SharedBufferType(reinterpret_cast(ptr), size), T, EOS, streamID); + this->queuePacket(BufferType(reinterpret_cast(ptr), size), T, EOS, streamID); } - template < typename PortTraits > - typename InNumericPort< PortTraits >::StreamList InNumericPort< PortTraits >::pollStreams(float timeout) + template + typename InNumericPort::StreamList InNumericPort::pollStreams(float timeout) { return pollStreams(0, timeout); } - template < typename PortTraits > - typename InNumericPort< PortTraits >::StreamList InNumericPort< PortTraits >::pollStreams(StreamList& pollset, float timeout) + template + typename InNumericPort::StreamList InNumericPort::pollStreams(StreamList& pollset, float timeout) { return pollStreams(pollset, 0, timeout); } - template < typename PortTraits > - typename InNumericPort< PortTraits >::StreamList InNumericPort< PortTraits >::pollStreams(size_t samples, float timeout) + template + typename InNumericPort::StreamList InNumericPort::pollStreams(size_t samples, float timeout) { redhawk::signal::waiter waiter(&packetWaiters, timeout); @@ -768,8 +768,8 @@ namespace bulkio { return result; } - template < typename PortTraits > - typename InNumericPort< PortTraits >::StreamList InNumericPort< PortTraits >::pollStreams(StreamList& pollset, size_t samples, float timeout) + template + typename InNumericPort::StreamList InNumericPort::pollStreams(StreamList& pollset, size_t samples, float timeout) { redhawk::signal::waiter waiter(&packetWaiters, timeout); @@ -793,8 +793,8 @@ namespace bulkio { return result; } - template < typename PortTraits > - typename InNumericPort< PortTraits >::StreamList InNumericPort< PortTraits >::getReadyStreams(size_t samples) + template + typename InNumericPort::StreamList InNumericPort::getReadyStreams(size_t samples) { StreamList result; boost::mutex::scoped_lock lock(streamsMutex); @@ -814,7 +814,7 @@ namespace bulkio { LOGGER_PTR logger, bulkio::sri::Compare compareSri, SriListener *newStreamCB) : - InPort(port_name, logger, compareSri, newStreamCB) + InPort(port_name, logger, compareSri, newStreamCB) { } @@ -822,12 +822,12 @@ namespace bulkio { InFilePort::InFilePort(std::string port_name, bulkio::sri::Compare compareSri, SriListener *newStreamCB) : - InPort(port_name, LOGGER_PTR(), compareSri, newStreamCB) + InPort(port_name, LOGGER_PTR(), compareSri, newStreamCB) { } InFilePort::InFilePort(std::string port_name, void* /*unused*/) : - InPort(port_name, LOGGER_PTR()) + InPort(port_name, LOGGER_PTR()) { } @@ -845,7 +845,7 @@ namespace bulkio { LOGGER_PTR logger, bulkio::sri::Compare compareSri, SriListener* newStreamCB) : - InPort(name, logger, compareSri, newStreamCB) + InPort(name, logger, compareSri, newStreamCB) { } @@ -853,12 +853,12 @@ namespace bulkio { InXMLPort::InXMLPort(std::string name, bulkio::sri::Compare compareSri, SriListener* newStreamCB) : - InPort(name, LOGGER_PTR(), compareSri, newStreamCB) + InPort(name, LOGGER_PTR(), compareSri, newStreamCB) { } InXMLPort::InXMLPort(std::string name, void* /*unused*/) : - InPort(name, LOGGER_PTR()) + InPort(name, LOGGER_PTR()) { } @@ -895,18 +895,18 @@ namespace bulkio { #define INSTANTIATE_NUMERIC_TEMPLATE(x) \ INSTANTIATE_TEMPLATE(x); template class InNumericPort; - INSTANTIATE_NUMERIC_TEMPLATE(CharPortTraits); - INSTANTIATE_NUMERIC_TEMPLATE(OctetPortTraits); - INSTANTIATE_NUMERIC_TEMPLATE(ShortPortTraits); - INSTANTIATE_NUMERIC_TEMPLATE(UShortPortTraits); - INSTANTIATE_NUMERIC_TEMPLATE(LongPortTraits); - INSTANTIATE_NUMERIC_TEMPLATE(ULongPortTraits); - INSTANTIATE_NUMERIC_TEMPLATE(LongLongPortTraits); - INSTANTIATE_NUMERIC_TEMPLATE(ULongLongPortTraits); - INSTANTIATE_NUMERIC_TEMPLATE(FloatPortTraits); - INSTANTIATE_NUMERIC_TEMPLATE(DoublePortTraits); - - INSTANTIATE_TEMPLATE(FilePortTraits); - INSTANTIATE_TEMPLATE(XMLPortTraits); + INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataChar); + INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataOctet); + INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataShort); + INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataUshort); + INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataLong); + INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataUlong); + INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataLongLong); + INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataUlongLong); + INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataFloat); + INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataDouble); + + INSTANTIATE_TEMPLATE(BULKIO::dataFile); + INSTANTIATE_TEMPLATE(BULKIO::dataXML); } // end of bulkio namespace diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h index ae94595a4..a5ffebc5c 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h @@ -30,15 +30,31 @@ #include #include "bulkio_base.h" -#include "bulkio_traits.h" +#include "bulkio_typetraits.h" +#include "bulkio_datatransfer.h" #include "bulkio_in_stream.h" #include "bulkio_callbacks.h" namespace bulkio { - template + template class LocalTransport; + template + struct InStreamTraits { + typedef BufferedInputStream InStreamType; + }; + + template <> + struct InStreamTraits { + typedef InXMLStream InStreamType; + }; + + template <> + struct InStreamTraits { + typedef InFileStream InStreamType; + }; + // // InPort // Base template for data transfers between BULKIO ports. This class is defined by 2 trait classes @@ -46,33 +62,29 @@ namespace bulkio { // PortTraits - This template provides the context for the port's middleware transport classes and they base data types // passed between port objects // - template < typename PortTraits > - class InPort : public PortTraits::POAPortType, public Port_Provides_base_impl + template + class InPort : public CorbaTraits::POAType, public Port_Provides_base_impl { - public: - - typedef PortTraits Traits; - // Transport Sequence Type use to during push packet - typedef typename Traits::SequenceType PortSequenceType; + typedef typename CorbaTraits::SequenceType PortSequenceType; // // Transport type used by this port // - typedef typename Traits::TransportType TransportType; - - typedef typename Traits::PortType PortType; + typedef typename CorbaTraits::TransportType TransportType; // // Declaration of DataTransfer class from TransportType trait and DataBuffer type trait // - typedef DataTransfer< typename Traits::DataTransferTraits > DataTransferType; + typedef typename BufferTraits::VectorType VectorType; + typedef DataTransfer DataTransferType; + + // backwards compatible definition + typedef DataTransferType dataTransfer; - typedef typename Traits::SharedBufferType SharedBufferType; - // Input stream interface used by this port - typedef typename StreamTraits::InStreamType StreamType; + typedef typename InStreamTraits::InStreamType StreamType; // List type for input streams provided by this port typedef std::list StreamList; @@ -260,12 +272,14 @@ namespace bulkio { // if all members match then return true, otherwise false. This is used during the pushSRI method // @param newStreamCB interface that is called when new SRI.streamID is received InPort(std::string port_name, - LOGGER_PTR logger, - bulkio::sri::Compare sriCmp = bulkio::sri::DefaultComparator, - SriListener *newStreamCB = NULL ); + LOGGER_PTR logger, + bulkio::sri::Compare sriCmp = bulkio::sri::DefaultComparator, + SriListener *newStreamCB = NULL ); + typedef typename BufferTraits::BufferType BufferType; + struct Packet { - Packet(const SharedBufferType& buffer, const BULKIO::PrecisionUTCTime& T, bool EOS, const StreamDescriptor& SRI, bool sriChanged, bool inputQueueFlushed) : + Packet(const BufferType& buffer, const BULKIO::PrecisionUTCTime& T, bool EOS, const StreamDescriptor& SRI, bool sriChanged, bool inputQueueFlushed) : buffer(buffer), T(T), EOS(EOS), @@ -276,7 +290,7 @@ namespace bulkio { { } - SharedBufferType buffer; + BufferType buffer; BULKIO::PrecisionUTCTime T; bool EOS; StreamDescriptor SRI; @@ -362,10 +376,10 @@ namespace bulkio { // Queues a packet received via pushPacket; in most cases, this method maps // exactly to pushPacket, except for dataFile // - void queuePacket(const SharedBufferType& data, const BULKIO::PrecisionUTCTime& T, CORBA::Boolean EOS, const std::string& streamID); + void queuePacket(const BufferType& data, const BULKIO::PrecisionUTCTime& T, CORBA::Boolean EOS, const std::string& streamID); // Allow local transport classes to directly queue packets - friend class LocalTransport; + friend class LocalTransport; // // Fetches the next packet for the given stream ID, blocking for up to @@ -385,7 +399,7 @@ namespace bulkio { // first end-of-stream void discardPacketsForStream(const std::string& streamID); - friend class InputStream; + friend class InputStream; size_t samplesAvailable(const std::string& streamID, bool firstPacket); void createStream(const std::string& streamID, const StreamDescriptor& sri); @@ -399,45 +413,29 @@ namespace bulkio { // statistical tracking; enables XML and File specialization, which have // different notions of size // - int _getElementLength(const SharedBufferType& data); + int _getElementLength(const BufferType& data); }; - template < typename PortTraits > - class InNumericPort : public InPort + template + class InNumericPort : public InPort { public: - typedef PortTraits Traits; - - // Interface Type - typedef typename Traits::PortType PortType; - // Transport Sequence Type use to during push packet - typedef typename Traits::SequenceType PortSequenceType; - - // Shared buffer type used for local transfers - typedef typename Traits::SharedBufferType SharedBufferType; + typedef typename InPort::PortSequenceType PortSequenceType; // // Transport type used by this port // - typedef typename Traits::TransportType TransportType; + typedef typename InPort::TransportType TransportType; // // Native type mapping of TransportType // - typedef typename Traits::NativeType NativeType; - - // - // Declaration of DataTransfer class from TransportType trait and DataBuffer type trait - // - typedef DataTransfer< typename Traits::DataTransferTraits > DataTransferType; - - // backwards compatible definition - typedef DataTransferType dataTransfer; + typedef typename NativeTraits::NativeType NativeType; - typedef typename InPort::StreamType StreamType; + typedef typename InPort::StreamType StreamType; - typedef typename InPort::StreamList StreamList; + typedef typename InPort::StreamList StreamList; // // InNumericPort - creates a provides port that can accept data vectors from a source @@ -478,7 +476,10 @@ namespace bulkio { StreamList pollStreams(StreamList& pollset, size_t samples, float timeout); protected: - typedef InPort super; + // Shared buffer type used for local transfers + typedef typename InPort::BufferType BufferType; + + typedef InPort super; using super::packetWaiters; using super::logger; typedef typename super::StreamMap StreamMap; @@ -501,12 +502,9 @@ namespace bulkio { // - class InFilePort : public InPort + class InFilePort : public InPort { public: - typedef InPort::DataTransferType DataTransferType; - typedef DataTransferType dataTransfer; - // // InStringPort - creates a provides port that can accept floating point vectors from a source // @@ -538,12 +536,9 @@ namespace bulkio { }; - class InXMLPort : public InPort + class InXMLPort : public InPort { public: - typedef InPort::DataTransferType DataTransferType; - typedef DataTransferType dataTransfer; - InXMLPort(std::string port_name, LOGGER_PTR logger, bulkio::sri::Compare=bulkio::sri::DefaultComparator, SriListener* newStreamCB=NULL); @@ -572,41 +567,41 @@ namespace bulkio { * */ // Bulkio char (Int8) input - typedef InNumericPort InCharPort; + typedef InNumericPort InCharPort; // Bulkio octet (UInt8) input - typedef InNumericPort InOctetPort; + typedef InNumericPort InOctetPort; // Bulkio Int8 input - typedef InCharPort InInt8Port; + typedef InCharPort InInt8Port; // Bulkio UInt8 input - typedef InOctetPort InUInt8Port; + typedef InOctetPort InUInt8Port; // Bulkio short (Int16) input - typedef InNumericPort InShortPort; + typedef InNumericPort InShortPort; // Bulkio unsigned short (UInt16) input - typedef InNumericPort InUShortPort; + typedef InNumericPort InUShortPort; // Bulkio Int16 input - typedef InShortPort InInt16Port; + typedef InShortPort InInt16Port; // Bulkio UInt16 input - typedef InUShortPort InUInt16Port; + typedef InUShortPort InUInt16Port; // Bulkio long (Int32) input - typedef InNumericPort InLongPort; + typedef InNumericPort InLongPort; // Bulkio unsigned long (UInt32) input - typedef InNumericPort InULongPort; + typedef InNumericPort InULongPort; // Bulkio Int32 input - typedef InLongPort InInt32Port; + typedef InLongPort InInt32Port; // Bulkio UInt32 input - typedef InULongPort InUInt32Port; + typedef InULongPort InUInt32Port; // Bulkio long long (Int64) input - typedef InNumericPort InLongLongPort; + typedef InNumericPort InLongLongPort; // Bulkio unsigned long long (UInt64) input - typedef InNumericPort InULongLongPort; + typedef InNumericPort InULongLongPort; // Bulkio Int64 input - typedef InLongLongPort InInt64Port; + typedef InLongLongPort InInt64Port; // Bulkio UInt64 input - typedef InULongLongPort InUInt64Port; + typedef InULongLongPort InUInt64Port; // Bulkio float input - typedef InNumericPort InFloatPort; + typedef InNumericPort InFloatPort; // Bulkio double input - typedef InNumericPort InDoublePort; + typedef InNumericPort InDoublePort; // Maintained for backwards compatibility typedef InFilePort InURLPort; diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp index 5cb48073e..9d3f0f1e5 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp @@ -28,8 +28,8 @@ using bulkio::InputStream; -template -class InputStream::Impl : public StreamBase::Impl { +template +class InputStream::Impl : public StreamBase::Impl { public: typedef StreamBase::Impl ImplBase; @@ -159,80 +159,80 @@ class InputStream::Impl : public StreamBase::Impl { bool _enabled; }; -template -InputStream::InputStream() : +template +InputStream::InputStream() : StreamBase() { } -template -InputStream::InputStream(const StreamDescriptor& sri, InPortType* port) : +template +InputStream::InputStream(const StreamDescriptor& sri, InPortType* port) : StreamBase(boost::make_shared(sri, port)) { } -template -InputStream::InputStream(const boost::shared_ptr& impl) : +template +InputStream::InputStream(const boost::shared_ptr& impl) : StreamBase(impl) { } -template -typename InputStream::DataBlockType InputStream::read() +template +typename InputStream::DataBlockType InputStream::read() { return impl().readPacket(true); } -template -typename InputStream::DataBlockType InputStream::tryread() +template +typename InputStream::DataBlockType InputStream::tryread() { return impl().readPacket(false); } -template -bool InputStream::enabled() const +template +bool InputStream::enabled() const { return impl().enabled(); } -template -void InputStream::enable() +template +void InputStream::enable() { impl().enable(); } -template -void InputStream::disable() +template +void InputStream::disable() { impl().disable(); } -template -bool InputStream::eos() +template +bool InputStream::eos() { return impl().eos(); } -template -InputStream::operator unspecified_bool_type() const +template +InputStream::operator unspecified_bool_type() const { return _impl?static_cast(&InputStream::impl):0; } -template -typename InputStream::Impl& InputStream::impl() +template +typename InputStream::Impl& InputStream::impl() { return static_cast(*this->_impl); } -template -const typename InputStream::Impl& InputStream::impl() const +template +const typename InputStream::Impl& InputStream::impl() const { return static_cast(*this->_impl); } -template -bool InputStream::hasBufferedData() +template +bool InputStream::hasBufferedData() { return impl().hasBufferedData(); } @@ -240,14 +240,14 @@ bool InputStream::hasBufferedData() using bulkio::BufferedInputStream; -template -class BufferedInputStream::Impl : public Base::Impl { +template +class BufferedInputStream::Impl : public Base::Impl { public: typedef typename Base::Impl ImplBase; typedef typename ImplBase::PacketType PacketType; - typedef typename PortTraits::NativeType NativeType; - typedef typename PortTraits::SharedBufferType SharedBufferType; + typedef typename NativeTraits::NativeType NativeType; + typedef typename BufferTraits::BufferType BufferType; Impl(const bulkio::StreamDescriptor& sri, InPortType* port) : ImplBase(sri, port), @@ -432,7 +432,7 @@ class BufferedInputStream::Impl : public Base::Impl { void _consumeData(size_t count) { while (count > 0) { - const SharedBufferType& data = _queue.front().buffer; + const BufferType& data = _queue.front().buffer; const size_t available = data.size() - _sampleOffset; const size_t pass = std::min(available, count); @@ -495,7 +495,7 @@ class BufferedInputStream::Impl : public Base::Impl { size_t packet_offset = _sampleOffset; while (count > 0) { PacketType& packet = _queue[packet_index]; - const SharedBufferType& input_data = packet.buffer; + const BufferType& input_data = packet.buffer; // Add the timestamp for this pass _addTimestamp(data, packet_offset, data_offset, packet.T); @@ -616,86 +616,86 @@ class BufferedInputStream::Impl : public Base::Impl { }; -template -BufferedInputStream::BufferedInputStream() : +template +BufferedInputStream::BufferedInputStream() : Base() { } -template -BufferedInputStream::BufferedInputStream(const bulkio::StreamDescriptor& sri, InPortType* port) : +template +BufferedInputStream::BufferedInputStream(const bulkio::StreamDescriptor& sri, InPortType* port) : Base(boost::make_shared(sri, port)) { } -template -typename BufferedInputStream::DataBlockType BufferedInputStream::read() +template +typename BufferedInputStream::DataBlockType BufferedInputStream::read() { return impl().readPacket(true); } -template -typename BufferedInputStream::DataBlockType BufferedInputStream::read(size_t count) +template +typename BufferedInputStream::DataBlockType BufferedInputStream::read(size_t count) { return impl().read(count, count, true); } -template -typename BufferedInputStream::DataBlockType BufferedInputStream::read(size_t count, size_t consume) +template +typename BufferedInputStream::DataBlockType BufferedInputStream::read(size_t count, size_t consume) { return impl().read(count, consume, true); } -template -typename BufferedInputStream::DataBlockType BufferedInputStream::tryread() +template +typename BufferedInputStream::DataBlockType BufferedInputStream::tryread() { return impl().readPacket(false); } -template -typename BufferedInputStream::DataBlockType BufferedInputStream::tryread(size_t count) +template +typename BufferedInputStream::DataBlockType BufferedInputStream::tryread(size_t count) { return impl().read(count, count, false); } -template -typename BufferedInputStream::DataBlockType BufferedInputStream::tryread(size_t count, size_t consume) +template +typename BufferedInputStream::DataBlockType BufferedInputStream::tryread(size_t count, size_t consume) { return impl().read(count, consume, false); } -template -size_t BufferedInputStream::skip(size_t count) +template +size_t BufferedInputStream::skip(size_t count) { return impl().skip(count); } -template -size_t BufferedInputStream::samplesAvailable() +template +size_t BufferedInputStream::samplesAvailable() { return impl().samplesAvailable(); } -template -bool BufferedInputStream::operator==(const BufferedInputStream& other) const +template +bool BufferedInputStream::operator==(const BufferedInputStream& other) const { return _impl.get() == other._impl.get(); } -template -bool BufferedInputStream::ready() +template +bool BufferedInputStream::ready() { return impl().ready(); } -template -typename BufferedInputStream::Impl& BufferedInputStream::impl() +template +typename BufferedInputStream::Impl& BufferedInputStream::impl() { return static_cast(Base::impl()); } -template -const typename BufferedInputStream::Impl& BufferedInputStream::impl() const +template +const typename BufferedInputStream::Impl& BufferedInputStream::impl() const { return static_cast(Base::impl()); } @@ -706,15 +706,15 @@ const typename BufferedInputStream::Impl& BufferedInputStream; -INSTANTIATE_NUMERIC_TEMPLATE(bulkio::CharPortTraits); -INSTANTIATE_NUMERIC_TEMPLATE(bulkio::OctetPortTraits); -INSTANTIATE_NUMERIC_TEMPLATE(bulkio::ShortPortTraits); -INSTANTIATE_NUMERIC_TEMPLATE(bulkio::UShortPortTraits); -INSTANTIATE_NUMERIC_TEMPLATE(bulkio::LongPortTraits); -INSTANTIATE_NUMERIC_TEMPLATE(bulkio::ULongPortTraits); -INSTANTIATE_NUMERIC_TEMPLATE(bulkio::LongLongPortTraits); -INSTANTIATE_NUMERIC_TEMPLATE(bulkio::ULongLongPortTraits); -INSTANTIATE_NUMERIC_TEMPLATE(bulkio::FloatPortTraits); -INSTANTIATE_NUMERIC_TEMPLATE(bulkio::DoublePortTraits); -INSTANTIATE_TEMPLATE(bulkio::XMLPortTraits); -INSTANTIATE_TEMPLATE(bulkio::FilePortTraits); +INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataChar); +INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataOctet); +INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataShort); +INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataUshort); +INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataLong); +INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataUlong); +INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataLongLong); +INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataUlongLong); +INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataFloat); +INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataDouble); +INSTANTIATE_TEMPLATE(BULKIO::dataXML); +INSTANTIATE_TEMPLATE(BULKIO::dataFile); diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.h b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.h index de17aa598..3b67eb335 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.h @@ -26,34 +26,34 @@ #include -#include "bulkio_traits.h" +#include "bulkio_typetraits.h" #include "bulkio_datablock.h" #include "bulkio_stream.h" namespace bulkio { - template + template class InPort; - template + template struct BlockTraits { - typedef SampleDataBlock DataBlockType; + typedef SampleDataBlock::NativeType> DataBlockType; }; template <> - struct BlockTraits { + struct BlockTraits { typedef StringDataBlock DataBlockType; }; template <> - struct BlockTraits { + struct BlockTraits { typedef StringDataBlock DataBlockType; }; - template + template class InputStream : public StreamBase { public: - typedef typename BlockTraits::DataBlockType DataBlockType; + typedef typename BlockTraits::DataBlockType DataBlockType; DataBlockType read(); @@ -66,7 +66,7 @@ namespace bulkio { bool eos(); protected: - typedef InPort InPortType; + typedef InPort InPortType; class Impl; Impl& impl(); @@ -78,7 +78,7 @@ namespace bulkio { InputStream(const boost::shared_ptr& impl); // Allow matching InPort class to create instances of this stream type - friend class InPort; + friend class InPort; InputStream(const StreamDescriptor& sri, InPortType* port); bool hasBufferedData(); @@ -88,12 +88,12 @@ namespace bulkio { }; - template - class BufferedInputStream : public InputStream { + template + class BufferedInputStream : public InputStream { public: BufferedInputStream(); - typedef typename InputStream::DataBlockType DataBlockType; + typedef typename InputStream::DataBlockType DataBlockType; DataBlockType read(); DataBlockType read(size_t count); @@ -112,11 +112,11 @@ namespace bulkio { bool ready(); private: - typedef InputStream Base; + typedef InputStream Base; using Base::_impl; - friend class InPort; - typedef InPort InPortType; + friend class InPort; + typedef InPort InPortType; BufferedInputStream(const StreamDescriptor&, InPortType*); class Impl; @@ -124,33 +124,18 @@ namespace bulkio { const Impl& impl() const; }; - typedef BufferedInputStream InCharStream; - typedef BufferedInputStream InOctetStream; - typedef BufferedInputStream InShortStream; - typedef BufferedInputStream InUShortStream; - typedef BufferedInputStream InLongStream; - typedef BufferedInputStream InULongStream; - typedef BufferedInputStream InLongLongStream; - typedef BufferedInputStream InULongLongStream; - typedef BufferedInputStream InFloatStream; - typedef BufferedInputStream InDoubleStream; - typedef InputStream InXMLStream; - typedef InputStream InFileStream; - - template - struct StreamTraits { - typedef BufferedInputStream InStreamType; - }; - - template <> - struct StreamTraits { - typedef InXMLStream InStreamType; - }; - - template <> - struct StreamTraits { - typedef InFileStream InStreamType; - }; + typedef BufferedInputStream InCharStream; + typedef BufferedInputStream InOctetStream; + typedef BufferedInputStream InShortStream; + typedef BufferedInputStream InUShortStream; + typedef BufferedInputStream InLongStream; + typedef BufferedInputStream InULongStream; + typedef BufferedInputStream InLongLongStream; + typedef BufferedInputStream InULongLongStream; + typedef BufferedInputStream InFloatStream; + typedef BufferedInputStream InDoubleStream; + typedef InputStream InXMLStream; + typedef InputStream InFileStream; } // end of bulkio namespace diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp index 5aa28225d..12651f01f 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp @@ -37,8 +37,8 @@ namespace bulkio { Accepts connect/disconnect interfaces for notification when these events occur */ - template < typename PortTraits > - OutPort< PortTraits >::OutPort(const std::string& name, + template + OutPort::OutPort(const std::string& name, LOGGER_PTR logger, ConnectionEventListener *connectCB, ConnectionEventListener *disconnectCB) : @@ -65,14 +65,14 @@ namespace bulkio { } - template < typename PortTraits > - OutPort< PortTraits >::~OutPort(){ + template + OutPort::~OutPort(){ } - template < typename PortTraits > - void OutPort< PortTraits >::pushSRI(const BULKIO::StreamSRI& H) + template + void OutPort::pushSRI(const BULKIO::StreamSRI& H) { TRACE_ENTER(logger, "OutPort::pushSRI" ); @@ -117,24 +117,24 @@ namespace bulkio { TRACE_EXIT(logger, "OutPort::pushSRI"); } - template < typename PortTraits > - void OutPort< PortTraits >::_connectListenerAdapter(const std::string& connectionId) + template + void OutPort::_connectListenerAdapter(const std::string& connectionId) { if (_connectCB) { (*_connectCB)(connectionId.c_str()); } } - template < typename PortTraits > - void OutPort< PortTraits >::_disconnectListenerAdapter(const std::string& connectionId) + template + void OutPort::_disconnectListenerAdapter(const std::string& connectionId) { if (_disconnectCB) { (*_disconnectCB)(connectionId.c_str()); } } - template < typename PortTraits > - bool OutPort< PortTraits >::_isStreamRoutedToConnection( + template + bool OutPort::_isStreamRoutedToConnection( const std::string& streamID, const std::string& connectionID) { @@ -154,8 +154,8 @@ namespace bulkio { } - template < typename PortTraits > - typename OutPort::StreamType OutPort< PortTraits >::_getStream(const std::string& streamID) + template + typename OutPort::StreamType OutPort::_getStream(const std::string& streamID) { typename StreamMap::iterator existing = streams.find(streamID); if (existing == streams.end()) { @@ -172,9 +172,9 @@ namespace bulkio { } - template < typename PortTraits > - void OutPort< PortTraits >::_sendPacket( - const SharedBufferType& data, + template + void OutPort::_sendPacket( + const BufferType& data, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID) @@ -219,8 +219,8 @@ namespace bulkio { } - template < typename PortTraits > - BULKIO::UsesPortStatisticsSequence* OutPort< PortTraits >::statistics() + template + BULKIO::UsesPortStatisticsSequence* OutPort::statistics() { SCOPED_LOCK lock(updatingPortsLock); BULKIO::UsesPortStatisticsSequence_var recStat = new BULKIO::UsesPortStatisticsSequence(); @@ -234,8 +234,8 @@ namespace bulkio { return recStat._retn(); } - template < typename PortTraits > - BULKIO::PortUsageType OutPort< PortTraits >::state() + template + BULKIO::PortUsageType OutPort::state() { SCOPED_LOCK lock(updatingPortsLock); if (_transports.empty()) { @@ -245,8 +245,8 @@ namespace bulkio { } } - template < typename PortTraits > - void OutPort< PortTraits >::enableStats(bool enable) + template + void OutPort::enableStats(bool enable) { SCOPED_LOCK lock(updatingPortsLock); for (TransportIterator port = _transports.begin(); port != _transports.end(); ++port) { @@ -255,9 +255,9 @@ namespace bulkio { } - template < typename PortTraits > + template redhawk::BasicTransport* - OutPort< PortTraits >::_createTransport(CORBA::Object_ptr object, const std::string& connectionId) + OutPort::_createTransport(CORBA::Object_ptr object, const std::string& connectionId) { PortVarType port; try { @@ -280,8 +280,8 @@ namespace bulkio { } - template - typename OutPort::StreamType OutPort::getStream(const std::string& streamID) + template + typename OutPort::StreamType OutPort::getStream(const std::string& streamID) { boost::mutex::scoped_lock lock(updatingPortsLock); typename StreamMap::iterator stream = streams.find(streamID); @@ -292,8 +292,8 @@ namespace bulkio { } } - template - typename OutPort::StreamList OutPort::getStreams() + template + typename OutPort::StreamList OutPort::getStreams() { StreamList result; boost::mutex::scoped_lock lock(updatingPortsLock); @@ -303,8 +303,8 @@ namespace bulkio { return result; } - template < typename PortTraits > - typename OutPort< PortTraits >::StreamType OutPort< PortTraits >::createStream(const std::string& streamID) + template + typename OutPort::StreamType OutPort::createStream(const std::string& streamID) { boost::mutex::scoped_lock lock(updatingPortsLock); typename StreamMap::iterator existing = streams.find(streamID); @@ -316,8 +316,8 @@ namespace bulkio { return stream; } - template < typename PortTraits > - typename OutPort< PortTraits >::StreamType OutPort< PortTraits >::createStream(const BULKIO::StreamSRI& sri) + template + typename OutPort::StreamType OutPort::createStream(const BULKIO::StreamSRI& sri) { boost::mutex::scoped_lock lock(updatingPortsLock); const std::string streamID(sri.streamID); @@ -332,8 +332,8 @@ namespace bulkio { return stream; } - template < typename PortTraits > - bulkio::SriMap OutPort< PortTraits >::getCurrentSRI() + template + bulkio::SriMap OutPort::getCurrentSRI() { bulkio::SriMap ret; SCOPED_LOCK lock(updatingPortsLock); // restrict access till method completes @@ -343,8 +343,8 @@ namespace bulkio { return ret; } - template < typename PortTraits > - bulkio::SriList OutPort< PortTraits >::getActiveSRIs() + template + bulkio::SriList OutPort::getActiveSRIs() { bulkio::SriList ret; SCOPED_LOCK lock(updatingPortsLock); // restrict access till method completes @@ -355,8 +355,8 @@ namespace bulkio { } - template < typename PortTraits > - typename OutPort< PortTraits >::ConnectionsList OutPort< PortTraits >::getConnections() + template + typename OutPort::ConnectionsList OutPort::getConnections() { SCOPED_LOCK lock(updatingPortsLock); // restrict access till method completes ConnectionsList outConnections; @@ -370,32 +370,32 @@ namespace bulkio { } - template < typename PortTraits > - void OutPort< PortTraits >::setNewConnectListener(ConnectionEventListener *newListener) + template + void OutPort::setNewConnectListener(ConnectionEventListener *newListener) { _connectCB = boost::shared_ptr< ConnectionEventListener >(newListener, null_deleter()); } - template < typename PortTraits > - void OutPort< PortTraits >::setNewConnectListener(ConnectionEventCallbackFn newListener) + template + void OutPort::setNewConnectListener(ConnectionEventCallbackFn newListener) { _connectCB = boost::make_shared< StaticConnectionListener >( newListener ); } - template < typename PortTraits > - void OutPort< PortTraits >::setNewDisconnectListener(ConnectionEventListener *newListener) + template + void OutPort::setNewDisconnectListener(ConnectionEventListener *newListener) { _disconnectCB = boost::shared_ptr< ConnectionEventListener >(newListener, null_deleter()); } - template < typename PortTraits > - void OutPort< PortTraits >::setNewDisconnectListener(ConnectionEventCallbackFn newListener) + template + void OutPort::setNewDisconnectListener(ConnectionEventCallbackFn newListener) { _disconnectCB = boost::make_shared< StaticConnectionListener >( newListener ); } - template < typename PortTraits > - std::string OutPort< PortTraits >::getRepid() const { + template + std::string OutPort::getRepid() const { return PortType::_PD_repoId; //return "IDL:CORBA/Object:1.0"; } @@ -406,52 +406,42 @@ namespace bulkio { Accepts connect/disconnect interfaces for notification when these events occur */ - template < typename PortTraits > - OutNumericPort< PortTraits >::OutNumericPort(const std::string& name, + template + OutNumericPort::OutNumericPort(const std::string& name, LOGGER_PTR logger, ConnectionEventListener *connectCB, ConnectionEventListener *disconnectCB ) : - OutPort(name, logger, connectCB, disconnectCB) + OutPort(name, logger, connectCB, disconnectCB) { } - template < typename PortTraits > - OutNumericPort< PortTraits >::OutNumericPort(const std::string& name, + template + OutNumericPort::OutNumericPort(const std::string& name, ConnectionEventListener *connectCB, ConnectionEventListener *disconnectCB) : - OutPort(name, LOGGER_PTR(), connectCB, disconnectCB) + OutPort(name, LOGGER_PTR(), connectCB, disconnectCB) { } - template < typename PortTraits > - OutNumericPort< PortTraits >::~OutNumericPort() + template + OutNumericPort::~OutNumericPort() { } - template < typename PortTraits > - void OutNumericPort< PortTraits >::pushPacket( - NativeSequenceType & data, + template + void OutNumericPort::pushPacket( + const VectorType& data, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID) { - this->_sendPacket(SharedBufferType::make_transient(&data[0], data.size()), T, EOS, streamID); - } - - template < typename PortTraits > - void OutNumericPort< PortTraits >::pushPacket( - const DataBufferType & data, - const BULKIO::PrecisionUTCTime& T, - bool EOS, - const std::string& streamID) - { - this->_sendPacket(SharedBufferType::make_transient(&data[0], data.size()), T, EOS, streamID); + this->_sendPacket(BufferType::make_transient(&data[0], data.size()), T, EOS, streamID); } - template < typename PortTraits > - void OutNumericPort< PortTraits >::pushPacket( + template + void OutNumericPort::pushPacket( const TransportType* data, size_t size, const BULKIO::PrecisionUTCTime& T, @@ -459,13 +449,13 @@ namespace bulkio { const std::string& streamID) { const NativeType* ptr = reinterpret_cast(data); - this->_sendPacket(SharedBufferType::make_transient(ptr, size), T, EOS, streamID); + this->_sendPacket(BufferType::make_transient(ptr, size), T, EOS, streamID); } OutCharPort::OutCharPort(const std::string& name, ConnectionEventListener *connectCB, ConnectionEventListener *disconnectCB): - OutNumericPort(name,connectCB, disconnectCB) + OutNumericPort(name,connectCB, disconnectCB) { } @@ -475,7 +465,7 @@ namespace bulkio { LOGGER_PTR logger, ConnectionEventListener *connectCB, ConnectionEventListener *disconnectCB) : - OutNumericPort(name, logger, connectCB, disconnectCB) + OutNumericPort(name, logger, connectCB, disconnectCB) { } @@ -483,33 +473,33 @@ namespace bulkio { void OutCharPort::pushPacket(const Int8* buffer, size_t size, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID) { const TransportType* data = reinterpret_cast(buffer); - OutNumericPort::pushPacket(data, size, T, EOS, streamID); + OutNumericPort::pushPacket(data, size, T, EOS, streamID); } void OutCharPort::pushPacket(const char* buffer, size_t size, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID) { const TransportType* data = reinterpret_cast(buffer); - OutNumericPort::pushPacket(data, size, T, EOS, streamID); + OutNumericPort::pushPacket(data, size, T, EOS, streamID); } void OutCharPort::pushPacket(const std::vector< Int8 >& data, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID) { const TransportType* buffer = reinterpret_cast(&data[0]); - OutNumericPort::pushPacket(buffer, data.size(), T, EOS, streamID); + OutNumericPort::pushPacket(buffer, data.size(), T, EOS, streamID); } void OutCharPort::pushPacket(const std::vector< Char >& data, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID) { const TransportType* buffer = reinterpret_cast(&data[0]); - OutNumericPort::pushPacket(buffer, data.size(), T, EOS, streamID); + OutNumericPort::pushPacket(buffer, data.size(), T, EOS, streamID); } OutFilePort::OutFilePort(const std::string& name, ConnectionEventListener *connectCB, ConnectionEventListener *disconnectCB) : - OutPort(name, LOGGER_PTR(), connectCB, disconnectCB) + OutPort(name, LOGGER_PTR(), connectCB, disconnectCB) { } @@ -518,7 +508,7 @@ namespace bulkio { LOGGER_PTR logger, ConnectionEventListener *connectCB, ConnectionEventListener *disconnectCB) : - OutPort(name,logger, connectCB, disconnectCB) + OutPort(name,logger, connectCB, disconnectCB) { } @@ -546,7 +536,7 @@ namespace bulkio { OutXMLPort::OutXMLPort(const std::string& name, ConnectionEventListener *connectCB, ConnectionEventListener *disconnectCB) : - OutPort(name, LOGGER_PTR(), connectCB, disconnectCB) + OutPort(name, LOGGER_PTR(), connectCB, disconnectCB) { } @@ -555,7 +545,7 @@ namespace bulkio { LOGGER_PTR logger, ConnectionEventListener *connectCB, ConnectionEventListener *disconnectCB) : - OutPort(name,logger,connectCB, disconnectCB) + OutPort(name,logger,connectCB, disconnectCB) { } @@ -601,18 +591,18 @@ namespace bulkio { #define INSTANTIATE_NUMERIC_TEMPLATE(x) \ INSTANTIATE_TEMPLATE(x); template class OutNumericPort; - INSTANTIATE_NUMERIC_TEMPLATE(CharPortTraits); - INSTANTIATE_NUMERIC_TEMPLATE(OctetPortTraits); - INSTANTIATE_NUMERIC_TEMPLATE(ShortPortTraits); - INSTANTIATE_NUMERIC_TEMPLATE(UShortPortTraits); - INSTANTIATE_NUMERIC_TEMPLATE(LongPortTraits); - INSTANTIATE_NUMERIC_TEMPLATE(ULongPortTraits); - INSTANTIATE_NUMERIC_TEMPLATE(LongLongPortTraits); - INSTANTIATE_NUMERIC_TEMPLATE(ULongLongPortTraits); - INSTANTIATE_NUMERIC_TEMPLATE(FloatPortTraits); - INSTANTIATE_NUMERIC_TEMPLATE(DoublePortTraits); - - INSTANTIATE_TEMPLATE(FilePortTraits); - INSTANTIATE_TEMPLATE(XMLPortTraits); + INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataChar); + INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataOctet); + INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataShort); + INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataUshort); + INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataLong); + INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataUlong); + INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataLongLong); + INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataUlongLong); + INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataFloat); + INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataDouble); + + INSTANTIATE_TEMPLATE(BULKIO::dataFile); + INSTANTIATE_TEMPLATE(BULKIO::dataXML); } // end of bulkio namespace diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h index dac70d392..c4cc6e4bd 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h @@ -33,13 +33,30 @@ #include #include "bulkio_base.h" -#include "bulkio_traits.h" +#include "bulkio_typetraits.h" #include "bulkio_callbacks.h" #include "bulkio_out_stream.h" namespace bulkio { - template class PortTransport; + template + class PortTransport; + + template + struct OutStreamTraits + { + typedef BufferedOutputStream OutStreamType; + }; + + template <> + struct OutStreamTraits { + typedef OutXMLStream OutStreamType; + }; + + template <> + struct OutStreamTraits { + typedef OutFileStream OutStreamType; + }; // // OutPort @@ -49,7 +66,7 @@ namespace bulkio { // passed between port objects // // - template < typename PortTraits > + template class OutPort : public redhawk::UsesPort #ifdef BEGIN_AUTOCOMPLETE_IGNORE , public virtual POA_BULKIO::UsesPortStatisticsProvider @@ -57,43 +74,20 @@ namespace bulkio { { public: - - typedef PortTraits Traits; - // // Port Variable Definition // - typedef typename Traits::PortVarType PortVarType; - - // - // BULKIO Interface Type - // - typedef typename Traits::PortType PortType; - - // - // Port pointer type - // - typedef typename PortType::_ptr_type PortPtrType; + typedef typename PortType::_var_type PortVarType; // // Sequence container used during actual pushPacket call // - typedef typename Traits::SequenceType PortSequenceType; - - // - // Shared buffer type used to transfer data without copies, where possible - // - typedef typename Traits::SharedBufferType SharedBufferType; - - // - // Data type of items passed into the pushPacket method - // - typedef typename Traits::NativeType NativeType; + typedef typename CorbaTraits::SequenceType PortSequenceType; // // OutputStream class // - typedef typename OutStreamTraits::OutStreamType StreamType; + typedef typename OutStreamTraits::OutStreamType StreamType; // // ConnectionList Definition @@ -253,10 +247,15 @@ namespace bulkio { OutPortSriMap currentSRIs __attribute__ ((deprecated)); protected: + // + // Shared buffer type used to transfer data without copies, where possible + // + typedef typename BufferTraits::BufferType BufferType; + // // Lookup table for connections to input ports in the same process space // - typedef PortTransport PortTransportType; + typedef PortTransport PortTransportType; virtual redhawk::BasicTransport* _createTransport(CORBA::Object_ptr object, const std::string& connectionId); @@ -282,8 +281,8 @@ namespace bulkio { // // Sends data and metadata to all connections enabled for the given stream // - friend class OutputStream; - void _sendPacket(const SharedBufferType& data, + friend class OutputStream; + void _sendPacket(const BufferType& data, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID); @@ -292,58 +291,23 @@ namespace bulkio { }; - template < typename PortTraits > - class OutNumericPort : public OutPort< PortTraits > { + template + class OutNumericPort : public OutPort { public: - - typedef PortTraits Traits; - - // - // Port Variable Definition - // - typedef typename Traits::PortVarType PortVarType; - - // - // BULKIO Interface Type - // - typedef typename Traits::PortType PortType; - - // - // Sequence container used during actual pushPacket call - // - typedef typename Traits::SequenceType PortSequenceType; - // // Data type contained in sequence container // - typedef typename Traits::TransportType TransportType; + typedef typename CorbaTraits::TransportType TransportType; // // Data type of items passed into the pushPacket method // - typedef typename Traits::NativeType NativeType; + typedef typename NativeTraits::NativeType NativeType; // // Data type of the container for passing data into the pushPacket method // - typedef std::vector< NativeType > NativeSequenceType; - - // - // Sequence of data returned from an input port and can be passed to the output port - // - typedef typename Traits::DataBufferType DataBufferType; - - // - // ConnectionList Definition - // - typedef typename bulkio::Connections< PortVarType >::List ConnectionsList; - - // - // Mapping of Stream IDs to SRI Map/Refresh objects - // - typedef std::map< std::string, SriMapStruct > OutPortSriMap; - - typedef typename Traits::SharedBufferType SharedBufferType; + typedef std::vector VectorType; // // OutNumericPort Creates a uses port object for publishing data to the framework @@ -366,22 +330,6 @@ namespace bulkio { // virtual ~OutNumericPort(); - /* - * pushPacket - * maps to data BULKIO method call for passing vectors of data - * - * data: sequence structure containing the payload to send out - * T: constant of type BULKIO::PrecisionUTCTime containing the timestamp for the outgoing data. - * tcmode: timecode mode - * tcstatus: timecode status - * toff: fractional sample offset - * twsec: J1970 GMT - * tfsec: fractional seconds: 0.0 to 1.0 - * EOS: end-of-stream flag - * streamID: stream identifier - */ - void pushPacket( NativeSequenceType & data, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID); - /* * pushPacket * maps to data BULKIO method call for passing a limited amount of data from a source vector @@ -413,7 +361,10 @@ namespace bulkio { * EOS: end-of-stream flag * streamID: stream identifier */ - void pushPacket( const DataBufferType & data, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID); + void pushPacket(const VectorType& data, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID); + + protected: + typedef typename OutPort::BufferType BufferType; }; // @@ -422,7 +373,7 @@ namespace bulkio { // This class overrides the pushPacket method to support Int8 and char data types // // Output port for Int8 and char data types - class OutCharPort : public OutNumericPort < CharPortTraits > { + class OutCharPort : public OutNumericPort { public: OutCharPort(const std::string& name, ConnectionEventListener *connectCB=NULL, @@ -454,43 +405,8 @@ namespace bulkio { // This class defines the pushPacket interface for file URL data. // // - class OutFilePort : public OutPort { - + class OutFilePort : public OutPort { public: - - typedef FilePortTraits Traits; - - // - // Port Variable Definition - // - typedef Traits::PortVarType PortVarType; - - // - // BULKIO Interface Type - // - typedef Traits::PortType PortType; - - // - // Sequence container used during actual pushPacket call - // - typedef Traits::SequenceType PortSequenceType; - - // - // Data type contained in sequence container - // - typedef Traits::TransportType TransportType; - - // - // Data type of the container for passing data into the pushPacket method - // - typedef char* NativeSequenceType; - - // - // Data type of items passed into the pushPacket method - // - typedef Traits::NativeType NativeType; - - OutFilePort(const std::string& name, ConnectionEventListener *connectCB=NULL, ConnectionEventListener *disconnectCB=NULL); @@ -547,45 +463,8 @@ namespace bulkio { // This class defines the pushPacket interface for XML data. // // - class OutXMLPort : public OutPort { - + class OutXMLPort : public OutPort { public: - - typedef XMLPortTraits Traits; - - typedef OutPort Base; - - // - // Port Variable Definition - // - typedef Traits::PortVarType PortVarType; - - // - // BULKIO Interface Type - // - typedef Traits::PortType PortType; - - // - // Sequence container used during actual pushPacket call - // - typedef Traits::SequenceType PortSequenceType; - - // - // Data type contained in sequence container - // - typedef Traits::TransportType TransportType; - - // - // Data type of the container for passing data into the pushPacket method - // - typedef char* NativeSequenceType; - - // - // Data type of items passed into the pushPacket method - // - typedef Traits::NativeType NativeType; - - OutXMLPort(const std::string& name, ConnectionEventListener *connectCB=NULL, ConnectionEventListener *disconnectCB=NULL); @@ -629,39 +508,39 @@ namespace bulkio { * */ // Bulkio octet (UInt8) output - typedef OutNumericPort OutOctetPort; + typedef OutNumericPort OutOctetPort; // Bulkio UInt8 output - typedef OutOctetPort OutUInt8Port; + typedef OutOctetPort OutUInt8Port; // Bulkio short output - typedef OutNumericPort OutShortPort; + typedef OutNumericPort OutShortPort; // Bulkio unsigned short output - typedef OutNumericPort OutUShortPort; + typedef OutNumericPort OutUShortPort; // Bulkio Int16 output - typedef OutShortPort OutInt16Port; + typedef OutShortPort OutInt16Port; // Bulkio UInt16 output - typedef OutUShortPort OutUInt16Port; + typedef OutUShortPort OutUInt16Port; // Bulkio long output - typedef OutNumericPort OutLongPort; + typedef OutNumericPort OutLongPort; // Bulkio unsigned long output - typedef OutNumericPort OutULongPort; + typedef OutNumericPort OutULongPort; // Bulkio Int32 output - typedef OutLongPort OutInt32Port; + typedef OutLongPort OutInt32Port; // Bulkio UInt32 output - typedef OutULongPort OutUInt32Port; + typedef OutULongPort OutUInt32Port; // Bulkio long long output - typedef OutNumericPort OutLongLongPort; + typedef OutNumericPort OutLongLongPort; // Bulkio unsigned long long output - typedef OutNumericPort OutULongLongPort; + typedef OutNumericPort OutULongLongPort; // Bulkio Int64 output - typedef OutLongLongPort OutInt64Port; + typedef OutLongLongPort OutInt64Port; // Bulkio UInt64 output - typedef OutULongLongPort OutUInt64Port; + typedef OutULongLongPort OutUInt64Port; // Bulkio float output - typedef OutNumericPort OutFloatPort; + typedef OutNumericPort OutFloatPort; // Bulkio double output - typedef OutNumericPort OutDoublePort; + typedef OutNumericPort OutDoublePort; // Bulkio URL output - typedef OutFilePort OutURLPort; + typedef OutFilePort OutURLPort; } // end of bulkio namespace inline bool operator>>= (const CORBA::Any& a, bulkio::connection_descriptor_struct& s) { diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp index 0888d6d89..ecd588035 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp @@ -25,11 +25,11 @@ using bulkio::OutputStream; -template -class OutputStream::Impl : public StreamBase::Impl { +template +class OutputStream::Impl : public StreamBase::Impl { public: typedef StreamBase::Impl ImplBase; - typedef typename PortTraits::SharedBufferType SharedBufferType; + typedef typename BufferTraits::BufferType BufferType; Impl(const BULKIO::StreamSRI& sri, OutPortType* port) : ImplBase(sri), @@ -46,7 +46,7 @@ class OutputStream::Impl : public StreamBase::Impl { { // Send an empty packet with an end-of-stream marker; since there is no // sample data, the timestamp does not matter - _send(SharedBufferType(), bulkio::time::utils::notSet(), true); + _send(BufferType(), bulkio::time::utils::notSet(), true); } void setXStart(double start) @@ -124,7 +124,7 @@ class OutputStream::Impl : public StreamBase::Impl { ++_modcount; } - virtual void write(const SharedBufferType& data, const BULKIO::PrecisionUTCTime& time) + virtual void write(const BufferType& data, const BULKIO::PrecisionUTCTime& time) { _send(data, time, false); } @@ -150,7 +150,7 @@ class OutputStream::Impl : public StreamBase::Impl { } } - void _send(const SharedBufferType& data, const BULKIO::PrecisionUTCTime& time, bool eos) + void _send(const BufferType& data, const BULKIO::PrecisionUTCTime& time, bool eos) { _port->_sendPacket(data, time, eos, _streamID); } @@ -159,135 +159,135 @@ class OutputStream::Impl : public StreamBase::Impl { OutPortType* _port; }; -template -OutputStream::OutputStream() : +template +OutputStream::OutputStream() : StreamBase() { } -template -OutputStream::OutputStream(const BULKIO::StreamSRI& sri, OutPortType* port) : +template +OutputStream::OutputStream(const BULKIO::StreamSRI& sri, OutPortType* port) : StreamBase(boost::make_shared(sri, port)) { } -template -OutputStream::OutputStream(boost::shared_ptr impl) : +template +OutputStream::OutputStream(boost::shared_ptr impl) : StreamBase(impl) { } -template -void OutputStream::sri(const BULKIO::StreamSRI& sri) +template +void OutputStream::sri(const BULKIO::StreamSRI& sri) { impl().setSRI(sri); } -template -void OutputStream::xstart(double start) +template +void OutputStream::xstart(double start) { impl().setXStart(start); } -template -void OutputStream::xdelta(double delta) +template +void OutputStream::xdelta(double delta) { impl().setXDelta(delta); } -template -void OutputStream::xunits(short units) +template +void OutputStream::xunits(short units) { impl().setXUnits(units); } -template -void OutputStream::subsize(int size) +template +void OutputStream::subsize(int size) { impl().setSubsize(size); } -template -void OutputStream::ystart(double start) +template +void OutputStream::ystart(double start) { impl().setYStart(start); } -template -void OutputStream::ydelta(double delta) +template +void OutputStream::ydelta(double delta) { impl().setYDelta(delta); } -template -void OutputStream::yunits(short units) +template +void OutputStream::yunits(short units) { impl().setYUnits(units); } -template -void OutputStream::complex(bool mode) +template +void OutputStream::complex(bool mode) { impl().setComplex(mode); } -template -void OutputStream::blocking(bool mode) +template +void OutputStream::blocking(bool mode) { impl().setBlocking(mode); } -template -void OutputStream::keywords(const _CORBA_Unbounded_Sequence& props) +template +void OutputStream::keywords(const _CORBA_Unbounded_Sequence& props) { impl().setKeywords(props); } -template -void OutputStream::setKeyword(const std::string& name, const CORBA::Any& value) +template +void OutputStream::setKeyword(const std::string& name, const CORBA::Any& value) { impl().setKeyword(name, value); } -template -void OutputStream::setKeyword(const std::string& name, const redhawk::Value& value) +template +void OutputStream::setKeyword(const std::string& name, const redhawk::Value& value) { impl().setKeyword(name, value); } -template -void OutputStream::eraseKeyword(const std::string& name) +template +void OutputStream::eraseKeyword(const std::string& name) { impl().eraseKeyword(name); } -template -void OutputStream::close() +template +void OutputStream::close() { impl().close(); _impl.reset(); } -template -OutputStream::operator unspecified_bool_type() const +template +OutputStream::operator unspecified_bool_type() const { return _impl?static_cast(&OutputStream::impl):0; } -template -typename OutputStream::Impl& OutputStream::impl() +template +typename OutputStream::Impl& OutputStream::impl() { return static_cast(*this->_impl); } -template -const typename OutputStream::Impl& OutputStream::impl() const +template +const typename OutputStream::Impl& OutputStream::impl() const { return static_cast(*this->_impl); } -template -int OutputStream::modcount() const +template +int OutputStream::modcount() const { return impl().modcount(); } @@ -295,13 +295,13 @@ int OutputStream::modcount() const using bulkio::BufferedOutputStream; -template -class BufferedOutputStream::Impl : public Base::Impl { +template +class BufferedOutputStream::Impl : public Base::Impl { public: typedef typename Base::Impl ImplBase; - typedef typename BufferedOutputStream::ScalarBuffer ScalarBuffer; - typedef typename BufferedOutputStream::ComplexBuffer ComplexBuffer; + typedef typename BufferedOutputStream::ScalarBuffer ScalarBuffer; + typedef typename BufferedOutputStream::ComplexBuffer ComplexBuffer; using ImplBase::_sri; using ImplBase::_streamID; @@ -451,92 +451,92 @@ class BufferedOutputStream::Impl : public Base::Impl { size_t _bufferOffset; }; -template -BufferedOutputStream::BufferedOutputStream() : +template +BufferedOutputStream::BufferedOutputStream() : Base() { } -template -BufferedOutputStream::BufferedOutputStream(const BULKIO::StreamSRI& sri, OutPortType* port) : +template +BufferedOutputStream::BufferedOutputStream(const BULKIO::StreamSRI& sri, OutPortType* port) : Base(boost::make_shared(sri, port)) { } -template -size_t BufferedOutputStream::bufferSize() const +template +size_t BufferedOutputStream::bufferSize() const { return impl().bufferSize(); } -template -void BufferedOutputStream::setBufferSize(size_t samples) +template +void BufferedOutputStream::setBufferSize(size_t samples) { impl().setBufferSize(samples); } -template -void BufferedOutputStream::flush() +template +void BufferedOutputStream::flush() { impl().flush(); } -template -void BufferedOutputStream::write(const ScalarBuffer& data, const BULKIO::PrecisionUTCTime& time) +template +void BufferedOutputStream::write(const ScalarBuffer& data, const BULKIO::PrecisionUTCTime& time) { impl().write(data, time); } -template -void BufferedOutputStream::write(const ScalarBuffer& data, const std::list& times) +template +void BufferedOutputStream::write(const ScalarBuffer& data, const std::list& times) { impl().write(data, times); } -template -void BufferedOutputStream::write(const ComplexBuffer& data, const BULKIO::PrecisionUTCTime& time) +template +void BufferedOutputStream::write(const ComplexBuffer& data, const BULKIO::PrecisionUTCTime& time) { impl().write(data, time); } -template -void BufferedOutputStream::write(const ComplexBuffer& data, const std::list& times) +template +void BufferedOutputStream::write(const ComplexBuffer& data, const std::list& times) { impl().write(data, times); } -template -void BufferedOutputStream::write(const ScalarType* data, size_t count, const BULKIO::PrecisionUTCTime& time) +template +void BufferedOutputStream::write(const ScalarType* data, size_t count, const BULKIO::PrecisionUTCTime& time) { impl().write(ScalarBuffer::make_transient(data, count), time); } -template -void BufferedOutputStream::write(const ScalarType* data, size_t count, const std::list& times) +template +void BufferedOutputStream::write(const ScalarType* data, size_t count, const std::list& times) { impl().write(ScalarBuffer::make_transient(data, count), times); } -template -void BufferedOutputStream::write(const ComplexType* data, size_t count, const BULKIO::PrecisionUTCTime& time) +template +void BufferedOutputStream::write(const ComplexType* data, size_t count, const BULKIO::PrecisionUTCTime& time) { impl().write(ComplexBuffer::make_transient(data, count), time); } -template -void BufferedOutputStream::write(const ComplexType* data, size_t count, const std::list& times) +template +void BufferedOutputStream::write(const ComplexType* data, size_t count, const std::list& times) { impl().write(ComplexBuffer::make_transient(data, count), times); } -template -typename BufferedOutputStream::Impl& BufferedOutputStream::impl() +template +typename BufferedOutputStream::Impl& BufferedOutputStream::impl() { return static_cast(*this->_impl); } -template -const typename BufferedOutputStream::Impl& BufferedOutputStream::impl() const +template +const typename BufferedOutputStream::Impl& BufferedOutputStream::impl() const { return static_cast(*this->_impl); } @@ -591,15 +591,15 @@ void OutFileStream::write(const std::string& URL, const BULKIO::PrecisionUTCTime #define INSTANTIATE_NUMERIC_TEMPLATE(x) \ INSTANTIATE_TEMPLATE(x); template class BufferedOutputStream; -INSTANTIATE_NUMERIC_TEMPLATE(bulkio::CharPortTraits); -INSTANTIATE_NUMERIC_TEMPLATE(bulkio::OctetPortTraits); -INSTANTIATE_NUMERIC_TEMPLATE(bulkio::ShortPortTraits); -INSTANTIATE_NUMERIC_TEMPLATE(bulkio::UShortPortTraits); -INSTANTIATE_NUMERIC_TEMPLATE(bulkio::LongPortTraits); -INSTANTIATE_NUMERIC_TEMPLATE(bulkio::ULongPortTraits); -INSTANTIATE_NUMERIC_TEMPLATE(bulkio::LongLongPortTraits); -INSTANTIATE_NUMERIC_TEMPLATE(bulkio::ULongLongPortTraits); -INSTANTIATE_NUMERIC_TEMPLATE(bulkio::FloatPortTraits); -INSTANTIATE_NUMERIC_TEMPLATE(bulkio::DoublePortTraits); -INSTANTIATE_TEMPLATE(bulkio::XMLPortTraits); -INSTANTIATE_TEMPLATE(bulkio::FilePortTraits); +INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataChar); +INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataOctet); +INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataShort); +INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataUshort); +INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataLong); +INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataUlong); +INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataLongLong); +INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataUlongLong); +INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataFloat); +INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataDouble); +INSTANTIATE_TEMPLATE(BULKIO::dataXML); +INSTANTIATE_TEMPLATE(BULKIO::dataFile); diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h index 698188aa2..ccbcbec0a 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h @@ -29,16 +29,16 @@ #include #include -#include "bulkio_traits.h" +#include "bulkio_typetraits.h" #include "bulkio_datablock.h" #include "bulkio_stream.h" namespace bulkio { - template + template class OutPort; - template + template class OutputStream : public StreamBase { public: using StreamBase::sri; @@ -81,7 +81,7 @@ namespace bulkio { void close(); protected: - typedef OutPort OutPortType; + typedef OutPort OutPortType; class Impl; Impl& impl(); @@ -100,10 +100,10 @@ namespace bulkio { }; - template - class BufferedOutputStream : public OutputStream { + template + class BufferedOutputStream : public OutputStream { public: - typedef typename PortTraits::DataTransferTraits::NativeDataType ScalarType; + typedef typename NativeTraits::NativeType ScalarType; typedef std::complex ComplexType; typedef redhawk::shared_buffer ScalarBuffer; @@ -184,10 +184,10 @@ namespace bulkio { void write(const ComplexType* data, size_t count, const std::list& times); private: - typedef OutputStream Base; + typedef OutputStream Base; - friend class OutPort; - typedef OutPort OutPortType; + friend class OutPort; + typedef OutPort OutPortType; BufferedOutputStream(const BULKIO::StreamSRI& sri, OutPortType* port); class Impl; @@ -196,7 +196,7 @@ namespace bulkio { }; - class OutXMLStream : public OutputStream { + class OutXMLStream : public OutputStream { public: OutXMLStream(); @@ -207,15 +207,15 @@ namespace bulkio { void write(const std::string& xmlString); private: - typedef OutputStream Base; + typedef OutputStream Base; - friend class OutPort; - typedef OutPort OutPortType; + friend class OutPort; + typedef OutPort OutPortType; OutXMLStream(const BULKIO::StreamSRI& sri, OutPortType* port); }; - class OutFileStream : public OutputStream { + class OutFileStream : public OutputStream { public: OutFileStream(); @@ -226,39 +226,23 @@ namespace bulkio { void write(const std::string& URL, const BULKIO::PrecisionUTCTime& time); private: - typedef OutputStream Base; + typedef OutputStream Base; - friend class OutPort; - typedef OutPort OutPortType; + friend class OutPort; + typedef OutPort OutPortType; OutFileStream(const BULKIO::StreamSRI& sri, OutPortType* port); }; - typedef BufferedOutputStream OutCharStream; - typedef BufferedOutputStream OutOctetStream; - typedef BufferedOutputStream OutShortStream; - typedef BufferedOutputStream OutUShortStream; - typedef BufferedOutputStream OutLongStream; - typedef BufferedOutputStream OutULongStream; - typedef BufferedOutputStream OutLongLongStream; - typedef BufferedOutputStream OutULongLongStream; - typedef BufferedOutputStream OutFloatStream; - typedef BufferedOutputStream OutDoubleStream; - - template - struct OutStreamTraits - { - typedef BufferedOutputStream OutStreamType; - }; - - template <> - struct OutStreamTraits { - typedef OutXMLStream OutStreamType; - }; - - template <> - struct OutStreamTraits { - typedef OutFileStream OutStreamType; - }; + typedef BufferedOutputStream OutCharStream; + typedef BufferedOutputStream OutOctetStream; + typedef BufferedOutputStream OutShortStream; + typedef BufferedOutputStream OutUShortStream; + typedef BufferedOutputStream OutLongStream; + typedef BufferedOutputStream OutULongStream; + typedef BufferedOutputStream OutLongLongStream; + typedef BufferedOutputStream OutULongLongStream; + typedef BufferedOutputStream OutFloatStream; + typedef BufferedOutputStream OutDoubleStream; } // end of bulkio namespace diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_traits.h b/bulkioInterfaces/libsrc/cpp/bulkio_traits.h index d06a08c51..c6b2910f9 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_traits.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_traits.h @@ -24,11 +24,10 @@ #include #include // for _seqVector -#include -#include #include "BULKIO_Interfaces.h" #include "bulkio_base.h" +#include "bulkio_datatransfer.h" namespace bulkio { @@ -50,14 +49,12 @@ template < typename TT, typename AT=_seqVector::seqVectorAllocator< TT > > // Traits template definition used to define input and output types used the port // classes // -template < typename PST, typename TT, typename NDT=TT, class DBT=std::vector< NDT >, - class SBT=redhawk::shared_buffer > +template < typename PST, typename TT, typename NDT=TT, class DBT=std::vector< NDT > > struct DataTransferTraits { typedef PST PortSequenceType; // Port Sequence type used by middleware typedef TT TransportType; // Transport Type contained in the Port Sequence container typedef NDT NativeDataType; // Native c++ mapping of Transport Type typedef DBT DataBufferType; // Container defintion to hold data from Input port - typedef SBT SharedBufferType; typedef typename DBT::allocator_type AllocatorType; }; @@ -72,106 +69,7 @@ typedef DataTransferTraits< PortTypes::LongLongSequence, CORBA::LongLong > Lo typedef DataTransferTraits< PortTypes::UlongLongSequence, CORBA::ULongLong > ULongLongDataTransferTraits; typedef DataTransferTraits< PortTypes::FloatSequence, CORBA::Float > FloatDataTransferTraits; typedef DataTransferTraits< PortTypes::DoubleSequence, CORBA::Double > DoubleDataTransferTraits; -typedef DataTransferTraits< Char *, Char, Char, std::string, std::string > StringDataTransferTraits; - - -// -// DataTransfer -// -// This is the packet of information returned from an InPort's getPacket method. The DataTransferTraits class -// defines the type context for this structure. -// -// This class tries to implement as efficient as possible data movement from the supplied PortSequenceType object. -// The supplied PortSequenceType's data buffer is used to set the start/end/length attributes of the dataBuffer object that will -// be used by the component. This class takes ownership of the PortSequenceType's memory buffer and assigns it the -// the dataBuffer's start address. The DataBufferType allows developers to use standard -// stl iterators and algorithms against the data in this buffer. -// -// All remaining member variables use each type's assignment/copy methods. It is assumed the -// PrecisionUTCTime and StreamSRI object will perform a "deep" copy. -// -// -template < typename DataTransferTraits > -struct DataTransfer { - - typedef DataTransferTraits Traits; - typedef typename Traits::PortSequenceType PortSequenceType; - typedef typename Traits::TransportType TransportType; - typedef typename Traits::NativeDataType NativeDataType; - typedef typename Traits::DataBufferType DataBufferType; - - // - // Construct a DataTransfer object to be returned from an InPort's getPacket method - // - DataTransfer(const PortSequenceType& data, const BULKIO::PrecisionUTCTime &_T, bool _EOS, const char* _streamID, const BULKIO::StreamSRI &_H, bool _sriChanged, bool _inputQueueFlushed); - - DataBufferType dataBuffer; - BULKIO::PrecisionUTCTime T; - bool EOS; - std::string streamID; - BULKIO::StreamSRI SRI; - bool sriChanged; - bool inputQueueFlushed; - - redhawk::PropertyMap& getKeywords() - { - return redhawk::PropertyMap::cast(SRI.keywords); - } - - const redhawk::PropertyMap& getKeywords() const - { - return redhawk::PropertyMap::cast(SRI.keywords); - } -}; - - -template < > -struct DataTransfer< StringDataTransferTraits > -{ - typedef StringDataTransferTraits Traits; - typedef Traits::PortSequenceType PortSequenceType; - typedef Traits::DataBufferType DataBufferType; - - DataTransfer(const char *data, const BULKIO::PrecisionUTCTime &_T, bool _EOS, const char* _streamID, const BULKIO::StreamSRI &_H, bool _sriChanged, bool _inputQueueFlushed) - { - if ( data != NULL ) dataBuffer = data; - T = _T; - EOS = _EOS; - streamID = _streamID; - SRI = _H; - sriChanged = _sriChanged; - inputQueueFlushed = _inputQueueFlushed; - } - DataTransfer(const char * data, bool _EOS, const char* _streamID, const BULKIO::StreamSRI &_H, bool _sriChanged, bool _inputQueueFlushed) - { - if ( data != NULL ) dataBuffer = data; - EOS = _EOS; - streamID = _streamID; - SRI = _H; - sriChanged = _sriChanged; - inputQueueFlushed = _inputQueueFlushed; - } - DataBufferType dataBuffer; - BULKIO::PrecisionUTCTime T; - bool EOS; - std::string streamID; - BULKIO::StreamSRI SRI; - bool sriChanged; - bool inputQueueFlushed; - -}; - -typedef DataTransfer< CharDataTransferTraits > CharDataTransfer; -typedef DataTransfer< OctetDataTransferTraits > OctetDataTransfer; -typedef DataTransfer< ShortDataTransferTraits > ShortDataTransfer; -typedef DataTransfer< UShortDataTransferTraits > UShortDataTransfer; -typedef DataTransfer< LongDataTransferTraits > LongDataTransfer; -typedef DataTransfer< ULongDataTransferTraits > ULongDataTransfer; -typedef DataTransfer< LongLongDataTransferTraits > LongLongDataTransfer; -typedef DataTransfer< ULongLongDataTransferTraits > ULongLongDataTransfer; -typedef DataTransfer< FloatDataTransferTraits > FloatDataTransfer; -typedef DataTransfer< DoubleDataTransferTraits > DoubleDataTransfer; -typedef DataTransfer< StringDataTransferTraits > StringDataTransfer; +typedef DataTransferTraits< Char *, Char, Char, std::string > StringDataTransferTraits; // // PortTraits @@ -196,7 +94,6 @@ struct PortTraits { typedef typename DTT::NativeDataType NativeType; typedef typename DTT::PortSequenceType SequenceType; typedef typename DTT::DataBufferType DataBufferType; - typedef typename DTT::SharedBufferType SharedBufferType; }; @@ -225,7 +122,6 @@ typedef ULongPortTraits Unt32PortTraits; typedef LongLongPortTraits Int64PortTraits; typedef ULongLongPortTraits Unt64PortTraits; - } // end of bulkio namespace diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_transport.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_transport.cpp index d13f8d098..d8fc4847c 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_transport.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_transport.cpp @@ -19,59 +19,59 @@ */ #include "bulkio_transport.h" -#include "bulkio_traits.h" +#include "bulkio_typetraits.h" #include "bulkio_time_operators.h" #include "bulkio_in_port.h" namespace bulkio { - template + template class LocalTransport; - template + template class RemoteTransport; - template + template class ChunkingTransport; - template - PortTransport* PortTransport::Factory(const std::string& connectionId, - const std::string& name, - PtrType port) + template + PortTransport* PortTransport::Factory(const std::string& connectionId, + const std::string& name, + PtrType port) { - typedef InPort LocalPortType; + typedef InPort LocalPortType; LocalPortType* local_port = ossie::corba::getLocalServant(port); if (local_port) { - return LocalTransport::Factory(connectionId, name, local_port, port); + return LocalTransport::Factory(connectionId, name, local_port, port); } else { - return RemoteTransport::Factory(connectionId, name, port); + return RemoteTransport::Factory(connectionId, name, port); } } - template - PortTransport::PortTransport(const std::string& connectionId, const std::string& name, PtrType objref) : + template + PortTransport::PortTransport(const std::string& connectionId, const std::string& name, PtrType objref) : redhawk::BasicTransport(connectionId, objref), stats(name, sizeof(NativeType)), _port(PortType::_duplicate(objref)) { } - template - PortTransport::~PortTransport() + template + PortTransport::~PortTransport() { } - template - void PortTransport::disconnect() + template + void PortTransport::disconnect() { // Send an end-of-stream for all active streams for (VersionMap::iterator stream = _sriVersions.begin(); stream != _sriVersions.end(); ++stream) { - this->_pushPacket(SharedBufferType(), bulkio::time::utils::notSet(), true, stream->first); + this->_pushPacket(BufferType(), bulkio::time::utils::notSet(), true, stream->first); } _sriVersions.clear(); } - template - void PortTransport::pushSRI(const std::string& streamID, const BULKIO::StreamSRI& sri, int version) + template + void PortTransport::pushSRI(const std::string& streamID, const BULKIO::StreamSRI& sri, int version) { VersionMap::iterator existing = _sriVersions.find(streamID); if (existing != _sriVersions.end()) { @@ -85,12 +85,12 @@ namespace bulkio { this->_pushSRI(sri); } - template - void PortTransport::pushPacket(const SharedBufferType& data, - const BULKIO::PrecisionUTCTime& T, - bool EOS, - const std::string& streamID, - const BULKIO::StreamSRI& sri) + template + void PortTransport::pushPacket(const BufferType& data, + const BULKIO::PrecisionUTCTime& T, + bool EOS, + const std::string& streamID, + const BULKIO::StreamSRI& sri) { this->_sendPacket(data, T, EOS, streamID, sri); if (EOS) { @@ -98,58 +98,57 @@ namespace bulkio { } } - template - typename PortTransport::PtrType PortTransport::port() + template + typename PortTransport::PtrType PortTransport::port() { return _port; } - template - bool PortTransport::isLocal() const + template + bool PortTransport::isLocal() const { return false; } - template - void PortTransport::_sendPacket(const SharedBufferType& data, - const BULKIO::PrecisionUTCTime& T, - bool EOS, - const std::string& streamID, - const BULKIO::StreamSRI& sri) + template + void PortTransport::_sendPacket(const BufferType& data, + const BULKIO::PrecisionUTCTime& T, + bool EOS, + const std::string& streamID, + const BULKIO::StreamSRI& sri) { this->_pushPacket(data, T, EOS, streamID); stats.update(this->_dataLength(data), 0, EOS, streamID); } - template - size_t PortTransport::_dataLength(const SharedBufferType& data) + template + size_t PortTransport::_dataLength(const BufferType& data) { return data.size(); } template <> - size_t PortTransport::_dataLength(const std::string& /*unused*/) + size_t PortTransport::_dataLength(const std::string& /*unused*/) { return 1; } - template - class RemoteTransport : public PortTransport + template + class RemoteTransport : public PortTransport { public: - typedef typename PortTraits::PortType PortType; typedef typename PortType::_ptr_type PtrType; - typedef typename PortTraits::SharedBufferType SharedBufferType; - typedef typename PortTraits::SequenceType PortSequenceType; - typedef typename PortTraits::TransportType TransportType; + typedef typename PortTransport::BufferType BufferType; + typedef typename CorbaTraits::SequenceType SequenceType; + typedef typename CorbaTraits::TransportType TransportType; static RemoteTransport* Factory(const std::string& connectionId, const std::string& name, PtrType port) { - return new ChunkingTransport(connectionId, name, port); + return new ChunkingTransport(connectionId, name, port); } RemoteTransport(const std::string& connectionId, const std::string& name, PtrType port) : - PortTransport(connectionId, name, port) + PortTransport(connectionId, name, port) { } @@ -163,7 +162,7 @@ namespace bulkio { } } - virtual void _pushPacket(const SharedBufferType& data, + virtual void _pushPacket(const BufferType& data, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID) @@ -176,62 +175,61 @@ namespace bulkio { } private: - void _pushPacketImpl(const SharedBufferType& data, + void _pushPacketImpl(const BufferType& data, const BULKIO::PrecisionUTCTime& T, bool EOS, const char* streamID) { const TransportType* ptr = reinterpret_cast(data.data()); - const PortSequenceType buffer(data.size(), data.size(), const_cast(ptr), false); + const SequenceType buffer(data.size(), data.size(), const_cast(ptr), false); this->_port->pushPacket(buffer, T, EOS, streamID); } }; template <> - RemoteTransport* RemoteTransport::Factory(const std::string& connectionId, - const std::string& name, - PtrType port) + RemoteTransport* RemoteTransport::Factory(const std::string& connectionId, + const std::string& name, + PtrType port) { - return new RemoteTransport(connectionId, name, port); + return new RemoteTransport(connectionId, name, port); } template <> - void RemoteTransport::_pushPacketImpl(const std::string& data, - const BULKIO::PrecisionUTCTime& T, - bool EOS, - const char* streamID) + void RemoteTransport::_pushPacketImpl(const std::string& data, + const BULKIO::PrecisionUTCTime& T, + bool EOS, + const char* streamID) { _port->pushPacket(data.c_str(), T, EOS, streamID); } template <> - RemoteTransport* RemoteTransport::Factory(const std::string& connectionId, - const std::string& name, - PtrType port) + RemoteTransport* RemoteTransport::Factory(const std::string& connectionId, + const std::string& name, + PtrType port) { - return new RemoteTransport(connectionId, name, port); + return new RemoteTransport(connectionId, name, port); } template <> - void RemoteTransport::_pushPacketImpl(const std::string& data, - const BULKIO::PrecisionUTCTime& /* unused */, - bool EOS, - const char* streamID) + void RemoteTransport::_pushPacketImpl(const std::string& data, + const BULKIO::PrecisionUTCTime& /* unused */, + bool EOS, + const char* streamID) { _port->pushPacket(data.c_str(), EOS, streamID); } - template - class ChunkingTransport : public RemoteTransport + template + class ChunkingTransport : public RemoteTransport { public: - typedef typename PortTraits::PortType PortType; typedef typename PortType::_ptr_type PtrType; - typedef typename PortTraits::TransportType TransportType; - typedef typename PortTraits::SharedBufferType SharedBufferType; + typedef typename PortTransport::BufferType BufferType; + typedef typename CorbaTraits::TransportType TransportType; ChunkingTransport(const std::string& connectionId, const std::string& name, PtrType port) : - RemoteTransport(connectionId, name, port) + RemoteTransport(connectionId, name, port) { // Multiply by some number < 1 to leave some margin for the CORBA header const size_t maxPayloadSize = (size_t) (bulkio::Const::MaxTransferBytes() * .9); @@ -244,7 +242,7 @@ namespace bulkio { * calls. The EOS is set to false for all of the sub-packets, except for * the last sub-packet, which uses the input EOS argument. */ - virtual void _sendPacket(const SharedBufferType& data, + virtual void _sendPacket(const BufferType& data, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID, @@ -282,8 +280,8 @@ namespace bulkio { } // Take the next slice of the input buffer. - SharedBufferType subPacket = data.slice(first, first + pushSize); - RemoteTransport::_sendPacket(subPacket, packetTime, packetEOS, streamID, sri); + BufferType subPacket = data.slice(first, first + pushSize); + RemoteTransport::_sendPacket(subPacket, packetTime, packetEOS, streamID, sri); // Synthesize the next packet timestamp if (packetTime.tcstatus == BULKIO::TCS_VALID) { @@ -300,14 +298,13 @@ namespace bulkio { }; - template - class LocalTransport : public PortTransport + template + class LocalTransport : public PortTransport { public: - typedef typename PortTraits::PortType PortType; typedef typename PortType::_ptr_type PtrType; - typedef InPort LocalPortType; - typedef typename PortTraits::SharedBufferType SharedBufferType; + typedef typename PortTransport::BufferType BufferType; + typedef InPort LocalPortType; static LocalTransport* Factory(const std::string& connectionId, const std::string& name, LocalPortType* localPort, PtrType port) @@ -317,7 +314,7 @@ namespace bulkio { LocalTransport(const std::string& connectionId, const std::string& name, LocalPortType* localPort, PtrType port) : - PortTransport(connectionId, name, port), + PortTransport(connectionId, name, port), _localPort(localPort) { _localPort->_add_ref(); @@ -339,7 +336,7 @@ namespace bulkio { _localPort->pushSRI(sri); } - virtual void _pushPacket(const SharedBufferType& data, + virtual void _pushPacket(const BufferType& data, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID) @@ -359,42 +356,42 @@ namespace bulkio { }; template <> - void LocalTransport::_pushPacket(const std::string& data, - const BULKIO::PrecisionUTCTime& T, - bool EOS, - const std::string& streamID) + void LocalTransport::_pushPacket(const std::string& data, + const BULKIO::PrecisionUTCTime& T, + bool EOS, + const std::string& streamID) { _localPort->queuePacket(data, T, EOS, streamID); } template <> - void LocalTransport::_pushPacket(const std::string& data, - const BULKIO::PrecisionUTCTime& T, - bool EOS, - const std::string& streamID) + void LocalTransport::_pushPacket(const std::string& data, + const BULKIO::PrecisionUTCTime& T, + bool EOS, + const std::string& streamID) { _localPort->queuePacket(data, T, EOS, streamID); } -#define INSTANTIATE_TEMPLATE(x) \ - template class PortTransport; \ - template class LocalTransport; \ - template class RemoteTransport; \ +#define INSTANTIATE_TEMPLATE(x) \ + template class PortTransport; \ + template class LocalTransport; \ + template class RemoteTransport; \ -#define INSTANTIATE_NUMERIC_TEMPLATE(x) \ +#define INSTANTIATE_NUMERIC_TEMPLATE(x) \ INSTANTIATE_TEMPLATE(x); template class ChunkingTransport; - INSTANTIATE_NUMERIC_TEMPLATE(CharPortTraits); - INSTANTIATE_NUMERIC_TEMPLATE(OctetPortTraits); - INSTANTIATE_NUMERIC_TEMPLATE(ShortPortTraits); - INSTANTIATE_NUMERIC_TEMPLATE(UShortPortTraits); - INSTANTIATE_NUMERIC_TEMPLATE(LongPortTraits); - INSTANTIATE_NUMERIC_TEMPLATE(ULongPortTraits); - INSTANTIATE_NUMERIC_TEMPLATE(LongLongPortTraits); - INSTANTIATE_NUMERIC_TEMPLATE(ULongLongPortTraits); - INSTANTIATE_NUMERIC_TEMPLATE(FloatPortTraits); - INSTANTIATE_NUMERIC_TEMPLATE(DoublePortTraits); - - INSTANTIATE_TEMPLATE(FilePortTraits); - INSTANTIATE_TEMPLATE(XMLPortTraits); + INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataChar); + INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataOctet); + INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataShort); + INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataUshort); + INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataLong); + INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataUlong); + INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataLongLong); + INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataUlongLong); + INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataFloat); + INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataDouble); + + INSTANTIATE_TEMPLATE(BULKIO::dataFile); + INSTANTIATE_TEMPLATE(BULKIO::dataXML); } diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_transport.h b/bulkioInterfaces/libsrc/cpp/bulkio_transport.h index 4a971c4a3..837ac3721 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_transport.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_transport.h @@ -23,18 +23,18 @@ #include #include "bulkio_base.h" +#include "bulkio_typetraits.h" namespace bulkio { - template + template class PortTransport : public redhawk::BasicTransport { public: - typedef typename PortTraits::PortType PortType; typedef typename PortType::_var_type VarType; typedef typename PortType::_ptr_type PtrType; - typedef typename PortTraits::NativeType NativeType; - typedef typename PortTraits::SharedBufferType SharedBufferType; + typedef typename NativeTraits::NativeType NativeType; + typedef typename BufferTraits::BufferType BufferType; static PortTransport* Factory(const std::string& connectionId, const std::string& name, PtrType port); @@ -46,7 +46,7 @@ namespace bulkio { void pushSRI(const std::string& streamID, const BULKIO::StreamSRI& sri, int version); - void pushPacket(const SharedBufferType& data, + void pushPacket(const BufferType& data, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID, @@ -61,13 +61,13 @@ namespace bulkio { protected: virtual void _pushSRI(const BULKIO::StreamSRI& sri) = 0; - virtual void _sendPacket(const SharedBufferType& data, + virtual void _sendPacket(const BufferType& data, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID, const BULKIO::StreamSRI& sri); - virtual void _pushPacket(const SharedBufferType& data, + virtual void _pushPacket(const BufferType& data, const BULKIO::PrecisionUTCTime& T, bool EOS, const std::string& streamID) = 0; @@ -77,7 +77,7 @@ namespace bulkio { // statistical tracking; enables XML and File specialization, which have // different notions of size // - size_t _dataLength(const SharedBufferType& data); + size_t _dataLength(const BufferType& data); VarType _port; typedef std::map VersionMap; diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_typetraits.h b/bulkioInterfaces/libsrc/cpp/bulkio_typetraits.h new file mode 100644 index 000000000..92b0d916c --- /dev/null +++ b/bulkioInterfaces/libsrc/cpp/bulkio_typetraits.h @@ -0,0 +1,90 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK bulkioInterfaces. + * + * REDHAWK bulkioInterfaces is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK bulkioInterfaces is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +#ifndef __bulkio_typetraits_h +#define __bulkio_typetraits_h + +#include +#include + +#include + +#include "BULKIO_Interfaces.h" + +namespace bulkio { + + template + struct CorbaTraits { + }; + +#define DEFINE_CORBA_TRAITS(NAME,TT,ST) \ + template <> \ + struct CorbaTraits { \ + typedef POA_##NAME POAType; \ + typedef TT TransportType; \ + typedef ST SequenceType; \ + }; + + DEFINE_CORBA_TRAITS(BULKIO::dataChar, CORBA::Char, PortTypes::CharSequence); + DEFINE_CORBA_TRAITS(BULKIO::dataOctet, CORBA::Octet, CF::OctetSequence); + DEFINE_CORBA_TRAITS(BULKIO::dataShort, CORBA::Short, PortTypes::ShortSequence); + DEFINE_CORBA_TRAITS(BULKIO::dataUshort, CORBA::UShort, PortTypes::UshortSequence); + DEFINE_CORBA_TRAITS(BULKIO::dataLong, CORBA::Long, PortTypes::LongSequence); + DEFINE_CORBA_TRAITS(BULKIO::dataUlong, CORBA::ULong, PortTypes::UlongSequence); + DEFINE_CORBA_TRAITS(BULKIO::dataLongLong, CORBA::LongLong, PortTypes::LongLongSequence); + DEFINE_CORBA_TRAITS(BULKIO::dataUlongLong, CORBA::ULongLong, PortTypes::UlongLongSequence); + DEFINE_CORBA_TRAITS(BULKIO::dataFloat, CORBA::Float, PortTypes::FloatSequence); + DEFINE_CORBA_TRAITS(BULKIO::dataDouble, CORBA::Double, PortTypes::DoubleSequence); + DEFINE_CORBA_TRAITS(BULKIO::dataFile, char, char*); + DEFINE_CORBA_TRAITS(BULKIO::dataXML, char, char*); + +#undef DEFINE_CORBA_TRAITS + + template + struct NativeTraits { + typedef typename CorbaTraits::TransportType NativeType; + }; + + template <> + struct NativeTraits { + typedef int8_t NativeType; + }; + + template + struct BufferTraits { + typedef typename NativeTraits::NativeType NativeType; + typedef std::vector VectorType; + typedef redhawk::shared_buffer BufferType; + }; + + template <> + struct BufferTraits { + typedef std::string VectorType; + typedef std::string BufferType; + }; + + template <> + struct BufferTraits { + typedef std::string VectorType; + typedef std::string BufferType; + }; +} + +#endif // __bulkio_typetraits_h From e7ef6c31b3823750e21abdd5bffbdced32a38a15 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 7 Dec 2016 14:18:53 -0500 Subject: [PATCH 0597/1644] Use a common preprocessor macro to instantiate templates for all BulkIO port types --- .../libsrc/cpp/bulkio_in_port.cpp | 21 +++++------------- .../libsrc/cpp/bulkio_in_stream.cpp | 19 +++++----------- .../libsrc/cpp/bulkio_out_port.cpp | 21 +++++------------- .../libsrc/cpp/bulkio_out_stream.cpp | 18 ++++----------- bulkioInterfaces/libsrc/cpp/bulkio_p.h | 16 ++++++++++++++ .../libsrc/cpp/bulkio_transport.cpp | 22 +++++-------------- 6 files changed, 41 insertions(+), 76 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp index 064a45251..f9479dfab 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp @@ -890,23 +890,12 @@ namespace bulkio { // #define INSTANTIATE_TEMPLATE(x) \ - template class InPort; + template class InPort; #define INSTANTIATE_NUMERIC_TEMPLATE(x) \ - INSTANTIATE_TEMPLATE(x); template class InNumericPort; - - INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataChar); - INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataOctet); - INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataShort); - INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataUshort); - INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataLong); - INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataUlong); - INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataLongLong); - INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataUlongLong); - INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataFloat); - INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataDouble); - - INSTANTIATE_TEMPLATE(BULKIO::dataFile); - INSTANTIATE_TEMPLATE(BULKIO::dataXML); + template class InNumericPort; + + FOREACH_PORT_TYPE(INSTANTIATE_TEMPLATE); + FOREACH_NUMERIC_PORT_TYPE(INSTANTIATE_NUMERIC_TEMPLATE); } // end of bulkio namespace diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp index 9d3f0f1e5..02a9abfa9 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp @@ -21,6 +21,7 @@ #include "bulkio_in_stream.h" #include "bulkio_time_operators.h" #include "bulkio_in_port.h" +#include "bulkio_p.h" #include #include @@ -704,17 +705,7 @@ const typename BufferedInputStream::Impl& BufferedInputStream; #define INSTANTIATE_NUMERIC_TEMPLATE(x) \ - INSTANTIATE_TEMPLATE(x); template class BufferedInputStream; - -INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataChar); -INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataOctet); -INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataShort); -INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataUshort); -INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataLong); -INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataUlong); -INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataLongLong); -INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataUlongLong); -INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataFloat); -INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataDouble); -INSTANTIATE_TEMPLATE(BULKIO::dataXML); -INSTANTIATE_TEMPLATE(BULKIO::dataFile); + template class BufferedInputStream; + + FOREACH_PORT_TYPE(INSTANTIATE_TEMPLATE); + FOREACH_NUMERIC_PORT_TYPE(INSTANTIATE_NUMERIC_TEMPLATE); diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp index 12651f01f..de58c3270 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp @@ -586,23 +586,12 @@ namespace bulkio { // #define INSTANTIATE_TEMPLATE(x) \ - template class OutPort; + template class OutPort; #define INSTANTIATE_NUMERIC_TEMPLATE(x) \ - INSTANTIATE_TEMPLATE(x); template class OutNumericPort; - - INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataChar); - INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataOctet); - INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataShort); - INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataUshort); - INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataLong); - INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataUlong); - INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataLongLong); - INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataUlongLong); - INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataFloat); - INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataDouble); - - INSTANTIATE_TEMPLATE(BULKIO::dataFile); - INSTANTIATE_TEMPLATE(BULKIO::dataXML); + template class OutNumericPort; + + FOREACH_PORT_TYPE(INSTANTIATE_TEMPLATE); + FOREACH_NUMERIC_PORT_TYPE(INSTANTIATE_NUMERIC_TEMPLATE); } // end of bulkio namespace diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp index ecd588035..bfea7097a 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp @@ -589,17 +589,7 @@ void OutFileStream::write(const std::string& URL, const BULKIO::PrecisionUTCTime template class OutputStream; #define INSTANTIATE_NUMERIC_TEMPLATE(x) \ - INSTANTIATE_TEMPLATE(x); template class BufferedOutputStream; - -INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataChar); -INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataOctet); -INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataShort); -INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataUshort); -INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataLong); -INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataUlong); -INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataLongLong); -INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataUlongLong); -INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataFloat); -INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataDouble); -INSTANTIATE_TEMPLATE(BULKIO::dataXML); -INSTANTIATE_TEMPLATE(BULKIO::dataFile); + template class BufferedOutputStream; + + FOREACH_PORT_TYPE(INSTANTIATE_TEMPLATE); + FOREACH_NUMERIC_PORT_TYPE(INSTANTIATE_NUMERIC_TEMPLATE); diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_p.h b/bulkioInterfaces/libsrc/cpp/bulkio_p.h index 81f7e8762..9679ef60e 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_p.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_p.h @@ -92,6 +92,22 @@ namespace bulkio { } // end of namespace +#define FOREACH_NUMERIC_PORT_TYPE(x) \ + x(BULKIO::dataChar); \ + x(BULKIO::dataOctet); \ + x(BULKIO::dataShort); \ + x(BULKIO::dataUshort); \ + x(BULKIO::dataLong); \ + x(BULKIO::dataUlong); \ + x(BULKIO::dataLongLong); \ + x(BULKIO::dataUlongLong); \ + x(BULKIO::dataFloat); \ + x(BULKIO::dataDouble); + +#define FOREACH_PORT_TYPE(x) \ + FOREACH_NUMERIC_PORT_TYPE(x) \ + x(BULKIO::dataFile); \ + x(BULKIO::dataXML); #endif // __bulkio_p_h__ diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_transport.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_transport.cpp index d8fc4847c..a6ffceec3 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_transport.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_transport.cpp @@ -22,6 +22,7 @@ #include "bulkio_typetraits.h" #include "bulkio_time_operators.h" #include "bulkio_in_port.h" +#include "bulkio_p.h" namespace bulkio { template @@ -378,20 +379,9 @@ namespace bulkio { template class LocalTransport; \ template class RemoteTransport; \ -#define INSTANTIATE_NUMERIC_TEMPLATE(x) \ - INSTANTIATE_TEMPLATE(x); template class ChunkingTransport; - - INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataChar); - INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataOctet); - INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataShort); - INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataUshort); - INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataLong); - INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataUlong); - INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataLongLong); - INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataUlongLong); - INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataFloat); - INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataDouble); - - INSTANTIATE_TEMPLATE(BULKIO::dataFile); - INSTANTIATE_TEMPLATE(BULKIO::dataXML); +#define INSTANTIATE_NUMERIC_TEMPLATE(x) \ + template class ChunkingTransport; + + FOREACH_PORT_TYPE(INSTANTIATE_TEMPLATE); + FOREACH_NUMERIC_PORT_TYPE(INSTANTIATE_NUMERIC_TEMPLATE); } From afc2965f5ac768b37a5ed71c7ec3ea87013bd47d Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 7 Dec 2016 16:30:57 -0500 Subject: [PATCH 0598/1644] Fix backwards compatibility issues after traits refactor --- .../libsrc/cpp/bulkio_datatransfer.h | 114 +++++++++++------- bulkioInterfaces/libsrc/cpp/bulkio_out_port.h | 8 +- 2 files changed, 75 insertions(+), 47 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_datatransfer.h b/bulkioInterfaces/libsrc/cpp/bulkio_datatransfer.h index bdde48195..0e1ad3e02 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_datatransfer.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_datatransfer.h @@ -28,42 +28,6 @@ #include namespace bulkio { - namespace detail { - template - void assign(Tout& dest, const Tin& src) - { - dest = src; - } - - template - void assign_vector(std::vector& dest, const _CORBA_Sequence& src) - { - if (src.release()) { - _CORBA_Sequence& in = const_cast<_CORBA_Sequence&>(src); - const size_t length = in.length(); - typedef typename std::_Vector_base::_Vector_impl* VectorPtr; - VectorPtr vectorPtr = (VectorPtr)(&dest); - vectorPtr->_M_start = reinterpret_cast(in.get_buffer(1)); - vectorPtr->_M_finish = vectorPtr->_M_start + length; - vectorPtr->_M_end_of_storage = vectorPtr->_M_finish; - } else { - dest.assign(src.get_buffer(), src.get_buffer() + src.length()); - } - } - - template - void assign(std::vector& dest, const Tin& src) - { - assign_vector(dest, src); - } - - inline void assign(std::string& dest, const char* src) - { - if (src) { - dest = src; - } - } - } // // DataTransfer @@ -96,7 +60,7 @@ namespace bulkio { sriChanged(sriChanged), inputQueueFlushed(inputQueueFlushed) { - detail::assign(dataBuffer, data); + assign(dataBuffer, data); } DataBufferType dataBuffer; @@ -116,24 +80,83 @@ namespace bulkio { { return redhawk::PropertyMap::cast(SRI.keywords); } + + private: + template + static void assign(std::vector& dest, const _CORBA_Sequence& src) + { + if (src.release()) { + _CORBA_Sequence& in = const_cast<_CORBA_Sequence&>(src); + const size_t length = in.length(); + typedef typename std::_Vector_base::_Vector_impl* VectorPtr; + VectorPtr vectorPtr = (VectorPtr)(&dest); + vectorPtr->_M_start = reinterpret_cast(in.get_buffer(1)); + vectorPtr->_M_finish = vectorPtr->_M_start + length; + vectorPtr->_M_end_of_storage = vectorPtr->_M_finish; + } else { + dest.assign(src.get_buffer(), src.get_buffer() + src.length()); + } + } + }; + template <> + struct DataTransfer { + // + // Construct a DataTransfer object to be returned from an InPort's getPacket method + // + DataTransfer(const char* data, const BULKIO::PrecisionUTCTime& T, bool EOS, const char* streamID, + const BULKIO::StreamSRI& H, bool sriChanged, bool inputQueueFlushed) : + T(T), + EOS(EOS), + streamID(streamID), + SRI(H), + sriChanged(sriChanged), + inputQueueFlushed(inputQueueFlushed) + { + assign(dataBuffer, data); + } + + DataTransfer(const char* data, bool EOS, const char* streamID, const BULKIO::StreamSRI& H, + bool sriChanged, bool inputQueueFlushed) : + T(), + EOS(EOS), + streamID(streamID), + SRI(H), + sriChanged(sriChanged), + inputQueueFlushed(inputQueueFlushed) + { + assign(dataBuffer, data); + } + + std::string dataBuffer; + BULKIO::PrecisionUTCTime T; + bool EOS; + std::string streamID; + BULKIO::StreamSRI SRI; + bool sriChanged; + bool inputQueueFlushed; + + redhawk::PropertyMap& getKeywords() + { + return redhawk::PropertyMap::cast(SRI.keywords); + } - struct StringDataTransfer : public DataTransfer - { - StringDataTransfer(const char* data, const BULKIO::PrecisionUTCTime& T, bool EOS, const char* streamID, - const BULKIO::StreamSRI& H, bool sriChanged, bool inputQueueFlushed) : - DataTransfer(data, T, EOS, streamID, H, sriChanged, inputQueueFlushed) + const redhawk::PropertyMap& getKeywords() const { + return redhawk::PropertyMap::cast(SRI.keywords); } - StringDataTransfer(const char* data, bool EOS, const char* streamID, const BULKIO::StreamSRI&H, - bool sriChanged, bool inputQueueFlushed) : - DataTransfer(data, BULKIO::PrecisionUTCTime(), EOS, streamID, H, sriChanged, inputQueueFlushed) + private: + static void assign(std::string& dest, const char* src) { + if (src) { + dest = src; + } } }; + typedef DataTransfer > CharDataTransfer; typedef DataTransfer > OctetDataTransfer; typedef DataTransfer > ShortDataTransfer; @@ -144,6 +167,7 @@ namespace bulkio { typedef DataTransfer > ULongLongDataTransfer; typedef DataTransfer > FloatDataTransfer; typedef DataTransfer > DoubleDataTransfer; + typedef DataTransfer StringDataTransfer; } #endif // __bulkio_datatransfer_h diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h index c4cc6e4bd..ae988552d 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h @@ -99,7 +99,6 @@ namespace bulkio { // typedef std::map< std::string, SriMapStruct > OutPortSriMap; - // // OutPort Creates a uses port object for publishing data to the framework // @@ -307,7 +306,8 @@ namespace bulkio { // // Data type of the container for passing data into the pushPacket method // - typedef std::vector VectorType; + typedef typename BufferTraits::VectorType VectorType; + typedef VectorType NativeSequenceType; // // OutNumericPort Creates a uses port object for publishing data to the framework @@ -407,6 +407,8 @@ namespace bulkio { // class OutFilePort : public OutPort { public: + typedef char* NativeSequenceType; + OutFilePort(const std::string& name, ConnectionEventListener *connectCB=NULL, ConnectionEventListener *disconnectCB=NULL); @@ -465,6 +467,8 @@ namespace bulkio { // class OutXMLPort : public OutPort { public: + typedef char* NativeSequenceType; + OutXMLPort(const std::string& name, ConnectionEventListener *connectCB=NULL, ConnectionEventListener *disconnectCB=NULL); From 40042b5a780b8fae2e49e056fd1a8b751fc86d8b Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 8 Dec 2016 09:26:01 -0500 Subject: [PATCH 0599/1644] Handle exceptions from port transport disconnect in disconnectPort() --- redhawk/src/base/framework/UsesPort.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/redhawk/src/base/framework/UsesPort.cpp b/redhawk/src/base/framework/UsesPort.cpp index c14ab5f4d..eb1160511 100644 --- a/redhawk/src/base/framework/UsesPort.cpp +++ b/redhawk/src/base/framework/UsesPort.cpp @@ -19,6 +19,7 @@ */ #include +#include #include namespace redhawk { @@ -102,7 +103,19 @@ namespace redhawk { } RH_DEBUG(logger, "Disconnecting connection '" << connectionId << "'"); - (*transport)->disconnect(); + try { + (*transport)->disconnect(); + } catch (const std::exception& exc) { + if ((*transport)->isAlive()) { + RH_WARN(logger, "Exception disconnecting '" << connectionId << "': " + << exc.what()); + } + } catch (const CORBA::Exception& exc) { + if ((*transport)->isAlive()) { + RH_WARN(logger, "Exception disconnecting '" << connectionId << "': " + << ossie::corba::describeException(exc)); + } + } delete (*transport); _transports.erase(transport); From 33cbfb9fc487931ecd06ce7b6f5a93b98bba27ed Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 8 Dec 2016 10:09:44 -0500 Subject: [PATCH 0600/1644] Forward the input queue flush flag to statistics --- bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp index f9479dfab..a0a82787e 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp @@ -275,7 +275,7 @@ namespace bulkio { } LOG_TRACE(logger, "bulkio::InPort pushPacket NEW PACKET (QUEUE" << packetQueue.size()+1 << ")"); - stats->update(length, (float)(packetQueue.size()+1)/(float)maxQueue, EOS, streamID, false); + stats->update(length, (float)(packetQueue.size()+1)/(float)maxQueue, EOS, streamID, flushToReport); Packet *tmpIn = new Packet(data, T, EOS, sri, sriChanged, flushToReport); packetQueue.push_back(tmpIn); dataAvailable.notify_all(); From 686043bc258812c98bc6a0bccefa90ee246c02b8 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 8 Dec 2016 10:37:12 -0500 Subject: [PATCH 0601/1644] Remove duplicate alive flag from BurstIO transport classes --- burstioInterfaces/src/cpp/lib/OutPortImpl.h | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/burstioInterfaces/src/cpp/lib/OutPortImpl.h b/burstioInterfaces/src/cpp/lib/OutPortImpl.h index 2380d4ea5..c0b4995a0 100644 --- a/burstioInterfaces/src/cpp/lib/OutPortImpl.h +++ b/burstioInterfaces/src/cpp/lib/OutPortImpl.h @@ -42,8 +42,7 @@ namespace burstio { RemoteTransport(OutPort* parent, typename PortType::_ptr_type port, const std::string& connectionId) : super(port, connectionId, parent->name), - parent_(parent), - alive_(true) + parent_(parent) { } @@ -63,15 +62,15 @@ namespace burstio { RH_ERROR(parent_->logger, "pushBursts to " << this->connectionId() << " failed because the burst size is too long"); } } catch (const CORBA::Exception& ex) { - if (alive_) { + if (this->isAlive()) { RH_ERROR(parent_->logger, "pushBursts to " << this->connectionId() << " failed: CORBA::" << ex._name()); } - alive_ = false; + this->setAlive(false); } catch (...) { - if (alive_) { + if (this->isAlive()) { RH_ERROR(parent_->logger, "pushBursts to " << this->connectionId() << " failed"); } - alive_ = false; + this->setAlive(false); } } @@ -82,7 +81,7 @@ namespace burstio { boost::posix_time::time_duration delay = boost::get_system_time() - startTime; this->port_->pushBursts(bursts); - alive_ = true; + this->setAlive(true); // Count up total elements size_t total_elements = 0; @@ -108,7 +107,6 @@ namespace burstio { } OutPort* parent_; - bool alive_; }; template From a0c683d4f9ea252f3147cf99c1ffdbcc3eea8b9e Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 8 Dec 2016 10:57:12 -0500 Subject: [PATCH 0602/1644] Simplify BurstIO handling of buffer ownership in transfers --- .../src/cpp/include/burstio/OutPortDecl.h | 4 -- burstioInterfaces/src/cpp/lib/InPortImpl.h | 10 ++++- burstioInterfaces/src/cpp/lib/OutPortImpl.h | 42 ++++--------------- 3 files changed, 16 insertions(+), 40 deletions(-) diff --git a/burstioInterfaces/src/cpp/include/burstio/OutPortDecl.h b/burstioInterfaces/src/cpp/include/burstio/OutPortDecl.h index 52cc14a5c..300f8d5ae 100644 --- a/burstioInterfaces/src/cpp/include/burstio/OutPortDecl.h +++ b/burstioInterfaces/src/cpp/include/burstio/OutPortDecl.h @@ -79,10 +79,6 @@ namespace burstio { return stats_.retrieve(); } - // Return true if this connection may modify the burst sequence memory - // on push - virtual bool modifiesBursts () const = 0; - protected: VarType port_; SenderStatistics stats_; diff --git a/burstioInterfaces/src/cpp/lib/InPortImpl.h b/burstioInterfaces/src/cpp/lib/InPortImpl.h index c1dad8387..0635b3c98 100644 --- a/burstioInterfaces/src/cpp/lib/InPortImpl.h +++ b/burstioInterfaces/src/cpp/lib/InPortImpl.h @@ -153,8 +153,14 @@ namespace burstio { // Add bursts to queue, if there are any if (total_bursts > 0) { LOG_INSTANCE_TRACE("Queueing " << total_bursts << " bursts"); - queue_.push_back(new BurstSequenceType()); - ossie::corba::move(queue_.back(), const_cast(bursts)); + if (bursts.release()) { + // Steal the bursts + queue_.push_back(new BurstSequenceType()); + ossie::corba::move(queue_.back(), const_cast(bursts)); + } else { + // Someone else owns the bursts, make a copy + queue_.push_back(new BurstSequenceType(bursts)); + } queuedBursts_ += total_bursts; queueNotEmpty_.notify_all(); } else { diff --git a/burstioInterfaces/src/cpp/lib/OutPortImpl.h b/burstioInterfaces/src/cpp/lib/OutPortImpl.h index c0b4995a0..fe074aa7e 100644 --- a/burstioInterfaces/src/cpp/lib/OutPortImpl.h +++ b/burstioInterfaces/src/cpp/lib/OutPortImpl.h @@ -46,11 +46,6 @@ namespace burstio { { } - bool modifiesBursts() const - { - return false; - } - void pushBursts(const BurstSequenceType& bursts, boost::system_time startTime, float queueDepth) { try { @@ -125,11 +120,6 @@ namespace burstio { { } - bool modifiesBursts() const - { - return true; - } - void pushBursts(const BurstSequenceType& bursts, boost::system_time startTime, float queueDepth) { try { @@ -486,7 +476,13 @@ namespace burstio { void OutPort::sendBursts(const BurstSequenceType& bursts, boost::system_time startTime, float queueDepth, const std::string& streamID) { RH_TRACE(logger, "Sending " << bursts.length() << " bursts"); - std::vector deferred_ports; + + // Create a non-owning view to prevent local transport from stealing + // the burst buffer; for N local connections, this will lead to making + // N copies (optimal is N-1), but this approach is simpler and safe. + BurstType* buffer = const_cast(bursts.get_buffer()); + BurstSequenceType const_bursts(bursts.length(), bursts.length(), buffer, false); + boost::mutex::scoped_lock lock(updatingPortsLock); for (TransportIterator ii = _transports.begin(); ii != _transports.end(); ++ii) { TransportType* connection = *ii; @@ -495,29 +491,7 @@ namespace burstio { continue; } - // If this connection may modify the burst sequence, save the push - // until the second pass - if (connection->modifiesBursts()) { - deferred_ports.push_back(connection); - } else { - connection->pushBursts(bursts, startTime, queueDepth); - } - } - - // Second pass: push to connections that may modify (i.e., steal) the - // burst sequence, making copies as needed - if (!deferred_ports.empty()) { - // There are remaining ports that may require a copy - int remaining = deferred_ports.size(); - BOOST_FOREACH(TransportType* connection, deferred_ports) { - if (remaining == 1) { - // Last connection, can allow it to steal the buffer - connection->pushBursts(bursts, startTime, queueDepth); - } else { - // There are more connections, make an (unnamed) copy - connection->pushBursts(BurstSequenceType(bursts), startTime, queueDepth); - } - } + connection->pushBursts(const_bursts, startTime, queueDepth); } } From 5378217ad675eefea2e724270dbe06571ec236f2 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 8 Dec 2016 11:00:15 -0500 Subject: [PATCH 0603/1644] Hide base BurstIO transport class implementation --- .../src/cpp/include/burstio/OutPortDecl.h | 27 +----------------- burstioInterfaces/src/cpp/lib/OutPortImpl.h | 28 +++++++++++++++++++ 2 files changed, 29 insertions(+), 26 deletions(-) diff --git a/burstioInterfaces/src/cpp/include/burstio/OutPortDecl.h b/burstioInterfaces/src/cpp/include/burstio/OutPortDecl.h index 300f8d5ae..8b137ddbc 100644 --- a/burstioInterfaces/src/cpp/include/burstio/OutPortDecl.h +++ b/burstioInterfaces/src/cpp/include/burstio/OutPortDecl.h @@ -57,32 +57,7 @@ namespace burstio { }; template - class BurstTransport : public redhawk::BasicTransport - { - public: - typedef typename Traits::PortType PortType; - typedef typename PortType::_var_type VarType; - typedef typename Traits::BurstSequenceType BurstSequenceType; - typedef typename Traits::ElementType ElementType; - - BurstTransport(typename PortType::_ptr_type port, const std::string& connectionId, const std::string& name) : - redhawk::BasicTransport(connectionId, port), - port_(PortType::_duplicate(port)), - stats_(name, sizeof(ElementType) * 8) - { - } - - virtual void pushBursts(const BurstSequenceType& bursts, boost::system_time startTime, float queueDepth) = 0; - - BULKIO::PortStatistics* getStatistics() const - { - return stats_.retrieve(); - } - - protected: - VarType port_; - SenderStatistics stats_; - }; + class BurstTransport; template class OutPort : public redhawk::UsesPort, public virtual POA_BULKIO::UsesPortStatisticsProvider diff --git a/burstioInterfaces/src/cpp/lib/OutPortImpl.h b/burstioInterfaces/src/cpp/lib/OutPortImpl.h index fe074aa7e..f6f4f9aef 100644 --- a/burstioInterfaces/src/cpp/lib/OutPortImpl.h +++ b/burstioInterfaces/src/cpp/lib/OutPortImpl.h @@ -31,6 +31,34 @@ namespace burstio { + template + class BurstTransport : public redhawk::BasicTransport + { + public: + typedef typename Traits::PortType PortType; + typedef typename PortType::_var_type VarType; + typedef typename Traits::BurstSequenceType BurstSequenceType; + typedef typename Traits::ElementType ElementType; + + BurstTransport(typename PortType::_ptr_type port, const std::string& connectionId, const std::string& name) : + redhawk::BasicTransport(connectionId, port), + port_(PortType::_duplicate(port)), + stats_(name, sizeof(ElementType) * 8) + { + } + + virtual void pushBursts(const BurstSequenceType& bursts, boost::system_time startTime, float queueDepth) = 0; + + BULKIO::PortStatistics* getStatistics() const + { + return stats_.retrieve(); + } + + protected: + VarType port_; + SenderStatistics stats_; + }; + template class OutPort::RemoteTransport : public BurstTransport { From 4784787bfac2c88494ac60b2150786aaa3496cfc Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 8 Dec 2016 13:08:24 -0500 Subject: [PATCH 0604/1644] Expect InvalidPort exceptions for non-existent connection IDs in C++ BulkIO tests --- .../libsrc/testing/tests/cpp/Bulkio_OutPort_Fixture.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/bulkioInterfaces/libsrc/testing/tests/cpp/Bulkio_OutPort_Fixture.cpp b/bulkioInterfaces/libsrc/testing/tests/cpp/Bulkio_OutPort_Fixture.cpp index 297f86832..4c8001367 100644 --- a/bulkioInterfaces/libsrc/testing/tests/cpp/Bulkio_OutPort_Fixture.cpp +++ b/bulkioInterfaces/libsrc/testing/tests/cpp/Bulkio_OutPort_Fixture.cpp @@ -93,7 +93,7 @@ void Bulkio_OutPort_Fixture::test_port_api( T *port ) { port->connectPort( p->_this(), "connection_1"); port->disconnectPort( "connection_1"); - port->disconnectPort( "connection_1"); + CPPUNIT_ASSERT_THROW(port->disconnectPort("connection_1"), CF::Port::InvalidPort); //ossie::corba::RootPOA()->deactivate_object(p_oid); BULKIO::StreamSRI sri; @@ -180,7 +180,7 @@ void Bulkio_OutPort_Fixture::test_port_api< bulkio::OutCharPort, bulkio::InChar port->connectPort( p->_this(), "connection_1"); port->disconnectPort( "connection_1"); - port->disconnectPort( "connection_1"); + CPPUNIT_ASSERT_THROW(port->disconnectPort("connection_1"), CF::Port::InvalidPort); ossie::corba::RootPOA()->deactivate_object(p_oid); BULKIO::StreamSRI sri; @@ -232,7 +232,7 @@ void Bulkio_OutPort_Fixture::test_port_api< bulkio::OutFilePort, bulkio::InFile port->connectPort( p->_this(), "connection_1"); port->disconnectPort( "connection_1"); - port->disconnectPort( "connection_1"); + CPPUNIT_ASSERT_THROW(port->disconnectPort("connection_1"), CF::Port::InvalidPort); ossie::corba::RootPOA()->deactivate_object(p_oid); BULKIO::StreamSRI sri; @@ -273,7 +273,7 @@ void Bulkio_OutPort_Fixture::test_port_api< bulkio::OutXMLPort, bulkio::InXMLPo port->connectPort( p->_this(), "connection_1"); port->disconnectPort( "connection_1"); - port->disconnectPort( "connection_1"); + CPPUNIT_ASSERT_THROW(port->disconnectPort("connection_1"), CF::Port::InvalidPort); ossie::corba::RootPOA()->deactivate_object(p_oid); BULKIO::StreamSRI sri; From 25dcd03c329eab7ca17193ac359e6f7bc228051f Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 8 Dec 2016 15:25:42 -0500 Subject: [PATCH 0605/1644] Fix order of arguments to BurstIO output port _createTransport so the correct one gets called --- burstioInterfaces/src/cpp/include/burstio/OutPortDecl.h | 2 +- burstioInterfaces/src/cpp/lib/OutPortImpl.h | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/burstioInterfaces/src/cpp/include/burstio/OutPortDecl.h b/burstioInterfaces/src/cpp/include/burstio/OutPortDecl.h index 8b137ddbc..97fa5af4c 100644 --- a/burstioInterfaces/src/cpp/include/burstio/OutPortDecl.h +++ b/burstioInterfaces/src/cpp/include/burstio/OutPortDecl.h @@ -248,7 +248,7 @@ namespace burstio { void queueBurst (SequenceType& data, const BURSTIO::BurstSRI& sri, const BULKIO::PrecisionUTCTime& timestamp, bool eos, bool isComplex); - virtual redhawk::BasicTransport* _createTransport(const std::string& connectionId, CORBA::Object_ptr object); + virtual redhawk::BasicTransport* _createTransport(CORBA::Object_ptr object, const std::string& connectionId); const Queue& getQueueForStream (const std::string& streamID) const; Queue& getQueueForStream (const std::string& streamID); diff --git a/burstioInterfaces/src/cpp/lib/OutPortImpl.h b/burstioInterfaces/src/cpp/lib/OutPortImpl.h index f6f4f9aef..7dc7fc86d 100644 --- a/burstioInterfaces/src/cpp/lib/OutPortImpl.h +++ b/burstioInterfaces/src/cpp/lib/OutPortImpl.h @@ -579,17 +579,18 @@ namespace burstio { } template - redhawk::BasicTransport* OutPort::_createTransport (const std::string& connectionId, - CORBA::Object_ptr object) + redhawk::BasicTransport* OutPort::_createTransport (CORBA::Object_ptr object, + const std::string& connectionId) { typedef typename PortType::_var_type var_type; var_type port = ossie::corba::_narrowSafe(object); InPort* local_port = ossie::corba::getLocalServant >(port); if (local_port) { - RH_DEBUG(logger, "Using local connection to port " << local_port->getName() + RH_DEBUG(logger, "Using local transport to port " << local_port->getName() << " for connection " << connectionId); return new LocalTransport(this, local_port, port, connectionId); } else { + RH_DEBUG(logger, "Using CORBA transport for connection " << connectionId); return new RemoteTransport(this, port, connectionId); } } From ac577078ed458afd6f0b16c0681e134cc59b373b Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 8 Dec 2016 15:44:27 -0500 Subject: [PATCH 0606/1644] CF-1505 Add a component-based test for querying connections from C++ message supplier ports --- .../MessageTestCpp/MessageTestCpp.sad.xml | 20 +++++++------- .../src/testing/tests/test_08_MessagingCpp.py | 27 ++++++++++++++++++- 2 files changed, 36 insertions(+), 11 deletions(-) diff --git a/redhawk/src/testing/sdr/dom/waveforms/MessageTestCpp/MessageTestCpp.sad.xml b/redhawk/src/testing/sdr/dom/waveforms/MessageTestCpp/MessageTestCpp.sad.xml index f2b3fcbc9..955217aee 100644 --- a/redhawk/src/testing/sdr/dom/waveforms/MessageTestCpp/MessageTestCpp.sad.xml +++ b/redhawk/src/testing/sdr/dom/waveforms/MessageTestCpp/MessageTestCpp.sad.xml @@ -32,7 +32,7 @@ with this program. If not, see http://www.gnu.org/licenses/. - + MessageReceiverCpp_1 @@ -41,7 +41,7 @@ with this program. If not, see http://www.gnu.org/licenses/. - + MessageSenderCpp_1 @@ -50,32 +50,32 @@ with this program. If not, see http://www.gnu.org/licenses/. - + - + message_out - + message_in - + - + message_in - + - + message_out - + diff --git a/redhawk/src/testing/tests/test_08_MessagingCpp.py b/redhawk/src/testing/tests/test_08_MessagingCpp.py index 4793eed9d..f75310c4b 100644 --- a/redhawk/src/testing/tests/test_08_MessagingCpp.py +++ b/redhawk/src/testing/tests/test_08_MessagingCpp.py @@ -25,6 +25,7 @@ import threading import time +import CosEventChannelAdmin class EventPortConnectionsTest(scatest.CorbaTestCase): def setUp(self): @@ -96,10 +97,34 @@ def test_EventDevicePortConnectionCppOnly(self): components = app._get_registeredComponents() for component in components: print component.componentObject._get_identifier() - if 'DCE:b1fe6cc1-2562-4878-9a69-f191f89a6ef8' in component.componentObject._get_identifier(): + if 'MessageReceiverCpp_1' in component.componentObject._get_identifier(): stuff = component.componentObject.query([]) recval = any.from_any(stuff[0].value) self.assertEquals(6, len(recval)) for val in recval: self.assertEquals('test_message' in val, True) app.releaseObject() # kill producer/consumer + + def test_QueryablePortCpp(self): + self._devBooter, self._devMgr = self.launchDeviceManager("/nodes/test_BasicTestDevice_node/DeviceManager.dcd.xml", self._domMgr) + self.assertNotEqual(self._devBooter, None) + self._domMgr.installApplication("/waveforms/MessageTestCpp/MessageTestCpp.sad.xml") + appFact = self._domMgr._get_applicationFactories()[0] + app = appFact.create(appFact._get_name(), [], []) + for component in app._get_registeredComponents(): + if 'MessageSenderCpp_1' in component.componentObject._get_identifier(): + sender_port = component.componentObject.getPort('message_out') + elif 'MessageReceiverCpp_1' in component.componentObject._get_identifier(): + receiver_port = component.componentObject.getPort('message_in') + + # There should be two connections, one to the receiver's port and + # another to the event channel + connections = sender_port._get_connections() + self.assertEqual(len(connections), 2) + for connection in connections: + if 'direct' in connection.connectionId: + self.assertTrue(connection.port._is_equivalent(receiver_port)) + else: + channel = connection.port._narrow(CosEventChannelAdmin.EventChannel) + self.assertNotEqual(channel, None) + app.releaseObject() From d57d32a70fc068a6c91580e048aa773264c01873 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Thu, 8 Dec 2016 16:31:32 -0500 Subject: [PATCH 0607/1644] Fix build issue on CentOS 7 --- bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp index bfea7097a..98cffe744 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp @@ -413,7 +413,7 @@ class BufferedOutputStream::Impl : public Base::Impl { { // Push out all buffered data, which must be less than the full allocated // size otherwise it would have already been sent - _send(_buffer.slice(0, _bufferOffset), _bufferTime, eos); + this->_send(_buffer.slice(0, _bufferOffset), _bufferTime, eos); // Allocate a new buffer and reset the offset index _buffer = redhawk::buffer(_bufferSize); From dacc12d882ac9e3d28596f9e5b7a72ffdef8d5a6 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 8 Dec 2016 17:17:27 -0500 Subject: [PATCH 0608/1644] Add a description to the base C++ transport class so that each implementation (BulkIO, messaging, etc.) can provide additional information for logging --- bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp | 8 +------- bulkioInterfaces/libsrc/cpp/bulkio_transport.cpp | 15 +++++++-------- bulkioInterfaces/libsrc/cpp/bulkio_transport.h | 2 -- burstioInterfaces/src/cpp/lib/OutPortImpl.h | 13 ++++++++++--- redhawk/src/base/framework/MessageSupplier.cpp | 10 ++++++++++ redhawk/src/base/framework/UsesPort.cpp | 7 +++++++ redhawk/src/base/include/ossie/UsesPort.h | 2 ++ 7 files changed, 37 insertions(+), 20 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp index de58c3270..74076de07 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_port.cpp @@ -270,13 +270,7 @@ namespace bulkio { throw CF::Port::InvalidPort(1, "Unable to narrow"); } - PortTransportType* transport = PortTransportType::Factory(connectionId, name, port); - if (transport->isLocal()) { - PortBase* local_port = ossie::corba::getLocalServant(port); - LOG_DEBUG(logger, "Using local connection to port " << local_port->getName() - << " for connection " << connectionId); - } - return transport; + return PortTransportType::Factory(connectionId, name, port); } diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_transport.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_transport.cpp index a6ffceec3..2d87add0c 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_transport.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_transport.cpp @@ -105,12 +105,6 @@ namespace bulkio { return _port; } - template - bool PortTransport::isLocal() const - { - return false; - } - template void PortTransport::_sendPacket(const BufferType& data, const BULKIO::PrecisionUTCTime& T, @@ -153,6 +147,11 @@ namespace bulkio { { } + virtual std::string getDescription() const + { + return "CORBA BulkIO transport"; + } + protected: virtual void _pushSRI(const BULKIO::StreamSRI& sri) { @@ -326,9 +325,9 @@ namespace bulkio { _localPort->_remove_ref(); } - virtual bool isLocal() const + virtual std::string getDescription() const { - return true; + return "local BulkIO connection to " + _localPort->getName(); } protected: diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_transport.h b/bulkioInterfaces/libsrc/cpp/bulkio_transport.h index 837ac3721..0d44ff604 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_transport.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_transport.h @@ -54,8 +54,6 @@ namespace bulkio { PtrType port(); - virtual bool isLocal() const; - linkStatistics stats; protected: diff --git a/burstioInterfaces/src/cpp/lib/OutPortImpl.h b/burstioInterfaces/src/cpp/lib/OutPortImpl.h index 7dc7fc86d..e7d027a01 100644 --- a/burstioInterfaces/src/cpp/lib/OutPortImpl.h +++ b/burstioInterfaces/src/cpp/lib/OutPortImpl.h @@ -74,6 +74,11 @@ namespace burstio { { } + virtual std::string getDescription() const + { + return "CORBA BurstIO transport"; + } + void pushBursts(const BurstSequenceType& bursts, boost::system_time startTime, float queueDepth) { try { @@ -148,6 +153,11 @@ namespace burstio { { } + virtual std::string getDescription() const + { + return "local BurstIO connection to " + localPort_->getName(); + } + void pushBursts(const BurstSequenceType& bursts, boost::system_time startTime, float queueDepth) { try { @@ -586,11 +596,8 @@ namespace burstio { var_type port = ossie::corba::_narrowSafe(object); InPort* local_port = ossie::corba::getLocalServant >(port); if (local_port) { - RH_DEBUG(logger, "Using local transport to port " << local_port->getName() - << " for connection " << connectionId); return new LocalTransport(this, local_port, port, connectionId); } else { - RH_DEBUG(logger, "Using CORBA transport for connection " << connectionId); return new RemoteTransport(this, port, connectionId); } } diff --git a/redhawk/src/base/framework/MessageSupplier.cpp b/redhawk/src/base/framework/MessageSupplier.cpp index 0de8f6616..cdb98fc30 100644 --- a/redhawk/src/base/framework/MessageSupplier.cpp +++ b/redhawk/src/base/framework/MessageSupplier.cpp @@ -55,6 +55,11 @@ class MessageSupplierPort::RemoteTransport : public MessageSupplierPort::Message _consumer->connect_push_supplier(CosEventComm::PushSupplier::_nil()); } + virtual std::string getDescription() const + { + return "CORBA messaging transport"; + } + void push(const CORBA::Any& data) { _consumer->push(data); @@ -110,6 +115,11 @@ class MessageSupplierPort::LocalTransport : public MessageSupplierPort::MessageT { } + virtual std::string getDescription() const + { + return "local messaging connection to " + _consumer->getName(); + } + void push(const CORBA::Any& data) { CF::Properties* temp; diff --git a/redhawk/src/base/framework/UsesPort.cpp b/redhawk/src/base/framework/UsesPort.cpp index eb1160511..fd489a9fd 100644 --- a/redhawk/src/base/framework/UsesPort.cpp +++ b/redhawk/src/base/framework/UsesPort.cpp @@ -36,6 +36,11 @@ namespace redhawk { return _connectionId; } + std::string BasicTransport::getDescription() const + { + return "basic transport"; + } + bool BasicTransport::isAlive() const { return _alive; @@ -79,6 +84,8 @@ namespace redhawk { if (entry == _transports.end()) { BasicTransport* transport = _createTransport(connection, connection_id); _addTransportEntry(transport); + RH_DEBUG(logger, "Using " << transport->getDescription() + << " for connection '" << connection_id << "'"); } else { // TODO: Replace the object reference } diff --git a/redhawk/src/base/include/ossie/UsesPort.h b/redhawk/src/base/include/ossie/UsesPort.h index b3d59823e..2c0339edd 100644 --- a/redhawk/src/base/include/ossie/UsesPort.h +++ b/redhawk/src/base/include/ossie/UsesPort.h @@ -61,6 +61,8 @@ namespace redhawk { const std::string& connectionId() const; CORBA::Object_ptr objref() const; + virtual std::string getDescription() const; + bool isAlive() const; void setAlive(bool alive); From 3ab4e908b33ba96debb7c97ad74d53c3fac6ad8e Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 12 Dec 2016 10:31:37 -0500 Subject: [PATCH 0609/1644] Ignore build products --- GPP/.gitignore | 11 ++++++++++- GPP/cpp/.gitignore | 10 ---------- GPP/tests/.gitignore | 4 +++- burstioInterfaces/.gitignore | 21 +++++++++++---------- redhawk/src/testing/.gitignore | 1 + 5 files changed, 25 insertions(+), 22 deletions(-) diff --git a/GPP/.gitignore b/GPP/.gitignore index 8a622b0fb..4ebbe450c 100644 --- a/GPP/.gitignore +++ b/GPP/.gitignore @@ -1,3 +1,12 @@ *.o *.pyc - +.deps/ +Makefile +Makefile.in +aclocal.m4 +autom4te.cache/ +config.* +configure +depcomp +install-sh +missing diff --git a/GPP/cpp/.gitignore b/GPP/cpp/.gitignore index bc1a67473..c2b075fa7 100644 --- a/GPP/cpp/.gitignore +++ b/GPP/cpp/.gitignore @@ -1,13 +1,3 @@ -.deps .dirstamp GPP -Makefile -Makefile.in -aclocal.m4 -autom4te.cache/ compile -config.* -configure -depcomp -install-sh -missing diff --git a/GPP/tests/.gitignore b/GPP/tests/.gitignore index 65cc76261..f8310f91b 100644 --- a/GPP/tests/.gitignore +++ b/GPP/tests/.gitignore @@ -1,4 +1,6 @@ sdr/dev/devices/GPP/ sdr/dev/mgr/DeviceManager sdr/dom/mgr/DomainManager - +sdr/dom/components/check_cwd_cpp/cpp/check_cwd_cpp +sdr/dom/components/check_cwd_java/java/bin/ +sdr/dom/components/check_cwd_java/java/check_cwd_java.jar diff --git a/burstioInterfaces/.gitignore b/burstioInterfaces/.gitignore index 3d94b103f..fad13ac1e 100644 --- a/burstioInterfaces/.gitignore +++ b/burstioInterfaces/.gitignore @@ -1,3 +1,13 @@ +*.class +*.o +*.la +*.lo +*.java +*.jar +.deps/ +.idlj/ +.idljni/ +.libs/ Makefile Makefile.in aclocal.m4 @@ -14,19 +24,10 @@ install-sh libtool ltmain.sh missing -*.class -*.idlj -*.o -*.la -*.lo -*.java -*.jar -*.omnijni -*.deps -*.libs classlist.txt filelist.txt src/cpp/redhawk src/java/redhawk +src/python/build/ src/python/redhawk/burstioInterfaces src/python/setup.py diff --git a/redhawk/src/testing/.gitignore b/redhawk/src/testing/.gitignore index b3ba3934b..31e98ba5d 100644 --- a/redhawk/src/testing/.gitignore +++ b/redhawk/src/testing/.gitignore @@ -37,6 +37,7 @@ sdr/dom/components/TestCppOptionalProps/cpp/TestCppOptionalProps sdr/dom/components/foo/bar/comp/cpp/comp sdr/dom/components/C1/cpp/C1 sdr/dom/components/C2/cpp/C2 +sdr/dom/components/msg_through_cpp/cpp/msg_through_cpp sdr/dom/components/prop_trigger_timing/cpp/prop_trigger_timing sdr/dom/domain/ sdr/dom/mgr/DomainManager* From e817a623849443dc5fc1c4b796bf15eb52b172b4 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 12 Dec 2016 13:42:58 -0500 Subject: [PATCH 0610/1644] CF-1436 Basic test for ComponentHost and shared library components --- redhawk/src/configure.ac | 1 + redhawk/src/testing/.gitignore | 2 + redhawk/src/testing/Makefile.am | 1 + .../src/testing/_unitTestHelpers/scatest.py | 12 + .../BasicShared/.BasicShared.wavedev | 6 + .../BasicShared/BasicShared.prf.xml | 8 + .../BasicShared/BasicShared.scd.xml | 45 +++ .../BasicShared/BasicShared.spd.xml | 27 ++ .../dom/components/BasicShared/cpp/.md5sums | 10 + .../BasicShared/cpp/BasicShared.cpp | 274 ++++++++++++++++++ .../components/BasicShared/cpp/BasicShared.h | 40 +++ .../BasicShared/cpp/BasicShared_base.cpp | 87 ++++++ .../BasicShared/cpp/BasicShared_base.h | 49 ++++ .../components/BasicShared/cpp/Makefile.am | 65 +++++ .../BasicShared/cpp/Makefile.am.ide | 30 ++ .../dom/components/BasicShared/cpp/main.cpp | 30 ++ .../BasicSharedWave/BasicSharedWave.sad.xml | 32 ++ .../testing/tests/test_04_ComponentHost.py | 48 +++ 18 files changed, 767 insertions(+) create mode 100644 redhawk/src/testing/sdr/dom/components/BasicShared/.BasicShared.wavedev create mode 100644 redhawk/src/testing/sdr/dom/components/BasicShared/BasicShared.prf.xml create mode 100644 redhawk/src/testing/sdr/dom/components/BasicShared/BasicShared.scd.xml create mode 100644 redhawk/src/testing/sdr/dom/components/BasicShared/BasicShared.spd.xml create mode 100644 redhawk/src/testing/sdr/dom/components/BasicShared/cpp/.md5sums create mode 100644 redhawk/src/testing/sdr/dom/components/BasicShared/cpp/BasicShared.cpp create mode 100644 redhawk/src/testing/sdr/dom/components/BasicShared/cpp/BasicShared.h create mode 100644 redhawk/src/testing/sdr/dom/components/BasicShared/cpp/BasicShared_base.cpp create mode 100644 redhawk/src/testing/sdr/dom/components/BasicShared/cpp/BasicShared_base.h create mode 100644 redhawk/src/testing/sdr/dom/components/BasicShared/cpp/Makefile.am create mode 100644 redhawk/src/testing/sdr/dom/components/BasicShared/cpp/Makefile.am.ide create mode 100644 redhawk/src/testing/sdr/dom/components/BasicShared/cpp/main.cpp create mode 100644 redhawk/src/testing/sdr/dom/waveforms/BasicSharedWave/BasicSharedWave.sad.xml create mode 100644 redhawk/src/testing/tests/test_04_ComponentHost.py diff --git a/redhawk/src/configure.ac b/redhawk/src/configure.ac index ee39a7be0..55d90a612 100644 --- a/redhawk/src/configure.ac +++ b/redhawk/src/configure.ac @@ -358,6 +358,7 @@ AC_CONFIG_FILES(Makefile \ testing/sdr/dom/components/SimpleComponent/SimpleComponent_cpp_impl1/Makefile \ testing/sdr/dom/components/BasicAC/basicac_java_impl1/Makefile \ testing/sdr/dom/components/BasicAC/BasicAC_cpp_impl1/Makefile \ + testing/sdr/dom/components/BasicShared/cpp/Makefile \ testing/sdr/dom/components/MessageReceiverCpp/Makefile \ testing/sdr/dom/components/MessageSenderCpp/Makefile \ testing/sdr/dom/components/EventSend/EventSend_java_impl1/Makefile \ diff --git a/redhawk/src/testing/.gitignore b/redhawk/src/testing/.gitignore index 31e98ba5d..5a6a8f0f0 100644 --- a/redhawk/src/testing/.gitignore +++ b/redhawk/src/testing/.gitignore @@ -1,4 +1,5 @@ *.jar +*.so build helpers/buildconfig.py _unitTestHelpers/buildconfig.py @@ -41,6 +42,7 @@ sdr/dom/components/msg_through_cpp/cpp/msg_through_cpp sdr/dom/components/prop_trigger_timing/cpp/prop_trigger_timing sdr/dom/domain/ sdr/dom/mgr/DomainManager* +sdr/dom/mgr/rh/ sdr/runtests.log .pythonInstallFiles sdr/dev/nodes/test_affinity_node_socket/DeviceManager.dcd.xml diff --git a/redhawk/src/testing/Makefile.am b/redhawk/src/testing/Makefile.am index 387c26081..393578b6f 100644 --- a/redhawk/src/testing/Makefile.am +++ b/redhawk/src/testing/Makefile.am @@ -46,6 +46,7 @@ SUBDIRS = sdr/dev/devices/ExecutableDevice \ sdr/dom/components/linkedLibraryTest \ sdr/dom/components/TestCppsoftpkgDeps \ sdr/dom/components/BasicAC/BasicAC_cpp_impl1 \ + sdr/dom/components/BasicShared/cpp \ sdr/dom/components/SimpleComponent/SimpleComponent_cpp_impl1 \ sdr/dom/components/MessageReceiverCpp \ sdr/dom/components/MessageSenderCpp \ diff --git a/redhawk/src/testing/_unitTestHelpers/scatest.py b/redhawk/src/testing/_unitTestHelpers/scatest.py index c6ad81825..1d2d17f8c 100644 --- a/redhawk/src/testing/_unitTestHelpers/scatest.py +++ b/redhawk/src/testing/_unitTestHelpers/scatest.py @@ -127,6 +127,18 @@ def setupDeviceAndDomainMgrPackage(): for xmlFile in glob.glob(os.path.join(domMgrSrc, '*.xml')): updateLink(xmlFile, os.path.join(domMgrDest, os.path.basename(xmlFile))) + # "Install" the ComponentHost softpkg + compHostSrc = os.path.join(sdrSrc, 'ComponentHost') + compHostDest = os.path.join(getSdrPath(), "dom/mgr/rh/ComponentHost") + try: + os.makedirs(compHostDest) + except OSError: + # Assume it failed because the directory already exists + pass + updateLink(os.path.join(compHostSrc, 'ComponentHost'), os.path.join(compHostDest, 'ComponentHost')) + for xmlFile in glob.glob(os.path.join(compHostSrc, '*.xml')): + updateLink(xmlFile, os.path.join(compHostDest, os.path.basename(xmlFile))) + # "Install" the DeviceManager softpkg. devMgrSrc = os.path.join(sdrSrc, 'devmgr') devMgrDest = os.path.join(getSdrPath(), "dev", "mgr") diff --git a/redhawk/src/testing/sdr/dom/components/BasicShared/.BasicShared.wavedev b/redhawk/src/testing/sdr/dom/components/BasicShared/.BasicShared.wavedev new file mode 100644 index 000000000..f7936e04b --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/BasicShared/.BasicShared.wavedev @@ -0,0 +1,6 @@ + + + + + + diff --git a/redhawk/src/testing/sdr/dom/components/BasicShared/BasicShared.prf.xml b/redhawk/src/testing/sdr/dom/components/BasicShared/BasicShared.prf.xml new file mode 100644 index 000000000..ff0c301cd --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/BasicShared/BasicShared.prf.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/redhawk/src/testing/sdr/dom/components/BasicShared/BasicShared.scd.xml b/redhawk/src/testing/sdr/dom/components/BasicShared/BasicShared.scd.xml new file mode 100644 index 000000000..df94ceaf5 --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/BasicShared/BasicShared.scd.xml @@ -0,0 +1,45 @@ + + + + 2.2 + + resource + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/redhawk/src/testing/sdr/dom/components/BasicShared/BasicShared.spd.xml b/redhawk/src/testing/sdr/dom/components/BasicShared/BasicShared.spd.xml new file mode 100644 index 000000000..9e172ff96 --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/BasicShared/BasicShared.spd.xml @@ -0,0 +1,27 @@ + + + + + + null + + + + + + + + + The implementation contains descriptive information about the template for a software resource. + + + cpp/BasicShared.so + + + + + + + + + diff --git a/redhawk/src/testing/sdr/dom/components/BasicShared/cpp/.md5sums b/redhawk/src/testing/sdr/dom/components/BasicShared/cpp/.md5sums new file mode 100644 index 000000000..e30756515 --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/BasicShared/cpp/.md5sums @@ -0,0 +1,10 @@ +ebab982ed6b7711d65ef5c4ed652f729 main.cpp +d23f51d099f8c3b419d46aa7a2d953de reconf +14dde722388b115ea07760e334c50f92 BasicShared_base.cpp +8b63aebb71c1015a942d2e7200816be8 configure.ac +91b35020418b07c156987bace0f23823 BasicShared.cpp +4e5b9b0356f5fb46ac9aefa910763516 Makefile.am.ide +b640eb40dc780b01f8872f6a9bcc9372 BasicShared.h +b1835160ba93e9e1248209acc174363d build.sh +03c8ef5a559ed7754644d158f5f8693c Makefile.am +82001e92f27216006398b208ba37bafe BasicShared_base.h diff --git a/redhawk/src/testing/sdr/dom/components/BasicShared/cpp/BasicShared.cpp b/redhawk/src/testing/sdr/dom/components/BasicShared/cpp/BasicShared.cpp new file mode 100644 index 000000000..1cc74735c --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/BasicShared/cpp/BasicShared.cpp @@ -0,0 +1,274 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK core. + * + * REDHAWK core is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ +/************************************************************************** + + This is the component code. This file contains the child class where + custom functionality can be added to the component. Custom + functionality to the base class can be extended here. Access to + the ports can also be done from this class + +**************************************************************************/ + +#include "BasicShared.h" + +PREPARE_LOGGING(BasicShared_i) + +BasicShared_i::BasicShared_i(const char *uuid, const char *label) : + BasicShared_base(uuid, label) +{ + // Avoid placing constructor code here. Instead, use the "constructor" function. + +} + +BasicShared_i::~BasicShared_i() +{ +} + +void BasicShared_i::constructor() +{ + /*********************************************************************************** + This is the RH constructor. All properties are properly initialized before this function is called + ***********************************************************************************/ + setPropertyQueryImpl(pid, this, &BasicShared_i::get_pid); +} + +pid_t BasicShared_i::get_pid() +{ + return ::getpid(); +} + +/*********************************************************************************************** + + Basic functionality: + + The service function is called by the serviceThread object (of type ProcessThread). + This call happens immediately after the previous call if the return value for + the previous call was NORMAL. + If the return value for the previous call was NOOP, then the serviceThread waits + an amount of time defined in the serviceThread's constructor. + + SRI: + To create a StreamSRI object, use the following code: + std::string stream_id = "testStream"; + BULKIO::StreamSRI sri = bulkio::sri::create(stream_id); + + Time: + To create a PrecisionUTCTime object, use the following code: + BULKIO::PrecisionUTCTime tstamp = bulkio::time::utils::now(); + + + Ports: + + Data is passed to the serviceFunction through by reading from input streams + (BulkIO only). The input stream class is a port-specific class, so each port + implementing the BulkIO interface will have its own type-specific input stream. + UDP multicast (dataSDDS and dataVITA49) and string-based (dataString, dataXML and + dataFile) do not support streams. + + The input stream from which to read can be requested with the getCurrentStream() + method. The optional argument to getCurrentStream() is a floating point number that + specifies the time to wait in seconds. A zero value is non-blocking. A negative value + is blocking. Constants have been defined for these values, bulkio::Const::BLOCKING and + bulkio::Const::NON_BLOCKING. + + More advanced uses of input streams are possible; refer to the REDHAWK documentation + for more details. + + Input streams return data blocks that automatically manage the memory for the data + and include the SRI that was in effect at the time the data was received. It is not + necessary to delete the block; it will be cleaned up when it goes out of scope. + + To send data using a BulkIO interface, create an output stream and write the + data to it. When done with the output stream, the close() method sends and end-of- + stream flag and cleans up. + + NOTE: If you have a BULKIO dataSDDS or dataVITA49 port, you must manually call + "port->updateStats()" to update the port statistics when appropriate. + + Example: + // This example assumes that the component has two ports: + // An input (provides) port of type bulkio::InShortPort called dataShort_in + // An output (uses) port of type bulkio::OutFloatPort called dataFloat_out + // The mapping between the port and the class is found + // in the component base class header file + // The component class must have an output stream member; add to + // BasicShared.h: + // bulkio::OutFloatStream outputStream; + + bulkio::InShortStream inputStream = dataShort_in->getCurrentStream(); + if (!inputStream) { // No streams are available + return NOOP; + } + + bulkio::ShortDataBlock block = inputStream.read(); + if (!block) { // No data available + // Propagate end-of-stream + if (inputStream.eos()) { + outputStream.close(); + } + return NOOP; + } + + short* inputData = block.data(); + std::vector outputData; + outputData.resize(block.size()); + for (size_t index = 0; index < block.size(); ++index) { + outputData[index] = (float) inputData[index]; + } + + // If there is no output stream open, create one + if (!outputStream) { + outputStream = dataFloat_out->createStream(block.sri()); + } else if (block.sriChanged()) { + // Update output SRI + outputStream.sri(block.sri()); + } + + // Write to the output stream + outputStream.write(outputData, block.getTimestamps()); + + // Propagate end-of-stream + if (inputStream.eos()) { + outputStream.close(); + } + + return NORMAL; + + If working with complex data (i.e., the "mode" on the SRI is set to + true), the data block's complex() method will return true. Data blocks + provide functions that return the correct interpretation of the data + buffer and number of complex elements: + + if (block.complex()) { + std::complex* data = block.cxdata(); + for (size_t index = 0; index < block.cxsize(); ++index) { + data[index] = std::abs(data[index]); + } + outputStream.write(data, block.cxsize(), bulkio::time::utils::now()); + } + + Interactions with non-BULKIO ports are left up to the component developer's discretion + + Messages: + + To receive a message, you need (1) an input port of type MessageEvent, (2) a message prototype described + as a structure property of kind message, (3) a callback to service the message, and (4) to register the callback + with the input port. + + Assuming a property of type message is declared called "my_msg", an input port called "msg_input" is declared of + type MessageEvent, create the following code: + + void BasicShared_i::my_message_callback(const std::string& id, const my_msg_struct &msg){ + } + + Register the message callback onto the input port with the following form: + this->msg_input->registerMessage("my_msg", this, &BasicShared_i::my_message_callback); + + To send a message, you need to (1) create a message structure, (2) a message prototype described + as a structure property of kind message, and (3) send the message over the port. + + Assuming a property of type message is declared called "my_msg", an output port called "msg_output" is declared of + type MessageEvent, create the following code: + + ::my_msg_struct msg_out; + this->msg_output->sendMessage(msg_out); + + Accessing the Application and Domain Manager: + + Both the Application hosting this Component and the Domain Manager hosting + the Application are available to the Component. + + To access the Domain Manager: + CF::DomainManager_ptr dommgr = this->getDomainManager()->getRef(); + To access the Application: + CF::Application_ptr app = this->getApplication()->getRef(); + + Properties: + + Properties are accessed directly as member variables. For example, if the + property name is "baudRate", it may be accessed within member functions as + "baudRate". Unnamed properties are given the property id as its name. + Property types are mapped to the nearest C++ type, (e.g. "string" becomes + "std::string"). All generated properties are declared in the base class + (BasicShared_base). + + Simple sequence properties are mapped to "std::vector" of the simple type. + Struct properties, if used, are mapped to C++ structs defined in the + generated file "struct_props.h". Field names are taken from the name in + the properties file; if no name is given, a generated name of the form + "field_n" is used, where "n" is the ordinal number of the field. + + Example: + // This example makes use of the following Properties: + // - A float value called scaleValue + // - A boolean called scaleInput + + if (scaleInput) { + dataOut[i] = dataIn[i] * scaleValue; + } else { + dataOut[i] = dataIn[i]; + } + + Callback methods can be associated with a property so that the methods are + called each time the property value changes. This is done by calling + addPropertyListener(, this, &BasicShared_i::) + in the constructor. + + The callback method receives two arguments, the old and new values, and + should return nothing (void). The arguments can be passed by value, + receiving a copy (preferred for primitive types), or by const reference + (preferred for strings, structs and vectors). + + Example: + // This example makes use of the following Properties: + // - A float value called scaleValue + // - A struct property called status + + //Add to BasicShared.cpp + BasicShared_i::BasicShared_i(const char *uuid, const char *label) : + BasicShared_base(uuid, label) + { + addPropertyListener(scaleValue, this, &BasicShared_i::scaleChanged); + addPropertyListener(status, this, &BasicShared_i::statusChanged); + } + + void BasicShared_i::scaleChanged(float oldValue, float newValue) + { + LOG_DEBUG(BasicShared_i, "scaleValue changed from" << oldValue << " to " << newValue); + } + + void BasicShared_i::statusChanged(const status_struct& oldValue, const status_struct& newValue) + { + LOG_DEBUG(BasicShared_i, "status changed"); + } + + //Add to BasicShared.h + void scaleChanged(float oldValue, float newValue); + void statusChanged(const status_struct& oldValue, const status_struct& newValue); + + +************************************************************************************************/ +int BasicShared_i::serviceFunction() +{ + LOG_DEBUG(BasicShared_i, "serviceFunction() example log message"); + + return NOOP; +} + diff --git a/redhawk/src/testing/sdr/dom/components/BasicShared/cpp/BasicShared.h b/redhawk/src/testing/sdr/dom/components/BasicShared/cpp/BasicShared.h new file mode 100644 index 000000000..bf8b5c988 --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/BasicShared/cpp/BasicShared.h @@ -0,0 +1,40 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK core. + * + * REDHAWK core is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ +#ifndef BASICSHARED_I_IMPL_H +#define BASICSHARED_I_IMPL_H + +#include "BasicShared_base.h" + +class BasicShared_i : public BasicShared_base +{ + ENABLE_LOGGING + public: + BasicShared_i(const char *uuid, const char *label); + ~BasicShared_i(); + + void constructor(); + + int serviceFunction(); + + private: + pid_t get_pid(); +}; + +#endif // BASICSHARED_I_IMPL_H diff --git a/redhawk/src/testing/sdr/dom/components/BasicShared/cpp/BasicShared_base.cpp b/redhawk/src/testing/sdr/dom/components/BasicShared/cpp/BasicShared_base.cpp new file mode 100644 index 000000000..6842c566d --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/BasicShared/cpp/BasicShared_base.cpp @@ -0,0 +1,87 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK core. + * + * REDHAWK core is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ +#include "BasicShared_base.h" + +/******************************************************************************************* + + AUTO-GENERATED CODE. DO NOT MODIFY + + The following class functions are for the base class for the component class. To + customize any of these functions, do not modify them here. Instead, overload them + on the child class + +******************************************************************************************/ + +BasicShared_base::BasicShared_base(const char *uuid, const char *label) : + Component(uuid, label), + ThreadedComponent() +{ + setThreadName(label); + + loadProperties(); +} + +BasicShared_base::~BasicShared_base() +{ +} + +/******************************************************************************************* + Framework-level functions + These functions are generally called by the framework to perform housekeeping. +*******************************************************************************************/ +void BasicShared_base::start() throw (CORBA::SystemException, CF::Resource::StartError) +{ + Component::start(); + ThreadedComponent::startThread(); +} + +void BasicShared_base::stop() throw (CORBA::SystemException, CF::Resource::StopError) +{ + Component::stop(); + if (!ThreadedComponent::stopThread()) { + throw CF::Resource::StopError(CF::CF_NOTSET, "Processing thread did not die"); + } +} + +void BasicShared_base::releaseObject() throw (CORBA::SystemException, CF::LifeCycle::ReleaseError) +{ + // This function clears the component running condition so main shuts down everything + try { + stop(); + } catch (CF::Resource::StopError& ex) { + // TODO - this should probably be logged instead of ignored + } + + Component::releaseObject(); +} + +void BasicShared_base::loadProperties() +{ + addProperty(pid, + "pid", + "", + "readonly", + "", + "external", + "property"); + +} + + diff --git a/redhawk/src/testing/sdr/dom/components/BasicShared/cpp/BasicShared_base.h b/redhawk/src/testing/sdr/dom/components/BasicShared/cpp/BasicShared_base.h new file mode 100644 index 000000000..c41d16dbf --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/BasicShared/cpp/BasicShared_base.h @@ -0,0 +1,49 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK core. + * + * REDHAWK core is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ +#ifndef BASICSHARED_BASE_IMPL_BASE_H +#define BASICSHARED_BASE_IMPL_BASE_H + +#include +#include +#include + + +class BasicShared_base : public Component, protected ThreadedComponent +{ + public: + BasicShared_base(const char *uuid, const char *label); + ~BasicShared_base(); + + void start() throw (CF::Resource::StartError, CORBA::SystemException); + + void stop() throw (CF::Resource::StopError, CORBA::SystemException); + + void releaseObject() throw (CF::LifeCycle::ReleaseError, CORBA::SystemException); + + void loadProperties(); + + protected: + // Member variables exposed as properties + /// Property: pid + CORBA::ULong pid; + + private: +}; +#endif // BASICSHARED_BASE_IMPL_BASE_H diff --git a/redhawk/src/testing/sdr/dom/components/BasicShared/cpp/Makefile.am b/redhawk/src/testing/sdr/dom/components/BasicShared/cpp/Makefile.am new file mode 100644 index 000000000..42b901a07 --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/BasicShared/cpp/Makefile.am @@ -0,0 +1,65 @@ +# +# This file is protected by Copyright. Please refer to the COPYRIGHT file +# distributed with this source distribution. +# +# This file is part of REDHAWK core. +# +# REDHAWK core is free software: you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# REDHAWK core is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License +# for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/. +# + +CFDIR = $(top_srcdir)/base +PROJECTDEPS_CFLAGS = -I$(CFDIR)/include -I$(CFDIR)/include/ossie +PROJECTDEPS_LIBS = $(CFDIR)/framework/libossiecf.la $(CFDIR)/framework/idl/libossieidl.la + +ossieName = BasicShared +libdir = $(prefix)/dom/components/BasicShared/cpp +lib_LTLIBRARIES = BasicShared.la + +.PHONY: convenience-link clean-convenience-link + +install: + +all-local : convenience-link +clean-local : clean-convenience-link + +convenience-link : BasicShared.la + @ln -fs .libs/BasicShared.so + +clean-convenience-link: + @rm -f BasicShared.so + +distclean-local: + rm -rf m4 + rm -f config.* + rm -rf autom4te.cache + rm -f acinclude.m4 + rm -f aclocal.m4 + rm -f configure + rm -f depcomp + rm -f install-sh + rm -f ltmain.sh + rm -f Makefile.in + rm -f missing + rm -rf .deps + + +# Sources, libraries and library directories are auto-included from a file +# generated by the REDHAWK IDE. You can remove/modify the following lines if +# you wish to manually control these options. +include $(srcdir)/Makefile.am.ide +BasicShared_la_SOURCES = $(redhawk_SOURCES_auto) +BasicShared_la_LIBADD = $(SOFTPKG_LIBS) $(PROJECTDEPS_LIBS) $(BOOST_LDFLAGS) $(BOOST_THREAD_LIB) $(BOOST_REGEX_LIB) $(BOOST_SYSTEM_LIB) $(INTERFACEDEPS_LIBS) $(redhawk_LDADD_auto) +BasicShared_la_CXXFLAGS = -Wall $(SOFTPKG_CFLAGS) $(PROJECTDEPS_CFLAGS) $(BOOST_CPPFLAGS) $(INTERFACEDEPS_CFLAGS) $(redhawk_INCLUDES_auto) +BasicShared_la_LDFLAGS = -shared -module -export-dynamic -export-symbols-regex 'make_component' -avoid-version $(redhawk_LDFLAGS_auto) + diff --git a/redhawk/src/testing/sdr/dom/components/BasicShared/cpp/Makefile.am.ide b/redhawk/src/testing/sdr/dom/components/BasicShared/cpp/Makefile.am.ide new file mode 100644 index 000000000..7b9de3784 --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/BasicShared/cpp/Makefile.am.ide @@ -0,0 +1,30 @@ +# +# This file is protected by Copyright. Please refer to the COPYRIGHT file +# distributed with this source distribution. +# +# This file is part of REDHAWK core. +# +# REDHAWK core is free software: you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# REDHAWK core is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License +# for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/. +# +# This file is regularly auto-generated by the REDHAWK IDE. Do not modify! +# Files can be excluded by right-clicking on the file in the project explorer +# and choosing Resource Configurations -> Exclude from build. Re-include files +# by opening the Properties dialog of your project and choosing C/C++ Build -> +# Tool Chain Editor, and un-checking "Exclude resource from build " +redhawk_SOURCES_auto = main.cpp +redhawk_SOURCES_auto += BasicShared.cpp +redhawk_SOURCES_auto += BasicShared.h +redhawk_SOURCES_auto += BasicShared_base.cpp +redhawk_SOURCES_auto += BasicShared_base.h + diff --git a/redhawk/src/testing/sdr/dom/components/BasicShared/cpp/main.cpp b/redhawk/src/testing/sdr/dom/components/BasicShared/cpp/main.cpp new file mode 100644 index 000000000..812960c91 --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/BasicShared/cpp/main.cpp @@ -0,0 +1,30 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK core. + * + * REDHAWK core is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ +#include +#include "ossie/ossieSupport.h" + +#include "BasicShared.h" +extern "C" { + Resource_impl* make_component(const std::string& uuid, const std::string& identifier) + { + return new BasicShared_i(uuid.c_str(), identifier.c_str()); + } +} + diff --git a/redhawk/src/testing/sdr/dom/waveforms/BasicSharedWave/BasicSharedWave.sad.xml b/redhawk/src/testing/sdr/dom/waveforms/BasicSharedWave/BasicSharedWave.sad.xml new file mode 100644 index 000000000..6a9c59d3e --- /dev/null +++ b/redhawk/src/testing/sdr/dom/waveforms/BasicSharedWave/BasicSharedWave.sad.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + BasicShared_1 + + + + + + + + + BasicShared_2 + + + + + + + + + + diff --git a/redhawk/src/testing/tests/test_04_ComponentHost.py b/redhawk/src/testing/tests/test_04_ComponentHost.py new file mode 100644 index 000000000..ee7d504e0 --- /dev/null +++ b/redhawk/src/testing/tests/test_04_ComponentHost.py @@ -0,0 +1,48 @@ +# +# This file is protected by Copyright. Please refer to the COPYRIGHT file +# distributed with this source distribution. +# +# This file is part of REDHAWK core. +# +# REDHAWK core is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation, either version 3 of the License, or (at your option) any +# later version. +# +# REDHAWK core is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +# details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/. +# + +from omniORB.any import to_any, from_any + +from _unitTestHelpers import scatest +from ossie.cf import CF + +class ComponentHostTest(scatest.CorbaTestCase): + def setUp(self): + self.launchDomainManager() + self.launchDeviceManager('/nodes/test_GPP_node/DeviceManager.dcd.xml') + + def test_BasicShared(self): + self.assertNotEqual(self._domainManager, None) + + app = self._domainManager.createApplication('/waveforms/BasicSharedWave/BasicSharedWave.sad.xml', + 'BasicSharedWave', [], []) + + comps = app._get_registeredComponents() + self.assertEqual(len(comps), 2) + + request = [CF.DataType('pid', to_any(None))] + props1 = comps[0].componentObject.query(request) + props2 = comps[1].componentObject.query(request) + + self.assertEqual(len(props1), 1) + self.assertEqual(props1[0].id, 'pid') + self.assertEqual(len(props2), 1) + self.assertEqual(props2[0].id, 'pid') + self.assertEqual(from_any(props1[0].value), from_any(props2[0].value)) From 8334bc3ea7228178dd4523a481b13363dfc8c358 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 12 Dec 2016 13:49:29 -0500 Subject: [PATCH 0611/1644] CF-1518 Basic test for launching shared library components in the sandbox --- redhawk/src/testing/tests/test_13_TestSB.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/redhawk/src/testing/tests/test_13_TestSB.py b/redhawk/src/testing/tests/test_13_TestSB.py index ad1889f50..e89751cb2 100644 --- a/redhawk/src/testing/tests/test_13_TestSB.py +++ b/redhawk/src/testing/tests/test_13_TestSB.py @@ -1383,6 +1383,24 @@ def test_MessageSource(self): self.assertEqual(len(comp.received_messages), 1) self.assertEqual(comp.received_messages[0], "test_message,0.0,'first'") + def test_BasicSharedComponent(self): + """ + Test that two shared library components launched from the sandbox have + the same process ID. + """ + comp1 = sb.launch('BasicShared') + comp2 = sb.launch('BasicShared') + self.assertEqual(int(comp1.pid), int(comp2.pid)) + + def test_NotSharedComponent(self): + """ + Test that forcing a shared library component to run in a non-shared + context reports a different process ID. + """ + comp1 = sb.launch('BasicShared') + comp2 = sb.launch('BasicShared', shared=False) + self.assertNotEqual(int(comp1.pid), int(comp2.pid)) + class BulkioTest(unittest.TestCase): XMLDATA = """ From 1a23294b16e3554cc3459735b3b34a5c80f22b88 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 12 Dec 2016 14:22:05 -0500 Subject: [PATCH 0612/1644] Make it easier to fold in new generated test components by setting PROJECTDEPS_CFLAGS and PROJECTDEPS_LIBS in core configure.ac --- redhawk/src/configure.ac | 4 ++++ .../testing/sdr/dom/components/BasicShared/cpp/Makefile.am | 4 ---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/redhawk/src/configure.ac b/redhawk/src/configure.ac index 55d90a612..aba73bf4e 100644 --- a/redhawk/src/configure.ac +++ b/redhawk/src/configure.ac @@ -244,6 +244,10 @@ AC_SUBST(OSSIE_CFLAGS, '-I$(top_srcdir)/base/include') AC_SUBST(OSSIE_IDLDIR, '$(top_srcdir)/idl') AC_SUBST(OSSIEIDL_LIBS, '$(top_builddir)/base/framework/idl/libossieidl.la') +# For test components with a generated Makefile.am, set the expected flags +AC_SUBST(PROJECTDEPS_CFLAGS, '$(OSSIE_CFLAGS) -I$(top_srcdir)/base/include/ossie') +AC_SUBST(PROJECTDEPS_LIBS, '$(top_builddir)/base/framework/libossiecf.la $(OSSIEIDL_LIBS)') + if test "$HAVE_JAVASUPPORT" = yes; then AC_SUBST(OSSIE_CLASSPATH, '$(top_srcdir)/base/framework/java/CFInterfaces.jar:$(top_srcdir)/base/framework/java/log4j-1.2.15.jar:$(top_srcdir)/base/framework/java/ossie/ossie.jar') diff --git a/redhawk/src/testing/sdr/dom/components/BasicShared/cpp/Makefile.am b/redhawk/src/testing/sdr/dom/components/BasicShared/cpp/Makefile.am index 42b901a07..b88a5df19 100644 --- a/redhawk/src/testing/sdr/dom/components/BasicShared/cpp/Makefile.am +++ b/redhawk/src/testing/sdr/dom/components/BasicShared/cpp/Makefile.am @@ -18,10 +18,6 @@ # along with this program. If not, see http://www.gnu.org/licenses/. # -CFDIR = $(top_srcdir)/base -PROJECTDEPS_CFLAGS = -I$(CFDIR)/include -I$(CFDIR)/include/ossie -PROJECTDEPS_LIBS = $(CFDIR)/framework/libossiecf.la $(CFDIR)/framework/idl/libossieidl.la - ossieName = BasicShared libdir = $(prefix)/dom/components/BasicShared/cpp lib_LTLIBRARIES = BasicShared.la From 128b0adfdc51ea792cdad2fbd5f1b9c6f4037887 Mon Sep 17 00:00:00 2001 From: 8530 <8530@vm-131.vsi-corp.com> Date: Mon, 12 Dec 2016 11:21:46 -0500 Subject: [PATCH 0613/1644] the device manager will try to resolve a registering service to the propertyemitter, propertyset, or lifecycle (initialize only) interface, and invoke those methods as defined , CF-463 --- .../control/sdr/devmgr/DeviceManager_impl.cpp | 255 ++++++++++++++---- .../control/sdr/devmgr/DeviceManager_impl.h | 11 + .../DeviceManager.dcd.xml | 36 +++ .../testing/sdr/dev/services/S2/S2.prf.xml | 13 + .../testing/sdr/dev/services/S2/S2.scd.xml | 18 ++ .../testing/sdr/dev/services/S2/S2.spd.xml | 25 ++ .../testing/sdr/dev/services/S2/python/S2.py | 153 +++++++++++ .../testing/tests/test_01_DeviceManager.py | 22 ++ 8 files changed, 488 insertions(+), 45 deletions(-) create mode 100644 redhawk/src/testing/sdr/dev/nodes/test_service_startup_node/DeviceManager.dcd.xml create mode 100644 redhawk/src/testing/sdr/dev/services/S2/S2.prf.xml create mode 100644 redhawk/src/testing/sdr/dev/services/S2/S2.scd.xml create mode 100644 redhawk/src/testing/sdr/dev/services/S2/S2.spd.xml create mode 100755 redhawk/src/testing/sdr/dev/services/S2/python/S2.py diff --git a/redhawk/src/control/sdr/devmgr/DeviceManager_impl.cpp b/redhawk/src/control/sdr/devmgr/DeviceManager_impl.cpp index 89aa17548..69d81376a 100644 --- a/redhawk/src/control/sdr/devmgr/DeviceManager_impl.cpp +++ b/redhawk/src/control/sdr/devmgr/DeviceManager_impl.cpp @@ -682,7 +682,6 @@ void DeviceManager_impl::createDeviceCacheLocation( } else { usageName = instantiation.getUsageName(); } - cacheAndCwdStruct cacheCwd = getOverloadCacheAndCwd(spdFile, instantiation); if (cacheCwd.cache.empty()) { @@ -1324,7 +1323,6 @@ void DeviceManager_impl::postConstructor ( checkDeviceConfigurationProfile(); - DeviceManagerConfiguration DCDParser; parseDCDProfile(DCDParser, overrideDomainName); SoftPkg devmgrspdparser; @@ -1885,6 +1883,7 @@ DeviceManager_impl::registeredServices ()throw (CORBA::SystemException) DeviceManager_impl::cacheAndCwdStruct DeviceManager_impl::getOverloadCacheAndCwd(std::string spdFile, const ossie::ComponentInstantiation& instantiation) { + LOG_DEBUG(DeviceManager_impl, "Getting Cache/Working Directories for: " << instantiation.instantiationId ); ossie::SpdSupport::ResourceInfo spdinfo = this->buildSpdinfo(spdFile, instantiation.instantiationId); const CF::Properties cprops = spdinfo.getNonNilConstructProperties(); redhawk::PropertyMap tmpProps = redhawk::PropertyMap::cast(cprops); @@ -1911,38 +1910,16 @@ ossie::SpdSupport::ResourceInfo DeviceManager_impl::buildSpdinfo(std::string spd } std::string spd_name = spdinfo.getName(); std::string spd_id = spdinfo.getID(); - LOG_INFO(DeviceManager_impl, "Device ID: " << device_id << " SPD loaded: " << spd_name << "' - '" << spd_id ); + LOG_INFO(DeviceManager_impl, "ID: " << device_id << " SPD loaded: " << spd_name << "' - '" << spd_id ); CF::Properties componentProperties; - DeviceManagerConfiguration DCDParser; - try { - File_stream _dcd(this->_fileSys, _deviceConfigurationProfile.c_str()); - DCDParser.load(_dcd); - _dcd.close(); - } catch ( std::exception& ex ) { - std::ostringstream eout; - eout << "The following standard exception occurred: "<rebind(service_name, registeringService); - } catch ( ... ) { - // there is already something bound to that name - // from the perspective of this framework implementation, the multiple names are not acceptable - // consider this a registered device - LOG_WARN(DeviceManager_impl, "Service is already registered") + if (serviceIsRegistered(name) == true ) { + LOG_WARN(DeviceManager_impl, "Service: " << name << ", is already registered") + return; + } + // Per the specification, service usagenames are not optional and *MUST* be + // unique per each service type. Therefore, a domain cannot have two + // services of the same usagename. + LOG_TRACE(DeviceManager_impl, "Binding service to name " << name); + CosNaming::Name_var service_name = ossie::corba::stringToName(name); + try { + rootContext->rebind(service_name, registeringService); + } catch ( ... ) { + // there is already something bound to that name + // from the perspective of this framework implementation, the multiple names are not acceptable + // consider this a registered device + LOG_WARN(DeviceManager_impl, "Service is already registered") return; - } + } - increment_registeredServices(registeringService, name); + // + // If the service support's any of the redhawk resource startup interfaces. + // + tryResourceStartup( registeringService, name ); + + increment_registeredServices(registeringService, name); - } else { - LOG_WARN(DeviceManager_impl, "Service is already registered") - return; - } //The registerService operation shall register the registeringService with the DomainManager //when the DeviceManager has already registered to the DomainManager and the @@ -3036,3 +3017,187 @@ bool DeviceManager_impl::allChildrenExited () return false; } + + +void DeviceManager_impl::tryResourceStartup( CORBA::Object_ptr registeringService, + const std::string &svc_name ) +{ + ossie::SpdSupport::ResourceInfo spdinfo; + try { + spdinfo = buildServiceSpd(svc_name); + } + catch(...){ + LOG_WARN(DeviceManager_impl, "Error processing SoftwareProfile for Service: " << svc_name << ", continue with normal registration."); + return; + } + + // + // Try standard Redhawk resource startup... + // initializeProperties, initialized, configure + // + CF::LifeCycle_var svc_lc = ossie::corba::_narrowSafe (registeringService); + CF::PropertySet_var svc_ps = ossie::corba::_narrowSafe (registeringService); + CF::PropertyEmitter_var svc_em = ossie::corba::_narrowSafe (registeringService); + std::ostringstream eout; + std::string emsg; + try { + LOG_DEBUG(DeviceManager_impl, "Initialize properties for spd/service: " << spdinfo.getName() << "/" << svc_name); + const CF::Properties cprops = spdinfo.getNonNilConstructProperties(); + for (unsigned int j = 0; j < cprops.length (); j++) { + LOG_DEBUG(DeviceManager_impl, "initializeProperties prop id " << cprops[j].id ); + } + + if ( !CORBA::is_nil(svc_em)) { + // Try to set the initial values for the resource + LOG_DEBUG(DeviceManager_impl, "Calling Service: " << svc_name << " initializeProperties props: " << cprops.length()); + svc_em->initializeProperties(cprops); + } + else { + if ( cprops.length() > 0 ) { + LOG_WARN(DeviceManager_impl,"Service: " << svc_name << " has configuration properties but does not implement PropertEmitter interface."); + } + } + + }catch(CF::PropertySet::InvalidConfiguration& e) { + eout << "Invalid Configuration exception occurred, service '" << svc_name <<"."; + } catch(CF::PropertySet::PartialConfiguration& e) { + eout << "Partial configuration exception for Service '" << svc_name << "."; + } catch ( std::exception& ex ) { + eout << "Standard exception occurred: "< 0 ) { + LOG_WARN(DeviceManager_impl, eout.str() << " Continuing with normal service registration."); + return; + } + + LOG_DEBUG(DeviceManager_impl, "Initializing Service " << svc_name << " on DeviceManager: " << _label); + eout.clear(); eout.str(""); + try { + if ( !CORBA::is_nil(svc_lc)) { + LOG_DEBUG(DeviceManager_impl, "Calling Service " << svc_name << " initialize method."); + svc_lc->initialize(); + } + else { + LOG_DEBUG(DeviceManager_impl, "Service does not implement LifeCycle interface."); + } + + } catch (CF::LifeCycle::InitializeError& ex) { + eout << "Service: "<< svc_name << " threw a CF::LifeCycle::InitializeError exception."; + } catch ( std::exception& ex ) { + eout << "The following standard exception occurred: "< 0 ) { + LOG_WARN(DeviceManager_impl, eout.str() << " Continuing with normal service registration."); + return; + } + + eout.clear(); eout.str(""); + //configure properties + try { + LOG_DEBUG(DeviceManager_impl, "Configuring service " << svc_name << " on Device Manager " << _label); + const CF::Properties cprops = spdinfo.getNonNilConfigureProperties(); + LOG_TRACE(DeviceManager_impl, "Listing configuration properties"); + for (unsigned int j=0; jconfigure (cprops); + } + else { + eout << "Service has configuration properties but does not implement PropertSet interface. Continuing with normal service registration."; + } + } + + } catch (CF::PropertySet::PartialConfiguration& ex) { + eout << "Partial configuration exception for Service '" << svc_name << "."; + } catch (CF::PropertySet::InvalidConfiguration& ex) { + eout << "Invalid Configuration exception occurred, service '" << svc_name <<"."; + } catch ( std::exception& ex ) { + eout << "Standard exception occurred: "< 0 ) { + LOG_WARN(DeviceManager_impl, eout.str() << " Continuing with normal service registration."); + return; + } + +} + +ossie::SpdSupport::ResourceInfo DeviceManager_impl::buildServiceSpd( const std::string &svc_name) +{ + CF::Properties componentProperties; + std::ostringstream eout; + std::string cname; + ossie::SpdSupport::ResourceInfo spdinfo; + try { + // get service's spd from DeviceManager's DCD file + const std::vector& components = DCDParser.getComponentPlacements(); + LOG_TRACE(DeviceManager_impl, "Getting ComponentPlacements, size is " << components.size()); + for ( std::vector< ossie::ComponentPlacement >::const_iterator comp = components.begin(); + comp != components.end(); comp++) { + + for (unsigned int i = 0; i < comp->instantiations.size(); i++) { + cname = comp->instantiations[i].getID(); + if ( cname == svc_name ) { + LOG_TRACE(DeviceManager_impl, "Getting file name for refid " << comp->getFileRefId()); + const char* spdFile = DCDParser.getFileNameFromRefId(comp->getFileRefId()); + if (spdFile == 0) { + eout << "Service: " << svc_name << " missing fileRefId: " << comp->getFileRefId(); + LOG_WARN(DeviceManager_impl, eout.str()); + throw(CF::InvalidObjectReference(eout.str().c_str())); + } + + // loads in service's spd file + ossie::SpdSupport::ResourceInfo::LoadResource(this->_fileSys, spdFile, spdinfo); + } + } + } + } + catch(...){ + eout << "Loading Services's SPD failed, device:" << svc_name; + LOG_WARN(DeviceManager_impl, eout.str()); + throw(CF::InvalidObjectReference(eout.str().c_str())); + } + + std::string spd_name = spdinfo.getName(); + std::string spd_id = spdinfo.getID(); + LOG_INFO(DeviceManager_impl, "Service: " << svc_name << " SPD loaded: " << spd_name << "' - '" << spd_id ); + + try { + const ComponentInstantiation& instantiation = DCDParser.getComponentInstantiationById(svc_name); + if (instantiation.getUsageName() != NULL) + std::string tmp_name = instantiation.getUsageName(); // this is here to get rid of a warning + } catch (...) { + eout << "ComponentInstantiation is invalid for Service:" << svc_name; + LOG_WARN(DeviceManager_impl, eout.str()); + throw(CF::InvalidObjectReference(eout.str().c_str())); + } + + // override device properties in DCD file + const ComponentInstantiation& instantiation = DCDParser.getComponentInstantiationById(svc_name); + const ossie::ComponentPropertyList& overrideProps = instantiation.getProperties(); + // Check for any overrides from DCD componentproperites + for (unsigned int j = 0; j < overrideProps.size (); j++) { + LOG_DEBUG(DeviceManager_impl, "Service:" << svc_name << " Override Properties - ID: " << overrideProps[j].getID()); + spdinfo.overrideProperty( overrideProps[j] ); + } + return spdinfo; + } diff --git a/redhawk/src/control/sdr/devmgr/DeviceManager_impl.h b/redhawk/src/control/sdr/devmgr/DeviceManager_impl.h index e36b52798..2fc5fa704 100644 --- a/redhawk/src/control/sdr/devmgr/DeviceManager_impl.h +++ b/redhawk/src/control/sdr/devmgr/DeviceManager_impl.h @@ -163,6 +163,8 @@ class DeviceManager_impl: CosNaming::NamingContext_var devMgrContext; CF::FileSystem_var _fileSys; CF::DeviceManager_var myObj; + ossie::DeviceManagerConfiguration DCDParser; + bool checkWriteAccess(std::string &path); struct cacheAndCwdStruct{ @@ -174,6 +176,15 @@ class DeviceManager_impl: ossie::SpdSupport::ResourceInfo buildSpdinfo(std::string spdFile, std::string device_id); + // + // tryResourceStartup - try the following interfaces initializeproperties, initialize, configure + // + void tryResourceStartup( CORBA::Object_ptr registeringService, + const std::string &svc_name ); + + ossie::SpdSupport::ResourceInfo buildServiceSpd(const std::string &svc_name); + + enum DevMgrAdmnType { DEVMGR_REGISTERED, DEVMGR_UNREGISTERED, diff --git a/redhawk/src/testing/sdr/dev/nodes/test_service_startup_node/DeviceManager.dcd.xml b/redhawk/src/testing/sdr/dev/nodes/test_service_startup_node/DeviceManager.dcd.xml new file mode 100644 index 000000000..50c46cc38 --- /dev/null +++ b/redhawk/src/testing/sdr/dev/nodes/test_service_startup_node/DeviceManager.dcd.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + S1_1 + + + + + + S2_1 + + + + + + + + + + + diff --git a/redhawk/src/testing/sdr/dev/services/S2/S2.prf.xml b/redhawk/src/testing/sdr/dev/services/S2/S2.prf.xml new file mode 100644 index 000000000..2cc5b7c52 --- /dev/null +++ b/redhawk/src/testing/sdr/dev/services/S2/S2.prf.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/redhawk/src/testing/sdr/dev/services/S2/S2.scd.xml b/redhawk/src/testing/sdr/dev/services/S2/S2.scd.xml new file mode 100644 index 000000000..6296f0f91 --- /dev/null +++ b/redhawk/src/testing/sdr/dev/services/S2/S2.scd.xml @@ -0,0 +1,18 @@ + + + + 2.2 + + service + + + + + + + + + + + + diff --git a/redhawk/src/testing/sdr/dev/services/S2/S2.spd.xml b/redhawk/src/testing/sdr/dev/services/S2/S2.spd.xml new file mode 100644 index 000000000..a008159f6 --- /dev/null +++ b/redhawk/src/testing/sdr/dev/services/S2/S2.spd.xml @@ -0,0 +1,25 @@ + + + + + + null + + + + + + + + + The implementation contains descriptive information about the template for a software component. + + + python/S2.py + + + + + + + diff --git a/redhawk/src/testing/sdr/dev/services/S2/python/S2.py b/redhawk/src/testing/sdr/dev/services/S2/python/S2.py new file mode 100755 index 000000000..06dcf4f45 --- /dev/null +++ b/redhawk/src/testing/sdr/dev/services/S2/python/S2.py @@ -0,0 +1,153 @@ +#!/usr/bin/env python +# +# AUTO-GENERATED +# +# Source: S2.spd.xml + +import sys, signal, copy, os +import logging + +from ossie.cf import CF, CF__POA #@UnusedImport +from ossie.service import start_service +from omniORB import any, CORBA, URI, PortableServer + +from ossie.cf import CF +from ossie.cf import CF__POA +from ossie import properties; + + +class S2(CF__POA.PropertyEmitter): + + def __init__(self, name="S2", execparams={}): + self.name = name + self._log = logging.getLogger(self.name) + self._props = properties.PropertyStorage(self, (), execparams) + self._props._addProperty( S2.p1 ) + self._props._addProperty( S2.p2) + self._props.initialize() + + def terminateService(self): + pass + + def configure(self, configProperties): + + # TODO + pass + + def query(self, configProperties): + if configProperties == []: + self._log.trace("query all properties") + try: + rv = [] + for propid in self._props.keys(): + if self._props.has_id(propid) and self._props.isQueryable(propid): + try: + value = self._props.query(propid) + except Exception, e: + self._log.error('Failed to query %s: %s', propid, e) + value = any.to_any(None) + prp = self._props.getPropDef(propid) + if type(prp) == properties.struct_property: + newvalval = [] + for v in value.value(): + if prp.fields[v.id][1].optional == True: + if isinstance(v.value.value(), list): + if v.value.value() != []: + newvalval.append(v) + else: + if v.value.value() != None: + newvalval.append(v) + else: + newvalval.append(v) + value = CORBA.Any(value.typecode(), newvalval) + + rv.append(CF.DataType(propid, value)) + except: + raise + + # otherwise get only the requested ones + else: + self._log.trace("query %s properties", len(configProperties)) + try: + unknownProperties = [] + for prop in configProperties: + if self._props.has_id(prop.id) and self._props.isQueryable(prop.id): + try: + prop.value = self._props.query(prop.id) + except Exception, e: + self._log.error('Failed to query %s: %s', prop.id, e) + prp = self._props.getPropDef(prop.id) + if type(prp) == properties.struct_property: + newvalval = [] + for v in prop.value.value(): + if prp.fields[v.id][1].optional == True: + if isinstance(v.value.value(), list): + if v.value.value() != []: + newvalval.append(v) + else: + if v.value.value() != None: + newvalval.append(v) + else: + newvalval.append(v) + prop.value = CORBA.Any(prop.value.typecode(), newvalval) + else: + self._log.warning("property %s cannot be queried. valid Id: %s", + prop.id, self._props.has_id(prop.id)) + unknownProperties.append(prop) + except: + raise + + if len(unknownProperties) > 0: + self._log.warning("query called with invalid properties %s", unknownProperties) + raise CF.UnknownProperties(unknownProperties) + + rv = configProperties + self._log.trace("query -> %s properties", len(rv)) + return rv + + def initializeProperties(self, ctorProps): + notSet = [] + for prop in ctorProps: + try: + if self._props.has_id(prop.id) and self._props.isProperty(prop.id): + try: + # run configure on property.. disable callback feature + self._props.construct(prop.id, prop.value) + except ValueError, e: + self._log.warning("Invalid value provided to construct for property %s %s", prop.id, e) + notSet.append(prop) + else: + self._log.warning("Tried to construct non-existent, readonly, or property with action not equal to external %s", prop.id) + notSet.append(prop) + except Exception, e: + self._log.exception("Unexpected exception.") + notSet.append(prop) + + + def registerPropertyListener(self, obj, prop_ids, interval): + # TODO + pass + + def unregisterPropertyListener(self, id): + # TODO + pass + + p1 = properties.simple_property(id_="p1", + name="p1", + type_="string", + mode="readwrite", + action="external", + kinds=("property",), + description=""" """) + + + p2 = properties.simple_property(id_="p2", + name="p2", + type_="long", + mode="readwrite", + action="external", + kinds=("property",)) + + +if __name__ == '__main__': + start_service(S2, thread_policy=PortableServer.SINGLE_THREAD_MODEL) diff --git a/redhawk/src/testing/tests/test_01_DeviceManager.py b/redhawk/src/testing/tests/test_01_DeviceManager.py index 11ecaab52..11a30fe7c 100644 --- a/redhawk/src/testing/tests/test_01_DeviceManager.py +++ b/redhawk/src/testing/tests/test_01_DeviceManager.py @@ -22,6 +22,7 @@ from _unitTestHelpers import scatest from omniORB import URI, any, CORBA from ossie.cf import CF +from ossie import properties import commands import CosNaming import tempfile @@ -1286,3 +1287,24 @@ def test_ValgrindOption(self): if ub_patch: os.unlink(altpath+'.bin') + + def test_Service_Startup(self): + devmgr_nb, devMgr = self.launchDeviceManager("/nodes/test_service_startup_node/DeviceManager.dcd.xml") + from ossie.utils import redhawk + d=redhawk.attach(self._domainManager._get_name()) + + svc=None + for s in d.services: + if s._id == 'S2_1': + svc = s + self.assertNotEqual(svc, None) + + # get p1 from service + res=s.query([CF.DataType(id='p1', value=any.to_any(None))]) + p1=properties.props_to_dict(res) + self.assertEqual(p1['p1'],'p1 set by DCD file') + + # get p2 from service + res=s.query([CF.DataType(id='p2', value=any.to_any(None))]) + p1=properties.props_to_dict(res) + self.assertEqual(p1['p2'],123456) From 65e7a626ad3c10e5a47de2966fc0de3a5a6335b9 Mon Sep 17 00:00:00 2001 From: 8530 <8530@vm-131.vsi-corp.com> Date: Mon, 12 Dec 2016 15:18:40 -0500 Subject: [PATCH 0614/1644] mods for prior merge --- .../control/sdr/devmgr/DeviceManager_impl.cpp | 241 +++++++++--------- 1 file changed, 122 insertions(+), 119 deletions(-) diff --git a/redhawk/src/control/sdr/devmgr/DeviceManager_impl.cpp b/redhawk/src/control/sdr/devmgr/DeviceManager_impl.cpp index 69d81376a..ec400f810 100644 --- a/redhawk/src/control/sdr/devmgr/DeviceManager_impl.cpp +++ b/redhawk/src/control/sdr/devmgr/DeviceManager_impl.cpp @@ -3022,123 +3022,125 @@ bool DeviceManager_impl::allChildrenExited () void DeviceManager_impl::tryResourceStartup( CORBA::Object_ptr registeringService, const std::string &svc_name ) { - ossie::SpdSupport::ResourceInfo spdinfo; try { - spdinfo = buildServiceSpd(svc_name); - } - catch(...){ - LOG_WARN(DeviceManager_impl, "Error processing SoftwareProfile for Service: " << svc_name << ", continue with normal registration."); - return; - } - // - // Try standard Redhawk resource startup... - // initializeProperties, initialized, configure - // - CF::LifeCycle_var svc_lc = ossie::corba::_narrowSafe (registeringService); - CF::PropertySet_var svc_ps = ossie::corba::_narrowSafe (registeringService); - CF::PropertyEmitter_var svc_em = ossie::corba::_narrowSafe (registeringService); - std::ostringstream eout; - std::string emsg; - try { - LOG_DEBUG(DeviceManager_impl, "Initialize properties for spd/service: " << spdinfo.getName() << "/" << svc_name); - const CF::Properties cprops = spdinfo.getNonNilConstructProperties(); - for (unsigned int j = 0; j < cprops.length (); j++) { - LOG_DEBUG(DeviceManager_impl, "initializeProperties prop id " << cprops[j].id ); - } + ossie::SpdSupport::ResourceInfo spdinfo = buildServiceSpd(svc_name); - if ( !CORBA::is_nil(svc_em)) { - // Try to set the initial values for the resource - LOG_DEBUG(DeviceManager_impl, "Calling Service: " << svc_name << " initializeProperties props: " << cprops.length()); - svc_em->initializeProperties(cprops); - } - else { - if ( cprops.length() > 0 ) { - LOG_WARN(DeviceManager_impl,"Service: " << svc_name << " has configuration properties but does not implement PropertEmitter interface."); + // + // Try standard Redhawk resource startup... + // initializeProperties, initialized, configure + // + CF::LifeCycle_var svc_lc = ossie::corba::_narrowSafe (registeringService); + CF::PropertySet_var svc_ps = ossie::corba::_narrowSafe (registeringService); + CF::PropertyEmitter_var svc_em = ossie::corba::_narrowSafe (registeringService); + std::ostringstream eout; + std::string emsg; + try { + LOG_DEBUG(DeviceManager_impl, "Initialize properties for spd/service: " << spdinfo.getName() << "/" << svc_name); + const CF::Properties cprops = spdinfo.getNonNilConstructProperties(); + for (unsigned int j = 0; j < cprops.length (); j++) { + LOG_DEBUG(DeviceManager_impl, "initializeProperties prop id " << cprops[j].id ); + } + + if ( !CORBA::is_nil(svc_em)) { + // Try to set the initial values for the resource + LOG_DEBUG(DeviceManager_impl, "Calling Service: " << svc_name << " initializeProperties props: " << cprops.length()); + svc_em->initializeProperties(cprops); + } + else { + if ( cprops.length() > 0 ) { + LOG_WARN(DeviceManager_impl,"Service: " << svc_name << " has configuration properties but does not implement PropertEmitter interface."); + } } - } - }catch(CF::PropertySet::InvalidConfiguration& e) { + }catch(CF::PropertySet::InvalidConfiguration& e) { eout << "Invalid Configuration exception occurred, service '" << svc_name <<"."; - } catch(CF::PropertySet::PartialConfiguration& e) { + } catch(CF::PropertySet::PartialConfiguration& e) { eout << "Partial configuration exception for Service '" << svc_name << "."; - } catch ( std::exception& ex ) { - eout << "Standard exception occurred: "< 0 ) { - LOG_WARN(DeviceManager_impl, eout.str() << " Continuing with normal service registration."); - return; - } - - LOG_DEBUG(DeviceManager_impl, "Initializing Service " << svc_name << " on DeviceManager: " << _label); - eout.clear(); eout.str(""); - try { - if ( !CORBA::is_nil(svc_lc)) { - LOG_DEBUG(DeviceManager_impl, "Calling Service " << svc_name << " initialize method."); - svc_lc->initialize(); + } catch ( std::exception& ex ) { + eout << "Standard exception occurred: "< 0 ) { + LOG_WARN(DeviceManager_impl, eout.str() << " Continuing with normal service registration."); + return; } - } catch (CF::LifeCycle::InitializeError& ex) { - eout << "Service: "<< svc_name << " threw a CF::LifeCycle::InitializeError exception."; - } catch ( std::exception& ex ) { - eout << "The following standard exception occurred: "<initialize(); + } + else { + LOG_DEBUG(DeviceManager_impl, "Service does not implement LifeCycle interface."); + } - // handle error conditions - emsg = eout.str(); - if ( emsg.size() > 0 ) { - LOG_WARN(DeviceManager_impl, eout.str() << " Continuing with normal service registration."); - return; - } + } catch (CF::LifeCycle::InitializeError& ex) { + eout << "Service: "<< svc_name << " threw a CF::LifeCycle::InitializeError exception."; + } catch ( std::exception& ex ) { + eout << "The following standard exception occurred: "<configure (cprops); + // handle error conditions + emsg = eout.str(); + if ( emsg.size() > 0 ) { + LOG_WARN(DeviceManager_impl, eout.str() << " Continuing with normal service registration."); + return; + } + + eout.clear(); eout.str(""); + //configure properties + try { + LOG_DEBUG(DeviceManager_impl, "Configuring service " << svc_name << " on Device Manager " << _label); + const CF::Properties cprops = spdinfo.getNonNilConfigureProperties(); + LOG_TRACE(DeviceManager_impl, "Listing configuration properties"); + for (unsigned int j=0; jconfigure (cprops); + } + else { + eout << "Service has configuration properties but does not implement PropertSet interface. Continuing with normal service registration."; + } } + + } catch (CF::PropertySet::PartialConfiguration& ex) { + eout << "Partial configuration exception for Service '" << svc_name << "."; + } catch (CF::PropertySet::InvalidConfiguration& ex) { + eout << "Invalid Configuration exception occurred, service '" << svc_name <<"."; + } catch ( std::exception& ex ) { + eout << "Standard exception occurred: "< 0 ) { + LOG_WARN(DeviceManager_impl, eout.str() << " Continuing with normal service registration."); + return; + } - // handle error conditions - emsg = eout.str(); - if ( emsg.size() > 0 ) { - LOG_WARN(DeviceManager_impl, eout.str() << " Continuing with normal service registration."); + } + catch(...){ + LOG_WARN(DeviceManager_impl, "Error processing SoftwareProfile for Service: " << svc_name << ", continue with normal registration."); return; } + } ossie::SpdSupport::ResourceInfo DeviceManager_impl::buildServiceSpd( const std::string &svc_name) @@ -3146,31 +3148,32 @@ ossie::SpdSupport::ResourceInfo DeviceManager_impl::buildServiceSpd( const std:: CF::Properties componentProperties; std::ostringstream eout; std::string cname; - ossie::SpdSupport::ResourceInfo spdinfo; - try { - // get service's spd from DeviceManager's DCD file - const std::vector& components = DCDParser.getComponentPlacements(); - LOG_TRACE(DeviceManager_impl, "Getting ComponentPlacements, size is " << components.size()); - for ( std::vector< ossie::ComponentPlacement >::const_iterator comp = components.begin(); - comp != components.end(); comp++) { - - for (unsigned int i = 0; i < comp->instantiations.size(); i++) { - cname = comp->instantiations[i].getID(); - if ( cname == svc_name ) { - LOG_TRACE(DeviceManager_impl, "Getting file name for refid " << comp->getFileRefId()); - const char* spdFile = DCDParser.getFileNameFromRefId(comp->getFileRefId()); - if (spdFile == 0) { - eout << "Service: " << svc_name << " missing fileRefId: " << comp->getFileRefId(); - LOG_WARN(DeviceManager_impl, eout.str()); - throw(CF::InvalidObjectReference(eout.str().c_str())); - } - - // loads in service's spd file - ossie::SpdSupport::ResourceInfo::LoadResource(this->_fileSys, spdFile, spdinfo); + std::string spdFile; + // get service's spd from DeviceManager's DCD file + const std::vector& components = DCDParser.getComponentPlacements(); + LOG_TRACE(DeviceManager_impl, "Getting ComponentPlacements, size is " << components.size()); + for ( std::vector< ossie::DevicePlacement >::const_iterator comp = components.begin(); + comp != components.end(); comp++) { + + for (unsigned int i = 0; i < comp->instantiations.size(); i++) { + cname = comp->instantiations[i].getID(); + if ( cname == svc_name ) { + LOG_TRACE(DeviceManager_impl, "Getting file name for refid " << comp->getFileRefId()); + const char* svc_spdFile = DCDParser.getFileNameFromRefId(comp->getFileRefId().c_str()); + if (svc_spdFile == 0) { + eout << "Service: " << svc_name << " missing fileRefId: " << comp->getFileRefId(); + LOG_WARN(DeviceManager_impl, eout.str()); + throw(CF::InvalidObjectReference(eout.str().c_str())); } + spdFile=svc_spdFile; } } } + + ossie::SpdSupport::ResourceInfo spdinfo(spdFile); + try { + spdinfo.load(_fileSys); + } catch(...){ eout << "Loading Services's SPD failed, device:" << svc_name; LOG_WARN(DeviceManager_impl, eout.str()); @@ -3183,7 +3186,7 @@ ossie::SpdSupport::ResourceInfo DeviceManager_impl::buildServiceSpd( const std:: try { const ComponentInstantiation& instantiation = DCDParser.getComponentInstantiationById(svc_name); - if (instantiation.getUsageName() != NULL) + if (!instantiation.getUsageName().empty()) std::string tmp_name = instantiation.getUsageName(); // this is here to get rid of a warning } catch (...) { eout << "ComponentInstantiation is invalid for Service:" << svc_name; From cf8de1d19685df7722ce2cedb0e61db2647df89f Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 12 Dec 2016 16:28:01 -0500 Subject: [PATCH 0615/1644] Recreate nested typedefs used by some basic components --- bulkioInterfaces/libsrc/cpp/bulkio_datatransfer.h | 4 +++- bulkioInterfaces/libsrc/cpp/bulkio_in_stream.h | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_datatransfer.h b/bulkioInterfaces/libsrc/cpp/bulkio_datatransfer.h index 0e1ad3e02..7a00ac527 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_datatransfer.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_datatransfer.h @@ -45,8 +45,10 @@ namespace bulkio { // PrecisionUTCTime and StreamSRI object will perform a "deep" copy. // // - template + template struct DataTransfer { + typedef BufferType DataBufferType; + // // Construct a DataTransfer object to be returned from an InPort's getPacket method // diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.h b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.h index 3b67eb335..c667690eb 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.h @@ -53,6 +53,7 @@ namespace bulkio { template class InputStream : public StreamBase { public: + typedef typename NativeTraits::NativeType NativeType; typedef typename BlockTraits::DataBlockType DataBlockType; DataBlockType read(); From 6ff70097bf22a9520ee2aa0db61959136b83c813 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Tue, 13 Dec 2016 10:28:54 -0500 Subject: [PATCH 0616/1644] Attaching to a missing named Domain using the Python package yields a more useful message --- .../src/base/framework/python/ossie/utils/redhawk/core.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/redhawk/core.py b/redhawk/src/base/framework/python/ossie/utils/redhawk/core.py index 700794838..ae3b07d2d 100644 --- a/redhawk/src/base/framework/python/ossie/utils/redhawk/core.py +++ b/redhawk/src/base/framework/python/ossie/utils/redhawk/core.py @@ -1412,7 +1412,11 @@ def __init__(self, name="DomainName1", location=None, connectDomainEvents=True): raise StandardError, "Did not find domain "+name self.ref = obj._narrow(_CF.DomainManager) - self.fileManager = self.ref._get_fileMgr() + try: + self.fileManager = self.ref._get_fileMgr() + except: + raise RuntimeError('Domain Manager '+self.name+' is not available') + self.id = self.ref._get_identifier() try: spd, scd, prf = _readProfile("/mgr/DomainManager.spd.xml", self.fileManager) From 2e9235b4b52468ac0328e2a843119fa249ce182e Mon Sep 17 00:00:00 2001 From: Max Robert Date: Tue, 13 Dec 2016 10:33:57 -0500 Subject: [PATCH 0617/1644] Refs CF-1642. Change from RuntimeError to StandardError --- redhawk/src/base/framework/python/ossie/utils/redhawk/core.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/redhawk/core.py b/redhawk/src/base/framework/python/ossie/utils/redhawk/core.py index ae3b07d2d..31baa4fda 100644 --- a/redhawk/src/base/framework/python/ossie/utils/redhawk/core.py +++ b/redhawk/src/base/framework/python/ossie/utils/redhawk/core.py @@ -1415,7 +1415,7 @@ def __init__(self, name="DomainName1", location=None, connectDomainEvents=True): try: self.fileManager = self.ref._get_fileMgr() except: - raise RuntimeError('Domain Manager '+self.name+' is not available') + raise StandardError('Domain Manager '+self.name+' is not available') self.id = self.ref._get_identifier() try: From abb18c13b1b4fe16e1373c4e9a01d380c2b6dc2b Mon Sep 17 00:00:00 2001 From: Max Robert Date: Wed, 14 Dec 2016 13:48:07 -0500 Subject: [PATCH 0618/1644] Refs CF-1596. Changed persistence property to be queryable --- redhawk/src/control/framework/nodebooter.cpp | 16 ++++++++++++++++ .../src/control/sdr/dommgr/DomainManager.prf.xml | 4 ++-- .../control/sdr/dommgr/DomainManager_impl.cpp | 12 +++++++++++- .../src/control/sdr/dommgr/DomainManager_impl.h | 3 ++- redhawk/src/control/sdr/dommgr/main.cpp | 3 ++- 5 files changed, 33 insertions(+), 5 deletions(-) diff --git a/redhawk/src/control/framework/nodebooter.cpp b/redhawk/src/control/framework/nodebooter.cpp index 8446aae75..337bd0cd2 100644 --- a/redhawk/src/control/framework/nodebooter.cpp +++ b/redhawk/src/control/framework/nodebooter.cpp @@ -161,6 +161,22 @@ void loadPRFExecParams (const std::string& prfFile, ExecParams& execParams) } execParams[simpleProp->getID()] = simpleProp->getValue(); } + + const std::vector& propertyProps = prf.getConstructProperties(); + + for ( prop = propertyProps.begin(); prop != propertyProps.end(); ++prop) { + const ossie::SimpleProperty* simpleProp; + simpleProp = dynamic_cast(*prop); + if (!simpleProp) { + LOG_WARN(nodebooter, "Only execparams of type \"simple\" supported"); + continue; + } else if (!simpleProp->getValue()) { + continue; + } + if (not simpleProp->isCommandLine()) + continue; + execParams[simpleProp->getID()] = simpleProp->getValue(); + } } diff --git a/redhawk/src/control/sdr/dommgr/DomainManager.prf.xml b/redhawk/src/control/sdr/dommgr/DomainManager.prf.xml index 748e58d98..b74f19aba 100644 --- a/redhawk/src/control/sdr/dommgr/DomainManager.prf.xml +++ b/redhawk/src/control/sdr/dommgr/DomainManager.prf.xml @@ -45,12 +45,12 @@ with this program. If not, see http://www.gnu.org/licenses/. - + Enable CORBA persistence for the domain manager. true - + diff --git a/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp b/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp index e07e0f4a5..bd87a6fce 100644 --- a/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp @@ -75,7 +75,7 @@ PREPARE_CF_LOGGING(DomainManager_impl) // If _overrideDomainName == NULL read the domain name from the DMD file DomainManager_impl::DomainManager_impl (const char* dmdFile, const char* _rootpath, const char* domainName, const char *db_uri, - const char* _logconfig_uri, bool useLogCfgResolver, bool bindToDomain ) : + const char* _logconfig_uri, bool useLogCfgResolver, bool bindToDomain, bool _persistence) : _eventChannelMgr(NULL), _domainName(domainName), _domainManagerProfile(dmdFile), @@ -101,6 +101,16 @@ DomainManager_impl::DomainManager_impl (const char* dmdFile, const char* _rootpa addProperty(redhawk_version, VERSION, "REDHAWK_VERSION", "redhawk_version", "readonly", "", "external", "configure"); + + addProperty(PERSISTENCE, + "PERSISTENCE", + "", + "readonly", + "", + "external", + "property"); + + PERSISTENCE = _persistence; addProperty(client_wait_times, client_wait_times_struct(), diff --git a/redhawk/src/control/sdr/dommgr/DomainManager_impl.h b/redhawk/src/control/sdr/dommgr/DomainManager_impl.h index 0b0919ac0..a84ffcc34 100644 --- a/redhawk/src/control/sdr/dommgr/DomainManager_impl.h +++ b/redhawk/src/control/sdr/dommgr/DomainManager_impl.h @@ -60,7 +60,7 @@ class DomainManager_impl: public virtual POA_CF::DomainManager, public PropertyS /////////////////////////// public: - DomainManager_impl (const char*, const char*, const char*, const char *, const char*, bool, bool ); + DomainManager_impl (const char*, const char*, const char*, const char *, const char*, bool, bool, bool); ~DomainManager_impl (); friend class ODM_Channel_Supplier_i; @@ -330,6 +330,7 @@ class DomainManager_impl: public virtual POA_CF::DomainManager, public PropertyS DOM_Publisher_ptr _odm_publisher; redhawk::events::DomainEventReader _idm_reader; + bool PERSISTENCE; /////////////////////// // Private Domain State diff --git a/redhawk/src/control/sdr/dommgr/main.cpp b/redhawk/src/control/sdr/dommgr/main.cpp index 5b101ca1f..150dca1f7 100644 --- a/redhawk/src/control/sdr/dommgr/main.cpp +++ b/redhawk/src/control/sdr/dommgr/main.cpp @@ -396,7 +396,8 @@ int old_main(int argc, char* argv[]) (db_uri.empty()) ? NULL : db_uri.c_str(), (logfile_uri.empty()) ? NULL : logfile_uri.c_str(), useLogCfgResolver, - bindToDomain + bindToDomain, + enablePersistence ); // set logging level for the DomainManager's logger From 2d9aafdc2af68b0b2a33894883423ec1bd695077 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Thu, 15 Dec 2016 14:30:15 -0500 Subject: [PATCH 0619/1644] Refs CF-1596. Device Manager reboots when it detects clean re-launch of the Domain Manager after a catastrophic failure --- redhawk/src/control/framework/nodebooter.cpp | 2 + .../control/sdr/devmgr/DeviceManager.prf.xml | 11 +- .../control/sdr/devmgr/DeviceManager_impl.cpp | 153 +++++++++++++++++- .../control/sdr/devmgr/DeviceManager_impl.h | 113 ++++++++++++- redhawk/src/control/sdr/devmgr/main.cpp | 13 +- 5 files changed, 280 insertions(+), 12 deletions(-) diff --git a/redhawk/src/control/framework/nodebooter.cpp b/redhawk/src/control/framework/nodebooter.cpp index 337bd0cd2..aa20dd2a7 100644 --- a/redhawk/src/control/framework/nodebooter.cpp +++ b/redhawk/src/control/framework/nodebooter.cpp @@ -240,6 +240,8 @@ static pid_t launchSPD ( LOG_TRACE(nodebooter, "Loading implementation-specific PRF: " << prfFile); loadPRFExecParams(prfFile, execParams); } + + execParams["SPD"] = spdFile; // Update the execparams with the user-supplied overrides. for (ExecParams::const_iterator param = overrideExecParams.begin(); param != overrideExecParams.end(); ++param) { diff --git a/redhawk/src/control/sdr/devmgr/DeviceManager.prf.xml b/redhawk/src/control/sdr/devmgr/DeviceManager.prf.xml index 310158c84..ac348dfe1 100644 --- a/redhawk/src/control/sdr/devmgr/DeviceManager.prf.xml +++ b/redhawk/src/control/sdr/devmgr/DeviceManager.prf.xml @@ -51,7 +51,7 @@ with this program. If not, see http://www.gnu.org/licenses/. The amount of time (in seconds) that the Device Manager will wait for a Device to exit before issuing a kill signal 0.5 - + @@ -72,6 +72,13 @@ with this program. If not, see http://www.gnu.org/licenses/. Name of the host where this device manager is running - + + + + + How often the Device Manager should check to see if the Domain contains a reference to this Device Manager (in seconds). This applies to persistence only + + 10 + diff --git a/redhawk/src/control/sdr/devmgr/DeviceManager_impl.cpp b/redhawk/src/control/sdr/devmgr/DeviceManager_impl.cpp index ed6a7784b..a7864b15e 100644 --- a/redhawk/src/control/sdr/devmgr/DeviceManager_impl.cpp +++ b/redhawk/src/control/sdr/devmgr/DeviceManager_impl.cpp @@ -1235,7 +1235,8 @@ DeviceManager_impl::DeviceManager_impl( struct utsname uname, bool useLogCfgResolver, const char *cpuBlackList, - bool* internalShutdown) : + bool* internalShutdown, + std::string& spdFile) : _registeredDevices() { // These should probably be execparams at some point @@ -1246,6 +1247,8 @@ DeviceManager_impl::DeviceManager_impl( _internalShutdown = internalShutdown; _useLogConfigUriResolver = useLogCfgResolver; + _spdFile = spdFile; + // Initialize properties logging_config_prop = (StringProperty*)addProperty(logging_config_uri, "LOGGING_CONFIG_URI", @@ -1264,15 +1267,25 @@ DeviceManager_impl::DeviceManager_impl( "readonly", "", "external", - "configure"); + "property"); + + addProperty(DOMAIN_REFRESH, + 10.0, + "DOMAIN_REFRESH", + "DOMAIN_REFRESH", + "readwrite", + "", + "external", + "property"); addProperty(DEVICE_FORCE_QUIT_TIME, + 0.5, "DEVICE_FORCE_QUIT_TIME", "DEVICE_FORCE_QUIT_TIME", "readwrite", "", "external", - "configure"); + "property"); addProperty(CLIENT_WAIT_TIME, 10000, @@ -1290,16 +1303,89 @@ DeviceManager_impl::DeviceManager_impl( catch(...){ std::cerr << " Error processing cpu blacklist for this manager." << std::endl; } - - // this is hard-coded here because 1.10 and earlier Device Managers do not - // have this property in their prf - this->DEVICE_FORCE_QUIT_TIME = 0.5; char _hostname[1024]; gethostname(_hostname, 1024); std::string hostname(_hostname); HOSTNAME = hostname; this->_dmnMgr = CF::DomainManager::_nil(); + domain_persistence = false; + this->DOMAIN_REFRESH = 0; +} + +int DeviceManager_impl::checkDomain() +{ + CF::DomainManager::DeviceManagerSequence_var devMgrs; + try { + devMgrs = this->_dmnMgr->deviceManagers(); + } catch ( ... ) { + if ((this->startDomainWarn.tv_sec == 0) and (this->startDomainWarn.tv_usec == 0)) { + LOG_WARN(DeviceManager_impl, "Unable to contact the Domain Manager"); + gettimeofday(&startDomainWarn, NULL); + return DomainCheckThread::NOOP; + } + struct timeval now; + gettimeofday(&now, NULL); + float minutes = 15; + if ((now.tv_sec - startDomainWarn.tv_sec) >= (minutes * 60)) { + LOG_WARN(DeviceManager_impl, "Unable to contact the Domain Manager"); + gettimeofday(&startDomainWarn, NULL); + return DomainCheckThread::NOOP; + } + return DomainCheckThread::NOOP; + } + + for (unsigned int i=0; ilength(); i++) { + if (devMgrs[i]->_is_equivalent(this->_this())) { + return DomainCheckThread::NOOP; + } + } + + this->reset(); + + return DomainCheckThread::NOOP; +} + +void DeviceManager_impl::domainRefreshChanged(float oldValue, float newValue) +{ + if ((not this->domain_persistence) and (newValue != 0)) { + this->DOMAIN_REFRESH = 0; + std::string message("DOMAIN_REFRESH can only be set when the Domain Manager persistence is enabled"); + redhawk::PropertyMap query_props; + query_props["DOMAIN_REFRESH"] = redhawk::Value(newValue); + throw(CF::PropertySet::InvalidConfiguration(message.c_str(), query_props)); + } + this->DOMAIN_REFRESH = newValue; + this->DomainWatchThread->updateDelay(this->DOMAIN_REFRESH); +} + +void DeviceManager_impl::reset() +{ + if (_adminState == DEVMGR_SHUTTING_DOWN) + return; + + // release all devices and services + clean_registeredServices(); + clean_externalServices(); + clean_registeredDevices(); + + try { + deleteFileSystems(); + } catch ( ... ) { + } + + // try to get the reference + bool done = false; + while (not done) { + try { + getDomainManagerReference (_domainName.c_str()); + usleep(500); + done = true; + } catch ( ... ) { + } + } + // call postContructor + postConstructor(_domainName.c_str()); } /* @@ -1639,6 +1725,56 @@ void DeviceManager_impl::postConstructor ( instanceprops); } } + + File_stream devMgrSpdStream(_fileSys, _spdFile.c_str()); + ossie::SoftPkg parsedSpd; + ossie::Properties parsedPrf; + parsedSpd.load(devMgrSpdStream, _spdFile); + + if (parsedSpd.getPRFFile()) { + File_stream prf(_fileSys, parsedSpd.getPRFFile()); + parsedPrf.load(prf); + } + + redhawk::PropertyMap query_props; + query_props["PERSISTENCE"] = redhawk::Value(); + this->_dmnMgr->query(query_props); + domain_persistence = query_props["PERSISTENCE"].toBoolean(); + + redhawk::PropertyMap set_props; + std::vector props = parsedPrf.getConstructProperties(); + for (unsigned int i=0; iisCommandLine()) + continue; + if (props[i]->getMode() == ossie::Property::MODE_READONLY) + continue; + std::string prop_id(props[i]->getID()); + if ((prop_id == "DOMAIN_REFRESH") and (not this->domain_persistence)) + continue; + set_props[props[i]->getID()] = convertPropertyToDataType(props[i]).value; + } + + props = parsedPrf.getConfigureProperties(); + for (unsigned int i=0; igetMode() == ossie::Property::MODE_READONLY) + continue; + set_props[props[i]->getID()] = convertPropertyToDataType(props[i]).value; + } + + if (set_props.size() != 0) { + this->configure(set_props); + } + + if (domain_persistence) { + DomainWatchThread = new DomainCheckThread(this); + DomainWatchThread->updateDelay(this->DOMAIN_REFRESH); + this->startDomainWarn.tv_sec = 0; + this->startDomainWarn.tv_usec = 0; + DomainWatchThread->start(); + } else { + DomainWatchThread = NULL; + } + addPropertyListener(DOMAIN_REFRESH, this, &DeviceManager_impl::domainRefreshChanged); } const SPD::Implementation* DeviceManager_impl::locateMatchingDeviceImpl(const SoftPkg& devSpd, const SPD::Implementation* deployOnImpl) @@ -2215,6 +2351,9 @@ void DeviceManager_impl::shutdown () throw (CORBA::SystemException) { + if (DomainWatchThread) + this->DomainWatchThread->stop(); + *_internalShutdown = true; LOG_DEBUG(DeviceManager_impl, "SHUTDOWN START........." << *_internalShutdown) diff --git a/redhawk/src/control/sdr/devmgr/DeviceManager_impl.h b/redhawk/src/control/sdr/devmgr/DeviceManager_impl.h index c89110bd6..ca66cb718 100644 --- a/redhawk/src/control/sdr/devmgr/DeviceManager_impl.h +++ b/redhawk/src/control/sdr/devmgr/DeviceManager_impl.h @@ -43,15 +43,19 @@ #include +class DomainCheckThread; + class DeviceManager_impl: public virtual POA_CF::DeviceManager, public PropertySet_impl, public PortSet_impl { ENABLE_LOGGING + + friend DomainCheckThread; public: - DeviceManager_impl (const char*, const char*, const char*, const char*, struct utsname uname, bool, const char *, bool *); + DeviceManager_impl (const char*, const char*, const char*, const char*, struct utsname uname, bool, const char *, bool *, std::string&); ~DeviceManager_impl (); char* deviceConfigurationProfile () @@ -78,6 +82,9 @@ class DeviceManager_impl: // Run this after the constructor void postConstructor( const char*) throw (CORBA::SystemException, std::runtime_error); + // Re-start all devices and services, and re-associate with the Domain + void reset(); + void registerDevice (CF::Device_ptr registeringDevice) throw (CF::InvalidObjectReference, CORBA::SystemException); @@ -129,6 +136,12 @@ class DeviceManager_impl: CORBA::Object_ptr service; pid_t pid; }; + + DomainCheckThread *DomainWatchThread; + void domainRefreshChanged(float oldValue, float newValue); + int checkDomain(); + struct timeval startDomainWarn; + bool domain_persistence; typedef std::vector DeviceList; typedef std::vector ServiceList; @@ -149,12 +162,14 @@ class DeviceManager_impl: std::string logging_uri; float DEVICE_FORCE_QUIT_TIME; CORBA::ULong CLIENT_WAIT_TIME; + float DOMAIN_REFRESH; // read only attributes struct utsname _uname; std::string _identifier; std::string _label; std::string _deviceConfigurationProfile; + std::string _spdFile; std::string _fsroot; std::string _cacheroot; redhawk::affinity::CpuList cpu_blacklist; @@ -390,5 +405,101 @@ class DeviceManager_impl: }; +class DomainCheckThread { + +public: + + enum { + NOOP = 0, + FINISH = -1, + }; + +private: + boost::thread* _thread; + volatile bool _running; + DeviceManager_impl * _target; + struct timespec _delay; + +public: + boost::thread*& _mythread; + +public: + DomainCheckThread( DeviceManager_impl *target, float delay=0.5) : + _thread(0), + _running(false), + _target(target), + _mythread(_thread) + { + updateDelay(delay); + } + + void start() { + if (!_thread) { + _running = true; + _thread = new boost::thread(&DomainCheckThread::run, this); + } + } + + void run() + { + while (_running) { + int state = _target->checkDomain(); + if (state == FINISH) { + return; + } else if (state == NOOP) { + nanosleep(&_delay, NULL); + } + else { + boost::this_thread::yield(); + } + } + } + + bool release(unsigned long secs=0, unsigned long usecs=0) { + + _running = false; + if (_thread) { + if ((secs == 0) && (usecs == 0)){ + _thread->join(); + } else { + boost::system_time waitime = boost::get_system_time() + boost::posix_time::seconds(secs) + boost::posix_time::microseconds(usecs); + if (!_thread->timed_join(waitime)) { + return false; + } + } + delete _thread; + _thread = 0; + } + + return true; + } + + void stop() { + _running = false; + if ( _thread ) _thread->interrupt(); + } + + ~DomainCheckThread() + { + if (_thread) { + release(0); + _thread = 0; + } + } + + void updateDelay(float delay) + { + _delay.tv_sec = (time_t)delay; + _delay.tv_nsec = (delay-_delay.tv_sec)*1e9; + } + + bool threadRunning() + { + return _running; + } + +}; + + #endif /* __DEVICEMANAGER_IMPL__ */ diff --git a/redhawk/src/control/sdr/devmgr/main.cpp b/redhawk/src/control/sdr/devmgr/main.cpp index 1175d833f..c54e764be 100644 --- a/redhawk/src/control/sdr/devmgr/main.cpp +++ b/redhawk/src/control/sdr/devmgr/main.cpp @@ -187,6 +187,7 @@ int main(int argc, char* argv[]) // parse command line options std::string dcdFile; std::string sdrRoot; + std::string spdFile; std::string sdrCache; std::string logfile_uri; std::string domainName; @@ -217,12 +218,17 @@ int main(int argc, char* argv[]) dcdFile = argv[ii]; } else if (param == "SDRROOT") { sdrRoot = argv[ii]; + } else if (param == "SPD") { + spdFile = argv[ii]; } else if (param == "SDRCACHE") { sdrCache = argv[ii]; + execparams[param] = argv[ii]; } else if (param == "DOMAIN_NAME") { domainName = argv[ii]; + execparams[param] = argv[ii]; } else if (param == "LOGGING_CONFIG_URI") { logfile_uri = argv[ii]; + execparams[param] = argv[ii]; } else if (pupper == "NOLOGCFG") { useLogCfgResolver=false; } else if (pupper == "CPUBLACKLIST") { @@ -448,7 +454,8 @@ int main(int argc, char* argv[]) un, useLogCfgResolver, cpuBlackList.c_str(), - &internalShutdown_devMgr + &internalShutdown_devMgr, + spdFile ); DeviceManager_servant->setExecparamProperties(execparams); pstage=0; @@ -460,7 +467,9 @@ int main(int argc, char* argv[]) // for its deletion. PortableServer::POA_var devmgr_poa = root_poa->find_POA("DeviceManager", 1); PortableServer::ObjectId_var oid = devmgr_poa->activate_object(DeviceManager_servant); - + + + // finish initializing the Device Manager try { pstage++; From 8d7e22d6f31b4bf394848b6c90117258ebb65c15 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Thu, 15 Dec 2016 15:37:37 -0500 Subject: [PATCH 0620/1644] Give more time to the Device Manager, Domain Manager, and Name Service processes to synchronize --- redhawk/src/testing/tests/test_09_DomainPersistence.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/redhawk/src/testing/tests/test_09_DomainPersistence.py b/redhawk/src/testing/tests/test_09_DomainPersistence.py index bdec5da80..9f52c477a 100644 --- a/redhawk/src/testing/tests/test_09_DomainPersistence.py +++ b/redhawk/src/testing/tests/test_09_DomainPersistence.py @@ -556,11 +556,11 @@ def test_DeviceManagerSurprise(self): self._nb_devMgr, devMgr = self.launchDeviceManager("/nodes/test_BasicTestDevice_node/DeviceManager.dcd.xml", wait=False) # this sleep is needed to allow the Device Manager to figure out that the Domain Manager is not available - time.sleep(0.5) + time.sleep(1) # Start the domainMgr again self._nb_domMgr, newDomMgr = self.launchDomainManager(endpoint="giop:tcp::5679", dbURI=self._dbfile) - time.sleep(0.5) # sleep needed to make sure that the Device Manager has registered with the Domain Manager + time.sleep(1) # sleep needed to make sure that the Device Manager has registered with the Domain Manager node_name = 'BasicTestDevice_node' domainName = scatest.getTestDomainName() From ba353fd9717dc35ddb8537bb89cedc114d321ba9 Mon Sep 17 00:00:00 2001 From: Ryan Bauman Date: Fri, 16 Dec 2016 07:42:23 -0500 Subject: [PATCH 0621/1644] RELENG-488 - update frontendInterfaces version to 2.4.0 --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 08942a39a..dd6823d60 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,6 +1,6 @@ variables: REDHAWK_VERSION: '2.1.0' - FRONTEND_VERSION: '2.3.4' + FRONTEND_VERSION: '2.4.0' stages: - build From caf889d35539cb6e3a82bfe1211fce871bed05b3 Mon Sep 17 00:00:00 2001 From: 8530 <8530@vm-131.vsi-corp.com> Date: Fri, 16 Dec 2016 11:38:45 -0500 Subject: [PATCH 0622/1644] fix el6 compilation issue --- redhawk/src/control/sdr/devmgr/DeviceManager_impl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/redhawk/src/control/sdr/devmgr/DeviceManager_impl.h b/redhawk/src/control/sdr/devmgr/DeviceManager_impl.h index ca66cb718..931bec4f4 100644 --- a/redhawk/src/control/sdr/devmgr/DeviceManager_impl.h +++ b/redhawk/src/control/sdr/devmgr/DeviceManager_impl.h @@ -52,7 +52,7 @@ class DeviceManager_impl: { ENABLE_LOGGING - friend DomainCheckThread; + friend class DomainCheckThread; public: DeviceManager_impl (const char*, const char*, const char*, const char*, struct utsname uname, bool, const char *, bool *, std::string&); From 127b9fed0ed26e0948bd1844df0117bafcec37dd Mon Sep 17 00:00:00 2001 From: 8530 <8530@vm-131.vsi-corp.com> Date: Thu, 15 Dec 2016 13:42:22 -0500 Subject: [PATCH 0623/1644] added deployerrequires and devicerequires sections and initial tests --- .../control/include/ossie/componentProfile.h | 7 ++ .../src/control/parser/componentProfile.cpp | 8 ++ .../control/parser/internal/dcd-parser.cpp | 4 + .../src/control/parser/internal/dcd-pimpl.cpp | 31 ++++++ .../src/control/parser/internal/dcd-pimpl.h | 21 ++++ redhawk/src/control/parser/internal/dcd.map | 1 + .../control/parser/internal/sad-parser.cpp | 4 + .../src/control/parser/internal/sad-pimpl.cpp | 29 ++++++ .../src/control/parser/internal/sad-pimpl.h | 21 ++++ redhawk/src/control/parser/internal/sad.map | 1 + .../test_GPP_green/DeviceManager.dcd.xml | 46 +++++++++ .../nodes/test_GPP_red/DeviceManager.dcd.xml | 47 +++++++++ .../device_requires/device_requires.sad.xml | 58 +++++++++++ .../testing/tests/test_08_DeployerRequires.py | 99 +++++++++++++++++++ redhawk/src/xml/dtd/deviceconfiguration.dtd | 5 + redhawk/src/xml/dtd/softwareassembly.dtd | 5 + redhawk/src/xml/xsd/dcd.xsd | 8 ++ redhawk/src/xml/xsd/sad.xsd | 7 ++ 18 files changed, 402 insertions(+) create mode 100644 redhawk/src/testing/sdr/dev/nodes/test_GPP_green/DeviceManager.dcd.xml create mode 100644 redhawk/src/testing/sdr/dev/nodes/test_GPP_red/DeviceManager.dcd.xml create mode 100644 redhawk/src/testing/sdr/dom/waveforms/device_requires/device_requires.sad.xml create mode 100644 redhawk/src/testing/tests/test_08_DeployerRequires.py diff --git a/redhawk/src/control/include/ossie/componentProfile.h b/redhawk/src/control/include/ossie/componentProfile.h index bc3edef0b..ea4a77fbc 100644 --- a/redhawk/src/control/include/ossie/componentProfile.h +++ b/redhawk/src/control/include/ossie/componentProfile.h @@ -179,6 +179,9 @@ namespace ossie { ossie::optional_value startOrder; AffinityProperties affinityProperties; LoggingConfig loggingConfig; + ossie::ComponentPropertyList deployerrequires; + ossie::ComponentPropertyList devicerequires; + public: ComponentInstantiation(); @@ -199,6 +202,10 @@ namespace ossie { const AffinityProperties &getAffinity() const; + const ossie::ComponentPropertyList & getDeployerRequires() const; + + const ossie::ComponentPropertyList & getDeviceRequires() const; + bool isNamingService() const; const std::string& getFindByNamingServiceName() const; diff --git a/redhawk/src/control/parser/componentProfile.cpp b/redhawk/src/control/parser/componentProfile.cpp index 0cda1a547..9a5d74a30 100644 --- a/redhawk/src/control/parser/componentProfile.cpp +++ b/redhawk/src/control/parser/componentProfile.cpp @@ -168,6 +168,14 @@ const ComponentInstantiation::LoggingConfig &ComponentInstantiation::getLoggingC return loggingConfig; } +const ossie::ComponentPropertyList & ComponentInstantiation::getDeployerRequires() const { + return deployerrequires; +} + +const ossie::ComponentPropertyList & ComponentInstantiation::getDeviceRequires() const { + return devicerequires; +} + // // ComponentPlacement // diff --git a/redhawk/src/control/parser/internal/dcd-parser.cpp b/redhawk/src/control/parser/internal/dcd-parser.cpp index 28e8252fe..e5a4469e7 100644 --- a/redhawk/src/control/parser/internal/dcd-parser.cpp +++ b/redhawk/src/control/parser/internal/dcd-parser.cpp @@ -65,6 +65,7 @@ ossie::internalparser::parseDCD(std::istream& input) throw (ossie::parser_error) ::dcd::filesystemname_pimpl filesystemname_p; ::dcd::affinity_pimpl affinity_p; ::dcd::loggingconfig_pimpl loggingconfig_p; + ::dcd::deployerrequires_pimpl deployerrequires_p; // Connect the parsers together. @@ -110,6 +111,7 @@ ossie::internalparser::parseDCD(std::istream& input) throw (ossie::parser_error) componentproperties_p, affinity_p, loggingconfig_p, + deployerrequires_p, string_p); affinity_p.parsers (simpleref_p, @@ -119,6 +121,8 @@ ossie::internalparser::parseDCD(std::istream& input) throw (ossie::parser_error) loggingconfig_p.parsers(string_p); + deployerrequires_p.parsers(simpleref_p); + componentproperties_p.parsers (simpleref_p, simplesequenceref_p, structref_p, diff --git a/redhawk/src/control/parser/internal/dcd-pimpl.cpp b/redhawk/src/control/parser/internal/dcd-pimpl.cpp index d2ece82b0..e127bffe2 100644 --- a/redhawk/src/control/parser/internal/dcd-pimpl.cpp +++ b/redhawk/src/control/parser/internal/dcd-pimpl.cpp @@ -416,6 +416,13 @@ const ::ossie::ComponentFile &componentfile_pimpl:: componentInstantiation.loggingConfig = log_cfg; } + void componentinstantiation_pimpl::deployerrequires (const ossie::ComponentPropertyList& deployerrequires) + { + LOG_TRACE(dcd_parser, "deployer requires"); + componentInstantiation.deployerrequires = deployerrequires; + } + + const ::ossie::ComponentInstantiation& componentinstantiation_pimpl:: post_componentinstantiation () @@ -489,6 +496,30 @@ const ::ossie::ComponentInstantiation& componentinstantiation_pimpl:: } + // deployerrequires_pimpl + // + + void deployerrequires_pimpl:: + pre () + { + deployerrequires.clear(); + } + + void deployerrequires_pimpl:: + simpleref (const ossie::SimplePropertyRef& simpleref) + { + LOG_TRACE(dcd_parser, "Adding simpleref "); + deployerrequires.push_back(simpleref.clone()); + } + + const ossie::ComponentPropertyList& deployerrequires_pimpl:: + post_deployerrequires () + { + return deployerrequires; + } + + + // componentproperties_pimpl // diff --git a/redhawk/src/control/parser/internal/dcd-pimpl.h b/redhawk/src/control/parser/internal/dcd-pimpl.h index f3c4745cb..558ea582f 100644 --- a/redhawk/src/control/parser/internal/dcd-pimpl.h +++ b/redhawk/src/control/parser/internal/dcd-pimpl.h @@ -271,6 +271,9 @@ namespace dcd virtual void loggingconfig (const ossie::ComponentInstantiation::LoggingConfig& ); + virtual void + deployerrequires (const ossie::ComponentPropertyList& ); + virtual const ::ossie::ComponentInstantiation& post_componentinstantiation (); @@ -319,6 +322,24 @@ namespace dcd }; + class deployerrequires_pimpl: public virtual deployerrequires_pskel + { + public: + virtual void + pre (); + + virtual void + simpleref (const ossie::SimplePropertyRef&); + + virtual const ossie::ComponentPropertyList& + post_deployerrequires (); + + private: + ossie::ComponentPropertyList deployerrequires; + }; + + + class componentproperties_pimpl: public virtual componentproperties_pskel { public: diff --git a/redhawk/src/control/parser/internal/dcd.map b/redhawk/src/control/parser/internal/dcd.map index 4c580272f..cc6f3f315 100644 --- a/redhawk/src/control/parser/internal/dcd.map +++ b/redhawk/src/control/parser/internal/dcd.map @@ -56,4 +56,5 @@ namespace urn:mil:jpeojtrs:sca:dcd { deviceusedbythiscomponentref "::std::pair"; affinity "const ossie::ComponentInstantiation::AffinityProperties&" "const ossie::ComponentInstantiation::AffinityProperties&"; loggingconfig "const ossie::ComponentInstantiation::LoggingConfig&" "const ossie::ComponentInstantiation::LoggingConfig&"; + deployerrequires "const ossie::ComponentPropertyList&" "const ossie::ComponentPropertyList&"; } diff --git a/redhawk/src/control/parser/internal/sad-parser.cpp b/redhawk/src/control/parser/internal/sad-parser.cpp index 63a356274..3e154dbc7 100644 --- a/redhawk/src/control/parser/internal/sad-parser.cpp +++ b/redhawk/src/control/parser/internal/sad-parser.cpp @@ -71,6 +71,7 @@ ossie::internalparser::parseSAD(std::istream& input) throw (ossie::parser_error) ::sad::propertyref_pimpl propertyref_p; ::sad::affinity_pimpl affinity_p; ::sad::loggingconfig_pimpl loggingconfig_p; + ::sad::devicerequires_pimpl devicerequires_p; // Connect the parsers together. @@ -108,6 +109,7 @@ ossie::internalparser::parseSAD(std::istream& input) throw (ossie::parser_error) affinity_p, loggingconfig_p, findcomponent_p, + devicerequires_p, string_p, string_p); @@ -118,6 +120,8 @@ ossie::internalparser::parseSAD(std::istream& input) throw (ossie::parser_error) loggingconfig_p.parsers(string_p); + devicerequires_p.parsers (simpleref_p); + componentproperties_p.parsers (simpleref_p, simplesequenceref_p, structref_p, diff --git a/redhawk/src/control/parser/internal/sad-pimpl.cpp b/redhawk/src/control/parser/internal/sad-pimpl.cpp index 4a7f12a0a..aecb353bb 100644 --- a/redhawk/src/control/parser/internal/sad-pimpl.cpp +++ b/redhawk/src/control/parser/internal/sad-pimpl.cpp @@ -320,6 +320,12 @@ namespace sad componentInstantiation.loggingConfig = log_cfg; } + void componentinstantiation_pimpl::devicerequires (ossie::ComponentPropertyList& requiresproperties) + { + componentInstantiation.devicerequires.swap(requiresproperties); + } + + const ::ossie::ComponentInstantiation& componentinstantiation_pimpl:: post_componentinstantiation () @@ -385,6 +391,29 @@ namespace sad return info; } + // devicerequires_pimpl + // + + void devicerequires_pimpl:: + pre () + { + devicerequires.clear(); + } + + void devicerequires_pimpl:: + simpleref (const ossie::SimplePropertyRef& simpleref) + { + devicerequires.push_back(simpleref.clone()); + } + + ossie::ComponentPropertyList& devicerequires_pimpl:: + post_devicerequires () + { + return devicerequires; + } + + + // componentproperties_pimpl // diff --git a/redhawk/src/control/parser/internal/sad-pimpl.h b/redhawk/src/control/parser/internal/sad-pimpl.h index c4c5ae1f1..ea7b6e743 100644 --- a/redhawk/src/control/parser/internal/sad-pimpl.h +++ b/redhawk/src/control/parser/internal/sad-pimpl.h @@ -209,6 +209,9 @@ namespace sad virtual void loggingconfig (const ossie::ComponentInstantiation::LoggingConfig&); + virtual void + devicerequires (ossie::ComponentPropertyList&); + virtual const ::ossie::ComponentInstantiation& post_componentinstantiation (); @@ -257,6 +260,24 @@ namespace sad ossie::ComponentInstantiation::LoggingConfig info; }; + class devicerequires_pimpl: public virtual devicerequires_pskel + { + public: + + virtual void + pre (); + + virtual void + simpleref (const ossie::SimplePropertyRef&); + + virtual ossie::ComponentPropertyList& + post_devicerequires (); + + private: + ossie::ComponentPropertyList devicerequires; + }; + + class componentproperties_pimpl: public virtual componentproperties_pskel { diff --git a/redhawk/src/control/parser/internal/sad.map b/redhawk/src/control/parser/internal/sad.map index 63347b835..48a219ca3 100644 --- a/redhawk/src/control/parser/internal/sad.map +++ b/redhawk/src/control/parser/internal/sad.map @@ -65,5 +65,6 @@ namespace urn:mil:jpeojtrs:sca:sad { propertyref "ossie::PropertyRef"; affinity "ossie::ComponentInstantiation::AffinityProperties&"; loggingconfig "const ossie::ComponentInstantiation::LoggingConfig&" "const ossie::ComponentInstantiation::LoggingConfig&"; + devicerequires "ossie::ComponentPropertyList &" "ossie::ComponentPropertyList &"; } diff --git a/redhawk/src/testing/sdr/dev/nodes/test_GPP_green/DeviceManager.dcd.xml b/redhawk/src/testing/sdr/dev/nodes/test_GPP_green/DeviceManager.dcd.xml new file mode 100644 index 000000000..59fe31632 --- /dev/null +++ b/redhawk/src/testing/sdr/dev/nodes/test_GPP_green/DeviceManager.dcd.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + GPP_1 + + + + + + + + + + diff --git a/redhawk/src/testing/sdr/dev/nodes/test_GPP_red/DeviceManager.dcd.xml b/redhawk/src/testing/sdr/dev/nodes/test_GPP_red/DeviceManager.dcd.xml new file mode 100644 index 000000000..da67d01b8 --- /dev/null +++ b/redhawk/src/testing/sdr/dev/nodes/test_GPP_red/DeviceManager.dcd.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + GPP_1 + + + + + + + + + + + diff --git a/redhawk/src/testing/sdr/dom/waveforms/device_requires/device_requires.sad.xml b/redhawk/src/testing/sdr/dom/waveforms/device_requires/device_requires.sad.xml new file mode 100644 index 000000000..5cbf8e232 --- /dev/null +++ b/redhawk/src/testing/sdr/dom/waveforms/device_requires/device_requires.sad.xml @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + SimpleComponent_1 + + + + + + + + + + + + + SimpleComponent_2 + + + + + + + + + + + + + diff --git a/redhawk/src/testing/tests/test_08_DeployerRequires.py b/redhawk/src/testing/tests/test_08_DeployerRequires.py new file mode 100644 index 000000000..af8229b3c --- /dev/null +++ b/redhawk/src/testing/tests/test_08_DeployerRequires.py @@ -0,0 +1,99 @@ +# +# This file is protected by Copyright. Please refer to the COPYRIGHT file +# distributed with this source distribution. +# +# This file is part of REDHAWK core. +# +# REDHAWK core is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation, either version 3 of the License, or (at your option) any +# later version. +# +# REDHAWK core is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +# details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/. +# + +import unittest +from _unitTestHelpers import scatest +from ossie.cf import CF, ExtendedCF +from omniORB import any, CORBA +from ossie import properties + +class DeviceRequires(scatest.CorbaTestCase): + def setUp(self): + self._app = None + + def tearDown(self): + if self._app: + self._app.stop() + self._app.releaseObject() + + # Do all application shutdown before calling the base class tearDown, + # or failures will probably occur. + scatest.CorbaTestCase.tearDown(self) + + def _createApp(self, app): + self.assertNotEqual(self._domMgr, None) + self.assertNotEqual(self._devMgr, None) + + sadpath = '/waveforms/'+app+'/'+app+'.sad.xml' + self._domMgr.installApplication(sadpath) + self.assertEqual(len(self._domMgr._get_applicationFactories()), 1) + appFact = self._domMgr._get_applicationFactories()[0] + + try: + self._app = appFact.create(appFact._get_name(), [], []) + except: + self.fail("Did not create application ") + + def test_createNoDeployerRequires(self): + domBooter, self._domMgr = self.launchDomainManager() + devBooter, self._devMgr = self.launchDeviceManager("/nodes/test_GPP_node/DeviceManager.dcd.xml") + + self.assertNotEqual(self._domMgr, None) + self.assertNotEqual(self._devMgr, None) + + self._createApp('device_requires') + + self.assertNotEqual(self._app, None) + xx=self._app.query([]) + +class DeployerRequiresTest(scatest.CorbaTestCase): + def setUp(self): + self._app = None + + def tearDown(self): + # Do all application shutdown before calling the base class tearDown, + # or failures will probably occur. + scatest.CorbaTestCase.tearDown(self) + + def test_launchRedNode(self): + domBooter, self._domMgr = self.launchDomainManager() + devBooter, self._devMgr = self.launchDeviceManager("/nodes/test_GPP_red/DeviceManager.dcd.xml") + + self.assertNotEqual(self._domMgr, None) + self.assertNotEqual(self._devMgr, None) + + def test_launchGreenNode(self): + domBooter, self._domMgr = self.launchDomainManager() + devBooter, self._devMgr = self.launchDeviceManager("/nodes/test_GPP_red/DeviceManager.dcd.xml") + + self.assertNotEqual(self._domMgr, None) + self.assertNotEqual(self._devMgr, None) + + + def test_launchMixNode(self): + domBooter, self._domMgr = self.launchDomainManager() + redBooter, self._rednode = self.launchDeviceManager("/nodes/test_GPP_red/DeviceManager.dcd.xml") + greenBooter, self._greennode = self.launchDeviceManager("/nodes/test_GPP_green/DeviceManager.dcd.xml") + plainBooter, self._plainnode = self.launchDeviceManager("/nodes/test_GPP_node/DeviceManager.dcd.xml") + + self.assertNotEqual(self._domMgr, None) + self.assertNotEqual(self._rednode, None) + self.assertNotEqual(self._greennode, None) + self.assertNotEqual(self._plainnode, None) diff --git a/redhawk/src/xml/dtd/deviceconfiguration.dtd b/redhawk/src/xml/dtd/deviceconfiguration.dtd index afaadab95..a5c23d986 100644 --- a/redhawk/src/xml/dtd/deviceconfiguration.dtd +++ b/redhawk/src/xml/dtd/deviceconfiguration.dtd @@ -87,6 +87,7 @@ with this program. If not, see http://www.gnu.org/licenses/. ,componentproperties? ,affinity? ,loggingconfig? + ,deployerrequires? )> @@ -104,6 +105,10 @@ with this program. If not, see http://www.gnu.org/licenses/. | structsequenceref )+ > + + + + + @@ -221,6 +222,13 @@ usagename element needs to be unique for each service type. + + + + + + + diff --git a/redhawk/src/xml/xsd/sad.xsd b/redhawk/src/xml/xsd/sad.xsd index ad8569f32..a1a71feea 100644 --- a/redhawk/src/xml/xsd/sad.xsd +++ b/redhawk/src/xml/xsd/sad.xsd @@ -79,6 +79,7 @@ with this program. If not, see http://www.gnu.org/licenses/. + @@ -102,6 +103,12 @@ with this program. If not, see http://www.gnu.org/licenses/. + + + + + + From 78d4aeab5f3c81ab14fe4b4ebaa3a3bca1a2ef86 Mon Sep 17 00:00:00 2001 From: 8530 <8530@vm-131.vsi-corp.com> Date: Mon, 19 Dec 2016 16:41:16 -0500 Subject: [PATCH 0624/1644] adding deployerrequires and devicerequires to allow device filters during deployment, added unit tests and fixes from testing, CF-1416 --- redhawk/src/control/framework/prop_utils.cpp | 11 + .../ossie/DeviceManagerConfiguration.h | 6 +- .../control/include/ossie/componentProfile.h | 7 + .../src/control/include/ossie/prop_utils.h | 4 + .../control/parser/internal/dcd-parser.cpp | 6 +- .../src/control/parser/internal/dcd-pimpl.cpp | 38 ++- .../src/control/parser/internal/dcd-pimpl.h | 23 +- redhawk/src/control/parser/internal/dcd.map | 1 + .../control/parser/internal/sad-parser.cpp | 6 +- .../src/control/parser/internal/sad-pimpl.cpp | 37 ++- .../src/control/parser/internal/sad-pimpl.h | 22 +- redhawk/src/control/parser/internal/sad.map | 1 + .../control/sdr/devmgr/DeviceManager_impl.cpp | 4 + .../sdr/dommgr/AllocationManager_impl.cpp | 85 +++++- .../sdr/dommgr/AllocationManager_impl.h | 29 +- .../sdr/dommgr/ApplicationFactory_impl.cpp | 24 +- redhawk/src/control/sdr/dommgr/Deployment.cpp | 9 + redhawk/src/control/sdr/dommgr/Deployment.h | 3 + .../control/sdr/dommgr/DomainManager_impl.cpp | 34 ++- .../src/control/sdr/dommgr/PersistenceStore.h | 4 + redhawk/src/control/sdr/dommgr/createHelper.h | 6 +- .../test_GPP_green/DeviceManager.dcd.xml | 8 +- .../nodes/test_GPP_red/DeviceManager.dcd.xml | 30 +- .../device_requires_green.sad.xml | 45 +++ .../device_requires_multicolor.sad.xml} | 22 +- .../device_requires_red.sad.xml | 46 +++ .../testing/tests/test_08_DeployerRequires.py | 268 ++++++++++++++++-- redhawk/src/xml/dtd/deviceconfiguration.dtd | 7 +- redhawk/src/xml/dtd/softwareassembly.dtd | 7 +- redhawk/src/xml/xsd/dcd.xsd | 8 +- redhawk/src/xml/xsd/sad.xsd | 9 +- 31 files changed, 701 insertions(+), 109 deletions(-) create mode 100644 redhawk/src/testing/sdr/dom/waveforms/device_requires_green/device_requires_green.sad.xml rename redhawk/src/testing/sdr/dom/waveforms/{device_requires/device_requires.sad.xml => device_requires_multicolor/device_requires_multicolor.sad.xml} (72%) create mode 100644 redhawk/src/testing/sdr/dom/waveforms/device_requires_red/device_requires_red.sad.xml diff --git a/redhawk/src/control/framework/prop_utils.cpp b/redhawk/src/control/framework/prop_utils.cpp index a38728dfd..25a309119 100644 --- a/redhawk/src/control/framework/prop_utils.cpp +++ b/redhawk/src/control/framework/prop_utils.cpp @@ -647,6 +647,17 @@ void ossie::convertComponentProperties( const ossie::ComponentPropertyList &cp_p cf_props[cf_props.length()-1] = dt; } } + +void ossie::convertComponentProperties( const ossie::ComponentPropertyList &cp_props, + redhawk::PropertyMap &cf_props ) +{ + ossie::ComponentPropertyList::const_iterator piter = cp_props.begin(); + for ( ; piter != cp_props.end(); piter++ ) { + CF::DataType dt = ossie::convertPropertyRefToDataType( *piter ); + cf_props.push_back(dt); + } +} + std::string ossie::retrieveParserErrorLineNumber(std::string message) { size_t begin_n_line = message.find_first_of(':'); diff --git a/redhawk/src/control/include/ossie/DeviceManagerConfiguration.h b/redhawk/src/control/include/ossie/DeviceManagerConfiguration.h index 2c31c397f..76ab97f1b 100644 --- a/redhawk/src/control/include/ossie/DeviceManagerConfiguration.h +++ b/redhawk/src/control/include/ossie/DeviceManagerConfiguration.h @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -30,6 +31,7 @@ #include "ossie/exceptions.h" #include "ossie/ossieparser.h" #include "ossie/componentProfile.h" +#include namespace ossie { @@ -76,7 +78,7 @@ namespace ossie { * information from a DCD file. You must call load() before calling any * other functions on this class. */ - DeviceManagerConfiguration() : _dcd(0) {} + DeviceManagerConfiguration() : _dcd() {} /* * Create a DeviceManagerConfiguration, parsing the DCD information provided by input. @@ -114,7 +116,7 @@ namespace ossie { const ComponentInstantiation& getComponentInstantiationById(std::string id) throw(std::out_of_range); private: - std::auto_ptr _dcd; + boost::shared_ptr _dcd; }; } diff --git a/redhawk/src/control/include/ossie/componentProfile.h b/redhawk/src/control/include/ossie/componentProfile.h index ea4a77fbc..815bf2745 100644 --- a/redhawk/src/control/include/ossie/componentProfile.h +++ b/redhawk/src/control/include/ossie/componentProfile.h @@ -98,6 +98,7 @@ namespace ossie { return out; } + /* * */ @@ -114,6 +115,12 @@ namespace ossie { const std::string _asString() const; }; + + class IdValue : public SimplePropertyRef { + + }; + + /* * */ diff --git a/redhawk/src/control/include/ossie/prop_utils.h b/redhawk/src/control/include/ossie/prop_utils.h index 6360de7f3..846c7f715 100644 --- a/redhawk/src/control/include/ossie/prop_utils.h +++ b/redhawk/src/control/include/ossie/prop_utils.h @@ -27,6 +27,7 @@ #include #include "ossie/Properties.h" +#include "ossie/PropertyMap.h" #include "ossie/SoftPkg.h" #include "ossie/componentProfile.h" @@ -73,6 +74,9 @@ namespace ossie void convertComponentProperties( const ossie::ComponentPropertyList &cp_props, CF::Properties &cf_props ); + + void convertComponentProperties( const ossie::ComponentPropertyList &cp_props, + redhawk::PropertyMap &cf_props ); std::string retrieveParserErrorLineNumber(std::string message); diff --git a/redhawk/src/control/parser/internal/dcd-parser.cpp b/redhawk/src/control/parser/internal/dcd-parser.cpp index e5a4469e7..526b8b735 100644 --- a/redhawk/src/control/parser/internal/dcd-parser.cpp +++ b/redhawk/src/control/parser/internal/dcd-parser.cpp @@ -66,6 +66,7 @@ ossie::internalparser::parseDCD(std::istream& input) throw (ossie::parser_error) ::dcd::affinity_pimpl affinity_p; ::dcd::loggingconfig_pimpl loggingconfig_p; ::dcd::deployerrequires_pimpl deployerrequires_p; + ::dcd::idvalue_pimpl idvalue_p; // Connect the parsers together. @@ -121,13 +122,16 @@ ossie::internalparser::parseDCD(std::istream& input) throw (ossie::parser_error) loggingconfig_p.parsers(string_p); - deployerrequires_p.parsers(simpleref_p); + deployerrequires_p.parsers(idvalue_p); componentproperties_p.parsers (simpleref_p, simplesequenceref_p, structref_p, structsequenceref_p); + idvalue_p.parsers (string_p, + string_p); + simpleref_p.parsers (string_p, string_p); diff --git a/redhawk/src/control/parser/internal/dcd-pimpl.cpp b/redhawk/src/control/parser/internal/dcd-pimpl.cpp index e127bffe2..d2037cbda 100644 --- a/redhawk/src/control/parser/internal/dcd-pimpl.cpp +++ b/redhawk/src/control/parser/internal/dcd-pimpl.cpp @@ -506,10 +506,10 @@ const ::ossie::ComponentInstantiation& componentinstantiation_pimpl:: } void deployerrequires_pimpl:: - simpleref (const ossie::SimplePropertyRef& simpleref) + requires (const ossie::IdValue& idvalue) { - LOG_TRACE(dcd_parser, "Adding simpleref "); - deployerrequires.push_back(simpleref.clone()); + LOG_TRACE(dcd_parser, "Adding idvalue " << idvalue._id << " value " << idvalue._value ); + deployerrequires.push_back(idvalue.clone()); } const ossie::ComponentPropertyList& deployerrequires_pimpl:: @@ -611,6 +611,38 @@ const ::ossie::ComponentInstantiation& componentinstantiation_pimpl:: return info; } + // idvalueref_pimpl + // + + void idvalue_pimpl:: + pre () + { + LOG_TRACE(dcd_parser, "pre idvalue"); + simple = ossie::IdValue(); + } + + void idvalue_pimpl:: + id (const ::std::string& id) + { + LOG_TRACE(dcd_parser, "idvalue id: " << id); + simple._id = id; + } + + void idvalue_pimpl:: + value (const ::std::string& value) + { + LOG_TRACE(dcd_parser, "idvalue value: " << value); + simple._value = value; + } + + const ossie::IdValue& idvalue_pimpl:: + post_idvalue () + { + LOG_TRACE(dcd_parser, "post idvalue"); + return simple; + } + + // simpleref_pimpl // diff --git a/redhawk/src/control/parser/internal/dcd-pimpl.h b/redhawk/src/control/parser/internal/dcd-pimpl.h index 558ea582f..a75dc5559 100644 --- a/redhawk/src/control/parser/internal/dcd-pimpl.h +++ b/redhawk/src/control/parser/internal/dcd-pimpl.h @@ -329,7 +329,7 @@ namespace dcd pre (); virtual void - simpleref (const ossie::SimplePropertyRef&); + requires (const ossie::IdValue &); virtual const ossie::ComponentPropertyList& post_deployerrequires (); @@ -400,6 +400,27 @@ namespace dcd std::pair info; }; + + class idvalue_pimpl: public virtual idvalue_pskel + { + public: + virtual void + pre (); + + virtual void + id (const ::std::string&); + + virtual void + value (const ::std::string&); + + virtual const ossie::IdValue& + post_idvalue (); + + private: + ossie::IdValue simple; + }; + + class simpleref_pimpl: public virtual simpleref_pskel { public: diff --git a/redhawk/src/control/parser/internal/dcd.map b/redhawk/src/control/parser/internal/dcd.map index cc6f3f315..8d7ed6b1f 100644 --- a/redhawk/src/control/parser/internal/dcd.map +++ b/redhawk/src/control/parser/internal/dcd.map @@ -57,4 +57,5 @@ namespace urn:mil:jpeojtrs:sca:dcd { affinity "const ossie::ComponentInstantiation::AffinityProperties&" "const ossie::ComponentInstantiation::AffinityProperties&"; loggingconfig "const ossie::ComponentInstantiation::LoggingConfig&" "const ossie::ComponentInstantiation::LoggingConfig&"; deployerrequires "const ossie::ComponentPropertyList&" "const ossie::ComponentPropertyList&"; + idvalue "const ossie::IdValue&" "const ossie::IdValue&"; } diff --git a/redhawk/src/control/parser/internal/sad-parser.cpp b/redhawk/src/control/parser/internal/sad-parser.cpp index 3e154dbc7..d39bee7c9 100644 --- a/redhawk/src/control/parser/internal/sad-parser.cpp +++ b/redhawk/src/control/parser/internal/sad-parser.cpp @@ -72,6 +72,7 @@ ossie::internalparser::parseSAD(std::istream& input) throw (ossie::parser_error) ::sad::affinity_pimpl affinity_p; ::sad::loggingconfig_pimpl loggingconfig_p; ::sad::devicerequires_pimpl devicerequires_p; + ::sad::idvalue_pimpl idvalue_p; // Connect the parsers together. @@ -120,13 +121,16 @@ ossie::internalparser::parseSAD(std::istream& input) throw (ossie::parser_error) loggingconfig_p.parsers(string_p); - devicerequires_p.parsers (simpleref_p); + devicerequires_p.parsers (idvalue_p); componentproperties_p.parsers (simpleref_p, simplesequenceref_p, structref_p, structsequenceref_p); + idvalue_p.parsers (string_p, + string_p); + simpleref_p.parsers (string_p, string_p); diff --git a/redhawk/src/control/parser/internal/sad-pimpl.cpp b/redhawk/src/control/parser/internal/sad-pimpl.cpp index aecb353bb..9da641331 100644 --- a/redhawk/src/control/parser/internal/sad-pimpl.cpp +++ b/redhawk/src/control/parser/internal/sad-pimpl.cpp @@ -401,9 +401,9 @@ namespace sad } void devicerequires_pimpl:: - simpleref (const ossie::SimplePropertyRef& simpleref) + requires (const ossie::IdValue& idvalue) { - devicerequires.push_back(simpleref.clone()); + devicerequires.push_back(idvalue.clone()); } ossie::ComponentPropertyList& devicerequires_pimpl:: @@ -615,6 +615,39 @@ namespace sad { } + + + // idvalueref_pimpl + // + + void idvalue_pimpl:: + pre () + { + LOG_TRACE(sad_parser, "pre idvalue"); + simple = ossie::IdValue(); + } + + void idvalue_pimpl:: + id (const ::std::string& id) + { + LOG_TRACE(sad_parser, "idvalue id: " << id); + simple._id = id; + } + + void idvalue_pimpl:: + value (const ::std::string& value) + { + LOG_TRACE(sad_parser, "idvalue value: " << value); + simple._value = value; + } + + const ossie::IdValue& idvalue_pimpl:: + post_idvalue () + { + LOG_TRACE(sad_parser, "post idvalue"); + return simple; + } + // simpleref_pimpl // diff --git a/redhawk/src/control/parser/internal/sad-pimpl.h b/redhawk/src/control/parser/internal/sad-pimpl.h index ea7b6e743..4bd177707 100644 --- a/redhawk/src/control/parser/internal/sad-pimpl.h +++ b/redhawk/src/control/parser/internal/sad-pimpl.h @@ -268,7 +268,7 @@ namespace sad pre (); virtual void - simpleref (const ossie::SimplePropertyRef&); + requires (const ossie::IdValue&); virtual ossie::ComponentPropertyList& post_devicerequires (); @@ -415,6 +415,26 @@ namespace sad post_resourcefactoryproperties (); }; + class idvalue_pimpl: public virtual idvalue_pskel + { + public: + virtual void + pre (); + + virtual void + id (const ::std::string&); + + virtual void + value (const ::std::string&); + + virtual const ossie::IdValue& + post_idvalue (); + + private: + ossie::IdValue simple; + }; + + class simpleref_pimpl: public virtual simpleref_pskel { public: diff --git a/redhawk/src/control/parser/internal/sad.map b/redhawk/src/control/parser/internal/sad.map index 48a219ca3..b972f2d06 100644 --- a/redhawk/src/control/parser/internal/sad.map +++ b/redhawk/src/control/parser/internal/sad.map @@ -66,5 +66,6 @@ namespace urn:mil:jpeojtrs:sca:sad { affinity "ossie::ComponentInstantiation::AffinityProperties&"; loggingconfig "const ossie::ComponentInstantiation::LoggingConfig&" "const ossie::ComponentInstantiation::LoggingConfig&"; devicerequires "ossie::ComponentPropertyList &" "ossie::ComponentPropertyList &"; + idvalue "const ossie::IdValue&" "const ossie::IdValue&"; } diff --git a/redhawk/src/control/sdr/devmgr/DeviceManager_impl.cpp b/redhawk/src/control/sdr/devmgr/DeviceManager_impl.cpp index a7864b15e..73987bed9 100644 --- a/redhawk/src/control/sdr/devmgr/DeviceManager_impl.cpp +++ b/redhawk/src/control/sdr/devmgr/DeviceManager_impl.cpp @@ -1237,6 +1237,7 @@ DeviceManager_impl::DeviceManager_impl( const char *cpuBlackList, bool* internalShutdown, std::string& spdFile) : + DomainWatchThread(NULL), _registeredDevices() { // These should probably be execparams at some point @@ -1726,6 +1727,9 @@ void DeviceManager_impl::postConstructor ( } } + + if ( _spdFile.empty() ) return; + File_stream devMgrSpdStream(_fileSys, _spdFile.c_str()); ossie::SoftPkg parsedSpd; ossie::Properties parsedPrf; diff --git a/redhawk/src/control/sdr/dommgr/AllocationManager_impl.cpp b/redhawk/src/control/sdr/dommgr/AllocationManager_impl.cpp index d29d9646e..5f36dc85c 100644 --- a/redhawk/src/control/sdr/dommgr/AllocationManager_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/AllocationManager_impl.cpp @@ -208,7 +208,12 @@ CF::AllocationManager::AllocationResponseSequence* AllocationManager_impl::alloc } } - std::pair result = allocateRequest(requestID, request.allocationProperties, requestedDevices, sourceID, std::vector(), std::vector(), domainName); + std::pair result = allocateRequest(requestID, + request.allocationProperties, + requestedDevices, + sourceID, std::vector(), + std::vector(), + domainName); if (result.first) { local_allocations.push_back(result.first); ossie::AllocationType* allocation(result.first); @@ -230,12 +235,18 @@ CF::AllocationManager::AllocationResponseSequence* AllocationManager_impl::alloc return response._retn(); } -std::pair AllocationManager_impl::allocateRequest(const std::string& requestID, const CF::Properties& dependencyProperties, ossie::DeviceList& devices, const std::string& sourceID, const std::vector& processorDeps, const std::vector& osDeps, const std::string& domainName) +std::pair AllocationManager_impl::allocateRequest(const std::string& requestID, + const CF::Properties& dependencyProperties, + ossie::DeviceList& devices, const std::string& sourceID, + const std::vector& processorDeps, + const std::vector& osDeps, + const std::string& domainName, + const CF::Properties &deviceRequires ) { for (ossie::DeviceList::iterator iter = devices.begin(); iter != devices.end(); ++iter) { boost::shared_ptr node = *iter; CF::Properties allocatedProperties; - if (allocateDevice(dependencyProperties, *node, allocatedProperties, processorDeps, osDeps)) { + if (allocateDevice(dependencyProperties, *node, allocatedProperties, processorDeps, osDeps, deviceRequires)) { ossie::AllocationType* allocation = new ossie::AllocationType(); allocation->allocationID = ossie::generateUUID(); allocation->sourceID = sourceID; @@ -249,10 +260,16 @@ std::pair AllocationManager_ return std::make_pair((ossie::AllocationType*)0, devices.end()); } -ossie::AllocationResult AllocationManager_impl::allocateDeployment(const std::string& requestID, const CF::Properties& allocationProperties, ossie::DeviceList& devices, const std::string& sourceID, const std::vector& processorDeps, const std::vector& osDeps) +ossie::AllocationResult AllocationManager_impl::allocateDeployment(const std::string& requestID, + const CF::Properties& allocationProperties, + ossie::DeviceList& devices, + const std::string& sourceID, + const std::vector& processorDeps, + const std::vector& osDeps, + const CF::Properties& deviceRequires ) { const std::string domainName = this->_domainManager->getDomainManagerName(); - std::pair result = allocateRequest(requestID, allocationProperties, devices, sourceID, processorDeps, osDeps, domainName); + std::pair result = allocateRequest(requestID, allocationProperties, devices, sourceID, processorDeps, osDeps, domainName, deviceRequires); if (result.first) { // Update the allocation table, including the persistence store const std::string allocationID = result.first->allocationID; @@ -281,7 +298,12 @@ bool AllocationManager_impl::hasListenerAllocation(const CF::Properties& request return false; } -bool AllocationManager_impl::allocateDevice(const CF::Properties& requestedProperties, ossie::DeviceNode& node, CF::Properties& allocatedProperties, const std::vector& processorDeps, const std::vector& osDeps) +bool AllocationManager_impl::allocateDevice(const CF::Properties& requestedProperties, + ossie::DeviceNode& node, + CF::Properties& allocatedProperties, + const std::vector& processorDeps, + const std::vector& osDeps, + const CF::Properties& devicerequires) { if (!ossie::corba::objectExists(node.device)) { LOG_WARN(AllocationManager_impl, "Not using device for uses_device allocation " << node.identifier << " because it no longer exists"); @@ -306,6 +328,12 @@ bool AllocationManager_impl::allocateDevice(const CF::Properties& requestedPrope return false; } + LOG_INFO(AllocationManager_impl, "allocateDevice::PartitionMatching " << node.requiresProps ); + if ( !checkPartitionMatching( node, devicerequires )) { + LOG_TRACE(AllocationManager_impl, "Partition Matching failed"); + return false; + } + // If there are no external properties to allocate, the allocation is // already successful if (allocProps.length() == 0) { @@ -465,6 +493,51 @@ bool AllocationManager_impl::checkDeviceMatching(ossie::Properties& prf, CF::Pro return true; } +bool AllocationManager_impl::checkPartitionMatching( ossie::DeviceNode& node, + const CF::Properties& devicerequires ) +{ + // + // perform matching of a device's deployrequires property set against a componentplacment's devicerequires list + // + + + // Check if the device has a required property set for deployment + if ( node.requiresProps.size() == 0 ) { + LOG_DEBUG(AllocationManager_impl, "Device: " << node.label << " has no required properties to filter deployments against."); + return true; + } + + // Check if the device has a required property set for deployment + if ( devicerequires.length() == 0 ) { + LOG_DEBUG(AllocationManager_impl, "Device: " << node.label << " has required properties for deployment, component does not provide any properties."); + return false; + } + + const redhawk::PropertyMap &provided_props = redhawk::PropertyMap::cast( devicerequires ); + redhawk::PropertyMap::iterator iter = node.requiresProps.begin(); + for ( ; iter != node.requiresProps.end(); ++iter) { + std::string pid(iter->getId()); + LOG_TRACE(AllocationManager_impl, "checkPartitionMatching source device requires: " << pid ); + redhawk::PropertyMap::const_iterator provided_prop = provided_props.find( pid ); + if ( provided_prop == provided_props.end() ) { + LOG_INFO(AllocationManager_impl, "Device: " << node.label << ", Missing REQUIRES property: " << pid << " from component for deployment"); + return false; + } + + // Convert the input Any to the property's data type via string; if it came + // from the ApplicationFactory, it's already a string, but a remote request + // could be of any type + std::string action("eq"); + if ( !ossie::compare_anys(iter->getValue(), provided_prop->getValue(), action) ) { + return false; + } + } + + LOG_TRACE(AllocationManager_impl, "checkPartitionMatch PASSED for device: " << node.label ); + return true; +} + + /* Deallocates a set of allocations */ void AllocationManager_impl::deallocate(const CF::AllocationManager::allocationIDSequence &allocationIDs) throw (CF::AllocationManager::InvalidAllocationId) { diff --git a/redhawk/src/control/sdr/dommgr/AllocationManager_impl.h b/redhawk/src/control/sdr/dommgr/AllocationManager_impl.h index e79265c9c..634f593c3 100644 --- a/redhawk/src/control/sdr/dommgr/AllocationManager_impl.h +++ b/redhawk/src/control/sdr/dommgr/AllocationManager_impl.h @@ -72,7 +72,13 @@ class AllocationManager_impl: public virtual POA_CF::AllocationManager CF::DomainManager_ptr domainMgr(); /* Allocates a set of dependencies for deployment; not part of the CORBA API */ - ossie::AllocationResult allocateDeployment(const std::string& requestID, const CF::Properties& allocationProperties, ossie::DeviceList& devices, const std::string& sourceID, const std::vector& processorDeps, const std::vector& osDeps); + ossie::AllocationResult allocateDeployment(const std::string& requestID, + const CF::Properties& allocationProperties, + ossie::DeviceList& devices, + const std::string& sourceID, + const std::vector& processorDeps, + const std::vector& osDeps, + const CF::Properties& deviceRequires); /* Deallocates a set of allocations */ template @@ -108,13 +114,30 @@ class AllocationManager_impl: public virtual POA_CF::AllocationManager private: CF::AllocationManager::AllocationResponseSequence* allocateDevices(const CF::AllocationManager::AllocationRequestSequence &requests, ossie::DeviceList& devices, const std::string& domainName); - std::pair allocateRequest(const std::string& requestID, const CF::Properties& allocationProperties, ossie::DeviceList& devices, const std::string& sourceID, const std::vector& processorDeps, const std::vector& osDeps, const std::string& domainName); + std::pair allocateRequest(const std::string& requestID, + const CF::Properties& allocationProperties, + ossie::DeviceList& devices, + const std::string& sourceID, + const std::vector& processorDeps, + const std::vector& osDeps, + const std::string& domainName, + const CF::Properties& deviceRequires = CF::Properties() ); bool checkDeviceMatching(ossie::Properties& _prf, CF::Properties& externalProps, const CF::Properties& dependencyPropertiesFromComponent, const std::vector& processorDeps, const std::vector& osDeps); bool checkMatchingProperty(const ossie::Property* property, const CF::DataType& dependency); + bool checkPartitionMatching( ossie::DeviceNode& node, + const CF::Properties& devicerequires ); - bool allocateDevice(const CF::Properties& requestedProperties, ossie::DeviceNode& device, CF::Properties& allocatedProperties, const std::vector& processorDeps, const std::vector& osDeps); + redhawk::PropertyMap getDeviceRequiredProperties( ossie::DeviceNode& node ); + + + bool allocateDevice(const CF::Properties& requestedProperties, + ossie::DeviceNode& device, + CF::Properties& allocatedProperties, + const std::vector& processorDeps, + const std::vector& osDeps, + const CF::Properties& deviceRequires = CF::Properties() ); void partitionProperties(const CF::Properties& properties, std::vector& outProps); bool completeAllocations(CF::Device_ptr device, const std::vector& duplicates); diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index cd61db4d2..c1f1be995 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -336,12 +336,13 @@ bool createHelper::placeHostCollocation(redhawk::ApplicationDeployment& appDeplo DeploymentList::const_iterator current, ossie::DeviceList& deploymentDevices, const ProcessorList& processorDeps, - const OSList& osDeps) + const OSList& osDeps, + const CF::Properties& deviceRequires) { if (current == components.end()) { // Reached the end of the component deployments; all implementations // should be set, so give it a try - return allocateHostCollocation(appDeployment, components, deploymentDevices, processorDeps, osDeps); + return allocateHostCollocation(appDeployment, components, deploymentDevices, processorDeps, osDeps, deviceRequires); } // Try all of the implementations from the current component for matches @@ -373,9 +374,11 @@ bool createHelper::placeHostCollocation(redhawk::ApplicationDeployment& appDeplo continue; } + redhawk::PropertyMap devRequires(deviceRequires); + devRequires.update(deployment->getDeviceRequires()); // Set this implementation for deployment and recurse one more level deployment->setImplementation(implementation); - if (placeHostCollocation(appDeployment, components, current, deploymentDevices, proc_list, os_list)) { + if (placeHostCollocation(appDeployment, components, current, deploymentDevices, proc_list, os_list, devRequires)) { return true; } } @@ -387,7 +390,8 @@ bool createHelper::allocateHostCollocation(redhawk::ApplicationDeployment& appDe const DeploymentList& components, ossie::DeviceList& deploymentDevices, const ProcessorList& processorDeps, - const OSList& osDeps) + const OSList& osDeps, + const CF::Properties& deviceRequires ) { // Consolidate the allocation properties into a single list CF::Properties allocationProperties = _consolidateAllocations(components); @@ -400,7 +404,7 @@ bool createHelper::allocateHostCollocation(redhawk::ApplicationDeployment& appDe } const std::string requestid = ossie::generateUUID(); - ossie::AllocationResult response = _allocationMgr->allocateDeployment(requestid, allocationProperties, deploymentDevices, appDeployment.getIdentifier(), processorDeps, osDeps); + ossie::AllocationResult response = _allocationMgr->allocateDeployment(requestid, allocationProperties, deploymentDevices, appDeployment.getIdentifier(), processorDeps, osDeps, deviceRequires); if (!response.first.empty()) { // Ensure that all capacities get cleaned up, keeping ownership local // to this scope until it's clear that the device can support all of @@ -1298,8 +1302,14 @@ ossie::AllocationResult createHelper::allocateComponentToDevice(redhawk::Compone substr["nic_allocation::identifier"] = alloc_id; } } - - ossie::AllocationResult response = this->_allocationMgr->allocateDeployment(requestid, allocationProperties, devices, appIdentifier, implementation->getProcessors(), implementation->getOsDeps()); + + ossie::AllocationResult response = this->_allocationMgr->allocateDeployment(requestid, + allocationProperties, + devices, + appIdentifier, + implementation->getProcessors(), + implementation->getOsDeps(), + deployment->getDeviceRequires()); if (allocationProperties.contains("nic_allocation")) { if (!response.first.empty()) { redhawk::PropertyMap query_props; diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index 1a5a3ce61..3c4db4029 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -276,6 +276,11 @@ ComponentDeployment::ComponentDeployment(const SoftPkg* softpkg, RH_NL_TRACE("ApplicationFactory_impl", "Setting affinity options"); affinityOptions = ossie::getAffinityOptions(instantiation->getAffinity()); } + + if (!instantiation->getDeviceRequires().empty()) { + RH_NL_TRACE("ApplicationFactory_impl", "Getting devicerequires property set"); + ossie::convertComponentProperties(instantiation->getDeviceRequires(),deviceRequires); + } } const std::string& ComponentDeployment::getIdentifier() const @@ -414,6 +419,10 @@ float ComponentDeployment::getCpuReservation() const return *cpuReservation; } +redhawk::PropertyMap ComponentDeployment::getDeviceRequires() const { + return deviceRequires; +} + redhawk::PropertyMap ComponentDeployment::getAllocationContext() const { redhawk::PropertyMap properties; diff --git a/redhawk/src/control/sdr/dommgr/Deployment.h b/redhawk/src/control/sdr/dommgr/Deployment.h index dd6e5c19e..636f80fc5 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.h +++ b/redhawk/src/control/sdr/dommgr/Deployment.h @@ -159,6 +159,8 @@ namespace redhawk { std::string getLoggingConfiguration() const; + redhawk::PropertyMap getDeviceRequires() const; + redhawk::ApplicationComponent* getApplicationComponent(); void setApplicationComponent(redhawk::ApplicationComponent* appComponent); @@ -214,6 +216,7 @@ namespace redhawk { std::string nicAssignment; ossie::optional_value cpuReservation; redhawk::PropertyMap affinityOptions; + redhawk::PropertyMap deviceRequires; }; } diff --git a/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp b/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp index bd87a6fce..1a95564a8 100644 --- a/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp @@ -1028,18 +1028,26 @@ void DomainManager_impl::_local_registerDeviceManager (CF::DeviceManager_ptr dev } addDeviceMgr (deviceMgr); - + node = findDeviceManagerById(identifier); CORBA::String_var devMgrLabel; try { mountDeviceMgrFileSys(deviceMgr); LOG_TRACE(DomainManager_impl, "Getting connections from DeviceManager DCD"); - DeviceManagerConfiguration dcdParser; + DeviceManagerConfiguration *dcdParser; + DeviceManagerConfiguration _dcdParser; try { CF::FileSystem_var devMgrFileSys = deviceMgr->fileSys(); CORBA::String_var profile = deviceMgr->deviceConfigurationProfile(); File_stream dcd(devMgrFileSys, profile); - dcdParser.load(dcd); + if ( node != _registeredDeviceManagers.end() ) { + node->dcd.load(dcd); + dcdParser = &(node->dcd); + } + else { + _dcdParser.load(dcd); + dcdParser = &_dcdParser; + } dcd.close(); } catch ( ossie::parser_error& e ) { std::string parser_error_line = ossie::retrieveParserErrorLineNumber(e.what()); @@ -1047,11 +1055,11 @@ void DomainManager_impl::_local_registerDeviceManager (CF::DeviceManager_ptr dev throw(CF::DomainManager::RegisterError()); } - const std::vector& connections = dcdParser.getConnections(); + const std::vector& connections = dcdParser->getConnections(); for (size_t ii = 0; ii < connections.size(); ++ii) { try { - _connectionManager.addConnection(dcdParser.getName(), connections[ii]); + _connectionManager.addConnection(dcdParser->getName(), connections[ii]); } catch (const ossie::InvalidConnection& ex) { LOG_ERROR(DomainManager_impl, "Ignoring unresolvable connection: " << ex.what()); } @@ -2484,22 +2492,12 @@ void DomainManager_impl::parseDeviceProfile (ossie::DeviceNode& node) // Override with values from the DCD LOG_TRACE(DomainManager_impl, "Parsing DCD overrides for device " << node.identifier); - ossie::DeviceManagerConfiguration dcd; const std::string deviceManagerProfile = ossie::corba::returnString(node.devMgr.deviceManager->deviceConfigurationProfile()); - try { - File_stream dcd_file(devMgrFS, deviceManagerProfile.c_str()); - dcd.load(dcd_file); - } catch (const ossie::parser_error& error) { - std::string parser_error_line = ossie::retrieveParserErrorLineNumber(error.what()); - LOG_WARN(DomainManager_impl, "Error parsing DCD: " << deviceManagerProfile << " overrides for Device: " << node.identifier << ". " << parser_error_line << " The XML parser returned the following error: " << error.what()); - } catch (...) { - LOG_WARN(DomainManager_impl, "Unable to cache DCD overrides for Device: " << node.identifier); - } - - - const ComponentInstantiation* instantiation = findComponentInstantiation(dcd.getComponentPlacements(), node.identifier); + const ComponentInstantiation* instantiation = findComponentInstantiation(node.devMgr.dcd.getComponentPlacements(), node.identifier); if (instantiation) { node.prf.override(instantiation->properties); + ossie::convertComponentProperties( instantiation->getDeployerRequires(), + node.requiresProps ); } else { LOG_WARN(DomainManager_impl, "Unable to find device " << node.identifier << " in DCD"); } diff --git a/redhawk/src/control/sdr/dommgr/PersistenceStore.h b/redhawk/src/control/sdr/dommgr/PersistenceStore.h index b37dd2c96..05e9707f4 100644 --- a/redhawk/src/control/sdr/dommgr/PersistenceStore.h +++ b/redhawk/src/control/sdr/dommgr/PersistenceStore.h @@ -27,6 +27,8 @@ #include #include #include +#include +#include #include "connectionSupport.h" @@ -44,6 +46,7 @@ namespace ossie { std::string identifier; std::string label; CF::DeviceManager_var deviceManager; + DeviceManagerConfiguration dcd; }; class DomainManagerNode { @@ -70,6 +73,7 @@ namespace ossie { ossie::SoftPkg spd; ossie::Properties prf; std::string implementationId; + redhawk::PropertyMap requiresProps; CF::LoadableDevice_var loadableDevice; CF::ExecutableDevice_var executableDevice; diff --git a/redhawk/src/control/sdr/dommgr/createHelper.h b/redhawk/src/control/sdr/dommgr/createHelper.h index 705709505..eeee8eb68 100644 --- a/redhawk/src/control/sdr/dommgr/createHelper.h +++ b/redhawk/src/control/sdr/dommgr/createHelper.h @@ -115,7 +115,8 @@ class createHelper DeploymentList::const_iterator current, ossie::DeviceList& deploymentDevices, const ProcessorList& processorDeps=ProcessorList(), - const OSList& osDeps=OSList()); + const OSList& osDeps=OSList(), + const CF::Properties& deviceRequires=CF::Properties()); void _handleUsesDevices(redhawk::ApplicationDeployment& appDeployment, const std::string& appName); std::vector _getFailedUsesDevices(const std::vector& usesDevices, @@ -146,7 +147,8 @@ class createHelper const DeploymentList& components, ossie::DeviceList& deploymentDevices, const ProcessorList& processorDeps, - const OSList& osDeps); + const OSList& osDeps, + const CF::Properties& = CF::Properties() ); bool resolveSoftpkgDependencies(redhawk::ApplicationDeployment& appDeployment, redhawk::SoftPkgDeployment* deployment, diff --git a/redhawk/src/testing/sdr/dev/nodes/test_GPP_green/DeviceManager.dcd.xml b/redhawk/src/testing/sdr/dev/nodes/test_GPP_green/DeviceManager.dcd.xml index 59fe31632..c59cae8d1 100644 --- a/redhawk/src/testing/sdr/dev/nodes/test_GPP_green/DeviceManager.dcd.xml +++ b/redhawk/src/testing/sdr/dev/nodes/test_GPP_green/DeviceManager.dcd.xml @@ -20,7 +20,7 @@ with this program. If not, see http://www.gnu.org/licenses/. --> - + @@ -32,10 +32,10 @@ with this program. If not, see http://www.gnu.org/licenses/. - - GPP_1 + + test_GPP_green::GPP_1 - + diff --git a/redhawk/src/testing/sdr/dev/nodes/test_GPP_red/DeviceManager.dcd.xml b/redhawk/src/testing/sdr/dev/nodes/test_GPP_red/DeviceManager.dcd.xml index da67d01b8..7c871e729 100644 --- a/redhawk/src/testing/sdr/dev/nodes/test_GPP_red/DeviceManager.dcd.xml +++ b/redhawk/src/testing/sdr/dev/nodes/test_GPP_red/DeviceManager.dcd.xml @@ -1,26 +1,6 @@ - - - + @@ -32,11 +12,11 @@ with this program. If not, see http://www.gnu.org/licenses/. - - GPP_1 + + test_GPP_red::GPP_1 - - + + diff --git a/redhawk/src/testing/sdr/dom/waveforms/device_requires_green/device_requires_green.sad.xml b/redhawk/src/testing/sdr/dom/waveforms/device_requires_green/device_requires_green.sad.xml new file mode 100644 index 000000000..f12b1cb1a --- /dev/null +++ b/redhawk/src/testing/sdr/dom/waveforms/device_requires_green/device_requires_green.sad.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + SimpleComponent_Green + + + + + + + + + + + + + diff --git a/redhawk/src/testing/sdr/dom/waveforms/device_requires/device_requires.sad.xml b/redhawk/src/testing/sdr/dom/waveforms/device_requires_multicolor/device_requires_multicolor.sad.xml similarity index 72% rename from redhawk/src/testing/sdr/dom/waveforms/device_requires/device_requires.sad.xml rename to redhawk/src/testing/sdr/dom/waveforms/device_requires_multicolor/device_requires_multicolor.sad.xml index 5cbf8e232..5854961ff 100644 --- a/redhawk/src/testing/sdr/dom/waveforms/device_requires/device_requires.sad.xml +++ b/redhawk/src/testing/sdr/dom/waveforms/device_requires_multicolor/device_requires_multicolor.sad.xml @@ -19,7 +19,7 @@ You should have received a copy of the GNU Lesser General Public License along with this program. If not, see http://www.gnu.org/licenses/. --> - + @@ -28,31 +28,31 @@ with this program. If not, see http://www.gnu.org/licenses/. - - SimpleComponent_1 + + SimpleComponent_Red - + - - + + - - SimpleComponent_2 + + SimpleComponent_Green - + - + - + diff --git a/redhawk/src/testing/sdr/dom/waveforms/device_requires_red/device_requires_red.sad.xml b/redhawk/src/testing/sdr/dom/waveforms/device_requires_red/device_requires_red.sad.xml new file mode 100644 index 000000000..99a848495 --- /dev/null +++ b/redhawk/src/testing/sdr/dom/waveforms/device_requires_red/device_requires_red.sad.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + SimpleComponent_Red + + + + + + + + + + + + + + diff --git a/redhawk/src/testing/tests/test_08_DeployerRequires.py b/redhawk/src/testing/tests/test_08_DeployerRequires.py index af8229b3c..a02c92a9f 100644 --- a/redhawk/src/testing/tests/test_08_DeployerRequires.py +++ b/redhawk/src/testing/tests/test_08_DeployerRequires.py @@ -27,42 +27,279 @@ class DeviceRequires(scatest.CorbaTestCase): def setUp(self): self._app = None + self._red_app = None + self._green_app = None def tearDown(self): if self._app: self._app.stop() self._app.releaseObject() + if self._red_app: + self._red_app.stop() + self._red_app.releaseObject() + + if self._green_app: + self._green_app.stop() + self._green_app.releaseObject() + # Do all application shutdown before calling the base class tearDown, # or failures will probably occur. scatest.CorbaTestCase.tearDown(self) - def _createApp(self, app): + def _createApp(self, appName, exc=None): + self.assertNotEqual(self._domMgr, None) + app=None + + try: + sadpath = '/waveforms/'+appName+'/'+appName+'.sad.xml' + self._domMgr.installApplication(sadpath) + except Exception, e: + return app + + appFact=None + for x in self._domMgr._get_applicationFactories(): + if x._get_name() == appName: + appFact = x + + self.assertNotEqual(appFact, None) + if exc: + self.assertRaises(exc, appFact.create, appFact._get_name(), [], []) + else: + try: + app = appFact.create(appFact._get_name(), [], []) + except: + self.fail("Did not create application ") + return app + + def test_norequired_nocolor(self): + domBooter, self._domMgr = self.launchDomainManager() + devBooter, self._devMgr = self.launchDeviceManager("/nodes/test_GPP_node/DeviceManager.dcd.xml") + self.assertNotEqual(self._domMgr, None) self.assertNotEqual(self._devMgr, None) - sadpath = '/waveforms/'+app+'/'+app+'.sad.xml' - self._domMgr.installApplication(sadpath) - self.assertEqual(len(self._domMgr._get_applicationFactories()), 1) - appFact = self._domMgr._get_applicationFactories()[0] + self._app = self._createApp('device_requires_multicolor') + + self.assertNotEqual(self._app, None) + xx=self._app.query([]) - try: - self._app = appFact.create(appFact._get_name(), [], []) - except: - self.fail("Did not create application ") - def test_createNoDeployerRequires(self): + def test_norequired_redprovided(self): domBooter, self._domMgr = self.launchDomainManager() devBooter, self._devMgr = self.launchDeviceManager("/nodes/test_GPP_node/DeviceManager.dcd.xml") self.assertNotEqual(self._domMgr, None) self.assertNotEqual(self._devMgr, None) - self._createApp('device_requires') + self._app = self._createApp('device_requires_red') + + self.assertNotEqual(self._app, None) + xx=self._app.query([]) + + def test_norequired_greeprovided(self): + domBooter, self._domMgr = self.launchDomainManager() + devBooter, self._devMgr = self.launchDeviceManager("/nodes/test_GPP_node/DeviceManager.dcd.xml") + + self.assertNotEqual(self._domMgr, None) + self.assertNotEqual(self._devMgr, None) + + self._app = self._createApp('device_requires_green') + + self.assertNotEqual(self._app, None) + xx=self._app.query([]) + + def test_redrequired_redprovided(self): + domBooter, self._domMgr = self.launchDomainManager() + redBooter, self._rednode = self.launchDeviceManager("/nodes/test_GPP_red/DeviceManager.dcd.xml") + + self.assertNotEqual(self._domMgr, None) + self.assertNotEqual(self._rednode, None) + + self._app = self._createApp('device_requires_red') + + self.assertNotEqual(self._app, None) + xx=self._app.query([]) + + def test_redrequired_colormismatch(self): + domBooter, self._domMgr = self.launchDomainManager() + redBooter, self._rednode = self.launchDeviceManager("/nodes/test_GPP_red/DeviceManager.dcd.xml") + + self.assertNotEqual(self._domMgr, None) + self.assertNotEqual(self._rednode, None) + + self._app = self._createApp('device_requires_green', CF.ApplicationFactory.CreateApplicationError) + + self.assertEqual(self._app, None) + + def test_redrequired_nonocolors(self): + domBooter, self._domMgr = self.launchDomainManager() + redBooter, self._rednode = self.launchDeviceManager("/nodes/test_GPP_red/DeviceManager.dcd.xml") + + self.assertNotEqual(self._domMgr, None) + self.assertNotEqual(self._rednode, None) + + self._app = self._createApp('device_requires_multicolor', CF.ApplicationFactory.CreateApplicationError) + self.assertEqual(self._app, None) + + + def test_greenrequired_nonocolors(self): + domBooter, self._domMgr = self.launchDomainManager() + greenBooter, self._greennode = self.launchDeviceManager("/nodes/test_GPP_green/DeviceManager.dcd.xml") + + self.assertNotEqual(self._domMgr, None) + self.assertNotEqual(self._greennode, None) + + self._app = self._createApp('device_requires_multicolor', CF.ApplicationFactory.CreateApplicationError) + self.assertEqual(self._app, None) + + def test_greenrequired_redprovided(self): + domBooter, self._domMgr = self.launchDomainManager() + greenBooter, self._greennode = self.launchDeviceManager("/nodes/test_GPP_green/DeviceManager.dcd.xml") + + self.assertNotEqual(self._domMgr, None) + self.assertNotEqual(self._greennode, None) + + self._app = self._createApp('device_requires_red', CF.ApplicationFactory.CreateApplicationError) + self.assertEqual(self._app, None) + + def test_greenrequired_greenprovided(self): + domBooter, self._domMgr = self.launchDomainManager() + greenBooter, self._greennode = self.launchDeviceManager("/nodes/test_GPP_green/DeviceManager.dcd.xml") + + self.assertNotEqual(self._domMgr, None) + self.assertNotEqual(self._greennode, None) + + self._app = self._createApp('device_requires_red', CF.ApplicationFactory.CreateApplicationError) + self.assertEqual(self._app, None) + + def test_redmulti_redprovided(self): + domBooter, self._domMgr = self.launchDomainManager() + redBooter, self._rednode = self.launchDeviceManager("/nodes/test_GPP_red/DeviceManager.dcd.xml") + plainBooter, self._plainnode = self.launchDeviceManager("/nodes/test_GPP_node/DeviceManager.dcd.xml") + + self.assertNotEqual(self._domMgr, None) + self.assertNotEqual(self._rednode, None) + self.assertNotEqual(self._plainnode, None) + + self._app = self._createApp('device_requires_red') + + self.assertNotEqual(self._app, None) + xx=self._app.query([]) + + def test_redmulti_greenprovided(self): + domBooter, self._domMgr = self.launchDomainManager() + redBooter, self._rednode = self.launchDeviceManager("/nodes/test_GPP_red/DeviceManager.dcd.xml") + plainBooter, self._plainnode = self.launchDeviceManager("/nodes/test_GPP_node/DeviceManager.dcd.xml") + + self.assertNotEqual(self._domMgr, None) + self.assertNotEqual(self._rednode, None) + self.assertNotEqual(self._plainnode, None) + + self._app = self._createApp('device_requires_green') self.assertNotEqual(self._app, None) xx=self._app.query([]) + + def test_redmulti_nocolors(self): + domBooter, self._domMgr = self.launchDomainManager() + redBooter, self._rednode = self.launchDeviceManager("/nodes/test_GPP_red/DeviceManager.dcd.xml") + plainBooter, self._plainnode = self.launchDeviceManager("/nodes/test_GPP_node/DeviceManager.dcd.xml") + + self.assertNotEqual(self._domMgr, None) + self.assertNotEqual(self._rednode, None) + self.assertNotEqual(self._plainnode, None) + + self._app = self._createApp('device_requires_multicolor') + + self.assertNotEqual(self._app, None) + xx=self._app.query([]) + + def test_multidevices_nocolors(self): + domBooter, self._domMgr = self.launchDomainManager() + redBooter, self._rednode = self.launchDeviceManager("/nodes/test_GPP_red/DeviceManager.dcd.xml") + greenBooter, self._greennode = self.launchDeviceManager("/nodes/test_GPP_green/DeviceManager.dcd.xml") + plainBooter, self._plainnode = self.launchDeviceManager("/nodes/test_GPP_node/DeviceManager.dcd.xml") + + self.assertNotEqual(self._domMgr, None) + self.assertNotEqual(self._rednode, None) + self.assertNotEqual(self._greennode, None) + self.assertNotEqual(self._plainnode, None) + + self._app = self._createApp('device_requires_multicolor') + + self.assertNotEqual(self._app, None) + xx=self._app.query([]) + + + def test_multidevices_redprovided(self): + domBooter, self._domMgr = self.launchDomainManager() + redBooter, self._rednode = self.launchDeviceManager("/nodes/test_GPP_red/DeviceManager.dcd.xml") + greenBooter, self._greennode = self.launchDeviceManager("/nodes/test_GPP_green/DeviceManager.dcd.xml") + + self.assertNotEqual(self._domMgr, None) + self.assertNotEqual(self._rednode, None) + self.assertNotEqual(self._greennode, None) + + self._app = self._createApp('device_requires_red') + + self.assertNotEqual(self._app, None) + xx=self._app.query([]) + + def test_multidevices_greenprovided(self): + domBooter, self._domMgr = self.launchDomainManager() + redBooter, self._rednode = self.launchDeviceManager("/nodes/test_GPP_red/DeviceManager.dcd.xml") + greenBooter, self._greennode = self.launchDeviceManager("/nodes/test_GPP_green/DeviceManager.dcd.xml") + + self.assertNotEqual(self._domMgr, None) + self.assertNotEqual(self._rednode, None) + self.assertNotEqual(self._greennode, None) + + self._app = self._createApp('device_requires_green') + + self.assertNotEqual(self._app, None) + xx=self._app.query([]) + + + def test_multidevices_redgreenprovided(self): + domBooter, self._domMgr = self.launchDomainManager() + redBooter, self._rednode = self.launchDeviceManager("/nodes/test_GPP_red/DeviceManager.dcd.xml") + greenBooter, self._greennode = self.launchDeviceManager("/nodes/test_GPP_green/DeviceManager.dcd.xml") + + self.assertNotEqual(self._domMgr, None) + self.assertNotEqual(self._rednode, None) + self.assertNotEqual(self._greennode, None) + + self._green_app = self._createApp('device_requires_green') + self.assertNotEqual(self._green_app, None) + + self._red_app = self._createApp('device_requires_red') + self.assertNotEqual(self._red_app, None) + + + def test_multidevices_mixedcolors(self): + domBooter, self._domMgr = self.launchDomainManager() + redBooter, self._rednode = self.launchDeviceManager("/nodes/test_GPP_red/DeviceManager.dcd.xml") + greenBooter, self._greennode = self.launchDeviceManager("/nodes/test_GPP_green/DeviceManager.dcd.xml") + plainBooter, self._plainnode = self.launchDeviceManager("/nodes/test_GPP_node/DeviceManager.dcd.xml") + + self.assertNotEqual(self._domMgr, None) + self.assertNotEqual(self._rednode, None) + self.assertNotEqual(self._greennode, None) + self.assertNotEqual(self._plainnode, None) + + self._app = self._createApp('device_requires_multicolor') + self.assertNotEqual(self._app, None) + + self._green_app = self._createApp('device_requires_green') + self.assertNotEqual(self._green_app, None) + + self._red_app = self._createApp('device_requires_red') + self.assertNotEqual(self._red_app, None) + + + class DeployerRequiresTest(scatest.CorbaTestCase): def setUp(self): self._app = None @@ -72,22 +309,21 @@ def tearDown(self): # or failures will probably occur. scatest.CorbaTestCase.tearDown(self) - def test_launchRedNode(self): + def test_deployerRedNode(self): domBooter, self._domMgr = self.launchDomainManager() devBooter, self._devMgr = self.launchDeviceManager("/nodes/test_GPP_red/DeviceManager.dcd.xml") self.assertNotEqual(self._domMgr, None) self.assertNotEqual(self._devMgr, None) - def test_launchGreenNode(self): + def test_deployerGreenNode(self): domBooter, self._domMgr = self.launchDomainManager() - devBooter, self._devMgr = self.launchDeviceManager("/nodes/test_GPP_red/DeviceManager.dcd.xml") + devBooter, self._devMgr = self.launchDeviceManager("/nodes/test_GPP_green/DeviceManager.dcd.xml") self.assertNotEqual(self._domMgr, None) self.assertNotEqual(self._devMgr, None) - - def test_launchMixNode(self): + def test_deployerMixNode(self): domBooter, self._domMgr = self.launchDomainManager() redBooter, self._rednode = self.launchDeviceManager("/nodes/test_GPP_red/DeviceManager.dcd.xml") greenBooter, self._greennode = self.launchDeviceManager("/nodes/test_GPP_green/DeviceManager.dcd.xml") diff --git a/redhawk/src/xml/dtd/deviceconfiguration.dtd b/redhawk/src/xml/dtd/deviceconfiguration.dtd index a5c23d986..29f72232c 100644 --- a/redhawk/src/xml/dtd/deviceconfiguration.dtd +++ b/redhawk/src/xml/dtd/deviceconfiguration.dtd @@ -106,7 +106,7 @@ with this program. If not, see http://www.gnu.org/licenses/. )+ > + + + + + + - - + + + + + + diff --git a/redhawk/src/xml/xsd/sad.xsd b/redhawk/src/xml/xsd/sad.xsd index a1a71feea..12064911f 100644 --- a/redhawk/src/xml/xsd/sad.xsd +++ b/redhawk/src/xml/xsd/sad.xsd @@ -104,11 +104,16 @@ with this program. If not, see http://www.gnu.org/licenses/. - - + + + + + + + From 6d97d8e564e099ecd9d64d63992f9e2934f69ea6 Mon Sep 17 00:00:00 2001 From: 8530 <8530@vm-131.vsi-corp.com> Date: Tue, 20 Dec 2016 08:08:16 -0500 Subject: [PATCH 0625/1644] fixed issue with logging cfg for devmgr --- redhawk/src/control/sdr/devmgr/main.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/redhawk/src/control/sdr/devmgr/main.cpp b/redhawk/src/control/sdr/devmgr/main.cpp index c54e764be..695957f39 100644 --- a/redhawk/src/control/sdr/devmgr/main.cpp +++ b/redhawk/src/control/sdr/devmgr/main.cpp @@ -228,7 +228,6 @@ int main(int argc, char* argv[]) execparams[param] = argv[ii]; } else if (param == "LOGGING_CONFIG_URI") { logfile_uri = argv[ii]; - execparams[param] = argv[ii]; } else if (pupper == "NOLOGCFG") { useLogCfgResolver=false; } else if (pupper == "CPUBLACKLIST") { @@ -330,10 +329,12 @@ int main(int argc, char* argv[]) } } + // // apply logging settings to the library // ossie::logging::Configure(logcfg_uri, debugLevel, ctx); + execparams["LOGGING_CONFIG_URI"] = const_cast(logfile_uri.c_str()); /////////////////////////////////////////////////////////////////////////// // NO LOG_ STATEMENTS ABOVE THIS POINT From 644f7cd07804cf29f221670642525f6b1756d2bb Mon Sep 17 00:00:00 2001 From: 8530 <8530@vm-131.vsi-corp.com> Date: Tue, 20 Dec 2016 16:18:47 -0500 Subject: [PATCH 0626/1644] add exception probagation to call when application installation thrown and adjusted unit tests accordingly, CF-1520 --- .../control/sdr/dommgr/DomainManager_impl.cpp | 14 ++------- redhawk/src/idl/ossie/CF/cf.idl | 1 + .../testing/tests/test_01_DomainManager.py | 30 +++++++++---------- .../tests/test_04_ApplicationFactory.py | 7 +++++ 4 files changed, 26 insertions(+), 26 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp b/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp index 1a95564a8..ad725a95b 100644 --- a/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp @@ -1588,19 +1588,11 @@ CF::Application_ptr DomainManager_impl::createApplication(const char* profileFil { TRACE_ENTER(DomainManager_impl); - try { - ApplicationFactory_impl factory(profileFileName, _domainName, this); - CF::Application_var application = factory.create(name, initConfiguration, deviceAssignments); - TRACE_EXIT(DomainManager_impl); - return application._retn(); - } - catch( CF::DomainManager::ApplicationInstallationError& ex ) { - LOG_ERROR(DomainManager_impl, "Create application FAILED, reason: " << ex.msg ); - // rethrow as invalid profile... - throw CF::InvalidProfile(); - } + ApplicationFactory_impl factory(profileFileName, _domainName, this); + CF::Application_var application = factory.create(name, initConfiguration, deviceAssignments); TRACE_EXIT(DomainManager_impl); + return application._retn(); } diff --git a/redhawk/src/idl/ossie/CF/cf.idl b/redhawk/src/idl/ossie/CF/cf.idl index 9b10b154d..b930ad41e 100644 --- a/redhawk/src/idl/ossie/CF/cf.idl +++ b/redhawk/src/idl/ossie/CF/cf.idl @@ -805,6 +805,7 @@ module CF { in CF::DeviceAssignmentSequence deviceAssignments ) raises (CF::InvalidProfile,CF::InvalidFileName, + CF::DomainManager::ApplicationInstallationError, CF::ApplicationFactory::CreateApplicationError, CF::ApplicationFactory::CreateApplicationRequestError, CF::ApplicationFactory::CreateApplicationInsufficientCapacityError, diff --git a/redhawk/src/testing/tests/test_01_DomainManager.py b/redhawk/src/testing/tests/test_01_DomainManager.py index edcbaa632..b94c80884 100644 --- a/redhawk/src/testing/tests/test_01_DomainManager.py +++ b/redhawk/src/testing/tests/test_01_DomainManager.py @@ -515,7 +515,7 @@ def test_createApplication_sad_missing_impl(self): self.assertEqual(len(self._domMgr._get_applications()), 1) def test_createApplicationFailures_sad_invalid(self): - self.assertRaises( CF.InvalidProfile, self._domMgr.createApplication, "/waveforms/cpp_deps_wf.OUCH/cpp_deps_wf.sad.xml","",[],[]) + self.assertRaises( (CF.InvalidProfile,CF.DomainManager.ApplicationInstallationError), self._domMgr.createApplication, "/waveforms/cpp_deps_wf.OUCH/cpp_deps_wf.sad.xml","",[],[]) def test_createApplicationFailures_sad_compref_refid(self): wf_name=self.wf_name @@ -524,7 +524,7 @@ def test_createApplicationFailures_sad_compref_refid(self): ## copy bad compref test 1 to sad filex wf_sad=scatest.getSdrPath()+"/dom"+sadfile shutil.copy( wf_sad+".TEST.bad.compref", wf_sad) - self.assertRaises( CF.InvalidProfile, self._domMgr.createApplication, sadfile, "", [], []) + self.assertRaises( (CF.InvalidProfile,CF.DomainManager.ApplicationInstallationError), self._domMgr.createApplication, sadfile, "", [], []) ## reset sad file shutil.copy( wf_sad+".ORIG", wf_sad) @@ -536,7 +536,7 @@ def test_createApplicationFailures_sad_compref_file(self): ## copy bad compref test 1 to sad file wf_sad=scatest.getSdrPath()+"/dom"+sadfile shutil.copy( wf_sad+".TEST.bad.comp.file", wf_sad) - self.assertRaises( CF.InvalidProfile, self._domMgr.createApplication, sadfile, "", [], []) + self.assertRaises( (CF.InvalidProfile,CF.DomainManager.ApplicationInstallationError), self._domMgr.createApplication, sadfile, "", [], []) ## reset sad file shutil.copy( wf_sad+".ORIG", wf_sad) @@ -552,7 +552,7 @@ def test_createApplicationFailures_comp_missing(self): os.remove(comp_spd) except: pass - self.assertRaises( CF.InvalidProfile, self._domMgr.createApplication, sadfile, "", [], []) + self.assertRaises( (CF.InvalidProfile,CF.DomainManager.ApplicationInstallationError), self._domMgr.createApplication, sadfile, "", [], []) ## reset spd file shutil.copy(comp_spd+".ORIG", comp_spd) @@ -568,7 +568,7 @@ def test_createApplicationFailures_comp_missing2(self): os.remove(comp_scd) except: pass - self.assertRaises( CF.InvalidProfile, self._domMgr.createApplication, sadfile, "", [], []) + self.assertRaises( (CF.InvalidProfile,CF.DomainManager.ApplicationInstallationError), self._domMgr.createApplication, sadfile, "", [], []) ## reset file shutil.copy(comp_scd+".ORIG", comp_scd) @@ -583,7 +583,7 @@ def test_createApplicationFailures_comp_missing3(self): os.remove(comp_prf) except: pass - self.assertRaises( CF.InvalidProfile, self._domMgr.createApplication, sadfile, "", [], []) + self.assertRaises( (CF.InvalidProfile,CF.DomainManager.ApplicationInstallationError), self._domMgr.createApplication, sadfile, "", [], []) ## reset file shutil.copy(comp_prf+".ORIG", comp_prf) @@ -594,7 +594,7 @@ def test_createApplicationFailures_comp_bad_prf_file(self): comp_spd=scatest.getSdrPath()+"/dom/components/cpp_with_deps/cpp_with_deps.spd.xml" shutil.copy(comp_spd+".TEST.bad.prf", comp_spd) - self.assertRaises( CF.InvalidProfile, self._domMgr.createApplication, sadfile, "", [], []) + self.assertRaises( (CF.InvalidProfile,CF.DomainManager.ApplicationInstallationError), self._domMgr.createApplication, sadfile, "", [], []) ## reset file shutil.copy(comp_spd+".ORIG", comp_spd) @@ -605,7 +605,7 @@ def test_createApplicationFailures_comp_bad_scd_file(self): comp_spd=scatest.getSdrPath()+"/dom/components/cpp_with_deps/cpp_with_deps.spd.xml" shutil.copy(comp_spd+".TEST.bad.scd", comp_spd) - self.assertRaises( CF.InvalidProfile, self._domMgr.createApplication, sadfile, "", [], []) + self.assertRaises( (CF.InvalidProfile,CF.DomainManager.ApplicationInstallationError), self._domMgr.createApplication, sadfile, "", [], []) ## reset file shutil.copy(comp_spd+".ORIG", comp_spd) @@ -616,7 +616,7 @@ def test_createApplicationFailures_comp_bad_dep_ref(self): comp_spd=scatest.getSdrPath()+"/dom/components/cpp_with_deps/cpp_with_deps.spd.xml" shutil.copy(comp_spd+".TEST.bad.dep", comp_spd) - self.assertRaises( CF.InvalidProfile, self._domMgr.createApplication, sadfile, "", [], []) + self.assertRaises( (CF.InvalidProfile,CF.DomainManager.ApplicationInstallationError), self._domMgr.createApplication, sadfile, "", [], []) ## reset file shutil.copy(comp_spd+".ORIG", comp_spd) @@ -628,7 +628,7 @@ def test_createApplicationFailures_dep_missing(self): dep_dir=scatest.getSdrPath()+"/dom/deps/cpp_dep1" self.dep_dir=dep_dir shutil.move(dep_dir, dep_dir+".XXX") - self.assertRaises( CF.InvalidProfile, self._domMgr.createApplication, sadfile, "", [], []) + self.assertRaises( (CF.InvalidProfile,CF.DomainManager.ApplicationInstallationError), self._domMgr.createApplication, sadfile, "", [], []) ## reset file shutil.move(dep_dir+".XXX", dep_dir) @@ -641,7 +641,7 @@ def test_createApplicationFailures_dep_missing_dep_dir(self): dep_dir=scatest.getSdrPath()+"/dom/deps/cpp_dep1/cpp" self.dep_dir = dep_dir shutil.move(dep_dir, dep_dir+".XXX") - self.assertRaises( CF.InvalidProfile, self._domMgr.createApplication, sadfile, "", [], []) + self.assertRaises( (CF.InvalidProfile,CF.DomainManager.ApplicationInstallationError), self._domMgr.createApplication, sadfile, "", [], []) ## reset file shutil.move( dep_dir+".XXX", dep_dir) @@ -654,7 +654,7 @@ def test_createApplicationFailures_dep_bad_rec_dep_file(self): dep_spd=scatest.getSdrPath()+"/dom/deps/cpp_dep1/cpp_dep1.spd.xml" shutil.copy(dep_spd+".TEST.bad.rec.dep.file", dep_spd) - self.assertRaises( CF.InvalidProfile, self._domMgr.createApplication, sadfile, "", [], []) + self.assertRaises( (CF.InvalidProfile,CF.DomainManager.ApplicationInstallationError), self._domMgr.createApplication, sadfile, "", [], []) ## reset file shutil.copy(dep_spd+".ORIG", dep_spd) @@ -667,7 +667,7 @@ def test_createApplicationFailures_recdep_missing_dir(self): dep_spd=scatest.getSdrPath()+"/dom/deps/cpp_dep2" self.dep_dir=dep_spd shutil.move(dep_spd, dep_spd+".XXX") - self.assertRaises( CF.InvalidProfile, self._domMgr.createApplication, sadfile, "", [], []) + self.assertRaises( (CF.InvalidProfile,CF.DomainManager.ApplicationInstallationError), self._domMgr.createApplication, sadfile, "", [], []) ## reset file shutil.move(dep_spd+".XXX", dep_spd) @@ -680,7 +680,7 @@ def test_createApplicationFailures_recdep_missing_file(self): dep_spd=scatest.getSdrPath()+"/dom/deps/cpp_dep2/cpp_dep2.spd.xml" self.dep_dir=dep_spd shutil.move(dep_spd, dep_spd+".XXX") - self.assertRaises( CF.InvalidProfile, self._domMgr.createApplication, sadfile, "", [], []) + self.assertRaises( (CF.InvalidProfile,CF.DomainManager.ApplicationInstallationError), self._domMgr.createApplication, sadfile, "", [], []) ## reset file shutil.move(dep_spd+".XXX", dep_spd) @@ -693,7 +693,7 @@ def test_createApplicationFailures_recdep_bad_dir(self): dep_spd=scatest.getSdrPath()+"/dom/deps/cpp_dep2/cpp_dep2.spd.xml" shutil.copy( dep_spd+".TEST.bad.dir", dep_spd) - self.assertRaises( CF.InvalidProfile, self._domMgr.createApplication, sadfile, "", [], []) + self.assertRaises( (CF.InvalidProfile,CF.DomainManager.ApplicationInstallationError), self._domMgr.createApplication, sadfile, "", [], []) ## reset file shutil.copy(dep_spd+".ORIG", dep_spd) diff --git a/redhawk/src/testing/tests/test_04_ApplicationFactory.py b/redhawk/src/testing/tests/test_04_ApplicationFactory.py index 354478cad..4370accc4 100644 --- a/redhawk/src/testing/tests/test_04_ApplicationFactory.py +++ b/redhawk/src/testing/tests/test_04_ApplicationFactory.py @@ -407,6 +407,13 @@ def test_NoTimeout(self): self.assertTrue(end_time-begin_time >= 9.5) app.releaseObject() + def test_InvalidFile(self): + nodebooter, domMgr = self.launchDomainManager() + self.assertNotEqual(domMgr, None) + nodebooter, devMgr = self.launchDeviceManager("/nodes/test_BasicTestDevice_node/DeviceManager.dcd.xml") + self.assertNotEqual(devMgr, None) + self.assertRaises(CF.DomainManager.ApplicationInstallationError, domMgr.createApplication, "AppDoesNotExist", 'my_application', [], []) + def test_NonScaCompliant(self): nodebooter, domMgr = self.launchDomainManager() self.assertNotEqual(domMgr, None) From 90216bcb55b76fa8eeed7f3a2d75fbb0240330fb Mon Sep 17 00:00:00 2001 From: 8530 <8530@vm-131.vsi-corp.com> Date: Wed, 21 Dec 2016 07:37:09 -0500 Subject: [PATCH 0627/1644] added threshold ignore property to ignore usage state checks --- GPP/GPP.prf.xml | 5 +++ GPP/cpp/GPP.cpp | 17 ++++++++++ GPP/cpp/struct_props.h | 9 +++++ GPP/tests/test_GPP.py | 76 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 107 insertions(+) diff --git a/GPP/GPP.prf.xml b/GPP/GPP.prf.xml index 462584040..188654e9c 100644 --- a/GPP/GPP.prf.xml +++ b/GPP/GPP.prf.xml @@ -363,6 +363,11 @@ THRESHOLD_NOT_EXCEEDED: The measured value no longer exceeds the configured thr The thresholds that cause a failure for allocations + + false + + + 10 % diff --git a/GPP/cpp/GPP.cpp b/GPP/cpp/GPP.cpp index 6638066f0..59d2c1c0b 100644 --- a/GPP/cpp/GPP.cpp +++ b/GPP/cpp/GPP.cpp @@ -444,6 +444,7 @@ void GPP_i::_init() { // default cycle time setting for updating data model, metrics and state threshold_cycle_time = 500; + thresholds.ignore = false; // // Add property change listeners and allocation modifiers @@ -1515,6 +1516,22 @@ bool GPP_i::_check_limits( const thresholds_struct &thresholds) void GPP_i::updateUsageState() { + // allow for global ignore of thresholds + if ( thresholds.ignore == true ) { + LOG_TRACE(GPP_i, "Ignoring threshold checks "); + if (getPids().size() == 0) { + LOG_TRACE(GPP_i, "Usage State IDLE (trigger) pids === 0... "); + _resetReason(); + setUsageState(CF::Device::IDLE); + } + else { + LOG_TRACE(GPP_i, "Usage State ACTIVE..... "); + _resetReason(); + setUsageState(CF::Device::ACTIVE); + } + return; + } + double sys_idle = system_monitor->get_idle_percent(); double sys_idle_avg = system_monitor->get_idle_average(); double sys_load = system_monitor->get_loadavg(); diff --git a/GPP/cpp/struct_props.h b/GPP/cpp/struct_props.h index 75e5f3f37..458f4afca 100644 --- a/GPP/cpp/struct_props.h +++ b/GPP/cpp/struct_props.h @@ -335,6 +335,7 @@ inline bool operator!= (const threshold_event_struct& s1, const threshold_event_ struct thresholds_struct { thresholds_struct () { + ignore=false; cpu_idle = 10; load_avg = 80; mem_free = 100LL; @@ -347,6 +348,7 @@ struct thresholds_struct { return std::string("thresholds"); }; + bool ignore; float cpu_idle; float load_avg; CORBA::LongLong mem_free; @@ -359,6 +361,9 @@ inline bool operator>>= (const CORBA::Any& a, thresholds_struct& s) { CF::Properties* temp; if (!(a >>= temp)) return false; const redhawk::PropertyMap& props = redhawk::PropertyMap::cast(*temp); + if (props.contains("ignore")) { + if (!(props["ignore"] >>= s.ignore)) return false; + } if (props.contains("cpu_idle")) { if (!(props["cpu_idle"] >>= s.cpu_idle)) return false; } @@ -383,6 +388,8 @@ inline bool operator>>= (const CORBA::Any& a, thresholds_struct& s) { inline void operator<<= (CORBA::Any& a, const thresholds_struct& s) { redhawk::PropertyMap props; + props["ignore"] = s.ignore; + props["cpu_idle"] = s.cpu_idle; props["load_avg"] = s.load_avg; @@ -398,6 +405,8 @@ inline void operator<<= (CORBA::Any& a, const thresholds_struct& s) { } inline bool operator== (const thresholds_struct& s1, const thresholds_struct& s2) { + if (s1.ignore!=s2.ignore) + return false; if (s1.cpu_idle!=s2.cpu_idle) return false; if (s1.load_avg!=s2.load_avg) diff --git a/GPP/tests/test_GPP.py b/GPP/tests/test_GPP.py index 38a5b589f..fe49a2148 100755 --- a/GPP/tests/test_GPP.py +++ b/GPP/tests/test_GPP.py @@ -839,6 +839,82 @@ def test_threshold_usagestate(self): self.assertEquals(ustate, CF.Device.IDLE) + def test_threshold_usagestate_ignored(self): + + self.get_single_nic_interface() + if len(self.nic_list)> 1: + self.runGPP(configure={'nic_interfaces' : [ self.nic_list[0] ]}) + else: + self.runGPP() + + self.comp.thresholds.ignore = True + + # set cpu to be 100.00 ... the check busy state.. + orig_thres = self.comp.thresholds.cpu_idle.queryValue() + self.comp.thresholds.cpu_idle = 100.00 + ustate=None + for i in xrange(6): + ustate= self.comp._get_usageState() + if ustate == CF.Device.BUSY: break + time.sleep(.5) + + self.assertNotEquals(ustate, CF.Device.BUSY) + + # set cpu idle back + self.comp.thresholds.cpu_idle = orig_thres + ustate=None + for i in xrange(6): + ustate= self.comp._get_usageState() + if ustate == CF.Device.IDLE: break + time.sleep(.5) + + self.assertEquals(ustate, CF.Device.IDLE) + + # set mem_free + orig_thres = self.comp.thresholds.mem_free.queryValue() + mem_free = self.comp.memFree.queryValue() + self.comp.thresholds.mem_free = mem_free+2000 + ustate=None + for i in xrange(6): + ustate= self.comp._get_usageState() + if ustate == CF.Device.BUSY: break + time.sleep(.5) + + self.assertNotEquals(ustate, CF.Device.BUSY) + + # set mem_free back + self.comp.thresholds.mem_free = orig_thres + ustate=None + for i in xrange(6): + ustate= self.comp._get_usageState() + if ustate == CF.Device.IDLE: break + time.sleep(.5) + + self.assertEquals(ustate, CF.Device.IDLE) + + + # set load_avg + orig_thres = self.comp.thresholds.load_avg.queryValue() + self.comp.thresholds.load_avg=0.0 + ustate=None + for i in xrange(6): + ustate= self.comp._get_usageState() + if ustate == CF.Device.BUSY: break + time.sleep(.5) + + self.assertNotEquals(ustate, CF.Device.BUSY) + + # set load_avg back + self.comp.thresholds.load_avg = orig_thres + ustate=None + for i in xrange(6): + ustate= self.comp._get_usageState() + if ustate == CF.Device.IDLE: break + time.sleep(.5) + + self.assertEquals(ustate, CF.Device.IDLE) + + def DeployWithAffinityOptions(self, options_list, numa_layout_test, bl_cpus ): self.runGPP() From 540b7b0b64f076f5f179d7d9a7eea0e47b141dbe Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 21 Dec 2016 18:40:39 -0500 Subject: [PATCH 0628/1644] CF-1646 Absorb costs of mutex for atomic disable/enable of input streams into checking for whether to discard the packet, reducing the number of locks per pushPacket --- .../libsrc/cpp/bulkio_in_port.cpp | 54 +++++++++++++------ bulkioInterfaces/libsrc/cpp/bulkio_in_port.h | 5 +- .../libsrc/cpp/bulkio_in_stream.cpp | 21 ++++---- 3 files changed, 51 insertions(+), 29 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp index 266f8daaf..ea64487ef 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.cpp @@ -208,6 +208,14 @@ namespace bulkio { // Discard packets for disabled streams if (!_acceptPacket(streamID, EOS)) { + if (EOS) { + // If this was the only blocking stream, turn off blocking + bool turnOffBlocking = _handleEOS(streamID); + if (turnOffBlocking) { + SCOPED_LOCK lock(dataBufferLock); + blocking = false; + } + } return; } @@ -567,7 +575,7 @@ namespace bulkio { template void InPort::discardPacketsForStream(const std::string& streamID) { - // Caller must hold dataBufferLock + SCOPED_LOCK lock(dataBufferLock); for (typename PacketQueue::iterator ii = packetQueue.begin(); ii != packetQueue.end();) { if ((*ii)->streamID == streamID) { bool eos = (*ii)->EOS; @@ -646,10 +654,9 @@ namespace bulkio { LOG_DEBUG(logger, "Removing stream " << streamID); boost::mutex::scoped_lock lock(streamsMutex); - typename StreamMap::iterator stream = streams.find(streamID); - stream->second.close(); + // Remove the current stream, and if there's a pending stream with the same + // stream ID, move it to the active list streams.erase(streamID); - typename std::multimap::iterator next = pendingStreams.find(streamID); if (next != pendingStreams.end()) { LOG_DEBUG(logger, "Moving pending stream " << streamID << " to active"); @@ -679,21 +686,38 @@ namespace bulkio { template bool InPort::_acceptPacket(const std::string& streamID, bool EOS) { - // Acquire dataBufferLock for the duration of this call to ensure that + // Acquire streamsMutex for the duration of this call to ensure that // end-of-stream is handled atomically for disabled streams - SCOPED_LOCK(dataBufferLock); - if (isStreamEnabled(streamID)) { + boost::mutex::scoped_lock lock(streamsMutex); + + // Find the current stream for the stream ID and check whether it's + // enabled + typename StreamMap::iterator stream = streams.find(streamID); + if (stream == streams.end() || stream->second.enabled()) { + return true; + } + + // If there's a pending stream, the packet is designated for that + if (pendingStreams.find(streamID) != pendingStreams.end()) { return true; } + if (EOS) { - // Acknowledge the end-of-stream by removing the disabled stream before - // discarding the packet - removeStream(streamID); - - // If this was the only blocking stream, turn off blocking - bool turnOffBlocking = _handleEOS(streamID); - if (turnOffBlocking) { - blocking = false; + // Acknowledge the end-of-stream by removing the disabled stream + // before discarding the packet + LOG_DEBUG(logger, "Removing stream " << streamID); + stream->second.close(); + streams.erase(stream); + + typename std::multimap::iterator next = pendingStreams.find(streamID); + if (next != pendingStreams.end()) { + LOG_DEBUG(logger, "Moving pending stream " << streamID << " to active"); + StreamType stream = next->second; + streams.insert(*next); + pendingStreams.erase(next); + lock.unlock(); + + streamAdded(stream); } } return false; diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h index 8bc233bcf..aa254fb8e 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h @@ -396,7 +396,7 @@ namespace bulkio { Packet* fetchPacket(const std::string& streamID); // Discard currently queued packets for the given stream ID, up to the - // first end-of-stream; requires caller to hold dataBufferLock + // first end-of-stream void discardPacketsForStream(const std::string& streamID); friend class InputStream; @@ -409,7 +409,8 @@ namespace bulkio { bool isStreamEnabled(const std::string& streamID); // Checks whether the packet should be queued or discarded; also handles - // end-of-stream if the packet is being discarded + // notifying disabled streams of end-of-stream if the packet is being + // discarded bool _acceptPacket(const std::string& streamID, bool EOS); // Stops tracking the SRI for streamID, returning true if the stream was diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp index 99c0e5028..9775c7e14 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp @@ -78,9 +78,9 @@ class InputStream::Impl : public StreamBase::Impl { void enable() { - // Changing the enabled flag requires holding the port's dataBufferLock - // (that controls access to its queue) to ensure that the change is - // atomic with respect to handling end-of-stream packets. Otherwise, + // Changing the enabled flag requires holding the port's streamsMutex + // (that controls access to the stream map) to ensure that the change + // is atomic with respect to handling end-of-stream packets. Otherwise, // there is a race condition between the port's IO thread and the // thread that enables the stream--it could be re-enabled and start // reading in between the port checking whether to discard the packet @@ -88,14 +88,14 @@ class InputStream::Impl : public StreamBase::Impl { // that calls enable is the one doing the reading, it is not necessary // to apply mutual exclusion across the entire public stream API, just // enable/disable. - boost::mutex::scoped_lock lock(_port->dataBufferLock); + boost::mutex::scoped_lock lock(_port->streamsMutex); _enabled = true; } virtual void disable() { // See above re: locking - boost::mutex::scoped_lock lock(_port->dataBufferLock); + boost::mutex::scoped_lock lock(_port->streamsMutex); _enabled = false; // Unless end-of-stream has been received by the port (meaning any further @@ -108,14 +108,11 @@ class InputStream::Impl : public StreamBase::Impl { void close() { - // NB: This method is always called by the port with dataBufferLock held + // NB: This method is always called by the port with streamsMutex held - // If this stream is disabled, consider end-of-stream reported, since - // the stream has already been removed from the port; otherwise, there's - // nothing to do - if (!_enabled) { - _eosState = EOS_REPORTED; - } + // Consider end-of-stream reported, since the stream has already been + // removed from the port; otherwise, there's nothing to do + _eosState = EOS_REPORTED; } virtual bool eos() From 97b058b8b7c0d6bc172f7473a5276b82200e2c57 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 22 Dec 2016 10:59:50 -0500 Subject: [PATCH 0629/1644] Benchmark BulkIO in both CORBA and local transfer modes --- throughput/redhawk-benchmark | 18 ++++++++---- throughput/streams/bulkio/__init__.py | 40 +++++++++++++++++++-------- 2 files changed, 41 insertions(+), 17 deletions(-) diff --git a/throughput/redhawk-benchmark b/throughput/redhawk-benchmark index 0331f6bb4..16cbd5597 100755 --- a/throughput/redhawk-benchmark +++ b/throughput/redhawk-benchmark @@ -338,13 +338,16 @@ if __name__ == '__main__': elif key == '--no-gui': nogui = True - interface_list = ('raw', 'corba', 'bulkio') + interface_list = ('raw', 'corba', 'bulkio-corba', 'bulkio-local') interfaces = [] for arg in args: - if not arg.lower() in interface_list: + name = arg.lower() + if name == 'bulkio': + interfaces.extend(('bulkio-corba', 'bulkio-local')) + elif not name in interface_list: raise SystemExit("unknown interface '%s'" % arg) else: - interfaces.append(arg.lower()) + interfaces.append(name) if not interfaces: interfaces = interface_list @@ -403,9 +406,12 @@ if __name__ == '__main__': elif interface == 'corba': name = 'CORBA' factory = corba.factory(transport) - elif interface == 'bulkio': - name = 'BulkIO' - factory = bulkio.factory(transport) + elif interface == 'bulkio-corba': + name = 'BulkIO (CORBA)' + factory = bulkio.factory(transport, local=False) + elif interface == 'bulkio-local': + name = 'BulkIO (local)' + factory = bulkio.factory(transport, local=True) numa_policy = numa.NumaPolicy(numa_distance) diff --git a/throughput/streams/bulkio/__init__.py b/throughput/streams/bulkio/__init__.py index db00b4234..f6b85a023 100644 --- a/throughput/streams/bulkio/__init__.py +++ b/throughput/streams/bulkio/__init__.py @@ -18,6 +18,10 @@ # along with this program. If not, see http://www.gnu.org/licenses/. # import os +try: + from ossie.utils import sb +except ImportError: + sb = None __all__ = ('factory') @@ -42,11 +46,12 @@ def wrap(self, command, arguments): class BulkioStream(object): - def __init__(self, format, numa_policy): + def __init__(self, format, numa_policy, shared): # TODO: Use NUMA launcher when supported in sandbox for .so components launcher = NumaLauncher(numa_policy) - self.writer = sb.launch(os.path.join(PATH, 'writer/writer.spd.xml')) - self.reader = sb.launch(os.path.join(PATH, 'reader/reader.spd.xml')) + self.shared = shared + self.writer = sb.launch(os.path.join(PATH, 'writer/writer.spd.xml'), shared=self.shared) + self.reader = sb.launch(os.path.join(PATH, 'reader/reader.spd.xml'), shared=self.shared) self.writer.connect(self.reader) self.container = sb.domainless._getSandbox()._getComponentHost() @@ -57,10 +62,16 @@ def stop(self): sb.stop() def get_reader(self): - return self.container._process.pid() + if self.shared: + return self.container._process.pid() + else: + return self.reader._process.pid() def get_writer(self): - return self.container._process.pid() + if self.shared: + return self.container._process.pid() + else: + return self.writer._process.pid() def transfer_size(self, size): self.writer.transfer_length = int(size) @@ -78,18 +89,25 @@ def terminate(self): self.writer.releaseObject() self.reader.releaseObject() -class BulkioStreamFactory(object): +class BulkioCorbaFactory(object): def __init__(self, transport): configfile = 'config/omniORB-%s.cfg' % transport os.environ['OMNIORB_CONFIG'] = os.path.join(PATH, configfile) - from ossie.utils import sb - globals()['sb'] = sb def create(self, format, numa_policy): - return BulkioStream(format, numa_policy) + return BulkioStream(format, numa_policy, False) def cleanup(self): pass -def factory(transport): - return BulkioStreamFactory(transport) +class BulkioLocalFactory(object): + def create(self, format, numa_policy): + return BulkioStream(format, numa_policy, True) + +def factory(transport, local): + if sb is None: + raise ImportError('BulkIO is not available') + if local: + return BulkioLocalFactory() + else: + return BulkioCorbaFactory(transport) From d8e935b3955070b1e839537b3bae900ace7d8718 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 22 Dec 2016 11:15:50 -0500 Subject: [PATCH 0630/1644] Format the .csv filename for BulkIO CORBA and local output to remove spaces and parentheses --- throughput/benchmark/csv.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/throughput/benchmark/csv.py b/throughput/benchmark/csv.py index 1090114fa..1059529af 100644 --- a/throughput/benchmark/csv.py +++ b/throughput/benchmark/csv.py @@ -31,7 +31,7 @@ def add_field(self, key, header=None): self.fields.append((key, header)) def test_started(self, name, **kw): - filename = '%s-%d.csv' % (name.lower(), os.getpid()) + filename = '%s-%d.csv' % (self.make_filename(name), os.getpid()) self.file = open(filename, 'w') print >>self.file, ','.join(title for name, title in self.fields) @@ -40,3 +40,8 @@ def sample_added(self, **stats): def test_complete(self, **kw): self.file.close() + + def make_filename(self, name): + name = name.lower() + name = name.replace('(', '').replace(')', '') + return '-'.join(name.split()) From a269f855662d6a36e148b9ce08d2555da425371d Mon Sep 17 00:00:00 2001 From: 8530 <8530@vm-131.vsi-corp.com> Date: Thu, 22 Dec 2016 16:45:39 -0500 Subject: [PATCH 0631/1644] added support to collocation requests to include usesdevices to allow for collocation of components and devices to a common executabledevice, CF-1595 --- redhawk/src/control/framework/Makefile.am | 4 +- .../src/control/framework/helperFunctions.cpp | 121 +++++++++++++++++- .../control/include/ossie/SoftwareAssembly.h | 5 + .../src/control/include/ossie/UsesDevice.h | 18 +++ .../src/control/include/ossie/ossieSupport.h | 3 + .../control/parser/internal/sad-parser.cpp | 4 + .../src/control/parser/internal/sad-pimpl.cpp | 30 +++++ .../src/control/parser/internal/sad-pimpl.h | 20 +++ redhawk/src/control/parser/internal/sad.map | 1 + redhawk/src/control/sdr/devmgr/Makefile.am | 2 +- .../sdr/dommgr/ApplicationFactory_impl.cpp | 54 +++++++- redhawk/src/xml/dtd/softwareassembly.dtd | 7 +- redhawk/src/xml/xsd/sad.xsd | 12 +- 13 files changed, 269 insertions(+), 12 deletions(-) diff --git a/redhawk/src/control/framework/Makefile.am b/redhawk/src/control/framework/Makefile.am index 9fa964a63..46506fa79 100644 --- a/redhawk/src/control/framework/Makefile.am +++ b/redhawk/src/control/framework/Makefile.am @@ -30,14 +30,14 @@ libossiedomain_la_SOURCES = CorbaGC.cpp \ POACreator.cpp \ prop_utils.cpp -libossiedomain_la_CXXFLAGS = -Wall $(BOOST_CPPFLAGS) $(OMNICOS_CFLAGS) $(OMNIORB_CFLAGS) $(LOG4CXX_FLAGS) $(PERSISTENCE_CFLAGS) +libossiedomain_la_CXXFLAGS = -Wall -I$(OMNIORB_INCLUDEDIR)/omniORB4/internal $(BOOST_CPPFLAGS) $(OMNICOS_CFLAGS) $(OMNIORB_CFLAGS) $(LOG4CXX_FLAGS) $(PERSISTENCE_CFLAGS) libossiedomain_la_LIBADD = $(BOOST_LDFLAGS) $(BOOST_FILESYSTEM_LIB) $(BOOST_SERIALIZATION_LIB) $(BOOST_THREAD_LIB) $(BOOST_SYSTEM_LIB) $(OMNICOS_LIBS) $(OMNIORB_LIBS) $(LOG4CXX_LIBS) $(PERSISTENCE_LIBS) libossiedomain_la_LDFLAGS = -Wall bin_PROGRAMS = nodeBooter nodeBooter_SOURCES = nodebooter.cpp nodeBooter_CXXFLAGS = $(BOOST_CPPFLAGS) -nodeBooter_LDADD = $(BOOST_LDFLAGS) $(BOOST_FILESYSTEM_LIB) $(BOOST_SYSTEM_LIB) ../parser/libossieparser.la ./libossiedomain.la $(top_builddir)/base/framework/libossiecf.la $(top_builddir)/base/framework/idl/libossieidl.la $(OMNICOS_LIBS) $(OMNIORB_LIBS) +nodeBooter_LDADD = $(BOOST_LDFLAGS) $(BOOST_FILESYSTEM_LIB) $(BOOST_REGEX_LIB) $(BOOST_SYSTEM_LIB) ../parser/libossieparser.la ./libossiedomain.la $(top_builddir)/base/framework/libossiecf.la $(top_builddir)/base/framework/idl/libossieidl.la $(OMNICOS_LIBS) $(OMNIORB_LIBS) nodeBooter_LDFLAGS = -static bin_SCRIPTS = nodeCleanup.py diff --git a/redhawk/src/control/framework/helperFunctions.cpp b/redhawk/src/control/framework/helperFunctions.cpp index 1ee6ea87f..c6e9850e5 100644 --- a/redhawk/src/control/framework/helperFunctions.cpp +++ b/redhawk/src/control/framework/helperFunctions.cpp @@ -21,10 +21,20 @@ #include #include - #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include #include namespace fs = boost::filesystem; @@ -51,3 +61,112 @@ std::string ossie::generateUUID() return std::string("DCE:") + strbuf; } + + +static std::string _trim_addr( const std::string &addr, const std::string &exp="(.*):([^:]*)$" ) +{ + std::string ret; + boost::regex expr(exp.c_str()); + boost::smatch what; + if (boost::regex_search(addr, what, expr)) + { + ret = what[1]; + } + return ret; +} + + +static bool _match_remotes( CORBA::Object_ptr aobj, CORBA::Object_ptr bobj) +{ + bool retval=false; + omniIOR *a_ior = aobj->_PR_getobj()->_getIOR(); + omniIOR *b_ior = bobj->_PR_getobj()->_getIOR(); + omniIdentity* a_identity = aobj->_PR_getobj()->_identity(); + omniIdentity* b_identity = bobj->_PR_getobj()->_identity(); + omniRemoteIdentity *a_remote = omniRemoteIdentity::downcast(a_identity); + omniRemoteIdentity *b_remote = omniRemoteIdentity::downcast(b_identity); + if ( a_remote != NULL and b_remote != NULL ) { + omni::Rope *a_rope = a_remote->rope(); + omni::Rope *b_rope = b_remote->rope(); + RH_NL_TRACE("redhawk.corba.internal", "Rope A: " << a_rope << " Rope B: " << b_rope ); + if ( a_rope != NULL and b_rope != NULL and + a_rope == b_rope ) { + RH_NL_TRACE("redhawk.corba.internal", "Identities Same Rope == Same Remote Host."); + retval = true; + } + } + + // last ditch.. try IORInfo address list resolution + if ( !retval and a_ior and b_ior ) { + omniIOR::IORInfo *a_iorinfo = a_ior->getIORInfo(); + omniIOR::IORInfo *b_iorinfo = b_ior->getIORInfo(); + const omni::giopAddressList &a_addrs = a_iorinfo->addresses(); + const omni::giopAddressList &b_addrs = b_iorinfo->addresses(); + + omni::giopAddressList::const_iterator i, i_last, j, j_last, j_first; + i = a_addrs.begin(); + i_last = a_addrs.end(); + j_first= b_addrs.begin(); + j_last = b_addrs.end(); + if ( a_addrs.size() > b_addrs.size() ) { + i = b_addrs.begin(); + i_last = b_addrs.end(); + j_first = a_addrs.begin(); + j_last = a_addrs.end(); + } + + for (; i != i_last; i++) { + // try to match address space.. remove port string has + std::string a_addr = _trim_addr((*i)->address()); + j = j_first; + for (; j != j_last; j++) { + std::string b_addr = _trim_addr((*j)->address()); + RH_NL_TRACE("redhawk.corba.internal", "Identities A addr: " << a_addr << " B addr: " << b_addr ); + if ( a_addr == b_addr) { retval=true; return retval; } + } + } + } + + return retval; +} + + +bool ossie::sameHost(CORBA::Object_ptr aobj, CORBA::Object_ptr bobj) +{ + bool retval=false; + // if both identifies are the same + omniIdentity* a_identity = aobj->_PR_getobj()->_identity(); + omniIdentity* b_identity = bobj->_PR_getobj()->_identity(); + if ( a_identity->is_equivalent(b_identity) == true ) { + RH_NL_TRACE("redhawk.corba.internal", "Same identifies, so same host"); + retval = true; + } + else { + // if both identities are in the same process space then + // they are on the same host + if ( a_identity->inThisAddressSpace() and + b_identity->inThisAddressSpace() ) { + RH_NL_TRACE("redhawk.corba.internal", "Identifies Same address space..."); + retval = true; + } + else { + // if both identities processes then are on the same host + omniInProcessIdentity *a_proc = omniInProcessIdentity::downcast(a_identity); + omniInProcessIdentity *b_proc = omniInProcessIdentity::downcast(b_identity); + if ( a_proc != NULL and b_proc != NULL ) { + RH_NL_TRACE("redhawk.corba.internal", "Objects have ProcessIdentities, they are on same LOCAL HOST."); + retval= true; + } + else { + retval=_match_remotes( aobj, bobj ); + if ( retval ) { + RH_NL_TRACE("redhawk.corba.internal", "Remote Identities are on the SAME HOST."); + } + else { + RH_NL_TRACE("redhawk.corba.internal", "Remote Identities are different."); + } + } + } + } + return retval; +} diff --git a/redhawk/src/control/include/ossie/SoftwareAssembly.h b/redhawk/src/control/include/ossie/SoftwareAssembly.h index d377d2e2c..a0fed6bb6 100644 --- a/redhawk/src/control/include/ossie/SoftwareAssembly.h +++ b/redhawk/src/control/include/ossie/SoftwareAssembly.h @@ -38,6 +38,7 @@ namespace ossie { std::string id; std::string name; std::vector placements; + std::vector usesdevicerefs; const std::string& getID() const { return id; @@ -51,6 +52,10 @@ namespace ossie { return placements; } + const std::vector& getUsesDeviceRefs() const { + return usesdevicerefs; + } + const ComponentInstantiation* getInstantiation(const std::string& refid) const; }; diff --git a/redhawk/src/control/include/ossie/UsesDevice.h b/redhawk/src/control/include/ossie/UsesDevice.h index 2f14efb41..0dd47b6bc 100644 --- a/redhawk/src/control/include/ossie/UsesDevice.h +++ b/redhawk/src/control/include/ossie/UsesDevice.h @@ -27,6 +27,24 @@ #include "PropertyRef.h" namespace ossie { + + class UsesDeviceRef { + public: + std::string id; + + const std::string& getID() const { + return id; + } + + }; + + inline std::ostream& operator<<(std::ostream& out, const UsesDeviceRef& usesdev) + { + out << "UsesDeviceRef id: " << usesdev.id; + return out; + } + + class UsesDevice { public: std::string id; diff --git a/redhawk/src/control/include/ossie/ossieSupport.h b/redhawk/src/control/include/ossie/ossieSupport.h index 7ca164fb1..ed641e1e5 100644 --- a/redhawk/src/control/include/ossie/ossieSupport.h +++ b/redhawk/src/control/include/ossie/ossieSupport.h @@ -23,6 +23,7 @@ #define ORBSUPPORT_H #include +#include /* The ossieSupport namespace contains useful functions used throughout the @@ -40,5 +41,7 @@ namespace ossie std::string generateUUID(); + bool sameHost( CORBA::Object_ptr aobj, CORBA::Object_ptr bobj ); + } // Close ossieSupport Namespace #endif diff --git a/redhawk/src/control/parser/internal/sad-parser.cpp b/redhawk/src/control/parser/internal/sad-parser.cpp index d39bee7c9..44cdfb9b0 100644 --- a/redhawk/src/control/parser/internal/sad-parser.cpp +++ b/redhawk/src/control/parser/internal/sad-parser.cpp @@ -73,6 +73,7 @@ ossie::internalparser::parseSAD(std::istream& input) throw (ossie::parser_error) ::sad::loggingconfig_pimpl loggingconfig_p; ::sad::devicerequires_pimpl devicerequires_p; ::sad::idvalue_pimpl idvalue_p; + ::sad::usesdeviceref_pimpl usesdeviceref_p; // Connect the parsers together. @@ -163,9 +164,12 @@ ossie::internalparser::parseSAD(std::istream& input) throw (ossie::parser_error) namingservice_p.parsers (string_p); hostcollocation_p.parsers (componentplacement_p, + usesdeviceref_p, string_p, string_p); + usesdeviceref_p.parsers (string_p); + assemblycontroller_p.parsers (componentinstantiationref_p); componentinstantiationref_p.parsers (string_p); diff --git a/redhawk/src/control/parser/internal/sad-pimpl.cpp b/redhawk/src/control/parser/internal/sad-pimpl.cpp index 9da641331..95408fee2 100644 --- a/redhawk/src/control/parser/internal/sad-pimpl.cpp +++ b/redhawk/src/control/parser/internal/sad-pimpl.cpp @@ -931,6 +931,13 @@ namespace sad hostcollocation->placements.push_back(componentplacement); } + + void hostcollocation_pimpl:: + usesdeviceref (const ::ossie::UsesDeviceRef& usesdeviceref) + { + hostcollocation->usesdevicerefs.push_back(usesdeviceref); + } + void hostcollocation_pimpl:: id (const ::std::string& id) { @@ -949,6 +956,29 @@ namespace sad return *hostcollocation; } + + // usesdeviceref_pimpl + // + + void usesdeviceref_pimpl:: + pre () + { + udevref = ossie::UsesDeviceRef(); + } + + void usesdeviceref_pimpl:: + refid (const ::std::string& refid) + { + udevref.id = refid; + } + + const ossie::UsesDeviceRef& usesdeviceref_pimpl:: + post_usesdeviceref () + { + return udevref; + } + + // assemblycontroller_pimpl // diff --git a/redhawk/src/control/parser/internal/sad-pimpl.h b/redhawk/src/control/parser/internal/sad-pimpl.h index 4bd177707..c73c4a7cd 100644 --- a/redhawk/src/control/parser/internal/sad-pimpl.h +++ b/redhawk/src/control/parser/internal/sad-pimpl.h @@ -631,6 +631,9 @@ namespace sad virtual void componentplacement (const ::ossie::ComponentPlacement&); + virtual void + usesdeviceref (const ::ossie::UsesDeviceRef&); + virtual void id (const ::std::string&); @@ -644,6 +647,23 @@ namespace sad std::auto_ptr hostcollocation; }; + class usesdeviceref_pimpl: public virtual usesdeviceref_pskel + { + public: + virtual void + pre (); + + virtual void + refid (const ::std::string&); + + virtual const ossie::UsesDeviceRef& + post_usesdeviceref (); + + private: + ossie::UsesDeviceRef udevref; + }; + + class assemblycontroller_pimpl: public virtual assemblycontroller_pskel { public: diff --git a/redhawk/src/control/parser/internal/sad.map b/redhawk/src/control/parser/internal/sad.map index b972f2d06..595af8824 100644 --- a/redhawk/src/control/parser/internal/sad.map +++ b/redhawk/src/control/parser/internal/sad.map @@ -67,5 +67,6 @@ namespace urn:mil:jpeojtrs:sca:sad { loggingconfig "const ossie::ComponentInstantiation::LoggingConfig&" "const ossie::ComponentInstantiation::LoggingConfig&"; devicerequires "ossie::ComponentPropertyList &" "ossie::ComponentPropertyList &"; idvalue "const ossie::IdValue&" "const ossie::IdValue&"; + usesdeviceref "const ossie::UsesDeviceRef&" "const ossie::UsesDeviceRef&"; } diff --git a/redhawk/src/control/sdr/devmgr/Makefile.am b/redhawk/src/control/sdr/devmgr/Makefile.am index 6b8825a59..b56335c13 100644 --- a/redhawk/src/control/sdr/devmgr/Makefile.am +++ b/redhawk/src/control/sdr/devmgr/Makefile.am @@ -25,6 +25,6 @@ devmgr_PROGRAMS = DeviceManager DeviceManager_SOURCES = main.cpp spdSupport.cpp DeviceManager_impl.cpp DeviceManager_CPPFLAGS = -I../../include -I../../parser -I$(top_srcdir)/base/include -I$(top_srcdir)/base/framework/logging $(BOOST_CPPFLAGS) $(OMNIORB_CFLAGS) $(LOG4CXX_FLAGS) DeviceManager_CXXFLAGS = -Wall -DeviceManager_LDADD = ../../framework/libossiedomain.la ../../parser/libossieparser.la $(top_builddir)/base/framework/libossiecf.la $(top_builddir)/base/framework/idl/libossieidl.la $(OMNIORB_LIBS) $(BOOST_LDFLAGS) $(BOOST_FILESYSTEM_LIB) $(BOOST_SYSTEM_LIB) $(LOG4CXX_LIBS) -ldl +DeviceManager_LDADD = ../../framework/libossiedomain.la ../../parser/libossieparser.la $(top_builddir)/base/framework/libossiecf.la $(top_builddir)/base/framework/idl/libossieidl.la $(OMNIORB_LIBS) $(BOOST_LDFLAGS) $(BOOST_FILESYSTEM_LIB) $(BOOST_REGEX_LIB) $(BOOST_SYSTEM_LIB) $(LOG4CXX_LIBS) -ldl DeviceManager_LDFLAGS = -static diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index c1f1be995..b2054d0e6 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -482,17 +482,63 @@ void createHelper::_placeHostCollocation(redhawk::ApplicationDeployment& appDepl } } + // + // if there are any collocated device requires, get the actual resolved usesdevice + // + std::vector< CF::Device_var > req_usesDevices; + BOOST_FOREACH(const UsesDeviceRef& devref, collocation.getUsesDeviceRefs()) { + std::string refid= devref.getID(); + CF::Device_var dev=appDeployment.lookupDeviceUsedByApplication(refid); + LOG_DEBUG(ApplicationFactory_impl, "UsesDevice for collocation: " << dev->label() ); + if ( !CORBA::is_nil(dev) ) { + req_usesDevices.push_back(dev); + } + } + // Get the executable devices for the domain; if there were any devices // assigned, filter out all other devices ossie::DeviceList deploymentDevices = _executableDevices; if (!assignedDevices.empty()) { - for (ossie::DeviceList::iterator node = deploymentDevices.begin(); node != deploymentDevices.end(); ++node) { + for (ossie::DeviceList::iterator node = deploymentDevices.begin(); node != deploymentDevices.end(); ) { if (std::find(assignedDevices.begin(), assignedDevices.end(), (*node)->identifier) == assignedDevices.end()) { node = deploymentDevices.erase(node); } + else { + node++; + } } } + // if there is a usesdevice in the collocation that filter out the GPPs that we can use. + if ( req_usesDevices.size() > 0 ) { + // from the remaining list of deploymentDevices filter out those that not on the same host + for ( std::vector< CF::Device_var >::iterator dev = req_usesDevices.begin(); dev != req_usesDevices.end(); ++dev) { + LOG_TRACE(ApplicationFactory_impl, "Find GPP for device collocation, device: " << (*dev)->label() << " Number available GPPs:" << deploymentDevices.size() ); + for (ossie::DeviceList::iterator node = deploymentDevices.begin(); node != deploymentDevices.end(); ) { + bool retval = ossie::sameHost( *dev, (*node)->device ); + LOG_TRACE(ApplicationFactory_impl, "Check Collocation, Device: " << (*dev)->label() << " Executable Device: " << (*node)->device->label() << " --> RESULTS:" << retval ); + if ( retval == false ) { + node = deploymentDevices.erase(node); + } + else { + node++; + } + } + } + + if ( deploymentDevices.size() == 0 ) { + ostringstream os; + os << "No Collocated ExecutableDevices for Device: "; + for ( std::vector< CF::Device_var >::iterator dev = req_usesDevices.begin(); dev != req_usesDevices.end(); ++dev) { + os << (*dev)->label(); + if (dev+1 != req_usesDevices.end()) os << ", "; + } + LOG_DEBUG(ApplicationFactory_impl, os.str() ); + throw redhawk::PlacementFailure(collocation, os.str() ); + } + + } + LOG_TRACE(ApplicationFactory_impl, "Placing " << deployments.size() << " components"); if (!placeHostCollocation(appDeployment, deployments, deployments.begin(), deploymentDevices)) { if (_allDevicesBusy(deploymentDevices)) { @@ -814,14 +860,14 @@ CF::Application_ptr createHelper::create ( // Catch invalid device assignments _validateDAS(app_deployment, deviceAssignments); - // Assign all components to devices - assignPlacementsToDevices(app_deployment, deviceAssignments); - // Allocate any usesdevice capacities specified in the SAD file; at this // point, the complete set of component deployments is known, including any // property overrides for allocation context _handleUsesDevices(app_deployment, name); + // Assign all components to devices + assignPlacementsToDevices(app_deployment, deviceAssignments); + // Assign CPU reservations to components app_deployment.applyCpuReservations(specialized_reservations); diff --git a/redhawk/src/xml/dtd/softwareassembly.dtd b/redhawk/src/xml/dtd/softwareassembly.dtd index 6a3bf527b..fc9a13750 100644 --- a/redhawk/src/xml/dtd/softwareassembly.dtd +++ b/redhawk/src/xml/dtd/softwareassembly.dtd @@ -191,12 +191,17 @@ with this program. If not, see http://www.gnu.org/licenses/. name CDATA #IMPLIED> + + + diff --git a/redhawk/src/xml/xsd/sad.xsd b/redhawk/src/xml/xsd/sad.xsd index 12064911f..f2273aa69 100644 --- a/redhawk/src/xml/xsd/sad.xsd +++ b/redhawk/src/xml/xsd/sad.xsd @@ -208,12 +208,18 @@ with this program. If not, see http://www.gnu.org/licenses/. - - - + + + + + + + + + From f1ddaf6f1ea56585b62263c97d8b20a101d39197 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Fri, 30 Dec 2016 14:30:54 -0500 Subject: [PATCH 0632/1644] Added implementation to MessageReceiverCpp to work on 32 and 64 bit processors --- .../dom/components/MessageReceiverCpp/MessageReceiverCpp.spd.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/redhawk/src/testing/sdr/dom/components/MessageReceiverCpp/MessageReceiverCpp.spd.xml b/redhawk/src/testing/sdr/dom/components/MessageReceiverCpp/MessageReceiverCpp.spd.xml index d5149610f..0bf50786e 100644 --- a/redhawk/src/testing/sdr/dom/components/MessageReceiverCpp/MessageReceiverCpp.spd.xml +++ b/redhawk/src/testing/sdr/dom/components/MessageReceiverCpp/MessageReceiverCpp.spd.xml @@ -42,5 +42,6 @@ with this program. If not, see http://www.gnu.org/licenses/. + From 02be1427423dfe6142916b0767c935624355bbd3 Mon Sep 17 00:00:00 2001 From: 8530 <8530@vm-131.vsi-corp.com> Date: Wed, 4 Jan 2017 07:29:12 -0500 Subject: [PATCH 0633/1644] adding synchronous rolling file appender to resolve CF-1215 --- redhawk/src/base/framework/logging/RH_SyncRollingAppender.cpp | 1 + redhawk/src/base/framework/logging/RH_SyncRollingAppender.h | 1 - redhawk/src/testing/loggers/syncappender/.gitignore | 1 - redhawk/src/testing/loggers/syncappender/cleanmem.cpp | 1 + redhawk/src/testing/loggers/syncappender/log4j.appender | 1 - redhawk/src/testing/loggers/syncappender/test_suites.cpp | 2 -- redhawk/src/testing/loggers/syncappender/test_suites.h | 1 - redhawk/src/testing/sdr/logcfg/log4j.sync_appender | 2 -- 8 files changed, 2 insertions(+), 8 deletions(-) diff --git a/redhawk/src/base/framework/logging/RH_SyncRollingAppender.cpp b/redhawk/src/base/framework/logging/RH_SyncRollingAppender.cpp index ddaee1b1f..36d73578b 100644 --- a/redhawk/src/base/framework/logging/RH_SyncRollingAppender.cpp +++ b/redhawk/src/base/framework/logging/RH_SyncRollingAppender.cpp @@ -59,6 +59,7 @@ using namespace log4cxx::helpers; namespace log4cxx { + // // Allows for same naming reference to LogEvent Appender class // diff --git a/redhawk/src/base/framework/logging/RH_SyncRollingAppender.h b/redhawk/src/base/framework/logging/RH_SyncRollingAppender.h index 546bd4284..3f2cf9d42 100644 --- a/redhawk/src/base/framework/logging/RH_SyncRollingAppender.h +++ b/redhawk/src/base/framework/logging/RH_SyncRollingAppender.h @@ -108,7 +108,6 @@ namespace log4cxx ipc::shared_memory_object shm; ipc::mapped_region region; - }; }; // end of namespace diff --git a/redhawk/src/testing/loggers/syncappender/.gitignore b/redhawk/src/testing/loggers/syncappender/.gitignore index c2b1cdd8d..bf5638792 100644 --- a/redhawk/src/testing/loggers/syncappender/.gitignore +++ b/redhawk/src/testing/loggers/syncappender/.gitignore @@ -1,4 +1,3 @@ - Makefile.in Makefile configure diff --git a/redhawk/src/testing/loggers/syncappender/cleanmem.cpp b/redhawk/src/testing/loggers/syncappender/cleanmem.cpp index 65080136e..fca7c1747 100644 --- a/redhawk/src/testing/loggers/syncappender/cleanmem.cpp +++ b/redhawk/src/testing/loggers/syncappender/cleanmem.cpp @@ -28,5 +28,6 @@ int main (int argc, char **argv ) std::cout << ex.what() << std::endl; return -1; } + return 0; } diff --git a/redhawk/src/testing/loggers/syncappender/log4j.appender b/redhawk/src/testing/loggers/syncappender/log4j.appender index a27ec5183..e9782fc52 100644 --- a/redhawk/src/testing/loggers/syncappender/log4j.appender +++ b/redhawk/src/testing/loggers/syncappender/log4j.appender @@ -1,6 +1,5 @@ - #log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n log4j.rootLogger=ALL,stdout, mp diff --git a/redhawk/src/testing/loggers/syncappender/test_suites.cpp b/redhawk/src/testing/loggers/syncappender/test_suites.cpp index ad5fb6a6e..e0a774c41 100644 --- a/redhawk/src/testing/loggers/syncappender/test_suites.cpp +++ b/redhawk/src/testing/loggers/syncappender/test_suites.cpp @@ -19,8 +19,6 @@ CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( test_suite_one, "test_one" ); CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( test_suite_two, "test_two" ); CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( test_suite_three, "test_three" ); - - void test_suite_one::setUp() { diff --git a/redhawk/src/testing/loggers/syncappender/test_suites.h b/redhawk/src/testing/loggers/syncappender/test_suites.h index 8cf31ff81..6bfe2318b 100644 --- a/redhawk/src/testing/loggers/syncappender/test_suites.h +++ b/redhawk/src/testing/loggers/syncappender/test_suites.h @@ -19,7 +19,6 @@ class test_suite_one : public CppUnit::TestFixture void test_two(); log4cxx::LoggerPtr logger; - }; diff --git a/redhawk/src/testing/sdr/logcfg/log4j.sync_appender b/redhawk/src/testing/sdr/logcfg/log4j.sync_appender index 9067aaca4..e90764d7d 100644 --- a/redhawk/src/testing/sdr/logcfg/log4j.sync_appender +++ b/redhawk/src/testing/sdr/logcfg/log4j.sync_appender @@ -1,6 +1,4 @@ - - #log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n log4j.rootLogger=ALL,stdout, mp From 4628d2c7a8aff0aeaf0a7b5603fb6db9cdf87136 Mon Sep 17 00:00:00 2001 From: 8530 <8530@vm-131.vsi-corp.com> Date: Wed, 4 Jan 2017 11:46:17 -0500 Subject: [PATCH 0634/1644] added additional test for configure only, CF-463 --- .../DeviceManager.dcd.xml | 13 ++ .../testing/sdr/dev/services/S2/python/S2.py | 26 ++- .../sdr/dev/services/S2_pre/S2_pre.prf.xml | 13 ++ .../sdr/dev/services/S2_pre/S2_pre.scd.xml | 14 ++ .../sdr/dev/services/S2_pre/S2_pre.spd.xml | 25 +++ .../sdr/dev/services/S2_pre/python/S2_pre.py | 175 ++++++++++++++++++ .../testing/tests/test_01_DeviceManager.py | 23 ++- 7 files changed, 285 insertions(+), 4 deletions(-) create mode 100644 redhawk/src/testing/sdr/dev/services/S2_pre/S2_pre.prf.xml create mode 100644 redhawk/src/testing/sdr/dev/services/S2_pre/S2_pre.scd.xml create mode 100644 redhawk/src/testing/sdr/dev/services/S2_pre/S2_pre.spd.xml create mode 100755 redhawk/src/testing/sdr/dev/services/S2_pre/python/S2_pre.py diff --git a/redhawk/src/testing/sdr/dev/nodes/test_service_startup_node/DeviceManager.dcd.xml b/redhawk/src/testing/sdr/dev/nodes/test_service_startup_node/DeviceManager.dcd.xml index 50c46cc38..e0336b972 100644 --- a/redhawk/src/testing/sdr/dev/nodes/test_service_startup_node/DeviceManager.dcd.xml +++ b/redhawk/src/testing/sdr/dev/nodes/test_service_startup_node/DeviceManager.dcd.xml @@ -11,6 +11,9 @@ + + + @@ -29,6 +32,16 @@ + + + + S2_pre_1 + + + + + + diff --git a/redhawk/src/testing/sdr/dev/services/S2/python/S2.py b/redhawk/src/testing/sdr/dev/services/S2/python/S2.py index 06dcf4f45..78e0ef338 100755 --- a/redhawk/src/testing/sdr/dev/services/S2/python/S2.py +++ b/redhawk/src/testing/sdr/dev/services/S2/python/S2.py @@ -30,9 +30,31 @@ def terminateService(self): pass def configure(self, configProperties): + notSet = [] + error_message = '' + for prop in configProperties: + try: + if self._props.has_id(prop.id) and self._props.isConfigurable(prop.id): + try: + self._props.configure(prop.id, prop.value) + except Exception, e: + self._log.warning("Invalid value provided to configure for property %s: %s", prop.id, e) + notSet.append(prop) + else: + self._log.warning("Tried to configure non-existent, readonly, or property with action not equal to external %s", prop.id) + notSet.append(prop) + except Exception, e: + error_message += str(e) + self._log.exception("Unexpected exception.") + notSet.append(prop) - # TODO - pass + if len(notSet) > 0 and len(notSet) < len(configProperties): + self._log.warning("Configure failed with partial configuration, %s", notSet) + raise CF.PropertySet.PartialConfiguration(notSet) + elif len(notSet) > 0 and len(notSet) >= len(configProperties): + self._log.warning("Configure failed with invalid configuration, %s", notSet) + raise CF.PropertySet.InvalidConfiguration("Failure: "+error_message, notSet) + self._log.trace("configure(%s)", configProperties) def query(self, configProperties): if configProperties == []: diff --git a/redhawk/src/testing/sdr/dev/services/S2_pre/S2_pre.prf.xml b/redhawk/src/testing/sdr/dev/services/S2_pre/S2_pre.prf.xml new file mode 100644 index 000000000..724e67e97 --- /dev/null +++ b/redhawk/src/testing/sdr/dev/services/S2_pre/S2_pre.prf.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/redhawk/src/testing/sdr/dev/services/S2_pre/S2_pre.scd.xml b/redhawk/src/testing/sdr/dev/services/S2_pre/S2_pre.scd.xml new file mode 100644 index 000000000..117aaa6b9 --- /dev/null +++ b/redhawk/src/testing/sdr/dev/services/S2_pre/S2_pre.scd.xml @@ -0,0 +1,14 @@ + + + + 2.2 + + service + + + + + + + + diff --git a/redhawk/src/testing/sdr/dev/services/S2_pre/S2_pre.spd.xml b/redhawk/src/testing/sdr/dev/services/S2_pre/S2_pre.spd.xml new file mode 100644 index 000000000..e0f1422fb --- /dev/null +++ b/redhawk/src/testing/sdr/dev/services/S2_pre/S2_pre.spd.xml @@ -0,0 +1,25 @@ + + + + + + null + + + + + + + + + The implementation contains descriptive information about the template for a software component. + + + python/S2_pre.py + + + + + + + diff --git a/redhawk/src/testing/sdr/dev/services/S2_pre/python/S2_pre.py b/redhawk/src/testing/sdr/dev/services/S2_pre/python/S2_pre.py new file mode 100755 index 000000000..8b4694388 --- /dev/null +++ b/redhawk/src/testing/sdr/dev/services/S2_pre/python/S2_pre.py @@ -0,0 +1,175 @@ +#!/usr/bin/env python +# +# AUTO-GENERATED +# +# Source: S2_pre.spd.xml + +import sys, signal, copy, os +import logging + +from ossie.cf import CF, CF__POA #@UnusedImport +from ossie.service import start_service +from omniORB import any, CORBA, URI, PortableServer + +from ossie.cf import CF +from ossie.cf import CF__POA +from ossie import properties; + + +class S2_pre(CF__POA.PropertySet): + + def __init__(self, name="S2_pre", execparams={}): + self.name = name + self._log = logging.getLogger(self.name) + self._props = properties.PropertyStorage(self, (), execparams) + self._props._addProperty( S2_pre.p1 ) + self._props._addProperty( S2_pre.p2) + self._props.initialize() + + def terminateService(self): + pass + + def configure(self, configProperties): + notSet = [] + error_message = '' + for prop in configProperties: + try: + if self._props.has_id(prop.id) and self._props.isConfigurable(prop.id): + try: + self._props.configure(prop.id, prop.value) + except Exception, e: + self._log.warning("Invalid value provided to configure for property %s: %s", prop.id, e) + notSet.append(prop) + else: + self._log.warning("Tried to configure non-existent, readonly, or property with action not equal to external %s", prop.id) + notSet.append(prop) + except Exception, e: + error_message += str(e) + self._log.exception("Unexpected exception.") + notSet.append(prop) + + if len(notSet) > 0 and len(notSet) < len(configProperties): + self._log.warning("Configure failed with partial configuration, %s", notSet) + raise CF.PropertySet.PartialConfiguration(notSet) + elif len(notSet) > 0 and len(notSet) >= len(configProperties): + self._log.warning("Configure failed with invalid configuration, %s", notSet) + raise CF.PropertySet.InvalidConfiguration("Failure: "+error_message, notSet) + self._log.trace("configure(%s)", configProperties) + + + def query(self, configProperties): + if configProperties == []: + self._log.trace("query all properties") + try: + rv = [] + for propid in self._props.keys(): + if self._props.has_id(propid) and self._props.isQueryable(propid): + try: + value = self._props.query(propid) + except Exception, e: + self._log.error('Failed to query %s: %s', propid, e) + value = any.to_any(None) + prp = self._props.getPropDef(propid) + if type(prp) == properties.struct_property: + newvalval = [] + for v in value.value(): + if prp.fields[v.id][1].optional == True: + if isinstance(v.value.value(), list): + if v.value.value() != []: + newvalval.append(v) + else: + if v.value.value() != None: + newvalval.append(v) + else: + newvalval.append(v) + value = CORBA.Any(value.typecode(), newvalval) + + rv.append(CF.DataType(propid, value)) + except: + raise + + # otherwise get only the requested ones + else: + self._log.trace("query %s properties", len(configProperties)) + try: + unknownProperties = [] + for prop in configProperties: + if self._props.has_id(prop.id) and self._props.isQueryable(prop.id): + try: + prop.value = self._props.query(prop.id) + except Exception, e: + self._log.error('Failed to query %s: %s', prop.id, e) + prp = self._props.getPropDef(prop.id) + if type(prp) == properties.struct_property: + newvalval = [] + for v in prop.value.value(): + if prp.fields[v.id][1].optional == True: + if isinstance(v.value.value(), list): + if v.value.value() != []: + newvalval.append(v) + else: + if v.value.value() != None: + newvalval.append(v) + else: + newvalval.append(v) + prop.value = CORBA.Any(prop.value.typecode(), newvalval) + else: + self._log.warning("property %s cannot be queried. valid Id: %s", + prop.id, self._props.has_id(prop.id)) + unknownProperties.append(prop) + except: + raise + + if len(unknownProperties) > 0: + self._log.warning("query called with invalid properties %s", unknownProperties) + raise CF.UnknownProperties(unknownProperties) + + rv = configProperties + self._log.trace("query -> %s properties", len(rv)) + return rv + + def initializeProperties(self, ctorProps): + notSet = [] + for prop in ctorProps: + try: + if self._props.has_id(prop.id) and self._props.isProperty(prop.id): + try: + # run configure on property.. disable callback feature + self._props.construct(prop.id, prop.value) + except ValueError, e: + self._log.warning("Invalid value provided to construct for property %s %s", prop.id, e) + notSet.append(prop) + else: + self._log.warning("Tried to construct non-existent, readonly, or property with action not equal to external %s", prop.id) + notSet.append(prop) + except Exception, e: + self._log.exception("Unexpected exception.") + notSet.append(prop) + + def registerPropertyListener(self, obj, prop_ids, interval): + # TODO + pass + + def unregisterPropertyListener(self, id): + # TODO + pass + + p1 = properties.simple_property(id_="p1", + name="p1", + type_="string", + mode="readwrite", + action="external", + kinds=("configure",), + description=""" """) + + + p2 = properties.simple_property(id_="p2", + name="p2", + type_="long", + mode="readwrite", + action="external", + kinds=("configure",)) + + +if __name__ == '__main__': + start_service(S2_pre, thread_policy=PortableServer.SINGLE_THREAD_MODEL) diff --git a/redhawk/src/testing/tests/test_01_DeviceManager.py b/redhawk/src/testing/tests/test_01_DeviceManager.py index cf4f8fac1..08c011e8d 100644 --- a/redhawk/src/testing/tests/test_01_DeviceManager.py +++ b/redhawk/src/testing/tests/test_01_DeviceManager.py @@ -1306,17 +1306,36 @@ def test_Service_Startup(self): d=redhawk.attach(self._domainManager._get_name()) svc=None + svc_pre=None for s in d.services: if s._id == 'S2_1': svc = s + if s._id == 'S2_pre_1': + svc_pre = s self.assertNotEqual(svc, None) + self.assertNotEqual(svc_pre, None) # get p1 from service - res=s.query([CF.DataType(id='p1', value=any.to_any(None))]) + res=svc.query([CF.DataType(id='p1', value=any.to_any(None))]) p1=properties.props_to_dict(res) self.assertEqual(p1['p1'],'p1 set by DCD file') # get p2 from service - res=s.query([CF.DataType(id='p2', value=any.to_any(None))]) + res=svc.query([CF.DataType(id='p2', value=any.to_any(None))]) p1=properties.props_to_dict(res) self.assertEqual(p1['p2'],123456) + + + # get p1 from service + res=svc_pre.query([CF.DataType(id='p1', value=any.to_any(None))]) + p1=properties.props_to_dict(res) + self.assertEqual(p1['p1'],'pre p1 set by DCD file') + + # get p2 from service + res=svc_pre.query([CF.DataType(id='p2', value=any.to_any(None))]) + p1=properties.props_to_dict(res) + self.assertEqual(p1['p2'],654321) + + self.assertRaises(CF.PropertySet.InvalidConfiguration, svc.configure, [CF.DataType(id='fake', value=any.to_any(None))] ) + + self.assertRaises(CF.PropertySet.InvalidConfiguration, svc_pre.configure, [CF.DataType(id='fake', value=any.to_any(None))] ) From 95ff59e6a80dc02c587954b3feba2eeed1bac3c6 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Sat, 7 Jan 2017 13:32:01 -0500 Subject: [PATCH 0635/1644] Refs CF-1420. C++ support for timestamped queries --- .../src/base/framework/PropertySet_impl.cpp | 10 + .../src/base/include/ossie/PropertySet_impl.h | 18 ++ redhawk/src/idl/ossie/CF/DataType.idl | 6 + redhawk/src/idl/ossie/CF/cf.idl | 1 + .../components/timeprop_cpp/cpp/Makefile.am | 27 ++ .../dom/components/timeprop_cpp/cpp/main.cpp | 11 + .../timeprop_cpp/cpp/timeprop_cpp.cpp | 249 ++++++++++++++++++ .../timeprop_cpp/cpp/timeprop_cpp.h | 18 ++ .../timeprop_cpp/cpp/timeprop_cpp_base.cpp | 69 +++++ .../timeprop_cpp/cpp/timeprop_cpp_base.h | 30 +++ .../timeprop_cpp/timeprop_cpp.prf.xml | 9 + .../timeprop_cpp/timeprop_cpp.scd.xml | 45 ++++ .../timeprop_cpp/timeprop_cpp.spd.xml | 27 ++ 13 files changed, 520 insertions(+) create mode 100644 redhawk/src/testing/sdr/dom/components/timeprop_cpp/cpp/Makefile.am create mode 100644 redhawk/src/testing/sdr/dom/components/timeprop_cpp/cpp/main.cpp create mode 100644 redhawk/src/testing/sdr/dom/components/timeprop_cpp/cpp/timeprop_cpp.cpp create mode 100644 redhawk/src/testing/sdr/dom/components/timeprop_cpp/cpp/timeprop_cpp.h create mode 100644 redhawk/src/testing/sdr/dom/components/timeprop_cpp/cpp/timeprop_cpp_base.cpp create mode 100644 redhawk/src/testing/sdr/dom/components/timeprop_cpp/cpp/timeprop_cpp_base.h create mode 100644 redhawk/src/testing/sdr/dom/components/timeprop_cpp/timeprop_cpp.prf.xml create mode 100644 redhawk/src/testing/sdr/dom/components/timeprop_cpp/timeprop_cpp.scd.xml create mode 100644 redhawk/src/testing/sdr/dom/components/timeprop_cpp/timeprop_cpp.spd.xml diff --git a/redhawk/src/base/framework/PropertySet_impl.cpp b/redhawk/src/base/framework/PropertySet_impl.cpp index 11e760f62..a7cdbfc83 100644 --- a/redhawk/src/base/framework/PropertySet_impl.cpp +++ b/redhawk/src/base/framework/PropertySet_impl.cpp @@ -93,6 +93,7 @@ PREPARE_CF_LOGGING(PropertySet_impl); PropertySet_impl::PropertySet_impl (): propertyChangePort(0), + _propertyQueryTimestamp("QUERY_TIMESTAMP"), _propChangeThread( new PropertyChangeThread(*this), 0.1 ), _propertiesInitialized(false) { @@ -316,6 +317,9 @@ throw (CORBA::SystemException, CF::UnknownProperties) } ++jj; } + configProperties.length(configProperties.length() + 1); + configProperties[configProperties.length()-1].id = CORBA::string_dup(_propertyQueryTimestamp.c_str()); + configProperties[configProperties.length()-1].value <<= _makeTime(-1,0,0); } else { // For queries of length > 0, return all requested pairs in propertySet CF::Properties invalidProperties; @@ -324,6 +328,10 @@ throw (CORBA::SystemException, CF::UnknownProperties) for (CORBA::ULong ii = 0; ii < configProperties.length (); ++ii) { const std::string id = (const char*)configProperties[ii].id; LOG_TRACE(PropertySet_impl, "Query property " << id); + if (id == _propertyQueryTimestamp) { + configProperties[ii].value <<= _makeTime(-1,0,0); + continue; + } PropertyInterface* property = getPropertyFromId(id); if (property && property->isQueryable()) { if (property->isNilEnabled()) { @@ -748,6 +756,7 @@ int PropertySet_impl::EC_PropertyChangeListener::notify( PropertyChangeRec *rec evt.reg_id = CORBA::string_dup( rec->regId.c_str()); evt.resource_id = CORBA::string_dup( rec->rscId.c_str() ); evt.properties = changes; + evt.timestamp = _makeTime(-1,0,0); try { RH_NL_DEBUG("EC_PropertyChangeListener", "Send change event reg/id:" << rec->regId << "/" << uuid ); pub->push( evt ); @@ -781,6 +790,7 @@ int PropertySet_impl::INF_PropertyChangeListener::notify( PropertyChangeRec *rec evt.reg_id = CORBA::string_dup( rec->regId.c_str()); evt.resource_id = CORBA::string_dup( rec->rscId.c_str() ); evt.properties = changes; + evt.timestamp = _makeTime(-1,0,0); try { RH_NL_DEBUG("INF_PropertyChangeListener", "Send change event reg/id:" << rec->regId << "/" << uuid ); listener->propertyChange( evt ); diff --git a/redhawk/src/base/include/ossie/PropertySet_impl.h b/redhawk/src/base/include/ossie/PropertySet_impl.h index 27cee47cb..933555ae1 100644 --- a/redhawk/src/base/include/ossie/PropertySet_impl.h +++ b/redhawk/src/base/include/ossie/PropertySet_impl.h @@ -91,6 +91,22 @@ class PropertySet_impl // void startPropertyChangeMonitor( const std::string &rsc_id); void stopPropertyChangeMonitor(); + + static CF::UTCTime _makeTime(short status, double wsec, double fsec) { + CF::UTCTime _time; + struct timeval tv; + gettimeofday(&tv, NULL); + if (status == -1) { + _time.tcstatus = 1; + _time.twsec = tv.tv_sec; + _time.tfsec = tv.tv_usec/1e6; + } else { + _time.tcstatus = status; + _time.twsec = wsec; + _time.tfsec = fsec; + } + return _time; + }; protected: @@ -324,6 +340,8 @@ class PropertySet_impl // Preferred new-style properties. typedef std::map PropertyMap; PropertyMap propTable; + + std::string _propertyQueryTimestamp; private: template diff --git a/redhawk/src/idl/ossie/CF/DataType.idl b/redhawk/src/idl/ossie/CF/DataType.idl index 6fd235990..7ae8dc2dd 100644 --- a/redhawk/src/idl/ossie/CF/DataType.idl +++ b/redhawk/src/idl/ossie/CF/DataType.idl @@ -39,6 +39,12 @@ module CF { /* This type defines a sequence of strings */ typedef sequence StringSequence; + struct UTCTime { + short tcstatus; // timecode status + double twsec; // J1970 GMT + double tfsec; // 0.0 to 1.0 + }; + }; #endif diff --git a/redhawk/src/idl/ossie/CF/cf.idl b/redhawk/src/idl/ossie/CF/cf.idl index b930ad41e..a37bbbd6d 100644 --- a/redhawk/src/idl/ossie/CF/cf.idl +++ b/redhawk/src/idl/ossie/CF/cf.idl @@ -413,6 +413,7 @@ module CF { string reg_id; string resource_id; CF::Properties properties; + CF::UTCTime timestamp; }; void propertyChange( in PropertyChangeEvent prop_event ); diff --git a/redhawk/src/testing/sdr/dom/components/timeprop_cpp/cpp/Makefile.am b/redhawk/src/testing/sdr/dom/components/timeprop_cpp/cpp/Makefile.am new file mode 100644 index 000000000..bf05a4933 --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/timeprop_cpp/cpp/Makefile.am @@ -0,0 +1,27 @@ +# +# This file is protected by Copyright. Please refer to the COPYRIGHT file +# distributed with this source distribution. +# +# This file is part of REDHAWK core. +# +# REDHAWK core is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation, either version 3 of the License, or (at your option) any +# later version. +# +# REDHAWK core is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +# details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/. +# +CFDIR = $(top_srcdir)/base + +noinst_PROGRAMS = timeprop_cpp + +timeprop_cpp_SOURCES = timeprop_cpp.cpp timeprop_cpp.h timeprop_cpp_base.cpp timeprop_cpp_base.h main.cpp +timeprop_cpp_CXXFLAGS = -Wall $(BOOST_CPPFLAGS) -I$(CFDIR)/include +timeprop_cpp_LDADD = $(BOOST_REGEX_LIB) $(BOOST_SYSTEM_LIB) $(BOOST_THREAD_LIB) $(OMNIDYNAMIC_LIBS) $(OMNICOS_LIBS) $(CFDIR)/framework/libossiecf.la $(CFDIR)/framework/idl/libossieidl.la + diff --git a/redhawk/src/testing/sdr/dom/components/timeprop_cpp/cpp/main.cpp b/redhawk/src/testing/sdr/dom/components/timeprop_cpp/cpp/main.cpp new file mode 100644 index 000000000..2a4a62239 --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/timeprop_cpp/cpp/main.cpp @@ -0,0 +1,11 @@ +#include +#include "ossie/ossieSupport.h" + +#include "timeprop_cpp.h" +int main(int argc, char* argv[]) +{ + timeprop_cpp_i* timeprop_cpp_servant; + Component::start_component(timeprop_cpp_servant, argc, argv); + return 0; +} + diff --git a/redhawk/src/testing/sdr/dom/components/timeprop_cpp/cpp/timeprop_cpp.cpp b/redhawk/src/testing/sdr/dom/components/timeprop_cpp/cpp/timeprop_cpp.cpp new file mode 100644 index 000000000..b8e9b830a --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/timeprop_cpp/cpp/timeprop_cpp.cpp @@ -0,0 +1,249 @@ +/************************************************************************** + + This is the component code. This file contains the child class where + custom functionality can be added to the component. Custom + functionality to the base class can be extended here. Access to + the ports can also be done from this class + +**************************************************************************/ + +#include "timeprop_cpp.h" + +PREPARE_LOGGING(timeprop_cpp_i) + +timeprop_cpp_i::timeprop_cpp_i(const char *uuid, const char *label) : + timeprop_cpp_base(uuid, label) +{ + // Avoid placing constructor code here. Instead, use the "constructor" function. + +} + +timeprop_cpp_i::~timeprop_cpp_i() +{ +} + +void timeprop_cpp_i::constructor() +{ + /*********************************************************************************** + This is the RH constructor. All properties are properly initialized before this function is called + ***********************************************************************************/ +} + +/*********************************************************************************************** + + Basic functionality: + + The service function is called by the serviceThread object (of type ProcessThread). + This call happens immediately after the previous call if the return value for + the previous call was NORMAL. + If the return value for the previous call was NOOP, then the serviceThread waits + an amount of time defined in the serviceThread's constructor. + + SRI: + To create a StreamSRI object, use the following code: + std::string stream_id = "testStream"; + BULKIO::StreamSRI sri = bulkio::sri::create(stream_id); + + Time: + To create a PrecisionUTCTime object, use the following code: + BULKIO::PrecisionUTCTime tstamp = bulkio::time::utils::now(); + + + Ports: + + Data is passed to the serviceFunction through by reading from input streams + (BulkIO only). The input stream class is a port-specific class, so each port + implementing the BulkIO interface will have its own type-specific input stream. + UDP multicast (dataSDDS and dataVITA49) and string-based (dataString, dataXML and + dataFile) do not support streams. + + The input stream from which to read can be requested with the getCurrentStream() + method. The optional argument to getCurrentStream() is a floating point number that + specifies the time to wait in seconds. A zero value is non-blocking. A negative value + is blocking. Constants have been defined for these values, bulkio::Const::BLOCKING and + bulkio::Const::NON_BLOCKING. + + More advanced uses of input streams are possible; refer to the REDHAWK documentation + for more details. + + Input streams return data blocks that automatically manage the memory for the data + and include the SRI that was in effect at the time the data was received. It is not + necessary to delete the block; it will be cleaned up when it goes out of scope. + + To send data using a BulkIO interface, create an output stream and write the + data to it. When done with the output stream, the close() method sends and end-of- + stream flag and cleans up. + + NOTE: If you have a BULKIO dataSDDS or dataVITA49 port, you must manually call + "port->updateStats()" to update the port statistics when appropriate. + + Example: + // This example assumes that the component has two ports: + // An input (provides) port of type bulkio::InShortPort called dataShort_in + // An output (uses) port of type bulkio::OutFloatPort called dataFloat_out + // The mapping between the port and the class is found + // in the component base class header file + // The component class must have an output stream member; add to + // timeprop_cpp.h: + // bulkio::OutFloatStream outputStream; + + bulkio::InShortStream inputStream = dataShort_in->getCurrentStream(); + if (!inputStream) { // No streams are available + return NOOP; + } + + bulkio::ShortDataBlock block = inputStream.read(); + if (!block) { // No data available + // Propagate end-of-stream + if (inputStream.eos()) { + outputStream.close(); + } + return NOOP; + } + + short* inputData = block.data(); + std::vector outputData; + outputData.resize(block.size()); + for (size_t index = 0; index < block.size(); ++index) { + outputData[index] = (float) inputData[index]; + } + + // If there is no output stream open, create one + if (!outputStream) { + outputStream = dataFloat_out->createStream(block.sri()); + } else if (block.sriChanged()) { + // Update output SRI + outputStream.sri(block.sri()); + } + + // Write to the output stream + outputStream.write(outputData, block.getTimestamps()); + + // Propagate end-of-stream + if (inputStream.eos()) { + outputStream.close(); + } + + return NORMAL; + + If working with complex data (i.e., the "mode" on the SRI is set to + true), the data block's complex() method will return true. Data blocks + provide functions that return the correct interpretation of the data + buffer and number of complex elements: + + if (block.complex()) { + std::complex* data = block.cxdata(); + for (size_t index = 0; index < block.cxsize(); ++index) { + data[index] = std::abs(data[index]); + } + outputStream.write(data, block.cxsize(), bulkio::time::utils::now()); + } + + Interactions with non-BULKIO ports are left up to the component developer's discretion + + Messages: + + To receive a message, you need (1) an input port of type MessageEvent, (2) a message prototype described + as a structure property of kind message, (3) a callback to service the message, and (4) to register the callback + with the input port. + + Assuming a property of type message is declared called "my_msg", an input port called "msg_input" is declared of + type MessageEvent, create the following code: + + void timeprop_cpp_i::my_message_callback(const std::string& id, const my_msg_struct &msg){ + } + + Register the message callback onto the input port with the following form: + this->msg_input->registerMessage("my_msg", this, &timeprop_cpp_i::my_message_callback); + + To send a message, you need to (1) create a message structure, (2) a message prototype described + as a structure property of kind message, and (3) send the message over the port. + + Assuming a property of type message is declared called "my_msg", an output port called "msg_output" is declared of + type MessageEvent, create the following code: + + ::my_msg_struct msg_out; + this->msg_output->sendMessage(msg_out); + + Accessing the Application and Domain Manager: + + Both the Application hosting this Component and the Domain Manager hosting + the Application are available to the Component. + + To access the Domain Manager: + CF::DomainManager_ptr dommgr = this->getDomainManager()->getRef(); + To access the Application: + CF::Application_ptr app = this->getApplication()->getRef(); + + Properties: + + Properties are accessed directly as member variables. For example, if the + property name is "baudRate", it may be accessed within member functions as + "baudRate". Unnamed properties are given the property id as its name. + Property types are mapped to the nearest C++ type, (e.g. "string" becomes + "std::string"). All generated properties are declared in the base class + (timeprop_cpp_base). + + Simple sequence properties are mapped to "std::vector" of the simple type. + Struct properties, if used, are mapped to C++ structs defined in the + generated file "struct_props.h". Field names are taken from the name in + the properties file; if no name is given, a generated name of the form + "field_n" is used, where "n" is the ordinal number of the field. + + Example: + // This example makes use of the following Properties: + // - A float value called scaleValue + // - A boolean called scaleInput + + if (scaleInput) { + dataOut[i] = dataIn[i] * scaleValue; + } else { + dataOut[i] = dataIn[i]; + } + + Callback methods can be associated with a property so that the methods are + called each time the property value changes. This is done by calling + addPropertyListener(, this, &timeprop_cpp_i::) + in the constructor. + + The callback method receives two arguments, the old and new values, and + should return nothing (void). The arguments can be passed by value, + receiving a copy (preferred for primitive types), or by const reference + (preferred for strings, structs and vectors). + + Example: + // This example makes use of the following Properties: + // - A float value called scaleValue + // - A struct property called status + + //Add to timeprop_cpp.cpp + timeprop_cpp_i::timeprop_cpp_i(const char *uuid, const char *label) : + timeprop_cpp_base(uuid, label) + { + addPropertyListener(scaleValue, this, &timeprop_cpp_i::scaleChanged); + addPropertyListener(status, this, &timeprop_cpp_i::statusChanged); + } + + void timeprop_cpp_i::scaleChanged(float oldValue, float newValue) + { + LOG_DEBUG(timeprop_cpp_i, "scaleValue changed from" << oldValue << " to " << newValue); + } + + void timeprop_cpp_i::statusChanged(const status_struct& oldValue, const status_struct& newValue) + { + LOG_DEBUG(timeprop_cpp_i, "status changed"); + } + + //Add to timeprop_cpp.h + void scaleChanged(float oldValue, float newValue); + void statusChanged(const status_struct& oldValue, const status_struct& newValue); + + +************************************************************************************************/ +int timeprop_cpp_i::serviceFunction() +{ + LOG_DEBUG(timeprop_cpp_i, "serviceFunction() example log message"); + + return NOOP; +} + diff --git a/redhawk/src/testing/sdr/dom/components/timeprop_cpp/cpp/timeprop_cpp.h b/redhawk/src/testing/sdr/dom/components/timeprop_cpp/cpp/timeprop_cpp.h new file mode 100644 index 000000000..a19366112 --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/timeprop_cpp/cpp/timeprop_cpp.h @@ -0,0 +1,18 @@ +#ifndef TIMEPROP_CPP_I_IMPL_H +#define TIMEPROP_CPP_I_IMPL_H + +#include "timeprop_cpp_base.h" + +class timeprop_cpp_i : public timeprop_cpp_base +{ + ENABLE_LOGGING + public: + timeprop_cpp_i(const char *uuid, const char *label); + ~timeprop_cpp_i(); + + void constructor(); + + int serviceFunction(); +}; + +#endif // TIMEPROP_CPP_I_IMPL_H diff --git a/redhawk/src/testing/sdr/dom/components/timeprop_cpp/cpp/timeprop_cpp_base.cpp b/redhawk/src/testing/sdr/dom/components/timeprop_cpp/cpp/timeprop_cpp_base.cpp new file mode 100644 index 000000000..95d0e897b --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/timeprop_cpp/cpp/timeprop_cpp_base.cpp @@ -0,0 +1,69 @@ +#include "timeprop_cpp_base.h" + +/******************************************************************************************* + + AUTO-GENERATED CODE. DO NOT MODIFY + + The following class functions are for the base class for the component class. To + customize any of these functions, do not modify them here. Instead, overload them + on the child class + +******************************************************************************************/ + +timeprop_cpp_base::timeprop_cpp_base(const char *uuid, const char *label) : + Component(uuid, label), + ThreadedComponent() +{ + setThreadName(label); + + loadProperties(); +} + +timeprop_cpp_base::~timeprop_cpp_base() +{ +} + +/******************************************************************************************* + Framework-level functions + These functions are generally called by the framework to perform housekeeping. +*******************************************************************************************/ +void timeprop_cpp_base::start() throw (CORBA::SystemException, CF::Resource::StartError) +{ + Component::start(); + ThreadedComponent::startThread(); +} + +void timeprop_cpp_base::stop() throw (CORBA::SystemException, CF::Resource::StopError) +{ + Component::stop(); + if (!ThreadedComponent::stopThread()) { + throw CF::Resource::StopError(CF::CF_NOTSET, "Processing thread did not die"); + } +} + +void timeprop_cpp_base::releaseObject() throw (CORBA::SystemException, CF::LifeCycle::ReleaseError) +{ + // This function clears the component running condition so main shuts down everything + try { + stop(); + } catch (CF::Resource::StopError& ex) { + // TODO - this should probably be logged instead of ignored + } + + Component::releaseObject(); +} + +void timeprop_cpp_base::loadProperties() +{ + addProperty(prop, + "value", + "prop", + "", + "readwrite", + "", + "external", + "property"); + +} + + diff --git a/redhawk/src/testing/sdr/dom/components/timeprop_cpp/cpp/timeprop_cpp_base.h b/redhawk/src/testing/sdr/dom/components/timeprop_cpp/cpp/timeprop_cpp_base.h new file mode 100644 index 000000000..036c26fc0 --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/timeprop_cpp/cpp/timeprop_cpp_base.h @@ -0,0 +1,30 @@ +#ifndef TIMEPROP_CPP_BASE_IMPL_BASE_H +#define TIMEPROP_CPP_BASE_IMPL_BASE_H + +#include +#include +#include + + +class timeprop_cpp_base : public Component, protected ThreadedComponent +{ + public: + timeprop_cpp_base(const char *uuid, const char *label); + ~timeprop_cpp_base(); + + void start() throw (CF::Resource::StartError, CORBA::SystemException); + + void stop() throw (CF::Resource::StopError, CORBA::SystemException); + + void releaseObject() throw (CF::LifeCycle::ReleaseError, CORBA::SystemException); + + void loadProperties(); + + protected: + // Member variables exposed as properties + /// Property: prop + std::string prop; + + private: +}; +#endif // TIMEPROP_CPP_BASE_IMPL_BASE_H diff --git a/redhawk/src/testing/sdr/dom/components/timeprop_cpp/timeprop_cpp.prf.xml b/redhawk/src/testing/sdr/dom/components/timeprop_cpp/timeprop_cpp.prf.xml new file mode 100644 index 000000000..fac40ad7c --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/timeprop_cpp/timeprop_cpp.prf.xml @@ -0,0 +1,9 @@ + + + + + value + + + + diff --git a/redhawk/src/testing/sdr/dom/components/timeprop_cpp/timeprop_cpp.scd.xml b/redhawk/src/testing/sdr/dom/components/timeprop_cpp/timeprop_cpp.scd.xml new file mode 100644 index 000000000..df94ceaf5 --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/timeprop_cpp/timeprop_cpp.scd.xml @@ -0,0 +1,45 @@ + + + + 2.2 + + resource + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/redhawk/src/testing/sdr/dom/components/timeprop_cpp/timeprop_cpp.spd.xml b/redhawk/src/testing/sdr/dom/components/timeprop_cpp/timeprop_cpp.spd.xml new file mode 100644 index 000000000..97905b81a --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/timeprop_cpp/timeprop_cpp.spd.xml @@ -0,0 +1,27 @@ + + + + + + null + + + + + + + + + The implementation contains descriptive information about the template for a software resource. + + + cpp/timeprop_cpp + + + + + + + + + From 5a76af3a742e38e0dba007c54d65dd50d9b6538b Mon Sep 17 00:00:00 2001 From: Max Robert Date: Sat, 7 Jan 2017 13:32:45 -0500 Subject: [PATCH 0636/1644] Refs CF-1420. Python support for timestamped queries --- .../base/framework/python/ossie/resource.py | 21 ++- .../timeprop_py/python/timeprop_py.py | 156 ++++++++++++++++++ .../timeprop_py/python/timeprop_py_base.py | 70 ++++++++ .../timeprop_py/timeprop_py.prf.xml | 9 + .../timeprop_py/timeprop_py.scd.xml | 45 +++++ .../timeprop_py/timeprop_py.spd.xml | 25 +++ 6 files changed, 324 insertions(+), 2 deletions(-) create mode 100755 redhawk/src/testing/sdr/dom/components/timeprop_py/python/timeprop_py.py create mode 100644 redhawk/src/testing/sdr/dom/components/timeprop_py/python/timeprop_py_base.py create mode 100644 redhawk/src/testing/sdr/dom/components/timeprop_py/timeprop_py.prf.xml create mode 100644 redhawk/src/testing/sdr/dom/components/timeprop_py/timeprop_py.scd.xml create mode 100644 redhawk/src/testing/sdr/dom/components/timeprop_py/timeprop_py.spd.xml diff --git a/redhawk/src/base/framework/python/ossie/resource.py b/redhawk/src/base/framework/python/ossie/resource.py index bb69461f0..29c470b83 100644 --- a/redhawk/src/base/framework/python/ossie/resource.py +++ b/redhawk/src/base/framework/python/ossie/resource.py @@ -57,6 +57,15 @@ def _getCallback(obj, methodName): else: return None + +def _makeTime(status=-1, wsec=0, fsec=0): + _time = CF.UTCTime(status, wsec, fsec) + if status == -1: + _time.tcstatus = 1 + ts = time.time() + _time.twsec = int(ts) + _time.tfsec = ts-int(ts) + return _time class PropertyAttributeMixIn: """Include this MixIn with your Device if you want your properties to @@ -175,7 +184,8 @@ def notify( self, prec, props ): evt = CF.PropertyChangeListener.PropertyChangeEvent( str(uuid.uuid1()), prec.regId, prec.rscId, - props) + props, + _makeTime()) if self.pub: self.pub.push( evt ) except: @@ -204,7 +214,8 @@ def notify( self, prec, props ): evt = CF.PropertyChangeListener.PropertyChangeEvent( str(uuid.uuid1()), prec.regId, prec.rscId, - props) + props, + _makeTime()) if self.listener: self.listener.propertyChange( evt ) except: @@ -685,6 +696,8 @@ def runTest(self, testid, properties): """Override this function to provide the desired behavior.""" self._log.trace("runTest()") raise CF.Device.UnknownTest("unknown test: %s" % str(testid)) + + _propertyQueryTimestamp = 'QUERY_TIMESTAMP' ######################################### # CF::PropertySet @@ -721,6 +734,7 @@ def query(self, configProperties): except: self.propertySetAccess.release() raise + rv.append(CF.DataType(self._propertyQueryTimestamp, any.to_any(_makeTime()))) # otherwise get only the requested ones else: @@ -728,6 +742,9 @@ def query(self, configProperties): try: unknownProperties = [] for prop in configProperties: + if prop.id == self._propertyQueryTimestamp: + prop.value = any.to_any(_makeTime()) + continue if self._props.has_id(prop.id) and self._props.isQueryable(prop.id): try: prop.value = self._props.query(prop.id) diff --git a/redhawk/src/testing/sdr/dom/components/timeprop_py/python/timeprop_py.py b/redhawk/src/testing/sdr/dom/components/timeprop_py/python/timeprop_py.py new file mode 100755 index 000000000..ca56d272c --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/timeprop_py/python/timeprop_py.py @@ -0,0 +1,156 @@ +#!/usr/bin/env python +# +# +# AUTO-GENERATED +# +# Source: timeprop_py.spd.xml +from ossie.resource import start_component +import logging + +from timeprop_py_base import * + +class timeprop_py_i(timeprop_py_base): + """""" + def constructor(self): + """ + This is called by the framework immediately after your component registers with the system. + + In general, you should add customization here and not in the __init__ constructor. If you have + a custom port implementation you can override the specific implementation here with a statement + similar to the following: + self.some_port = MyPortImplementation() + + """ + # TODO add customization here. + + def process(self): + """ + Basic functionality: + + The process method should process a single "chunk" of data and then return. This method + will be called from the processing thread again, and again, and again until it returns + FINISH or stop() is called on the component. If no work is performed, then return NOOP. + + StreamSRI: + To create a StreamSRI object, use the following code (this generates a normalized SRI that does not flush the queue when full): + sri = bulkio.sri.create("my_stream_id") + + PrecisionUTCTime: + To create a PrecisionUTCTime object, use the following code: + tstamp = bulkio.timestamp.now() + + Ports: + + Each port instance is accessed through members of the following form: self.port_ + + Data is obtained in the process function through the getPacket call (BULKIO only) on a + provides port member instance. The optional argument is a timeout value, in seconds. + A zero value is non-blocking, while a negative value is blocking. Constants have been + defined for these values, bulkio.const.BLOCKING and bulkio.const.NON_BLOCKING. If no + timeout is given, it defaults to non-blocking. + + The return value is a named tuple with the following fields: + - dataBuffer + - T + - EOS + - streamID + - SRI + - sriChanged + - inputQueueFlushed + If no data is available due to a timeout, all fields are None. + + To send data, call the appropriate function in the port directly. In the case of BULKIO, + convenience functions have been added in the port classes that aid in output. + + Interactions with non-BULKIO ports are left up to the component developer's discretion. + + Messages: + + To receive a message, you need (1) an input port of type MessageEvent, (2) a message prototype described + as a structure property of kind message, (3) a callback to service the message, and (4) to register the callback + with the input port. + + Assuming a property of type message is declared called "my_msg", an input port called "msg_input" is declared of + type MessageEvent, create the following code: + + def msg_callback(self, msg_id, msg_value): + print msg_id, msg_value + + Register the message callback onto the input port with the following form: + self.port_input.registerMessage("my_msg", timeprop_py_i.MyMsg, self.msg_callback) + + To send a message, you need to (1) create a message structure, and (2) send the message over the port. + + Assuming a property of type message is declared called "my_msg", an output port called "msg_output" is declared of + type MessageEvent, create the following code: + + msg_out = timeprop_py_i.MyMsg() + this.port_msg_output.sendMessage(msg_out) + + Accessing the Device Manager and Domain Manager: + + Both the Device Manager hosting this Device and the Domain Manager hosting + the Device Manager are available to the Device. + + To access the Domain Manager: + dommgr = self.getDomainManager().getRef(); + To access the Device Manager: + devmgr = self.getDeviceManager().getRef(); + Properties: + + Properties are accessed directly as member variables. If the property name is baudRate, + then accessing it (for reading or writing) is achieved in the following way: self.baudRate. + + To implement a change callback notification for a property, create a callback function with the following form: + + def mycallback(self, id, old_value, new_value): + pass + + where id is the property id, old_value is the previous value, and new_value is the updated value. + + The callback is then registered on the component as: + self.addPropertyChangeListener('baudRate', self.mycallback) + + + Example: + + # This example assumes that the component has two ports: + # - A provides (input) port of type bulkio.InShortPort called dataShort_in + # - A uses (output) port of type bulkio.OutFloatPort called dataFloat_out + # The mapping between the port and the class if found in the component + # base class. + # This example also makes use of the following Properties: + # - A float value called amplitude + # - A boolean called increaseAmplitude + + packet = self.port_dataShort_in.getPacket() + + if packet.dataBuffer is None: + return NOOP + + outData = range(len(packet.dataBuffer)) + for i in range(len(packet.dataBuffer)): + if self.increaseAmplitude: + outData[i] = float(packet.dataBuffer[i]) * self.amplitude + else: + outData[i] = float(packet.dataBuffer[i]) + + # NOTE: You must make at least one valid pushSRI call + if packet.sriChanged: + self.port_dataFloat_out.pushSRI(packet.SRI); + + self.port_dataFloat_out.pushPacket(outData, packet.T, packet.EOS, packet.streamID) + return NORMAL + + """ + + # TODO fill in your code here + self._log.debug("process() example log message") + return NOOP + + +if __name__ == '__main__': + logging.getLogger().setLevel(logging.INFO) + logging.debug("Starting Component") + start_component(timeprop_py_i) + diff --git a/redhawk/src/testing/sdr/dom/components/timeprop_py/python/timeprop_py_base.py b/redhawk/src/testing/sdr/dom/components/timeprop_py/python/timeprop_py_base.py new file mode 100644 index 000000000..1ef931abb --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/timeprop_py/python/timeprop_py_base.py @@ -0,0 +1,70 @@ +#!/usr/bin/env python +# +# AUTO-GENERATED CODE. DO NOT MODIFY! +# +# Source: timeprop_py.spd.xml +from ossie.cf import CF +from ossie.cf import CF__POA +from ossie.utils import uuid + +from ossie.component import Component +from ossie.threadedcomponent import * +from ossie.properties import simple_property + +import Queue, copy, time, threading + +class timeprop_py_base(CF__POA.Resource, Component, ThreadedComponent): + # These values can be altered in the __init__ of your derived class + + PAUSE = 0.0125 # The amount of time to sleep if process return NOOP + TIMEOUT = 5.0 # The amount of time to wait for the process thread to die when stop() is called + DEFAULT_QUEUE_SIZE = 100 # The number of BulkIO packets that can be in the queue before pushPacket will block + + def __init__(self, identifier, execparams): + loggerName = (execparams['NAME_BINDING'].replace('/', '.')).rsplit("_", 1)[0] + Component.__init__(self, identifier, execparams, loggerName=loggerName) + ThreadedComponent.__init__(self) + + # self.auto_start is deprecated and is only kept for API compatibility + # with 1.7.X and 1.8.0 components. This variable may be removed + # in future releases + self.auto_start = False + # Instantiate the default implementations for all ports on this component + + def start(self): + Component.start(self) + ThreadedComponent.startThread(self, pause=self.PAUSE) + + def stop(self): + Component.stop(self) + if not ThreadedComponent.stopThread(self, self.TIMEOUT): + raise CF.Resource.StopError(CF.CF_NOTSET, "Processing thread did not die") + + def releaseObject(self): + try: + self.stop() + except Exception: + self._log.exception("Error stopping") + Component.releaseObject(self) + + ###################################################################### + # PORTS + # + # DO NOT ADD NEW PORTS HERE. You can add ports in your derived class, in the SCD xml file, + # or via the IDE. + + ###################################################################### + # PROPERTIES + # + # DO NOT ADD NEW PROPERTIES HERE. You can add properties in your derived class, in the PRF xml file + # or by using the IDE. + prop = simple_property(id_="prop", + type_="string", + defvalue="value", + mode="readwrite", + action="external", + kinds=("property",)) + + + + diff --git a/redhawk/src/testing/sdr/dom/components/timeprop_py/timeprop_py.prf.xml b/redhawk/src/testing/sdr/dom/components/timeprop_py/timeprop_py.prf.xml new file mode 100644 index 000000000..fac40ad7c --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/timeprop_py/timeprop_py.prf.xml @@ -0,0 +1,9 @@ + + + + + value + + + + diff --git a/redhawk/src/testing/sdr/dom/components/timeprop_py/timeprop_py.scd.xml b/redhawk/src/testing/sdr/dom/components/timeprop_py/timeprop_py.scd.xml new file mode 100644 index 000000000..df94ceaf5 --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/timeprop_py/timeprop_py.scd.xml @@ -0,0 +1,45 @@ + + + + 2.2 + + resource + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/redhawk/src/testing/sdr/dom/components/timeprop_py/timeprop_py.spd.xml b/redhawk/src/testing/sdr/dom/components/timeprop_py/timeprop_py.spd.xml new file mode 100644 index 000000000..2aa65201c --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/timeprop_py/timeprop_py.spd.xml @@ -0,0 +1,25 @@ + + + + + + null + + + + + + + + + The implementation contains descriptive information about the template for a software resource. + + + python/timeprop_py.py + + + + + + + From dbbe2ebf4c0c98b3411a907449819d7511fcfda6 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Sat, 7 Jan 2017 13:33:32 -0500 Subject: [PATCH 0637/1644] Refs CF-1420. Java support for timestamped queries --- .../ossie/component/PropertyChangeRec.java | 16 +- .../src/org/ossie/component/Resource.java | 25 +- .../msg_through_java/java/startJava.sh | 42 +-- .../components/timeprop_java/java/Makefile.am | 41 +++ .../src/timeprop_java/java/timeprop_java.java | 252 ++++++++++++++++++ .../java/timeprop_java_base.java | 102 +++++++ .../timeprop_java/java/startJava.sh | 38 +++ .../timeprop_java/timeprop_java.prf.xml | 9 + .../timeprop_java/timeprop_java.scd.xml | 45 ++++ .../timeprop_java/timeprop_java.spd.xml | 26 ++ 10 files changed, 576 insertions(+), 20 deletions(-) create mode 100644 redhawk/src/testing/sdr/dom/components/timeprop_java/java/Makefile.am create mode 100644 redhawk/src/testing/sdr/dom/components/timeprop_java/java/src/timeprop_java/java/timeprop_java.java create mode 100644 redhawk/src/testing/sdr/dom/components/timeprop_java/java/src/timeprop_java/java/timeprop_java_base.java create mode 100755 redhawk/src/testing/sdr/dom/components/timeprop_java/java/startJava.sh create mode 100644 redhawk/src/testing/sdr/dom/components/timeprop_java/timeprop_java.prf.xml create mode 100644 redhawk/src/testing/sdr/dom/components/timeprop_java/timeprop_java.scd.xml create mode 100644 redhawk/src/testing/sdr/dom/components/timeprop_java/timeprop_java.spd.xml diff --git a/redhawk/src/base/framework/java/ossie/src/org/ossie/component/PropertyChangeRec.java b/redhawk/src/base/framework/java/ossie/src/org/ossie/component/PropertyChangeRec.java index 1eda05a1b..915f57c59 100644 --- a/redhawk/src/base/framework/java/ossie/src/org/ossie/component/PropertyChangeRec.java +++ b/redhawk/src/base/framework/java/ossie/src/org/ossie/component/PropertyChangeRec.java @@ -102,10 +102,16 @@ public EC_PropertyChangeListener( org.omg.CORBA.Object obj ) public int notify( PropertyChangeRec prec, DataType[] props) { String uuid = UUID.randomUUID().toString(); + long tmp_time = System.currentTimeMillis(); + CF.UTCTime _time = new CF.UTCTime(); + _time.tcstatus = 1; + _time.twsec = tmp_time /1000; + _time.tfsec = (tmp_time % 1000)/1000.0; PropertyChangeEvent evt = new PropertyChangeEvent( uuid, prec.regId, prec.rscId, - props); + props, + _time); final Any any = ORB.init().create_any(); PropertyChangeEventHelper.insert( any, evt); @@ -142,10 +148,16 @@ public INF_PropertyChangeListener( org.omg.CORBA.Object obj ) public int notify( PropertyChangeRec prec, DataType[] props) { String uuid = UUID.randomUUID().toString(); + long tmp_time = System.currentTimeMillis(); + CF.UTCTime _time = new CF.UTCTime(); + _time.tcstatus = 1; + _time.twsec = tmp_time /1000; + _time.tfsec = (tmp_time % 1000)/1000.0; PropertyChangeEvent evt = new PropertyChangeEvent( uuid, prec.regId, prec.rscId, - props); + props, + _time); int retval=0; try { diff --git a/redhawk/src/base/framework/java/ossie/src/org/ossie/component/Resource.java b/redhawk/src/base/framework/java/ossie/src/org/ossie/component/Resource.java index cae1c0337..4c93bd429 100644 --- a/redhawk/src/base/framework/java/ossie/src/org/ossie/component/Resource.java +++ b/redhawk/src/base/framework/java/ossie/src/org/ossie/component/Resource.java @@ -640,6 +640,19 @@ public void configure(final DataType[] configProperties) throws InvalidConfigura } } + String _propertyQueryTimestamp = "QUERY_TIMESTAMP"; + + public CF.UTCTime _makeTime(final short status, final double wsec, final double fsec) { + CF.UTCTime _time = new CF.UTCTime(status, wsec, fsec); + if (status == -1) { + long tmp_time = System.currentTimeMillis(); + _time.tcstatus = 1; + _time.twsec = tmp_time /1000; + _time.tfsec = (tmp_time % 1000)/1000.0; + } + return _time; + } + /** * {@inheritDoc} */ @@ -647,7 +660,7 @@ public void query(final PropertiesHolder configProperties) throws UnknownPropert logger.trace("query()"); // For queries of zero length, return all id/value pairs in propertySet if (configProperties.value.length == 0) { - final ArrayList props = new ArrayList(this.propSet.size()); + final ArrayList props = new ArrayList(this.propSet.size()+1); for (final IProperty prop : this.propSet.values()) { logger.trace("Querying property: " + prop); if (prop.isQueryable()) { @@ -667,6 +680,10 @@ public void query(final PropertiesHolder configProperties) throws UnknownPropert } } } + + final Any anytime = ORB.init().create_any(); + CF.UTCTimeHelper.insert(anytime, this._makeTime((short)-1,0,0)); + props.add(new DataType(_propertyQueryTimestamp, anytime)); configProperties.value = props.toArray(new DataType[props.size()]); return; @@ -679,6 +696,12 @@ public void query(final PropertiesHolder configProperties) throws UnknownPropert // Return values for valid queries in the same order as requested for (final DataType dt : configProperties.value) { // Look up the property and ensure it is queryable + if (dt.id.equals(_propertyQueryTimestamp)) { + final Any anytime = ORB.init().create_any(); + CF.UTCTimeHelper.insert(anytime, this._makeTime((short)-1,0,0)); + validProperties.add(new DataType(_propertyQueryTimestamp, anytime)); + continue; + } final IProperty prop = this.propSet.get(dt.id); if ((prop != null) && prop.isQueryable()) { if (prop instanceof StructProperty) { diff --git a/redhawk/src/testing/sdr/dom/components/msg_through_java/java/startJava.sh b/redhawk/src/testing/sdr/dom/components/msg_through_java/java/startJava.sh index 82ee6cc82..0a353b587 100755 --- a/redhawk/src/testing/sdr/dom/components/msg_through_java/java/startJava.sh +++ b/redhawk/src/testing/sdr/dom/components/msg_through_java/java/startJava.sh @@ -1,18 +1,29 @@ #!/bin/sh -myDir=`dirname $0` +# +# This file is protected by Copyright. Please refer to the COPYRIGHT file +# distributed with this source distribution. +# +# This file is part of REDHAWK core. +# +# REDHAWK core is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation, either version 3 of the License, or (at your option) any +# later version. +# +# REDHAWK core is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +# details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/. +# -# Setup the OSSIEHOME Lib jars on the classpath -libDir=$OSSIEHOME/lib -libFiles=`ls -1 $libDir/*.jar` -for file in $libFiles -do - if [ x"$CLASSPATH" = "x" ] - then - export CLASSPATH=$file - else - export CLASSPATH=$file:$CLASSPATH - fi -done +#Sun ORB start line +# Important, the $@ must be quoted "$@" for arguments to be passed correctly +myDir=`dirname $0` +JAVA_LIBDIR=${myDir}/../../../../../base/framework/java +JAVA_CLASSPATH=${JAVA_LIBDIR}/apache-commons-lang-2.4.jar:${JAVA_LIBDIR}/log4j-1.2.15.jar:${JAVA_LIBDIR}/CFInterfaces.jar:${JAVA_LIBDIR}/ossie.jar:${myDir}/msg_through_java.jar:${myDir}:${myDir}/bin:${CLASSPATH} # Path for Java if test -x $JAVA_HOME/bin/java; then @@ -24,7 +35,4 @@ fi # NOTE: the $@ must be quoted "$@" for arguments to be passed correctly #Sun ORB start line -exec $JAVA -cp :$myDir/msg_through_java.jar:$myDir/bin:$CLASSPATH msg_through_java.java.msg_through_java "$@" - -#JacORB start lines -#exec $JAVA -cp :$myDir/jacorb.jar:$myDir/antlr.jar:$myDir/avalon-framework.jar:$myDir/backport-util-concurrent.jar:$myDir/logkit.jar:$myDir/msg_through_java.jar:$myDir/bin:$CLASSPATH msg_through_java.java.msg_through_java "$@" +exec $JAVA -cp ${JAVA_CLASSPATH} msg_through_java.java.msg_through_java "$@" diff --git a/redhawk/src/testing/sdr/dom/components/timeprop_java/java/Makefile.am b/redhawk/src/testing/sdr/dom/components/timeprop_java/java/Makefile.am new file mode 100644 index 000000000..c48f8b23f --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/timeprop_java/java/Makefile.am @@ -0,0 +1,41 @@ +## This file is protected by Copyright. Please refer to the COPYRIGHT file +# distributed with this source distribution. +# # +# # This file is part of REDHAWK core. +# # +# # REDHAWK core is free software: you can redistribute it and/or modify it under +# # the terms of the GNU Lesser General Public License as published by the Free +# # Software Foundation, either version 3 of the License, or (at your option) any +# # later version. +# # +# # REDHAWK core is distributed in the hope that it will be useful, but WITHOUT +# # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# # FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +# # details. +# # +# # You should have received a copy of the GNU Lesser General Public License +# # along with this program. If not, see http://www.gnu.org/licenses/. +# # +# +if HAVE_JAVASUPPORT + +timeprop_java.jar: + mkdir -p bin + find ./src -name "*.java" > fileList.txt + $(JAVAC) -cp $(OSSIE_CLASSPATH) -d bin @fileList.txt + $(JAR) cf ./timeprop_java.jar -C bin . + rm fileList.txt + +clean-local: + rm -rf bin + +timeprop_java_jar_SOURCES := $(shell find ./src -name "*.java") + +ossieName = timeprop_java +noinst_PROGRAMS = timeprop_java.jar + +else + +all-local: + @echo "Java support disabled - timeprop_java will not be compiled" +endif diff --git a/redhawk/src/testing/sdr/dom/components/timeprop_java/java/src/timeprop_java/java/timeprop_java.java b/redhawk/src/testing/sdr/dom/components/timeprop_java/java/src/timeprop_java/java/timeprop_java.java new file mode 100644 index 000000000..5c7bf3ba7 --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/timeprop_java/java/src/timeprop_java/java/timeprop_java.java @@ -0,0 +1,252 @@ +package timeprop_java.java; + +import java.util.Properties; + +/** + * This is the component code. This file contains the derived class where custom + * functionality can be added to the component. You may add methods and code to + * this class to handle property changes, respond to incoming data, and perform + * general component housekeeping + * + * Source: timeprop_java.spd.xml + */ +public class timeprop_java extends timeprop_java_base { + /** + * This is the component constructor. In this method, you may add + * additional functionality to properties such as listening for changes + * or handling allocation, register message handlers and set up internal + * state for your component. + * + * A component may listen for external changes to properties (i.e., by a + * call to configure) using the PropertyListener interface. Listeners are + * registered by calling addChangeListener() on the property instance + * with an object that implements the PropertyListener interface for that + * data type (e.g., "PropertyListener" for a float property). More + * than one listener can be connected to a property. + * + * Example: + * // This example makes use of the following properties: + * // - A float value called scaleValue + * // The file must import "org.ossie.properties.PropertyListener" + * // Add the following import to the top of the file: + * import org.ossie.properties.PropertyListener; + * + * //Add the following to the class constructor: + * this.scaleValue.addChangeListener(new PropertyListener() { + * public void valueChanged(Float oldValue, Float newValue) { + * scaleValueChanged(oldValue, newValue); + * } + * }); + * + * //Add the following method to the class: + * private void scaleValueChanged(Float oldValue, Float newValue) + * { + * logger.debug("Changed scaleValue " + oldValue + " to " + newValue); + * } + * + * The recommended practice is for the implementation of valueChanged() to + * contain only glue code to dispatch the call to a private method on the + * component class. + * Accessing the Application and Domain Manager: + * + * Both the Application hosting this Component and the Domain Manager hosting + * the Application are available to the Component. + * + * To access the Domain Manager: + * CF.DomainManager dommgr = this.getDomainManager().getRef(); + * To access the Application: + * CF.Application app = this.getApplication().getRef(); + * + * Messages: + * + * To send or receive messages, you must have at least one message + * prototype described as a struct property of kind "message." + * + * Receiving: + * + * To receive a message, you must have an input port of type MessageEvent + * (marked as "bi-dir" in the Ports editor). For each message type the + * component supports, you must register a message handler callback with + * the message input port. Message handlers implement the MessageListener + * interface. + * + * A callback is registered by calling registerMessage() on the message + * input port with the message ID, the message struct's Class object and + * an object that implements the MessageListener interface for that + * message struct (e.g., "MessageListener" for a + * message named "my_message"). + * + * Example: + * // Assume the component has a message type called "my_message" and + * // an input MessageEvent port called "message_in". + * // Add the following to the top of the file: + * import org.ossie.events.MessageListener; + * + * // Register the callback in the class constructor: + * this.message_in.registerMessage("my_message", my_message_struct.class, new MessageListener() { + * public void messageReceived(String messageId, my_message_struct messageData) { + * my_message_received(messageData); + * } + * }); + * + * // Implement the message handler method: + * private void my_message_received(my_message_struct messageData) { + * // Respond to the message + * } + * + * The recommended practice is for the implementation of messageReceived() + * to contain only glue code to dispatch the call to a private method on + * the component class. + * + * Sending: + * + * To send a message, you must have an output port of type MessageEvent. + * Create an instance of the message struct type and call sendMessage() + * to send a single message. + * + * Example: + * // Assume the component has a message type called "my_message" and + * // an output MessageEvent port called "message_out". + * my_message_struct message = new my_message_struct(); + * this.message_out.sendMessage(message); + * + * You may also send a batch of messages at once with the sendMessages() + * method. + */ + + public timeprop_java() + { + super(); + } + + public void constructor() + { + } + + + /** + * + * Main processing function + * + * General functionality: + * + * The serviceFunction() is called repeatedly by the component's processing + * thread, which runs independently of the main thread. Each invocation + * should perform a single unit of work, such as reading and processing one + * data packet. + * + * The return status of serviceFunction() determines how soon the next + * invocation occurs: + * - NORMAL: the next call happens immediately + * - NOOP: the next call happens after a pre-defined delay (100 ms) + * - FINISH: no more calls occur + * + * StreamSRI: + * To create a StreamSRI object, use the following code: + * String stream_id = "testStream"; + * BULKIO.StreamSRI sri = new BULKIO.StreamSRI(); + * sri.mode = 0; + * sri.xdelta = 0.0; + * sri.ydelta = 1.0; + * sri.subsize = 0; + * sri.xunits = 1; // TIME_S + * sri.streamID = (stream_id != null) ? stream_id : ""; + * + * PrecisionUTCTime: + * To create a PrecisionUTCTime object, use the following code: + * BULKIO.PrecisionUTCTime tstamp = bulkio.time.utils.now(); + * + * Ports: + * + * Each port instance is accessed through members of the following form: + * + * this.port_ + * + * Input BULKIO data is obtained by calling getPacket on the provides + * port. The getPacket method takes one argument: the time to wait for + * data to arrive, in milliseconds. A timeout of 0 causes getPacket to + * return immediately, while a negative timeout indicates an indefinite + * wait. If no data is queued and no packet arrives during the waiting + * period, getPacket returns null. + * + * Output BULKIO data is sent by calling pushPacket on the uses port. In + * the case of numeric data, the pushPacket method takes a primitive + * array (e.g., "float[]"), a timestamp, an end-of-stream flag and a + * stream ID. You must make at least one call to pushSRI to associate a + * StreamSRI with the stream ID before calling pushPacket, or receivers + * may drop the data. + * + * When all processing on a stream is complete, a call should be made to + * pushPacket with the end-of-stream flag set to "true". + * + * Interactions with non-BULKIO ports are left up to the discretion of + * the component developer. + * + * Properties: + * + * Properties are accessed through members of the same name; characters + * that are invalid for a Java identifier are replaced with "_". The + * current value of the property is read with getValue and written with + * setValue: + * + * float val = this.float_prop.getValue(); + * ... + * this.float_prop.setValue(1.5f); + * + * Primitive data types are stored using the corresponding Java object + * wrapper class. For example, a property of type "float" is stored as a + * Float. Java will automatically box and unbox primitive types where + * appropriate. + * + * Numeric properties support assignment via setValue from any numeric + * type. The standard Java type coercion rules apply (e.g., truncation + * of floating point values when converting to integer types). + * + * Example: + * + * This example assumes that the component has two ports: + * - A bulkio.InShortPort provides (input) port called dataShort_in + * - A bulkio.OutFloatPort uses (output) port called dataFloat_out + * The mapping between the port and the class is found in the component + * base class file. + * This example also makes use of the following Properties: + * - A float value called amplitude with a default value of 2.0 + * - A boolean called increaseAmplitude with a default value of true + * + * bulkio.InShortPort.Packet data = this.port_dataShort_in.getPacket(125); + * + * if (data != null) { + * float[] outData = new float[data.getData().length]; + * for (int i = 0; i < data.getData().length; i++) { + * if (this.increaseAmplitude.getValue()) { + * outData[i] = (float)data.getData()[i] * this.amplitude.getValue(); + * } else { + * outData[i] = (float)data.getData()[i]; + * } + * } + * + * // NOTE: You must make at least one valid pushSRI call + * if (data.sriChanged()) { + * this.port_dataFloat_out.pushSRI(data.getSRI()); + * } + * this.port_dataFloat_out.pushPacket(outData, data.getTime(), data.getEndOfStream(), data.getStreamID()); + * } + * + */ + protected int serviceFunction() { + logger.debug("serviceFunction() example log message"); + + return NOOP; + } + + /** + * Set additional options for ORB startup. For example: + * + * orbProps.put("com.sun.CORBA.giop.ORBFragmentSize", Integer.toString(fragSize)); + * + * @param orbProps + */ + public static void configureOrb(final Properties orbProps) { + } + +} diff --git a/redhawk/src/testing/sdr/dom/components/timeprop_java/java/src/timeprop_java/java/timeprop_java_base.java b/redhawk/src/testing/sdr/dom/components/timeprop_java/java/src/timeprop_java/java/timeprop_java_base.java new file mode 100644 index 000000000..401c36829 --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/timeprop_java/java/src/timeprop_java/java/timeprop_java_base.java @@ -0,0 +1,102 @@ +package timeprop_java.java; + + +import java.util.Properties; + +import org.apache.log4j.Logger; + +import org.omg.CosNaming.NamingContextPackage.CannotProceed; +import org.omg.CosNaming.NamingContextPackage.InvalidName; +import org.omg.CosNaming.NamingContextPackage.NotFound; +import org.omg.PortableServer.POAPackage.ServantNotActive; +import org.omg.PortableServer.POAPackage.WrongPolicy; + +import CF.InvalidObjectReference; + +import org.ossie.component.*; +import org.ossie.properties.*; + + +/** + * This is the component code. This file contains all the access points + * you need to use to be able to access all input and output ports, + * respond to incoming data, and perform general component housekeeping + * + * Source: timeprop_java.spd.xml + * + * @generated + */ + +public abstract class timeprop_java_base extends Component { + /** + * @generated + */ + public final static Logger logger = Logger.getLogger(timeprop_java_base.class.getName()); + + /** + * The property prop + * If the meaning of this property isn't clear, a description should be added. + * + * @generated + */ + public final StringProperty prop = + new StringProperty( + "prop", //id + null, //name + "value", //default value + Mode.READWRITE, //mode + Action.EXTERNAL, //action + new Kind[] {Kind.PROPERTY} + ); + + /** + * @generated + */ + public timeprop_java_base() + { + super(); + + setLogger( logger, timeprop_java_base.class.getName() ); + + + // Properties + addProperty(prop); + + } + + + + /** + * The main function of your component. If no args are provided, then the + * CORBA object is not bound to an SCA Domain or NamingService and can + * be run as a standard Java application. + * + * @param args + * @generated + */ + public static void main(String[] args) + { + final Properties orbProps = new Properties(); + timeprop_java.configureOrb(orbProps); + + try { + Component.start_component(timeprop_java.class, args, orbProps); + } catch (InvalidObjectReference e) { + e.printStackTrace(); + } catch (NotFound e) { + e.printStackTrace(); + } catch (CannotProceed e) { + e.printStackTrace(); + } catch (InvalidName e) { + e.printStackTrace(); + } catch (ServantNotActive e) { + e.printStackTrace(); + } catch (WrongPolicy e) { + e.printStackTrace(); + } catch (InstantiationException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + } +} diff --git a/redhawk/src/testing/sdr/dom/components/timeprop_java/java/startJava.sh b/redhawk/src/testing/sdr/dom/components/timeprop_java/java/startJava.sh new file mode 100755 index 000000000..a76c5a36d --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/timeprop_java/java/startJava.sh @@ -0,0 +1,38 @@ +#!/bin/sh +# +# This file is protected by Copyright. Please refer to the COPYRIGHT file +# distributed with this source distribution. +# +# This file is part of REDHAWK core. +# +# REDHAWK core is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation, either version 3 of the License, or (at your option) any +# later version. +# +# REDHAWK core is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +# details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/. +# + +#Sun ORB start line +# Important, the $@ must be quoted "$@" for arguments to be passed correctly +myDir=`dirname $0` +JAVA_LIBDIR=${myDir}/../../../../../base/framework/java +JAVA_CLASSPATH=${JAVA_LIBDIR}/apache-commons-lang-2.4.jar:${JAVA_LIBDIR}/log4j-1.2.15.jar:${JAVA_LIBDIR}/CFInterfaces.jar:${JAVA_LIBDIR}/ossie.jar:${myDir}/timeprop_java.jar:${myDir}:${myDir}/bin:${CLASSPATH} + +# Path for Java +if test -x $JAVA_HOME/bin/java; then + JAVA=$JAVA_HOME/bin/java +else + JAVA=java +fi + +# NOTE: the $@ must be quoted "$@" for arguments to be passed correctly + +#Sun ORB start line +exec $JAVA -cp ${JAVA_CLASSPATH} timeprop_java.java.timeprop_java "$@" diff --git a/redhawk/src/testing/sdr/dom/components/timeprop_java/timeprop_java.prf.xml b/redhawk/src/testing/sdr/dom/components/timeprop_java/timeprop_java.prf.xml new file mode 100644 index 000000000..fac40ad7c --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/timeprop_java/timeprop_java.prf.xml @@ -0,0 +1,9 @@ + + + + + value + + + + diff --git a/redhawk/src/testing/sdr/dom/components/timeprop_java/timeprop_java.scd.xml b/redhawk/src/testing/sdr/dom/components/timeprop_java/timeprop_java.scd.xml new file mode 100644 index 000000000..df94ceaf5 --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/timeprop_java/timeprop_java.scd.xml @@ -0,0 +1,45 @@ + + + + 2.2 + + resource + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/redhawk/src/testing/sdr/dom/components/timeprop_java/timeprop_java.spd.xml b/redhawk/src/testing/sdr/dom/components/timeprop_java/timeprop_java.spd.xml new file mode 100644 index 000000000..97d2d1971 --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/timeprop_java/timeprop_java.spd.xml @@ -0,0 +1,26 @@ + + + + + + null + + + + + + + + + The implementation contains descriptive information about the template for a software resource. + + + java/startJava.sh + + + + + + + + From bc5fd578c160adf248d543e8f68c17b15b099357 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Sat, 7 Jan 2017 13:34:12 -0500 Subject: [PATCH 0638/1644] Refs CF-1420. Test components --- redhawk/src/configure.ac | 2 ++ redhawk/src/testing/Makefile.am | 2 ++ 2 files changed, 4 insertions(+) diff --git a/redhawk/src/configure.ac b/redhawk/src/configure.ac index aba73bf4e..2412121b6 100644 --- a/redhawk/src/configure.ac +++ b/redhawk/src/configure.ac @@ -358,6 +358,7 @@ AC_CONFIG_FILES(Makefile \ testing/sdr/dom/components/javaDep/javaDep/Makefile \ testing/sdr/dom/components/java_comp/java/Makefile \ testing/sdr/dom/components/msg_through_java/java/Makefile \ + testing/sdr/dom/components/timeprop_java/java/Makefile \ testing/sdr/dom/components/HardLimit/HardLimit_java_impl1/Makefile \ testing/sdr/dom/components/SimpleComponent/SimpleComponent_cpp_impl1/Makefile \ testing/sdr/dom/components/BasicAC/basicac_java_impl1/Makefile \ @@ -388,6 +389,7 @@ AC_CONFIG_FILES(Makefile \ testing/sdr/dom/components/Property_CPP/cpp/Makefile \ testing/sdr/dom/components/msg_through_cpp/cpp/Makefile \ testing/sdr/dom/components/commandline_prop/cpp/Makefile \ + testing/sdr/dom/components/timeprop_cpp/cpp/Makefile \ testing/sdr/dom/components/nocommandline_prop/cpp/Makefile \ testing/sdr/dom/components/Property_JAVA/java/Makefile \ testing/sdr/dom/components/foo/bar/comp/cpp/Makefile \ diff --git a/redhawk/src/testing/Makefile.am b/redhawk/src/testing/Makefile.am index 393578b6f..ebe44c6a2 100644 --- a/redhawk/src/testing/Makefile.am +++ b/redhawk/src/testing/Makefile.am @@ -71,6 +71,7 @@ SUBDIRS = sdr/dev/devices/ExecutableDevice \ sdr/dom/components/foo/bar/comp/cpp \ sdr/dom/components/TestCppOptionalProps/cpp \ sdr/dom/components/cpp_with_deps/cpp \ + sdr/dom/components/timeprop_cpp/cpp \ sdr/dom/components/msg_through_cpp/cpp if HAVE_JAVASUPPORT @@ -84,6 +85,7 @@ SUBDIRS += sdr/dev/devices/BasicTestDevice_java/java \ sdr/dom/components/javaDep/javaDep \ sdr/dom/components/java_comp/java \ sdr/dom/components/msg_through_java/java \ + sdr/dom/components/timeprop_java/java \ sdr/dom/components/HardLimit/HardLimit_java_impl1 \ sdr/dom/components/PropertyChangeEventsJava/PropertyChangeEventsJava_java_impl1 \ sdr/dom/components/TestJavaProps \ From 1b7c18d94cd666834223f8a8023f689dc3abd301 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Sat, 7 Jan 2017 14:24:14 -0500 Subject: [PATCH 0639/1644] Refs CF-1420. Timestamp is only returned when requested --- .../src/base/framework/PropertySet_impl.cpp | 4 +- .../src/org/ossie/component/Resource.java | 6 +- .../base/framework/python/ossie/resource.py | 2 +- .../src/testing/tests/test_11_AllPropTypes.py | 75 ++++++++++++++++++- 4 files changed, 79 insertions(+), 8 deletions(-) diff --git a/redhawk/src/base/framework/PropertySet_impl.cpp b/redhawk/src/base/framework/PropertySet_impl.cpp index a7cdbfc83..e64d1a250 100644 --- a/redhawk/src/base/framework/PropertySet_impl.cpp +++ b/redhawk/src/base/framework/PropertySet_impl.cpp @@ -317,9 +317,9 @@ throw (CORBA::SystemException, CF::UnknownProperties) } ++jj; } - configProperties.length(configProperties.length() + 1); + /*configProperties.length(configProperties.length() + 1); configProperties[configProperties.length()-1].id = CORBA::string_dup(_propertyQueryTimestamp.c_str()); - configProperties[configProperties.length()-1].value <<= _makeTime(-1,0,0); + configProperties[configProperties.length()-1].value <<= _makeTime(-1,0,0);*/ } else { // For queries of length > 0, return all requested pairs in propertySet CF::Properties invalidProperties; diff --git a/redhawk/src/base/framework/java/ossie/src/org/ossie/component/Resource.java b/redhawk/src/base/framework/java/ossie/src/org/ossie/component/Resource.java index 4c93bd429..4c8e82c6a 100644 --- a/redhawk/src/base/framework/java/ossie/src/org/ossie/component/Resource.java +++ b/redhawk/src/base/framework/java/ossie/src/org/ossie/component/Resource.java @@ -660,7 +660,7 @@ public void query(final PropertiesHolder configProperties) throws UnknownPropert logger.trace("query()"); // For queries of zero length, return all id/value pairs in propertySet if (configProperties.value.length == 0) { - final ArrayList props = new ArrayList(this.propSet.size()+1); + final ArrayList props = new ArrayList(this.propSet.size()); for (final IProperty prop : this.propSet.values()) { logger.trace("Querying property: " + prop); if (prop.isQueryable()) { @@ -681,9 +681,9 @@ public void query(final PropertiesHolder configProperties) throws UnknownPropert } } - final Any anytime = ORB.init().create_any(); + /*final Any anytime = ORB.init().create_any(); CF.UTCTimeHelper.insert(anytime, this._makeTime((short)-1,0,0)); - props.add(new DataType(_propertyQueryTimestamp, anytime)); + props.add(new DataType(_propertyQueryTimestamp, anytime));*/ configProperties.value = props.toArray(new DataType[props.size()]); return; diff --git a/redhawk/src/base/framework/python/ossie/resource.py b/redhawk/src/base/framework/python/ossie/resource.py index 29c470b83..c82433d22 100644 --- a/redhawk/src/base/framework/python/ossie/resource.py +++ b/redhawk/src/base/framework/python/ossie/resource.py @@ -734,7 +734,7 @@ def query(self, configProperties): except: self.propertySetAccess.release() raise - rv.append(CF.DataType(self._propertyQueryTimestamp, any.to_any(_makeTime()))) + #rv.append(CF.DataType(self._propertyQueryTimestamp, any.to_any(_makeTime()))) # otherwise get only the requested ones else: diff --git a/redhawk/src/testing/tests/test_11_AllPropTypes.py b/redhawk/src/testing/tests/test_11_AllPropTypes.py index 4b92eefd5..3c74ba26e 100644 --- a/redhawk/src/testing/tests/test_11_AllPropTypes.py +++ b/redhawk/src/testing/tests/test_11_AllPropTypes.py @@ -21,9 +21,80 @@ from omniORB import any import unittest from _unitTestHelpers import scatest -from ossie.cf import CF +from ossie.cf import CF, CF__POA from omniORB import CORBA -import struct +from ossie.utils import sb +import struct, time, os + +globalsdrRoot = os.environ['SDRROOT'] + +class PropertyChangeListener_Receiver(CF__POA.PropertyChangeListener): + def __init__(self): + self.rcv_event = None + + def propertyChange( self, pce ) : + self.rcv_event = pce + +class TimeTest(scatest.CorbaTestCase): + def setUp(self): + sb.setDEBUG(False) + self.test_comp = "Sandbox" + # Flagrant violation of sandbox API: if the sandbox singleton exists, + # clean up previous state and dispose of it. + if sb.domainless._sandbox: + sb.domainless._sandbox.shutdown() + sb.domainless._sandbox = None + + def tearDown(self): + sb.release() + sb.setDEBUG(False) + os.environ['SDRROOT'] = globalsdrRoot + + def basetest_getTime(self, comp_name): + _timeprop = CF.DataType(id='QUERY_TIMESTAMP',value=any.to_any(None)) + comp = sb.launch(comp_name) + _prop=CF.DataType(id='prop',value=any.to_any(None)) + _retval = comp.query([_prop]) + self.assertEqual(_retval[0].value._v, 'value') + self.assertEqual(len(_retval), 1) + + _retval = comp.query([]) + self.assertEqual(_retval[0].value._v, 'value') + self.assertEqual(len(_retval), 1) + + _retval = comp.query([_prop, _timeprop]) + self.assertEqual(_retval[0].value._v, 'value') + self.assertEqual(len(_retval), 2) + + myl = PropertyChangeListener_Receiver() + t=float(0.5) + regid=comp.registerPropertyListener( myl._this(), ['prop'],t) + + comp.prop = 'hello' + time.sleep(1) + + _retval = comp.query([_prop]) + self.assertEqual(_retval[0].value._v, 'hello') + self.assertEqual(myl.rcv_event.properties[0].value._v, 'hello') + + _retval = comp.query([_timeprop]) + self.assertEqual(len(_retval), 1) + self.assertEqual(_retval[0].value._v.tcstatus, 1) + _time1 = myl.rcv_event.timestamp.twsec + myl.rcv_event.timestamp.tfsec + _time2 = _retval[0].value._v.twsec + _retval[0].value._v.tfsec + between = True + if _time2 - _time1 < 0.25 or _time2 - _time1 > 0.75: + between = False + self.assertEqual(between, True) + + def test_getTimeCpp(self): + self.basetest_getTime('timeprop_cpp') + + def test_getTimePython(self): + self.basetest_getTime('timeprop_py') + + def test_getTimeJava(self): + self.basetest_getTime('timeprop_java') class TestAllTypes(scatest.CorbaTestCase): def setUp(self): From 7fc98473d76f1c2281c7fc8204f5c13533472020 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 9 Jan 2017 15:33:05 -0500 Subject: [PATCH 0640/1644] CF-1656 Add a BufferManager class (and associated implementation classes) that provides thread-based caching of allocated memory to reduce the cost of frequent allocations with shared_buffer --- redhawk/src/base/framework/BufferManager.cpp | 436 ++++++++++++++++++ redhawk/src/base/framework/Makefile.am | 4 +- redhawk/src/base/framework/inplace_list.h | 239 ++++++++++ .../src/base/include/ossie/BufferManager.h | 186 ++++++++ redhawk/src/base/include/ossie/Makefile.am | 3 +- .../src/base/include/ossie/shared_buffer.h | 5 +- redhawk/src/testing/cpp/SharedBufferTest.cpp | 1 + 7 files changed, 871 insertions(+), 3 deletions(-) create mode 100644 redhawk/src/base/framework/BufferManager.cpp create mode 100644 redhawk/src/base/framework/inplace_list.h create mode 100644 redhawk/src/base/include/ossie/BufferManager.h diff --git a/redhawk/src/base/framework/BufferManager.cpp b/redhawk/src/base/framework/BufferManager.cpp new file mode 100644 index 000000000..cd1537ae9 --- /dev/null +++ b/redhawk/src/base/framework/BufferManager.cpp @@ -0,0 +1,436 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK core. + * + * REDHAWK core is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +#include + +#include +#include "inplace_list.h" + +using redhawk::BufferManager; + +struct BufferManager::CacheBlock { + CacheBlock(size_t size) : + size(size), + cache(0) + { + } + + static CacheBlock* from_pointer(void* ptr) + { + CacheBlock* block = reinterpret_cast(ptr); + return block - 1; + } + + void* data() + { + return this + 1; + } + + static size_t required_bytes(size_t bytes) + { + return bytes + sizeof(CacheBlock); + } + + static size_t usable_bytes(size_t bytes) + { + return bytes - sizeof(CacheBlock); + } + + const size_t size; + BufferManager::BufferCache* cache; +}; + +class BufferManager::BufferCache { +public: + // The CacheNode structure contains fields that are only required when a + // memory block is being stored in the cache + struct CacheNode : public CacheBlock { + CacheNode* prev; + CacheNode* next; + size_t lastUsed; + }; + + BufferCache(BufferManager* manager) : + _manager(manager), + _enabled(true), + _time(0), + _maxBytes(-1), + _maxBlocks(-1), + _maxAge(-1), + _hits(0), + _misses(0), + _currentBytes(0), + _refcount(1) + { + } + + CacheBlock* fetch(size_t bytes) + { + boost::mutex::scoped_lock lock(_lock); + CacheNode* node = _fetch(bytes); + if (!node) { + ++_misses; + return 0; + } + + ++_hits; + _currentBytes -= node->size; + _manager->_decreaseSize(node->size); + return node; + } + + void store(CacheBlock* block) + { + // Overlay the CacheNode struct on the block + CacheNode* node = static_cast(block); + boost::mutex::scoped_lock lock(_lock); + node->lastUsed = ++_time; + _cache.push_front(*node); + _currentBytes += node->size; + _manager->_increaseSize(node->size); + _compact(); + } + + void enable(bool enabled) + { + boost::mutex::scoped_lock lock(_lock); + _enabled = enabled; + if (!_enabled) { + _compact(); + } + } + + void setMaxBytes(size_t bytes) + { + boost::mutex::scoped_lock lock(_lock); + _maxBytes = bytes; + _compact(); + } + + void setMaxBlocks(size_t blocks) + { + boost::mutex::scoped_lock lock(_lock); + _maxBlocks = blocks; + _compact(); + } + + void setMaxAge(size_t age) + { + boost::mutex::scoped_lock lock(_lock); + _maxAge = age; + _compact(); + } + + size_t hits() + { + return _hits; + } + + size_t misses() + { + return _misses; + } + + size_t size() + { + return _cache.size(); + } + + void incref() + { + __sync_fetch_and_add(&_refcount, 1); + } + + bool decref() + { + size_t count = __sync_sub_and_fetch(&_refcount, 1); + if (count == 0) { + delete this; + return false; + } + return true; + } + + static void release(BufferCache* cache) + { + cache->decref(); + } + +private: + ~BufferCache() + { + _enabled = false; + _compact(); + _manager->_removeCache(this); + } + + inline CacheNode* _fetch(size_t bytes) + { + for (CacheList::iterator iter = _cache.begin(); iter != _cache.end(); ++iter) { + if (iter->size == bytes) { + CacheNode* node = iter.get_node(); + _cache.erase(iter); + return node; + } + } + return 0; + } + + inline bool _overThreshold() + { + if (_cache.empty()) { + return false; + } + if (!_enabled) { + return true; + } + size_t age = _time - _cache.back().lastUsed; + return (age > _maxAge) || (_currentBytes > _maxBytes) || (_cache.size() > _maxBlocks); + } + + inline void _compact() + { + size_t previous = _currentBytes; + while (_overThreshold()) { + CacheNode* node = &_cache.back(); + _cache.pop_back(); + _currentBytes -= node->size; + _manager->_deallocate(node); + } + size_t delta = previous - _currentBytes; + if (delta > 0) { + _manager->_decreaseSize(delta); + } + } + + BufferManager* _manager; + boost::mutex _lock; + typedef redhawk::inplace_list CacheList; + CacheList _cache; + bool _enabled; + size_t _time; + + size_t _maxBytes; + size_t _maxBlocks; + size_t _maxAge; + size_t _hits; + size_t _misses; + size_t _currentBytes; + volatile size_t _refcount; +}; + +BufferManager::BufferManager() : + _threadCache(&BufferCache::release), + _enabled(true), + _maxThreadBytes(-1), + _maxThreadBlocks(-1), + _maxThreadAge(-1), + _hits(0), + _misses(0), + _currentBytes(0), + _highWaterBytes(0) +{ +} + +BufferManager::~BufferManager() +{ +} + +BufferManager& BufferManager::Instance() +{ + return _instance; +} + +void* BufferManager::allocate(size_t bytes) +{ + bytes = _nearestSize(bytes); + + BufferCache* cache = 0; + CacheBlock* block = 0; + if (_enabled) { + cache = _getCache(); + cache->incref(); + block = cache->fetch(bytes); + } + if (!block) { + block = _allocate(bytes); + block->cache = cache; + } + return block->data(); +} + +void BufferManager::deallocate(void* ptr) +{ + CacheBlock* block = CacheBlock::from_pointer(ptr); + BufferCache* cache = block->cache; + if (cache) { + if (cache->decref() && _enabled) { + cache->store(block); + return; + } + } + _deallocate(block); +} + +size_t BufferManager::_nearestSize(size_t bytes) +{ + // Include cache overhead in rounding + bytes = CacheBlock::required_bytes(bytes); + if (bytes <= 128*1024) { + // Up to 128K, round to nearest 1K + bytes = (bytes + 1023) & ~1023; + } else { + // Round to nearest 4K + bytes = (bytes + 4095) & ~4095; + } + // Remove cache overhead, leaving usable bytes + return CacheBlock::usable_bytes(bytes); +} + +BufferManager::CacheBlock* BufferManager::_allocate(size_t bytes) +{ + void* buffer = ::operator new(CacheBlock::required_bytes(bytes)); + return new (buffer) CacheBlock(bytes); +} + +void BufferManager::_deallocate(CacheBlock* block) +{ + ::operator delete(block); +} + +bool BufferManager::isEnabled() const +{ + return _enabled; +} + +void BufferManager::enable(bool enabled) +{ + _enabled = enabled; + boost::mutex::scoped_lock lock(_lock); + for (CacheList::iterator ii = _caches.begin(); ii != _caches.end(); ++ii) { + (*ii)->enable(enabled); + } +} + +size_t BufferManager::getMaxThreadBytes() const +{ + return _maxThreadBytes; +} + +void BufferManager::setMaxThreadBytes(size_t bytes) +{ + boost::mutex::scoped_lock lock(_lock); + _maxThreadBytes = bytes; + for (CacheList::iterator ii = _caches.begin(); ii != _caches.end(); ++ii) { + (*ii)->setMaxBytes(bytes); + } +} + +size_t BufferManager::getMaxThreadBlocks() const +{ + return _maxThreadBlocks; +} + +void BufferManager::setMaxThreadBlocks(size_t blocks) +{ + boost::mutex::scoped_lock lock(_lock); + _maxThreadBlocks = blocks; + for (CacheList::iterator ii = _caches.begin(); ii != _caches.end(); ++ii) { + (*ii)->setMaxBlocks(blocks); + } +} + +size_t BufferManager::getMaxThreadAge() const +{ + return _maxThreadAge; +} + +void BufferManager::setMaxThreadAge(size_t age) +{ + boost::mutex::scoped_lock lock(_lock); + _maxThreadAge = age; + for (CacheList::iterator ii = _caches.begin(); ii != _caches.end(); ++ii) { + (*ii)->setMaxAge(age); + } +} + +BufferManager::Statistics BufferManager::getStatistics() +{ + boost::mutex::scoped_lock lock(_lock); + Statistics stats; + stats.caches = _caches.size(); + stats.hits = _hits; + stats.misses = _misses; + stats.blocks = 0; + stats.bytes = _currentBytes; + stats.highBytes = _highWaterBytes; + + for (CacheList::iterator iter = _caches.begin(); iter != _caches.end(); ++iter) { + BufferCache* cache = *iter; + stats.hits += cache->hits(); + stats.misses += cache->misses(); + stats.blocks += cache->size(); + } + return stats; +} + +BufferManager::BufferCache* BufferManager::_getCache() +{ + BufferCache* cache = _threadCache.get(); + if (!cache) { + cache = new BufferCache(this); + cache->setMaxBytes(_maxThreadBytes); + cache->setMaxBlocks(_maxThreadBlocks); + cache->setMaxAge(_maxThreadAge); + this->_addCache(cache); + _threadCache.reset(cache); + } + return cache; +} + +void BufferManager::_addCache(BufferCache* cache) +{ + boost::mutex::scoped_lock lock(_lock); + _caches.insert(cache); +} + +void BufferManager::_removeCache(BufferCache* cache) +{ + boost::mutex::scoped_lock lock(_lock); + _hits += cache->hits(); + _misses += cache->misses(); + _caches.erase(cache); +} + +void BufferManager::_increaseSize(size_t bytes) +{ + size_t current = __sync_add_and_fetch(&_currentBytes, bytes); + size_t high = _highWaterBytes; + while (current > high) { + high = __sync_val_compare_and_swap(&_highWaterBytes, high, current); + } +} + +void BufferManager::_decreaseSize(size_t bytes) +{ + __sync_fetch_and_sub(&_currentBytes, bytes); +} + +BufferManager BufferManager::_instance; diff --git a/redhawk/src/base/framework/Makefile.am b/redhawk/src/base/framework/Makefile.am index 8c7ad8f57..7b7f52693 100644 --- a/redhawk/src/base/framework/Makefile.am +++ b/redhawk/src/base/framework/Makefile.am @@ -59,7 +59,9 @@ libossiecf_la_SOURCES = AggregateDevice_impl.cpp \ PropertyMap.cpp \ Versions.cpp \ ExecutorService.cpp \ - UsesPort.cpp + UsesPort.cpp \ + BufferManager.cpp \ + inplace_list.h libossiecf_la_CXXFLAGS = -Wall $(BOOST_CPPFLAGS) $(OMNICOS_CFLAGS) $(OMNIORB_CFLAGS) $(LOG4CXX_FLAGS) # Include the omniORB internal directory, otherwise CorbaUtils will not build diff --git a/redhawk/src/base/framework/inplace_list.h b/redhawk/src/base/framework/inplace_list.h new file mode 100644 index 000000000..9a1eea623 --- /dev/null +++ b/redhawk/src/base/framework/inplace_list.h @@ -0,0 +1,239 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK core. + * + * REDHAWK core is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +namespace redhawk { + + template + struct list_node_traits { + typedef Node node_type; + + static inline void set_prev(node_type& node, node_type* prev) + { + node.*Prev = prev; + } + + static inline node_type* get_prev(const node_type& node) + { + return node.*Prev; + } + + static inline void set_next(node_type& node, node_type* next) + { + node.*Next = next; + } + + static inline node_type* get_next(const node_type& node) + { + return node.*Next; + } + }; + + template + struct list_iterator { + public: + typedef NodeTraits node_traits; + typedef std::bidirectional_iterator_tag iterator_category; + typedef typename NodeTraits::node_type value_type; + typedef ptrdiff_t difference_type; + typedef Node* pointer; + typedef Node& reference; + + list_iterator(pointer node=0) : + _M_node(node) + { + } + + list_iterator(const list_iterator& other) : + _M_node(other.get_node()) + { + } + + list_iterator& operator++() + { + _M_node = node_traits::get_next(*_M_node); + return *this; + } + + list_iterator operator++(int) + { + list_iterator result(*this); + return ++result; + } + + list_iterator& operator--() + { + _M_node = node_traits::get_prev(*_M_node); + return *this; + } + + list_iterator operator--(int) + { + list_iterator result(*this); + return --result; + } + + reference operator*() const + { + return *get_node(); + } + + pointer operator->() const + { + return get_node(); + } + + pointer get_node() const + { + return _M_node; + } + + bool operator==(const list_iterator& other) const + { + return (_M_node == other._M_node); + } + + bool operator!=(const list_iterator& other) const + { + return !(*this == other); + } + + private: + pointer _M_node; + }; + + template > + class inplace_list { + public: + typedef Node node_type; + typedef NodeTraits node_traits; + + typedef list_iterator iterator; + typedef list_iterator const_iterator; + + inplace_list() : + _M_head(0), + _M_tail(0), + _M_size(0) + { + } + + size_t size() const + { + return _M_size; + } + + bool empty() const + { + return (_M_head == 0); + } + + iterator begin() + { + return iterator(_M_head); + } + + iterator end() + { + return iterator(); + } + + const_iterator begin() const + { + return const_iterator(_M_head); + } + + const_iterator end() const + { + return const_iterator(); + } + + void insert(iterator pos, node_type& node) + { + node_type* prev = 0; + node_type* next = 0; + if (pos == begin()) { + next = _M_head; + _M_head = &node; + if (!_M_tail) { + _M_tail = _M_head; + } + } else if (pos == end()) { + prev = _M_tail; + _M_tail = &node; + } else { + prev = node_traits::get_prev(*pos); + next = &(*pos); + } + + if (prev) { + node_traits::set_next(*prev, &node); + } + node_traits::set_prev(node, prev); + node_traits::set_next(node, next); + if (next) { + node_traits::set_prev(*next, &node); + } + ++_M_size; + } + + void erase(iterator iter) + { + node_type* prev = node_traits::get_prev(*iter); + node_type* next = node_traits::get_next(*iter); + if (!prev) { + _M_head = next; + } else { + node_traits::set_next(*prev, next); + } + if (next) { + node_traits::set_prev(*next, prev); + } else { + _M_tail = prev; + } + --_M_size; + } + + void push_front(node_type& node) + { + insert(begin(), node); + } + + node_type& front() + { + return *_M_head; + } + + void pop_back() + { + erase(_M_tail); + } + + node_type& back() + { + return *_M_tail; + } + + private: + node_type* _M_head; + node_type* _M_tail; + size_t _M_size; + }; + +} diff --git a/redhawk/src/base/include/ossie/BufferManager.h b/redhawk/src/base/include/ossie/BufferManager.h new file mode 100644 index 000000000..af8436528 --- /dev/null +++ b/redhawk/src/base/include/ossie/BufferManager.h @@ -0,0 +1,186 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK core. + * + * REDHAWK core is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +#ifndef REDHAWK_BUFFERMANAGER_H +#define REDHAWK_BUFFERMANAGER_H + +#include + +#include +#include + +namespace redhawk { + /** + * Per-thread cache-based allocation. + */ + class BufferManager { + public: + + template + class Allocator : public std::allocator + { + public: + typedef std::allocator base; + typedef typename base::pointer pointer; + typedef typename base::value_type value_type; + typedef typename base::size_type size_type; + + static const size_type MIN_ELEMENTS = 1024 / sizeof(value_type); + + template + struct rebind { + typedef Allocator other; + }; + + Allocator() throw() : + base() + { + } + + Allocator(const Allocator& other) throw() : + base(other) + { + } + + template + Allocator(const Allocator& other) throw() : + base(other) + { + } + + pointer allocate(size_type count) + { + if (count >= MIN_ELEMENTS) { + return static_cast(BufferManager::Allocate(count * sizeof(value_type))); + } else { + return base::allocate(count); + } + } + + void deallocate(pointer ptr, size_type count) + { + if (count >= MIN_ELEMENTS) { + BufferManager::Deallocate(ptr); + } else { + base::deallocate(ptr, count); + } + } + }; + + BufferManager(); + ~BufferManager(); + + static BufferManager& Instance(); + + static inline void* Allocate(size_t bytes) + { + return Instance().allocate(bytes); + } + + static inline void Deallocate(void* ptr) + { + return Instance().deallocate(ptr); + } + + void* allocate(size_t bytes); + void deallocate(void* ptr); + + bool isEnabled() const; + void enable(bool enabled); + + size_t getMaxThreadBytes() const; + void setMaxThreadBytes(size_t bytes); + + size_t getMaxThreadBlocks() const; + void setMaxThreadBlocks(size_t blocks); + + size_t getMaxThreadAge() const; + void setMaxThreadAge(size_t age); + + // Statistical information + struct Statistics { + size_t caches; + size_t hits; + size_t misses; + size_t blocks; + size_t bytes; + size_t highBytes; + }; + + Statistics getStatistics(); + + private: + BufferManager(const BufferManager&); + BufferManager& operator=(const BufferManager&); + + class CacheBlock; + friend class CacheBlock; + + class BufferCache; + friend class BufferCache; + + size_t _nearestSize(size_t bytes); + CacheBlock* _allocate(size_t bytes); + void _deallocate(CacheBlock* ptr); + + void _addCache(BufferCache* cache); + void _removeCache(BufferCache* cache); + BufferCache* _getCache(); + + void _increaseSize(size_t bytes); + void _decreaseSize(size_t bytes); + + typedef std::set CacheList; + boost::mutex _lock; + CacheList _caches; + boost::thread_specific_ptr _threadCache; + + bool _enabled; + size_t _maxThreadBytes; + size_t _maxThreadBlocks; + size_t _maxThreadAge; + + size_t _hits; + size_t _misses; + + volatile size_t _currentBytes; + volatile size_t _highWaterBytes; + + static BufferManager _instance; + }; + + + template + inline bool operator==(const BufferManager::Allocator& a1, + const BufferManager::Allocator& a2) + { + return true; + } + + template + inline bool operator!=(const BufferManager::Allocator& a1, + const BufferManager::Allocator& a2) + { + return false; + } + +} // namespace redhawk + +#endif // OSSIE_THREADCACHE_H diff --git a/redhawk/src/base/include/ossie/Makefile.am b/redhawk/src/base/include/ossie/Makefile.am index e88da5b93..de887a55b 100644 --- a/redhawk/src/base/include/ossie/Makefile.am +++ b/redhawk/src/base/include/ossie/Makefile.am @@ -65,7 +65,8 @@ pkginclude_HEADERS = AggregateDevice_impl.h \ Versions.h \ shared_buffer.h \ ExecutorService.h \ - UsesPort.h + UsesPort.h \ + BufferManager.h nobase_pkginclude_HEADERS = internal/equals.h \ logging/rh_logger.h \ diff --git a/redhawk/src/base/include/ossie/shared_buffer.h b/redhawk/src/base/include/ossie/shared_buffer.h index b9495c743..e512a9c7b 100644 --- a/redhawk/src/base/include/ossie/shared_buffer.h +++ b/redhawk/src/base/include/ossie/shared_buffer.h @@ -25,6 +25,7 @@ #include #include +#include "BufferManager.h" #ifdef _RH_SHARED_BUFFER_DEBUG #include "debug/check.h" @@ -483,8 +484,10 @@ namespace redhawk { /// @brief The default allocator class. #ifdef _RH_SHARED_BUFFER_DEBUG typedef ::redhawk::debug::checked_allocator default_allocator; -#else +#elif defined(_RH_SHARED_BUFFER_USE_STD_ALLOC) typedef std::allocator default_allocator; +#else + typedef ::redhawk::BufferManager::Allocator default_allocator; #endif /** diff --git a/redhawk/src/testing/cpp/SharedBufferTest.cpp b/redhawk/src/testing/cpp/SharedBufferTest.cpp index a70e2bb79..f2e1399aa 100644 --- a/redhawk/src/testing/cpp/SharedBufferTest.cpp +++ b/redhawk/src/testing/cpp/SharedBufferTest.cpp @@ -22,6 +22,7 @@ #include +#define _RH_SHARED_BUFFER_USE_STD_ALLOC #include CPPUNIT_TEST_SUITE_REGISTRATION(SharedBufferTest); From 94d5e91b4c0d168e53dc882419df89c03ebfdb2f Mon Sep 17 00:00:00 2001 From: 8530 <8530@vm-131.vsi-corp.com> Date: Thu, 12 Jan 2017 13:20:13 -0500 Subject: [PATCH 0641/1644] fix uses port abiquity from adding extra external port, CF-1660 --- redhawk/src/testing/tests/test_13_RedhawkModule.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/redhawk/src/testing/tests/test_13_RedhawkModule.py b/redhawk/src/testing/tests/test_13_RedhawkModule.py index e913aa056..48e958892 100644 --- a/redhawk/src/testing/tests/test_13_RedhawkModule.py +++ b/redhawk/src/testing/tests/test_13_RedhawkModule.py @@ -681,7 +681,7 @@ def test_connect(self): for comp in app1.comps + app2.comps: pre.extend(comp.runTest(0, [])) - app1.connect(app2) + app1.connect(app2, usesPortName="resource_out") # Tally up the connections to check that a new one has been made post = [] From ea4be2eca23fafd145a8054a24b0fa340ae99915 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 13 Jan 2017 11:24:48 -0500 Subject: [PATCH 0642/1644] CF-1656 Unit tests for BufferManager --- .../src/base/framework/ExecutorService.cpp | 40 +- .../src/base/include/ossie/ExecutorService.h | 7 + redhawk/src/testing/cpp/BufferManagerTest.cpp | 444 ++++++++++++++++++ redhawk/src/testing/cpp/BufferManagerTest.h | 73 +++ redhawk/src/testing/cpp/Makefile.am | 1 + 5 files changed, 544 insertions(+), 21 deletions(-) create mode 100644 redhawk/src/testing/cpp/BufferManagerTest.cpp create mode 100644 redhawk/src/testing/cpp/BufferManagerTest.h diff --git a/redhawk/src/base/framework/ExecutorService.cpp b/redhawk/src/base/framework/ExecutorService.cpp index bf8915521..1e32ca73c 100644 --- a/redhawk/src/base/framework/ExecutorService.cpp +++ b/redhawk/src/base/framework/ExecutorService.cpp @@ -28,6 +28,11 @@ ExecutorService::ExecutorService() : { } +ExecutorService::~ExecutorService() +{ + stop(); +} + void ExecutorService::start () { boost::mutex::scoped_lock lock(_mutex); @@ -72,31 +77,24 @@ void ExecutorService::_run () { boost::mutex::scoped_lock lock(_mutex); while (_running) { - while (!_queue.empty()) { - // Start at the front of the queue every time--a task may - // have been added while the lock was released to service - // the last task + if (_queue.empty()) { + _cond.wait(lock); + } else { task_queue::iterator task = _queue.begin(); if (task->first > boost::get_system_time()) { // Head of queue is scheduled in the future - break; - } + boost::system_time when = task->first; + _cond.timed_wait(lock, when); + } else { + // Copy the task's function and remove it from the queue + func_type func = task->second; + _queue.erase(task); - // Copy the task's function and remove it from the queue - func_type func = task->second; - _queue.erase(task); - - // Run task with the lock released - lock.unlock(); - func(); - lock.lock(); - } - - if (_queue.empty()) { - _cond.wait(lock); - } else { - boost::system_time when = _queue.front().first; - _cond.timed_wait(lock, when); + // Run task with the lock released + lock.unlock(); + func(); + lock.lock(); + } } } } diff --git a/redhawk/src/base/include/ossie/ExecutorService.h b/redhawk/src/base/include/ossie/ExecutorService.h index e318aea28..24583fe79 100644 --- a/redhawk/src/base/include/ossie/ExecutorService.h +++ b/redhawk/src/base/include/ossie/ExecutorService.h @@ -48,6 +48,13 @@ namespace redhawk { */ ExecutorService(); + /** + * @brief Destroys the %ExecutorService. + * + * The executor thread is stopped and all queued functions are purged. + */ + ~ExecutorService(); + /** * @brief Starts executing scheduled functions. * diff --git a/redhawk/src/testing/cpp/BufferManagerTest.cpp b/redhawk/src/testing/cpp/BufferManagerTest.cpp new file mode 100644 index 000000000..d6574d6bb --- /dev/null +++ b/redhawk/src/testing/cpp/BufferManagerTest.cpp @@ -0,0 +1,444 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK core. + * + * REDHAWK core is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +#include "BufferManagerTest.h" +#include + +#include + +CPPUNIT_TEST_SUITE_REGISTRATION(BufferManagerTest); + +void BufferManagerTest::setUp() +{ + _manager = &redhawk::BufferManager::Instance(); + + // (Re-)enable the buffer manager + _manager->enable(true); + + // Reset cache policies + _manager->setMaxThreadBytes(-1); + _manager->setMaxThreadBlocks(-1); + _manager->setMaxThreadAge(-1); +} + +void BufferManagerTest::tearDown() +{ + // Clean up all allocations from the test + std::for_each(_allocations.begin(), _allocations.end(), &redhawk::BufferManager::Deallocate); + _allocations.clear(); + + // Disable the buffer manager to return all memory to the operating system + _manager->enable(false); +} + +void BufferManagerTest::testBasicAllocate() +{ + // Make sure a simple allocation succeeds, then return it to the cache + const size_t SMALL_BYTES = 1000; + void* buffer = _allocate(SMALL_BYTES); + CPPUNIT_ASSERT(buffer != 0); + _deallocate(buffer); + + // Allocate a different-sized buffer that cannot re-use the prior buffer + const size_t LARGE_BYTES = 128*1024; + void* large_buffer = _allocate(LARGE_BYTES); + CPPUNIT_ASSERT(large_buffer != 0); + CPPUNIT_ASSERT(buffer != large_buffer); + + // Allocate the original size and check that it returned the same buffer + void* buffer2 = _allocate(SMALL_BYTES); + CPPUNIT_ASSERT_EQUAL(buffer, buffer2); + + // Release the large buffer, and allocate another block of the smaller size + _deallocate(large_buffer); + buffer2 = _allocate(SMALL_BYTES); + CPPUNIT_ASSERT(buffer2 != 0); + CPPUNIT_ASSERT(buffer2 != buffer); + CPPUNIT_ASSERT(buffer2 != large_buffer); +} + +void BufferManagerTest::testAllocator() +{ + typedef std::vector > FloatVec; + + // Create a 1K-element vector; the allocation had better succeed + FloatVec vec; + vec.resize(1024); + float* buffer = vec.data(); + CPPUNIT_ASSERT(buffer != 0); + + // Resize vector up enough that it gets a different allocation + const size_t ELEMENT_COUNT = 65536; + vec.resize(ELEMENT_COUNT); + float* large_buffer = vec.data(); + CPPUNIT_ASSERT(large_buffer != buffer); + + // Clear the vector's buffer + size_t blocks_pre = _manager->getStatistics().blocks; + { + // Swapping with a new, empty vector is the most reliable way to reset + // the vector's internal buffer; when the temporary gets destroyed at + // the end of the scope, it should deallocate the buffer + FloatVec tmp; + vec.swap(tmp); + } + CPPUNIT_ASSERT(vec.data() != large_buffer); + size_t blocks_post = _manager->getStatistics().blocks; + CPPUNIT_ASSERT_EQUAL(blocks_pre + 1, blocks_post); + + // Resize back up to the last used size and check that we got the same + // buffer back + vec.resize(ELEMENT_COUNT); + CPPUNIT_ASSERT_EQUAL(large_buffer, vec.data()); +} + +void BufferManagerTest::testEnable() +{ + // Start enabled and check that it reports true + _manager->enable(true); + CPPUNIT_ASSERT(_manager->isEnabled()); + + // Disable the buffer manager and check that it reports false + _manager->enable(false); + CPPUNIT_ASSERT_EQUAL(false, _manager->isEnabled()); + + // The cache(s) should be empty + redhawk::BufferManager::Statistics stats = _manager->getStatistics(); + CPPUNIT_ASSERT_EQUAL((size_t) 0, stats.bytes); + CPPUNIT_ASSERT_EQUAL((size_t) 0, stats.blocks); + + // Allocate and deallocate some buffers; the cache(s) should still be empty + _fillCache(16, 8192); + stats = _manager->getStatistics(); + CPPUNIT_ASSERT_EQUAL((size_t) 0, stats.bytes); + CPPUNIT_ASSERT_EQUAL((size_t) 0, stats.blocks); + + // Re-enable and allocate more buffers + _manager->enable(true); + _fillCache(16, 8192); + stats = _manager->getStatistics(); + CPPUNIT_ASSERT(stats.bytes >= (16*8192)); + CPPUNIT_ASSERT_EQUAL((size_t) 16, stats.blocks); + + // Disable the buffer manager again; it should purge the caches + _manager->enable(false); + stats = _manager->getStatistics(); + CPPUNIT_ASSERT_EQUAL((size_t) 0, stats.bytes); + CPPUNIT_ASSERT_EQUAL((size_t) 0, stats.blocks); +} + +void BufferManagerTest::testStatistics() +{ + // The cache should be clear (tearDown is supposed to clear it for us) + redhawk::BufferManager::Statistics pre_stats = _manager->getStatistics(); + CPPUNIT_ASSERT_EQUAL((size_t) 0, pre_stats.blocks); + CPPUNIT_ASSERT_EQUAL((size_t) 0, pre_stats.bytes); + + // Allocate in increasing sizes; each one should be a cache miss + size_t total_blocks = 8; + size_t total_bytes = 0; + size_t current_size = 1024; + for (size_t ii = 0; ii < total_blocks; ++ii) { + _deallocate(_allocate(current_size)); + total_bytes += current_size; + current_size <<= 1; + } + redhawk::BufferManager::Statistics post_stats = _manager->getStatistics(); + size_t hits = post_stats.hits - pre_stats.hits; + size_t misses = post_stats.misses - pre_stats.misses; + CPPUNIT_ASSERT_EQUAL((size_t) 0, hits); + CPPUNIT_ASSERT_EQUAL((size_t) total_blocks, misses); + CPPUNIT_ASSERT(post_stats.blocks >= total_blocks); + CPPUNIT_ASSERT(post_stats.bytes >= total_bytes); + + // Allocate a few blocks of sizes that should be in the cache; they should + // all be hits + current_size = 2048; + for (size_t ii = 0; ii < 4; ++ii) { + pre_stats = post_stats; + _deallocate(_allocate(current_size)); + current_size <<= 2; + post_stats = _manager->getStatistics(); + hits = post_stats.hits - pre_stats.hits; + misses = post_stats.misses - pre_stats.misses; + CPPUNIT_ASSERT_EQUAL((size_t) 1, hits); + CPPUNIT_ASSERT_EQUAL((size_t) 0, misses); + } + + // Exceed the high water mark + pre_stats = post_stats; + size_t gap = std::min(pre_stats.highBytes - pre_stats.bytes, (size_t) 1024); + size_t count = (gap / 1024) + 2; + _fillCache(count, 1024); + post_stats = _manager->getStatistics(); + CPPUNIT_ASSERT(post_stats.highBytes > pre_stats.highBytes); +} + +void BufferManagerTest::testThreading() +{ + // Pre-cache a buffer on the current thread + _fillCache(1, 1024); + redhawk::BufferManager::Statistics pre_stats = _manager->getStatistics(); + + // Allocate a buffer on the executor service's thread + redhawk::ExecutorService service; + service.start(); + boost::packaged_task task(boost::bind(&BufferManagerTest::_allocate, this, 1024)); + boost::unique_future future = task.get_future(); + service.execute(boost::ref(task)); + void* buffer = future.get(); + + // It should be a new buffer, not one from the cache; also, a new cache + // should have been created + redhawk::BufferManager::Statistics post_stats = _manager->getStatistics(); + CPPUNIT_ASSERT_EQUAL(pre_stats.caches + 1, post_stats.caches); + CPPUNIT_ASSERT_EQUAL(pre_stats.blocks, post_stats.blocks); + CPPUNIT_ASSERT_EQUAL(pre_stats.bytes, post_stats.bytes); + + // Free the buffers allocated on the other thread; it should go back into + // the executor thread's cache + _deallocate(buffer); + post_stats = _manager->getStatistics(); + CPPUNIT_ASSERT_EQUAL(pre_stats.blocks + 1, post_stats.blocks); + size_t delta = post_stats.bytes - pre_stats.bytes; + CPPUNIT_ASSERT(delta >= 1024); + + // Allocate two buffers on the current thread; only one of them should come + // from the cache--the other buffer is in the executor thread's cache + CPPUNIT_ASSERT_EQUAL((size_t) 2, post_stats.blocks); + pre_stats = post_stats; + void* buffer1 = _allocate(1024); + void* buffer2 = _allocate(1024); + post_stats = _manager->getStatistics(); + CPPUNIT_ASSERT_EQUAL(pre_stats.blocks - 1, post_stats.blocks); + + // Deallocate both buffers on the executor thread + pre_stats = post_stats; + boost::packaged_task deallocate1(boost::bind(&BufferManagerTest::_deallocate, this, buffer1)); + boost::packaged_task deallocate2(boost::bind(&BufferManagerTest::_deallocate, this, buffer2)); + service.execute(boost::ref(deallocate1)); + service.execute(boost::ref(deallocate2)); + deallocate1.get_future().wait(); + deallocate2.get_future().wait(); + + // Make sure that the buffers returned to the cache + post_stats = _manager->getStatistics(); + CPPUNIT_ASSERT_EQUAL(pre_stats.blocks + 2, post_stats.blocks); + CPPUNIT_ASSERT(post_stats.bytes > pre_stats.bytes); + + // End the executable service's thread, which should free that cache; only + // the buffer that was *allocated* on the thread should be freed + pre_stats = post_stats; + service.stop(); + post_stats = _manager->getStatistics(); + CPPUNIT_ASSERT_EQUAL(pre_stats.caches - 1, post_stats.caches); + CPPUNIT_ASSERT_EQUAL(pre_stats.blocks - 1, post_stats.blocks); + CPPUNIT_ASSERT(pre_stats.bytes > post_stats.bytes); +} + +void BufferManagerTest::testPolicyBytes() +{ + // Fill the cache with more than 64K worth of buffers + const size_t SMALL_BYTES = 8192; + const size_t SMALL_LIMIT = 65536; + _fillCache((SMALL_LIMIT / SMALL_BYTES) + 1, SMALL_BYTES); + CPPUNIT_ASSERT(_manager->getStatistics().bytes > SMALL_LIMIT); + + // Limit the cache to 64K; this should free some buffers + _manager->setMaxThreadBytes(65536); + CPPUNIT_ASSERT_EQUAL((size_t) 65536, _manager->getMaxThreadBytes()); + CPPUNIT_ASSERT(_manager->getStatistics().bytes <= _manager->getMaxThreadBytes()); + + // Allocate a couple of buffers and make sure they came from the cache + size_t blocks = _manager->getStatistics().blocks; + void* buffer1 = _allocate(SMALL_BYTES); + void* buffer2 = _allocate(SMALL_BYTES); + CPPUNIT_ASSERT(_manager->getStatistics().blocks < blocks); + + // Bring the limit down a little more; this shouldn't change the cache + // size + const size_t TEST_LIMIT = SMALL_LIMIT - (SMALL_BYTES/2); + CPPUNIT_ASSERT(_manager->getStatistics().bytes <= TEST_LIMIT); + size_t pre_bytes = _manager->getStatistics().bytes; + _manager->setMaxThreadBytes(TEST_LIMIT); + size_t post_bytes = _manager->getStatistics().bytes; + CPPUNIT_ASSERT_EQUAL(pre_bytes, post_bytes); + + // Return one buffer to the cache; this should succeed and remain below the + // limit + pre_bytes = _manager->getStatistics().bytes; + _deallocate(buffer1); + post_bytes = _manager->getStatistics().bytes; + CPPUNIT_ASSERT(post_bytes > pre_bytes); + CPPUNIT_ASSERT(post_bytes <= _manager->getMaxThreadBytes()); + + // Deallocate the second; this would exceed the limit, so the cache should + // free it + pre_bytes = post_bytes; + _deallocate(buffer2); + post_bytes = _manager->getStatistics().bytes; + CPPUNIT_ASSERT_EQUAL(pre_bytes, post_bytes); + + // Increase the max bytes and try to fill past the limit; the cached bytes + // should not exceed the limit, but the should be within a buffer size + // (otherwise it would have accepted the buffer) + const size_t LARGE_LIMIT = 1024 * 1024; + _manager->setMaxThreadBytes(LARGE_LIMIT); + const size_t LARGE_BYTES = 128*1024; + _fillCache(10, LARGE_BYTES); + redhawk::BufferManager::Statistics stats = _manager->getStatistics(); + CPPUNIT_ASSERT(stats.bytes <= LARGE_LIMIT); + CPPUNIT_ASSERT((LARGE_LIMIT - stats.bytes) < LARGE_BYTES); + + // Turn off the byte policy, retaining all buffers from now on + _manager->setMaxThreadBytes(-1); + size_t pre_blocks = stats.blocks; + _fillCache(10, 65536); + stats = _manager->getStatistics(); + CPPUNIT_ASSERT(stats.bytes > LARGE_LIMIT); + CPPUNIT_ASSERT_EQUAL(pre_blocks + 10, stats.blocks); +} + +void BufferManagerTest::testPolicyBlocks() +{ + // Fill the cache with a set number of buffers + const size_t SMALL_BYTES = 8192; + size_t block_count = 12; + _fillCache(block_count, SMALL_BYTES); + CPPUNIT_ASSERT(_manager->getStatistics().blocks >= block_count); + + // Limit the cache to 8 block; this should free some buffers + block_count = 8; + _manager->setMaxThreadBlocks(block_count); + CPPUNIT_ASSERT_EQUAL(block_count, _manager->getMaxThreadBlocks()); + CPPUNIT_ASSERT_EQUAL(block_count, _manager->getStatistics().blocks); + + // Allocate a couple of buffers and make sure they came from the cache + void* buffer1 = _allocate(SMALL_BYTES); + void* buffer2 = _allocate(SMALL_BYTES); + CPPUNIT_ASSERT(_manager->getStatistics().blocks < block_count); + + // Bring the limit down a little more; this shouldn't change the cache + // size + block_count = 7; + size_t pre_blocks = _manager->getStatistics().blocks; + _manager->setMaxThreadBlocks(block_count); + CPPUNIT_ASSERT_EQUAL(pre_blocks, _manager->getStatistics().blocks); + + // Return one buffer to the cache; this should succeed and remain below the + // limit + _deallocate(buffer1); + size_t post_blocks = _manager->getStatistics().blocks; + CPPUNIT_ASSERT(post_blocks > pre_blocks); + CPPUNIT_ASSERT(post_blocks <= _manager->getMaxThreadBlocks()); + + // Deallocate the second; this would exceed the limit, so the cache should + // free it + pre_blocks = post_blocks; + _deallocate(buffer2); + CPPUNIT_ASSERT_EQUAL(pre_blocks, _manager->getStatistics().blocks); + + // Increase the block limit and allocate enough more buffers both hit the + // limit and flush the old buffers + block_count += 5; + _manager->setMaxThreadBlocks(block_count); + const size_t LARGE_BYTES = SMALL_BYTES * 4; + _fillCache(block_count * 2, LARGE_BYTES); + redhawk::BufferManager::Statistics stats = _manager->getStatistics(); + CPPUNIT_ASSERT_EQUAL(block_count, stats.blocks); + CPPUNIT_ASSERT(stats.bytes >= (stats.blocks * LARGE_BYTES)); + + // Turn off the block policy, retaining all buffers from now on + _manager->setMaxThreadBlocks(-1); + pre_blocks = stats.blocks; + _fillCache(10, SMALL_BYTES); + CPPUNIT_ASSERT_EQUAL(pre_blocks + 10, _manager->getStatistics().blocks); +} + +void BufferManagerTest::testPolicyAge() +{ + const size_t SMALL_BYTES = 1024; // 1K + _fillCache(10, SMALL_BYTES); + + // Set a maximum thread age less than the current number of blocks and + // check that some blocks are freed + size_t pre_blocks = _manager->getStatistics().blocks; + CPPUNIT_ASSERT_EQUAL((size_t) 10, pre_blocks); + _manager->setMaxThreadAge(8); + CPPUNIT_ASSERT_EQUAL((size_t) 8, _manager->getMaxThreadAge()); + CPPUNIT_ASSERT(_manager->getStatistics().blocks < pre_blocks); + + // Allocate a bunch of different-sized buffers; this should age off all of + // the smaller buffers + const size_t MEDIUM_BYTES = 65536; // 64K + for (int ii = 0; ii < 2; ++ii) { + _fillCache(5, MEDIUM_BYTES); + } + redhawk::BufferManager::Statistics stats = _manager->getStatistics(); + size_t post_blocks = stats.blocks; + CPPUNIT_ASSERT_EQUAL((size_t) 5, post_blocks); + CPPUNIT_ASSERT(stats.bytes >= (post_blocks * MEDIUM_BYTES)); + + // Cycle another larger buffer to the front just enough times that the + // oldest medium buffer is still in the cache + pre_blocks = post_blocks; + const size_t LARGE_BYTES = 1024*1024; // 1M + for (int ii = 0; ii < 4; ++ii) { + _deallocate(_allocate(LARGE_BYTES)); + } + post_blocks = _manager->getStatistics().blocks; + CPPUNIT_ASSERT(post_blocks > pre_blocks); + + // The next allocate/deallocate cycle should age off an old buffer + pre_blocks = _manager->getStatistics().blocks; + _deallocate(_allocate(LARGE_BYTES)); + post_blocks = _manager->getStatistics().blocks; + CPPUNIT_ASSERT(post_blocks < pre_blocks); + + // Turn off the age policy, retaining all buffers from now on + pre_blocks = post_blocks; + _manager->setMaxThreadAge(-1); + for (int ii = 0; ii < 1000; ++ii) { + _deallocate(_allocate(LARGE_BYTES)); + } + CPPUNIT_ASSERT_EQUAL(pre_blocks, _manager->getStatistics().blocks); +} + +void* BufferManagerTest::_allocate(size_t bytes) +{ + void* ptr = redhawk::BufferManager::Allocate(bytes); + _allocations.insert(ptr); + return ptr; +} + +void BufferManagerTest::_deallocate(void* ptr) +{ + CPPUNIT_ASSERT_MESSAGE("Deallocating unknown allocation", _allocations.erase(ptr)); + redhawk::BufferManager::Deallocate(ptr); +} + +void BufferManagerTest::_fillCache(size_t count, size_t bufferSize) +{ + BufferList buffers; + for (size_t blocks = 0; blocks < count; ++blocks) { + buffers.insert(_manager->allocate(bufferSize)); + } + std::for_each(buffers.begin(), buffers.end(), &redhawk::BufferManager::Deallocate); +} diff --git a/redhawk/src/testing/cpp/BufferManagerTest.h b/redhawk/src/testing/cpp/BufferManagerTest.h new file mode 100644 index 000000000..6f17839bb --- /dev/null +++ b/redhawk/src/testing/cpp/BufferManagerTest.h @@ -0,0 +1,73 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK core. + * + * REDHAWK core is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +#ifndef BUFFERMANAGERTEST_H +#define BUFFERMANAGERTEST_H + +#include + +#include + +#include + +class BufferManagerTest : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE(BufferManagerTest); + CPPUNIT_TEST(testBasicAllocate); + CPPUNIT_TEST(testAllocator); + CPPUNIT_TEST(testEnable); + CPPUNIT_TEST(testStatistics); + CPPUNIT_TEST(testThreading); + CPPUNIT_TEST(testPolicyBytes); + CPPUNIT_TEST(testPolicyBlocks); + CPPUNIT_TEST(testPolicyAge); + CPPUNIT_TEST_SUITE_END(); + +public: + void setUp(); + void tearDown(); + + void testBasicAllocate(); + void testAllocator(); + + void testEnable(); + + void testStatistics(); + + void testThreading(); + + void testPolicyBytes(); + void testPolicyBlocks(); + void testPolicyAge(); + +private: + typedef std::set BufferList; + + void* _allocate(size_t bytes); + void _deallocate(void* ptr); + + void _fillCache(size_t count, size_t bufferSize); + + redhawk::BufferManager* _manager; + + BufferList _allocations; +}; + +#endif // BUFFERMANAGER_TEST_H diff --git a/redhawk/src/testing/cpp/Makefile.am b/redhawk/src/testing/cpp/Makefile.am index f4b842996..09eb3c542 100644 --- a/redhawk/src/testing/cpp/Makefile.am +++ b/redhawk/src/testing/cpp/Makefile.am @@ -15,5 +15,6 @@ test_libossiecf_SOURCES += ValueSequenceTest.cpp ValueSequenceTest.h test_libossiecf_SOURCES += PropertyMapTest.cpp PropertyMapTest.h test_libossiecf_SOURCES += MessagingTest.cpp MessagingTest.h test_libossiecf_SOURCES += ExecutorServiceTest.cpp ExecutorServiceTest.h +test_libossiecf_SOURCES += BufferManagerTest.cpp BufferManagerTest.h test_libossiecf_CXXFLAGS = $(CPPUNIT_CFLAGS) -I $(top_srcdir)/base/include test_libossiecf_LDFLAGS = $(CPPUNIT_LIBS) $(top_builddir)/base/framework/libossiecf.la $(top_builddir)/base/framework/idl/libossieidl.la From 4b6c2607ab92fbca4b9ab28ddd68b48292314ca5 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 13 Jan 2017 11:27:20 -0500 Subject: [PATCH 0643/1644] Ignore test file --- redhawk/src/testing/.gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/redhawk/src/testing/.gitignore b/redhawk/src/testing/.gitignore index 5a6a8f0f0..02e3a34a6 100644 --- a/redhawk/src/testing/.gitignore +++ b/redhawk/src/testing/.gitignore @@ -40,6 +40,7 @@ sdr/dom/components/C1/cpp/C1 sdr/dom/components/C2/cpp/C2 sdr/dom/components/msg_through_cpp/cpp/msg_through_cpp sdr/dom/components/prop_trigger_timing/cpp/prop_trigger_timing +sdr/dom/components/timeprop_cpp/cpp/timeprop_cpp sdr/dom/domain/ sdr/dom/mgr/DomainManager* sdr/dom/mgr/rh/ From a0a036982c57d43d6b5c92c7d0602a674e089454 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Sat, 14 Jan 2017 10:14:14 -0500 Subject: [PATCH 0644/1644] Added CF.UTCTime --- redhawk/src/control/sdr/dommgr/Deployment.cpp | 1 + redhawk/src/idl/ossie/CF/DataType.idl | 1 + redhawk/src/xml/dtd/properties.dtd | 4 ++-- redhawk/src/xml/xsd/prf.xsd | 1 + 4 files changed, 5 insertions(+), 2 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index 3c4db4029..e267218bd 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -28,6 +28,7 @@ #include "PersistenceStore.h" #include "Deployment.h" #include "DeploymentExceptions.h" +#include using namespace redhawk; using namespace ossie; diff --git a/redhawk/src/idl/ossie/CF/DataType.idl b/redhawk/src/idl/ossie/CF/DataType.idl index 7ae8dc2dd..59fe3fa2a 100644 --- a/redhawk/src/idl/ossie/CF/DataType.idl +++ b/redhawk/src/idl/ossie/CF/DataType.idl @@ -44,6 +44,7 @@ module CF { double twsec; // J1970 GMT double tfsec; // 0.0 to 1.0 }; + typedef sequence UTCTimeSequence; }; diff --git a/redhawk/src/xml/dtd/properties.dtd b/redhawk/src/xml/dtd/properties.dtd index d26eb346e..3ad02d5ef 100644 --- a/redhawk/src/xml/dtd/properties.dtd +++ b/redhawk/src/xml/dtd/properties.dtd @@ -42,7 +42,7 @@ with this program. If not, see http://www.gnu.org/licenses/. id ID #REQUIRED type ( boolean | char | double | float | short | long | longlong | objref | octet - | string | ulong | ulonglong | ushort ) #REQUIRED + | string | ulong | ulonglong | ushort | utctime ) #REQUIRED name CDATA #IMPLIED complex ( false | true ) "false" commandline ( false | true ) "false" @@ -90,7 +90,7 @@ with this program. If not, see http://www.gnu.org/licenses/. id ID #REQUIRED type ( boolean | char | double | float | short | long | longlong | objref | octet - | string | ulong | ulonglong | ushort ) #REQUIRED + | string | ulong | ulonglong | ushort | utctime ) #REQUIRED name CDATA #IMPLIED complex ( false | true ) "false" optional ( false | true ) "false" diff --git a/redhawk/src/xml/xsd/prf.xsd b/redhawk/src/xml/xsd/prf.xsd index bf0af5b96..b4e66887f 100644 --- a/redhawk/src/xml/xsd/prf.xsd +++ b/redhawk/src/xml/xsd/prf.xsd @@ -156,6 +156,7 @@ defined. + From 2bcd494e9bde5e95e2273c99e054b5509414ae4d Mon Sep 17 00:00:00 2001 From: Max Robert Date: Sat, 14 Jan 2017 10:16:41 -0500 Subject: [PATCH 0645/1644] Refs CF-1420. C++ support for UTCTime --- .../src/base/framework/PropertyInterface.cpp | 136 ++++++++++++++++++ redhawk/src/base/framework/prop_helpers.cpp | 114 ++++++++++++++- redhawk/src/base/include/ossie/CorbaUtils.h | 8 ++ .../base/include/ossie/PropertyInterface.h | 28 ++++ .../src/base/include/ossie/PropertyMonitor.h | 4 + .../src/base/include/ossie/PropertySet_impl.h | 16 +++ redhawk/src/base/include/ossie/prop_helpers.h | 27 ++++ .../TestAllPropTypes/TestAllPropTypes.prf.xml | 8 ++ .../cpp/TestAllPropTypes_base.cpp | 16 +++ .../cpp/TestAllPropTypes_base.h | 2 + .../components/TestCppProps/TestCppProps.cpp | 37 +++++ .../components/TestCppProps/TestCppProps.h | 4 + .../TestCppProps/TestCppProps.prf.xml | 18 +++ .../TestCppProps/TestCppProps.sad.xml | 1 + .../testing/tests/test_11_CppProperties.py | 15 ++ 15 files changed, 433 insertions(+), 1 deletion(-) diff --git a/redhawk/src/base/framework/PropertyInterface.cpp b/redhawk/src/base/framework/PropertyInterface.cpp index 464fd7272..b3946c496 100644 --- a/redhawk/src/base/framework/PropertyInterface.cpp +++ b/redhawk/src/base/framework/PropertyInterface.cpp @@ -20,6 +20,122 @@ #include "ossie/PropertyInterface.h" +namespace CF { + + CF::UTCTime operator+(const CF::UTCTime& lhs, double seconds) + { + CF::UTCTime result = lhs; + result += seconds; + return result; + } + + CF::UTCTime& operator+=(CF::UTCTime& lhs, double seconds) + { + // Split fractional and whole seconds to preserve precision + lhs.tfsec += std::modf(seconds, &seconds); + lhs.twsec += seconds; + redhawk::time::utils::normalize(lhs); + return lhs; + } + + CF::UTCTime operator-(const CF::UTCTime& lhs, double seconds) + { + CF::UTCTime result = lhs; + result -= seconds; + return result; + } + + double operator-(const CF::UTCTime& lhs, const CF::UTCTime& rhs) + { + return (lhs.twsec - rhs.twsec) + (lhs.tfsec - rhs.tfsec); + } + + CF::UTCTime& operator-=(CF::UTCTime& lhs, double seconds) + { + // Split fractional and whole seconds to preserve precision + lhs.tfsec -= std::modf(seconds, &seconds); + lhs.twsec -= seconds; + redhawk::time::utils::normalize(lhs); + return lhs; + } + + bool operator==(const CF::UTCTime& lhs, const CF::UTCTime& rhs) + { + if (lhs.tcstatus != rhs.tcstatus) { + return false; + } else if (lhs.twsec != rhs.twsec) { + return false; + } else if (lhs.tfsec != rhs.tfsec) { + return false; + } + return true; + } + + bool operator!=(const CF::UTCTime& lhs, const CF::UTCTime& rhs) + { + if (lhs.tcstatus != rhs.tcstatus) { + return true; + } else if (lhs.twsec != rhs.twsec) { + return true; + } else if (lhs.tfsec != rhs.tfsec) { + return true; + } + return false; + } + + bool operator<(const CF::UTCTime& lhs, const CF::UTCTime& rhs) + { + if (lhs.twsec == rhs.twsec) { + return lhs.tfsec < rhs.tfsec; + } else { + return lhs.twsec < rhs.twsec; + } + } + + bool operator<=(const CF::UTCTime& lhs, const CF::UTCTime& rhs) + { + if (lhs.twsec == rhs.twsec) { + return lhs.tfsec <= rhs.tfsec; + } else { + return lhs.twsec <= rhs.twsec; + } + } + + bool operator>(const CF::UTCTime& lhs, const CF::UTCTime& rhs) + { + if (lhs.twsec == rhs.twsec) { + return lhs.tfsec > rhs.tfsec; + } else { + return lhs.twsec > rhs.twsec; + } + } + + bool operator>=(const CF::UTCTime& lhs, const CF::UTCTime& rhs) + { + if (lhs.twsec == rhs.twsec) { + return lhs.tfsec >= rhs.tfsec; + } else { + return lhs.twsec >= rhs.twsec; + } + } + + std::ostream& operator<<(std::ostream& stream, const CF::UTCTime& utc) + { + struct tm time; + time_t seconds = utc.twsec; + gmtime_r(&seconds, &time); + stream << (1900+time.tm_year) << ':'; + stream << std::setw(2) << std::setfill('0') << (time.tm_mon+1) << ':'; + stream << std::setw(2) << time.tm_mday << "::"; + stream << std::setw(2) << time.tm_hour << ":"; + stream << std::setw(2) << time.tm_min << ":"; + stream << std::setw(2) << time.tm_sec; + int usec = round(utc.tfsec * 1000000.0); + stream << "." << std::setw(6) << usec; + return stream; + } + +} PropertyInterface::PropertyInterface (CORBA::TypeCode_ptr _type) : id(), @@ -178,6 +294,16 @@ inline void SimplePropertyWrapper::toAny (const char& v, CORBA::Any& a) } +template <> +inline bool SimplePropertyWrapper::fromAny (const CORBA::Any& a, CF::UTCTime& v) +{ + CF::UTCTime *tmp; + if (not (a >>= tmp)) + return false; + v = *tmp; + return true; +} + template <> inline bool SimplePropertyWrapper::fromAny (const CORBA::Any& a, CORBA::Octet& v) { @@ -324,7 +450,14 @@ N##Property* PropertyWrapperFactory::Create (T& value) \ return new SimplePropertyWrapper< T >(value); \ } +#define SIMPLE_STRUCT_FACTORY_CREATE(N,T) \ +N##Property* PropertyWrapperFactory::Create (T& value) \ +{ \ + return new PropertyWrapper< T >(value); \ +} + SIMPLE_FACTORY_CREATE(String, std::string); +SIMPLE_FACTORY_CREATE(UTCTime, CF::UTCTime); SIMPLE_FACTORY_CREATE(Boolean, bool); SIMPLE_FACTORY_CREATE(Char, char); @@ -366,6 +499,7 @@ N##SeqProperty* PropertyWrapperFactory::Create (std::vector& value) \ } SIMPLE_SEQUENCE_FACTORY_CREATE(String, std::string); +SIMPLE_SEQUENCE_FACTORY_CREATE(UTCTime, CF::UTCTime); SIMPLE_SEQUENCE_FACTORY_CREATE(Boolean, bool); SIMPLE_SEQUENCE_FACTORY_CREATE(Char, char); SIMPLE_SEQUENCE_FACTORY_CREATE(Octet, CORBA::Octet); @@ -403,6 +537,7 @@ N##Property* MonitorFactory::Create (T& value) \ } SIMPLEMONITOR_FACTORY_CREATE(String, std::string); +SIMPLEMONITOR_FACTORY_CREATE(UTCTime, CF::UTCTime); SIMPLEMONITOR_FACTORY_CREATE(Boolean, bool); SIMPLEMONITOR_FACTORY_CREATE(Char, char); @@ -438,6 +573,7 @@ N##SeqProperty* MonitorFactory::Create (std::vector& value) \ } SIMPLEMONITOR_SEQUENCE_FACTORY_CREATE(String, std::string); +SIMPLEMONITOR_SEQUENCE_FACTORY_CREATE(UTCTime, CF::UTCTime); SIMPLEMONITOR_SEQUENCE_FACTORY_CREATE(Boolean, bool); SIMPLEMONITOR_SEQUENCE_FACTORY_CREATE(Char, char); SIMPLEMONITOR_SEQUENCE_FACTORY_CREATE(Octet, CORBA::Octet); diff --git a/redhawk/src/base/framework/prop_helpers.cpp b/redhawk/src/base/framework/prop_helpers.cpp index 3ce716fa0..9c44adae1 100644 --- a/redhawk/src/base/framework/prop_helpers.cpp +++ b/redhawk/src/base/framework/prop_helpers.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #if HAVE_OMNIORB4 #include "omniORB4/CORBA.h" #endif @@ -367,6 +368,111 @@ CORBA::Any ossie::stringToComplexAny(std::string value, std::string structName) return result; } +namespace redhawk { + namespace time { + namespace utils { + CF::UTCTime create( const double wholeSecs, const double fractionalSecs ) { + double wsec = wholeSecs; + double fsec = fractionalSecs; + if ( wsec < 0.0 || fsec < 0.0 ) { + struct timeval tmp_time; + struct timezone tmp_tz; + gettimeofday(&tmp_time, &tmp_tz); + wsec = tmp_time.tv_sec; + fsec = tmp_time.tv_usec / 1e6; + } + CF::UTCTime tstamp = CF::UTCTime(); + tstamp.tcstatus = 1; + struct tm t = {0}; + tstamp.twsec = wsec + t.tm_gmtoff; + tstamp.tfsec = fsec; + return tstamp; + } + + CF::UTCTime convert( const std::string formatted ) { + unsigned int year; + unsigned int month; + unsigned int day; + unsigned int hour; + unsigned int minute; + double second; + int retval = sscanf(formatted.c_str(), "%d:%d:%d::%d:%d:%lf",&year,&month,&day,&hour,&minute,&second); + CF::UTCTime utctime; + if (retval != 6) { + utctime.tcstatus=0; + return utctime; + } + utctime.tcstatus=1; + struct tm t = {0}; + t.tm_year = year - 1900; + t.tm_mon = month - 1; + t.tm_mday = day; + t.tm_hour = hour; + t.tm_min = minute; + t.tm_sec = (int)second; + utctime.twsec = mktime(&t); + utctime.tfsec = second - (int)second; + return utctime; + } + + std::string toString( const CF::UTCTime utc ) { + struct tm time; + time_t seconds = utc.twsec; + std::ostringstream stream; + gmtime_r(&seconds, &time); + stream << (1900+time.tm_year) << ':'; + stream << std::setw(2) << std::setfill('0') << (time.tm_mon+1) << ':'; + stream << std::setw(2) << time.tm_mday << "::"; + stream << std::setw(2) << time.tm_hour << ":"; + stream << std::setw(2) << time.tm_min << ":"; + stream << std::setw(2) << time.tm_sec; + int usec = round(utc.tfsec * 1000000.0); + stream << "." << std::setw(6) << usec; + return stream.str(); + } + + /* + * Create a time stamp object from the current time of day reported by the system + */ + CF::UTCTime now() { + return create(); + } + + /* + * Create a time stamp object from the current time of day reported by the system + */ + CF::UTCTime notSet() { + CF::UTCTime tstamp = CF::UTCTime(); + tstamp.tcstatus = 0; + tstamp.twsec = 0.0; + tstamp.tfsec = 0.0; + return tstamp; + } + + /* + * Adjust the whole and fractional portions of a time stamp object to + * ensure there is no fraction in the whole seconds, and vice-versa + */ + void normalize(CF::UTCTime& time) { + // Get fractional adjustment from whole seconds + double fadj = std::modf(time.twsec, &time.twsec); + + // Adjust fractional seconds and get whole seconds adjustment + double wadj = 0; + time.tfsec = std::modf(time.tfsec + fadj, &wadj); + + // If fractional seconds are negative, borrow a second from the whole + // seconds to make it positive, normalizing to [0,1) + if (time.tfsec < 0.0) { + time.tfsec += 1.0; + wadj -= 1.0; + } + time.twsec += wadj; + } + } + } +} + /* * Convert from a string to a simple CORBA::Any. * @@ -426,7 +532,11 @@ CORBA::Any ossie::string_to_any(std::string value, CORBA::TypeCode_ptr type) // that are not explicitly supported will cause the function to // return a new, empty CORBA::Any. std::string structName = any_to_string(*(type->parameter(0))); - result = stringToComplexAny(value, structName); + if (structName == std::string("UTCTime")) { + result <<= redhawk::time::utils::convert(value); + } else { + result = stringToComplexAny(value, structName); + } } else { result = stringToSimpleAny(value, type->kind()); @@ -1002,6 +1112,8 @@ CORBA::TypeCode_ptr ossie::getTypeCode(std::string type) { kind = CORBA::_tc_ulonglong; } else if (type == "string"){ kind = CORBA::_tc_string; + } else if (type == "utctime"){ + kind = CF::_tc_UTCTime; } else if (type == "complexDouble") { kind = CF::_tc_complexDouble; } else if (type == "complexFloat") { diff --git a/redhawk/src/base/include/ossie/CorbaUtils.h b/redhawk/src/base/include/ossie/CorbaUtils.h index 71f53b503..3136f5c14 100644 --- a/redhawk/src/base/include/ossie/CorbaUtils.h +++ b/redhawk/src/base/include/ossie/CorbaUtils.h @@ -25,6 +25,7 @@ #include #include #include +#include #include "CorbaSequence.h" #include "ossie/debug.h" @@ -352,6 +353,12 @@ namespace ossie { { return CORBA::_tc_string; } + + template<> + inline CORBA::TypeCode_ptr TypeCode (void) + { + return CORBA::_tc_TypeCode; + } // Instantiates POAs on demand class POACreator : public virtual POA_PortableServer::AdapterActivator @@ -512,6 +519,7 @@ ANY_VECTOR_OPERATORS(CORBA::LongLong, CORBA::LongLongSeq); ANY_VECTOR_OPERATORS(CORBA::ULongLong, CORBA::ULongLongSeq); ANY_VECTOR_OPERATORS(CORBA::Float, CORBA::FloatSeq); ANY_VECTOR_OPERATORS(CORBA::Double, CORBA::DoubleSeq); +ANY_VECTOR_OPERATORS(CF::UTCTime, CF::UTCTimeSequence); #undef ANY_VECTOR_OPERATORS #define ANY_VECTOR_CONVERT_OPERATORS(T,SEQ) \ diff --git a/redhawk/src/base/include/ossie/PropertyInterface.h b/redhawk/src/base/include/ossie/PropertyInterface.h index 721bc8be5..a6de6e58b 100644 --- a/redhawk/src/base/include/ossie/PropertyInterface.h +++ b/redhawk/src/base/include/ossie/PropertyInterface.h @@ -31,6 +31,7 @@ #include "ossie/AnyUtils.h" #include "ossie/CorbaUtils.h" #include "CF/cf.h" +#include "CF/DataType.h" #include "ossie/Port_impl.h" #include "ossie/ComplexProperties.h" @@ -43,6 +44,8 @@ #include #include "PropertyMonitor.h" +#include + /* * @@ -475,6 +478,7 @@ typedef PropertyWrapper ULongLongProperty; typedef PropertyWrapper LongLongProperty; typedef PropertyWrapper FloatProperty; typedef PropertyWrapper DoubleProperty; +typedef PropertyWrapper UTCTimeProperty; typedef PropertyWrapper > ComplexFloatProperty; typedef PropertyWrapper > ComplexBooleanProperty; @@ -521,6 +525,27 @@ class SequenceProperty : public PropertyWrapper > } }; +namespace CF { + + CF::UTCTime operator+(const CF::UTCTime& lhs, double seconds); + + CF::UTCTime& operator+=(CF::UTCTime& lhs, double seconds); + + double operator-(const CF::UTCTime& lhs, const CF::UTCTime& rhs); + CF::UTCTime operator-(const CF::UTCTime& lhs, double seconds); + + CF::UTCTime& operator-=(CF::UTCTime& lhs, double seconds); + + bool operator==(const CF::UTCTime& lhs, const CF::UTCTime& rhs); + bool operator!=(const CF::UTCTime& lhs, const CF::UTCTime& rhs); + bool operator<(const CF::UTCTime& lhs, const CF::UTCTime& rhs); + bool operator<=(const CF::UTCTime& lhs, const CF::UTCTime& rhs); + bool operator>(const CF::UTCTime& lhs, const CF::UTCTime& rhs); + bool operator>=(const CF::UTCTime& lhs, const CF::UTCTime& rhs); + + std::ostream& operator<<(std::ostream&, const CF::UTCTime&); +} + typedef SequenceProperty StringSeqProperty; typedef SequenceProperty CharSeqProperty; typedef SequenceProperty BooleanSeqProperty; @@ -533,6 +558,7 @@ typedef SequenceProperty LongLongSeqProperty; typedef SequenceProperty ULongLongSeqProperty; typedef SequenceProperty FloatSeqProperty; typedef SequenceProperty DoubleSeqProperty; +typedef SequenceProperty UTCTimeSeqProperty; typedef SequenceProperty > ComplexFloatSeqProperty; typedef SequenceProperty > ComplexDoubleSeqProperty; @@ -658,6 +684,7 @@ class PropertyWrapperFactory static ULongLongProperty* Create (CORBA::ULongLong&); static FloatProperty* Create (CORBA::Float&); static DoubleProperty* Create (CORBA::Double&); + static UTCTimeProperty* Create (CF::UTCTime&); static ComplexBooleanProperty* Create (std::complex&); static ComplexCharProperty* Create (std::complex&); @@ -683,6 +710,7 @@ class PropertyWrapperFactory static ULongLongSeqProperty* Create (std::vector&); static FloatSeqProperty* Create (std::vector&); static DoubleSeqProperty* Create (std::vector&); + static UTCTimeSeqProperty* Create (std::vector&); static ComplexBooleanSeqProperty* Create (std::vector >&); static ComplexCharSeqProperty* Create (std::vector >&); diff --git a/redhawk/src/base/include/ossie/PropertyMonitor.h b/redhawk/src/base/include/ossie/PropertyMonitor.h index f145f32fc..f01f5b347 100644 --- a/redhawk/src/base/include/ossie/PropertyMonitor.h +++ b/redhawk/src/base/include/ossie/PropertyMonitor.h @@ -119,6 +119,7 @@ typedef SimpleMonitor ULongLongProperty; typedef SimpleMonitor LongLongProperty; typedef SimpleMonitor FloatProperty; typedef SimpleMonitor DoubleProperty; +typedef SimpleMonitor UTCTimeProperty; typedef SimpleMonitor > ComplexFloatProperty; typedef SimpleMonitor > ComplexBooleanProperty; @@ -189,6 +190,7 @@ typedef SequenceMonitor LongLongSeqProperty; typedef SequenceMonitor ULongLongSeqProperty; typedef SequenceMonitor FloatSeqProperty; typedef SequenceMonitor DoubleSeqProperty; +typedef SequenceMonitor UTCTimeSeqProperty; typedef SequenceMonitor > ComplexFloatSeqProperty; typedef SequenceMonitor > ComplexDoubleSeqProperty; @@ -288,6 +290,7 @@ typedef SequenceMonitor > ComplexULongLongSeqProp static ULongLongProperty* Create (CORBA::ULongLong&); static FloatProperty* Create (CORBA::Float&); static DoubleProperty* Create (CORBA::Double&); + static UTCTimeProperty* Create (CF::UTCTime&); static ComplexBooleanProperty* Create (std::complex&); static ComplexCharProperty* Create (std::complex&); @@ -313,6 +316,7 @@ typedef SequenceMonitor > ComplexULongLongSeqProp static ULongLongSeqProperty* Create (std::vector&); static FloatSeqProperty* Create (std::vector&); static DoubleSeqProperty* Create (std::vector&); + static UTCTimeSeqProperty* Create (std::vector&); static ComplexBooleanSeqProperty* Create (std::vector >&); static ComplexCharSeqProperty* Create (std::vector >&); diff --git a/redhawk/src/base/include/ossie/PropertySet_impl.h b/redhawk/src/base/include/ossie/PropertySet_impl.h index 933555ae1..545fe90bf 100644 --- a/redhawk/src/base/include/ossie/PropertySet_impl.h +++ b/redhawk/src/base/include/ossie/PropertySet_impl.h @@ -159,6 +159,22 @@ class PropertySet_impl wrapper->isNil(false); return wrapper; } + + template + PropertyInterface* addProperty (CF::UTCTime& value, + const T2& initial_value, + const std::string& id, + const std::string& name, + const std::string& mode, + const std::string& units, + const std::string& action, + const std::string& kinds) + { + PropertyInterface* wrapper = addProperty(value, id, name, mode, units, action, kinds); + value = redhawk::time::utils::convert(initial_value); + wrapper->isNil(false); + return wrapper; + } template void addPropertyChangeListener (const std::string& id, C* target, void (C::*func)(const T*, const T*)) diff --git a/redhawk/src/base/include/ossie/prop_helpers.h b/redhawk/src/base/include/ossie/prop_helpers.h index 259afe319..b39538553 100644 --- a/redhawk/src/base/include/ossie/prop_helpers.h +++ b/redhawk/src/base/include/ossie/prop_helpers.h @@ -31,6 +31,33 @@ #include "CF/cf.h" +namespace redhawk { + namespace time { + namespace utils { + CF::UTCTime create( const double wholeSecs=-1.0, const double fractionalSecs=-1.0 ); + + // year:month:day::hour:minute:second + CF::UTCTime convert( const std::string formatted ); + + /* + * Create a time stamp object from the current time of day reported by the system + */ + CF::UTCTime now(); + + /* + * Create a time stamp object from the current time of day reported by the system + */ + CF::UTCTime notSet(); + + /* + * Adjust the whole and fractional portions of a time stamp object to + * ensure there is no fraction in the whole seconds, and vice-versa + */ + void normalize(CF::UTCTime& time); + } + } +} + namespace ossie { template diff --git a/redhawk/src/testing/sdr/dom/components/TestAllPropTypes/TestAllPropTypes.prf.xml b/redhawk/src/testing/sdr/dom/components/TestAllPropTypes/TestAllPropTypes.prf.xml index c742e7d43..6d7addc78 100644 --- a/redhawk/src/testing/sdr/dom/components/TestAllPropTypes/TestAllPropTypes.prf.xml +++ b/redhawk/src/testing/sdr/dom/components/TestAllPropTypes/TestAllPropTypes.prf.xml @@ -73,6 +73,10 @@ with this program. If not, see http://www.gnu.org/licenses/. + + + + @@ -125,6 +129,10 @@ with this program. If not, see http://www.gnu.org/licenses/. + + + + diff --git a/redhawk/src/testing/sdr/dom/components/TestAllPropTypes/cpp/TestAllPropTypes_base.cpp b/redhawk/src/testing/sdr/dom/components/TestAllPropTypes/cpp/TestAllPropTypes_base.cpp index 4eea84484..5ab93d4f1 100644 --- a/redhawk/src/testing/sdr/dom/components/TestAllPropTypes/cpp/TestAllPropTypes_base.cpp +++ b/redhawk/src/testing/sdr/dom/components/TestAllPropTypes/cpp/TestAllPropTypes_base.cpp @@ -216,6 +216,14 @@ void TestAllPropTypes_base::loadProperties() "external", "configure"); + addProperty(simple_utctime, + "simple_utctime", + "", + "readwrite", + "", + "external", + "property"); + addProperty(simple_sequence_string, "simple_sequence_string", "", @@ -320,6 +328,14 @@ void TestAllPropTypes_base::loadProperties() "external", "configure"); + addProperty(simple_sequence_utctime, + "simple_sequence_utctime", + "", + "readwrite", + "", + "external", + "property"); + addProperty(struct_vars, struct_vars_struct(), "struct_vars", diff --git a/redhawk/src/testing/sdr/dom/components/TestAllPropTypes/cpp/TestAllPropTypes_base.h b/redhawk/src/testing/sdr/dom/components/TestAllPropTypes/cpp/TestAllPropTypes_base.h index eeb07d4df..f3a5b8a98 100644 --- a/redhawk/src/testing/sdr/dom/components/TestAllPropTypes/cpp/TestAllPropTypes_base.h +++ b/redhawk/src/testing/sdr/dom/components/TestAllPropTypes/cpp/TestAllPropTypes_base.h @@ -136,6 +136,7 @@ class TestAllPropTypes_base : public Resource_impl CORBA::Long simple_long; CORBA::LongLong simple_longlong; CORBA::ULongLong simple_ulonglong; + CF::UTCTime simple_utctime; std::vector simple_sequence_string; std::vector simple_sequence_boolean; std::vector simple_sequence_ulong; @@ -149,6 +150,7 @@ class TestAllPropTypes_base : public Resource_impl std::vector simple_sequence_long; std::vector simple_sequence_longlong; std::vector simple_sequence_ulonglong; + std::vector simple_sequence_utctime; struct_vars_struct struct_vars; std::vector struct_seq; diff --git a/redhawk/src/testing/sdr/dom/components/TestCppProps/TestCppProps.cpp b/redhawk/src/testing/sdr/dom/components/TestCppProps/TestCppProps.cpp index ed04e02ee..552b90437 100644 --- a/redhawk/src/testing/sdr/dom/components/TestCppProps/TestCppProps.cpp +++ b/redhawk/src/testing/sdr/dom/components/TestCppProps/TestCppProps.cpp @@ -52,6 +52,35 @@ TestCppProps::TestCppProps(const char *uuid, const char *label) : "external", "configure"); + addProperty(simple_utctime, + "2017:2:1::12:01:00.123", + "simple_utctime", + "", + "readwrite", + "", + "external", + "property"); + + seq_utctime.push_back(redhawk::time::utils::convert("2010:2:1::12:01:00.123")); + seq_utctime.push_back(redhawk::time::utils::convert("2011:2:1::12:01:00.123")); + addProperty(seq_utctime, + seq_utctime, + "seq_utctime", + "", + "readwrite", + "", + "external", + "property"); + + addProperty(reset_utctime, + "false", + "reset_utctime", + "", + "readwrite", + "", + "external", + "property"); + addProperty(seq_oct, "DCE:f877b9ee-a682-43a6-ba21-5ea980167f55", "seq_oct", @@ -82,12 +111,20 @@ TestCppProps::TestCppProps(const char *uuid, const char *label) : "", "external", "property"); + addPropertyListener(reset_utctime, this, &TestCppProps::resetUTCtime); } TestCppProps::~TestCppProps (void) { } +void TestCppProps::resetUTCtime(bool oldValue, bool newValue) +{ + if (newValue) { + this->simple_utctime = redhawk::time::utils::create(); + } +} + void TestCppProps::runTest (CORBA::ULong testId, CF::Properties& testValues) throw (CF::UnknownProperties, CF::TestableObject::UnknownTest, CORBA::SystemException) { diff --git a/redhawk/src/testing/sdr/dom/components/TestCppProps/TestCppProps.h b/redhawk/src/testing/sdr/dom/components/TestCppProps/TestCppProps.h index 0dbc5dcb3..7df331624 100644 --- a/redhawk/src/testing/sdr/dom/components/TestCppProps/TestCppProps.h +++ b/redhawk/src/testing/sdr/dom/components/TestCppProps/TestCppProps.h @@ -53,6 +53,7 @@ class TestCppProps : public Resource_impl void testMemberCallbacks (CF::Properties& values); void testStaticCallbacks (CF::Properties& values); void testCallbacks (CF::Properties& values); + void resetUTCtime(bool oldValue, bool newValue); void testEnableNil (CF::Properties& values); void testSetNil (CF::Properties& values); @@ -60,6 +61,9 @@ class TestCppProps : public Resource_impl // Member variables exposed as properties CORBA::Long prop_long; std::string prop_str; + CF::UTCTime simple_utctime; + bool reset_utctime; + std::vector seq_utctime; std::vector seq_oct; std::vector seq_foo; diff --git a/redhawk/src/testing/sdr/dom/components/TestCppProps/TestCppProps.prf.xml b/redhawk/src/testing/sdr/dom/components/TestCppProps/TestCppProps.prf.xml index 7a721917e..11116d7ee 100644 --- a/redhawk/src/testing/sdr/dom/components/TestCppProps/TestCppProps.prf.xml +++ b/redhawk/src/testing/sdr/dom/components/TestCppProps/TestCppProps.prf.xml @@ -30,6 +30,24 @@ with this program. If not, see http://www.gnu.org/licenses/. + + 2017:2:1::12:01:00.123 + + + + + false + + + + + + 2010:2:1::12:01:00.123 + 2011:2:1::12:01:00.123 + + + + diff --git a/redhawk/src/testing/sdr/dom/waveforms/TestCppProps/TestCppProps.sad.xml b/redhawk/src/testing/sdr/dom/waveforms/TestCppProps/TestCppProps.sad.xml index 875ad83d9..9dc5b0501 100644 --- a/redhawk/src/testing/sdr/dom/waveforms/TestCppProps/TestCppProps.sad.xml +++ b/redhawk/src/testing/sdr/dom/waveforms/TestCppProps/TestCppProps.sad.xml @@ -38,6 +38,7 @@ with this program. If not, see http://www.gnu.org/licenses/. + diff --git a/redhawk/src/testing/tests/test_11_CppProperties.py b/redhawk/src/testing/tests/test_11_CppProperties.py index 71bcfeed6..fbe427dc2 100644 --- a/redhawk/src/testing/tests/test_11_CppProperties.py +++ b/redhawk/src/testing/tests/test_11_CppProperties.py @@ -72,6 +72,21 @@ def test_LegacyPropertyCallbacks(self): for result in self._app.runTest(1, props): self.assert_(result.value._v) + def test_UTCTime(self): + prop = self._app.query([CF.DataType('simple_utctime', any.to_any(None))]) + datetime = time.localtime(prop[0].value.value().twsec) + self.assertEquals(datetime.tm_year,2017) + self.assertEquals(datetime.tm_mon,2) + self.assertEquals(datetime.tm_mday,1) + self.assertEquals(datetime.tm_hour,10) + self.assertEquals(datetime.tm_min,1) + self.assertEquals(datetime.tm_sec,0) + self.assertEquals(prop[0].value.value().tfsec,0.123) + self._app.configure([CF.DataType('reset_utctime', any.to_any(True))]) + prop = self._app.query([CF.DataType('simple_utctime', any.to_any(None))]) + now = time.time() + self.assertEquals(abs(now-(prop[0].value.value().twsec+prop[0].value.value().tfsec))<0.1,True) + def test_NilProperty(self): self.preconditions() From 5b2b38eed56f5f423eaef8f694910a4ae084559a Mon Sep 17 00:00:00 2001 From: Max Robert Date: Sat, 14 Jan 2017 10:17:17 -0500 Subject: [PATCH 0646/1644] Refs CF-1420. Java support for UTCTime --- .../src/base/framework/java/ossie/Makefile.am | 8 +- .../src/org/ossie/properties/AnyUtils.java | 10 + .../org/ossie/redhawk/time/Comparator.java | 33 ++++ .../ossie/redhawk/time/DefaultComparator.java | 41 ++++ .../src/org/ossie/redhawk/time/utils.java | 175 ++++++++++++++++++ .../TestJavaProps/TestJavaProps.java | 46 ++++- .../TestJavaProps/TestJavaProps.prf.xml | 18 ++ .../TestJavaProps/TestJavaProps.sad.xml | 1 + .../testing/tests/test_11_JavaProperties.py | 44 +++++ 9 files changed, 374 insertions(+), 2 deletions(-) create mode 100644 redhawk/src/base/framework/java/ossie/src/org/ossie/redhawk/time/Comparator.java create mode 100644 redhawk/src/base/framework/java/ossie/src/org/ossie/redhawk/time/DefaultComparator.java create mode 100644 redhawk/src/base/framework/java/ossie/src/org/ossie/redhawk/time/utils.java diff --git a/redhawk/src/base/framework/java/ossie/Makefile.am b/redhawk/src/base/framework/java/ossie/Makefile.am index 10e3d487b..d8f77aeae 100644 --- a/redhawk/src/base/framework/java/ossie/Makefile.am +++ b/redhawk/src/base/framework/java/ossie/Makefile.am @@ -144,6 +144,8 @@ ossie_jar_SOURCE = src/org/ossie/component/AllocCapacity.java \ src/org/ossie/properties/PrimitiveArrayUtils.java \ src/org/ossie/properties/Property.java \ src/org/ossie/properties/PropertyListener.java \ + src/org/ossie/properties/UTCTimeProperty.java \ + src/org/ossie/properties/UTCTimeSequenceProperty.java \ src/org/ossie/properties/StringProperty.java \ src/org/ossie/properties/StringSequenceProperty.java \ src/org/ossie/properties/StructDef.java \ @@ -153,7 +155,11 @@ ossie_jar_SOURCE = src/org/ossie/component/AllocCapacity.java \ src/org/ossie/redhawk/ApplicationContainer.java \ src/org/ossie/redhawk/DomainManagerContainer.java \ src/org/ossie/redhawk/NetworkContainer.java \ - src/org/ossie/redhawk/DeviceManagerContainer.java + src/org/ossie/redhawk/DeviceManagerContainer.java \ + src/org/ossie/redhawk/NetworkContainer.java \ + src/org/ossie/redhawk/time/DefaultComparator.java \ + src/org/ossie/redhawk/time/Comparator.java \ + src/org/ossie/redhawk/time/utils.java # Deprecated generic property classes, replaced by strongly-typed classes but # maintained for source compatibility. diff --git a/redhawk/src/base/framework/java/ossie/src/org/ossie/properties/AnyUtils.java b/redhawk/src/base/framework/java/ossie/src/org/ossie/properties/AnyUtils.java index 00c6deacd..363b258f5 100644 --- a/redhawk/src/base/framework/java/ossie/src/org/ossie/properties/AnyUtils.java +++ b/redhawk/src/base/framework/java/ossie/src/org/ossie/properties/AnyUtils.java @@ -67,6 +67,7 @@ import CF.complexULongHelper; import CF.complexLongLongHelper; import CF.complexULongLongHelper; +import CF.UTCTimeHelper; import CF.complexFloatSeqHelper; import CF.complexDoubleSeqHelper; @@ -79,6 +80,7 @@ import CF.complexULongSeqHelper; import CF.complexLongLongSeqHelper; import CF.complexULongLongSeqHelper; +import CF.UTCTimeSequenceHelper; public final class AnyUtils { @@ -334,6 +336,8 @@ public static Object convertAny(final Any theAny, final TypeCode typeCode) { return complexLongLongHelper.extract(theAny); } else if (typeCode.name().equals("complexULongLong")) { return complexULongLongHelper.extract(theAny); + } else if (typeCode.name().equals("UTCTime")) { + return UTCTimeHelper.extract(theAny); } case TCKind._tk_longdouble: case TCKind._tk_array: @@ -1258,6 +1262,12 @@ public static boolean compareAnys(final Any a, final Any b, final String action) CF.complexULongLongHelper.extract(b), action, a.type()); + } else if (a.type().equivalent(UTCTimeHelper.type())) { + result = AnyUtils.performAction( + CF.UTCTimeHelper.extract(a), + CF.UTCTimeHelper.extract(b), + action, + a.type()); } else { result = false; } diff --git a/redhawk/src/base/framework/java/ossie/src/org/ossie/redhawk/time/Comparator.java b/redhawk/src/base/framework/java/ossie/src/org/ossie/redhawk/time/Comparator.java new file mode 100644 index 000000000..70c1fbf98 --- /dev/null +++ b/redhawk/src/base/framework/java/ossie/src/org/ossie/redhawk/time/Comparator.java @@ -0,0 +1,33 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK bulkioInterfaces. + * + * REDHAWK bulkioInterfaces is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK bulkioInterfaces is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +package org.ossie.redhawk.time; + +import java.lang.System; +import CF.UTCTime; + +/** + * @generated + */ +public interface Comparator { + + public boolean compare(final UTCTime T1, final UTCTime T2); +} + diff --git a/redhawk/src/base/framework/java/ossie/src/org/ossie/redhawk/time/DefaultComparator.java b/redhawk/src/base/framework/java/ossie/src/org/ossie/redhawk/time/DefaultComparator.java new file mode 100644 index 000000000..38abfe0b6 --- /dev/null +++ b/redhawk/src/base/framework/java/ossie/src/org/ossie/redhawk/time/DefaultComparator.java @@ -0,0 +1,41 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK bulkioInterfaces. + * + * REDHAWK bulkioInterfaces is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK bulkioInterfaces is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +package org.ossie.redhawk.time; + +import java.lang.System; +import CF.UTCTime; + +/** + * @generated + */ +public class DefaultComparator implements org.ossie.redhawk.time.Comparator { + + public boolean compare(final UTCTime T1, final UTCTime T2) { + if (T1.tcstatus != T2.tcstatus) + return false; + if (T1.tfsec != T2.tfsec) + return false; + if (T1.twsec != T2.twsec) + return false; + return true; + } + +} diff --git a/redhawk/src/base/framework/java/ossie/src/org/ossie/redhawk/time/utils.java b/redhawk/src/base/framework/java/ossie/src/org/ossie/redhawk/time/utils.java new file mode 100644 index 000000000..043bdf64a --- /dev/null +++ b/redhawk/src/base/framework/java/ossie/src/org/ossie/redhawk/time/utils.java @@ -0,0 +1,175 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK bulkioInterfaces. + * + * REDHAWK bulkioInterfaces is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK bulkioInterfaces is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +package org.ossie.redhawk.time; + +import java.lang.System; +import java.util.Calendar; +import java.util.TimeZone; + +import CF.UTCTime; + +public class utils { + + public static UTCTime create( double wholesecs, double fractionalsecs) { + + double wsec = wholesecs; + double fsec = fractionalsecs; + if ( wsec < 0.0 || fsec < 0.0 ) { + long tmp_time = System.currentTimeMillis(); + wsec = tmp_time /1000; + fsec = (tmp_time % 1000)/1000.0; + } + UTCTime tstamp = new UTCTime(); + tstamp.tcstatus = 1; + tstamp.twsec = wsec; + tstamp.tfsec = fsec; + return tstamp; + } + + + public static UTCTime now() { + return create(-1.0,-1.0); + } + + public static UTCTime notSet() { + UTCTime tstamp = create(0.0,0.0); + tstamp.tcstatus = 0; + return tstamp; + } + + /** + * Normalizes a UTCTime, such that the whole portion contains an integral number of seconds, + * and the fractional portion is in the range [0.0, 1.0). + */ + public static void normalize(UTCTime time) { + // Get fractional adjustment from whole seconds + double fadj = time.twsec % 1.0; + time.twsec -= fadj; + + // Adjust fractional seconds and get whole seconds adjustment + time.tfsec += fadj; + double wadj = Math.floor(time.tfsec); + time.twsec += wadj; + time.tfsec -= wadj; + } + + /** + * Returns a new copy of a UTCTime. + */ + public static UTCTime copy(UTCTime time) { + return new UTCTime(time.tcstatus, time.twsec, time.tfsec); + } + + public static int compare(UTCTime time1, UTCTime time2) { + if (time1.twsec == time2.twsec) { + return Double.compare(time1.tfsec, time2.tfsec); + } + return Double.compare(time1.twsec, time2.twsec); + } + + /** + * Returns the result of adding an offset to a UTCTime. + */ + public static UTCTime add(UTCTime time, double seconds) { + return utils.increment(utils.copy(time), seconds); + } + + /** + * Adds an offset to a UTCTime. + */ + public static UTCTime increment(UTCTime time, double seconds) { + // Separate the fractional and whole portions of the offset + double fractional = seconds % 1.0; + double whole = seconds - fractional; + time.tfsec += fractional; + time.twsec += (seconds - fractional); + utils.normalize(time); + return time; + } + + /** + * Returns the result of substracting an offset from a UTCTime. + */ + public static UTCTime subtract(UTCTime time, double seconds) { + return utils.add(time, -seconds); + } + + /** + * Subtracts an offset from a UTCTime. + */ + public static UTCTime decrement(UTCTime time, double seconds) { + return utils.increment(time, -seconds); + } + + /** + * Returns the difference, in seconds, between two UTCTime values (i.e., lhs - rhs). + */ + public static double difference(UTCTime lhs, UTCTime rhs) { + return (lhs.twsec - rhs.twsec) + (lhs.tfsec - rhs.tfsec); + } + + /** + * String format to produce YYYY:MM:DD::HH:MM:SS.SSSSSS output for UTCTime. + */ + private static final String TIME_FORMAT = "%1$tY:%1$tm:%1$td::%1$tH:%1$tM:%1$tS.%2$06d"; + + /** + * Formats a UTCTime as a human-readable string following the format: + * YYYY:MM:DD::HH:MM:SS.SSSSSS + */ + public static String toString(UTCTime time) { + // Use Calendar to hold the integral seconds, but since it is limited + // to millisecond precision, exclude the fractional seconds. It must be + // created with the UTC time zone, otherwise the formatter will return + // local time. + Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC")); + calendar.setTimeInMillis((long)(time.twsec * 1000.0)); + + // Append the fractional seconds down to microsecond precision. + int usec = (int) Math.round(time.tfsec * 1000000.0); + + return String.format(utils.TIME_FORMAT, calendar, usec); + } + + /** + * Converts a human-readable string following of the format: + * YYYY:MM:DD::HH:MM:SS.SSSSSS + * to UTCTime + */ + public static UTCTime convert(String time) { + String[] token = time.split(":"); + if (token.length != 7) + return new CF.UTCTime(); + int year = Integer.parseInt(token[0]); + int month = Integer.parseInt(token[1])-1; + int day = Integer.parseInt(token[2]); + int hours = Integer.parseInt(token[4]); + int minutes = Integer.parseInt(token[5]); + double full_seconds = Double.parseDouble(token[6]); + int seconds = (int)full_seconds; + Calendar _calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC")); + + _calendar.set(year, month, day, hours, minutes, seconds); + double wsec = _calendar.getTimeInMillis()/1000; + double fsec = full_seconds - seconds; + return new CF.UTCTime((short)1, wsec, fsec); + } +} diff --git a/redhawk/src/testing/sdr/dom/components/TestJavaProps/TestJavaProps.java b/redhawk/src/testing/sdr/dom/components/TestJavaProps/TestJavaProps.java index c0bae293a..dacc5e5c2 100644 --- a/redhawk/src/testing/sdr/dom/components/TestJavaProps/TestJavaProps.java +++ b/redhawk/src/testing/sdr/dom/components/TestJavaProps/TestJavaProps.java @@ -45,6 +45,8 @@ import java.util.ArrayList; import java.util.List; import java.util.Arrays; +import org.ossie.properties.PropertyListener; +import org.ossie.redhawk.time.utils; /** * This is the component code. This file contains all the access points @@ -125,6 +127,35 @@ public class TestJavaProps extends Resource implements Runnable { new Kind[] {Kind.CONFIGURE,} // kind ); + public final UTCTimeProperty simple_utctime = + new UTCTimeProperty( + "simple_utctime", //id + null, //name + "2017:2:1::14:01:00.123", //default value + Mode.READWRITE, //mode + Action.EXTERNAL, //action + new Kind[] {Kind.PROPERTY} + ); + + public final UTCTimeSequenceProperty seq_utctime = + new UTCTimeSequenceProperty( + "seq_utctime", //id + null, //name + UTCTimeSequenceProperty.asList("2010:2:1::12:01:00.123","2011:2:1::12:01:00.123"), //default value + Mode.READWRITE, //mode + Action.EXTERNAL, //action + new Kind[] {Kind.PROPERTY} + ); + public final BooleanProperty reset_utctime = + new BooleanProperty( + "reset_utctime", //id + null, //name + false, //default value + Mode.READWRITE, //mode + Action.EXTERNAL, //action + new Kind[] {Kind.PROPERTY} + ); + /** * The property readOnly * If the meaning of this property isn't clear, a description should be added. @@ -242,14 +273,27 @@ public TestJavaProps() addProperty(struct_prop); addProperty(structseq_prop); addProperty(readOnly); + addProperty(simple_utctime); + addProperty(reset_utctime); + addProperty(seq_utctime); // Project/input // Uses/outputs //begin-user-code + this.reset_utctime.addChangeListener(new PropertyListener() { + public void valueChanged(Boolean oldValue, Boolean newValue) { + reset_utctimeValueChanged(oldValue, newValue); + } + }); //end-user-code } - + + private void reset_utctimeValueChanged(Boolean oldValue, Boolean newValue) + { + this.simple_utctime.setValue(utils.now()); + } + /** * * Main processing thread diff --git a/redhawk/src/testing/sdr/dom/components/TestJavaProps/TestJavaProps.prf.xml b/redhawk/src/testing/sdr/dom/components/TestJavaProps/TestJavaProps.prf.xml index d20f20a68..83ea0e271 100644 --- a/redhawk/src/testing/sdr/dom/components/TestJavaProps/TestJavaProps.prf.xml +++ b/redhawk/src/testing/sdr/dom/components/TestJavaProps/TestJavaProps.prf.xml @@ -41,6 +41,24 @@ with this program. If not, see http://www.gnu.org/licenses/. + + 2017:2:1::13:01:00.123 + + + + + false + + + + + + 2010:2:1::12:01:00.123 + 2011:2:1::12:01:00.123 + + + + 0 diff --git a/redhawk/src/testing/sdr/dom/waveforms/TestJavaProps/TestJavaProps.sad.xml b/redhawk/src/testing/sdr/dom/waveforms/TestJavaProps/TestJavaProps.sad.xml index 4fb2a9dee..2c6d63fb1 100644 --- a/redhawk/src/testing/sdr/dom/waveforms/TestJavaProps/TestJavaProps.sad.xml +++ b/redhawk/src/testing/sdr/dom/waveforms/TestJavaProps/TestJavaProps.sad.xml @@ -46,6 +46,7 @@ with this program. If not, see http://www.gnu.org/licenses/. + diff --git a/redhawk/src/testing/tests/test_11_JavaProperties.py b/redhawk/src/testing/tests/test_11_JavaProperties.py index 751a83406..e44ece1ab 100644 --- a/redhawk/src/testing/tests/test_11_JavaProperties.py +++ b/redhawk/src/testing/tests/test_11_JavaProperties.py @@ -738,6 +738,50 @@ def test_Property_JAVA(self): app.releaseObject() +@scatest.requireJava +class JavaUTCTimeTest(scatest.CorbaTestCase): + def setUp(self): + domBooter, self._domMgr = self.launchDomainManager() + devBooter, self._devMgr = self.launchDeviceManager("/nodes/test_ExecutableDevice_node/DeviceManager.dcd.xml") + self._app = None + if self._domMgr: + try: + sadpath = "/waveforms/TestJavaProps/TestJavaProps.sad.xml" + self._domMgr.installApplication(sadpath) + appFact = self._domMgr._get_applicationFactories()[0] + self._app = appFact.create(appFact._get_name(), [], []) + except: + pass + + def tearDown(self): + if self._app: + self._app.stop() + self._app.releaseObject() + + # Do all application shutdown before calling the base class tearDown, + # or failures will probably occur. + scatest.CorbaTestCase.tearDown(self) + + def preconditions(self): + self.assertNotEqual(self._domMgr, None, "DomainManager not available") + self.assertNotEqual(self._devMgr, None, "DeviceManager not available") + self.assertNotEqual(self._app, None, "Application not created") + + def test_UTCTimeJava(self): + prop = self._app.query([CF.DataType('simple_utctime', any.to_any(None))]) + datetime = time.localtime(prop[0].value.value().twsec) + self.assertEquals(datetime.tm_year,2017) + self.assertEquals(datetime.tm_mon,2) + self.assertEquals(datetime.tm_mday,1) + self.assertEquals(datetime.tm_hour,10) + self.assertEquals(datetime.tm_min,1) + self.assertEquals(datetime.tm_sec,0) + self.assertEquals(prop[0].value.value().tfsec,0.123) + self._app.configure([CF.DataType('reset_utctime', any.to_any(True))]) + prop = self._app.query([CF.DataType('simple_utctime', any.to_any(None))]) + now = time.time() + self.assertEquals(abs(now-(prop[0].value.value().twsec+prop[0].value.value().tfsec))<0.1,True) + @scatest.requireJava class JavaPropertiesReadOnly(scatest.CorbaTestCase): From 6a1a11d63e06e3b6055f3748185a7fc827b732e5 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Sat, 14 Jan 2017 12:35:20 -0500 Subject: [PATCH 0647/1644] Merge conflict resolution --- .../base/framework/python/ossie/properties.py | 19 ++- .../python/ossie/utils/prop_helpers.py | 2 +- .../framework/python/redhawk/time/__init__.py | 23 +++ .../framework/python/redhawk/time/utils.py | 152 ++++++++++++++++++ .../TestPythonProps/TestPythonProps.prf.xml | 19 +++ .../TestPythonProps/TestPythonProps.py | 27 ++++ .../TestPythonProps/TestPythonProps.sad.xml | 3 + .../src/testing/tests/test_11_PyProperties.py | 43 +++++ 8 files changed, 284 insertions(+), 4 deletions(-) create mode 100644 redhawk/src/base/framework/python/redhawk/time/__init__.py create mode 100644 redhawk/src/base/framework/python/redhawk/time/utils.py diff --git a/redhawk/src/base/framework/python/ossie/properties.py b/redhawk/src/base/framework/python/ossie/properties.py index 05e7ec8c5..33c55e25b 100644 --- a/redhawk/src/base/framework/python/ossie/properties.py +++ b/redhawk/src/base/framework/python/ossie/properties.py @@ -33,6 +33,7 @@ import types import struct import inspect +import redhawk.time.utils # numpy types to Corba Type codes __NP_ALT_MAP = { @@ -128,7 +129,12 @@ CF._tc_complexULongLong, CF.complexULongLong, long, - CF._tc_complexULongLongSeq) + CF._tc_complexULongLongSeq), + 'utctime': (CF.UTCTime, + CF._tc_UTCTime, + CF.UTCTime, + CF.UTCTime, + CF._tc_UTCTimeSequence) } _SCA_TYPES = [ @@ -136,7 +142,7 @@ 'objref', 'octet', 'string', 'ulong', 'ushort', 'longlong', 'ulonglong', 'complexFloat', 'complexBoolean', 'complexULong', 'complexShort', 'complexOctet', 'complexChar', 'complexUShort', 'complexDouble', - 'complexLong', 'complexLongLong', 'complexULongLong' + 'complexLong', 'complexLongLong', 'complexULongLong', 'utctime' ] def getPyType(type_, alt_map=None): @@ -209,6 +215,8 @@ def to_pyvalue(data, type_,alt_py_tc=None): data = pytype(data,0) else: data = pytype(data) + elif pytype == CF.UTCTime: + data = pytype(data['tcstatus'], data['twsec'], data['tfsec']) else: data = pytype(data) return data @@ -246,6 +254,8 @@ def to_xmlvalue(data, type_): v=retval elif type_ == "boolean": v = str(bool(data)).lower() + elif type_ == "utctime": + v = redhawk.time.utils.toString(data) elif type_ == "string": # Remove quotes added by repr v = v[1:-1] return v @@ -278,6 +288,10 @@ def to_tc_value(data, type_, alt_map=None): # get the CF typecode tc = getTypeCode(type_) return CORBA.Any(tc, data) + elif type_.find('utctime') == 0: + tc = getTypeCode(type_) + _any = CORBA.Any(tc, data) + return CORBA.Any(tc, data) elif alt_map and alt_map.has_key(type_): pytype, tc = alt_map[type_] if tc == None: @@ -296,7 +310,6 @@ def to_tc_value(data, type_, alt_map=None): # Convert to the correct Python using alternate mapping data = to_pyvalue(data, type_, alt_map) return CORBA.Any(tc, data) - elif __TYPE_MAP.has_key(type_): # If the typecode is known, use that pytype, tc = __TYPE_MAP[type_] diff --git a/redhawk/src/base/framework/python/ossie/utils/prop_helpers.py b/redhawk/src/base/framework/python/ossie/utils/prop_helpers.py index ce63ae7f4..dba2b0674 100644 --- a/redhawk/src/base/framework/python/ossie/utils/prop_helpers.py +++ b/redhawk/src/base/framework/python/ossie/utils/prop_helpers.py @@ -719,7 +719,7 @@ def __init__(self, id, valueType, enum, compRef, kinds,defValue=None, parent=Non structRef, structSeqRef, structSeqIdx """ if valueType not in SCA_TYPES: - raise('"' + str(valueType) + '"' + ' is not a valid valueType, choose from\n ' + str(SCA_TYPES)) + raise(Exception('"' + str(valueType) + '"' + ' is not a valid valueType, choose from\n ' + str(SCA_TYPES))) # Initialize the parent Property.__init__(self, id, type=valueType, kinds=kinds,compRef=compRef, mode=mode, action=action, parent=parent, diff --git a/redhawk/src/base/framework/python/redhawk/time/__init__.py b/redhawk/src/base/framework/python/redhawk/time/__init__.py new file mode 100644 index 000000000..5304a70ad --- /dev/null +++ b/redhawk/src/base/framework/python/redhawk/time/__init__.py @@ -0,0 +1,23 @@ +# +# This file is protected by Copyright. Please refer to the COPYRIGHT file +# distributed with this source distribution. +# +# This file is part of REDHAWK core. +# +# REDHAWK core is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation, either version 3 of the License, or (at your option) any +# later version. +# +# REDHAWK core is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +# details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/. +# + +# This is a stub file to provide the 'redhawk' namespace +# Python files generated for new IDLs will be added under this namespace +# e.g. 'redhawk.mynamespace' diff --git a/redhawk/src/base/framework/python/redhawk/time/utils.py b/redhawk/src/base/framework/python/redhawk/time/utils.py new file mode 100644 index 000000000..321442ad0 --- /dev/null +++ b/redhawk/src/base/framework/python/redhawk/time/utils.py @@ -0,0 +1,152 @@ +# +# This file is protected by Copyright. Please refer to the COPYRIGHT file +# distributed with this source distribution. +# +# This file is part of REDHAWK bulkioInterfaces. +# +# REDHAWK bulkioInterfaces is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation, either version 3 of the License, or (at your option) any +# later version. +# +# REDHAWK bulkioInterfaces is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +# details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/. +# +import time +import copy +import math + +from ossie.cf import CF + +def now(): + """ + Generates a CF.UTCTime object using the current + CPU time that you can use in the pushPacket call + """ + ts = time.time() + return CF.UTCTime(1, int(ts), ts - int(ts)) + +def notSet(): + """ + Generates a CF.UTCTime object with zero time + and an invalid flag. This is used by the automatic EOS + """ + return CF.UTCTime(1, 0.0, 0.0) + +def cpuTimeStamp(): + return now() + +def create( whole_secs=-1.0, fractional_secs=-1.0 ): + """ + Generates a CF.UTCTime object using the current + CPU time that you can use in the pushPacket call + """ + wsec = whole_secs; + fsec = fractional_secs; + if wsec < 0.0 and fsec < 0.0 : + ts=time.time() + wsec=int(ts) + fsec = ts-int(ts) + + return CF.UTCTime(1, wsec, fsec ) + +def compare(T1, T2): + """ + Will compare two CF.UTCTime objects and return True + if they are both equal, and false otherwise + """ + if not T1 or not T2: + return False + + if T1.tcstatus != T2.tcstatus: + return False + if T1.tfsec != T2.tfsec: + return False + if T1.twsec != T2.twsec: + return False + return True + +def addSampleOffset(T, numSamples=0, xdelta=0.0): + tstamp = copy.deepcopy(T) + tstamp.twsec += int(numSamples*xdelta) + tstamp.tfsec += numSamples*xdelta - int(numSamples*xdelta) + if tstamp.tfsec >= 1.0: + tstamp.twsec += 1 + tstamp.tfsec -= 1.0 + return tstamp + +def normalize(tstamp): + # Get fractional adjustment from whole seconds + fadj, tstamp.twsec = math.modf(tstamp.twsec) + + # Adjust fractional seconds and get whole seconds adjustment + tstamp.tfsec, wadj = math.modf(tstamp.tfsec + fadj) + + # If fractional seconds are negative, borrow a second from the whole + # seconds to make it positive, normalizing to [0,1) + if (tstamp.tfsec < 0.0): + tstamp.tfsec += 1.0; + wadj -= 1.0; + + tstamp.twsec += wadj; + +def difference(t1, t2): + return (t1.twsec - t2.twsec) + (t1.tfsec - t2.tfsec) + +def add(t1, offset): + return iadd(copy.copy(t1), offset) + +def iadd(t1, offset): + fractional, whole = math.modf(offset) + t1.twsec += whole + t1.tfsec += fractional + normalize(t1) + return t1 + +def sub(t1, other): + if isinstance(other, CF.UTCTime): + return difference(t1, other) + else: + return isub(copy.copy(t1), other) + +def isub(t1, offset): + return iadd(t1, -offset) + +def compare(t1, t2): + if not isinstance(t2, CF.UTCTime): + return -1 + if (t1.twsec == t2.twsec): + return cmp(t1.tfsec, t2.tfsec) + else: + return cmp(t1.twsec, t2.twsec) + +def toString(tstamp): + # Break out the whole seconds into a GMT time + gmt = time.gmtime(tstamp.twsec) + # Append the fractional seconds down to microsecond precision + fractional = int(round(tstamp.tfsec * 1e6)) + return '%04d:%02d:%02d::%02d:%02d:%02d.%06d' % (gmt.tm_year, gmt.tm_mon, gmt.tm_mday, gmt.tm_hour, + gmt.tm_min, gmt.tm_sec, fractional) + +def convert(timeString): + _sets = timeString.split(':') + if len(_sets) != 7: + return CF.UTCTime(0,0,0) + _year, _month, _day, _blank, _hours, _minutes, _seconds = timeString.split(':') + _full_seconds = float(_seconds) + _time = time.mktime((int(_year),int(_month),int(_day),int(_hours),int(_minutes),int(_full_seconds),0,0,0)) + return CF.UTCTime(1, _time, _full_seconds - int(_full_seconds)) + # Break out the whole seconds into a GMT time + +# Insert the arithmetic functions as operators on the PrecisionUTCTime class +CF.UTCTime.__add__ = add +CF.UTCTime.__iadd__ = iadd +CF.UTCTime.__sub__ = sub +CF.UTCTime.__isub__ = isub +CF.UTCTime.__str__ = toString +CF.UTCTime.__cmp__ = compare diff --git a/redhawk/src/testing/sdr/dom/components/TestPythonProps/TestPythonProps.prf.xml b/redhawk/src/testing/sdr/dom/components/TestPythonProps/TestPythonProps.prf.xml index 0cb88da1b..76dad64e7 100644 --- a/redhawk/src/testing/sdr/dom/components/TestPythonProps/TestPythonProps.prf.xml +++ b/redhawk/src/testing/sdr/dom/components/TestPythonProps/TestPythonProps.prf.xml @@ -88,6 +88,25 @@ with this program. If not, see http://www.gnu.org/licenses/. + + 2017:2:1::13:01:00.123 + + + + + false + + + + + + 2010:2:1::12:01:00.123 + 2011:2:1::12:01:00.123 + + + + + empty diff --git a/redhawk/src/testing/sdr/dom/components/TestPythonProps/TestPythonProps.py b/redhawk/src/testing/sdr/dom/components/TestPythonProps/TestPythonProps.py index f7cca8240..a3a61278a 100755 --- a/redhawk/src/testing/sdr/dom/components/TestPythonProps/TestPythonProps.py +++ b/redhawk/src/testing/sdr/dom/components/TestPythonProps/TestPythonProps.py @@ -25,6 +25,7 @@ from ossie.resource import Resource, start_component from ossie.properties import simple_property, simpleseq_property, struct_property, structseq_property from omniORB.any import from_any +import redhawk.time.utils class TestPythonProps (CF__POA.Resource, Resource): @@ -64,6 +65,29 @@ class TestPythonProps (CF__POA.Resource, Resource): action="external", kinds=("property",)) + simple_utctime = simple_property(id_="simple_utctime", + name="simple_utctime", + type_="utctime", + defvalue="2017:2:1::14:01:00.123", + mode="readwrite", + action="external", + kinds=("property",)) + + reset_utctime = simple_property(id_="reset_utctime", + name="reset_utctime", + type_="boolean", + defvalue=False, + mode="readwrite", + action="external", + kinds=("property",)) + + seq_utctime = simpleseq_property(id_="seq_utctime", + name="seq_utctime", + type_="utctime", + mode="readwrite", + action="external", + kinds=("property",)) + class SomeStruct(object): field1 = simple_property(id_="item1", type_="string", @@ -90,6 +114,8 @@ def __init__(self, ip_address="", port=0): self.ip_address = ip_address self.port = port + def reset_utcCallback(self, id, old_value, new_value): + self.simple_utctime = redhawk.time.utils.now() multicasts = structseq_property(id_="DCE:897a5489-f680-46a8-a698-e36fd8bbae80[]", name="multicasts", @@ -98,6 +124,7 @@ def __init__(self, ip_address="", port=0): def __init__(self, identifier, execparams): Resource.__init__(self, identifier, execparams) + self.addPropertyChangeListener('reset_utctime', self.reset_utcCallback) def runTest(self, test, props): if test == 0: diff --git a/redhawk/src/testing/sdr/dom/waveforms/TestPythonProps/TestPythonProps.sad.xml b/redhawk/src/testing/sdr/dom/waveforms/TestPythonProps/TestPythonProps.sad.xml index 3c8e85a4f..ea97336b3 100644 --- a/redhawk/src/testing/sdr/dom/waveforms/TestPythonProps/TestPythonProps.sad.xml +++ b/redhawk/src/testing/sdr/dom/waveforms/TestPythonProps/TestPythonProps.sad.xml @@ -31,6 +31,9 @@ with this program. If not, see http://www.gnu.org/licenses/. TestPythonProps1 + + + diff --git a/redhawk/src/testing/tests/test_11_PyProperties.py b/redhawk/src/testing/tests/test_11_PyProperties.py index ad915b108..d09d88637 100644 --- a/redhawk/src/testing/tests/test_11_PyProperties.py +++ b/redhawk/src/testing/tests/test_11_PyProperties.py @@ -1156,3 +1156,46 @@ def test_readonly_sad(self): self.assertNotEqual(comp,None) readonly_prop=CF.DataType("readOnly", any.to_any("try_again")) self.assertRaises(CF.PropertySet.InvalidConfiguration, comp.configure, [ readonly_prop ] ) + +class PythonUTCTimeTest(scatest.CorbaTestCase): + def setUp(self): + domBooter, self._domMgr = self.launchDomainManager() + devBooter, self._devMgr = self.launchDeviceManager("/nodes/test_ExecutableDevice_node/DeviceManager.dcd.xml") + self._app = None + if self._domMgr: + try: + sadpath = "/waveforms/TestPythonProps/TestPythonProps.sad.xml" + self._domMgr.installApplication(sadpath) + appFact = self._domMgr._get_applicationFactories()[0] + self._app = appFact.create(appFact._get_name(), [], []) + except: + pass + + def tearDown(self): + if self._app: + self._app.stop() + self._app.releaseObject() + + # Do all application shutdown before calling the base class tearDown, + # or failures will probably occur. + scatest.CorbaTestCase.tearDown(self) + + def preconditions(self): + self.assertNotEqual(self._domMgr, None, "DomainManager not available") + self.assertNotEqual(self._devMgr, None, "DeviceManager not available") + self.assertNotEqual(self._app, None, "Application not created") + + def test_UTCTimePython(self): + prop = self._app.query([CF.DataType('simple_utctime', any.to_any(None))]) + datetime = time.localtime(prop[0].value.value().twsec) + self.assertEquals(datetime.tm_year,2017) + self.assertEquals(datetime.tm_mon,2) + self.assertEquals(datetime.tm_mday,1) + self.assertEquals(datetime.tm_hour,10) + self.assertEquals(datetime.tm_min,1) + self.assertEquals(datetime.tm_sec,0) + self.assertEquals(prop[0].value.value().tfsec,0.123) + self._app.configure([CF.DataType('reset_utctime', any.to_any(True))]) + prop = self._app.query([CF.DataType('simple_utctime', any.to_any(None))]) + now = time.time() + self.assertEquals(abs(now-(prop[0].value.value().twsec+prop[0].value.value().tfsec))<0.1,True) From 43b295f7e1e6bebbbc65732e69ba2f50dfb90a04 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Sat, 14 Jan 2017 12:34:12 -0500 Subject: [PATCH 0648/1644] Refs CF-1420. Code generator testing for UTCTime properties --- .../sdr/dom/components/props/props.prf.xml | 18 ++++++++++++++++++ redhawk-codegen/redhawk/codegen/generate.py | 6 +++++- .../codegen/jinja/cpp/properties/mapping.py | 19 +++++++++++++++---- .../redhawk/codegen/jinja/java/properties.py | 8 +++++--- redhawk-codegen/redhawk/codegen/lang/cpp.py | 1 + redhawk-codegen/redhawk/codegen/lang/idl.py | 2 +- redhawk-codegen/redhawk/codegen/lang/java.py | 9 ++++++--- .../redhawk/codegen/lang/python.py | 4 ++++ .../src/org/ossie/properties/AnyUtils.java | 4 +++- .../python/ossie/utils/model/__init__.py | 8 +++++++- .../python/ossie/utils/prop_helpers.py | 2 ++ .../python/ossie/utils/type_helpers.py | 4 ++++ redhawk/src/base/framework/python/setup.py | 3 ++- 13 files changed, 73 insertions(+), 15 deletions(-) diff --git a/codegenTesting/sdr/dom/components/props/props.prf.xml b/codegenTesting/sdr/dom/components/props/props.prf.xml index 5a918f1a6..86b4ae391 100644 --- a/codegenTesting/sdr/dom/components/props/props.prf.xml +++ b/codegenTesting/sdr/dom/components/props/props.prf.xml @@ -293,4 +293,22 @@ with this program. If not, see http://www.gnu.org/licenses/. + + 2017:2:1::12:01:00.123 + + + + + false + + + + + + 2010:2:1::12:01:00.123 + 2011:2:1::12:01:00.123 + + + + diff --git a/redhawk-codegen/redhawk/codegen/generate.py b/redhawk-codegen/redhawk/codegen/generate.py index 52de58d68..56ba334e1 100644 --- a/redhawk-codegen/redhawk/codegen/generate.py +++ b/redhawk-codegen/redhawk/codegen/generate.py @@ -36,7 +36,11 @@ def importTemplate(template): """ Imports a code generation module from the given fully-qualified name. """ - package = __import__(template) + try: + package = __import__(template) + except Exception, e: + print e + raise # Since the module name probably has dots, get the most specific module # (e.g. 'component' from 'template.cpp.component'). diff --git a/redhawk-codegen/redhawk/codegen/jinja/cpp/properties/mapping.py b/redhawk-codegen/redhawk/codegen/jinja/cpp/properties/mapping.py index 04044b926..79f0bbf6f 100644 --- a/redhawk-codegen/redhawk/codegen/jinja/cpp/properties/mapping.py +++ b/redhawk-codegen/redhawk/codegen/jinja/cpp/properties/mapping.py @@ -37,6 +37,7 @@ CorbaTypes.DOUBLE : 'd', CorbaTypes.STRING : 's', CorbaTypes.OBJREF : 's', + CorbaTypes.UTCTIME : 'u', } class CppPropertyMapper(PropertyMapper): @@ -65,9 +66,14 @@ def mapSimpleProperty(self, prop): cppprop['isOptional'] = prop.isOptional() cppprop['cpptype'] = cpp.cppType(prop.type(), prop.isComplex()) if prop.hasValue(): - cppprop['cppvalue'] = cpp.literal(prop.value(), + _prepend = '' + _append = '' + if prop.type() == 'utctime': + _prepend = '"' + _append = '"' + cppprop['cppvalue'] = _prepend+cpp.literal(prop.value(), prop.type(), - prop.isComplex()) + prop.isComplex())+_append cppprop['format'] = self._getSimpleFormat(prop, False) return cppprop @@ -76,9 +82,14 @@ def mapSimpleSequenceProperty(self, prop): cppprop['cpptype'] = cpp.sequenceType(prop.type(), prop.isComplex()) cppprop['isOptional'] = prop.isOptional() if prop.hasValue(): - cppprop['cppvalues'] = [cpp.literal(v, + _prepend = '' + _append = '' + if prop.type() == 'utctime': + _prepend = 'redhawk::time::utils::convert("' + _append = '")' + cppprop['cppvalues'] = [_prepend+cpp.literal(v, prop.type(), - prop.isComplex()) + prop.isComplex())+_append for v in prop.value()] cppprop['format'] = self._getSimpleFormat(prop, True) return cppprop diff --git a/redhawk-codegen/redhawk/codegen/jinja/java/properties.py b/redhawk-codegen/redhawk/codegen/jinja/java/properties.py index 3fd6d3769..dae449a82 100644 --- a/redhawk-codegen/redhawk/codegen/jinja/java/properties.py +++ b/redhawk-codegen/redhawk/codegen/jinja/java/properties.py @@ -38,6 +38,7 @@ CorbaTypes.ULONGLONG: java.Types.LONG, CorbaTypes.FLOAT: java.Types.FLOAT, CorbaTypes.DOUBLE: java.Types.DOUBLE, + CorbaTypes.UTCTIME: java.Types.UTCTIME, CorbaTypes.STRING: 'String', CorbaTypes.OBJREF: 'String' } @@ -55,6 +56,7 @@ CorbaTypes.ULONGLONG: 'ULongLong', CorbaTypes.FLOAT: 'Float', CorbaTypes.DOUBLE: 'Double', + CorbaTypes.UTCTIME: 'UTCTime', CorbaTypes.STRING: 'String', CorbaTypes.OBJREF: 'Objref' } @@ -107,13 +109,13 @@ def mapSimpleProperty(self, prop): def mapSimpleSequenceProperty(self, prop): javaprop, javatype = self._createComplexJavaProp(prop) - values = [] + values = [] if prop.hasValue(): - for value in prop.value(): + for value in prop.value(): values.append(java.literal(value, javatype, complex = prop.isComplex())) - javaprop['javavalues'] = values + javaprop['javavalues'] = values javaprop['isOptional'] = prop.isOptional() return javaprop diff --git a/redhawk-codegen/redhawk/codegen/lang/cpp.py b/redhawk-codegen/redhawk/codegen/lang/cpp.py index 376968ae4..80a473ef0 100644 --- a/redhawk-codegen/redhawk/codegen/lang/cpp.py +++ b/redhawk-codegen/redhawk/codegen/lang/cpp.py @@ -55,6 +55,7 @@ CorbaTypes.FLOAT: 'float', CorbaTypes.DOUBLE: 'double', CorbaTypes.STRING: 'std::string', + CorbaTypes.UTCTIME: 'CF::UTCTime', CorbaTypes.OBJREF: 'std::string' } diff --git a/redhawk-codegen/redhawk/codegen/lang/idl.py b/redhawk-codegen/redhawk/codegen/lang/idl.py index 8a9db6194..96299d413 100644 --- a/redhawk-codegen/redhawk/codegen/lang/idl.py +++ b/redhawk-codegen/redhawk/codegen/lang/idl.py @@ -25,7 +25,7 @@ from redhawk.codegen.utils import strenum CorbaTypes = strenum('octet','boolean','char','short','ushort','long','ulong', - 'longlong','ulonglong','float','double','string','objref') + 'longlong','ulonglong','float','double','string','objref', 'utctime') idlRepo = IDLLibrary() idlRepo.addSearchPath(os.path.join(os.environ['OSSIEHOME'], 'share/idl')) diff --git a/redhawk-codegen/redhawk/codegen/lang/java.py b/redhawk-codegen/redhawk/codegen/lang/java.py index a906b9dfa..2dc499cef 100644 --- a/redhawk-codegen/redhawk/codegen/lang/java.py +++ b/redhawk-codegen/redhawk/codegen/lang/java.py @@ -28,8 +28,8 @@ TRUE = 'true' FALSE = 'false' -Types = strenum('boolean', 'char', 'byte', 'short', 'int', 'long', 'float', 'double') -BoxTypes = strenum('Boolean', 'Character', 'Byte', 'Short', 'Integer', 'Long', 'Float', 'Double') +Types = strenum('boolean', 'char', 'byte', 'short', 'int', 'long', 'float', 'double', 'utctime') +BoxTypes = strenum('Boolean', 'Character', 'Byte', 'Short', 'Integer', 'Long', 'Float', 'Double', 'UTCTime') _reservedKeywords = set(("abstract", "assert", "boolean", "break", "byte", "case", "catch", "char", "class", "const", "continue", "default", @@ -49,7 +49,8 @@ Types.INT: BoxTypes.INTEGER, Types.LONG: BoxTypes.LONG, Types.FLOAT: BoxTypes.FLOAT, - Types.DOUBLE: BoxTypes.DOUBLE + Types.DOUBLE: BoxTypes.DOUBLE, + Types.UTCTIME: BoxTypes.UTCTIME } _typeSize = { @@ -124,6 +125,8 @@ def _complexLiteral(value, typename): def literal(value, typename, complex=False): if complex: return _complexLiteral(value, typename) + elif typename == 'utctime': + return stringLiteral(value) elif typename == 'String': return stringLiteral(value) elif typename == 'Object': diff --git a/redhawk-codegen/redhawk/codegen/lang/python.py b/redhawk-codegen/redhawk/codegen/lang/python.py index addd634b8..715a6e48e 100644 --- a/redhawk-codegen/redhawk/codegen/lang/python.py +++ b/redhawk-codegen/redhawk/codegen/lang/python.py @@ -43,6 +43,9 @@ def boolLiteral(value): def floatLiteral(value): return repr(float(value)) +def UTCTimeLiteral(value): + return '"%s"' % (value,) + def intLiteral(value): return repr(int(value)) @@ -69,6 +72,7 @@ def stringToBoolean(value): CorbaTypes.ULONGLONG: longLiteral, CorbaTypes.FLOAT: floatLiteral, CorbaTypes.DOUBLE: floatLiteral, + CorbaTypes.UTCTIME: UTCTimeLiteral, CorbaTypes.STRING: stringLiteral, CorbaTypes.OBJREF: stringLiteral, } diff --git a/redhawk/src/base/framework/java/ossie/src/org/ossie/properties/AnyUtils.java b/redhawk/src/base/framework/java/ossie/src/org/ossie/properties/AnyUtils.java index 363b258f5..e3ba11ee9 100644 --- a/redhawk/src/base/framework/java/ossie/src/org/ossie/properties/AnyUtils.java +++ b/redhawk/src/base/framework/java/ossie/src/org/ossie/properties/AnyUtils.java @@ -443,6 +443,8 @@ private static Object[] extractSequence(final Any theAny, return complexLongSeqHelper.extract(theAny); } else if (complexULongLongHelper.type().equivalent(contentType)) { return complexULongLongSeqHelper.extract(theAny); + } else if (UTCTimeHelper.type().equivalent(contentType)) { + return UTCTimeSequenceHelper.extract(theAny); } else { throw new IllegalArgumentException("Unsupported struct content type: " + contentType); } @@ -1129,7 +1131,7 @@ public static boolean compareAnys(final Any a, final Any b, final String action) } return false; } - + // Here is the test to determine if we have a struct sequence if(tmpA.getClass() == Any[].class) { Any[] anysA = (Any[])tmpA; diff --git a/redhawk/src/base/framework/python/ossie/utils/model/__init__.py b/redhawk/src/base/framework/python/ossie/utils/model/__init__.py index ec5d3afc3..b2102f0c7 100644 --- a/redhawk/src/base/framework/python/ossie/utils/model/__init__.py +++ b/redhawk/src/base/framework/python/ossie/utils/model/__init__.py @@ -40,10 +40,11 @@ from ossie.cf import ExtendedCF as _ExtendedCF from ossie.utils.formatting import TablePrinter from ossie.utils import prop_helpers +import redhawk.time.utils import warnings as _warnings from connect import * -_DEBUG = False +_DEBUG = False _trackLaunchedApps = False _idllib = idllib.IDLLibrary() @@ -105,6 +106,11 @@ def _convertType(propType, val): real = int(real) imag = int(imag) newValue = complex(real, imag) + elif propType == 'utctime': + if type(val) == str: + newValue = redhawk.time.utils.convert(val) + else: + newValue = val else: newValue = None return newValue diff --git a/redhawk/src/base/framework/python/ossie/utils/prop_helpers.py b/redhawk/src/base/framework/python/ossie/utils/prop_helpers.py index dba2b0674..81b11a3fd 100644 --- a/redhawk/src/base/framework/python/ossie/utils/prop_helpers.py +++ b/redhawk/src/base/framework/python/ossie/utils/prop_helpers.py @@ -904,6 +904,8 @@ def __init__(self, id, valueType, kinds, compRef, defValue=None, parent=None, mo # to determine complexity, as in the case of a struct sequence, # the value of self.valueType may not be a string. self.complex = True + elif self.valueType == 'utctime': + self.typecode = getCFSeqType(self.valueType) def _getItemKey(self): return self.id diff --git a/redhawk/src/base/framework/python/ossie/utils/type_helpers.py b/redhawk/src/base/framework/python/ossie/utils/type_helpers.py index 9c4f2afe1..7253911fa 100644 --- a/redhawk/src/base/framework/python/ossie/utils/type_helpers.py +++ b/redhawk/src/base/framework/python/ossie/utils/type_helpers.py @@ -112,6 +112,10 @@ def checkValidValue(value, dataType): return value elif dataType == 'boolean': return bool(value) + elif dataType == 'utctime': + if type(value) == str: + return redhawk.time.utils.convert(value) + return value #this is used for structs #datatype is a list of (ID, propType) pairs, value is a dict mapping an ID to a value for validation elif isinstance(dataType, list): diff --git a/redhawk/src/base/framework/python/setup.py b/redhawk/src/base/framework/python/setup.py index fd5ea86df..eb9c76936 100644 --- a/redhawk/src/base/framework/python/setup.py +++ b/redhawk/src/base/framework/python/setup.py @@ -74,7 +74,8 @@ 'ossie/utils/sca', 'ossie/utils/testing', 'ossie/utils/tools', - 'redhawk'] + 'redhawk', + 'redhawk/time'] exec(open('ossie/version.py').read()) From d9f487aaf09ea7b59ec29a0313b26ff51d0f1867 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Tue, 17 Jan 2017 11:03:25 -0500 Subject: [PATCH 0649/1644] Refs CF-1420. Missing file for timestamp property --- .../org/ossie/properties/UTCTimeProperty.java | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 redhawk/src/base/framework/java/ossie/src/org/ossie/properties/UTCTimeProperty.java diff --git a/redhawk/src/base/framework/java/ossie/src/org/ossie/properties/UTCTimeProperty.java b/redhawk/src/base/framework/java/ossie/src/org/ossie/properties/UTCTimeProperty.java new file mode 100644 index 000000000..110ebc54e --- /dev/null +++ b/redhawk/src/base/framework/java/ossie/src/org/ossie/properties/UTCTimeProperty.java @@ -0,0 +1,64 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK core. + * + * REDHAWK core is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +package org.ossie.properties; + +import org.omg.CORBA.Any; +import CF.UTCTime; +import CF.UTCTimeHelper; +import org.ossie.redhawk.time.utils; + +public class UTCTimeProperty extends AbstractSimpleProperty { + public UTCTimeProperty(String id, String name, UTCTime value, Mode mode, + Action action, Kind[] kinds) { + super(id, name, "utctime", value, mode, action, kinds); + } + + public UTCTimeProperty(String id, String name, UTCTime value, Mode mode, + Action action, Kind[] kinds, boolean optional) { + super(id, name, "utctime", value, mode, action, kinds, optional); + } + + public UTCTimeProperty(String id, String name, String value, Mode mode, + Action action, Kind[] kinds) { + super(id, name, "utctime", utils.convert(value), mode, action, kinds); + } + + public UTCTimeProperty(String id, String name, String value, Mode mode, + Action action, Kind[] kinds, boolean optional) { + super(id, name, "utctime", utils.convert(value), mode, action, kinds, optional); + } + + protected UTCTime extract(Any any) { + try { + return (UTCTime)AnyUtils.convertAny(any); + } catch (ClassCastException ex) { + throw new IllegalArgumentException("Incorrect any type recevied"); + } + } + + protected void insert(Any any, UTCTime value) { + UTCTimeHelper.insert(any, value); + } + + protected UTCTime parseString(String time) { + return utils.convert(time); + } +} From 70e764c8cfd44c1654e75f5b49262ff8a8cb3bbd Mon Sep 17 00:00:00 2001 From: Max Robert Date: Tue, 17 Jan 2017 11:03:56 -0500 Subject: [PATCH 0650/1644] Refs CF-1420. Missing file for timestamp property --- .../properties/UTCTimeSequenceProperty.java | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 redhawk/src/base/framework/java/ossie/src/org/ossie/properties/UTCTimeSequenceProperty.java diff --git a/redhawk/src/base/framework/java/ossie/src/org/ossie/properties/UTCTimeSequenceProperty.java b/redhawk/src/base/framework/java/ossie/src/org/ossie/properties/UTCTimeSequenceProperty.java new file mode 100644 index 000000000..0e84998f6 --- /dev/null +++ b/redhawk/src/base/framework/java/ossie/src/org/ossie/properties/UTCTimeSequenceProperty.java @@ -0,0 +1,68 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK core. + * + * REDHAWK core is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +package org.ossie.properties; + +import java.util.Arrays; +import java.util.ArrayList; +import java.util.List; + +import org.omg.CORBA.Any; +import CF.UTCTime; +import CF.UTCTimeSequenceHelper; +import org.ossie.redhawk.time.utils; + +public class UTCTimeSequenceProperty extends AbstractSequenceProperty { + public UTCTimeSequenceProperty(String id, String name, List value, Mode mode, + Action action, Kind[] kinds) { + super(id, name, "utctime", value, mode, action, kinds); + } + + public UTCTimeSequenceProperty(String id, String name, List value, Mode mode, + Action action, Kind[] kinds, boolean optional) { + super(id, name, "utctime", value, mode, action, kinds, optional); + } + + public static List asList(CF.UTCTime... array) { + return new ArrayList(Arrays.asList(array)); + } + + public static List asList(String... array) { + List list = new ArrayList(0); + for (String item : array) { + list.add(utils.convert(item)); + } + return list; + } + + protected List extract(Any any) { + CF.UTCTime[] array = CF.UTCTimeSequenceHelper.extract(any); + List list = new ArrayList(array.length); + for (CF.UTCTime item : array) { + list.add(item); + } + return list; + } + + protected void insert(Any any, List value) { + CF.UTCTime[] array = value.toArray(new CF.UTCTime[value.size()]); + CF.UTCTimeSequenceHelper.insert(any, array); + } +} From 1d8cf7a60254e6813ccd778d96a06aca8677cf04 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 17 Jan 2017 10:39:21 -0500 Subject: [PATCH 0651/1644] CF-1656 Added documentation comments to BufferManager API --- .../src/base/include/ossie/BufferManager.h | 175 +++++++++++++++++- 1 file changed, 169 insertions(+), 6 deletions(-) diff --git a/redhawk/src/base/include/ossie/BufferManager.h b/redhawk/src/base/include/ossie/BufferManager.h index af8436528..07ed5f528 100644 --- a/redhawk/src/base/include/ossie/BufferManager.h +++ b/redhawk/src/base/include/ossie/BufferManager.h @@ -28,11 +28,32 @@ namespace redhawk { /** - * Per-thread cache-based allocation. + * @brief Singleton class providing buffer allocation management. + * + * The %BufferManager improves the performance of repetetive allocations by + * caching allocated memory blocks on a per-thread basis. When a memory + * block is deallocated, it is returned to the cache of the thread that + * made the original allocation. Future allocations of the same (or nearly + * the same) size on the originating thread can return cached memory blocks + * rather than allocating a new memory block from the operating system. In + * comparison to using the operating system's facilities, the memory is not + * zeroed before it is returned to the caller; skipping this step provides + * the most significant optimization in the allocation process. + * + * %BufferManager's API gives additional control over caching policy to + * limit the size of per-thread caches. */ class BufferManager { public: + /** + * @brief STL-compliant allocator using BufferManager. + * + * %Allocator goes through the BufferManager to improve performance + * with repetitive allocations. In testing, allocations under 1K bytes + * did not show any benefit from %BufferManager; as a result, they + * defer to the basic std::allocator implementation. + */ template class Allocator : public std::allocator { @@ -84,50 +105,168 @@ namespace redhawk { } }; - BufferManager(); - ~BufferManager(); - + /** + * @brief Gets the %BufferManager singleton. + * @return Reference to the singleton instace. + */ static BufferManager& Instance(); + /** + * Static convenience function to allocate memory. + * @see allocate(size_t) + */ static inline void* Allocate(size_t bytes) { return Instance().allocate(bytes); } + /** + * Static convenience function to deallocate memory. + * @see deallocate(void*) + */ static inline void Deallocate(void* ptr) { return Instance().deallocate(ptr); } + /** + * @brief Allocate memory. + * @param bytes Required number of bytes. + * @return A void* to a memory block of at least @a bytes. + * + * If the requested allocation can be satisfied by the current thread's + * cache, a previously used memory block is returned. Otherwise, a new + * memory block is allocated from the operating system. + */ void* allocate(size_t bytes); + + /** + * @brief Deallocate memory. + * @param ptr The memory block to deallocate. + * + * The memory block is returned to the cache of the thread that originally + * allocated it. + */ void deallocate(void* ptr); + /** + * @brief Checks whether the %BufferManager is enabled. + * @return true if the %BufferManager is enabled. + * + * If the %BufferManager is disabled, deallocated memory blocks are + * immediately returned to the operating system. + */ bool isEnabled() const; + + /** + * @brief Enable or disable the %BufferManager. + * @param enabled true to enable the %BufferManager, false to disable + * + * If the %BufferManager is changing from enabled to disabled, all + * currently cached memory blocks are returned to the operating system. + */ void enable(bool enabled); + /** + * @returns The current per-thread cache byte limit. + */ size_t getMaxThreadBytes() const; + + /** + * @brief Sets the per-thread cache byte limit. + * @param bytes Maximum cached bytes (per thread). + */ void setMaxThreadBytes(size_t bytes); + /** + * @returns The current per-thread cached memory block limit. + */ size_t getMaxThreadBlocks() const; + + /** + * @brief Sets the per-thread cached memory block limit. + * @param bytes Maximum cached memory blocks (per thread). + */ void setMaxThreadBlocks(size_t blocks); + /** + * @returns The current per-thread cache memory block age limit. + */ size_t getMaxThreadAge() const; + + /** + * @brief Sets the per-thread cache memory block age limit. + * @param bytes Maximum age of cached memory block (per thread). + * + * The age of a memory block is defined in terms of deallocate cycles. + * When a block is returned to the cache, it starts with an age of 0. + * Each time another block of memory is returned to the cache, the age + * of all existing blocks in the cache increases by one. If a block's + * age hits the age limit it is deallocated, allowing infrequently used + * blocks to be returned to the operating system. + */ void setMaxThreadAge(size_t age); - // Statistical information + /** + * @brief Statistical information about buffer caches. + * + * The %Statistics struct describes the aggregate state of all thread + * caches maintained by %BufferManager. + */ struct Statistics { + /** + * Number of currently active caches. + */ size_t caches; + + /** + * Number of times an allocation was satisfied with a memory block + * from the cache. + */ size_t hits; + + /** + * Number of times the cache was not able to satisfy an allocation + * and a new memory block had to be allocated from the system. + */ size_t misses; + + /** + * Total number of memory blocks currently cached. + */ size_t blocks; + + /** + * Total bytes currently cached. + */ size_t bytes; + + /** + * High water mark for total cached bytes. + */ size_t highBytes; }; + /** + * @brief Returns the current statistical information for all caches. + */ Statistics getStatistics(); private: + /// @cond IMPL + + // BufferManager is a singleton object. This method is inaccessible to + // user code. + BufferManager(); + + // BufferManager is a singleton whose lifetime is managed by the + // library. This method is inaccessible to user code. + ~BufferManager(); + + // Non-copyable BufferManager(const BufferManager&); + + // Non-assignable BufferManager& operator=(const BufferManager&); class CacheBlock; @@ -136,34 +275,58 @@ namespace redhawk { class BufferCache; friend class BufferCache; + // Round up the given allocation size to the nearest granularity, + // taking the CacheBlock overhead into consideration size_t _nearestSize(size_t bytes); + + // Acquire a new memory block from the operating system CacheBlock* _allocate(size_t bytes); + + // Return an existing memory block to the operating system void _deallocate(CacheBlock* ptr); + // Associate a new thread's buffer cache with the BufferManager void _addCache(BufferCache* cache); + + // Remove an existing buffer cache from the BufferManager void _removeCache(BufferCache* cache); + + // Returns the buffer cache for the current thread BufferCache* _getCache(); + // Report an increase in the total cached bytes (also updates high + // water mark if necessary) void _increaseSize(size_t bytes); + + // Report a decrease in the total cached bytes void _decreaseSize(size_t bytes); - typedef std::set CacheList; + // Lock protecting the cache list boost::mutex _lock; + typedef std::set CacheList; CacheList _caches; + + // Per-thread association of buffer cache boost::thread_specific_ptr _threadCache; + // Policy settings bool _enabled; size_t _maxThreadBytes; size_t _maxThreadBlocks; size_t _maxThreadAge; + // Statistical data size_t _hits; size_t _misses; + // Total size tracking; must be updated atomically volatile size_t _currentBytes; volatile size_t _highWaterBytes; + // Singleton instance static BufferManager _instance; + + /// @endcond }; From f12efc109a04d8e6e31e5f424ec0d2f9ae6ed8d6 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 18 Jan 2017 09:58:29 -0500 Subject: [PATCH 0652/1644] Conditionally skip new tests that require Java --- redhawk/src/testing/tests/test_08_Messaging.py | 2 ++ redhawk/src/testing/tests/test_11_AllPropTypes.py | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/redhawk/src/testing/tests/test_08_Messaging.py b/redhawk/src/testing/tests/test_08_Messaging.py index eb8b5e080..e7d773c76 100644 --- a/redhawk/src/testing/tests/test_08_Messaging.py +++ b/redhawk/src/testing/tests/test_08_Messaging.py @@ -156,6 +156,7 @@ def test_MessagingCpp(self): self.assertEquals(self.rcv_msg.c, 'C') self.rcv_msg = None + @scatest.requireJava def test_MessagingJava(self): src=sb.MessageSource('foo') c=sb.launch('msg_through_java') @@ -243,6 +244,7 @@ def test_MessageCyclePython(self): comp = sb.launch('MessageReceiverPy') self.__MessageCycle(comp) + @scatest.requireJava def test_MessageCycleJava(self): comp = sb.launch('EventReceive') self.__MessageCycle(comp) diff --git a/redhawk/src/testing/tests/test_11_AllPropTypes.py b/redhawk/src/testing/tests/test_11_AllPropTypes.py index 3c74ba26e..b4175a349 100644 --- a/redhawk/src/testing/tests/test_11_AllPropTypes.py +++ b/redhawk/src/testing/tests/test_11_AllPropTypes.py @@ -92,7 +92,8 @@ def test_getTimeCpp(self): def test_getTimePython(self): self.basetest_getTime('timeprop_py') - + + @scatest.requireJava def test_getTimeJava(self): self.basetest_getTime('timeprop_java') From b496d4f877cbed64d66421ba7e7bb1a344b2d14b Mon Sep 17 00:00:00 2001 From: 8530 <8530@vm-131.vsi-corp.com> Date: Wed, 18 Jan 2017 11:40:44 -0500 Subject: [PATCH 0653/1644] fixes for broken presistence unit tests --- .../ossie/DeviceManagerConfiguration.h | 2 + .../parser/DeviceManagerConfiguration.cpp | 4 ++ .../sdr/dommgr/AllocationManager_impl.cpp | 2 +- .../control/sdr/dommgr/DomainManager_impl.cpp | 62 ++++++++++++++----- .../testing/tests/test_08_SADProperties.py | 2 +- .../testing/tests/test_11_JavaProperties.py | 2 +- redhawk/src/xml/dtd/softwareassembly.dtd | 5 +- 7 files changed, 59 insertions(+), 20 deletions(-) diff --git a/redhawk/src/control/include/ossie/DeviceManagerConfiguration.h b/redhawk/src/control/include/ossie/DeviceManagerConfiguration.h index 76ab97f1b..72283803d 100644 --- a/redhawk/src/control/include/ossie/DeviceManagerConfiguration.h +++ b/redhawk/src/control/include/ossie/DeviceManagerConfiguration.h @@ -97,6 +97,8 @@ namespace ossie { public: void load(std::istream& input) throw (ossie::parser_error); + const bool isLoaded() const; + const char* getID() const; const char* getName() const; diff --git a/redhawk/src/control/parser/DeviceManagerConfiguration.cpp b/redhawk/src/control/parser/DeviceManagerConfiguration.cpp index cae5b2459..2247d627c 100644 --- a/redhawk/src/control/parser/DeviceManagerConfiguration.cpp +++ b/redhawk/src/control/parser/DeviceManagerConfiguration.cpp @@ -35,6 +35,10 @@ void DeviceManagerConfiguration::load(std::istream& input) throw (ossie::parser_ _dcd = ossie::internalparser::parseDCD(input); } +const bool DeviceManagerConfiguration::isLoaded() const { + return _dcd.get() != 0; +} + const char* DeviceManagerConfiguration::getID() const { assert(_dcd.get() != 0); return _dcd->id.c_str(); diff --git a/redhawk/src/control/sdr/dommgr/AllocationManager_impl.cpp b/redhawk/src/control/sdr/dommgr/AllocationManager_impl.cpp index 611afcca9..6a371a833 100644 --- a/redhawk/src/control/sdr/dommgr/AllocationManager_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/AllocationManager_impl.cpp @@ -328,7 +328,7 @@ bool AllocationManager_impl::allocateDevice(const CF::Properties& requestedPrope return false; } - LOG_INFO(AllocationManager_impl, "allocateDevice::PartitionMatching " << node.requiresProps ); + LOG_DEBUG(AllocationManager_impl, "allocateDevice::PartitionMatching " << node.requiresProps ); if ( !checkPartitionMatching( node, devicerequires )) { LOG_TRACE(AllocationManager_impl, "Partition Matching failed"); return false; diff --git a/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp b/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp index ad725a95b..346181723 100644 --- a/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp @@ -1039,16 +1039,20 @@ void DomainManager_impl::_local_registerDeviceManager (CF::DeviceManager_ptr dev try { CF::FileSystem_var devMgrFileSys = deviceMgr->fileSys(); CORBA::String_var profile = deviceMgr->deviceConfigurationProfile(); - File_stream dcd(devMgrFileSys, profile); if ( node != _registeredDeviceManagers.end() ) { - node->dcd.load(dcd); + if ( node->dcd.isLoaded() == false ) { + File_stream dcd(devMgrFileSys, profile); + node->dcd.load(dcd); + dcd.close(); + } dcdParser = &(node->dcd); } else { + File_stream dcd(devMgrFileSys, profile); _dcdParser.load(dcd); dcdParser = &_dcdParser; + dcd.close(); } - dcd.close(); } catch ( ossie::parser_error& e ) { std::string parser_error_line = ossie::retrieveParserErrorLineNumber(e.what()); LOG_ERROR(DomainManager_impl, "Failed device manager registration; error parsing device manager DCD: " << deviceMgr->deviceConfigurationProfile() << ". " << parser_error_line << " The XML parser returned the following error: " << e.what()) @@ -1105,6 +1109,16 @@ DomainManager_impl::addDeviceMgr (CF::DeviceManager_ptr deviceMgr) tmp_devMgr.deviceManager = CF::DeviceManager::_duplicate(deviceMgr); tmp_devMgr.identifier = static_cast(identifier); tmp_devMgr.label = static_cast(label); + try{ + // preload DCD + CF::FileSystem_var devMgrFileSys = tmp_devMgr.deviceManager->fileSys(); + CORBA::String_var profile = tmp_devMgr.deviceManager->deviceConfigurationProfile(); + File_stream dcd(devMgrFileSys, profile); + tmp_devMgr.dcd.load(dcd); + dcd.close(); + } + catch(...){ + } _registeredDeviceManagers.push_back(tmp_devMgr); try { @@ -2002,21 +2016,34 @@ void DomainManager_impl::_local_registerService (CORBA::Object_ptr registeringSe throw CF::DomainManager::DeviceManagerNotRegistered(); } - DeviceManagerConfiguration _DCDParser; + DeviceManagerConfiguration *_DCDParser=0; + DeviceManagerConfiguration _dcdParser; bool readDCD = true; std::string serviceId(""); std::string inputUsageName(name); try { CF::FileSystem_var devMgrFileSys = registeredDeviceMgr->fileSys(); CORBA::String_var profile = registeredDeviceMgr->deviceConfigurationProfile(); - File_stream _dcd(devMgrFileSys, profile); - _DCDParser.load(_dcd); - _dcd.close(); + DeviceManagerList::iterator node = findDeviceManagerByObject(registeredDeviceMgr); + if ( node != _registeredDeviceManagers.end() ) { + if ( node->dcd.isLoaded() == false ) { + File_stream dcd(devMgrFileSys, profile); + node->dcd.load(dcd); + dcd.close(); + } + _DCDParser = &(node->dcd); + } + else { + File_stream dcd(devMgrFileSys, profile); + _dcdParser.load(dcd); + _DCDParser = &_dcdParser; + dcd.close(); + } } catch ( ... ) { readDCD = false; } if (readDCD) { - const std::vector& componentPlacements = _DCDParser.getComponentPlacements(); + const std::vector& componentPlacements = _DCDParser->getComponentPlacements(); bool foundId = false; for (unsigned int i = 0; i < componentPlacements.size(); i++) { for (unsigned int j=0; jdeviceConfigurationProfile()); - const ComponentInstantiation* instantiation = findComponentInstantiation(node.devMgr.dcd.getComponentPlacements(), node.identifier); - if (instantiation) { - node.prf.override(instantiation->properties); - ossie::convertComponentProperties( instantiation->getDeployerRequires(), - node.requiresProps ); - } else { - LOG_WARN(DomainManager_impl, "Unable to find device " << node.identifier << " in DCD"); + if ( node.devMgr.dcd.isLoaded() == false ) { + LOG_WARN(DomainManager_impl, "DCD file was not loaded for node: " << node.identifier ); + } + else { + const ComponentInstantiation* instantiation = findComponentInstantiation(node.devMgr.dcd.getComponentPlacements(), node.identifier); + if (instantiation) { + node.prf.override(instantiation->properties); + ossie::convertComponentProperties( instantiation->getDeployerRequires(), + node.requiresProps ); + } else { + LOG_WARN(DomainManager_impl, "Unable to find device " << node.identifier << " in DCD"); + } } } diff --git a/redhawk/src/testing/tests/test_08_SADProperties.py b/redhawk/src/testing/tests/test_08_SADProperties.py index a899e3414..263f8d74b 100644 --- a/redhawk/src/testing/tests/test_08_SADProperties.py +++ b/redhawk/src/testing/tests/test_08_SADProperties.py @@ -98,7 +98,7 @@ def test_ExternalProps(self): to_find = 2 if java_support: props.append(javaProp) - number_props = 7 + number_props = 10 to_find = 3 self._app.configure(props) # Make sure all were set diff --git a/redhawk/src/testing/tests/test_11_JavaProperties.py b/redhawk/src/testing/tests/test_11_JavaProperties.py index e44ece1ab..594359bea 100644 --- a/redhawk/src/testing/tests/test_11_JavaProperties.py +++ b/redhawk/src/testing/tests/test_11_JavaProperties.py @@ -40,7 +40,7 @@ def tearDown(self): def test_EmptyQuery (self): results = self.comp.query([]) - self.assertEqual(len(results), 6) + self.assertEqual(len(results), 9) ids = set(r.id for r in results) expected = ("ulong_prop", diff --git a/redhawk/src/xml/dtd/softwareassembly.dtd b/redhawk/src/xml/dtd/softwareassembly.dtd index fc9a13750..5adbfd422 100644 --- a/redhawk/src/xml/dtd/softwareassembly.dtd +++ b/redhawk/src/xml/dtd/softwareassembly.dtd @@ -191,9 +191,10 @@ with this program. If not, see http://www.gnu.org/licenses/. name CDATA #IMPLIED> + From abfc9e761d370a85ea0e3c839ca8bc12f8445957 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 18 Jan 2017 14:01:21 -0500 Subject: [PATCH 0654/1644] RELENG-542 Provide XML output from C++ unit tests for integration into Jenkins --- redhawk/src/testing/cpp/Makefile.am | 7 +--- redhawk/src/testing/cpp/test_libossiecf.cpp | 29 +++++++++---- redhawk/src/testing/cpp/test_standalone.cpp | 42 ------------------- .../CommandWrapperEmptyDir/Makefile | 1 + 4 files changed, 24 insertions(+), 55 deletions(-) delete mode 100644 redhawk/src/testing/cpp/test_standalone.cpp diff --git a/redhawk/src/testing/cpp/Makefile.am b/redhawk/src/testing/cpp/Makefile.am index 09eb3c542..d7f36a450 100644 --- a/redhawk/src/testing/cpp/Makefile.am +++ b/redhawk/src/testing/cpp/Makefile.am @@ -1,14 +1,11 @@ -TESTS = test_standalone test_libossiecf +TESTS = test_libossiecf AM_CPPFLAGS = -Wall check_PROGRAMS = $(TESTS) -test_standalone_SOURCES = test_standalone.cpp SharedBufferTest.cpp SharedBufferTest.h -test_standalone_CXXFLAGS = $(CPPUNIT_CFLAGS) -I $(top_srcdir)/base/include -test_standalone_LDFLAGS = $(CPPUNIT_LIBS) - test_libossiecf_SOURCES = test_libossiecf.cpp +test_libossiecf_SOURCES += SharedBufferTest.cpp SharedBufferTest.h test_libossiecf_SOURCES += AnyUtilsTest.cpp AnyUtilsTest.h test_libossiecf_SOURCES += ValueTest.cpp ValueTest.h test_libossiecf_SOURCES += ValueSequenceTest.cpp ValueSequenceTest.h diff --git a/redhawk/src/testing/cpp/test_libossiecf.cpp b/redhawk/src/testing/cpp/test_libossiecf.cpp index acff55a93..598539024 100644 --- a/redhawk/src/testing/cpp/test_libossiecf.cpp +++ b/redhawk/src/testing/cpp/test_libossiecf.cpp @@ -19,7 +19,10 @@ */ #include +#include #include +#include +#include #include #include @@ -33,15 +36,25 @@ int main(int argc, char* argv[]) // Get the top level suite from the registry CppUnit::Test* suite = CppUnit::TestFactoryRegistry::getRegistry().makeTest(); - // Adds the test to the list of test to run + // Create the event manager and test controller + CppUnit::TestResult controller; + + // Add a listener that collects test result + CppUnit::TestResultCollector result; + controller.addListener(&result); + + // Create XML and stderr output + std::ofstream xmlout("../cppunit-results.xml"); + CppUnit::XmlOutputter xmlOutputter(&result, xmlout); + CppUnit::CompilerOutputter compilerOutputter(&result, std::cerr); + + // Run the tests CppUnit::TextUi::TestRunner runner; runner.addTest(suite); + runner.run(controller); + xmlOutputter.write(); + compilerOutputter.write(); - // Change the default outputter to a compiler error format outputter - runner.setOutputter(new CppUnit::CompilerOutputter(&runner.result(), std::cerr)); - // Run the tests. - bool wasSucessful = runner.run(); - - // Return error code 1 if the one of test failed. - return wasSucessful ? 0 : 1; + // Return error code 1 if any of the tests failed + return result.wasSuccessful() ? 0 : 1; } diff --git a/redhawk/src/testing/cpp/test_standalone.cpp b/redhawk/src/testing/cpp/test_standalone.cpp deleted file mode 100644 index bb3ead102..000000000 --- a/redhawk/src/testing/cpp/test_standalone.cpp +++ /dev/null @@ -1,42 +0,0 @@ -/* - * This file is protected by Copyright. Please refer to the COPYRIGHT file - * distributed with this source distribution. - * - * This file is part of REDHAWK core. - * - * REDHAWK core is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see http://www.gnu.org/licenses/. - */ - -#include -#include -#include - - -int main(int argc, char* argv[]) -{ - // Get the top level suite from the registry - CppUnit::Test* suite = CppUnit::TestFactoryRegistry::getRegistry().makeTest(); - - // Adds the test to the list of test to run - CppUnit::TextUi::TestRunner runner; - runner.addTest(suite); - - // Change the default outputter to a compiler error format outputter - runner.setOutputter(new CppUnit::CompilerOutputter(&runner.result(), std::cerr)); - // Run the tests. - bool wasSucessful = runner.run(); - - // Return error code 1 if the one of test failed. - return wasSucessful ? 0 : 1; -} diff --git a/redhawk/src/testing/sdr/dom/components/CommandWrapperEmptyDir/Makefile b/redhawk/src/testing/sdr/dom/components/CommandWrapperEmptyDir/Makefile index af9470e97..2f6fe40f3 100644 --- a/redhawk/src/testing/sdr/dom/components/CommandWrapperEmptyDir/Makefile +++ b/redhawk/src/testing/sdr/dom/components/CommandWrapperEmptyDir/Makefile @@ -14,3 +14,4 @@ distclean: clean: +check: From 9a68598b411631d06ef44f5c0a55183775575cf4 Mon Sep 17 00:00:00 2001 From: 8530 <8530@vm-131.vsi-corp.com> Date: Thu, 19 Jan 2017 10:24:02 -0500 Subject: [PATCH 0655/1644] resolve issue for failed unit tests, fixed deployments for usesdevice with math operations --- .../control/include/ossie/SoftwareAssembly.h | 2 ++ .../src/control/parser/SoftwareAssembly.cpp | 16 +++++++++++ .../sdr/dommgr/ApplicationDeployment.cpp | 11 +++++++- .../sdr/dommgr/ApplicationDeployment.h | 1 + .../sdr/dommgr/ApplicationFactory_impl.cpp | 27 ++++++++++++++++--- redhawk/src/control/sdr/dommgr/createHelper.h | 1 + 6 files changed, 54 insertions(+), 4 deletions(-) diff --git a/redhawk/src/control/include/ossie/SoftwareAssembly.h b/redhawk/src/control/include/ossie/SoftwareAssembly.h index a0fed6bb6..c7404c80e 100644 --- a/redhawk/src/control/include/ossie/SoftwareAssembly.h +++ b/redhawk/src/control/include/ossie/SoftwareAssembly.h @@ -142,6 +142,8 @@ namespace ossie { const std::string& getAssemblyControllerRefId() const; + const ComponentPlacement* getAssemblyControllerPlacement() const; + const std::vector& getExternalPorts() const; const std::vector& getExternalProperties() const; diff --git a/redhawk/src/control/parser/SoftwareAssembly.cpp b/redhawk/src/control/parser/SoftwareAssembly.cpp index 410157c4a..e4f18adb6 100644 --- a/redhawk/src/control/parser/SoftwareAssembly.cpp +++ b/redhawk/src/control/parser/SoftwareAssembly.cpp @@ -184,6 +184,22 @@ const std::vector& SoftwareAssembly::getUsesDevices() const { return _sad->usesdevice; } +const ComponentPlacement * SoftwareAssembly::getAssemblyControllerPlacement() const +{ + BOOST_FOREACH(const ComponentPlacement& placement, _sad->partitioning.placements) { + const ComponentInstantiation* instantiation = placement.getInstantiation(_sad->assemblycontroller); + if (instantiation) return &(placement); + } + + BOOST_FOREACH(HostCollocation& collocation, _sad->partitioning.collocations) { + BOOST_FOREACH(const ComponentPlacement& placement, collocation.getComponents()) { + const ComponentInstantiation* instantiation = placement.getInstantiation(_sad->assemblycontroller); + if (instantiation) return &(placement); + } + } + return NULL; +} + const ComponentInstantiation* SoftwareAssembly::getComponentInstantiation(const std::string& refid) const { BOOST_FOREACH(HostCollocation& collocation, _sad->partitioning.collocations) { diff --git a/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp b/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp index addc50b81..46074792a 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp @@ -51,12 +51,14 @@ ApplicationDeployment::ApplicationDeployment(const SoftwareAssembly& sad, // (e.g. "Application_1"). identifier(sad.getID() + ":" + instanceName), instanceName(instanceName), - initConfiguration(initConfiguration) + initConfiguration(initConfiguration), + ac(0) { } ApplicationDeployment::~ApplicationDeployment() { + ac=NULL; BOOST_FOREACH(ComponentDeployment* component, components) { delete component; } @@ -65,6 +67,7 @@ ApplicationDeployment::~ApplicationDeployment() } } + const std::string& ApplicationDeployment::getIdentifier() const { return identifier; @@ -104,11 +107,17 @@ ComponentDeployment* ApplicationDeployment::createComponentDeployment(const Soft << softpkg->getName() << " is SCA-compliant"); } + if ( (instantiation->getID() == sad.getAssemblyControllerRefId() ) && ac ) { + LOG_TRACE(ApplicationDeployment, " Requesting AssemblyController " << instantiation->getID() ); + return ac; + } + ComponentDeployment* deployment = new ComponentDeployment(softpkg, instantiation, component_id); components.push_back(deployment); // Override properties from initial configuration if (instantiation->getID() == sad.getAssemblyControllerRefId()) { + ac = deployment; deployment->setIsAssemblyController(true); overrideAssemblyControllerProperties(deployment); } else { diff --git a/redhawk/src/control/sdr/dommgr/ApplicationDeployment.h b/redhawk/src/control/sdr/dommgr/ApplicationDeployment.h index 92bf20c72..d9734e4e2 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationDeployment.h +++ b/redhawk/src/control/sdr/dommgr/ApplicationDeployment.h @@ -109,6 +109,7 @@ namespace redhawk { redhawk::PropertyMap initConfiguration; ComponentList components; ContainerList containers; + ComponentDeployment *ac; }; } diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index b2054d0e6..9ce04a26b 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -860,9 +860,11 @@ CF::Application_ptr createHelper::create ( // Catch invalid device assignments _validateDAS(app_deployment, deviceAssignments); - // Allocate any usesdevice capacities specified in the SAD file; at this - // point, the complete set of component deployments is known, including any - // property overrides for allocation context + // resolve assembly controller to assist with usesdevices that + // require matching properties + _resolveAssemblyController(app_deployment); + + // Allocate any usesdevice capacities specified in the SAD file _handleUsesDevices(app_deployment, name); // Assign all components to devices @@ -998,6 +1000,25 @@ CF::Application_ptr createHelper::create ( return appObj._retn(); } + +void createHelper::_resolveAssemblyController( redhawk::ApplicationDeployment& appDeployment ) { + + // Place the remaining components one-by-one + std::string asm_refid = _appFact._sadParser.getAssemblyControllerRefId(); + const ComponentPlacement *asm_placement = _appFact._sadParser.getAssemblyControllerPlacement(); + if ( asm_placement && asm_refid != "" and asm_refid.size() > 0 ) { + const SoftPkg* softpkg = _profileCache.loadProfile(asm_placement->filename); + const ComponentInstantiation *asm_inst = asm_placement->getInstantiation(asm_refid); + if ( asm_inst ) { + std::string inst_id = asm_inst->getID(); + LOG_DEBUG(ApplicationFactory_impl, "Resolved ASSEMBLY CONTROLLER: " << asm_refid ); + redhawk::ComponentDeployment *cp __attribute__((unused)); + cp = appDeployment.createComponentDeployment(softpkg, asm_inst); + return; + } + } +} + CF::AllocationManager::AllocationResponseSequence* createHelper::allocateUsesDeviceProperties(const std::vector& usesDevices, const CF::Properties& configureProperties) { CF::AllocationManager::AllocationRequestSequence request; diff --git a/redhawk/src/control/sdr/dommgr/createHelper.h b/redhawk/src/control/sdr/dommgr/createHelper.h index eeee8eb68..a32a45854 100644 --- a/redhawk/src/control/sdr/dommgr/createHelper.h +++ b/redhawk/src/control/sdr/dommgr/createHelper.h @@ -104,6 +104,7 @@ class createHelper // createHelper helper methods void assignPlacementsToDevices(redhawk::ApplicationDeployment& appDeployment, const DeviceAssignmentMap& devices); + void _resolveAssemblyController(redhawk::ApplicationDeployment& appDeployment); void _validateDAS(redhawk::ApplicationDeployment& appDeployment, const DeviceAssignmentMap& deviceAssignments); void setUpExternalPorts(redhawk::ApplicationDeployment& appDeployment, Application_impl* application); void setUpExternalProperties(redhawk::ApplicationDeployment& appDeployment, Application_impl* application); From 1985ca9cae08c923758ad22e6c485823e903d3cc Mon Sep 17 00:00:00 2001 From: Max Robert Date: Thu, 19 Jan 2017 12:32:54 -0500 Subject: [PATCH 0656/1644] Refs CF-1594. Deprecated interactive mode for components, devices, and services --- redhawk/src/base/framework/Device_impl.cpp | 7 ++ redhawk/src/base/framework/Resource_impl.cpp | 6 ++ .../ossie/src/org/ossie/component/Device.java | 7 ++ .../src/org/ossie/component/Resource.java | 6 ++ .../src/org/ossie/component/Service.java | 7 ++ .../src/base/framework/python/ossie/device.py | 5 + .../base/framework/python/ossie/resource.py | 3 + .../base/framework/python/ossie/service.py | 4 + redhawk/src/base/include/ossie/Service_impl.h | 6 ++ redhawk/src/configure.ac | 1 + redhawk/src/testing/Makefile.am | 1 + .../BasicTestDevice_java/java/startJava.sh | 2 +- .../BasicService_cpp/BasicService_cpp.scd.xml | 18 ++++ .../BasicService_cpp/BasicService_cpp.spd.xml | 24 +++++ .../BasicService_cpp/cpp/BasicService_cpp.cpp | 102 ++++++++++++++++++ .../BasicService_cpp/cpp/BasicService_cpp.h | 29 +++++ .../cpp/BasicService_cpp_base.cpp | 34 ++++++ .../cpp/BasicService_cpp_base.h | 18 ++++ .../services/BasicService_cpp/cpp/Makefile.am | 31 ++++++ .../services/BasicService_cpp/cpp/main.cpp | 26 +++++ redhawk/src/testing/tests/test_13_TestSB.py | 66 ++++++++++++ 21 files changed, 402 insertions(+), 1 deletion(-) create mode 100644 redhawk/src/testing/sdr/dev/services/BasicService_cpp/BasicService_cpp.scd.xml create mode 100644 redhawk/src/testing/sdr/dev/services/BasicService_cpp/BasicService_cpp.spd.xml create mode 100644 redhawk/src/testing/sdr/dev/services/BasicService_cpp/cpp/BasicService_cpp.cpp create mode 100644 redhawk/src/testing/sdr/dev/services/BasicService_cpp/cpp/BasicService_cpp.h create mode 100644 redhawk/src/testing/sdr/dev/services/BasicService_cpp/cpp/BasicService_cpp_base.cpp create mode 100644 redhawk/src/testing/sdr/dev/services/BasicService_cpp/cpp/BasicService_cpp_base.h create mode 100644 redhawk/src/testing/sdr/dev/services/BasicService_cpp/cpp/Makefile.am create mode 100644 redhawk/src/testing/sdr/dev/services/BasicService_cpp/cpp/main.cpp diff --git a/redhawk/src/base/framework/Device_impl.cpp b/redhawk/src/base/framework/Device_impl.cpp index 1cd9900fa..8456a997c 100644 --- a/redhawk/src/base/framework/Device_impl.cpp +++ b/redhawk/src/base/framework/Device_impl.cpp @@ -1024,6 +1024,13 @@ void Device_impl::start_device(Device_impl::ctor_type ctor, struct sigaction sa, bool skip_run = false; bool enablesigfd=false; + for (int index = 1; index < argc; ++index) { + if (std::string(argv[index]) == std::string("-i")) { + std::cout<<"Interactive mode (-i) no longer supported. Please use the sandbox to run Components/Devices/Services outside the scope of a Domain"< execparams; for (int i = 0; i < argc; i++) { diff --git a/redhawk/src/base/framework/Resource_impl.cpp b/redhawk/src/base/framework/Resource_impl.cpp index c51963903..f7866a64d 100644 --- a/redhawk/src/base/framework/Resource_impl.cpp +++ b/redhawk/src/base/framework/Resource_impl.cpp @@ -285,6 +285,12 @@ static void sigint_handler(int signum) void Resource_impl::start_component(Resource_impl::ctor_type ctor, int argc, char* argv[]) { + for (int index = 1; index < argc; ++index) { + if (std::string(argv[index]) == std::string("-i")) { + std::cout<<"Interactive mode (-i) no longer supported. Please use the sandbox to run Components/Devices/Services outside the scope of a Domain"< clazz, final Stri final POA rootpoa = org.ossie.corba.utils.RootPOA(); + if (args.length == 1) { + if (args[0].equals("-i")) { + System.out.println("Interactive mode (-i) no longer supported. Please use the sandbox to run Components/Devices/Services outside the scope of a Domain"); + System.exit(-1); + } + } + Map execparams = parseArgs(args); DeviceManager devMgr = null; diff --git a/redhawk/src/base/framework/java/ossie/src/org/ossie/component/Resource.java b/redhawk/src/base/framework/java/ossie/src/org/ossie/component/Resource.java index 4c8e82c6a..5dbff6955 100644 --- a/redhawk/src/base/framework/java/ossie/src/org/ossie/component/Resource.java +++ b/redhawk/src/base/framework/java/ossie/src/org/ossie/component/Resource.java @@ -1164,6 +1164,12 @@ public static void start_component(final Class clazz, final public static void start_component(final Class clazz, final String[] args, final Properties props) throws InstantiationException, IllegalAccessException, InvalidObjectReference, NotFound, CannotProceed, org.omg.CosNaming.NamingContextPackage.InvalidName, ServantNotActive, WrongPolicy { + if (args.length == 1) { + if (args[0].equals("-i")) { + System.out.println("Interactive mode (-i) no longer supported. Please use the sandbox to run Components/Devices/Services outside the scope of a Domain"); + System.exit(-1); + } + } // initialize library's ORB reference final org.omg.CORBA.ORB orb = org.ossie.corba.utils.Init( args, props ); diff --git a/redhawk/src/base/framework/java/ossie/src/org/ossie/component/Service.java b/redhawk/src/base/framework/java/ossie/src/org/ossie/component/Service.java index e9e50036e..969497a57 100644 --- a/redhawk/src/base/framework/java/ossie/src/org/ossie/component/Service.java +++ b/redhawk/src/base/framework/java/ossie/src/org/ossie/component/Service.java @@ -204,6 +204,13 @@ public static void start_service(final Class clazz, final Str final POA rootpoa = org.ossie.corba.utils.RootPOA(); + if (args.length == 1) { + if (args[0].equals("-i")) { + System.out.println("Interactive mode (-i) no longer supported. Please use the sandbox to run Components/Devices/Services outside the scope of a Domain"); + System.exit(-1); + } + } + Map execparams = parseArgs(args); DeviceManager deviceMgr = null; diff --git a/redhawk/src/base/framework/python/ossie/device.py b/redhawk/src/base/framework/python/ossie/device.py index f9b8ba164..39a4e2a0f 100644 --- a/redhawk/src/base/framework/python/ossie/device.py +++ b/redhawk/src/base/framework/python/ossie/device.py @@ -1328,6 +1328,11 @@ def start_device(deviceclass, interactive_callback=None, thread_policy=None,logg start_device(MyDeviceImpl) """ execparams, interactive = resource.parseCommandLineArgs(deviceclass) + + if interactive: + print "Interactive mode (-i) no longer supported. Please use the sandbox to run Components/Devices/Services outside the scope of a Domain" + sys.exit(-1) + if not skip_run: resource.setupSignalHandlers() signal.signal(signal.SIGINT, signal.SIG_IGN) diff --git a/redhawk/src/base/framework/python/ossie/resource.py b/redhawk/src/base/framework/python/ossie/resource.py index c82433d22..ee4a34e42 100644 --- a/redhawk/src/base/framework/python/ossie/resource.py +++ b/redhawk/src/base/framework/python/ossie/resource.py @@ -1230,6 +1230,9 @@ def parseCommandLineArgs(componentclass): def start_component(componentclass, interactive_callback=None, thread_policy=None, loggerName=None): execparams, interactive = parseCommandLineArgs(componentclass) + if interactive: + print "Interactive mode (-i) no longer supported. Please use the sandbox to run Components/Devices/Services outside the scope of a Domain" + sys.exit(-1) name_binding="NOT SET" setupSignalHandlers() orb = None diff --git a/redhawk/src/base/framework/python/ossie/service.py b/redhawk/src/base/framework/python/ossie/service.py index a71377e82..a7d0519c6 100644 --- a/redhawk/src/base/framework/python/ossie/service.py +++ b/redhawk/src/base/framework/python/ossie/service.py @@ -163,6 +163,10 @@ def start_service(serviceclass, thread_policy=None): import signal import getopt + if len(sys.argv) == 2: + if sys.argv[1] == '-i': + print "Interactive mode (-i) no longer supported. Please use the sandbox to run Components/Devices/Services outside the scope of a Domain" + sys.exit(-1) try: # IMPORTANT YOU CANNOT USE gnu_getopt OR OptionParser # because they will treat execparams with negative number diff --git a/redhawk/src/base/include/ossie/Service_impl.h b/redhawk/src/base/include/ossie/Service_impl.h index c3a8af713..f53452a41 100644 --- a/redhawk/src/base/include/ossie/Service_impl.h +++ b/redhawk/src/base/include/ossie/Service_impl.h @@ -52,6 +52,12 @@ class Service_impl std::string dpath(""); std::string sname(""); + for (int index = 1; index < argc; ++index) { + if (std::string(argv[index]) == std::string("-i")) { + std::cout<<"Interactive mode (-i) no longer supported. Please use the sandbox to run Components/Devices/Services outside the scope of a Domain"< execparams; for (int i = 0; i < argc; i++) { diff --git a/redhawk/src/configure.ac b/redhawk/src/configure.ac index 2412121b6..24972fc2e 100644 --- a/redhawk/src/configure.ac +++ b/redhawk/src/configure.ac @@ -343,6 +343,7 @@ AC_CONFIG_FILES(Makefile \ testing/sdr/dev/devices/java_dev/java/Makefile \ testing/sdr/dev/devices/LongDevice/cpp/Makefile \ testing/sdr/dev/services/BasicService_java/java/Makefile \ + testing/sdr/dev/services/BasicService_cpp/cpp/Makefile \ testing/sdr/dom/deps/cpp_dep1/cpp/Makefile \ testing/sdr/dom/deps/cpp_dep1/cpp/cpp_dep1.pc \ testing/sdr/dom/deps/cpp_dep2/cpp/Makefile \ diff --git a/redhawk/src/testing/Makefile.am b/redhawk/src/testing/Makefile.am index ebe44c6a2..041317fdd 100644 --- a/redhawk/src/testing/Makefile.am +++ b/redhawk/src/testing/Makefile.am @@ -40,6 +40,7 @@ SUBDIRS = sdr/dev/devices/ExecutableDevice \ sdr/dev/devices/GPP/cpp \ sdr/dev/devices/java_dev/java \ sdr/dev/devices/LongDevice/cpp \ + sdr/dev/services/BasicService_cpp/cpp \ sdr/dom/deps/cpp_dep1/cpp \ sdr/dom/deps/cpp_dep2/cpp \ sdr/dom/components/TestCppProps \ diff --git a/redhawk/src/testing/sdr/dev/devices/BasicTestDevice_java/java/startJava.sh b/redhawk/src/testing/sdr/dev/devices/BasicTestDevice_java/java/startJava.sh index 4ace76682..16d3e1b2f 100755 --- a/redhawk/src/testing/sdr/dev/devices/BasicTestDevice_java/java/startJava.sh +++ b/redhawk/src/testing/sdr/dev/devices/BasicTestDevice_java/java/startJava.sh @@ -22,7 +22,7 @@ myDir=`dirname $0` # Setup the OSSIEHOME Lib jars on the classpath -libDir=../../../../../base/framework/java +libDir=${SDRROOT}/../../base/framework/java libFiles=`ls -1 $libDir/*.jar` for file in $libFiles do diff --git a/redhawk/src/testing/sdr/dev/services/BasicService_cpp/BasicService_cpp.scd.xml b/redhawk/src/testing/sdr/dev/services/BasicService_cpp/BasicService_cpp.scd.xml new file mode 100644 index 000000000..f18f8f6b3 --- /dev/null +++ b/redhawk/src/testing/sdr/dev/services/BasicService_cpp/BasicService_cpp.scd.xml @@ -0,0 +1,18 @@ + + + + 2.2 + + service + + + + + + + + + + + + diff --git a/redhawk/src/testing/sdr/dev/services/BasicService_cpp/BasicService_cpp.spd.xml b/redhawk/src/testing/sdr/dev/services/BasicService_cpp/BasicService_cpp.spd.xml new file mode 100644 index 000000000..e4a0c7232 --- /dev/null +++ b/redhawk/src/testing/sdr/dev/services/BasicService_cpp/BasicService_cpp.spd.xml @@ -0,0 +1,24 @@ + + + + + + null + + + + + + The implementation contains descriptive information about the template for a software resource. + + + cpp/BasicService_cpp + + + + + + + + + diff --git a/redhawk/src/testing/sdr/dev/services/BasicService_cpp/cpp/BasicService_cpp.cpp b/redhawk/src/testing/sdr/dev/services/BasicService_cpp/cpp/BasicService_cpp.cpp new file mode 100644 index 000000000..8e0a7b6de --- /dev/null +++ b/redhawk/src/testing/sdr/dev/services/BasicService_cpp/cpp/BasicService_cpp.cpp @@ -0,0 +1,102 @@ +/************************************************************************** + + This is the service code. This file contains the child class where + custom functionality can be added to the service. Custom + functionality to the base class can be extended here. Access to + the ports can also be done from this class + +**************************************************************************/ + +#include "BasicService_cpp.h" + +PREPARE_LOGGING(BasicService_cpp_i) +BasicService_cpp_i::BasicService_cpp_i(char *devMgr_ior, char *name) : + BasicService_cpp_base(devMgr_ior, name) +{ +} + +BasicService_cpp_i::~BasicService_cpp_i() +{ +} + +void BasicService_cpp_i::remove(const char* fileName) +{ + // TODO: Fill in this function +} + +void BasicService_cpp_i::copy(const char* sourceFileName, const char* destinationFileName) +{ + // TODO: Fill in this function +} + +void BasicService_cpp_i::move(const char* sourceFileName, const char* destinationFileName) +{ + // TODO: Fill in this function +} + +CORBA::Boolean BasicService_cpp_i::exists(const char* fileName) +{ + CORBA::Boolean tmpVal; + // TODO: Fill in this function + + return tmpVal; +} + +CF::FileSystem::FileInformationSequence* BasicService_cpp_i::list(const char* pattern) +{ + CF::FileSystem::FileInformationSequence* tmpVal; + // TODO: Fill in this function + + return tmpVal; +} + +CF::File_ptr BasicService_cpp_i::create(const char* fileName) +{ + CF::File_ptr tmpVal; + // TODO: Fill in this function + + return tmpVal; +} + +CF::File_ptr BasicService_cpp_i::open(const char* fileName, CORBA::Boolean read_Only) +{ + CF::File_ptr tmpVal; + // TODO: Fill in this function + + return tmpVal; +} + +void BasicService_cpp_i::mkdir(const char* directoryName) +{ + // TODO: Fill in this function +} + +void BasicService_cpp_i::rmdir(const char* directoryName) +{ + // TODO: Fill in this function +} + +void BasicService_cpp_i::query(CF::Properties& fileSystemProperties) +{ + // TODO: Fill in this function +} + +void BasicService_cpp_i::mount(const char* mountPoint, CF::FileSystem_ptr file_System) +{ + // TODO: Fill in this function +} + +void BasicService_cpp_i::unmount(const char* mountPoint) +{ + // TODO: Fill in this function +} + +CF::FileManager::MountSequence* BasicService_cpp_i::getMounts() +{ + CF::FileManager::MountSequence* tmpVal; + // TODO: Fill in this function + + return tmpVal; +} + + diff --git a/redhawk/src/testing/sdr/dev/services/BasicService_cpp/cpp/BasicService_cpp.h b/redhawk/src/testing/sdr/dev/services/BasicService_cpp/cpp/BasicService_cpp.h new file mode 100644 index 000000000..211623e14 --- /dev/null +++ b/redhawk/src/testing/sdr/dev/services/BasicService_cpp/cpp/BasicService_cpp.h @@ -0,0 +1,29 @@ +#ifndef BASICSERVICE_CPP_I_IMPL_H +#define BASICSERVICE_CPP_I_IMPL_H + +#include "BasicService_cpp_base.h" + +class BasicService_cpp_i; + +class BasicService_cpp_i : public BasicService_cpp_base +{ + ENABLE_LOGGING + public: + BasicService_cpp_i(char *devMgr_ior, char *name); + ~BasicService_cpp_i(); + void remove(const char* fileName); + void copy(const char* sourceFileName, const char* destinationFileName); + void move(const char* sourceFileName, const char* destinationFileName); + CORBA::Boolean exists(const char* fileName); + CF::FileSystem::FileInformationSequence* list(const char* pattern); + CF::File_ptr create(const char* fileName); + CF::File_ptr open(const char* fileName, CORBA::Boolean read_Only); + void mkdir(const char* directoryName); + void rmdir(const char* directoryName); + void query(CF::Properties& fileSystemProperties); + void mount(const char* mountPoint, CF::FileSystem_ptr file_System); + void unmount(const char* mountPoint); + CF::FileManager::MountSequence* getMounts(); +}; + +#endif // BASICSERVICE_CPP_I_IMPL_H diff --git a/redhawk/src/testing/sdr/dev/services/BasicService_cpp/cpp/BasicService_cpp_base.cpp b/redhawk/src/testing/sdr/dev/services/BasicService_cpp/cpp/BasicService_cpp_base.cpp new file mode 100644 index 000000000..9b598e8b2 --- /dev/null +++ b/redhawk/src/testing/sdr/dev/services/BasicService_cpp/cpp/BasicService_cpp_base.cpp @@ -0,0 +1,34 @@ +#include "BasicService_cpp_base.h" + +/******************************************************************************************* + + AUTO-GENERATED CODE. DO NOT MODIFY + + The following class functions are for the base class for the service class. To + customize any of these functions, do not modify them here. Instead, overload them + on the child class + +******************************************************************************************/ + +BasicService_cpp_base::BasicService_cpp_base(char *devMgr_ior, char *name) : + Service_impl(devMgr_ior, name) +{ +} + +void BasicService_cpp_base::registerServiceWithDevMgr () +{ + _deviceManager->registerService(this->_this(), this->_name.c_str()); +} + +void BasicService_cpp_base::terminateService () +{ + try { + _deviceManager->unregisterService(this->_this(), this->_name.c_str()); + } catch (...) { + } + + PortableServer::POA_ptr root_poa = ossie::corba::RootPOA(); + PortableServer::ObjectId_var oid = root_poa->servant_to_id(this); + root_poa->deactivate_object(oid); +} + diff --git a/redhawk/src/testing/sdr/dev/services/BasicService_cpp/cpp/BasicService_cpp_base.h b/redhawk/src/testing/sdr/dev/services/BasicService_cpp/cpp/BasicService_cpp_base.h new file mode 100644 index 000000000..0594edafb --- /dev/null +++ b/redhawk/src/testing/sdr/dev/services/BasicService_cpp/cpp/BasicService_cpp_base.h @@ -0,0 +1,18 @@ +#ifndef BASICSERVICE_CPP_BASE_IMPL_BASE_H +#define BASICSERVICE_CPP_BASE_IMPL_BASE_H + +#include +#include +#include + +class BasicService_cpp_base : public Service_impl, public virtual POA_CF::FileManager +{ + public: + BasicService_cpp_base(char *devMgr_ior, char *name); + + void registerServiceWithDevMgr (); + void terminateService (); + void construct (); + +}; +#endif // BASICSERVICE_CPP_BASE_IMPL_BASE_H diff --git a/redhawk/src/testing/sdr/dev/services/BasicService_cpp/cpp/Makefile.am b/redhawk/src/testing/sdr/dev/services/BasicService_cpp/cpp/Makefile.am new file mode 100644 index 000000000..e7e490412 --- /dev/null +++ b/redhawk/src/testing/sdr/dev/services/BasicService_cpp/cpp/Makefile.am @@ -0,0 +1,31 @@ +# +# This file is protected by Copyright. Please refer to the COPYRIGHT file +# distributed with this source distribution. +# +# This file is part of REDHAWK core. +# +# REDHAWK core is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation, either version 3 of the License, or (at your option) any +# later version. +# +# REDHAWK core is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +# details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/. +# +CFDIR = $(top_srcdir)/base + +noinst_PROGRAMS = BasicService_cpp + +BasicService_cpp_SOURCES = BasicService_cpp.cpp \ +BasicService_cpp.h \ +BasicService_cpp_base.cpp \ +BasicService_cpp_base.h \ +main.cpp + +BasicService_cpp_CXXFLAGS = -Wall $(BOOST_CPPFLAGS) -I$(CFDIR)/include -I$(CFDIR)/include/ossie +BasicService_cpp_LDADD = $(BOOST_REGEX_LIB) $(BOOST_SYSTEM_LIB) $(BOOST_FILESYSTEM_LIB) $(BOOST_THREAD_LIB) $(OMNIDYNAMIC_LIBS) $(OMNICOS_LIBS) $(CFDIR)/framework/libossiecf.la $(CFDIR)/framework/idl/libossieidl.la diff --git a/redhawk/src/testing/sdr/dev/services/BasicService_cpp/cpp/main.cpp b/redhawk/src/testing/sdr/dev/services/BasicService_cpp/cpp/main.cpp new file mode 100644 index 000000000..d0ab6b2ac --- /dev/null +++ b/redhawk/src/testing/sdr/dev/services/BasicService_cpp/cpp/main.cpp @@ -0,0 +1,26 @@ +#include +#include "ossie/ossieSupport.h" + +#include "BasicService_cpp.h" + +BasicService_cpp_i *servicePtr; + +void signal_catcher(int sig) +{ + // IMPORTANT Don't call exit(...) in this function + // issue all CORBA calls that you need for cleanup here before calling ORB shutdown + if (servicePtr) { + servicePtr->halt(); + } +} + +int main(int argc, char* argv[]) +{ + struct sigaction sa; + sa.sa_handler = signal_catcher; + sa.sa_flags = 0; + servicePtr = 0; + + Service_impl::start_service(&servicePtr, sa, argc, argv); + return 0; +} diff --git a/redhawk/src/testing/tests/test_13_TestSB.py b/redhawk/src/testing/tests/test_13_TestSB.py index 2c08cb237..ddc42da92 100644 --- a/redhawk/src/testing/tests/test_13_TestSB.py +++ b/redhawk/src/testing/tests/test_13_TestSB.py @@ -28,6 +28,8 @@ import copy import threading import warnings +import subprocess +import commands from omniORB import CORBA, any @@ -59,6 +61,70 @@ def _initSourceAndSink(dataFormat): return source, sink +@scatest.requireJava +class InteractiveTestJava(scatest.CorbaTestCase): + def setUp(self): + self.message = "Interactive mode (-i) no longer supported. Please use the sandbox to run Components/Devices/Services outside the scope of a Domain" + + def tearDown(self): + pass + + def test_NoInteractiveJavaService(self): + status, output=commands.getstatusoutput('sdr/dev/services/BasicService_java/java/startJava.sh -i') + self.assertEquals(output,self.message) + + def test_NoInteractiveJavaDevice(self): + print os.getcwd() + status, output=commands.getstatusoutput('sdr/dev/devices/BasicTestDevice_java/java/startJava.sh -i') + self.assertEquals(output,self.message) + + def test_NoInteractiveJavaComponent(self): + print os.getcwd() + status, output=commands.getstatusoutput('sdr/dom/components/ECM_JAVA/java/startJava.sh -i') + self.assertEquals(output,self.message) + +class InteractiveTestPython(scatest.CorbaTestCase): + def setUp(self): + self.message = "Interactive mode (-i) no longer supported. Please use the sandbox to run Components/Devices/Services outside the scope of a Domain" + + def tearDown(self): + pass + + def test_NoInteractivePythonService(self): + status, output=commands.getstatusoutput('sdr/dev/services/S1/python/S1.py -i') + self.assertEquals(output,self.message) + + def test_NoInteractivePythonDevice(self): + print os.getcwd() + status, output=commands.getstatusoutput('sdr/dev/devices/BasicTestDevice/BasicTestDevice.py -i') + self.assertEquals(output,"DEBUG:root:Starting Device\n"+self.message) + + def test_NoInteractivePythonComponent(self): + print os.getcwd() + status, output=commands.getstatusoutput('sdr/dom/components/ECM_PY/python/ECM_PY.py -i') + self.assertEquals(output,self.message) + +class InteractiveTestCpp(scatest.CorbaTestCase): + def setUp(self): + self.message = "Interactive mode (-i) no longer supported. Please use the sandbox to run Components/Devices/Services outside the scope of a Domain" + + def tearDown(self): + pass + + def test_NoInteractiveCppService(self): + status, output=commands.getstatusoutput('sdr/dev/services/BasicService_cpp/cpp/BasicService_cpp -i') + self.assertEquals(output,self.message) + + def test_NoInteractiveCppDevice(self): + print os.getcwd() + status, output=commands.getstatusoutput('sdr/dev/devices/cpp_dev/cpp/cpp_dev -i') + self.assertEquals(output,self.message) + + def test_NoInteractiveCppComponent(self): + print os.getcwd() + status, output=commands.getstatusoutput('sdr/dom/components/ECM_CPP/cpp/ECM_CPP -i') + self.assertEquals(output,self.message) + class SBTestTest(scatest.CorbaTestCase): def setUp(self): sb.setDEBUG(False) From eb785d8afa2a25383d56ae0d613e1fb09092d774 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 19 Jan 2017 15:03:09 -0500 Subject: [PATCH 0657/1644] Modernize BulkIO autotools build --- bulkioInterfaces/Makefile.am | 2 ++ bulkioInterfaces/configure.ac | 3 ++- bulkioInterfaces/m4/.gitignore | 1 + bulkioInterfaces/reconf | 39 +--------------------------------- 4 files changed, 6 insertions(+), 39 deletions(-) create mode 100644 bulkioInterfaces/m4/.gitignore diff --git a/bulkioInterfaces/Makefile.am b/bulkioInterfaces/Makefile.am index 9f220728c..48d34829e 100644 --- a/bulkioInterfaces/Makefile.am +++ b/bulkioInterfaces/Makefile.am @@ -18,6 +18,8 @@ # along with this program. If not, see http://www.gnu.org/licenses/. # +ACLOCAL_AMFLAGS = -I m4 -I ${OSSIEHOME}/share/aclocal/ossie + ############################################################################### # CONFIGURE YOUR INTERFACES LIBRARY HERE # diff --git a/bulkioInterfaces/configure.ac b/bulkioInterfaces/configure.ac index 93707a2a2..c6611dc1e 100644 --- a/bulkioInterfaces/configure.ac +++ b/bulkioInterfaces/configure.ac @@ -19,9 +19,10 @@ # AC_INIT(bulkioInterfaces, 2.1.0) +AC_CONFIG_MACRO_DIR([m4]) AC_SUBST([LIBBULKIOINTERFACES_VERSION_INFO], [3:0:1]) -AM_INIT_AUTOMAKE([nostdinc subdir-objects]) +AM_INIT_AUTOMAKE([foreign nostdinc subdir-objects]) AC_PROG_CC AC_PROG_CXX AC_PROG_INSTALL diff --git a/bulkioInterfaces/m4/.gitignore b/bulkioInterfaces/m4/.gitignore new file mode 100644 index 000000000..0f4126cd6 --- /dev/null +++ b/bulkioInterfaces/m4/.gitignore @@ -0,0 +1 @@ +*.m4 diff --git a/bulkioInterfaces/reconf b/bulkioInterfaces/reconf index e5cae955d..b9c1ef072 100755 --- a/bulkioInterfaces/reconf +++ b/bulkioInterfaces/reconf @@ -19,41 +19,4 @@ # along with this program. If not, see http://www.gnu.org/licenses/. # - -rm -f config.cache - -# Setup the libtool stuff -if [ -e /usr/local/share/aclocal/libtool.m4 ]; then - /bin/cp /usr/local/share/aclocal/libtool.m4 aclocal.d/acinclude.m4 -elif [ -e /usr/share/aclocal/libtool.m4 ]; then - /bin/cp /usr/share/aclocal/libtool.m4 acinclude.m4 -fi -libtoolize --force --automake - -# Search in expected locations for the OSSIE acincludes -# 1. Included with CF source -# 2. Using installed CF -if [ -d ../../common/acinclude ]; then - OSSIE_AC_INCLUDE=../../common/acinclude -elif [ -n ${OSSIEHOME} ] && [ -d ${OSSIEHOME}/share/aclocal/ossie ]; then - OSSIE_AC_INCLUDE=${OSSIEHOME}/share/aclocal/ossie -else - echo "Error: Cannot find the OSSIE aclocal files. This is not expected!" -fi - -if [ -n ${OSSIE_AC_INCLUDE} ]; then - aclocal -I ${OSSIE_AC_INCLUDE} -else - aclocal -fi - -autoconf -automake --foreign --add-missing - -# Due to strange autotools bootstrap issues, -# if ltmain.sh doesn't exists we have to run both again -if [ ! -f ltmain.sh ]; then - libtoolize --force --automake - automake --foreign --add-missing -fi - +autoreconf -i From 526adf214228046fc8a9f60ca82598e301bdf13c Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 19 Jan 2017 15:30:14 -0500 Subject: [PATCH 0658/1644] Integrate BulkIO C++ unit tests into the main build, instead of using their own Autotools build --- bulkioInterfaces/configure.ac | 6 ++ .../libsrc/testing/tests/buildtests | 4 -- .../libsrc/testing/tests/cpp/Makefile.am | 7 +-- .../libsrc/testing/tests/cpp/configure.ac | 46 --------------- .../libsrc/testing/tests/cpp/reconf | 57 ------------------- .../libsrc/testing/tests/cpp/runtests | 3 - 6 files changed, 9 insertions(+), 114 deletions(-) delete mode 100644 bulkioInterfaces/libsrc/testing/tests/cpp/configure.ac delete mode 100755 bulkioInterfaces/libsrc/testing/tests/cpp/reconf diff --git a/bulkioInterfaces/configure.ac b/bulkioInterfaces/configure.ac index c6611dc1e..50290634e 100644 --- a/bulkioInterfaces/configure.ac +++ b/bulkioInterfaces/configure.ac @@ -136,12 +136,18 @@ AC_MSG_RESULT($HAVE_JAVASUPPORT) AM_CONDITIONAL(HAVE_JAVASUPPORT, test $HAVE_JAVASUPPORT = yes) # End optional java support +# C++ unit testing support. May want to conditionally enable/disable this. +AM_PATH_CPPUNIT(1.12.1) +AC_SUBST(BULKIO_CFLAGS, "-I \$(top_srcdir)/src/cpp -I \$(top_srcdir)/libsrc/cpp") +AC_SUBST(BULKIO_LIBS, "-L\$(top_srcdir)/libsrc -lbulkio-${BULKIO_API_VERSION} -L\$(top_srcdir) -lbulkioInterfaces") + AC_CONFIG_FILES([bulkioInterfaces.pc setup.py Makefile jni/Makefile]) if test "$enable_base_classes" != "no"; then if test "$HAVE_JAVASUPPORT = yes"; then AC_CONFIG_FILES([libsrc/java/META-INF/MANIFEST.MF]) fi AC_CONFIG_FILES([libsrc/Makefile libsrc/bulkio.pc]) + AC_CONFIG_FILES([libsrc/testing/tests/cpp/Makefile]) fi AC_OUTPUT diff --git a/bulkioInterfaces/libsrc/testing/tests/buildtests b/bulkioInterfaces/libsrc/testing/tests/buildtests index 0588870f1..4ef5f38be 100755 --- a/bulkioInterfaces/libsrc/testing/tests/buildtests +++ b/bulkioInterfaces/libsrc/testing/tests/buildtests @@ -58,7 +58,3 @@ cd - cd ../devices/dev_snk/java ./reconf; ./configure; make cd - - -cd cpp -./reconf; ./configure; -cd - diff --git a/bulkioInterfaces/libsrc/testing/tests/cpp/Makefile.am b/bulkioInterfaces/libsrc/testing/tests/cpp/Makefile.am index a754a581b..487204e4e 100644 --- a/bulkioInterfaces/libsrc/testing/tests/cpp/Makefile.am +++ b/bulkioInterfaces/libsrc/testing/tests/cpp/Makefile.am @@ -20,9 +20,8 @@ # Rules for the test code (use `make check` to execute) TESTS = Bulkio check_PROGRAMS = $(TESTS) -bulkio_top=../../../../ -bulkio_libsrc_top=$(bulkio_top)/libsrc + Bulkio_SOURCES = Bulkio.cpp Bulkio_Helper_Fixture.cpp Bulkio_InPort_Fixture.cpp Bulkio_OutPort_Fixture.cpp Bulkio_MultiOut_Port.cpp Bulkio_SOURCES += InStreamTest.h InStreamTest.cpp -Bulkio_CXXFLAGS = $(CPPUNIT_CFLAGS) -I$(bulkio_libsrc_top)/cpp -I$(bulkio_top)/src/cpp -I$(bulkio_top)/src/cpp/ossie $(BOOST_CPPFLAGS) $(RH_DEPS_CFLAGS) -Bulkio_LDADD = -L$(bulkio_libsrc_top)/.libs -L$(bulkio_top)/.libs -lbulkio-2.1 -lbulkioInterfaces $(BOOST_LDFLAGS) $(BOOST_SYSTEM_LIB) $(RH_DEPS_LIBS) $(CPPUNIT_LIBS) -llog4cxx +Bulkio_CXXFLAGS = $(BULKIO_CFLAGS) $(BOOST_CPPFLAGS) $(OSSIE_CFLAGS) $(CPPUNIT_CFLAGS) +Bulkio_LDADD = $(BULKIO_LIBS) $(BOOST_LDFLAGS) $(BOOST_SYSTEM_LIB) $(OSSIE_LIBS) $(CPPUNIT_LIBS) $(LOG4CXX_LIBS) diff --git a/bulkioInterfaces/libsrc/testing/tests/cpp/configure.ac b/bulkioInterfaces/libsrc/testing/tests/cpp/configure.ac deleted file mode 100644 index c5a8a761b..000000000 --- a/bulkioInterfaces/libsrc/testing/tests/cpp/configure.ac +++ /dev/null @@ -1,46 +0,0 @@ -/* - * This file is protected by Copyright. Please refer to the COPYRIGHT file - * distributed with this source distribution. - * - * This file is part of REDHAWK bulkioInterfaces. - * - * REDHAWK bulkioInterfaces is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * REDHAWK bulkioInterfaces is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see http://www.gnu.org/licenses/. - */ - - -dnl Process this file with autoconf to produce a configure script. -AC_INIT([Bulkio_Test], [0.1]) -AC_CONFIG_SRCDIR([Bulkio.cpp]) -AM_INIT_AUTOMAKE -AM_PATH_CPPUNIT(1.9.6) -AC_PROG_CXX -AC_PROG_CC -AC_PROG_INSTALL -AC_PREFIX_DEFAULT(${OSSIEHOME}) -AX_BOOST_BASE([1.41]) -AX_BOOST_THREAD -AX_BOOST_SYSTEM - - -OSSIE_CHECK_OSSIE -OSSIE_OSSIEHOME_AS_PREFIX -PKG_CHECK_MODULES([RH_DEPS], [ossie >= 1.7 omniORB4 >= 4.0.0]) - -# set PKG_CONFIG_PATH to look at local xxx.pc files - -export PKG_CONFIG_PATH="../../../..:../../..":$PKG_CONFIG_PATH -PKG_CHECK_MODULES([BIO], [ bulkio >= 1.0 bulkioInterfaces >= 1.8 ]) - -AC_CORBA_ORB -AC_OUTPUT(Makefile) diff --git a/bulkioInterfaces/libsrc/testing/tests/cpp/reconf b/bulkioInterfaces/libsrc/testing/tests/cpp/reconf deleted file mode 100755 index 50400ed26..000000000 --- a/bulkioInterfaces/libsrc/testing/tests/cpp/reconf +++ /dev/null @@ -1,57 +0,0 @@ -#!/bin/sh -# -# This file is protected by Copyright. Please refer to the COPYRIGHT file -# distributed with this source distribution. -# -# This file is part of REDHAWK bulkioInterfaces. -# -# REDHAWK bulkioInterfaces is free software: you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation, either version 3 of the License, or (at your option) any -# later version. -# -# REDHAWK bulkioInterfaces is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more -# details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with this program. If not, see http://www.gnu.org/licenses/. -# - -rm -f config.cache - -# Setup the libtool stuff -if [ -e /usr/local/share/aclocal/libtool.m4 ]; then - /bin/cp /usr/local/share/aclocal/libtool.m4 aclocal.d/acinclude.m4 -elif [ -e /usr/share/aclocal/libtool.m4 ]; then - /bin/cp /usr/share/aclocal/libtool.m4 acinclude.m4 -fi -libtoolize --force --automake - -# Search in expected locations for the OSSIE acincludes -# 1. Included with CF source -# 2. Using installed CF -if [ -d ../../common/acinclude ]; then - OSSIE_AC_INCLUDE=../../common/acinclude -elif [ -n ${OSSIEHOME} ] && [ -d ${OSSIEHOME}/share/aclocal/ossie ]; then - OSSIE_AC_INCLUDE=${OSSIEHOME}/share/aclocal/ossie -else - echo "Error: Cannot find the OSSIE aclocal files. This is not expected!" -fi - -if [ -n ${OSSIE_AC_INCLUDE} ]; then - aclocal -I ${OSSIE_AC_INCLUDE} -else - aclocal -fi - -autoconf -automake --foreign --add-missing - -# Due to strange autotools bootstrap issues, -# if ltmain.sh doesn't exists we have to run both again -if [ ! -f ltmain.sh ]; then - libtoolize --force --automake - automake --foreign --add-missing -fi diff --git a/bulkioInterfaces/libsrc/testing/tests/cpp/runtests b/bulkioInterfaces/libsrc/testing/tests/cpp/runtests index b418ece15..d47789ecd 100755 --- a/bulkioInterfaces/libsrc/testing/tests/cpp/runtests +++ b/bulkioInterfaces/libsrc/testing/tests/cpp/runtests @@ -1,7 +1,4 @@ # # -bulkio_top=../../../.. -bulkio_libsrc_top=$bulkio_top/libsrc -export LD_LIBRARY_PATH=$bulkio_libsrc_top/.libs:$bulkio_top/.libs:${LD_LIBRARY_PATH} make check -j 10 From fc085ab4cbe59835735fc5d0ca1f0dc7346af95e Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 23 Jan 2017 12:59:40 -0500 Subject: [PATCH 0659/1644] Integrate all test components into the main configure.ac, with a (non-linked) Makefile to build them all --- bulkioInterfaces/configure.ac | 23 +++- .../cpp/reconf => Makefile.am} | 9 +- .../components/CPP_Ports/CPP_Ports.spec | 102 ------------------ .../testing/components/CPP_Ports/build.sh | 45 -------- .../testing/components/CPP_Ports/cpp/.md5sums | 1 + .../components/CPP_Ports/cpp/Makefile.am | 22 ++-- .../testing/components/CPP_Ports/cpp/build.sh | 37 ------- .../components/CPP_Ports/cpp/configure.ac | 44 -------- .../testing/components/CPP_Ports/cpp/reconf | 46 -------- .../components/Java_Ports/java/.md5sums | 1 + .../components/Java_Ports/java/Makefile.am | 19 ++-- .../Oversized_framedata/cpp/.md5sums | 1 + .../Oversized_framedata/cpp/Makefile.am | 11 +- .../Oversized_framedata/cpp/configure.ac | 45 -------- .../Oversized_framedata/cpp/m4/.gitignore | 1 - .../Oversized_framedata/java/.md5sums | 1 + .../Oversized_framedata/java/Makefile.am | 9 +- .../components/TestLargePush/cpp/.md5sums | 1 + .../components/TestLargePush/cpp/Makefile.am | 18 ++-- .../components/TestLargePush/cpp/build.sh | 32 ------ .../components/TestLargePush/cpp/configure.ac | 48 --------- .../components/TestLargePush/cpp/reconf | 47 -------- .../components/TestLargePush/java/.md5sums | 1 + .../components/TestLargePush/java/Makefile.am | 15 +-- .../multiout_attachable/cpp/.md5sums | 2 +- .../multiout_attachable/cpp/Makefile.am | 16 ++- .../multiout_attachable/cpp/build.sh | 32 ------ .../multiout_attachable/cpp/configure.ac | 47 -------- .../components/multiout_attachable/cpp/reconf | 47 -------- .../multiout_attachable/java/.md5sums | 2 +- .../multiout_attachable/java/Makefile.am | 15 ++- .../multiout_attachable/java/configure.ac | 49 --------- .../multiout_attachable/java/reconf | 47 -------- .../components/sri_changed_cpp/.md5sums | 2 +- .../components/sri_changed_cpp/cpp/.md5sums | 2 +- .../sri_changed_cpp/cpp/Makefile.am | 16 ++- .../components/sri_changed_cpp/cpp/build.sh | 29 ----- .../sri_changed_cpp/cpp/configure.ac | 47 -------- .../sri_changed_cpp/cpp/m4/.gitignore | 1 - .../components/sri_changed_cpp/cpp/reconf | 23 ---- .../sri_changed_cpp/sri_changed_cpp.spec | 87 --------------- .../testing/devices/dev_snk/java/.md5sums | 1 + .../testing/devices/dev_snk/java/Makefile.am | 2 +- .../testing/devices/dev_snk/java/configure.ac | 37 ------- .../testing/devices/dev_snk/java/reconf | 25 ----- .../libsrc/testing/devices/dev_src/build.sh | 63 ----------- .../testing/devices/dev_src/java/.md5sums | 1 + .../testing/devices/dev_src/java/Makefile.am | 2 +- .../testing/devices/dev_src/java/configure.ac | 37 ------- .../testing/devices/dev_src/java/reconf | 25 ----- .../libsrc/testing/tests/buildtests | 59 +--------- 51 files changed, 112 insertions(+), 1183 deletions(-) rename bulkioInterfaces/libsrc/testing/{components/Oversized_framedata/cpp/reconf => Makefile.am} (68%) mode change 100755 => 100644 delete mode 100644 bulkioInterfaces/libsrc/testing/components/CPP_Ports/CPP_Ports.spec delete mode 100755 bulkioInterfaces/libsrc/testing/components/CPP_Ports/build.sh create mode 100644 bulkioInterfaces/libsrc/testing/components/CPP_Ports/cpp/.md5sums delete mode 100755 bulkioInterfaces/libsrc/testing/components/CPP_Ports/cpp/build.sh delete mode 100644 bulkioInterfaces/libsrc/testing/components/CPP_Ports/cpp/configure.ac delete mode 100755 bulkioInterfaces/libsrc/testing/components/CPP_Ports/cpp/reconf create mode 100644 bulkioInterfaces/libsrc/testing/components/Java_Ports/java/.md5sums create mode 100644 bulkioInterfaces/libsrc/testing/components/Oversized_framedata/cpp/.md5sums delete mode 100644 bulkioInterfaces/libsrc/testing/components/Oversized_framedata/cpp/configure.ac delete mode 100644 bulkioInterfaces/libsrc/testing/components/Oversized_framedata/cpp/m4/.gitignore create mode 100644 bulkioInterfaces/libsrc/testing/components/Oversized_framedata/java/.md5sums create mode 100644 bulkioInterfaces/libsrc/testing/components/TestLargePush/cpp/.md5sums delete mode 100755 bulkioInterfaces/libsrc/testing/components/TestLargePush/cpp/build.sh delete mode 100644 bulkioInterfaces/libsrc/testing/components/TestLargePush/cpp/configure.ac delete mode 100755 bulkioInterfaces/libsrc/testing/components/TestLargePush/cpp/reconf create mode 100644 bulkioInterfaces/libsrc/testing/components/TestLargePush/java/.md5sums delete mode 100755 bulkioInterfaces/libsrc/testing/components/multiout_attachable/cpp/build.sh delete mode 100644 bulkioInterfaces/libsrc/testing/components/multiout_attachable/cpp/configure.ac delete mode 100755 bulkioInterfaces/libsrc/testing/components/multiout_attachable/cpp/reconf delete mode 100644 bulkioInterfaces/libsrc/testing/components/multiout_attachable/java/configure.ac delete mode 100755 bulkioInterfaces/libsrc/testing/components/multiout_attachable/java/reconf delete mode 100755 bulkioInterfaces/libsrc/testing/components/sri_changed_cpp/cpp/build.sh delete mode 100644 bulkioInterfaces/libsrc/testing/components/sri_changed_cpp/cpp/configure.ac delete mode 100644 bulkioInterfaces/libsrc/testing/components/sri_changed_cpp/cpp/m4/.gitignore delete mode 100755 bulkioInterfaces/libsrc/testing/components/sri_changed_cpp/cpp/reconf delete mode 100644 bulkioInterfaces/libsrc/testing/components/sri_changed_cpp/sri_changed_cpp.spec create mode 100644 bulkioInterfaces/libsrc/testing/devices/dev_snk/java/.md5sums delete mode 100644 bulkioInterfaces/libsrc/testing/devices/dev_snk/java/configure.ac delete mode 100755 bulkioInterfaces/libsrc/testing/devices/dev_snk/java/reconf delete mode 100755 bulkioInterfaces/libsrc/testing/devices/dev_src/build.sh create mode 100644 bulkioInterfaces/libsrc/testing/devices/dev_src/java/.md5sums delete mode 100644 bulkioInterfaces/libsrc/testing/devices/dev_src/java/configure.ac delete mode 100755 bulkioInterfaces/libsrc/testing/devices/dev_src/java/reconf diff --git a/bulkioInterfaces/configure.ac b/bulkioInterfaces/configure.ac index 50290634e..a34e32a7c 100644 --- a/bulkioInterfaces/configure.ac +++ b/bulkioInterfaces/configure.ac @@ -146,8 +146,27 @@ if test "$enable_base_classes" != "no"; then if test "$HAVE_JAVASUPPORT = yes"; then AC_CONFIG_FILES([libsrc/java/META-INF/MANIFEST.MF]) fi - AC_CONFIG_FILES([libsrc/Makefile libsrc/bulkio.pc]) - AC_CONFIG_FILES([libsrc/testing/tests/cpp/Makefile]) + AC_SUBST(PROJECTDEPS_CFLAGS, "\$(OSSIE_CFLAGS)") + AC_SUBST(PROJECTDEPS_LIBS, "\$(OSSIE_LIBS)") + AC_SUBST(INTERFACEDEPS_CFLAGS, "\$(BULKIO_CFLAGS)") + AC_SUBST(INTERFACEDEPS_LIBS, "\$(BULKIO_LIBS)") + AC_SUBST(REDHAWK_CLASSPATH, "\$(OSSIE_CLASSPATH)") + AC_SUBST(BULKIO_CLASSPATH, "\$(top_srcdir)/libsrc/bulkio.jar:\$(top_srcdir)/BULKIOInterfaces.jar") + AC_CONFIG_FILES([libsrc/Makefile \ + libsrc/bulkio.pc \ + libsrc/testing/Makefile \ + libsrc/testing/tests/cpp/Makefile \ + libsrc/testing/components/CPP_Ports/cpp/Makefile \ + libsrc/testing/components/Java_Ports/java/Makefile \ + libsrc/testing/components/Oversized_framedata/cpp/Makefile \ + libsrc/testing/components/Oversized_framedata/java/Makefile \ + libsrc/testing/components/TestLargePush/cpp/Makefile \ + libsrc/testing/components/TestLargePush/java/Makefile \ + libsrc/testing/components/multiout_attachable/cpp/Makefile \ + libsrc/testing/components/multiout_attachable/java/Makefile \ + libsrc/testing/components/sri_changed_cpp/cpp/Makefile \ + libsrc/testing/devices/dev_snk/java/Makefile \ + libsrc/testing/devices/dev_src/java/Makefile]) fi AC_OUTPUT diff --git a/bulkioInterfaces/libsrc/testing/components/Oversized_framedata/cpp/reconf b/bulkioInterfaces/libsrc/testing/Makefile.am old mode 100755 new mode 100644 similarity index 68% rename from bulkioInterfaces/libsrc/testing/components/Oversized_framedata/cpp/reconf rename to bulkioInterfaces/libsrc/testing/Makefile.am index ece304047..080a7f3e1 --- a/bulkioInterfaces/libsrc/testing/components/Oversized_framedata/cpp/reconf +++ b/bulkioInterfaces/libsrc/testing/Makefile.am @@ -1,4 +1,3 @@ -#!/bin/sh # # This file is protected by Copyright. Please refer to the COPYRIGHT file # distributed with this source distribution. @@ -19,5 +18,9 @@ # along with this program. If not, see http://www.gnu.org/licenses/. # -rm -f config.cache -autoreconf -i +SUBDIRS = components/CPP_Ports/cpp components/sri_changed_cpp/cpp components/Java_Ports/java +SUBDIRS += components/TestLargePush/cpp components/TestLargePush/java +SUBDIRS += components/multiout_attachable/cpp components/multiout_attachable/java +SUBDIRS += components/Oversized_framedata/cpp components/Oversized_framedata/java +SUBDIRS += devices/dev_src/java devices/dev_snk/java +SUBDIRS += tests/cpp diff --git a/bulkioInterfaces/libsrc/testing/components/CPP_Ports/CPP_Ports.spec b/bulkioInterfaces/libsrc/testing/components/CPP_Ports/CPP_Ports.spec deleted file mode 100644 index 3d1cf56ad..000000000 --- a/bulkioInterfaces/libsrc/testing/components/CPP_Ports/CPP_Ports.spec +++ /dev/null @@ -1,102 +0,0 @@ -# -# This file is protected by Copyright. Please refer to the COPYRIGHT file -# distributed with this source distribution. -# -# This file is part of REDHAWK bulkioInterfaces. -# -# REDHAWK bulkioInterfaces is free software: you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation, either version 3 of the License, or (at your option) any -# later version. -# -# REDHAWK bulkioInterfaces is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more -# details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with this program. If not, see http://www.gnu.org/licenses/. -# -# By default, the RPM will install to the standard REDHAWK SDR root location (/var/redhawk/sdr) -# You can override this at install time using --prefix /new/sdr/root when invoking rpm (preferred method, if you must) -%{!?_sdrroot: %define _sdrroot /var/redhawk/sdr} -%define _prefix %{_sdrroot} -Prefix: %{_prefix} - -# Point install paths to locations within our target SDR root -%define _sysconfdir %{_prefix}/etc -%define _localstatedir %{_prefix}/var -%define _mandir %{_prefix}/man -%define _infodir %{_prefix}/info - -Name: CPP_Ports -Summary: Component %{name} -Version: 1.0.0 -Release: 1 -License: None -Group: REDHAWK/Components -Source: %{name}-%{version}.tar.gz -BuildRoot: %{_tmppath}/%{name}-root - -Requires: redhawk >= 1.8 -BuildRequires: redhawk >= 1.8 -BuildRequires: autoconf automake libtool - -# Interface requirements -Requires: bulkioInterfaces -BuildRequires: bulkioInterfaces - -# C++ requirements -Requires: libomniORB4.1 -Requires: boost >= 1.41 -Requires: apache-log4cxx >= 0.10 -BuildRequires: boost-devel >= 1.41 -BuildRequires: libomniORB4.1-devel -BuildRequires: apache-log4cxx-devel >= 0.10 - -# Java requirements -Requires: java -BuildRequires: jdk - -# Python requirements -Requires: python omniORBpy -BuildRequires: libomniORBpy3-devel -BuildRequires: python-devel >= 2.3 - -%description -Component %{name} - -%prep -%setup - -%build -# Implementation cpp -pushd cpp -./reconf -%define _bindir %{_prefix}/dom/components/CPP_Ports/cpp -%configure -make -popd - -%install -rm -rf $RPM_BUILD_ROOT -# Implementation cpp -pushd cpp -%define _bindir %{_prefix}/dom/components/CPP_Ports/cpp -make install DESTDIR=$RPM_BUILD_ROOT -popd - -%clean -rm -rf $RPM_BUILD_ROOT - -%files -%defattr(-,redhawk,redhawk) -%dir %{_prefix}/dom/components/%{name} -%{_prefix}/dom/components/%{name}/CPP_Ports.scd.xml -%{_prefix}/dom/components/%{name}/CPP_Ports.prf.xml -%{_prefix}/dom/components/%{name}/CPP_Ports.spd.xml -%{_prefix}/dom/components/%{name}/cpp -%{_prefix}/dom/components/%{name}/python -%{_prefix}/dom/components/%{name}/java -%{_prefix}/dom/components/%{name}/ - diff --git a/bulkioInterfaces/libsrc/testing/components/CPP_Ports/build.sh b/bulkioInterfaces/libsrc/testing/components/CPP_Ports/build.sh deleted file mode 100755 index 690b18e57..000000000 --- a/bulkioInterfaces/libsrc/testing/components/CPP_Ports/build.sh +++ /dev/null @@ -1,45 +0,0 @@ -#!/bin/sh -# -# This file is protected by Copyright. Please refer to the COPYRIGHT file -# distributed with this source distribution. -# -# This file is part of REDHAWK bulkioInterfaces. -# -# REDHAWK bulkioInterfaces is free software: you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation, either version 3 of the License, or (at your option) any -# later version. -# -# REDHAWK bulkioInterfaces is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more -# details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with this program. If not, see http://www.gnu.org/licenses/. -# - -if [ "$1" == "rpm" ]; then - # A very simplistic RPM build scenario - if [ -e CPP_Ports.spec ]; then - mydir=`dirname $0` - tmpdir=`mktemp -d` - cp -r ${mydir} ${tmpdir}/CPP_Ports-1.0.0 - tar czf ${tmpdir}/CPP_Ports-1.0.0.tar.gz --exclude=".svn" -C ${tmpdir} CPP_Ports-1.0.0 - rpmbuild -ta ${tmpdir}/CPP_Ports-1.0.0.tar.gz - rm -rf $tmpdir - else - echo "Missing RPM spec file in" `pwd` - exit 1 - fi -else - for impl in java2 ; do - pushd $impl &> /dev/null - if [ -e build.sh ]; then - ./build.sh $* - else - echo "No build.sh found for $impl" - fi - popd &> /dev/null - done -fi diff --git a/bulkioInterfaces/libsrc/testing/components/CPP_Ports/cpp/.md5sums b/bulkioInterfaces/libsrc/testing/components/CPP_Ports/cpp/.md5sums new file mode 100644 index 000000000..7b040aa22 --- /dev/null +++ b/bulkioInterfaces/libsrc/testing/components/CPP_Ports/cpp/.md5sums @@ -0,0 +1 @@ +e44b9b9cef8e221832f111c9a4b7c718 Makefile.am diff --git a/bulkioInterfaces/libsrc/testing/components/CPP_Ports/cpp/Makefile.am b/bulkioInterfaces/libsrc/testing/components/CPP_Ports/cpp/Makefile.am index c5048173e..1908f43e9 100644 --- a/bulkioInterfaces/libsrc/testing/components/CPP_Ports/cpp/Makefile.am +++ b/bulkioInterfaces/libsrc/testing/components/CPP_Ports/cpp/Makefile.am @@ -18,17 +18,16 @@ # along with this program. If not, see http://www.gnu.org/licenses/. # ossieName = CPP_Ports -bindir = $(prefix)/dom/components/CPP_Ports/cpp/ +bindir = $(prefix)/dom/components/CPP_Ports/cpp bin_PROGRAMS = CPP_Ports -xmldir = $(prefix)/dom/components/CPP_Ports/ -dist_xml_DATA = ../CPP_Ports.prf.xml ../CPP_Ports.scd.xml ../CPP_Ports.spd.xml - -# this is use to build against local bulkio interface and library and not installed version -bulkio_top=../../../../../ -bulkio_libsrc_top=$(bulkio_top)/libsrc +xmldir = $(prefix)/dom/components/CPP_Ports +dist_xml_DATA = ../CPP_Ports.scd.xml ../CPP_Ports.prf.xml ../CPP_Ports.spd.xml +ACLOCAL_AMFLAGS = -I m4 -I${OSSIEHOME}/share/aclocal/ossie +AUTOMAKE_OPTIONS = subdir-objects distclean-local: + rm -rf m4 rm -f config.* rm -rf autom4te.cache rm -f acinclude.m4 @@ -41,12 +40,13 @@ distclean-local: rm -f missing rm -rf .deps + # Sources, libraries and library directories are auto-included from a file # generated by the REDHAWK IDE. You can remove/modify the following lines if # you wish to manually control these options. include $(srcdir)/Makefile.am.ide CPP_Ports_SOURCES = $(redhawk_SOURCES_auto) -##CPP_Ports_CXXFLAGS = -Wall $(PROJECTDEPS_CFLAGS) $(BOOST_CPPFLAGS) -I$(bulkio_libsrc_top)/cpp -I$(bulkio_top)/src/cpp -I$(bulkio_top)/src/cpp/ossie $(BOOST_CPPFLAGS) $(RH_DEPS_CFLAGS) $(redhawk_INCLUDES_auto) -CPP_Ports_CXXFLAGS = -Wall -I$(bulkio_libsrc_top)/cpp -I$(bulkio_top)/src/cpp -I$(bulkio_top)/src/cpp/ossie $(PROJECTDEPS_CFLAGS) $(BOOST_CPPFLAGS) $(RH_DEPS_CFLAGS) $(redhawk_INCLUDES_auto) -CPP_Ports_LDADD = -L$(bulkio_libsrc_top)/.libs -L$(bulkio_top)/.libs $(BIO_LIBS) $(PROJECTDEPS_LIBS) $(BOOST_LDFLAGS) $(BOOST_THREAD_LIB) $(BOOST_SYSTEM_LIB) $(INTERFACEDEPS_LIBS) $(redhawk_LDADD_auto) -CPP_Ports_LDFLAGS = -Wall $(redhawk_LDFLAGS_auto) +CPP_Ports_LDADD = $(SOFTPKG_LIBS) $(PROJECTDEPS_LIBS) $(BOOST_LDFLAGS) $(BOOST_THREAD_LIB) $(BOOST_REGEX_LIB) $(BOOST_SYSTEM_LIB) $(INTERFACEDEPS_LIBS) $(redhawk_LDADD_auto) +CPP_Ports_CXXFLAGS = -Wall $(SOFTPKG_CFLAGS) $(PROJECTDEPS_CFLAGS) $(BOOST_CPPFLAGS) $(INTERFACEDEPS_CFLAGS) $(redhawk_INCLUDES_auto) +CPP_Ports_LDFLAGS = -Wall $(redhawk_LDFLAGS_auto) + diff --git a/bulkioInterfaces/libsrc/testing/components/CPP_Ports/cpp/build.sh b/bulkioInterfaces/libsrc/testing/components/CPP_Ports/cpp/build.sh deleted file mode 100755 index 50619f198..000000000 --- a/bulkioInterfaces/libsrc/testing/components/CPP_Ports/cpp/build.sh +++ /dev/null @@ -1,37 +0,0 @@ -#!/bin/sh -# -# This file is protected by Copyright. Please refer to the COPYRIGHT file -# distributed with this source distribution. -# -# This file is part of REDHAWK bulkioInterfaces. -# -# REDHAWK bulkioInterfaces is free software: you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation, either version 3 of the License, or (at your option) any -# later version. -# -# REDHAWK bulkioInterfaces is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more -# details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with this program. If not, see http://www.gnu.org/licenses/. -# -configure='configure' -makefile_in='Makefile.in' -config_ac='configure.ac' -make_am='Makefile.am' -makefile='Makefile' - -if [ "$1" == 'clean' ]; then - make clean -else - # Checks if build is newer than makefile (based on modification time) - if [[ ! -e $configure || ! -e $makefile_in || $config_ac -nt $makefile || $make_am -nt $makefile ]]; then - ./reconf - ./configure - fi - make - exit 0 -fi diff --git a/bulkioInterfaces/libsrc/testing/components/CPP_Ports/cpp/configure.ac b/bulkioInterfaces/libsrc/testing/components/CPP_Ports/cpp/configure.ac deleted file mode 100644 index db7b4c73a..000000000 --- a/bulkioInterfaces/libsrc/testing/components/CPP_Ports/cpp/configure.ac +++ /dev/null @@ -1,44 +0,0 @@ -/* - * This file is protected by Copyright. Please refer to the COPYRIGHT file - * distributed with this source distribution. - * - * This file is part of REDHAWK bulkioInterfaces. - * - * REDHAWK bulkioInterfaces is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * REDHAWK bulkioInterfaces is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see http://www.gnu.org/licenses/. - */ -AC_INIT(CPP_Ports, 1.0.0) -AM_INIT_AUTOMAKE(nostdinc) - -AC_PROG_CC -AC_PROG_CXX -AC_PROG_INSTALL - -AC_CORBA_ORB -OSSIE_CHECK_OSSIE -OSSIE_SDRROOT_AS_PREFIX - -# Dependencies -export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig" -PKG_CHECK_MODULES([PROJECTDEPS], [ossie >= 1.8 omniORB4 >= 4.0.0]) -OSSIE_ENABLE_LOG4CXX -AX_BOOST_BASE([1.41]) -AX_BOOST_THREAD -AX_BOOST_SYSTEM -#CHECK_VECTOR_IMPL - -export PKG_CONFIG_PATH="../../../..:../../..":$PKG_CONFIG_PATH -PKG_CHECK_MODULES([BIO], [bulkio >= 1.10]) - -AC_CONFIG_FILES(Makefile) -AC_OUTPUT diff --git a/bulkioInterfaces/libsrc/testing/components/CPP_Ports/cpp/reconf b/bulkioInterfaces/libsrc/testing/components/CPP_Ports/cpp/reconf deleted file mode 100755 index c17e1c744..000000000 --- a/bulkioInterfaces/libsrc/testing/components/CPP_Ports/cpp/reconf +++ /dev/null @@ -1,46 +0,0 @@ -#!/bin/sh -# -# This file is protected by Copyright. Please refer to the COPYRIGHT file -# distributed with this source distribution. -# -# This file is part of REDHAWK bulkioInterfaces. -# -# REDHAWK bulkioInterfaces is free software: you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation, either version 3 of the License, or (at your option) any -# later version. -# -# REDHAWK bulkioInterfaces is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more -# details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with this program. If not, see http://www.gnu.org/licenses/. -# - -rm -f config.cache - -# Setup the libtool stuff -if [ -e /usr/local/share/aclocal/libtool.m4 ]; then - /bin/cp /usr/local/share/aclocal/libtool.m4 aclocal.d/acinclude.m4 -elif [ -e /usr/share/aclocal/libtool.m4 ]; then - /bin/cp /usr/share/aclocal/libtool.m4 acinclude.m4 -fi -libtoolize --force --automake - -# Search in expected locations for the OSSIE acincludes -if [ -n ${OSSIEHOME} ] && [ -d ${OSSIEHOME}/share/aclocal/ossie ]; then - OSSIE_AC_INCLUDE=${OSSIEHOME}/share/aclocal/ossie -else - echo "Error: Cannot find the OSSIE aclocal files. This is not expected!" -fi - -if [ -n ${OSSIE_AC_INCLUDE} ]; then - aclocal -I ${OSSIE_AC_INCLUDE} -else - aclocal -fi - -autoconf -automake --foreign --add-missing \ No newline at end of file diff --git a/bulkioInterfaces/libsrc/testing/components/Java_Ports/java/.md5sums b/bulkioInterfaces/libsrc/testing/components/Java_Ports/java/.md5sums new file mode 100644 index 000000000..f05ec4e24 --- /dev/null +++ b/bulkioInterfaces/libsrc/testing/components/Java_Ports/java/.md5sums @@ -0,0 +1 @@ +79c5784ed8f81f67fa0a0074dd737db0 Makefile.am diff --git a/bulkioInterfaces/libsrc/testing/components/Java_Ports/java/Makefile.am b/bulkioInterfaces/libsrc/testing/components/Java_Ports/java/Makefile.am index 3b5b4f2be..aebe9d40e 100644 --- a/bulkioInterfaces/libsrc/testing/components/Java_Ports/java/Makefile.am +++ b/bulkioInterfaces/libsrc/testing/components/Java_Ports/java/Makefile.am @@ -17,17 +17,22 @@ # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see http://www.gnu.org/licenses/. # +ACLOCAL_AMFLAGS = -I m4 -I${OSSIEHOME}/share/aclocal/ossie +AUTOMAKE_OPTIONS = subdir-objects + +Java_Ports_jar_CLASSPATH = $(SOFTPKG_CLASSPATH):$(REDHAWK_CLASSPATH):$(BULKIO_CLASSPATH) Java_Ports.jar$(EXEEXT): $(Java_Ports_jar_SOURCES) - @mkdir -p bin - $(JAVAC) -cp $(OSSIE_HOME)/lib/CFInterfaces.jar:$(OSSIE_HOME)/lib/log4j-1.2.15.jar:$(OSSIE_HOME)/lib/ossie.jar:$(bulkio_libsrc_top)/bulkio.jar:$(bulkio_top)/BULKIOInterfaces.jar -d bin $(Java_Ports_jar_SOURCES) + mkdir -p bin + $(JAVAC) -cp $(Java_Ports_jar_CLASSPATH) -g -d bin $(Java_Ports_jar_SOURCES) $(JAR) cf ./Java_Ports.jar -C bin . - + $(JAR) uf ./Java_Ports.jar -C src . clean-local: rm -rf bin distclean-local: + rm -rf m4 rm -f config.* rm -rf autom4te.cache rm -f acinclude.m4 @@ -45,14 +50,8 @@ bindir = $(prefix)/dom/components/Java_Ports/java/ bin_PROGRAMS = Java_Ports.jar Java_Ports_jar_SOURCES := $(shell find ./src -name "*.java") -## -## This is used to build against local bulkio interface library and not installed version -## -bulkio_top=../../../../.. -bulkio_libsrc_top=$(bulkio_top)/libsrc - xmldir = $(prefix)/dom/components/Java_Ports/ -dist_xml_DATA = ../Java_Ports.prf.xml ../Java_Ports.scd.xml ../Java_Ports.spd.xml +dist_xml_DATA = ../Java_Ports.scd.xml ../Java_Ports.prf.xml ../Java_Ports.spd.xml domdir = $(prefix)/dom/components/Java_Ports/java/ dist_dom_SCRIPTS = startJava.sh diff --git a/bulkioInterfaces/libsrc/testing/components/Oversized_framedata/cpp/.md5sums b/bulkioInterfaces/libsrc/testing/components/Oversized_framedata/cpp/.md5sums new file mode 100644 index 000000000..dd3adbd1c --- /dev/null +++ b/bulkioInterfaces/libsrc/testing/components/Oversized_framedata/cpp/.md5sums @@ -0,0 +1 @@ +ba80f42e76c8861c9423b8ed602dce02 Makefile.am diff --git a/bulkioInterfaces/libsrc/testing/components/Oversized_framedata/cpp/Makefile.am b/bulkioInterfaces/libsrc/testing/components/Oversized_framedata/cpp/Makefile.am index 46b484dc9..fb9724690 100644 --- a/bulkioInterfaces/libsrc/testing/components/Oversized_framedata/cpp/Makefile.am +++ b/bulkioInterfaces/libsrc/testing/components/Oversized_framedata/cpp/Makefile.am @@ -18,15 +18,16 @@ # along with this program. If not, see http://www.gnu.org/licenses/. # ossieName = Oversized_framedata -bindir = $(prefix)/dom/components/Oversized_framedata/cpp/ +bindir = $(prefix)/dom/components/Oversized_framedata/cpp bin_PROGRAMS = Oversized_framedata -xmldir = $(prefix)/dom/components/Oversized_framedata/ +xmldir = $(prefix)/dom/components/Oversized_framedata dist_xml_DATA = ../Oversized_framedata.scd.xml ../Oversized_framedata.prf.xml ../Oversized_framedata.spd.xml ACLOCAL_AMFLAGS = -I m4 -I${OSSIEHOME}/share/aclocal/ossie - +AUTOMAKE_OPTIONS = subdir-objects distclean-local: + rm -rf m4 rm -f config.* rm -rf autom4te.cache rm -f acinclude.m4 @@ -45,7 +46,7 @@ distclean-local: # you wish to manually control these options. include $(srcdir)/Makefile.am.ide Oversized_framedata_SOURCES = $(redhawk_SOURCES_auto) -Oversized_framedata_LDADD = $(PROJECTDEPS_LIBS) $(BOOST_LDFLAGS) $(BOOST_THREAD_LIB) $(BOOST_REGEX_LIB) $(BOOST_SYSTEM_LIB) $(INTERFACEDEPS_LIBS) $(redhawk_LDADD_auto) -Oversized_framedata_CXXFLAGS = -Wall $(PROJECTDEPS_CFLAGS) $(BOOST_CPPFLAGS) $(INTERFACEDEPS_CFLAGS) $(redhawk_INCLUDES_auto) +Oversized_framedata_LDADD = $(SOFTPKG_LIBS) $(PROJECTDEPS_LIBS) $(BOOST_LDFLAGS) $(BOOST_THREAD_LIB) $(BOOST_REGEX_LIB) $(BOOST_SYSTEM_LIB) $(INTERFACEDEPS_LIBS) $(redhawk_LDADD_auto) +Oversized_framedata_CXXFLAGS = -Wall $(SOFTPKG_CFLAGS) $(PROJECTDEPS_CFLAGS) $(BOOST_CPPFLAGS) $(INTERFACEDEPS_CFLAGS) $(redhawk_INCLUDES_auto) Oversized_framedata_LDFLAGS = -Wall $(redhawk_LDFLAGS_auto) diff --git a/bulkioInterfaces/libsrc/testing/components/Oversized_framedata/cpp/configure.ac b/bulkioInterfaces/libsrc/testing/components/Oversized_framedata/cpp/configure.ac deleted file mode 100644 index 3c45e494d..000000000 --- a/bulkioInterfaces/libsrc/testing/components/Oversized_framedata/cpp/configure.ac +++ /dev/null @@ -1,45 +0,0 @@ -# -# This file is protected by Copyright. Please refer to the COPYRIGHT file -# distributed with this source distribution. -# -# This file is part of REDHAWK bulkioInterfaces. -# -# REDHAWK bulkioInterfaces is free software: you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation, either version 3 of the License, or (at your option) any -# later version. -# -# REDHAWK bulkioInterfaces is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more -# details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with this program. If not, see http://www.gnu.org/licenses/. -# -AC_INIT(Oversized_framedata, 1.0.0) -AM_INIT_AUTOMAKE([nostdinc foreign]) - -AC_PROG_CC -AC_PROG_CXX -AC_PROG_INSTALL - -AC_CORBA_ORB -OSSIE_CHECK_OSSIE -OSSIE_SDRROOT_AS_PREFIX - -m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) - -# Dependencies -export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig" -PKG_CHECK_MODULES([PROJECTDEPS], [ossie >= 1.10 omniORB4 >= 4.1.0 ]) -PKG_CHECK_MODULES([INTERFACEDEPS], [bulkio >= 1.10]) -OSSIE_ENABLE_LOG4CXX -AX_BOOST_BASE([1.41]) -AX_BOOST_SYSTEM -AX_BOOST_THREAD -AX_BOOST_REGEX - -AC_CONFIG_FILES([Makefile]) -AC_OUTPUT - diff --git a/bulkioInterfaces/libsrc/testing/components/Oversized_framedata/cpp/m4/.gitignore b/bulkioInterfaces/libsrc/testing/components/Oversized_framedata/cpp/m4/.gitignore deleted file mode 100644 index 0f4126cd6..000000000 --- a/bulkioInterfaces/libsrc/testing/components/Oversized_framedata/cpp/m4/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.m4 diff --git a/bulkioInterfaces/libsrc/testing/components/Oversized_framedata/java/.md5sums b/bulkioInterfaces/libsrc/testing/components/Oversized_framedata/java/.md5sums new file mode 100644 index 000000000..536519357 --- /dev/null +++ b/bulkioInterfaces/libsrc/testing/components/Oversized_framedata/java/.md5sums @@ -0,0 +1 @@ +59a728f0968103426e50f8a81120ee62 Makefile.am diff --git a/bulkioInterfaces/libsrc/testing/components/Oversized_framedata/java/Makefile.am b/bulkioInterfaces/libsrc/testing/components/Oversized_framedata/java/Makefile.am index 77eabbec4..c84a476b2 100644 --- a/bulkioInterfaces/libsrc/testing/components/Oversized_framedata/java/Makefile.am +++ b/bulkioInterfaces/libsrc/testing/components/Oversized_framedata/java/Makefile.am @@ -17,17 +17,22 @@ # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see http://www.gnu.org/licenses/. # -Oversized_framedata_jar_CLASSPATH = $(CLASSPATH_SOFTPKG_DEP)$(OSSIE_HOME)/lib/CFInterfaces.jar:$(OSSIE_HOME)/lib/log4j-1.2.15.jar:$(OSSIE_HOME)/lib/ossie.jar:$(OSSIE_HOME)/lib/bulkio.jar:$(OSSIE_HOME)/lib/BULKIOInterfaces.jar +ACLOCAL_AMFLAGS = -I m4 -I${OSSIEHOME}/share/aclocal/ossie +AUTOMAKE_OPTIONS = subdir-objects + +Oversized_framedata_jar_CLASSPATH = $(SOFTPKG_CLASSPATH):$(REDHAWK_CLASSPATH):$(BULKIO_CLASSPATH) Oversized_framedata.jar$(EXEEXT): $(Oversized_framedata_jar_SOURCES) mkdir -p bin - $(JAVAC) -cp $(Oversized_framedata_jar_CLASSPATH) -d bin $(Oversized_framedata_jar_SOURCES) + $(JAVAC) -cp $(Oversized_framedata_jar_CLASSPATH) -g -d bin $(Oversized_framedata_jar_SOURCES) $(JAR) cf ./Oversized_framedata.jar -C bin . + $(JAR) uf ./Oversized_framedata.jar -C src . clean-local: rm -rf bin distclean-local: + rm -rf m4 rm -f config.* rm -rf autom4te.cache rm -f acinclude.m4 diff --git a/bulkioInterfaces/libsrc/testing/components/TestLargePush/cpp/.md5sums b/bulkioInterfaces/libsrc/testing/components/TestLargePush/cpp/.md5sums new file mode 100644 index 000000000..569c0c562 --- /dev/null +++ b/bulkioInterfaces/libsrc/testing/components/TestLargePush/cpp/.md5sums @@ -0,0 +1 @@ +396c1d1970d0a4e4a57991df37e1a198 Makefile.am diff --git a/bulkioInterfaces/libsrc/testing/components/TestLargePush/cpp/Makefile.am b/bulkioInterfaces/libsrc/testing/components/TestLargePush/cpp/Makefile.am index d0462899d..ef71f1178 100644 --- a/bulkioInterfaces/libsrc/testing/components/TestLargePush/cpp/Makefile.am +++ b/bulkioInterfaces/libsrc/testing/components/TestLargePush/cpp/Makefile.am @@ -18,17 +18,16 @@ # along with this program. If not, see http://www.gnu.org/licenses/. # ossieName = TestLargePush -bindir = $(prefix)/dom/components/TestLargePush/cpp/ +bindir = $(prefix)/dom/components/TestLargePush/cpp bin_PROGRAMS = TestLargePush -xmldir = $(prefix)/dom/components/TestLargePush/ +xmldir = $(prefix)/dom/components/TestLargePush dist_xml_DATA = ../TestLargePush.scd.xml ../TestLargePush.prf.xml ../TestLargePush.spd.xml - -# this is use to build against local bulkio interface and library and not installed version -bulkio_top=../../../../../ -bulkio_libsrc_top=$(bulkio_top)/libsrc +ACLOCAL_AMFLAGS = -I m4 -I${OSSIEHOME}/share/aclocal/ossie +AUTOMAKE_OPTIONS = subdir-objects distclean-local: + rm -rf m4 rm -f config.* rm -rf autom4te.cache rm -f acinclude.m4 @@ -47,8 +46,7 @@ distclean-local: # you wish to manually control these options. include $(srcdir)/Makefile.am.ide TestLargePush_SOURCES = $(redhawk_SOURCES_auto) -TestLargePush_LDADD = -L$(bulkio_libsrc_top)/.libs -L$(bulkio_top)/.libs $(BIO_LIBS) $(PROJECTDEPS_LIBS) $(BOOST_LDFLAGS) $(BOOST_THREAD_LIB) $(BOOST_SYSTEM_LIB) $(INTERFACEDEPS_LIBS) $(redhawk_LDADD_auto) -#TestLargePush_CXXFLAGS = -Wall $(PROJECTDEPS_CFLAGS) $(BOOST_CPPFLAGS) $(INTERFACEDEPS_CFLAGS) $(redhawk_INCLUDES_auto) -TestLargePush_CXXFLAGS = -Wall -I$(bulkio_libsrc_top)/cpp -I$(bulkio_top)/src/cpp $(PROJECTDEPS_CFLAGS) $(BOOST_CPPFLAGS) $(INTERFACEDEPS_CFLAGS) $(redhawk_INCLUDES_auto) -TestLargePush_LDFLAGS = -Wall $(redhawk_LDFLAGS_auto) +TestLargePush_LDADD = $(SOFTPKG_LIBS) $(PROJECTDEPS_LIBS) $(BOOST_LDFLAGS) $(BOOST_THREAD_LIB) $(BOOST_REGEX_LIB) $(BOOST_SYSTEM_LIB) $(INTERFACEDEPS_LIBS) $(redhawk_LDADD_auto) +TestLargePush_CXXFLAGS = -Wall $(SOFTPKG_CFLAGS) $(PROJECTDEPS_CFLAGS) $(BOOST_CPPFLAGS) $(INTERFACEDEPS_CFLAGS) $(redhawk_INCLUDES_auto) +TestLargePush_LDFLAGS = -Wall $(redhawk_LDFLAGS_auto) diff --git a/bulkioInterfaces/libsrc/testing/components/TestLargePush/cpp/build.sh b/bulkioInterfaces/libsrc/testing/components/TestLargePush/cpp/build.sh deleted file mode 100755 index c6089ee81..000000000 --- a/bulkioInterfaces/libsrc/testing/components/TestLargePush/cpp/build.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/sh -# -# This file is protected by Copyright. Please refer to the COPYRIGHT file -# distributed with this source distribution. -# -# This file is part of REDHAWK bulkioInterfaces. -# -# REDHAWK bulkioInterfaces is free software: you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation, either version 3 of the License, or (at your option) any -# later version. -# -# REDHAWK bulkioInterfaces is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more -# details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with this program. If not, see http://www.gnu.org/licenses/. -# - -if [ "$1" = "clean" ]; then - make clean -else - # Checks if build is newer than makefile (based on modification time) - if [ ! -e configure ] || [ ! -e Makefile ] || [ configure.ac -nt Makefile ] || [ Makefile.am -nt Makefile ]; then - ./reconf - ./configure - fi - make -j - exit 0 -fi diff --git a/bulkioInterfaces/libsrc/testing/components/TestLargePush/cpp/configure.ac b/bulkioInterfaces/libsrc/testing/components/TestLargePush/cpp/configure.ac deleted file mode 100644 index fd2ec8bde..000000000 --- a/bulkioInterfaces/libsrc/testing/components/TestLargePush/cpp/configure.ac +++ /dev/null @@ -1,48 +0,0 @@ -/* - * This file is protected by Copyright. Please refer to the COPYRIGHT file - * distributed with this source distribution. - * - * This file is part of REDHAWK bulkioInterfaces. - * - * REDHAWK bulkioInterfaces is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * REDHAWK bulkioInterfaces is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see http://www.gnu.org/licenses/. - */ -AC_INIT(TestLargePush, 1.0.0) -AM_INIT_AUTOMAKE(nostdinc) - - -AC_PROG_CC -AC_PROG_CXX -AC_PROG_INSTALL - -AC_CORBA_ORB -OSSIE_CHECK_OSSIE -OSSIE_SDRROOT_AS_PREFIX - -m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) - -# Dependencies -export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig" -PKG_CHECK_MODULES([PROJECTDEPS], [ossie >= 1.9 omniORB4 >= 4.1.0 ]) -OSSIE_ENABLE_LOG4CXX -AX_BOOST_BASE([1.41]) -AX_BOOST_THREAD - -AX_BOOST_SYSTEM - -export PKG_CONFIG_PATH="../../../..:../../..":$PKG_CONFIG_PATH -PKG_CHECK_MODULES([BIO], [bulkio >= 1.10]) - -AC_CONFIG_FILES([Makefile]) -AC_OUTPUT - diff --git a/bulkioInterfaces/libsrc/testing/components/TestLargePush/cpp/reconf b/bulkioInterfaces/libsrc/testing/components/TestLargePush/cpp/reconf deleted file mode 100755 index ba319ec54..000000000 --- a/bulkioInterfaces/libsrc/testing/components/TestLargePush/cpp/reconf +++ /dev/null @@ -1,47 +0,0 @@ -#!/bin/sh -# -# This file is protected by Copyright. Please refer to the COPYRIGHT file -# distributed with this source distribution. -# -# This file is part of REDHAWK bulkioInterfaces. -# -# REDHAWK bulkioInterfaces is free software: you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation, either version 3 of the License, or (at your option) any -# later version. -# -# REDHAWK bulkioInterfaces is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more -# details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with this program. If not, see http://www.gnu.org/licenses/. -# - -rm -f config.cache - -# Setup the libtool stuff -if [ -e /usr/local/share/aclocal/libtool.m4 ]; then - /bin/cp /usr/local/share/aclocal/libtool.m4 aclocal.d/acinclude.m4 -elif [ -e /usr/share/aclocal/libtool.m4 ]; then - /bin/cp /usr/share/aclocal/libtool.m4 acinclude.m4 -fi -libtoolize --force --automake - -# Search in expected locations for the OSSIE acincludes -if [ -n ${OSSIEHOME} ] && [ -d ${OSSIEHOME}/share/aclocal/ossie ]; then - OSSIE_AC_INCLUDE=${OSSIEHOME}/share/aclocal/ossie -else - echo "Error: Cannot find the OSSIE aclocal files. This is not expected!" -fi - -if [ -n ${OSSIE_AC_INCLUDE} ]; then - aclocal -I ${OSSIE_AC_INCLUDE} -else - aclocal -fi - -autoconf -automake --foreign --add-missing - diff --git a/bulkioInterfaces/libsrc/testing/components/TestLargePush/java/.md5sums b/bulkioInterfaces/libsrc/testing/components/TestLargePush/java/.md5sums new file mode 100644 index 000000000..b79be2cf2 --- /dev/null +++ b/bulkioInterfaces/libsrc/testing/components/TestLargePush/java/.md5sums @@ -0,0 +1 @@ +e7e48351847aee365b95df73f16cac70 Makefile.am diff --git a/bulkioInterfaces/libsrc/testing/components/TestLargePush/java/Makefile.am b/bulkioInterfaces/libsrc/testing/components/TestLargePush/java/Makefile.am index 45921db8b..911e1a896 100644 --- a/bulkioInterfaces/libsrc/testing/components/TestLargePush/java/Makefile.am +++ b/bulkioInterfaces/libsrc/testing/components/TestLargePush/java/Makefile.am @@ -17,15 +17,22 @@ # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see http://www.gnu.org/licenses/. # +ACLOCAL_AMFLAGS = -I m4 -I${OSSIEHOME}/share/aclocal/ossie +AUTOMAKE_OPTIONS = subdir-objects + +TestLargePush_jar_CLASSPATH = $(SOFTPKG_CLASSPATH):$(REDHAWK_CLASSPATH):$(BULKIO_CLASSPATH) + TestLargePush.jar$(EXEEXT): $(TestLargePush_jar_SOURCES) mkdir -p bin - $(JAVAC) -cp $(CLASSPATH_SOFTPKG_DEP)$(OSSIE_HOME)/lib/CFInterfaces.jar:$(OSSIE_HOME)/lib/log4j-1.2.15.jar:$(OSSIE_HOME)/lib/ossie.jar:$(bulkio_top)/BULKIOInterfaces.jar:$(bulkio_libsrc_top)/bulkio.jar -d bin $(TestLargePush_jar_SOURCES) + $(JAVAC) -cp $(TestLargePush_jar_CLASSPATH) -g -d bin $(TestLargePush_jar_SOURCES) $(JAR) cf ./TestLargePush.jar -C bin . + $(JAR) uf ./TestLargePush.jar -C src . clean-local: rm -rf bin distclean-local: + rm -rf m4 rm -f config.* rm -rf autom4te.cache rm -f acinclude.m4 @@ -43,12 +50,6 @@ bindir = $(prefix)/dom/components/TestLargePush/java/ bin_PROGRAMS = TestLargePush.jar TestLargePush_jar_SOURCES := $(shell find ./src -name "*.java") -## -## This is used to build against local bulkio interface library and not installed version -## -bulkio_top=../../../../.. -bulkio_libsrc_top=$(bulkio_top)/libsrc - xmldir = $(prefix)/dom/components/TestLargePush/ dist_xml_DATA = ../TestLargePush.scd.xml ../TestLargePush.prf.xml ../TestLargePush.spd.xml diff --git a/bulkioInterfaces/libsrc/testing/components/multiout_attachable/cpp/.md5sums b/bulkioInterfaces/libsrc/testing/components/multiout_attachable/cpp/.md5sums index c66941dc1..90d946248 100644 --- a/bulkioInterfaces/libsrc/testing/components/multiout_attachable/cpp/.md5sums +++ b/bulkioInterfaces/libsrc/testing/components/multiout_attachable/cpp/.md5sums @@ -1,7 +1,7 @@ 3e90cd586ef55340f720fa01c394f810 main.cpp c99df9fa4ab0cd042eac42fcee6441c3 reconf 93debcdba56b6826a722d6572c43802a configure.ac -310ea7ad0ede382044a0cc94aa9aa24a Makefile.am +b3244a77701ca4fd7a6d4e08c0901e6d Makefile.am ccfa2e64e7cf8f57a2bc5056e90f0297 struct_props.h 1f8c0483ef3c90c0c9cd0f1402679791 Makefile.am.ide bcb90affbdcff3322084421ffb5edb92 multiout_attachable_base.cpp diff --git a/bulkioInterfaces/libsrc/testing/components/multiout_attachable/cpp/Makefile.am b/bulkioInterfaces/libsrc/testing/components/multiout_attachable/cpp/Makefile.am index b1514928e..0b9d53e4a 100644 --- a/bulkioInterfaces/libsrc/testing/components/multiout_attachable/cpp/Makefile.am +++ b/bulkioInterfaces/libsrc/testing/components/multiout_attachable/cpp/Makefile.am @@ -18,17 +18,16 @@ # along with this program. If not, see http://www.gnu.org/licenses/. # ossieName = multiout_attachable -bindir = $(prefix)/dom/components/multiout_attachable/cpp/ +bindir = $(prefix)/dom/components/multiout_attachable/cpp bin_PROGRAMS = multiout_attachable -xmldir = $(prefix)/dom/components/multiout_attachable/ +xmldir = $(prefix)/dom/components/multiout_attachable dist_xml_DATA = ../multiout_attachable.scd.xml ../multiout_attachable.prf.xml ../multiout_attachable.spd.xml - -# this is use to build against local bulkio interface and library and not installed version -bulkio_top=../../../../../ -bulkio_libsrc_top=$(bulkio_top)/libsrc +ACLOCAL_AMFLAGS = -I m4 -I${OSSIEHOME}/share/aclocal/ossie +AUTOMAKE_OPTIONS = subdir-objects distclean-local: + rm -rf m4 rm -f config.* rm -rf autom4te.cache rm -f acinclude.m4 @@ -47,8 +46,7 @@ distclean-local: # you wish to manually control these options. include $(srcdir)/Makefile.am.ide multiout_attachable_SOURCES = $(redhawk_SOURCES_auto) -multiout_attachable_LDADD = -L$(bulkio_libsrc_top)/.libs -L$(bulkio_top)/.libs $(BIO_LIBS) $(PROJECTDEPS_LIBS) $(BOOST_LDFLAGS) $(BOOST_THREAD_LIB) $(BOOST_REGEX_LIB) $(BOOST_SYSTEM_LIB) $(INTERFACEDEPS_LIBS) $(redhawk_LDADD_auto) -#multiout_attachable_CXXFLAGS = -Wall $(PROJECTDEPS_CFLAGS) $(BOOST_CPPFLAGS) $(INTERFACEDEPS_CFLAGS) $(redhawk_INCLUDES_auto) -multiout_attachable_CXXFLAGS = -Wall -I$(bulkio_libsrc_top)/cpp -I$(bulkio_top)/src/cpp $(PROJECTDEPS_CFLAGS) $(BOOST_CPPFLAGS) $(INTERFACEDEPS_CFLAGS) $(redhawk_INCLUDES_auto) +multiout_attachable_LDADD = $(SOFTPKG_LIBS) $(PROJECTDEPS_LIBS) $(BOOST_LDFLAGS) $(BOOST_THREAD_LIB) $(BOOST_REGEX_LIB) $(BOOST_SYSTEM_LIB) $(INTERFACEDEPS_LIBS) $(redhawk_LDADD_auto) +multiout_attachable_CXXFLAGS = -Wall $(SOFTPKG_CFLAGS) $(PROJECTDEPS_CFLAGS) $(BOOST_CPPFLAGS) $(INTERFACEDEPS_CFLAGS) $(redhawk_INCLUDES_auto) multiout_attachable_LDFLAGS = -Wall $(redhawk_LDFLAGS_auto) diff --git a/bulkioInterfaces/libsrc/testing/components/multiout_attachable/cpp/build.sh b/bulkioInterfaces/libsrc/testing/components/multiout_attachable/cpp/build.sh deleted file mode 100755 index c6089ee81..000000000 --- a/bulkioInterfaces/libsrc/testing/components/multiout_attachable/cpp/build.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/sh -# -# This file is protected by Copyright. Please refer to the COPYRIGHT file -# distributed with this source distribution. -# -# This file is part of REDHAWK bulkioInterfaces. -# -# REDHAWK bulkioInterfaces is free software: you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation, either version 3 of the License, or (at your option) any -# later version. -# -# REDHAWK bulkioInterfaces is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more -# details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with this program. If not, see http://www.gnu.org/licenses/. -# - -if [ "$1" = "clean" ]; then - make clean -else - # Checks if build is newer than makefile (based on modification time) - if [ ! -e configure ] || [ ! -e Makefile ] || [ configure.ac -nt Makefile ] || [ Makefile.am -nt Makefile ]; then - ./reconf - ./configure - fi - make -j - exit 0 -fi diff --git a/bulkioInterfaces/libsrc/testing/components/multiout_attachable/cpp/configure.ac b/bulkioInterfaces/libsrc/testing/components/multiout_attachable/cpp/configure.ac deleted file mode 100644 index 37a61cf4f..000000000 --- a/bulkioInterfaces/libsrc/testing/components/multiout_attachable/cpp/configure.ac +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This file is protected by Copyright. Please refer to the COPYRIGHT file - * distributed with this source distribution. - * - * This file is part of REDHAWK bulkioInterfaces. - * - * REDHAWK bulkioInterfaces is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * REDHAWK bulkioInterfaces is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see http://www.gnu.org/licenses/. - */ -AC_INIT(multiout_attachable, 1.0.0) -AM_INIT_AUTOMAKE(nostdinc) - -AC_PROG_CC -AC_PROG_CXX -AC_PROG_INSTALL - -AC_CORBA_ORB -OSSIE_CHECK_OSSIE -OSSIE_SDRROOT_AS_PREFIX - -m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) - -# Dependencies -export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig" -PKG_CHECK_MODULES([PROJECTDEPS], [ossie >= 1.10 omniORB4 >= 4.1.0 ]) -OSSIE_ENABLE_LOG4CXX -AX_BOOST_BASE([1.41]) -AX_BOOST_SYSTEM -AX_BOOST_THREAD -AX_BOOST_REGEX - -export PKG_CONFIG_PATH="../../../..:../../..":$PKG_CONFIG_PATH -PKG_CHECK_MODULES([BIO], [bulkio >= 1.10]) - -AC_CONFIG_FILES([Makefile]) -AC_OUTPUT - diff --git a/bulkioInterfaces/libsrc/testing/components/multiout_attachable/cpp/reconf b/bulkioInterfaces/libsrc/testing/components/multiout_attachable/cpp/reconf deleted file mode 100755 index ba319ec54..000000000 --- a/bulkioInterfaces/libsrc/testing/components/multiout_attachable/cpp/reconf +++ /dev/null @@ -1,47 +0,0 @@ -#!/bin/sh -# -# This file is protected by Copyright. Please refer to the COPYRIGHT file -# distributed with this source distribution. -# -# This file is part of REDHAWK bulkioInterfaces. -# -# REDHAWK bulkioInterfaces is free software: you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation, either version 3 of the License, or (at your option) any -# later version. -# -# REDHAWK bulkioInterfaces is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more -# details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with this program. If not, see http://www.gnu.org/licenses/. -# - -rm -f config.cache - -# Setup the libtool stuff -if [ -e /usr/local/share/aclocal/libtool.m4 ]; then - /bin/cp /usr/local/share/aclocal/libtool.m4 aclocal.d/acinclude.m4 -elif [ -e /usr/share/aclocal/libtool.m4 ]; then - /bin/cp /usr/share/aclocal/libtool.m4 acinclude.m4 -fi -libtoolize --force --automake - -# Search in expected locations for the OSSIE acincludes -if [ -n ${OSSIEHOME} ] && [ -d ${OSSIEHOME}/share/aclocal/ossie ]; then - OSSIE_AC_INCLUDE=${OSSIEHOME}/share/aclocal/ossie -else - echo "Error: Cannot find the OSSIE aclocal files. This is not expected!" -fi - -if [ -n ${OSSIE_AC_INCLUDE} ]; then - aclocal -I ${OSSIE_AC_INCLUDE} -else - aclocal -fi - -autoconf -automake --foreign --add-missing - diff --git a/bulkioInterfaces/libsrc/testing/components/multiout_attachable/java/.md5sums b/bulkioInterfaces/libsrc/testing/components/multiout_attachable/java/.md5sums index 28e74c938..25538c424 100644 --- a/bulkioInterfaces/libsrc/testing/components/multiout_attachable/java/.md5sums +++ b/bulkioInterfaces/libsrc/testing/components/multiout_attachable/java/.md5sums @@ -3,4 +3,4 @@ c99df9fa4ab0cd042eac42fcee6441c3 reconf 9ec485b3eae2b94286c8b7a91eb6b645 configure.ac d6ed4ba3d1efb79c37961c7de007975b startJava.sh 20646b5bde62d405d38d41c3c15e95b7 src/multiout_attachable/java/multiout_attachable.java -8c165edc10e1cafc735199598bc76847 Makefile.am +956df491c9d35608c1e9c5732df5a16b Makefile.am diff --git a/bulkioInterfaces/libsrc/testing/components/multiout_attachable/java/Makefile.am b/bulkioInterfaces/libsrc/testing/components/multiout_attachable/java/Makefile.am index 872d778d1..ffd5715a9 100644 --- a/bulkioInterfaces/libsrc/testing/components/multiout_attachable/java/Makefile.am +++ b/bulkioInterfaces/libsrc/testing/components/multiout_attachable/java/Makefile.am @@ -17,17 +17,22 @@ # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see http://www.gnu.org/licenses/. # -multiout_attachable_jar_CLASSPATH = $(CLASSPATH_SOFTPKG_DEP)$(OSSIE_HOME)/lib/CFInterfaces.jar:$(OSSIE_HOME)/lib/log4j-1.2.15.jar:$(OSSIE_HOME)/lib/ossie.jar:$(bulkio_libsrc_top)/bulkio.jar:$(bulkio_top)/BULKIOInterfaces.jar +ACLOCAL_AMFLAGS = -I m4 -I${OSSIEHOME}/share/aclocal/ossie +AUTOMAKE_OPTIONS = subdir-objects + +multiout_attachable_jar_CLASSPATH = $(SOFTPKG_CLASSPATH):$(REDHAWK_CLASSPATH):$(BULKIO_CLASSPATH) multiout_attachable.jar$(EXEEXT): $(multiout_attachable_jar_SOURCES) mkdir -p bin - $(JAVAC) -cp $(multiout_attachable_jar_CLASSPATH) -d bin $(multiout_attachable_jar_SOURCES) + $(JAVAC) -cp $(multiout_attachable_jar_CLASSPATH) -g -d bin $(multiout_attachable_jar_SOURCES) $(JAR) cf ./multiout_attachable.jar -C bin . + $(JAR) uf ./multiout_attachable.jar -C src . clean-local: rm -rf bin distclean-local: + rm -rf m4 rm -f config.* rm -rf autom4te.cache rm -f acinclude.m4 @@ -45,12 +50,6 @@ bindir = $(prefix)/dom/components/multiout_attachable/java/ bin_PROGRAMS = multiout_attachable.jar multiout_attachable_jar_SOURCES := $(shell find ./src -name "*.java") -## -## This is used to build against local bulkio interface library and not installed version -## -bulkio_top=../../../../.. -bulkio_libsrc_top=$(bulkio_top)/libsrc - xmldir = $(prefix)/dom/components/multiout_attachable/ dist_xml_DATA = ../multiout_attachable.scd.xml ../multiout_attachable.prf.xml ../multiout_attachable.spd.xml diff --git a/bulkioInterfaces/libsrc/testing/components/multiout_attachable/java/configure.ac b/bulkioInterfaces/libsrc/testing/components/multiout_attachable/java/configure.ac deleted file mode 100644 index 510f5bccb..000000000 --- a/bulkioInterfaces/libsrc/testing/components/multiout_attachable/java/configure.ac +++ /dev/null @@ -1,49 +0,0 @@ -/* - * This file is protected by Copyright. Please refer to the COPYRIGHT file - * distributed with this source distribution. - * - * This file is part of REDHAWK bulkioInterfaces. - * - * REDHAWK bulkioInterfaces is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * REDHAWK bulkioInterfaces is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see http://www.gnu.org/licenses/. - */ -AC_INIT(multiout_attachable, 1.0.0) -AM_INIT_AUTOMAKE(nostdinc) - -AC_CORBA_ORB -OSSIE_CHECK_OSSIE -OSSIE_SDRROOT_AS_PREFIX - -export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig" -CLASSPATH_SOFTPKG_DEP="" -AC_SUBST(CLASSPATH_SOFTPKG_DEP) -PKG_CHECK_MODULES([OSSIE], [ossie >= 1.10]) - -AC_CHECK_PROG([IDLJ], [idlj], [idlj], [AC_MSG_ERROR([cannot find idlj program])]) -AC_CHECK_PROG([JAVAC], [javac], [javac], [AC_MSG_ERROR([cannot find Java compiler])]) -AC_CHECK_PROG([JAR], [jar], [jar], [AC_MSG_ERROR([cannot find jar program])]) - -AC_PATH_PROG(JAVAC, javac, [not found], [${JAVA_HOME}/bin]) -AC_PATH_PROG(JAVAH, javah, [not found], [${JAVA_HOME}/bin]) -AC_PATH_PROG(JAVA, java, [not found], [${JAVA_HOME}/bin]) -AC_PATH_PROG(JAR, jar, [not found], [${JAVA_HOME}/bin]) -AC_SUBST(JAVAC) -AC_SUBST(JAVAH) -AC_SUBST(JAR) -AC_SUBST(JAVA) - -export PKG_CONFIG_PATH="../../../..:../../..":$PKG_CONFIG_PATH -PKG_CHECK_MODULES([BIO], [bulkio >= 1.10]) - -AC_CONFIG_FILES(Makefile) -AC_OUTPUT diff --git a/bulkioInterfaces/libsrc/testing/components/multiout_attachable/java/reconf b/bulkioInterfaces/libsrc/testing/components/multiout_attachable/java/reconf deleted file mode 100755 index ba319ec54..000000000 --- a/bulkioInterfaces/libsrc/testing/components/multiout_attachable/java/reconf +++ /dev/null @@ -1,47 +0,0 @@ -#!/bin/sh -# -# This file is protected by Copyright. Please refer to the COPYRIGHT file -# distributed with this source distribution. -# -# This file is part of REDHAWK bulkioInterfaces. -# -# REDHAWK bulkioInterfaces is free software: you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation, either version 3 of the License, or (at your option) any -# later version. -# -# REDHAWK bulkioInterfaces is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more -# details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with this program. If not, see http://www.gnu.org/licenses/. -# - -rm -f config.cache - -# Setup the libtool stuff -if [ -e /usr/local/share/aclocal/libtool.m4 ]; then - /bin/cp /usr/local/share/aclocal/libtool.m4 aclocal.d/acinclude.m4 -elif [ -e /usr/share/aclocal/libtool.m4 ]; then - /bin/cp /usr/share/aclocal/libtool.m4 acinclude.m4 -fi -libtoolize --force --automake - -# Search in expected locations for the OSSIE acincludes -if [ -n ${OSSIEHOME} ] && [ -d ${OSSIEHOME}/share/aclocal/ossie ]; then - OSSIE_AC_INCLUDE=${OSSIEHOME}/share/aclocal/ossie -else - echo "Error: Cannot find the OSSIE aclocal files. This is not expected!" -fi - -if [ -n ${OSSIE_AC_INCLUDE} ]; then - aclocal -I ${OSSIE_AC_INCLUDE} -else - aclocal -fi - -autoconf -automake --foreign --add-missing - diff --git a/bulkioInterfaces/libsrc/testing/components/sri_changed_cpp/.md5sums b/bulkioInterfaces/libsrc/testing/components/sri_changed_cpp/.md5sums index 2fc8aa61f..54782304a 100644 --- a/bulkioInterfaces/libsrc/testing/components/sri_changed_cpp/.md5sums +++ b/bulkioInterfaces/libsrc/testing/components/sri_changed_cpp/.md5sums @@ -1,2 +1,2 @@ ad203121cc82e53a70d18fe05fb10cad sri_changed_cpp.spec -a9b4faa48de105491e9e2ec3e98c4e31 build.sh +78dbd56164ba142955871befa3fd1aca build.sh diff --git a/bulkioInterfaces/libsrc/testing/components/sri_changed_cpp/cpp/.md5sums b/bulkioInterfaces/libsrc/testing/components/sri_changed_cpp/cpp/.md5sums index 2aa9c15b9..2d005319c 100644 --- a/bulkioInterfaces/libsrc/testing/components/sri_changed_cpp/cpp/.md5sums +++ b/bulkioInterfaces/libsrc/testing/components/sri_changed_cpp/cpp/.md5sums @@ -4,7 +4,7 @@ c99df9fa4ab0cd042eac42fcee6441c3 reconf ae264440c7ce05f34ca3e62f86a41bee sri_changed_cpp_base.h be32db27e87a9c3e8d69629e4369789b sri_changed_cpp_base.cpp c3d08a91dc24cfede3ddf8b9035e1af9 configure.ac -0524e1037a2e8935e4923dfd9d588e8e Makefile.am +7974ec73e836992ee425ecece625d439 Makefile.am e1748f0f729341e18286dea4e4065da3 Makefile.am.ide 8ef82849c233a496d7bd4ae800a2195c sri_changed_cpp.h 0d1975802982b41325f73129696f8a63 build.sh diff --git a/bulkioInterfaces/libsrc/testing/components/sri_changed_cpp/cpp/Makefile.am b/bulkioInterfaces/libsrc/testing/components/sri_changed_cpp/cpp/Makefile.am index b9b33720c..3183a8acd 100644 --- a/bulkioInterfaces/libsrc/testing/components/sri_changed_cpp/cpp/Makefile.am +++ b/bulkioInterfaces/libsrc/testing/components/sri_changed_cpp/cpp/Makefile.am @@ -18,19 +18,16 @@ # along with this program. If not, see http://www.gnu.org/licenses/. # ossieName = sri_changed_cpp -bindir = $(prefix)/dom/components/sri_changed_cpp/cpp/ +bindir = $(prefix)/dom/components/sri_changed_cpp/cpp bin_PROGRAMS = sri_changed_cpp -xmldir = $(prefix)/dom/components/sri_changed_cpp/ +xmldir = $(prefix)/dom/components/sri_changed_cpp dist_xml_DATA = ../sri_changed_cpp.scd.xml ../sri_changed_cpp.prf.xml ../sri_changed_cpp.spd.xml ACLOCAL_AMFLAGS = -I m4 -I${OSSIEHOME}/share/aclocal/ossie - -# this is use to build against local bulkio interface and library and not installed version -bulkio_top=../../../../../ -bulkio_libsrc_top=$(bulkio_top)/libsrc +AUTOMAKE_OPTIONS = subdir-objects distclean-local: - rm -f m4/* + rm -rf m4 rm -f config.* rm -rf autom4te.cache rm -f acinclude.m4 @@ -49,8 +46,7 @@ distclean-local: # you wish to manually control these options. include $(srcdir)/Makefile.am.ide sri_changed_cpp_SOURCES = $(redhawk_SOURCES_auto) -sri_changed_cpp_LDADD = -L$(bulkio_libsrc_top)/.libs -L$(bulkio_top)/.libs $(BIO_LIBS) $(PROJECTDEPS_LIBS) $(BOOST_LDFLAGS) $(BOOST_THREAD_LIB) $(BOOST_REGEX_LIB) $(BOOST_SYSTEM_LIB) $(INTERFACEDEPS_LIBS) $(redhawk_LDADD_auto) -#sri_changed_cpp_CXXFLAGS = -Wall $(PROJECTDEPS_CFLAGS) $(BOOST_CPPFLAGS) $(INTERFACEDEPS_CFLAGS) $(redhawk_INCLUDES_auto) -sri_changed_cpp_CXXFLAGS = -Wall -I$(bulkio_libsrc_top)/cpp -I$(bulkio_top)/src/cpp -I$(bulkio_top)/src/cpp/ossie $(PROJECTDEPS_CFLAGS) $(BOOST_CPPFLAGS) $(RH_DEPS_CFLAGS) $(redhawk_INCLUDES_auto) +sri_changed_cpp_LDADD = $(SOFTPKG_LIBS) $(PROJECTDEPS_LIBS) $(BOOST_LDFLAGS) $(BOOST_THREAD_LIB) $(BOOST_REGEX_LIB) $(BOOST_SYSTEM_LIB) $(INTERFACEDEPS_LIBS) $(redhawk_LDADD_auto) +sri_changed_cpp_CXXFLAGS = -Wall $(SOFTPKG_CFLAGS) $(PROJECTDEPS_CFLAGS) $(BOOST_CPPFLAGS) $(INTERFACEDEPS_CFLAGS) $(redhawk_INCLUDES_auto) sri_changed_cpp_LDFLAGS = -Wall $(redhawk_LDFLAGS_auto) diff --git a/bulkioInterfaces/libsrc/testing/components/sri_changed_cpp/cpp/build.sh b/bulkioInterfaces/libsrc/testing/components/sri_changed_cpp/cpp/build.sh deleted file mode 100755 index 74e64498a..000000000 --- a/bulkioInterfaces/libsrc/testing/components/sri_changed_cpp/cpp/build.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/bin/sh -# -# This file is protected by Copyright. Please refer to the COPYRIGHT file -# distributed with this source distribution. -# -# This file is part of REDHAWK bulkioInterfaces. -# -# REDHAWK bulkioInterfaces is free software: you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation, either version 3 of the License, or (at your option) any -# later version. -# -# REDHAWK bulkioInterfaces is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more -# details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with this program. If not, see http://www.gnu.org/licenses/. -# - -# Create the Makefile if necessary -if [ ! -e Makefile ]; then - ./reconf - ./configure -fi - -make -j $* - diff --git a/bulkioInterfaces/libsrc/testing/components/sri_changed_cpp/cpp/configure.ac b/bulkioInterfaces/libsrc/testing/components/sri_changed_cpp/cpp/configure.ac deleted file mode 100644 index 7faedd0ec..000000000 --- a/bulkioInterfaces/libsrc/testing/components/sri_changed_cpp/cpp/configure.ac +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This file is protected by Copyright. Please refer to the COPYRIGHT file - * distributed with this source distribution. - * - * This file is part of REDHAWK bulkioInterfaces. - * - * REDHAWK bulkioInterfaces is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * REDHAWK bulkioInterfaces is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see http://www.gnu.org/licenses/. - */ -AC_INIT(sri_changed_cpp, 1.0.0) -AM_INIT_AUTOMAKE([nostdinc foreign]) - -AC_PROG_CC -AC_PROG_CXX -AC_PROG_INSTALL - -AC_CORBA_ORB -OSSIE_CHECK_OSSIE -OSSIE_SDRROOT_AS_PREFIX - -m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) - -# Dependencies -export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig" -PKG_CHECK_MODULES([PROJECTDEPS], [ossie >= 1.10 omniORB4 >= 4.1.0 ]) -OSSIE_ENABLE_LOG4CXX -AX_BOOST_BASE([1.41]) -AX_BOOST_SYSTEM -AX_BOOST_THREAD -AX_BOOST_REGEX - -export PKG_CONFIG_PATH="../../../..:../../..":$PKG_CONFIG_PATH -PKG_CHECK_MODULES([INTERFACEDEPS], [bulkio >= 1.10]) - -AC_CONFIG_FILES([Makefile]) -AC_OUTPUT - diff --git a/bulkioInterfaces/libsrc/testing/components/sri_changed_cpp/cpp/m4/.gitignore b/bulkioInterfaces/libsrc/testing/components/sri_changed_cpp/cpp/m4/.gitignore deleted file mode 100644 index 0f4126cd6..000000000 --- a/bulkioInterfaces/libsrc/testing/components/sri_changed_cpp/cpp/m4/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.m4 diff --git a/bulkioInterfaces/libsrc/testing/components/sri_changed_cpp/cpp/reconf b/bulkioInterfaces/libsrc/testing/components/sri_changed_cpp/cpp/reconf deleted file mode 100755 index ece304047..000000000 --- a/bulkioInterfaces/libsrc/testing/components/sri_changed_cpp/cpp/reconf +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/sh -# -# This file is protected by Copyright. Please refer to the COPYRIGHT file -# distributed with this source distribution. -# -# This file is part of REDHAWK bulkioInterfaces. -# -# REDHAWK bulkioInterfaces is free software: you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation, either version 3 of the License, or (at your option) any -# later version. -# -# REDHAWK bulkioInterfaces is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more -# details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with this program. If not, see http://www.gnu.org/licenses/. -# - -rm -f config.cache -autoreconf -i diff --git a/bulkioInterfaces/libsrc/testing/components/sri_changed_cpp/sri_changed_cpp.spec b/bulkioInterfaces/libsrc/testing/components/sri_changed_cpp/sri_changed_cpp.spec deleted file mode 100644 index b0a4d9446..000000000 --- a/bulkioInterfaces/libsrc/testing/components/sri_changed_cpp/sri_changed_cpp.spec +++ /dev/null @@ -1,87 +0,0 @@ -# -# This file is protected by Copyright. Please refer to the COPYRIGHT file -# distributed with this source distribution. -# -# This file is part of REDHAWK bulkioInterfaces. -# -# REDHAWK bulkioInterfaces is free software: you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation, either version 3 of the License, or (at your option) any -# later version. -# -# REDHAWK bulkioInterfaces is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more -# details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with this program. If not, see http://www.gnu.org/licenses/. -# -# By default, the RPM will install to the standard REDHAWK SDR root location (/var/redhawk/sdr) -# You can override this at install time using --prefix /new/sdr/root when invoking rpm (preferred method, if you must) -%{!?_sdrroot: %define _sdrroot /var/redhawk/sdr} -%define _prefix %{_sdrroot} -Prefix: %{_prefix} - -# Point install paths to locations within our target SDR root -%define _sysconfdir %{_prefix}/etc -%define _localstatedir %{_prefix}/var -%define _mandir %{_prefix}/man -%define _infodir %{_prefix}/info - -Name: sri_changed_cpp -Version: 1.0.0 -Release: 1%{?dist} -Summary: Component %{name} - -Group: REDHAWK/Components -License: None -Source0: %{name}-%{version}.tar.gz -BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) - -BuildRequires: redhawk-devel >= 1.10 -Requires: redhawk >= 1.10 - -# Interface requirements -BuildRequires: bulkioInterfaces >= 1.10 -Requires: bulkioInterfaces >= 1.10 - -%description -Component %{name} - - -%prep -%setup -q - - -%build -# Implementation cpp -pushd cpp -./reconf -%define _bindir %{_prefix}/dom/components/sri_changed_cpp/cpp -%configure -make %{?_smp_mflags} -popd - - -%install -rm -rf $RPM_BUILD_ROOT -# Implementation cpp -pushd cpp -%define _bindir %{_prefix}/dom/components/sri_changed_cpp/cpp -make install DESTDIR=$RPM_BUILD_ROOT -popd - - -%clean -rm -rf $RPM_BUILD_ROOT - - -%files -%defattr(-,redhawk,redhawk,-) -%dir %{_prefix}/dom/components/%{name} -%{_prefix}/dom/components/%{name}/sri_changed_cpp.scd.xml -%{_prefix}/dom/components/%{name}/sri_changed_cpp.prf.xml -%{_prefix}/dom/components/%{name}/sri_changed_cpp.spd.xml -%{_prefix}/dom/components/%{name}/cpp - diff --git a/bulkioInterfaces/libsrc/testing/devices/dev_snk/java/.md5sums b/bulkioInterfaces/libsrc/testing/devices/dev_snk/java/.md5sums new file mode 100644 index 000000000..874074737 --- /dev/null +++ b/bulkioInterfaces/libsrc/testing/devices/dev_snk/java/.md5sums @@ -0,0 +1 @@ +3d284eeeddf792b62e329376caeee0df Makefile.am diff --git a/bulkioInterfaces/libsrc/testing/devices/dev_snk/java/Makefile.am b/bulkioInterfaces/libsrc/testing/devices/dev_snk/java/Makefile.am index f9269d097..bf1cc60d6 100644 --- a/bulkioInterfaces/libsrc/testing/devices/dev_snk/java/Makefile.am +++ b/bulkioInterfaces/libsrc/testing/devices/dev_snk/java/Makefile.am @@ -20,7 +20,7 @@ ACLOCAL_AMFLAGS = -I m4 -I${OSSIEHOME}/share/aclocal/ossie AUTOMAKE_OPTIONS = subdir-objects -dev_snk_jar_CLASSPATH = $(SOFTPKG_CLASSPATH):$(REDHAWK_CLASSPATH):$(OSSIE_HOME)/lib/bulkio.jar:$(OSSIE_HOME)/lib/BULKIOInterfaces.jar +dev_snk_jar_CLASSPATH = $(SOFTPKG_CLASSPATH):$(REDHAWK_CLASSPATH):$(BULKIO_CLASSPATH) dev_snk.jar$(EXEEXT): $(dev_snk_jar_SOURCES) mkdir -p bin diff --git a/bulkioInterfaces/libsrc/testing/devices/dev_snk/java/configure.ac b/bulkioInterfaces/libsrc/testing/devices/dev_snk/java/configure.ac deleted file mode 100644 index 26b215e54..000000000 --- a/bulkioInterfaces/libsrc/testing/devices/dev_snk/java/configure.ac +++ /dev/null @@ -1,37 +0,0 @@ -# -# This file is protected by Copyright. Please refer to the COPYRIGHT file -# distributed with this source distribution. -# -# This file is part of REDHAWK bulkioInterfaces. -# -# REDHAWK bulkioInterfaces is free software: you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation, either version 3 of the License, or (at your option) any -# later version. -# -# REDHAWK bulkioInterfaces is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more -# details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with this program. If not, see http://www.gnu.org/licenses/. -# -AC_INIT(dev_snk, 1.0.0) -AM_INIT_AUTOMAKE([nostdinc foreign]) -AC_CONFIG_MACRO_DIR([m4]) - -OSSIE_CHECK_OSSIE -OSSIE_SDRROOT_AS_PREFIX - -PKG_CHECK_MODULES([OSSIE], [ossie >= 2.0]) - -RH_JAVA_HOME -RH_PROG_JAVAC([1.8]) -RH_PROG_JAR - -RH_PKG_CLASSPATH([REDHAWK], [ossie]) -PKG_CHECK_MODULES([INTERFACEDEPS], [bulkio >= 2.0]) - -AC_CONFIG_FILES([Makefile]) -AC_OUTPUT diff --git a/bulkioInterfaces/libsrc/testing/devices/dev_snk/java/reconf b/bulkioInterfaces/libsrc/testing/devices/dev_snk/java/reconf deleted file mode 100755 index 03a46fa0f..000000000 --- a/bulkioInterfaces/libsrc/testing/devices/dev_snk/java/reconf +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/sh -# -# This file is protected by Copyright. Please refer to the COPYRIGHT file -# distributed with this source distribution. -# -# This file is part of REDHAWK bulkioInterfaces. -# -# REDHAWK bulkioInterfaces is free software: you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation, either version 3 of the License, or (at your option) any -# later version. -# -# REDHAWK bulkioInterfaces is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more -# details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with this program. If not, see http://www.gnu.org/licenses/. -# - -rm -f config.cache -[ -d m4 ] || mkdir m4 -autoreconf -i - diff --git a/bulkioInterfaces/libsrc/testing/devices/dev_src/build.sh b/bulkioInterfaces/libsrc/testing/devices/dev_src/build.sh deleted file mode 100755 index 46ebbef8c..000000000 --- a/bulkioInterfaces/libsrc/testing/devices/dev_src/build.sh +++ /dev/null @@ -1,63 +0,0 @@ -#!/bin/bash -# -# This file is protected by Copyright. Please refer to the COPYRIGHT file -# distributed with this source distribution. -# -# This file is part of REDHAWK bulkioInterfaces. -# -# REDHAWK bulkioInterfaces is free software: you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation, either version 3 of the License, or (at your option) any -# later version. -# -# REDHAWK bulkioInterfaces is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more -# details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with this program. If not, see http://www.gnu.org/licenses/. -# - -if [ "$1" = "rpm" ]; then - # A very simplistic RPM build scenario - if [ -e dev_src.spec ]; then - mydir=`dirname $0` - tmpdir=`mktemp -d` - cp -r ${mydir} ${tmpdir}/dev_src-1.0.0 - tar czf ${tmpdir}/dev_src-1.0.0.tar.gz --exclude=".svn" -C ${tmpdir} dev_src-1.0.0 - rpmbuild -ta ${tmpdir}/dev_src-1.0.0.tar.gz - rm -rf $tmpdir - else - echo "Missing RPM spec file in" `pwd` - exit 1 - fi -else - for impl in java ; do - if [ ! -d "$impl" ]; then - echo "Directory '$impl' does not exist...continuing" - continue - fi - cd $impl - if [ -e build.sh ]; then - if [ $# == 1 ]; then - if [ $1 == 'clean' ]; then - rm -f Makefile - rm -f config.* - ./build.sh distclean - else - ./build.sh $* - fi - else - ./build.sh $* - fi - elif [ -e Makefile ] && [ Makefile.am -ot Makefile ]; then - make $* - elif [ -e reconf ]; then - ./reconf && ./configure && make $* - else - echo "No build.sh found for $impl" - fi - cd - - done -fi diff --git a/bulkioInterfaces/libsrc/testing/devices/dev_src/java/.md5sums b/bulkioInterfaces/libsrc/testing/devices/dev_src/java/.md5sums new file mode 100644 index 000000000..98780807a --- /dev/null +++ b/bulkioInterfaces/libsrc/testing/devices/dev_src/java/.md5sums @@ -0,0 +1 @@ +0245698762351f18b66f77d7e1330660 Makefile.am diff --git a/bulkioInterfaces/libsrc/testing/devices/dev_src/java/Makefile.am b/bulkioInterfaces/libsrc/testing/devices/dev_src/java/Makefile.am index a2d463ed5..60cb36526 100644 --- a/bulkioInterfaces/libsrc/testing/devices/dev_src/java/Makefile.am +++ b/bulkioInterfaces/libsrc/testing/devices/dev_src/java/Makefile.am @@ -20,7 +20,7 @@ ACLOCAL_AMFLAGS = -I m4 -I${OSSIEHOME}/share/aclocal/ossie AUTOMAKE_OPTIONS = subdir-objects -dev_src_jar_CLASSPATH = $(SOFTPKG_CLASSPATH):$(REDHAWK_CLASSPATH):$(OSSIE_HOME)/lib/bulkio.jar:$(OSSIE_HOME)/lib/BULKIOInterfaces.jar +dev_src_jar_CLASSPATH = $(SOFTPKG_CLASSPATH):$(REDHAWK_CLASSPATH):$(BULKIO_CLASSPATH) dev_src.jar$(EXEEXT): $(dev_src_jar_SOURCES) mkdir -p bin diff --git a/bulkioInterfaces/libsrc/testing/devices/dev_src/java/configure.ac b/bulkioInterfaces/libsrc/testing/devices/dev_src/java/configure.ac deleted file mode 100644 index ca12d85b4..000000000 --- a/bulkioInterfaces/libsrc/testing/devices/dev_src/java/configure.ac +++ /dev/null @@ -1,37 +0,0 @@ -# -# This file is protected by Copyright. Please refer to the COPYRIGHT file -# distributed with this source distribution. -# -# This file is part of REDHAWK bulkioInterfaces. -# -# REDHAWK bulkioInterfaces is free software: you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation, either version 3 of the License, or (at your option) any -# later version. -# -# REDHAWK bulkioInterfaces is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more -# details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with this program. If not, see http://www.gnu.org/licenses/. -# -AC_INIT(dev_src, 1.0.0) -AM_INIT_AUTOMAKE([nostdinc foreign]) -AC_CONFIG_MACRO_DIR([m4]) - -OSSIE_CHECK_OSSIE -OSSIE_SDRROOT_AS_PREFIX - -PKG_CHECK_MODULES([OSSIE], [ossie >= 2.0]) - -RH_JAVA_HOME -RH_PROG_JAVAC([1.8]) -RH_PROG_JAR - -RH_PKG_CLASSPATH([REDHAWK], [ossie]) -PKG_CHECK_MODULES([INTERFACEDEPS], [bulkio >= 2.0]) - -AC_CONFIG_FILES([Makefile]) -AC_OUTPUT diff --git a/bulkioInterfaces/libsrc/testing/devices/dev_src/java/reconf b/bulkioInterfaces/libsrc/testing/devices/dev_src/java/reconf deleted file mode 100755 index 03a46fa0f..000000000 --- a/bulkioInterfaces/libsrc/testing/devices/dev_src/java/reconf +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/sh -# -# This file is protected by Copyright. Please refer to the COPYRIGHT file -# distributed with this source distribution. -# -# This file is part of REDHAWK bulkioInterfaces. -# -# REDHAWK bulkioInterfaces is free software: you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation, either version 3 of the License, or (at your option) any -# later version. -# -# REDHAWK bulkioInterfaces is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more -# details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with this program. If not, see http://www.gnu.org/licenses/. -# - -rm -f config.cache -[ -d m4 ] || mkdir m4 -autoreconf -i - diff --git a/bulkioInterfaces/libsrc/testing/tests/buildtests b/bulkioInterfaces/libsrc/testing/tests/buildtests index 4ef5f38be..1f849361d 100755 --- a/bulkioInterfaces/libsrc/testing/tests/buildtests +++ b/bulkioInterfaces/libsrc/testing/tests/buildtests @@ -1,60 +1,5 @@ # # Build supporting components for bulkio test framework # - -bulkio_top=../../../ -bulkio_libsrc_top=$bulkio_top/libsrc -export LD_LIBRARY_PATH=$bulkio_libsrc_top/.libs:$bulkio_top/.libs:${LD_LIBRARY_PATH} -export PYTHONPATH=$bulkio_libsrc_top/build/lib:${PYTHONPATH} - -cd ../components/CPP_Ports/cpp -./reconf; ./configure; make -j -cd - - -cd ../components/sri_changed_cpp/cpp -./reconf; ./configure; make -j -cd - - -cd ../components/Java_Ports/java -./reconf; ./configure; make -cd - - -cd ../components/Python_Ports/python -./reconf; ./configure; make -cd - - -cd ../components/TestLargePush/cpp -./reconf; ./configure; make -j -cd - - -cd ../components/TestLargePush/java -./reconf; ./configure; make -cd - - -cd ../components/TestLargePush/python -./reconf; ./configure; make -cd - - -cd ../components/multiout_attachable/cpp -./reconf; ./configure; make -j -cd - - -cd ../components/multiout_attachable/java -./reconf; ./configure; make -cd - - -cd ../components/Oversized_framedata/cpp -./reconf; ./configure; make -j -cd - - -cd ../components/Oversized_framedata/java -./reconf; ./configure; make -cd - - -cd ../devices/dev_src/java -./reconf; ./configure; make -cd - - -cd ../devices/dev_snk/java -./reconf; ./configure; make -cd - +echo >&2 "$(basename $0) is deprecated; use 'make' in testing directory" +(cd .. && make -j) From 57a9eabc5866d93d366282eafb5f9fadb70ca575 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 25 Jan 2017 11:05:41 -0500 Subject: [PATCH 0660/1644] Add C++ unit tests for BulkIO output streams --- .../libsrc/testing/tests/cpp/InPortStub.h | 115 ++++ .../libsrc/testing/tests/cpp/Makefile.am | 1 + .../testing/tests/cpp/OutStreamTest.cpp | 544 ++++++++++++++++++ .../libsrc/testing/tests/cpp/OutStreamTest.h | 100 ++++ 4 files changed, 760 insertions(+) create mode 100644 bulkioInterfaces/libsrc/testing/tests/cpp/InPortStub.h create mode 100644 bulkioInterfaces/libsrc/testing/tests/cpp/OutStreamTest.cpp create mode 100644 bulkioInterfaces/libsrc/testing/tests/cpp/OutStreamTest.h diff --git a/bulkioInterfaces/libsrc/testing/tests/cpp/InPortStub.h b/bulkioInterfaces/libsrc/testing/tests/cpp/InPortStub.h new file mode 100644 index 000000000..baf33b12a --- /dev/null +++ b/bulkioInterfaces/libsrc/testing/tests/cpp/InPortStub.h @@ -0,0 +1,115 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK bulkioInterfaces. + * + * REDHAWK bulkioInterfaces is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK bulkioInterfaces is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ +#ifndef BULKIO_INPORTSTUB_H +#define BULKIO_INPORTSTUB_H + +#include "bulkio.h" + +template +class InPortStubBase : public virtual bulkio::CorbaTraits::POAType +{ +public: + InPortStubBase() : + sriCounter(0), + packetCounter(0) + { + } + + virtual void pushSRI(const BULKIO::StreamSRI& H) + { + this->H = H; + ++sriCounter; + } + + virtual BULKIO::PortUsageType state() + { + return BULKIO::IDLE; + } + + virtual BULKIO::PortStatistics* statistics() + { + return new BULKIO::PortStatistics(); + } + + virtual BULKIO::StreamSRISequence* activeSRIs() + { + return new BULKIO::StreamSRISequence(); + } + + BULKIO::StreamSRI H; + int sriCounter; + + BULKIO::PrecisionUTCTime T; + bool EOS; + std::string streamID; + int packetCounter; + +protected: + void _push(const BULKIO::PrecisionUTCTime& T, CORBA::Boolean EOS, const char* streamID) + { + this->T = T; + this->EOS = EOS; + this->streamID = streamID; + this->packetCounter++; + } +}; + +template +class InPortStub : public InPortStubBase +{ +public: + typedef typename bulkio::CorbaTraits::SequenceType SequenceType; + + virtual void pushPacket(const SequenceType& data, const BULKIO::PrecisionUTCTime& T, CORBA::Boolean EOS, const char* streamID) + { + this->data = data; + this->_push(T, EOS, streamID); + } + + SequenceType data; +}; + +template <> +class InPortStub : public InPortStubBase +{ +public: + virtual void pushPacket(const char* data, CORBA::Boolean EOS, const char* streamID) + { + this->data = data; + this->_push(bulkio::time::utils::notSet(), EOS, streamID); + } + + std::string data; +}; + +template <> +class InPortStub : public InPortStubBase +{ +public: + virtual void pushPacket(const char* data, const BULKIO::PrecisionUTCTime& T, CORBA::Boolean EOS, const char* streamID) + { + this->data = data; + this->_push(T, EOS, streamID); + } + + std::string data; +}; + +#endif // BULKIO_INPORTSTUB_H diff --git a/bulkioInterfaces/libsrc/testing/tests/cpp/Makefile.am b/bulkioInterfaces/libsrc/testing/tests/cpp/Makefile.am index 487204e4e..93ffb26a3 100644 --- a/bulkioInterfaces/libsrc/testing/tests/cpp/Makefile.am +++ b/bulkioInterfaces/libsrc/testing/tests/cpp/Makefile.am @@ -23,5 +23,6 @@ check_PROGRAMS = $(TESTS) Bulkio_SOURCES = Bulkio.cpp Bulkio_Helper_Fixture.cpp Bulkio_InPort_Fixture.cpp Bulkio_OutPort_Fixture.cpp Bulkio_MultiOut_Port.cpp Bulkio_SOURCES += InStreamTest.h InStreamTest.cpp +Bulkio_SOURCES += OutStreamTest.h OutStreamTest.cpp Bulkio_CXXFLAGS = $(BULKIO_CFLAGS) $(BOOST_CPPFLAGS) $(OSSIE_CFLAGS) $(CPPUNIT_CFLAGS) Bulkio_LDADD = $(BULKIO_LIBS) $(BOOST_LDFLAGS) $(BOOST_SYSTEM_LIB) $(OSSIE_LIBS) $(CPPUNIT_LIBS) $(LOG4CXX_LIBS) diff --git a/bulkioInterfaces/libsrc/testing/tests/cpp/OutStreamTest.cpp b/bulkioInterfaces/libsrc/testing/tests/cpp/OutStreamTest.cpp new file mode 100644 index 000000000..3f43addc0 --- /dev/null +++ b/bulkioInterfaces/libsrc/testing/tests/cpp/OutStreamTest.cpp @@ -0,0 +1,544 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK bulkioInterfaces. + * + * REDHAWK bulkioInterfaces is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK bulkioInterfaces is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +#include "OutStreamTest.h" + +#include +#include "bulkio.h" + +template +void OutStreamTest::setUp() +{ + ossie::corba::CorbaInit(0,0); + + std::string name = "data" + getPortName() + "_out"; + port = new OutPort(name); + + stub = new InPortStub(); + PortableServer::ObjectId_var oid = ossie::corba::RootPOA()->activate_object(stub); + + CORBA::Object_var objref = stub->_this(); + port->connectPort(objref, "test_connection"); +} + +template +void OutStreamTest::tearDown() +{ + port->disconnectPort("test_connection"); + + delete port; + + try { + PortableServer::ObjectId_var oid = ossie::corba::RootPOA()->servant_to_id(stub); + ossie::corba::RootPOA()->deactivate_object(oid); + } catch (...) { + // Ignore CORBA exceptions + } + stub->_remove_ref(); +} + +template +void OutStreamTest::testOperators() +{ + StreamType null_stream; + CPPUNIT_ASSERT(!null_stream); + if (null_stream) { + // This check is structured as an if/else to avoid using operator! + CPPUNIT_FAIL("Null stream evaluted to true"); + } + CPPUNIT_ASSERT(null_stream == StreamType()); + + // Create a new stream + StreamType good_stream = port->createStream("test_operators"); + CPPUNIT_ASSERT_EQUAL(false, !good_stream); + if (good_stream) { + // This check is structured as an if/else because CppUnit's assert + // macro implicitly uses operator! + } else { + CPPUNIT_FAIL("Valid stream evaluated to false"); + } + CPPUNIT_ASSERT(good_stream != null_stream); + + // Get another handle to the same stream, should be equal + StreamType same_stream = port->getStream("test_operators"); + CPPUNIT_ASSERT(same_stream == good_stream); + + // Create a new stream, should not be equal + StreamType other_stream = port->createStream("test_operators_2"); + CPPUNIT_ASSERT(other_stream != good_stream); +} + +template +void OutStreamTest::testBasicWrite() +{ + StreamType stream = port->createStream("test_basic_write"); + CPPUNIT_ASSERT(stub->packetCounter == 0); + + const BULKIO::PrecisionUTCTime time = bulkio::time::utils::now(); + _writeSinglePacket(stream, 256, time); + CPPUNIT_ASSERT(stub->packetCounter == 1); + CPPUNIT_ASSERT_EQUAL((size_t) 256, (size_t) stub->data.length()); + CPPUNIT_ASSERT(!stub->EOS); + if (_hasTimestamp()) { + CPPUNIT_ASSERT_EQUAL(time, stub->T); + } + CPPUNIT_ASSERT_EQUAL(stream.streamID(), stub->streamID); +} + +template +void OutStreamTest::testSriFields() +{ + BULKIO::StreamSRI sri = bulkio::sri::create("test_sri"); + sri.xstart = -2.5; + sri.xdelta = 0.125; + sri.xunits = BULKIO::UNITS_FREQUENCY; + sri.subsize = 1024; + sri.ystart = 2.5; + sri.ydelta = 1.0; + sri.yunits = BULKIO::UNITS_TIME; + sri.mode = 1; + sri.blocking = 1; + ossie::corba::push_back(sri.keywords, redhawk::PropertyType("string", "value")); + ossie::corba::push_back(sri.keywords, redhawk::PropertyType("number", 100)); + + // Create a stream from the SRI; assign to a const variable to ensure that + // all accessors are const-safe + const StreamType stream = port->createStream(sri); + CPPUNIT_ASSERT(stream.streamID() == (const char*) sri.streamID); + CPPUNIT_ASSERT(stream.xstart() == sri.xstart); + CPPUNIT_ASSERT(stream.xdelta() == sri.xdelta); + CPPUNIT_ASSERT(stream.xunits() == sri.xunits); + CPPUNIT_ASSERT(stream.subsize() == sri.subsize); + CPPUNIT_ASSERT(stream.ystart() == sri.ystart); + CPPUNIT_ASSERT(stream.ydelta() == sri.ydelta); + CPPUNIT_ASSERT(stream.yunits() == sri.yunits); + CPPUNIT_ASSERT(stream.complex()); + CPPUNIT_ASSERT(stream.blocking()); + CPPUNIT_ASSERT(sri.keywords.length() == stream.keywords().size()); + CPPUNIT_ASSERT_EQUAL(std::string("value"), stream.getKeyword("string").toString()); + CPPUNIT_ASSERT_EQUAL((CORBA::Long) 100, stream.getKeyword("number").toLong()); +} + +template +void OutStreamTest::testSriUpdate() +{ + // Create initial stream; all changes should be queued up for the first + // write + StreamType stream = port->createStream("test_sri_update"); + double xdelta = 1.0 / 1.25e6; + stream.xdelta(xdelta); + stream.blocking(true); + CPPUNIT_ASSERT(stub->sriCounter == 0); + + // Write data to trigger initial SRI update + _writeSinglePacket(stream, 10); + CPPUNIT_ASSERT(stub->sriCounter == 1); + CPPUNIT_ASSERT(stub->H.blocking); + CPPUNIT_ASSERT_EQUAL(xdelta, stub->H.xdelta); + + // Update xdelta; no SRI update should occur + double new_xdelta = 1.0/2.5e6; + stream.xdelta(new_xdelta); + CPPUNIT_ASSERT(stub->sriCounter == 1); + CPPUNIT_ASSERT_EQUAL(xdelta, stub->H.xdelta); + + // Write data to trigger SRI update + _writeSinglePacket(stream, 25); + CPPUNIT_ASSERT(stub->sriCounter == 2); + CPPUNIT_ASSERT_EQUAL(new_xdelta, stub->H.xdelta); + + // Change blocking flag, then trigger an SRI update + stream.blocking(false); + CPPUNIT_ASSERT(stub->sriCounter == 2); + CPPUNIT_ASSERT(stub->H.blocking); + _writeSinglePacket(stream, 25); + CPPUNIT_ASSERT(stub->sriCounter == 3); + CPPUNIT_ASSERT(!stub->H.blocking); + + // Change multiple fields, but only one SRI update should occur (after the + // next write) + stream.complex(true); + stream.subsize(16); + stream.xstart(-M_PI); + stream.xdelta(2.0 * M_PI / 1024.0); + stream.xunits(BULKIO::UNITS_FREQUENCY); + stream.ydelta(1024.0 / 1.25e6); + stream.yunits(BULKIO::UNITS_TIME); + CPPUNIT_ASSERT(stub->sriCounter == 3); + + // Trigger SRI update and verify that it matches + _writeSinglePacket(stream, 1024); + CPPUNIT_ASSERT(stub->sriCounter == 4); + CPPUNIT_ASSERT(bulkio::sri::DefaultComparator(stream.sri(), stub->H)); +} + +template +void OutStreamTest::testKeywords() +{ + StreamType stream = port->createStream("test_keywords"); + _writeSinglePacket(stream, 1); + CPPUNIT_ASSERT(stub->sriCounter == 1); + + // Set/get keywords + stream.setKeyword("integer", 250); + stream.setKeyword("string", "value"); + stream.setKeyword("double", 101.1e6); + stream.setKeyword("boolean", false); + CPPUNIT_ASSERT_EQUAL((CORBA::Long) 250, stream.getKeyword("integer").toLong()); + CPPUNIT_ASSERT_EQUAL(std::string("value"), stream.getKeyword("string").toString()); + CPPUNIT_ASSERT_EQUAL(101.1e6, stream.getKeyword("double").toDouble()); + CPPUNIT_ASSERT(!stream.getKeyword("boolean").toBoolean()); + + // Erase and check for presence of keywords + stream.eraseKeyword("string"); + CPPUNIT_ASSERT(stream.hasKeyword("integer")); + CPPUNIT_ASSERT(!stream.hasKeyword("string")); + CPPUNIT_ASSERT(stream.hasKeyword("double")); + CPPUNIT_ASSERT(stream.hasKeyword("boolean")); + + // Write a packet to trigger an SRI update + CPPUNIT_ASSERT(stub->sriCounter == 1); + _writeSinglePacket(stream, 1); + CPPUNIT_ASSERT(stub->sriCounter == 2); + { + const redhawk::PropertyMap& keywords = redhawk::PropertyMap::cast(stub->H.keywords); + CPPUNIT_ASSERT_EQUAL(stream.keywords().size(), keywords.size()); + CPPUNIT_ASSERT_EQUAL(stream.getKeyword("integer").toLong(), keywords.get("integer").toLong()); + CPPUNIT_ASSERT_EQUAL(stream.getKeyword("double").toDouble(), keywords.get("double").toDouble()); + CPPUNIT_ASSERT_EQUAL(stream.getKeyword("boolean").toBoolean(), keywords.get("boolean").toBoolean()); + } + + // Replace keywords with a new set + redhawk::PropertyMap new_keywords; + new_keywords["COL_RF"] = 100.0e6; + new_keywords["CHAN_RF"] = 101.1e6; + stream.keywords(new_keywords); + CPPUNIT_ASSERT_EQUAL((size_t) 2, stream.keywords().size()); + CPPUNIT_ASSERT_EQUAL(100.0e6, stream.getKeyword("COL_RF").toDouble()); + CPPUNIT_ASSERT_EQUAL(101.1e6, stream.getKeyword("CHAN_RF").toDouble()); + + // Trigger another SRI update + CPPUNIT_ASSERT(stub->sriCounter == 2); + _writeSinglePacket(stream, 1); + CPPUNIT_ASSERT(stub->sriCounter == 3); + { + const redhawk::PropertyMap& keywords = redhawk::PropertyMap::cast(stub->H.keywords); + CPPUNIT_ASSERT_EQUAL(stream.keywords().size(), keywords.size()); + CPPUNIT_ASSERT_EQUAL(stream.getKeyword("COL_RF").toDouble(), keywords.get("COL_RF").toDouble()); + CPPUNIT_ASSERT_EQUAL(stream.getKeyword("COL_RF").toDouble(), keywords.get("COL_RF").toDouble()); + } +} + +template +void OutStreamTest::testSendEosOnClose() +{ + StreamType stream = port->createStream("close_eos"); + + CPPUNIT_ASSERT(stub->sriCounter == 0); + CPPUNIT_ASSERT(stub->packetCounter == 0); + + _writeSinglePacket(stream, 16); + + CPPUNIT_ASSERT(stub->sriCounter == 1); + CPPUNIT_ASSERT(stub->packetCounter == 1); + CPPUNIT_ASSERT(!stub->EOS); + + stream.close(); + CPPUNIT_ASSERT(stub->packetCounter == 2); + CPPUNIT_ASSERT(stub->EOS); +} + +template +void OutStreamTest::_writeSinglePacket(StreamType& stream, size_t size, + const BULKIO::PrecisionUTCTime& time) +{ + typedef typename StreamType::ScalarType ScalarType; + std::vector buffer; + buffer.resize(size); + stream.write(buffer, time); +} + +template +bool OutStreamTest::_hasTimestamp() +{ + return true; +} + +// Specialization for dataFile, which uses std::string +template <> +void OutStreamTest::_writeSinglePacket(StreamType& stream, size_t size, + const BULKIO::PrecisionUTCTime& time) +{ + std::string url(size, 'F'); + stream.write(url, time); +} + +// Specializations for dataXML, which uses std::string and does not include a +// timestamp +template <> +void OutStreamTest::_writeSinglePacket(StreamType& stream, size_t size, + const BULKIO::PrecisionUTCTime& /*unused*/) +{ + std::string xml(size, 'X'); + stream.write(xml); +} + +template <> +bool OutStreamTest::_hasTimestamp() +{ + return false; +} + + +template +void BufferedOutStreamTest::testBufferedWrite() +{ + // Initial state is unbuffered; turn on buffering + StreamType stream = port->createStream("test_buffered_write"); + CPPUNIT_ASSERT_EQUAL((size_t) 0, stream.bufferSize()); + stream.setBufferSize(128); + CPPUNIT_ASSERT_EQUAL((size_t) 128, stream.bufferSize()); + CPPUNIT_ASSERT(stub->packetCounter == 0); + + // First write is below the buffer size + std::vector buffer; + buffer.resize(48); + stream.write(buffer, bulkio::time::utils::now()); + CPPUNIT_ASSERT(stub->packetCounter == 0); + + // The second write is still below the buffer size + stream.write(buffer, bulkio::time::utils::now()); + CPPUNIT_ASSERT(stub->packetCounter == 0); + + // The third write goes beyond the buffer size and should trigger a push, + // but only up to the buffer size (48*3 == 144) + stream.write(buffer, bulkio::time::utils::now()); + CPPUNIT_ASSERT(stub->packetCounter == 1); + CPPUNIT_ASSERT_EQUAL(stream.bufferSize(), (size_t) stub->data.length()); + + // There should now be 16 samples in the queue; writing another 48 should + // not trigger a push + stream.write(buffer, bulkio::time::utils::now()); + CPPUNIT_ASSERT(stub->packetCounter == 1); + + // Flush the stream and make sure we get as many samples as expected + stream.flush(); + CPPUNIT_ASSERT(stub->packetCounter == 2); + CPPUNIT_ASSERT_EQUAL((CORBA::ULong) 64, stub->data.length()); + + // Disable buffering; push should happen immediately + stream.setBufferSize(0); + stream.write(buffer, bulkio::time::utils::now()); + CPPUNIT_ASSERT(stub->packetCounter == 3); +} + +template +void BufferedOutStreamTest::testWriteSkipBuffer() +{ + // Turn on buffering + StreamType stream = port->createStream("test_skip_buffer"); + stream.setBufferSize(100); + + // With an empty queue, large write should go right through + std::vector buffer; + buffer.resize(256); + stream.write(buffer, bulkio::time::utils::now()); + CPPUNIT_ASSERT(stub->packetCounter == 1); + CPPUNIT_ASSERT_EQUAL(buffer.size(), (size_t) stub->data.length()); + + // Queue up a bit of data + buffer.resize(16); + stream.write(buffer, bulkio::time::utils::now()); + CPPUNIT_ASSERT(stub->packetCounter == 1); + + // With queued data, the large write should get broken up into a buffer- + // sized packet + buffer.resize(128); + stream.write(buffer, bulkio::time::utils::now()); + CPPUNIT_ASSERT(stub->packetCounter == 2); + CPPUNIT_ASSERT_EQUAL(stream.bufferSize(), (size_t) stub->data.length()); +} + +template +void BufferedOutStreamTest::testFlush() +{ + // Turn on buffering + StreamType stream = port->createStream("test_flush"); + stream.setBufferSize(64); + + // Queue data (should not flush) + std::vector buffer; + buffer.resize(48); + stream.write(buffer, bulkio::time::utils::now()); + CPPUNIT_ASSERT(stub->sriCounter == 0); + CPPUNIT_ASSERT(stub->packetCounter == 0); + + // Make sure flush sends a packet + stream.flush(); + CPPUNIT_ASSERT(stub->sriCounter == 1); + CPPUNIT_ASSERT(stub->packetCounter == 1); + CPPUNIT_ASSERT_EQUAL(buffer.size(), (size_t) stub->data.length()); +} + +template +void BufferedOutStreamTest::testFlushOnClose() +{ + StreamType stream = port->createStream("test_flush_close"); + stream.setBufferSize(64); + + // Queue data (should not flush) + std::vector buffer; + buffer.resize(48); + stream.write(buffer, bulkio::time::utils::now()); + CPPUNIT_ASSERT(stub->sriCounter == 0); + CPPUNIT_ASSERT(stub->packetCounter == 0); + + // Close the stream; should cause a flush + stream.close(); + CPPUNIT_ASSERT(stub->sriCounter == 1); + CPPUNIT_ASSERT(stub->packetCounter == 1); +} + +template +void BufferedOutStreamTest::testFlushOnSriChange() +{ + // Start with known values for important stream metadata + StreamType stream = port->createStream("test_flush_sri"); + stream.setBufferSize(64); + stream.xdelta(0.125); + stream.complex(false); + stream.blocking(false); + stream.subsize(0); + + // Queue data (should not flush) + std::vector buffer; + buffer.resize(48); + stream.write(buffer, bulkio::time::utils::now()); + + // Change the xdelta to cause a flush; the received data should be using + // the old xdelta + CPPUNIT_ASSERT(stub->packetCounter == 0); + stream.xdelta(0.25); + CPPUNIT_ASSERT_MESSAGE("xdelta change did not flush stream", stub->packetCounter == 1); + CPPUNIT_ASSERT_EQUAL(0.125, stub->H.xdelta); + + // Queue more data (should not flush) + stream.write(buffer, bulkio::time::utils::now()); + CPPUNIT_ASSERT(stub->sriCounter == 1); + CPPUNIT_ASSERT(stub->packetCounter == 1); + + // Change the mode to complex to cause a flush; the mode shouldn't change + // yet, but xdelta should be up-to-date now + stream.complex(true); + CPPUNIT_ASSERT_MESSAGE("Complex mode change did not flush stream", stub->packetCounter == 2); + CPPUNIT_ASSERT(stub->H.mode == 0); + CPPUNIT_ASSERT_EQUAL(stream.xdelta(), stub->H.xdelta); + + // Queue more data (should not flush) + stream.write(buffer, bulkio::time::utils::now()); + CPPUNIT_ASSERT(stub->sriCounter == 2); + CPPUNIT_ASSERT(stub->packetCounter == 2); + + // Change the blocking mode to cause a flush; the blocking flag shouldn't + // change yet, but mode should be up-to-date now + stream.blocking(true); + CPPUNIT_ASSERT_MESSAGE("Blocking change did not flush stream", stub->packetCounter == 3); + CPPUNIT_ASSERT(stub->H.blocking == 0); + CPPUNIT_ASSERT(stub->H.mode != 0); + + // Queue more data (should not flush) + stream.write(buffer, bulkio::time::utils::now()); + CPPUNIT_ASSERT(stub->sriCounter == 3); + CPPUNIT_ASSERT(stub->packetCounter == 3); + + // Change the subsize to cause a flush; the subsize shouldn't change yet, + // but blocking should be up-to-date now + stream.subsize(16); + CPPUNIT_ASSERT_MESSAGE("Subsize change did not flush stream", stub->packetCounter == 4); + CPPUNIT_ASSERT(stub->H.subsize == 0); + CPPUNIT_ASSERT(stub->H.blocking); +} + +template +void BufferedOutStreamTest::testFlushOnBufferSizeChange() +{ + StreamType stream = port->createStream("test_flush_buffer_size"); + stream.setBufferSize(64); + + // Queue data (should not flush) + std::vector buffer; + buffer.resize(48); + stream.write(buffer, bulkio::time::utils::now()); + CPPUNIT_ASSERT(stub->packetCounter == 0); + + // Reduce the buffer size smaller than the current queue, should trigger a + // flush + stream.setBufferSize(32); + CPPUNIT_ASSERT_MESSAGE("Reducing buffer size below queue size did not flush", stub->packetCounter == 1); + + // Reduce the buffer size again, but not down to the queue size, should not + // trigger a flush + buffer.resize(16); + stream.write(buffer, bulkio::time::utils::now()); + stream.setBufferSize(24); + CPPUNIT_ASSERT_MESSAGE("Reducing buffer size above queue size flushed", stub->packetCounter == 1); + + // Boundary condition: exact size + stream.setBufferSize(16); + CPPUNIT_ASSERT_MESSAGE("Reducing buffer size to exact size did not flush", stub->packetCounter == 2); + + // Increasing the buffer size should not trigger a flush + buffer.resize(8); + stream.write(buffer, bulkio::time::utils::now()); + stream.setBufferSize(128); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Increasing buffer size flushed", 2, stub->packetCounter); + + // Disabling buffering must flush + stream.setBufferSize(0); + CPPUNIT_ASSERT_MESSAGE("Disabling buffering did not flush", stub->packetCounter == 3); +} + +#define CREATE_TEST_IMPL(TESTCLASS,PORT,NAME,BASE,CORBA) \ + class TESTCLASS : public BASE \ + { \ + typedef BASE TestBase; \ + CPPUNIT_TEST_SUB_SUITE(TESTCLASS, TestBase); \ + CPPUNIT_TEST_SUITE_END(); \ + virtual std::string getPortName() const { return #NAME; }; \ + }; \ + CPPUNIT_TEST_SUITE_REGISTRATION(TESTCLASS); + +#define CREATE_TEST(x,BASE,y) CREATE_TEST_IMPL(Out##x##StreamTest,bulkio::Out##x##Port,x,BASE,y) +#define CREATE_BASIC_TEST(x,y) CREATE_TEST(x,OutStreamTest,y) +#define CREATE_BUFFERED_TEST(x,y) CREATE_TEST(x,BufferedOutStreamTest,y) + +CREATE_BUFFERED_TEST(Octet,BULKIO::dataOctet); +CREATE_BUFFERED_TEST(Char,BULKIO::dataChar); +CREATE_BUFFERED_TEST(Short,BULKIO::dataShort); +CREATE_BUFFERED_TEST(UShort,BULKIO::dataUshort); +CREATE_BUFFERED_TEST(Long,BULKIO::dataLong); +CREATE_BUFFERED_TEST(ULong,BULKIO::dataUlong); +CREATE_BUFFERED_TEST(LongLong,BULKIO::dataLongLong); +CREATE_BUFFERED_TEST(ULongLong,BULKIO::dataUlongLong); +CREATE_BUFFERED_TEST(Float,BULKIO::dataFloat); +CREATE_BUFFERED_TEST(Double,BULKIO::dataDouble); + +CREATE_BASIC_TEST(XML,BULKIO::dataXML); +CREATE_BASIC_TEST(File,BULKIO::dataFile); diff --git a/bulkioInterfaces/libsrc/testing/tests/cpp/OutStreamTest.h b/bulkioInterfaces/libsrc/testing/tests/cpp/OutStreamTest.h new file mode 100644 index 000000000..12a39de95 --- /dev/null +++ b/bulkioInterfaces/libsrc/testing/tests/cpp/OutStreamTest.h @@ -0,0 +1,100 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK bulkioInterfaces. + * + * REDHAWK bulkioInterfaces is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK bulkioInterfaces is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ +#ifndef BULKIO_OUTSTREAMTEST_H +#define BULKIO_OUTSTREAMTEST_H + +#include +#include + +#include "InPortStub.h" + +template +class OutStreamTest : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE(OutStreamTest); + CPPUNIT_TEST(testOperators); + CPPUNIT_TEST(testBasicWrite); + CPPUNIT_TEST(testSriFields); + CPPUNIT_TEST(testSriUpdate); + CPPUNIT_TEST(testKeywords); + CPPUNIT_TEST(testSendEosOnClose); + CPPUNIT_TEST_SUITE_END(); + +public: + void setUp(); + void tearDown(); + + void testOperators(); + + void testBasicWrite(); + + void testSriFields(); + void testSriUpdate(); + + void testKeywords(); + + void testSendEosOnClose(); + +protected: + typedef typename OutPort::StreamType StreamType; + + virtual std::string getPortName() const = 0; + void _writeSinglePacket(StreamType& stream, size_t size, + const BULKIO::PrecisionUTCTime& time=bulkio::time::utils::now()); + + bool _hasTimestamp(); + + OutPort* port; + InPortStub* stub; +}; + +template +class BufferedOutStreamTest : public OutStreamTest +{ + typedef OutStreamTest TestBase; + CPPUNIT_TEST_SUB_SUITE(BufferedOutStreamTest, TestBase); + CPPUNIT_TEST(testBufferedWrite); + CPPUNIT_TEST(testWriteSkipBuffer); + CPPUNIT_TEST(testFlush); + CPPUNIT_TEST(testFlushOnClose); + CPPUNIT_TEST(testFlushOnSriChange); + CPPUNIT_TEST(testFlushOnBufferSizeChange); + CPPUNIT_TEST_SUITE_END(); + +public: + void testBufferedWrite(); + void testWriteSkipBuffer(); + + void testFlush(); + void testFlushOnClose(); + void testFlushOnSriChange(); + void testFlushOnBufferSizeChange(); + +private: + typedef typename OutPort::StreamType StreamType; + typedef typename StreamType::ScalarType ScalarType; + + using TestBase::port; + using TestBase::stub; +}; + + + +#endif // BULKIO_OUTSTREAMTEST_H From 748b54a703846ae5c03bece6bc2a4e1e81385b14 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 25 Jan 2017 11:06:40 -0500 Subject: [PATCH 0661/1644] Fix C++ BulkIO output stream issues found by new unit tests: boundary condition on buffer flush; comparison operators. --- .../libsrc/cpp/bulkio_out_stream.cpp | 21 +++++++++++++++---- .../libsrc/cpp/bulkio_out_stream.h | 2 ++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp index 98cffe744..bd1f781f4 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.cpp @@ -274,6 +274,18 @@ OutputStream::operator unspecified_bool_type() const return _impl?static_cast(&OutputStream::impl):0; } +template +bool OutputStream::operator==(const OutputStream& other) const +{ + return _impl == other._impl; +} + +template +bool OutputStream::operator!=(const OutputStream& other) const +{ + return !(*this == other); +} + template typename OutputStream::Impl& OutputStream::impl() { @@ -367,12 +379,13 @@ class BufferedOutputStream::Impl : public Base::Impl { } _bufferSize = samples; - // If the new buffer size is less than the currently buffered data, flush - if (_bufferSize < _bufferOffset) { + // If the new buffer size is less than (or exactly equal to) the + // currently buffered data size, flush + if (_bufferSize <= _bufferOffset) { flush(); } else if (_bufferSize > _buffer.size()) { - // The buffer size is increasing beyond the existing allocation; allocate - // a new buffer of the desired size and copy existing data + // The buffer size is increasing beyond the existing allocation; + // allocate a new buffer of the desired size and copy existing data redhawk::buffer new_buffer(_bufferSize); if (_bufferOffset > 0) { std::copy(&_buffer[0], &_buffer[_bufferOffset], &new_buffer[0]); diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h index ccbcbec0a..537a44bea 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h +++ b/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h @@ -97,6 +97,8 @@ namespace bulkio { public: operator unspecified_bool_type() const; + bool operator==(const OutputStream& other) const; + bool operator!=(const OutputStream& other) const; }; From d6d3824e6b864f62ac6f660e6102a126f026c447 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 25 Jan 2017 13:07:13 -0500 Subject: [PATCH 0662/1644] CF-1671 Move C++ include files around to allow test components to use the uninstalled headers In runtests, include the library .jar on CLASSPATH for Java test components. --- bulkioInterfaces/configure.ac | 9 ++++- bulkioInterfaces/libsrc/Makefile.am | 34 +++++++++---------- .../{ => include/bulkio}/BULKIO_Interfaces.h | 0 .../libsrc/cpp/{ => include/bulkio}/bulkio.h | 0 .../bulkio}/bulkio_attachable_base.h | 0 .../cpp/{ => include/bulkio}/bulkio_base.h | 0 .../{ => include/bulkio}/bulkio_callbacks.h | 0 .../cpp/{ => include/bulkio}/bulkio_compat.h | 0 .../{ => include/bulkio}/bulkio_datablock.h | 0 .../bulkio}/bulkio_datatransfer.h | 0 .../cpp/{ => include/bulkio}/bulkio_in_port.h | 0 .../{ => include/bulkio}/bulkio_in_stream.h | 0 .../{ => include/bulkio}/bulkio_out_port.h | 0 .../{ => include/bulkio}/bulkio_out_stream.h | 0 .../cpp/{ => include/bulkio}/bulkio_stream.h | 0 .../bulkio}/bulkio_time_operators.h | 0 .../cpp/{ => include/bulkio}/bulkio_traits.h | 0 .../{ => include/bulkio}/bulkio_typetraits.h | 0 .../libsrc/testing/tests/runtests | 1 + 19 files changed, 26 insertions(+), 18 deletions(-) rename bulkioInterfaces/libsrc/cpp/{ => include/bulkio}/BULKIO_Interfaces.h (100%) rename bulkioInterfaces/libsrc/cpp/{ => include/bulkio}/bulkio.h (100%) rename bulkioInterfaces/libsrc/cpp/{ => include/bulkio}/bulkio_attachable_base.h (100%) rename bulkioInterfaces/libsrc/cpp/{ => include/bulkio}/bulkio_base.h (100%) rename bulkioInterfaces/libsrc/cpp/{ => include/bulkio}/bulkio_callbacks.h (100%) rename bulkioInterfaces/libsrc/cpp/{ => include/bulkio}/bulkio_compat.h (100%) rename bulkioInterfaces/libsrc/cpp/{ => include/bulkio}/bulkio_datablock.h (100%) rename bulkioInterfaces/libsrc/cpp/{ => include/bulkio}/bulkio_datatransfer.h (100%) rename bulkioInterfaces/libsrc/cpp/{ => include/bulkio}/bulkio_in_port.h (100%) rename bulkioInterfaces/libsrc/cpp/{ => include/bulkio}/bulkio_in_stream.h (100%) rename bulkioInterfaces/libsrc/cpp/{ => include/bulkio}/bulkio_out_port.h (100%) rename bulkioInterfaces/libsrc/cpp/{ => include/bulkio}/bulkio_out_stream.h (100%) rename bulkioInterfaces/libsrc/cpp/{ => include/bulkio}/bulkio_stream.h (100%) rename bulkioInterfaces/libsrc/cpp/{ => include/bulkio}/bulkio_time_operators.h (100%) rename bulkioInterfaces/libsrc/cpp/{ => include/bulkio}/bulkio_traits.h (100%) rename bulkioInterfaces/libsrc/cpp/{ => include/bulkio}/bulkio_typetraits.h (100%) diff --git a/bulkioInterfaces/configure.ac b/bulkioInterfaces/configure.ac index a34e32a7c..d63410e3e 100644 --- a/bulkioInterfaces/configure.ac +++ b/bulkioInterfaces/configure.ac @@ -138,7 +138,14 @@ AM_CONDITIONAL(HAVE_JAVASUPPORT, test $HAVE_JAVASUPPORT = yes) # C++ unit testing support. May want to conditionally enable/disable this. AM_PATH_CPPUNIT(1.12.1) -AC_SUBST(BULKIO_CFLAGS, "-I \$(top_srcdir)/src/cpp -I \$(top_srcdir)/libsrc/cpp") + +# For C++ test components, provide BULKIO_CFLAGS and BULKIO_LIBS so they build +# without modifying their Makefile.am to change the paths. In order to pick up +# the uninstalled headers, we need to provide the path to the BULKIO headers, +# the top-level include directory ("bulkio/bulkio.h") and the bulkio +# directory inside of include ("bulkio.h"). +bulkio_includedir="\$(top_srcdir)/libsrc/cpp/include" +AC_SUBST(BULKIO_CFLAGS, "-I \$(top_srcdir)/src/cpp -I ${bulkio_includedir} -I ${bulkio_includedir}/bulkio") AC_SUBST(BULKIO_LIBS, "-L\$(top_srcdir)/libsrc -lbulkio-${BULKIO_API_VERSION} -L\$(top_srcdir) -lbulkioInterfaces") AC_CONFIG_FILES([bulkioInterfaces.pc setup.py Makefile jni/Makefile]) diff --git a/bulkioInterfaces/libsrc/Makefile.am b/bulkioInterfaces/libsrc/Makefile.am index a9544d973..080dc77eb 100644 --- a/bulkioInterfaces/libsrc/Makefile.am +++ b/bulkioInterfaces/libsrc/Makefile.am @@ -52,22 +52,22 @@ libbulkio_@BULKIO_API_VERSION@_la_SOURCES = \ ## Define the list of public header files and their install location. library_includedir = $(includedir)/bulkio -library_include_HEADERS = cpp/bulkio.h \ - cpp/BULKIO_Interfaces.h \ - cpp/bulkio_base.h \ - cpp/bulkio_callbacks.h \ - cpp/bulkio_traits.h \ - cpp/bulkio_in_port.h \ - cpp/bulkio_in_stream.h \ - cpp/bulkio_out_port.h \ - cpp/bulkio_out_stream.h \ - cpp/bulkio_attachable_base.h \ - cpp/bulkio_stream.h \ - cpp/bulkio_time_operators.h \ - cpp/bulkio_datablock.h \ - cpp/bulkio_datatransfer.h \ - cpp/bulkio_typetraits.h \ - cpp/bulkio_compat.h +library_include_HEADERS = cpp/include/bulkio/bulkio.h \ + cpp/include/bulkio/BULKIO_Interfaces.h \ + cpp/include/bulkio/bulkio_base.h \ + cpp/include/bulkio/bulkio_callbacks.h \ + cpp/include/bulkio/bulkio_traits.h \ + cpp/include/bulkio/bulkio_in_port.h \ + cpp/include/bulkio/bulkio_in_stream.h \ + cpp/include/bulkio/bulkio_out_port.h \ + cpp/include/bulkio/bulkio_out_stream.h \ + cpp/include/bulkio/bulkio_attachable_base.h \ + cpp/include/bulkio/bulkio_stream.h \ + cpp/include/bulkio/bulkio_time_operators.h \ + cpp/include/bulkio/bulkio_datablock.h \ + cpp/include/bulkio/bulkio_datatransfer.h \ + cpp/include/bulkio/bulkio_typetraits.h \ + cpp/include/bulkio/bulkio_compat.h ## The generated configuration header is installed in its own subdirectory of ## $(libdir). The reason for this is that the configuration information put @@ -82,7 +82,7 @@ library_include_HEADERS = cpp/bulkio.h \ ## shipped with the source tarball. #bulkio_libincludedir = $(libdir)/bulkio-$(BULKIO_API_VERSION)/include -libbulkio_@BULKIO_API_VERSION@_la_CXXFLAGS = -Wall -I./cpp -DLOGGING $(BULKIO_INF_INCLUDES) $(BOOST_CPPFLAGS) $(OMNIORB_CFLAGS) $(OSSIE_CFLAGS) +libbulkio_@BULKIO_API_VERSION@_la_CXXFLAGS = -Wall -I $(srcdir)/cpp -I $(srcdir)/cpp/include/bulkio -DLOGGING $(BULKIO_INF_INCLUDES) $(BOOST_CPPFLAGS) $(OMNIORB_CFLAGS) $(OSSIE_CFLAGS) ############################################################################### # Python diff --git a/bulkioInterfaces/libsrc/cpp/BULKIO_Interfaces.h b/bulkioInterfaces/libsrc/cpp/include/bulkio/BULKIO_Interfaces.h similarity index 100% rename from bulkioInterfaces/libsrc/cpp/BULKIO_Interfaces.h rename to bulkioInterfaces/libsrc/cpp/include/bulkio/BULKIO_Interfaces.h diff --git a/bulkioInterfaces/libsrc/cpp/bulkio.h b/bulkioInterfaces/libsrc/cpp/include/bulkio/bulkio.h similarity index 100% rename from bulkioInterfaces/libsrc/cpp/bulkio.h rename to bulkioInterfaces/libsrc/cpp/include/bulkio/bulkio.h diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_attachable_base.h b/bulkioInterfaces/libsrc/cpp/include/bulkio/bulkio_attachable_base.h similarity index 100% rename from bulkioInterfaces/libsrc/cpp/bulkio_attachable_base.h rename to bulkioInterfaces/libsrc/cpp/include/bulkio/bulkio_attachable_base.h diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_base.h b/bulkioInterfaces/libsrc/cpp/include/bulkio/bulkio_base.h similarity index 100% rename from bulkioInterfaces/libsrc/cpp/bulkio_base.h rename to bulkioInterfaces/libsrc/cpp/include/bulkio/bulkio_base.h diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_callbacks.h b/bulkioInterfaces/libsrc/cpp/include/bulkio/bulkio_callbacks.h similarity index 100% rename from bulkioInterfaces/libsrc/cpp/bulkio_callbacks.h rename to bulkioInterfaces/libsrc/cpp/include/bulkio/bulkio_callbacks.h diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_compat.h b/bulkioInterfaces/libsrc/cpp/include/bulkio/bulkio_compat.h similarity index 100% rename from bulkioInterfaces/libsrc/cpp/bulkio_compat.h rename to bulkioInterfaces/libsrc/cpp/include/bulkio/bulkio_compat.h diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_datablock.h b/bulkioInterfaces/libsrc/cpp/include/bulkio/bulkio_datablock.h similarity index 100% rename from bulkioInterfaces/libsrc/cpp/bulkio_datablock.h rename to bulkioInterfaces/libsrc/cpp/include/bulkio/bulkio_datablock.h diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_datatransfer.h b/bulkioInterfaces/libsrc/cpp/include/bulkio/bulkio_datatransfer.h similarity index 100% rename from bulkioInterfaces/libsrc/cpp/bulkio_datatransfer.h rename to bulkioInterfaces/libsrc/cpp/include/bulkio/bulkio_datatransfer.h diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_port.h b/bulkioInterfaces/libsrc/cpp/include/bulkio/bulkio_in_port.h similarity index 100% rename from bulkioInterfaces/libsrc/cpp/bulkio_in_port.h rename to bulkioInterfaces/libsrc/cpp/include/bulkio/bulkio_in_port.h diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.h b/bulkioInterfaces/libsrc/cpp/include/bulkio/bulkio_in_stream.h similarity index 100% rename from bulkioInterfaces/libsrc/cpp/bulkio_in_stream.h rename to bulkioInterfaces/libsrc/cpp/include/bulkio/bulkio_in_stream.h diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_port.h b/bulkioInterfaces/libsrc/cpp/include/bulkio/bulkio_out_port.h similarity index 100% rename from bulkioInterfaces/libsrc/cpp/bulkio_out_port.h rename to bulkioInterfaces/libsrc/cpp/include/bulkio/bulkio_out_port.h diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h b/bulkioInterfaces/libsrc/cpp/include/bulkio/bulkio_out_stream.h similarity index 100% rename from bulkioInterfaces/libsrc/cpp/bulkio_out_stream.h rename to bulkioInterfaces/libsrc/cpp/include/bulkio/bulkio_out_stream.h diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_stream.h b/bulkioInterfaces/libsrc/cpp/include/bulkio/bulkio_stream.h similarity index 100% rename from bulkioInterfaces/libsrc/cpp/bulkio_stream.h rename to bulkioInterfaces/libsrc/cpp/include/bulkio/bulkio_stream.h diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_time_operators.h b/bulkioInterfaces/libsrc/cpp/include/bulkio/bulkio_time_operators.h similarity index 100% rename from bulkioInterfaces/libsrc/cpp/bulkio_time_operators.h rename to bulkioInterfaces/libsrc/cpp/include/bulkio/bulkio_time_operators.h diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_traits.h b/bulkioInterfaces/libsrc/cpp/include/bulkio/bulkio_traits.h similarity index 100% rename from bulkioInterfaces/libsrc/cpp/bulkio_traits.h rename to bulkioInterfaces/libsrc/cpp/include/bulkio/bulkio_traits.h diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_typetraits.h b/bulkioInterfaces/libsrc/cpp/include/bulkio/bulkio_typetraits.h similarity index 100% rename from bulkioInterfaces/libsrc/cpp/bulkio_typetraits.h rename to bulkioInterfaces/libsrc/cpp/include/bulkio/bulkio_typetraits.h diff --git a/bulkioInterfaces/libsrc/testing/tests/runtests b/bulkioInterfaces/libsrc/testing/tests/runtests index c34efd0ed..8e53084fa 100755 --- a/bulkioInterfaces/libsrc/testing/tests/runtests +++ b/bulkioInterfaces/libsrc/testing/tests/runtests @@ -8,6 +8,7 @@ bulkio_top=$(cd ../../..;pwd) bulkio_libsrc_top=$bulkio_top/libsrc export LD_LIBRARY_PATH=$bulkio_libsrc_top/.libs:$bulkio_top/.libs:$bulkio_top/jni/.libs:${LD_LIBRARY_PATH} export PYTHONPATH=$bulkio_libsrc_top/build/lib:${PYTHONPATH} +export CLASSPATH=${bulkio_libsrc_top}/bulkio.jar:${CLASSPATH} # Limit the number of threads Java uses for the garbage collector to avoid # misleading Java "out of memory" errors that in all actuality appear to be From 1bd5afb1bd81cda2869e5fcb2dbc1220ad11608d Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 25 Jan 2017 13:21:56 -0500 Subject: [PATCH 0663/1644] Ignore BulkIO test results --- bulkioInterfaces/libsrc/testing/tests/.gitignore | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 bulkioInterfaces/libsrc/testing/tests/.gitignore diff --git a/bulkioInterfaces/libsrc/testing/tests/.gitignore b/bulkioInterfaces/libsrc/testing/tests/.gitignore new file mode 100644 index 000000000..79da69a41 --- /dev/null +++ b/bulkioInterfaces/libsrc/testing/tests/.gitignore @@ -0,0 +1,2 @@ +TEST-*.xml +cppunit-results.xml From b0b3d3e9885b7e5de057d77a0e2cd05c04191106 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 25 Jan 2017 13:34:08 -0500 Subject: [PATCH 0664/1644] Replace old mentions of "read" instead of "shared" for shared_buffer --- .../cpp/include/bulkio/bulkio_out_stream.h | 8 ++--- .../src/base/include/ossie/shared_buffer.h | 34 +++++++++---------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/include/bulkio/bulkio_out_stream.h b/bulkioInterfaces/libsrc/cpp/include/bulkio/bulkio_out_stream.h index 537a44bea..56598d0f9 100644 --- a/bulkioInterfaces/libsrc/cpp/include/bulkio/bulkio_out_stream.h +++ b/bulkioInterfaces/libsrc/cpp/include/bulkio/bulkio_out_stream.h @@ -145,14 +145,14 @@ namespace bulkio { /** * @brief Write scalar data to the stream. - * @param data The %read_buffer to write. + * @param data The %shared_buffer to write. * @param time The timestamp of the first sample. */ void write(const ScalarBuffer& data, const BULKIO::PrecisionUTCTime& time); /** * @brief Write scalar data to the stream. - * @param data The %read_buffer to write. + * @param data The %shared_buffer to write. * @param times A list of sample timestamps. Sample offsets must be in * increasing order, starting at 0. * @@ -163,14 +163,14 @@ namespace bulkio { /** * @brief Write complex data to the stream. - * @param data The %read_buffer to write. + * @param data The %shared_buffer to write. * @param time The timestamp of the first sample. */ void write(const ComplexBuffer& data, const BULKIO::PrecisionUTCTime& time); /** * @brief Write complex data to the stream. - * @param data The %read_buffer to write. + * @param data The %shared_buffer to write. * @param times A list of sample timestamps. Sample offsets must be in * increasing order, starting at 0. * diff --git a/redhawk/src/base/include/ossie/shared_buffer.h b/redhawk/src/base/include/ossie/shared_buffer.h index e512a9c7b..c9aaaedab 100644 --- a/redhawk/src/base/include/ossie/shared_buffer.h +++ b/redhawk/src/base/include/ossie/shared_buffer.h @@ -465,8 +465,8 @@ namespace redhawk { class buffer : public shared_buffer { public: - /// @brief The read-only buffer type. - typedef shared_buffer read_type; + /// @brief The equivalent shared buffer type. + typedef shared_buffer shared_type; /// @brief The element type (T). typedef T value_type; /// @brief A random access iterator to value_type. @@ -494,7 +494,7 @@ namespace redhawk { * @brief Construct an empty %buffer. */ buffer() : - read_type() + shared_type() { } @@ -506,7 +506,7 @@ namespace redhawk { * initialization is performed. */ buffer(size_t size) : - read_type(this->_M_allocate(size, default_allocator())) + shared_type(this->_M_allocate(size, default_allocator())) { } @@ -521,7 +521,7 @@ namespace redhawk { */ template buffer(size_t size, const Alloc& allocator) : - read_type(this->_M_allocate(size, allocator)) + shared_type(this->_M_allocate(size, allocator)) { } @@ -535,7 +535,7 @@ namespace redhawk { * with delete[]. */ buffer(value_type* data, size_t size) : - read_type(data, size) + shared_type(data, size) { } @@ -552,7 +552,7 @@ namespace redhawk { */ template buffer(value_type* data, size_t size, D deleter) : - read_type(data, size, deleter) + shared_type(data, size, deleter) { } @@ -625,7 +625,7 @@ namespace redhawk { */ size_t size() const { - return read_type::size(); + return shared_type::size(); } /** @@ -633,7 +633,7 @@ namespace redhawk { */ bool empty() const { - return read_type::empty(); + return shared_type::empty(); } /** @@ -658,9 +658,9 @@ namespace redhawk { * @param end Index of last element, exclusive (default end). * @return The new %shared_buffer. */ - read_type slice(size_t start, size_t end=size_t(-1)) const + shared_type slice(size_t start, size_t end=size_t(-1)) const { - return read_type::slice(start, end); + return shared_type::slice(start, end); } /** @@ -683,7 +683,7 @@ namespace redhawk { */ void trim(size_t start, size_t end=size_t(-1)) { - read_type::trim(start, end); + shared_type::trim(start, end); } /** @@ -712,7 +712,7 @@ namespace redhawk { */ buffer copy() const { - return read_type::copy(); + return shared_type::copy(); } /** @@ -725,7 +725,7 @@ namespace redhawk { template buffer copy(const Alloc& allocator) const { - return read_type::copy(allocator); + return shared_type::copy(allocator); } /** @@ -752,7 +752,7 @@ namespace redhawk { // Use the base class' template method implementation, with this // type as the first template parameter (the second is deduced from // the argument). - return read_type::template _M_recast(other); + return shared_type::template _M_recast(other); } protected: @@ -781,10 +781,10 @@ namespace redhawk { // Implementation of allocate. template - static read_type _M_allocate(size_t size, const Alloc& allocator) + static shared_type _M_allocate(size_t size, const Alloc& allocator) { allocator_deleter deleter(size, allocator); - return read_type(deleter.allocate(size), size, deleter); + return shared_type(deleter.allocate(size), size, deleter); } /// @endcond From a6d4f622a39ed91e37f60e6b9ffe82dbf2f5d4cb Mon Sep 17 00:00:00 2001 From: 8530 <8530@vm-131.vsi-corp.com> Date: Thu, 26 Jan 2017 08:24:05 -0500 Subject: [PATCH 0665/1644] fix build issues for centos 7, CF-1215 --- .../src/testing/loggers/syncappender/Makefile.am | 2 +- .../src/testing/loggers/syncappender/configure.ac | 14 +++----------- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/redhawk/src/testing/loggers/syncappender/Makefile.am b/redhawk/src/testing/loggers/syncappender/Makefile.am index f030f1d6f..93e9ff386 100644 --- a/redhawk/src/testing/loggers/syncappender/Makefile.am +++ b/redhawk/src/testing/loggers/syncappender/Makefile.am @@ -1,5 +1,5 @@ # Rules for the test code (use `make check` to execute) -ACLOCAL_AMFLAGS = -I m4 -I ${OSSIEHOME}/share/aclocal/ossie +ACLOCAL_AMFLAGS = -I m4 -I ../../../acinclude TESTS = appender_test noinst_PROGRAMS = cleanmem proc_log check_PROGRAMS = $(TESTS) diff --git a/redhawk/src/testing/loggers/syncappender/configure.ac b/redhawk/src/testing/loggers/syncappender/configure.ac index 057b06037..af67720af 100644 --- a/redhawk/src/testing/loggers/syncappender/configure.ac +++ b/redhawk/src/testing/loggers/syncappender/configure.ac @@ -1,10 +1,5 @@ -dnl Process this file with autoconf to produce a configure script. -dnl AC_INIT(Makefile.am) -dnl AC_CONFIG_MACRO_DIR([m4]) -dnl AM_INIT_AUTOMAKE(Logging_Test,0.1) - AC_INIT(Logging_Test,0.1) AC_CONFIG_MACRO_DIR([m4]) AM_INIT_AUTOMAKE([foreign]) @@ -13,14 +8,11 @@ AM_PATH_CPPUNIT(1.9.6) AC_PROG_CXX AC_PROG_CC AC_PROG_INSTALL -AC_PREFIX_DEFAULT(${OSSIEHOME}) -OSSIE_CHECK_OSSIE -OSSIE_OSSIEHOME_AS_PREFIX -PKG_CHECK_MODULES([OMNI_DEPS], [ omniORB4 >= 4.0 omniEvents >= 2.0 omniDynamic4 >= 4.0.0 ]) -PKG_CHECK_MODULES([OSSIE_DEPS], [ossie >= 1.8 ] ) +AC_SEARCH_LIBS([shm_unlink], [rt]) + +PKG_CHECK_MODULES([LOG4CXX], [liblog4cxx >= 0.10.0]) AX_BOOST_BASE([1.41]) AX_BOOST_SYSTEM -AC_CORBA_ORB AC_OUTPUT(Makefile) From ffc2fa9c17632319b43700769b5ee68051c1cb2a Mon Sep 17 00:00:00 2001 From: Max Robert Date: Thu, 26 Jan 2017 15:58:36 -0500 Subject: [PATCH 0666/1644] Refs CF-1583. Added python helpers for the eventChannelManager --- .../python/ossie/utils/redhawk/core.py | 61 ++++++++++--------- 1 file changed, 33 insertions(+), 28 deletions(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/redhawk/core.py b/redhawk/src/base/framework/python/ossie/utils/redhawk/core.py index e0e218b2b..e7fb31987 100644 --- a/redhawk/src/base/framework/python/ossie/utils/redhawk/core.py +++ b/redhawk/src/base/framework/python/ossie/utils/redhawk/core.py @@ -1300,7 +1300,15 @@ def listRegistrants( self, channelName="", count=0 ): raise return retval + def registerConsumer(self, consumer, req): + if hassattr(consumer, '_this'): + return self.ref.registerConsumer(consumer._this(), req) + return self.ref.registerConsumer(consumer, req) + def registerPublisher(self, req, disconnectReceiver): + #if hassattr(disconnectReceiver, '_this'): + # return self.ref.registerPublisher(req, disconnectReceiver._this()) + return self.ref.registerPublisher(req, disconnectReceiver) class Domain(_CF__POA.DomainManager, QueryableBase, PropertyEmitter): """The Domain is a descriptor for a Domain Manager. @@ -1704,34 +1712,7 @@ def _get_domainManagerProfile(self): except: pass return retval - - def _get_allocationMgr(self): - retval = None - if self.ref: - try: - retval = self.ref._get_allocationMgr() - except: - pass - return retval - - def _get_connectionMgr(self): - retval = None - if self.ref: - try: - retval = self.ref._get_connectionMgr() - except: - pass - return retval - - def _get_eventChannelMgr(self): - retval = None - if self.ref: - try: - retval = self.ref._get_eventChannelMgr() - except: - pass - return retval - + def _get_name(self): retval = '' if self.ref: @@ -1913,6 +1894,30 @@ def getEventChannelMgr(self): except: raise return self.__eventChannelMgr + + def _get_allocationMgr(self): + if self.ref and self.__allocationMgr == None : + try: + self.__allocationMgr = AllocationManager(self.ref._get_allocationMgr()) + except: + raise + return self.__allocationMgr + + def _get_connectionMgr(self): + if self.ref and self.__connectionMgr == None : + try: + self.__connectionMgr = ConnectionManager(self.ref._get_connectionMgr()) + except: + raise + return self.__connectionMgr + + def _get_eventChannelMgr(self): + if self.ref and self.__eventChannelMgr == None : + try: + self.__eventChannelMgr = EventChannelManager(self.ref._get_eventChannelMgr()) + except: + raise + return self.__eventChannelMgr # End external Domain Manager API ######################################## From a16ce95202e90579ad57b964ba90fa9147565ba5 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Thu, 26 Jan 2017 15:59:05 -0500 Subject: [PATCH 0667/1644] Refs CF-1587. Added property change monitoring to the Python package --- .../python/ossie/events/Publisher.py | 46 ++- .../python/ossie/events/Subscriber.py | 57 ++- .../python/ossie/utils/model/__init__.py | 5 +- .../python/ossie/utils/sb/__init__.py | 4 + redhawk/src/base/include/ossie/EventTypes.h | 3 + .../sdr/dommgr/EventChannelManager.cpp | 302 ++++++++++++++- .../control/sdr/dommgr/EventChannelManager.h | 42 ++ .../src/idl/ossie/CF/EventChannelManager.idl | 63 ++- .../BasicService_cpp/cpp/BasicService_cpp.cpp | 10 +- .../tests/test_08_PropertyChangeListener.py | 364 +++--------------- .../testing/tests/test_13_RedhawkModule.py | 59 +++ redhawk/src/testing/tests/test_13_TestSB.py | 56 +++ 12 files changed, 681 insertions(+), 330 deletions(-) diff --git a/redhawk/src/base/framework/python/ossie/events/Publisher.py b/redhawk/src/base/framework/python/ossie/events/Publisher.py index 4a9cbde72..586a100b3 100644 --- a/redhawk/src/base/framework/python/ossie/events/Publisher.py +++ b/redhawk/src/base/framework/python/ossie/events/Publisher.py @@ -29,6 +29,7 @@ from omniORB import any, URI, CORBA import CosEventComm__POA import CosEventChannelAdmin, CosEventChannelAdmin__POA +from ossie.cf import CF class Receiver(CosEventComm__POA.PushSupplier): @@ -83,8 +84,27 @@ def __init__(self,parent): Receiver.__init__(self) class Publisher: - def __init__(self, channel ): - self.channel = channel + def __init__(self, remote_obj, channel_name=''): + ''' + remote_obj is either an Event Channel or a Domain Manager + if remote_obj is a Domain Manager, a channel_name must be supplied + ''' + self.channel = None + self.domain = None + self.channel_name = channel_name + self.registration = CF.EventChannelManager.EventRegistration( channel_name = self.channel_name, reg_id = "") + self.reg_resp = None + if hasattr(remote_obj, 'ref'): + if remote_obj.ref._narrow(CF.DomainManager) != None: + self.domain = remote_obj.ref + elif remote_obj._narrow(CosEventChannelAdmin.EventChannel) != None: + self.channel = remote_obj._narrow(CosEventChannelAdmin.EventChannel) + elif remote_obj._narrow(CF.DomainManager) != None: + self.domain = remote_obj._narrow(CF.DomainManager) + if self.channel == None and self.domain == None: + raise Exception("Error. remote_obj must either be an Event Channel or a Domain Manager") + if self.domain != None and channel_name == '': + raise Exception("Error. When passing a Domain Manager as an argument, channel_name must have a valid Event Channel name") self.proxy = None self.logger = logging.getLogger("ossie.events.Publisher") self.disconnectReceiver = DefaultReceiver(self) @@ -107,7 +127,7 @@ def __del__(self): def terminate(self): self.logger.debug("Publisher::terminate START") - if self.disconnectReceiver and self.disconnectReceiver.get_disconnect() == False: + if self.disconnectReceiver: self.logger.debug("Publisher::terminate DISCONNECT") self.disconnect() @@ -148,6 +168,15 @@ def push(self,data ): def disconnect(self, retries=10, retry_wait=.01): + if self.channel != None: + self.disconnectEvtChan(retries, retry_wait) + else: + self.disconnectDomMgr() + + def disconnectDomMgr(self): + self.ecm.unregister(self.reg_resp.reg) + + def disconnectEvtChan(self, retries=10, retry_wait=.01): retval=0 if self.channel == None: return retval @@ -173,6 +202,17 @@ def disconnect(self, retries=10, retry_wait=.01): def connect(self, retries=10, retry_wait=.01): + if self.channel != None: + self.connectEvtChan(retries, retry_wait) + else: + self.connectDomMgr() + + def connectDomMgr(self): + self.ecm = self.domain._get_eventChannelMgr() + self.reg_resp = self.ecm.registerPublisher(self.registration, self.disconnectReceiver._this()) + self.proxy = self.reg_resp.proxy_consumer + + def connectEvtChan(self, retries=10, retry_wait=.01): retval=-1 if self.channel == None: diff --git a/redhawk/src/base/framework/python/ossie/events/Subscriber.py b/redhawk/src/base/framework/python/ossie/events/Subscriber.py index 8fafa2791..131f58b20 100644 --- a/redhawk/src/base/framework/python/ossie/events/Subscriber.py +++ b/redhawk/src/base/framework/python/ossie/events/Subscriber.py @@ -86,17 +86,37 @@ def __init__(self,parent): Receiver.__init__(self) def push(self, data): + _data = any.from_any(data) if self.parent.dataArrivedCB != None: self.parent.logger.trace('Received (callback) DATA: ' + str(data)) - self.parent.dataArrivedCB( data ) + self.parent.dataArrivedCB(_data) else: self.parent.logger.trace('Received (queue) DATA: ' + str(data)) - self.parent.events.put(data) + self.parent.events.put(_data) class Subscriber: - def __init__(self, channel, dataArrivedCB=None): - self.channel = channel + def __init__(self, remote_obj, channel_name='', dataArrivedCB=None): + ''' + remote_obj is either an Event Channel or a Domain Manager + if remote_obj is a Domain Manager, a channel_name must be supplied + ''' + self.channel = None + self.domain = None + self.channel_name = channel_name + self.registration = CF.EventChannelManager.EventRegistration( channel_name = self.channel_name, reg_id = "") + self.reg_resp = None + if hasattr(remote_obj, 'ref'): + if remote_obj.ref._narrow(CF.DomainManager) != None: + self.domain = remote_obj.ref + elif remote_obj._narrow(CosEventChannelAdmin.EventChannel) != None: + self.channel = remote_obj._narrow(CosEventChannelAdmin.EventChannel) + elif remote_obj._narrow(CF.DomainManager) != None: + self.domain = remote_obj._narrow(CF.DomainManager) + if self.channel == None and self.domain == None: + raise Exception("Error. remote_obj must either be an Event Channel or a Domain Manager") + if self.domain != None and channel_name == '': + raise Exception("Error. When passing a Domain Manager as an argument, channel_name must have a valid Event Channel name") self.proxy = None self.logger = logging.getLogger('ossie.events.Subscriber') self.dataArrivedCB=dataArrivedCB @@ -105,10 +125,9 @@ def __init__(self, channel, dataArrivedCB=None): self.consumer = DefaultConsumer(self) self.connect() - def __del__(self): self.logger.debug("Subscriber DTOR START") - if self.consumer and self.consumer.get_disconnect() == False: + if self.consumer: self.logger.debug("Subscriber::DTOR DISCONNECT") self.disconnect() @@ -124,7 +143,7 @@ def setDataArrivedCB(self, newCB=None ): def terminate(self): self.logger.debug("Subscriber::terminate START") - if self.consumer and self.consumer.get_disconnect() == False: + if self.consumer: self.logger.debug("Subscriber::terminate DISCONNECT") self.disconnect() @@ -141,17 +160,24 @@ def getData(self): return retval; try: - tmp = self.events.get(False,.01) - self.logger.debug('getData: ' + str(tmp)) - retval = any.from_any(tmp) + retval = self.events.get(False,.01) + self.logger.debug('getData: ' + str(retval)) except: - #print traceback.print_exc() retval=None return retval def disconnect(self, retries=10, retry_wait=.01): + if self.channel != None: + self.disconnectEvtChan(retries, retry_wait) + else: + self.disconnectDomMgr() + + def disconnectDomMgr(self): + self.ecm.unregister(self.reg_resp.reg) + + def disconnectEvtChan(self, retries=10, retry_wait=.01): if self.channel == None: return -1 @@ -177,7 +203,16 @@ def disconnect(self, retries=10, retry_wait=.01): def connect(self, retries=10, retry_wait=.01): + if self.channel != None: + self.connectEvtChan(retries, retry_wait) + else: + self.connectDomMgr() + def connectDomMgr(self): + self.ecm = self.domain._get_eventChannelMgr() + self.reg_resp = self.ecm.registerConsumer(self.consumer._this(), self.registration) + + def connectEvtChan(self, retries=10, retry_wait=.01): if self.channel == None: return -1 diff --git a/redhawk/src/base/framework/python/ossie/utils/model/__init__.py b/redhawk/src/base/framework/python/ossie/utils/model/__init__.py index b2102f0c7..86bc31df8 100644 --- a/redhawk/src/base/framework/python/ossie/utils/model/__init__.py +++ b/redhawk/src/base/framework/python/ossie/utils/model/__init__.py @@ -559,8 +559,11 @@ def __init__(self): def registerPropertyListener( self, obj, prop_ids=[], interval=1.0): self.__log.trace("registerPropertyListener('%s')", str(prop_ids)) + _obj = obj + if hasattr(obj, '_this'): + _obj = obj._this() if self.ref: - return self.ref.registerPropertyListener(obj, prop_ids, interval ) + return self.ref.registerPropertyListener(_obj, prop_ids, interval ) return None def unregisterPropertyListener( self, reg_id ): diff --git a/redhawk/src/base/framework/python/ossie/utils/sb/__init__.py b/redhawk/src/base/framework/python/ossie/utils/sb/__init__.py index 8aa7f2238..6fed9a281 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sb/__init__.py +++ b/redhawk/src/base/framework/python/ossie/utils/sb/__init__.py @@ -62,6 +62,8 @@ Push data from a file into components and back. - MessageSource(), MessageSink(): Push messages from Python to components and back. + - PropertyChangeListener: + Container to receive asynchronous property change events - SoundSink(): Playback audio data from BULKIO streams - compareSRI(): @@ -116,7 +118,9 @@ """ from domainless import * from io_helpers import * +from prop_change_helpers import * from block_process import * + try: from bulkio.bulkioInterfaces import BULKIO except: diff --git a/redhawk/src/base/include/ossie/EventTypes.h b/redhawk/src/base/include/ossie/EventTypes.h index 0344496b4..45284dab6 100644 --- a/redhawk/src/base/include/ossie/EventTypes.h +++ b/redhawk/src/base/include/ossie/EventTypes.h @@ -69,6 +69,9 @@ namespace ossie { typedef CF::EventChannelManager::EventChannelReg EventChannelReg; typedef CF::EventChannelManager::EventChannelReg_var EventChannelReg_var; typedef CF::EventChannelManager::EventChannelReg* EventChannelReg_ptr; + typedef CF::EventChannelManager::PublisherReg PublisherReg; + typedef CF::EventChannelManager::PublisherReg_var PublisherReg_var; + typedef CF::EventChannelManager::PublisherReg* PublisherReg_ptr; }; // end of event namespace diff --git a/redhawk/src/control/sdr/dommgr/EventChannelManager.cpp b/redhawk/src/control/sdr/dommgr/EventChannelManager.cpp index 00c2552c6..a7a73254d 100644 --- a/redhawk/src/control/sdr/dommgr/EventChannelManager.cpp +++ b/redhawk/src/control/sdr/dommgr/EventChannelManager.cpp @@ -230,6 +230,39 @@ const ossie::events::EventChannel_ptr EventChannelManager::findChannel( const st } + void EventChannelManager::forceRelease( const char *channel_name) + throw ( CF::EventChannelManager::ChannelDoesNotExist, + CF::EventChannelManager::OperationFailed, + CF::EventChannelManager::OperationNotAllowed, + CF::EventChannelManager::ServiceUnavailable ) { + + SCOPED_LOCK(_mgrlock); + // get the event channel factory... throws ServiceUnavailable if factory is not resolved + _getEventChannelFactory(); + + ECM_DEBUG( "release", " Delete event channel: " << channel_name ); + std::string cname(channel_name); + + ECM_DEBUG( "release", " Check registration for event channel: " << channel_name ); + ChannelRegistrationPtr reg = _getChannelRegistration( cname ); + + // channel registration entry does not exists + if ( reg == NULL ) { + ECM_DEBUG( "release", " Registration DOES NOT EXISTS event channel: " << channel_name ); + throw (CF::EventChannelManager::ChannelDoesNotExist()); + } + + // check if anyone is still registered + CF::EventChannelManager::EventRegistration_var tmp_evt = new CF::EventChannelManager::EventRegistration(); + tmp_evt->channel_name = channel_name; + while ( reg->nregistrants() > 0 ) { + tmp_evt->reg_id = reg->registrants.begin()->first.c_str(); + _unregister(tmp_evt); + } + _release(channel_name); + + } + void EventChannelManager::release( const std::string &channel_name) throw ( CF::EventChannelManager::ChannelDoesNotExist, CF::EventChannelManager::RegistrationsExists, @@ -337,6 +370,30 @@ ossie::events::EventChannel_ptr EventChannelManager::create( const std::string & } +ossie::events::EventChannel_ptr EventChannelManager::get( const std::string &channel_name) + throw ( CF::EventChannelManager::ChannelDoesNotExist, + CF::EventChannelManager::OperationFailed, + CF::EventChannelManager::OperationNotAllowed, + CF::EventChannelManager::ServiceUnavailable ) + { + SCOPED_LOCK(_mgrlock); + return _get( channel_name ); + + } + + + + ossie::events::EventChannel_ptr EventChannelManager::get( const char *channel_name) + throw ( CF::EventChannelManager::ChannelDoesNotExist, + CF::EventChannelManager::OperationFailed, + CF::EventChannelManager::OperationNotAllowed, + CF::EventChannelManager::ServiceUnavailable ) + { + SCOPED_LOCK(_mgrlock); + return _get( channel_name ); + + } + ossie::events::EventChannel_ptr EventChannelManager::createForRegistrations( const char *channel_name) throw ( CF::EventChannelManager::ChannelAlreadyExists, @@ -440,6 +497,67 @@ ossie::events::EventChannel_ptr EventChannelManager::create( const std::string & return event_channel._retn(); } + ossie::events::EventChannel_ptr EventChannelManager::_get( const std::string &channel_name ) + throw ( CF::EventChannelManager::ChannelDoesNotExist, + CF::EventChannelManager::OperationFailed, + CF::EventChannelManager::OperationNotAllowed, + CF::EventChannelManager::ServiceUnavailable ) + { + // + // validate channel name... + // + if ( _validateChannelName( channel_name ) == false ) { + throw ( CF::EventChannelManager::InvalidChannelName()); + } + + // + // check if channel name is already registered + // + if ( _channelExists( channel_name ) ) { + ChannelRegistrationPtr cr_ptr = _getChannelRegistration( channel_name ); + return(ossie::events::EventChannel::_duplicate(cr_ptr->channel)); + } + + // + // check if channel name is already exists in the event service + // + ossie::events::EventChannel_var event_channel = ossie::events::EventChannel::_nil(); + std::string cname(channel_name); + std::string fqn = _getFQN(cname); + bool require_ns = false; // if channel exists and use_nameing_service is enabled + event_channel = _resolve_es( cname, fqn ); + + // if we found a matching channel + if ( !CORBA::is_nil(event_channel) ) { + + // if naming service disabled then throw + if ( _use_naming_service == false && _allow_es_resolve == false ) { + return(ossie::events::EventChannel::_duplicate(event_channel)); + } + else { + if ( _allow_es_resolve == false ) { + // set next search method to require use of NS + require_ns=true; + } + } + } + + // + // try and resolve with naming service (if enabled) + // + if ( require_ns ) { + ECM_TRACE( "_createChannel", " Checking NamingService for:" << fqn ); + event_channel = _resolve_ns( cname, fqn, _domain_context ); + // if NamingService is enable and we require its use, but channel evaluation failed + if ( CORBA::is_nil(event_channel) && require_ns) { + throw (CF::EventChannelManager::OperationFailed()); + } + return(ossie::events::EventChannel::_duplicate(event_channel)); + } + ECM_DEBUG("get", "Event channel: "<< channel_name << " does not exist in the local domain"); + throw (CF::EventChannelManager::ChannelDoesNotExist()); + } + void EventChannelManager::restore( ossie::events::EventChannel_ptr savedChannel, @@ -598,6 +716,152 @@ void EventChannelManager::restore( ossie::events::EventChannel_ptr savedChannel, // return reg; } + + ossie::events::EventChannelReg_ptr EventChannelManager::registerConsumer( CosEventComm::PushConsumer_ptr consumer, const ossie::events::EventRegistration &req) + throw ( CF::EventChannelManager::InvalidChannelName, + CF::EventChannelManager::RegistrationAlreadyExists, + CF::EventChannelManager::OperationFailed, + CF::EventChannelManager::OperationNotAllowed, + CF::EventChannelManager::ServiceUnavailable ) { + int retries = 10; + int retry_wait = 10; + int tries = retries; + CosEventChannelAdmin::ConsumerAdmin_var consumer_admin; + ossie::events::EventChannel_var channel = get(req.channel_name); + do + { + try { + consumer_admin = channel->for_consumers (); + break; + } + catch (CORBA::COMM_FAILURE& ex) { + } + if ( retry_wait > 0 ) { + boost::this_thread::sleep( boost::posix_time::microseconds( retry_wait*1000 ) ); + } else { + boost::this_thread::yield(); + } + tries--; + } while ( tries ); + + ossie::events::EventSubscriber_var _proxy; + + if ( CORBA::is_nil(consumer_admin) ) + throw (CF::EventChannelManager::OperationFailed()); + tries=retries; + do { + try { + _proxy = consumer_admin->obtain_push_supplier (); + break; + } + catch (CORBA::COMM_FAILURE& ex) { + } + if ( retry_wait > 0 ) { + boost::this_thread::sleep( boost::posix_time::microseconds( retry_wait*1000 ) ); + } else { + boost::this_thread::yield(); + } + tries--; + } while ( tries ); + if ( CORBA::is_nil(_proxy) ) + throw (CF::EventChannelManager::OperationFailed()); + tries=retries; + do { + try { + _proxy->connect_push_consumer(consumer); + } + catch (CORBA::BAD_PARAM& ex) { + ECM_DEBUG("registerConsumer", "Unable to connect consumer to the Event channel" ); + throw (CF::EventChannelManager::OperationFailed()); + } + catch (CosEventChannelAdmin::AlreadyConnected& ex) { + break; + } + catch (CORBA::COMM_FAILURE& ex) { + } + if ( retry_wait > 0 ) { + boost::this_thread::sleep( boost::posix_time::microseconds( retry_wait*1000 ) ); + } else { + boost::this_thread::yield(); + } + tries--; + } while ( tries ); + ossie::events::EventChannelReg_ptr ret_reg; + try { + ret_reg = registerResource(req); + } catch ( ... ) { + try { + _proxy->disconnect_push_supplier(); + } catch ( ... ) { + } + throw; + } + std::string _reg_id(ret_reg->reg.reg_id); + _subProxies[_reg_id] = ossie::events::EventSubscriber::_duplicate(_proxy); + return ret_reg; + } + + ossie::events::PublisherReg_ptr EventChannelManager::registerPublisher( const ossie::events::EventRegistration &req, CosEventComm::PushSupplier_ptr disconnectReceiver) + throw ( CF::EventChannelManager::InvalidChannelName, + CF::EventChannelManager::RegistrationAlreadyExists, + CF::EventChannelManager::OperationFailed, + CF::EventChannelManager::OperationNotAllowed, + CF::EventChannelManager::ServiceUnavailable ) { + + int retries = 10; + int retry_wait = 10; + int tries = retries; + + CosEventChannelAdmin::SupplierAdmin_var supplier_admin; + ossie::events::PublisherReg_ptr reg = new ossie::events::PublisherReg(); + ossie::events::EventChannel_var channel = get(req.channel_name); + do + { + try { + supplier_admin = channel->for_suppliers (); + break; + } catch (CORBA::COMM_FAILURE& ex) {} + if ( retry_wait > 0 ) { + boost::this_thread::sleep( boost::posix_time::microseconds( retry_wait*1000 ) ); + } else { + boost::this_thread::yield(); + } + tries--; + } while ( tries ); + + if ( CORBA::is_nil(supplier_admin) ) + throw (CF::EventChannelManager::OperationFailed());; + + tries=retries; + do { + try { + reg->proxy_consumer = supplier_admin->obtain_push_consumer (); + break; + } catch (CORBA::COMM_FAILURE& ex) {} + if ( retry_wait > 0 ) { + boost::this_thread::sleep( boost::posix_time::microseconds( retry_wait*1000 ) ); + } else { + boost::this_thread::yield(); + } + tries--; + } while ( tries ); + + ossie::events::EventChannelReg_var ret_reg; + try { + ret_reg = registerResource(req); + } catch ( ... ) { + throw; + } + reg->proxy_consumer->connect_push_supplier( disconnectReceiver ); + + reg->reg.channel_name = CORBA::string_dup(req.channel_name); + reg->reg.reg_id = CORBA::string_dup(ret_reg->reg.reg_id); + reg->channel = ossie::events::EventChannel::_duplicate(ret_reg->channel); + + std::string _reg_id(ret_reg->reg.reg_id); + _pubProxies[_reg_id] = CF::EventPublisher::_duplicate(reg->proxy_consumer); + return reg; + } @@ -636,7 +900,43 @@ void EventChannelManager::restore( ossie::events::EventChannel_ptr savedChannel, // std::string regid(reg.reg_id); std::string cname(reg.channel_name); - + + if (_subProxies.find(regid) != _subProxies.end()) { + try { + _subProxies[regid]->disconnect_push_supplier(); + } catch ( ... ) { + } + _subProxies.erase(regid); + } + + int retries = 10; + int retry_wait = 10; + if (_pubProxies.find(regid) != _pubProxies.end()) { + int tries = retries; + do { + try { + _pubProxies[regid]->disconnect_push_consumer(); + break; + } + catch (CORBA::COMM_FAILURE& ex) { + if ( tries == retries ) { + RH_NL_WARN("Publisher", "::disconnect, Caught COMM_FAILURE Exception " << "disconnecting Push Consumer! Retrying..." ); + } + } catch (...) { + if ( tries == retries ) { + RH_NL_WARN("Publisher", "::disconnect, UNKNOWN Exception " << "disconnecting Push Consumer! Retrying..." ); + } + } + if ( retry_wait > 0 ) { + boost::this_thread::sleep( boost::posix_time::microseconds( retry_wait*1000 ) ); + } else { + boost::this_thread::yield(); + } + tries--; + } while(tries); + _pubProxies.erase(regid); + } + ECM_DEBUG("unregister", "CHECK REGISTRATION, ID:" << regid<< " CHANNEL:" << cname); _regExists( cname, regid ); diff --git a/redhawk/src/control/sdr/dommgr/EventChannelManager.h b/redhawk/src/control/sdr/dommgr/EventChannelManager.h index 7722f25d9..7e188b112 100644 --- a/redhawk/src/control/sdr/dommgr/EventChannelManager.h +++ b/redhawk/src/control/sdr/dommgr/EventChannelManager.h @@ -83,6 +83,18 @@ class EventChannelManager: public virtual EventChannelManagerBase { CF::EventChannelManager::OperationNotAllowed, CF::EventChannelManager::ServiceUnavailable ); + ossie::events::EventChannel_ptr get( const char *channel_name ) + throw ( CF::EventChannelManager::ChannelDoesNotExist, + CF::EventChannelManager::OperationFailed, + CF::EventChannelManager::OperationNotAllowed, + CF::EventChannelManager::ServiceUnavailable ); + + ossie::events::EventChannel_ptr get( const std::string &channel_name ) + throw ( CF::EventChannelManager::ChannelDoesNotExist, + CF::EventChannelManager::OperationFailed, + CF::EventChannelManager::OperationNotAllowed, + CF::EventChannelManager::ServiceUnavailable ); + /* Return an Event Channel in the Domain associated with the Manager from the specified channel_name parameter. @@ -107,6 +119,15 @@ class EventChannelManager: public virtual EventChannelManagerBase { CF::EventChannelManager::OperationNotAllowed, CF::EventChannelManager::ServiceUnavailable ); + /* + Force the removal of the event channel from the Domain + */ + void forceRelease( const char *channel_name ) + throw ( CF::EventChannelManager::ChannelDoesNotExist, + CF::EventChannelManager::OperationFailed, + CF::EventChannelManager::OperationNotAllowed, + CF::EventChannelManager::ServiceUnavailable ); + /* Remove the event channel from the Domain */ @@ -153,6 +174,19 @@ class EventChannelManager: public virtual EventChannelManagerBase { CF::EventChannelManager::OperationNotAllowed, CF::EventChannelManager::ServiceUnavailable ); + ossie::events::EventChannelReg_ptr registerConsumer( CosEventComm::PushConsumer_ptr consumer, const ossie::events::EventRegistration &req) + throw ( CF::EventChannelManager::InvalidChannelName, + CF::EventChannelManager::RegistrationAlreadyExists, + CF::EventChannelManager::OperationFailed, + CF::EventChannelManager::OperationNotAllowed, + CF::EventChannelManager::ServiceUnavailable ); + ossie::events::PublisherReg_ptr registerPublisher( const ossie::events::EventRegistration &req, CosEventComm::PushSupplier_ptr disconnectReceiver) + throw ( CF::EventChannelManager::InvalidChannelName, + CF::EventChannelManager::RegistrationAlreadyExists, + CF::EventChannelManager::OperationFailed, + CF::EventChannelManager::OperationNotAllowed, + CF::EventChannelManager::ServiceUnavailable ); + /* Unregister a publisher or subcriber from an event channel and invalidates the context */ @@ -184,6 +218,9 @@ class EventChannelManager: public virtual EventChannelManagerBase { typedef std::pair< std::string, std::string > RegRecord; typedef std::map< std::string, std::string > RegIdList; + + std::map _subProxies; + std::map _pubProxies; struct ChannelRegistration { std::string channel_name; @@ -226,6 +263,11 @@ class EventChannelManager: public virtual EventChannelManagerBase { CF::EventChannelManager::OperationNotAllowed, CF::EventChannelManager::ServiceUnavailable ); + ossie::events::EventChannel_ptr _get( const std::string &channel_name ) + throw ( CF::EventChannelManager::ChannelDoesNotExist, + CF::EventChannelManager::OperationFailed, + CF::EventChannelManager::OperationNotAllowed, + CF::EventChannelManager::ServiceUnavailable ); ossie::events::EventChannel_ptr _create( const std::string &channel_name, const bool autoRelease=false ) throw ( CF::EventChannelManager::ChannelAlreadyExists, diff --git a/redhawk/src/idl/ossie/CF/EventChannelManager.idl b/redhawk/src/idl/ossie/CF/EventChannelManager.idl index df48404d6..865ec653f 100644 --- a/redhawk/src/idl/ossie/CF/EventChannelManager.idl +++ b/redhawk/src/idl/ossie/CF/EventChannelManager.idl @@ -96,7 +96,7 @@ module CF { typedef CosEventChannelAdmin::EventChannel EventChannel; typedef CosEventChannelAdmin::ProxyPushConsumer EventPublisher; typedef CosEventChannelAdmin::ProxyPushSupplier EventSubscriber; - + /** EventChannelManager Interface */ @@ -125,7 +125,13 @@ module CF { struct EventChannelReg { EventRegistration reg; CosEventChannelAdmin::EventChannel channel; - }; + }; + + struct PublisherReg { + EventRegistration reg; + CosEventChannelAdmin::EventChannel channel; + CF::EventPublisher proxy_consumer; + }; /** @@ -158,6 +164,23 @@ module CF { OperationFailed, ServiceUnavailable ); + /** + create + + Creates an Event Channel construct with the contents of the parameter channel_name + in the Domain associate with this Manager. Event channel names must be unique across the entire domain. + Event Channels created with this manager's interface will remain available for use during the entire duration the Domain + Manager's execution. Event channels can be removed with the release method. + + @param channel_name name of channel to create + @return EventChannel returns an EventChannel + */ + EventChannel get( in string channel_name ) + raises ( ChannelDoesNotExist, + OperationNotAllowed, + OperationFailed, + ServiceUnavailable ); + /** Create an Event Channel in the Domain assocaited with the Manager. Event Channel names must be unique across the Domain. If this channels is used by registrations when all registrants have unregistered the channel resources @@ -189,12 +212,46 @@ module CF { OperationFailed, ServiceUnavailable ); + /** + Force the release of the event channel from the domain. + */ + void forceRelease( in string channel_name ) + raises ( ChannelDoesNotExist, + OperationNotAllowed, + OperationFailed, + ServiceUnavailable ); + + /** + Attach a consumer to the event channel + - a registration is created automatically (use an empty string for automatic registration id) + */ + EventChannelReg registerConsumer( in CosEventComm::PushConsumer consumer, in EventRegistration req) + raises ( InvalidChannelName, + RegistrationAlreadyExists, + OperationFailed, + OperationNotAllowed, + ServiceUnavailable ); + + /** + Attach a publisher (supplier) to the event channel + - a registration is created automatically (use an empty string for automatic registration id) + - disconnectReceiver is to receive the notification that the de-registration of the supplier was + successful. This argument is optional. Use a nil reference to void the argument. + */ + PublisherReg registerPublisher( in EventRegistration req, in CosEventComm::PushSupplier disconnectReceiver) + raises ( InvalidChannelName, + RegistrationAlreadyExists, + OperationFailed, + OperationNotAllowed, + ServiceUnavailable ); /** Register an association with an Event Channel. Look up the registration against the current list for a match, if one exists then throw RegistrationAlreadyExists + + To generate a new unique registration id, pass an empty string in the registration request Look for an existing Event Channel object being managed. If the Event Channel is not found then add a new Event Channel object @@ -209,6 +266,8 @@ module CF { /** Unregister a from an event channel and invalidates the context + - if attachConsumer or attachProducer to create the registration, + the consumer or producer is automatically disconnected */ void unregister( in EventRegistration reg ) raises ( ChannelDoesNotExist, diff --git a/redhawk/src/testing/sdr/dev/services/BasicService_cpp/cpp/BasicService_cpp.cpp b/redhawk/src/testing/sdr/dev/services/BasicService_cpp/cpp/BasicService_cpp.cpp index 8e0a7b6de..da6ef962d 100644 --- a/redhawk/src/testing/sdr/dev/services/BasicService_cpp/cpp/BasicService_cpp.cpp +++ b/redhawk/src/testing/sdr/dev/services/BasicService_cpp/cpp/BasicService_cpp.cpp @@ -36,7 +36,7 @@ void BasicService_cpp_i::move(const char* sourceFileName, const char* destinatio CORBA::Boolean BasicService_cpp_i::exists(const char* fileName) { - CORBA::Boolean tmpVal; + CORBA::Boolean tmpVal = false; // TODO: Fill in this function return tmpVal; @@ -44,7 +44,7 @@ CORBA::Boolean BasicService_cpp_i::exists(const char* fileName) CF::FileSystem::FileInformationSequence* BasicService_cpp_i::list(const char* pattern) { - CF::FileSystem::FileInformationSequence* tmpVal; + CF::FileSystem::FileInformationSequence* tmpVal = new CF::FileSystem::FileInformationSequence(); // TODO: Fill in this function return tmpVal; @@ -52,7 +52,7 @@ CF::FileSystem::FileInformationSequence* BasicService_cpp_i::list(const char* pa CF::File_ptr BasicService_cpp_i::create(const char* fileName) { - CF::File_ptr tmpVal; + CF::File_ptr tmpVal = CF::File::_nil(); // TODO: Fill in this function return tmpVal; @@ -60,7 +60,7 @@ CF::File_ptr BasicService_cpp_i::create(const char* fileName) CF::File_ptr BasicService_cpp_i::open(const char* fileName, CORBA::Boolean read_Only) { - CF::File_ptr tmpVal; + CF::File_ptr tmpVal = CF::File::_nil(); // TODO: Fill in this function return tmpVal; @@ -93,7 +93,7 @@ void BasicService_cpp_i::unmount(const char* mountPoint) CF::FileManager::MountSequence* BasicService_cpp_i::getMounts() { - CF::FileManager::MountSequence* tmpVal; + CF::FileManager::MountSequence* tmpVal = new CF::FileManager::MountSequence(); // TODO: Fill in this function return tmpVal; diff --git a/redhawk/src/testing/tests/test_08_PropertyChangeListener.py b/redhawk/src/testing/tests/test_08_PropertyChangeListener.py index a135b457a..d150b8107 100644 --- a/redhawk/src/testing/tests/test_08_PropertyChangeListener.py +++ b/redhawk/src/testing/tests/test_08_PropertyChangeListener.py @@ -32,35 +32,18 @@ from ossie.events import ChannelManager from ossie.utils import redhawk from ossie.events import Subscriber +from ossie.utils import sb execDeviceNode = "/nodes/test_GPP_node/DeviceManager.dcd.xml" -class Consumer_i(CosEventComm__POA.PushConsumer): - def __init__(self, parent): - self.parent = parent - self.count = 0 - - def push(self, data): - if data: - self.parent.eventFlag = True - self.parent.localEvent.set() - self.count = self.count +1 - - def disconnect_push_consumer (self): - pass - - -class PropertyChangeListener_Receiver(CF__POA.PropertyChangeListener): - def __init__(self): - self.count = 0 - - def propertyChange( self, pce ) : - self.count = self.count +1 - - class PropertyChangeListenerTest(scatest.CorbaTestCase): def setUp(self): self._domBooter, self._domMgr = self.launchDomainManager() + self.dom=redhawk.attach(scatest.getTestDomainName()) + self.count = 0 + + def property_change_callback(self, event_id, registration_id, resource_id, properties, timestamp): + self.count = self.count + 1 def tearDown(self): try: @@ -88,32 +71,28 @@ def tearDown(self): # class tearDown, or failures will occur. scatest.CorbaTestCase.tearDown(self) - def test_PropertyChangeListener_CPP(self): + def baseline_test_PropertyChangeListener(self, app_name, comp_name): self.localEvent = threading.Event() self.eventFlag = False self._devBooter, self._devMgr = self.launchDeviceManager(execDeviceNode, self._domMgr) self.assertNotEqual(self._devBooter, None) - self._domMgr.installApplication("/waveforms/PropertyChangeListenerNoJava/PropertyChangeListenerNoJava.sad.xml") + self._domMgr.installApplication(app_name) appFact = self._domMgr._get_applicationFactories()[0] self.assertNotEqual(appFact, None) app = appFact.create(appFact._get_name(), [], []) self.assertNotEqual(app, None) self._app = app - ps=None c=None - d=redhawk.attach(scatest.getTestDomainName()) - a=d.apps[0] - c=filter( lambda c : c.name == 'PropertyChange_C1', a.comps )[0] + a=self.dom.apps[0] + c=filter( lambda c : c.name == comp_name, a.comps )[0] self.assertNotEqual(c,None) - ps = c.ref._narrow(CF.PropertySet) - self.assertNotEqual(ps,None) - # create listener interface - myl = PropertyChangeListener_Receiver() + # create listener instance + myl = sb.PropertyChangeListener(changeCallbacks={'prop1':self.property_change_callback}) t=float(0.5) - regid=ps.registerPropertyListener( myl._this(), ['prop1'],t) + regid=c.registerPropertyListener( myl, ['prop1'], t) app.start() time.sleep(1) @@ -127,161 +106,39 @@ def test_PropertyChangeListener_CPP(self): time.sleep(.6) # wait for listener to receive notice # now check results - self.assertEquals(myl.count,4) + self.assertEquals(self.count,4) # change unmonitored property c.prop2 = 100 time.sleep(.6) # wait for listener to receive notice # now check results - self.assertEquals(myl.count,4) + self.assertEquals(self.count,4) # unregister - ps.unregisterPropertyListener( regid ) + c.unregisterPropertyListener( regid ) c.prop1 = 100.0 time.sleep(.6) # wait for listener to receive notice # now check results, should be same... - self.assertEquals(myl.count,4) + self.assertEquals(self.count,4) self.assertRaises( CF.InvalidIdentifier, - ps.unregisterPropertyListener, regid ) - + c.unregisterPropertyListener, regid ) app.releaseObject() self._app=None - - - def test_PropertyChangeListener_PYTHON(self): - self.localEvent = threading.Event() - self.eventFlag = False - - self._devBooter, self._devMgr = self.launchDeviceManager(execDeviceNode, self._domMgr) - self.assertNotEqual(self._devBooter, None) - self._domMgr.installApplication("/waveforms/PropertyChangeListenerNoJava/PropertyChangeListenerNoJava.sad.xml") - appFact = self._domMgr._get_applicationFactories()[0] - self.assertNotEqual(appFact, None) - app = appFact.create(appFact._get_name(), [], []) - self.assertNotEqual(app, None) - self._app=app - - ps=None - c=None - d=redhawk.attach(scatest.getTestDomainName()) - a=d.apps[0] - c=filter( lambda c : c.name == 'PropertyChange_P1', a.comps )[0] - self.assertNotEqual(c,None) - ps = c.ref._narrow(CF.PropertySet) - self.assertNotEqual(ps,None) - - # create listener interface - myl = PropertyChangeListener_Receiver() - t=float(0.5) - regid=ps.registerPropertyListener( myl._this(), ['prop1'],t) - app.start() - time.sleep(1) - - # assign 3 changed values - c.prop1 = 100.0 - time.sleep(.6) # wait for listener to receive notice - c.prop1 = 200.0 - time.sleep(.6) # wait for listener to receive notice - c.prop1 = 300.0 - time.sleep(.6) # wait for listener to receive notice - - # now check results - self.assertEquals(myl.count,4) - - # change unmonitored property - c.prop2 = 100 - time.sleep(.6) # wait for listener to receive notice - - # now check results - self.assertEquals(myl.count,4) - - # unregister - ps.unregisterPropertyListener( regid ) - - c.prop1 = 100.0 - time.sleep(.6) # wait for listener to receive notice - # now check results, should be same... - self.assertEquals(myl.count,4) - - self.assertRaises( CF.InvalidIdentifier, - ps.unregisterPropertyListener, regid ) - - - app.releaseObject() - self._app=None + def test_PropertyChangeListener_CPP(self): + self.baseline_test_PropertyChangeListener("/waveforms/PropertyChangeListenerNoJava/PropertyChangeListenerNoJava.sad.xml", 'PropertyChange_C1') + def test_PropertyChangeListener_PYTHON(self): + self.baseline_test_PropertyChangeListener("/waveforms/PropertyChangeListenerNoJava/PropertyChangeListenerNoJava.sad.xml", 'PropertyChange_P1') @scatest.requireJava def test_PropertyChangeListener_JAVA(self): - self.localEvent = threading.Event() - self.eventFlag = False - - self._devBooter, self._devMgr = self.launchDeviceManager(execDeviceNode, self._domMgr) - self.assertNotEqual(self._devBooter, None) - self._domMgr.installApplication("/waveforms/PropertyChangeListener/PropertyChangeListener.sad.xml") - appFact = self._domMgr._get_applicationFactories()[0] - self.assertNotEqual(appFact, None) - app = appFact.create(appFact._get_name(), [], []) - self.assertNotEqual(app, None) - self._app=app - - ps=None - c=None - d=redhawk.attach(scatest.getTestDomainName()) - a=d.apps[0] - c=filter( lambda c : c.name == 'PropertyChange_J1', a.comps )[0] - self.assertNotEqual(c,None) - ps = c.ref._narrow(CF.PropertySet) - self.assertNotEqual(ps,None) - - # create listener interface - myl = PropertyChangeListener_Receiver() - t=float(0.5) - regid=ps.registerPropertyListener( myl._this(), ['prop1'],t) - - app.start() - time.sleep(1) - - # assign 3 changed values - c.prop1 = 100.0 - time.sleep(.6) # wait for listener to receive notice - c.prop1 = 200.0 - time.sleep(.6) # wait for listener to receive notice - c.prop1 = 300.0 - time.sleep(.6) # wait for listener to receive notice - - # now check results - self.assertEquals(myl.count,4) - - # change unmonitored property - c.prop2 = 100 - time.sleep(.6) # wait for listener to receive notice - - # now check results - self.assertEquals(myl.count,4) - - # unregister - ps.unregisterPropertyListener( regid ) - - c.prop1 = 100.0 - time.sleep(.6) # wait for listener to receive notice - - # now check results, should be same... - self.assertEquals(myl.count,4) - - self.assertRaises( CF.InvalidIdentifier, - ps.unregisterPropertyListener, regid ) - - - app.releaseObject() - self._app=None - + self.baseline_test_PropertyChangeListener("/waveforms/PropertyChangeListener/PropertyChangeListener.sad.xml", 'PropertyChange_J1') def test_PropertyChangeListener_APP(self): self.localEvent = threading.Event() @@ -296,10 +153,8 @@ def test_PropertyChangeListener_APP(self): self.assertNotEqual(app, None) self._app=app - ps=None c=None - d=redhawk.attach(scatest.getTestDomainName()) - a=d.apps[0] + a=self.dom.apps[0] # component with external property c=filter( lambda c : c.name == 'PropertyChange_C1', a.comps )[0] # assembly controller @@ -307,13 +162,11 @@ def test_PropertyChangeListener_APP(self): self.assertNotEqual(a,None) self.assertNotEqual(c,None) self.assertNotEqual(c2,None) - ps = a.ref._narrow(CF.PropertySet) - self.assertNotEqual(ps,None) # create listener interface - myl = PropertyChangeListener_Receiver() + myl = sb.PropertyChangeListener(defaultCallback = self.property_change_callback) t=float(0.5) - regid=ps.registerPropertyListener( myl._this(), ['prop1', 'app_prop1'],t) + regid=a.registerPropertyListener( myl, ['prop1', 'app_prop1'], t) app.start() time.sleep(1) @@ -330,7 +183,7 @@ def test_PropertyChangeListener_APP(self): time.sleep(.6) # wait for listener to receive notice # now check results - self.assertEquals(myl.count,8) + self.assertEquals(self.count,8) # change unmonitored property c.prop2 = 100 @@ -338,20 +191,20 @@ def test_PropertyChangeListener_APP(self): time.sleep(.6) # wait for listener to receive notice # now check results - self.assertEquals(myl.count,8) + self.assertEquals(self.count,8) # unregister - ps.unregisterPropertyListener( regid ) + a.unregisterPropertyListener( regid ) c.prop1 = 100.0 c2.prop1 = 100.0 time.sleep(.6) # wait for listener to receive notice # now check results, should be same... - self.assertEquals(myl.count,8) + self.assertEquals(self.count,8) self.assertRaises( CF.InvalidIdentifier, - ps.unregisterPropertyListener, regid ) + a.unregisterPropertyListener, regid ) app.releaseObject() self._app=None @@ -360,18 +213,21 @@ def test_PropertyChangeListener_APP(self): class PropertyChangeListenerEventTest(scatest.CorbaTestCase): def setUp(self): self._domBooter, self._domMgr = self.launchDomainManager() + self.dom=redhawk.attach(scatest.getTestDomainName()) # create listener interface - orb = CORBA.ORB_init() - self.chanMgr = ChannelManager(orb) self._app=None - # Force creation - self.channel1 = self.chanMgr.createEventChannel("TestChan", force=True) + self.channel_name = "TestChan" + self.chanMgr = self.dom._get_eventChannelMgr() + try: + self.channel1 = self.chanMgr.create(self.channel_name) + except CF.EventChannelManager.ChannelAlreadyExists: + self.channel1 = self.chanMgr.get(self.channel_name) def tearDown(self): try: if self.channel1: - self.chanMgr.destroyEventChannel("TestChan") + self.chanMgr.release(self.channel_name) except: pass @@ -401,36 +257,32 @@ def tearDown(self): scatest.CorbaTestCase.tearDown(self) - def test_PropertyChangeListener_EC_CPP(self): + def base_test_PropertyChangeListener_EC_Comps(self, app_name, comp_name): self.localEvent = threading.Event() self.eventFlag = False self._devBooter, self._devMgr = self.launchDeviceManager(execDeviceNode, self._domMgr) self.assertNotEqual(self._devBooter, None) - self._domMgr.installApplication("/waveforms/PropertyChangeListenerNoJava/PropertyChangeListenerNoJava.sad.xml") + self._domMgr.installApplication(app_name) appFact = self._domMgr._get_applicationFactories()[0] self.assertNotEqual(appFact, None) app = appFact.create(appFact._get_name(), [], []) self.assertNotEqual(app, None) self._app = app - ps=None c=None - d=redhawk.attach(scatest.getTestDomainName()) - a=d.apps[0] - c=filter( lambda c : c.name == 'PropertyChange_C1', a.comps )[0] + a=self.dom.apps[0] + c=filter( lambda c : c.name == comp_name, a.comps )[0] self.assertNotEqual(c,None) - ps = c.ref._narrow(CF.PropertySet) - self.assertNotEqual(ps,None) # check if channel is valid self.assertNotEqual(self.channel1, None) self.assertNotEqual(self.channel1._narrow(CosEventChannelAdmin.EventChannel), None) - sub = Subscriber( self.channel1 ) + sub = Subscriber( self.dom, self.channel_name ) t=float(0.5) - regid=ps.registerPropertyListener( self.channel1, ['prop1'],t) + regid=c.registerPropertyListener( self.channel1, ['prop1'],t) app.start() time.sleep(1) @@ -447,122 +299,24 @@ def test_PropertyChangeListener_EC_CPP(self): self.assertNotEqual(xx, None) # unregister - ps.unregisterPropertyListener( regid ) + c.unregisterPropertyListener( regid ) self.assertRaises( CF.InvalidIdentifier, - ps.unregisterPropertyListener, regid ) + c.unregisterPropertyListener, regid ) + app.stop() app.releaseObject() self._app=None - def test_PropertyChangeListener_EC_PYTHON(self): - self.localEvent = threading.Event() - self.eventFlag = False - - self._devBooter, self._devMgr = self.launchDeviceManager(execDeviceNode, self._domMgr) - self.assertNotEqual(self._devBooter, None) - self._domMgr.installApplication("/waveforms/PropertyChangeListenerNoJava/PropertyChangeListenerNoJava.sad.xml") - appFact = self._domMgr._get_applicationFactories()[0] - self.assertNotEqual(appFact, None) - app = appFact.create(appFact._get_name(), [], []) - self.assertNotEqual(app, None) - self._app = app - - ps=None - c=None - d=redhawk.attach(scatest.getTestDomainName()) - a=d.apps[0] - c=filter( lambda c : c.name == 'PropertyChange_P1', a.comps )[0] - self.assertNotEqual(c,None) - ps = c.ref._narrow(CF.PropertySet) - self.assertNotEqual(ps,None) - - # check if channel is valid - self.assertNotEqual(self.channel1, None) - self.assertNotEqual(self.channel1._narrow(CosEventChannelAdmin.EventChannel), None) - - sub = Subscriber( self.channel1 ) - - t=float(0.5) - regid=ps.registerPropertyListener( self.channel1, ['prop1'],t) - app.start() - time.sleep(1) - - # assign 3 changed values - c.prop1 = 100.0 - time.sleep(.6) # wait for listener to receive notice - c.prop1 = 200.0 - time.sleep(.6) # wait for listener to receive notice - c.prop1 = 300.0 - time.sleep(.6) # wait for listener to receive notice - - for n in range(4): - xx=sub.getData() - self.assertNotEqual(xx, None) - - # unregister - ps.unregisterPropertyListener( regid ) - - self.assertRaises( CF.InvalidIdentifier, - ps.unregisterPropertyListener, regid ) + def test_PropertyChangeListener_EC_CPP(self): + self.base_test_PropertyChangeListener_EC_Comps("/waveforms/PropertyChangeListenerNoJava/PropertyChangeListenerNoJava.sad.xml", 'PropertyChange_C1') - app.releaseObject() - self._app=None + def test_PropertyChangeListener_EC_PYTHON(self): + self.base_test_PropertyChangeListener_EC_Comps("/waveforms/PropertyChangeListenerNoJava/PropertyChangeListenerNoJava.sad.xml", 'PropertyChange_P1') @scatest.requireJava def test_PropertyChangeListener_EC_JAVA(self): - self.localEvent = threading.Event() - self.eventFlag = False - - self._devBooter, self._devMgr = self.launchDeviceManager(execDeviceNode, self._domMgr) - self.assertNotEqual(self._devBooter, None) - self._domMgr.installApplication("/waveforms/PropertyChangeListener/PropertyChangeListener.sad.xml") - appFact = self._domMgr._get_applicationFactories()[0] - self.assertNotEqual(appFact, None) - app = appFact.create(appFact._get_name(), [], []) - self.assertNotEqual(app, None) - self._app = app - - ps=None - c=None - d=redhawk.attach(scatest.getTestDomainName()) - a=d.apps[0] - c=filter( lambda c : c.name == 'PropertyChange_J1', a.comps )[0] - self.assertNotEqual(c,None) - ps = c.ref._narrow(CF.PropertySet) - self.assertNotEqual(ps,None) - - # check if channel is valid - self.assertNotEqual(self.channel1, None) - self.assertNotEqual(self.channel1._narrow(CosEventChannelAdmin.EventChannel), None) - - sub = Subscriber( self.channel1 ) - - t=float(0.5) - regid=ps.registerPropertyListener( self.channel1, ['prop1'],t) - app.start() - time.sleep(1) - - # assign 3 changed values - c.prop1 = 100.0 - time.sleep(.6) # wait for listener to receive notice - c.prop1 = 200.0 - time.sleep(.6) # wait for listener to receive notice - c.prop1 = 300.0 - time.sleep(.6) # wait for listener to receive notice - - for n in range(4): - xx=sub.getData() - self.assertNotEqual(xx, None) - - # unregister - ps.unregisterPropertyListener( regid ) - - self.assertRaises( CF.InvalidIdentifier, - ps.unregisterPropertyListener, regid ) - - app.releaseObject() - self._app=None + self.base_test_PropertyChangeListener_EC_Comps("/waveforms/PropertyChangeListener/PropertyChangeListener.sad.xml", 'PropertyChange_J1') def test_PropertyChangeListener_EC_APP(self): self.localEvent = threading.Event() @@ -577,10 +331,8 @@ def test_PropertyChangeListener_EC_APP(self): self.assertNotEqual(app, None) self._app = app - ps=None c=None - d=redhawk.attach(scatest.getTestDomainName()) - a=d.apps[0] + a=self.dom.apps[0] # component with external property c=filter( lambda c : c.name == 'PropertyChange_C1', a.comps )[0] # assembly controller @@ -588,8 +340,6 @@ def test_PropertyChangeListener_EC_APP(self): self.assertNotEqual(a,None) self.assertNotEqual(c,None) self.assertNotEqual(c2,None) - ps = a.ref._narrow(CF.PropertySet) - self.assertNotEqual(ps,None) # check if channel is valid self.assertNotEqual(self.channel1, None) @@ -598,7 +348,7 @@ def test_PropertyChangeListener_EC_APP(self): sub = Subscriber( self.channel1 ) t=float(0.5) - regid=ps.registerPropertyListener( self.channel1, ['prop1', 'app_prop1'],t) + regid=a.registerPropertyListener( self.channel1, ['prop1', 'app_prop1'],t) app.start() time.sleep(1) @@ -615,10 +365,10 @@ def test_PropertyChangeListener_EC_APP(self): self.assertNotEqual(xx, None) # unregister - ps.unregisterPropertyListener( regid ) + a.unregisterPropertyListener( regid ) self.assertRaises( CF.InvalidIdentifier, - ps.unregisterPropertyListener, regid ) + a.unregisterPropertyListener, regid ) app.releaseObject() self._app=None diff --git a/redhawk/src/testing/tests/test_13_RedhawkModule.py b/redhawk/src/testing/tests/test_13_RedhawkModule.py index 48e958892..ebaab18d8 100644 --- a/redhawk/src/testing/tests/test_13_RedhawkModule.py +++ b/redhawk/src/testing/tests/test_13_RedhawkModule.py @@ -22,11 +22,70 @@ from _unitTestHelpers import scatest import time from omniORB import CORBA +from omniORB import any as _any from xml.dom import minidom import os as _os from ossie.cf import CF from ossie.utils import redhawk from ossie.utils import type_helpers +from ossie.events import Subscriber, Publisher +from ossie.cf import CF + +class RedhawkModuleEventChannelTest(scatest.CorbaTestCase): + def setUp(self): + domBooter, self._domMgr = self.launchDomainManager() + self.ecm = self._domMgr._get_eventChannelMgr() + self.channelName = 'TestChan' + try: + self.channel = self.ecm.create(self.channelName) + except CF.EventChannelManager.ChannelAlreadyExists: + pass + self.channel = self.ecm.get(self.channelName) + + def tearDown(self): + try: + self.ecm.release(self.channelName) + except CF.EventChannelManager.ChannelDoesNotExist: + pass + scatest.CorbaTestCase.tearDown(self) + + def test_eventChannelPull(self): + sub = Subscriber(self._domMgr, self.channelName) + pub = Publisher(self._domMgr, self.channelName) + payload = 'hello' + data = _any.to_any(payload) + pub.push(data) + time.sleep(1) + self.rec_data = sub.getData() + self.assertEquals(self.rec_data, payload) + pub.terminate() + sub.terminate() + + def test_eventChannelForceDelete(self): + sub = Subscriber(self._domMgr, self.channelName) + pub = Publisher(self._domMgr, self.channelName) + payload = 'hello' + data = _any.to_any(payload) + pub.push(data) + time.sleep(1) + self.rec_data = sub.getData() + self.assertEquals(self.rec_data, payload) + self.ecm.forceRelease(self.channelName) + self.assertRaises(CF.EventChannelManager.ChannelDoesNotExist, self.ecm.release, self.channelName) + + def callback(self, data): + self.rec_data = data + + def test_eventChannelCB(self): + sub = Subscriber(self._domMgr, self.channelName, dataArrivedCB=self.callback) + pub = Publisher(self._domMgr, self.channelName) + payload = 'hello' + data = _any.to_any(payload) + pub.push(data) + time.sleep(1) + self.assertEquals(self.rec_data, payload) + pub.terminate() + sub.terminate() class RedhawkModuleTest(scatest.CorbaTestCase): def setUp(self): diff --git a/redhawk/src/testing/tests/test_13_TestSB.py b/redhawk/src/testing/tests/test_13_TestSB.py index 86ab6fc3b..302330fab 100644 --- a/redhawk/src/testing/tests/test_13_TestSB.py +++ b/redhawk/src/testing/tests/test_13_TestSB.py @@ -38,6 +38,7 @@ from ossie.cf import CF, StandardEvent from ossie.utils import sb, type_helpers from ossie.utils.bulkio import bulkio_helpers +from ossie.events import ChannelManager, Subscriber, Publisher from _unitTestHelpers import scatest, runtestHelpers @@ -126,6 +127,61 @@ def test_NoInteractiveCppComponent(self): status, output=commands.getstatusoutput('sdr/dom/components/ECM_CPP/cpp/ECM_CPP -i') self.assertEquals(output,self.message) +class SBEventChannelTest(scatest.CorbaTestCase): + def setUp(self): + orb = CORBA.ORB_init() + self.chanMgr = ChannelManager(orb) + self._app=None + self.rec_data = None + # Force creation + self.channel = self.chanMgr.createEventChannel("TestChan", force=True) + sb.setDEBUG(False) + self.test_comp = "Sandbox" + # Flagrant violation of sandbox API: if the sandbox singleton exists, + # clean up previous state and dispose of it. + if sb.domainless._sandbox: + sb.domainless._sandbox.shutdown() + sb.domainless._sandbox = None + + def assertComponentCount(self, count): + self.assertEquals(len(sb.domainless._getSandbox().getComponents()), count) + + def tearDown(self): + try: + if self.channel: + self.chanMgr.destroyEventChannel("TestChan") + except: + pass + sb.release() + sb.setDEBUG(False) + os.environ['SDRROOT'] = globalsdrRoot + + def test_PublishSubscribePull(self): + sub = Subscriber( self.channel ) + pub = Publisher( self.channel ) + payload = 'hello' + data = any.to_any(payload) + pub.push(data) + time.sleep(1) + self.rec_data = sub.getData() + self.assertEquals(self.rec_data, payload) + pub.terminate() + sub.terminate() + + def callback(self, data): + self.rec_data = data + + def test_PublishSubscribeCB(self): + sub = Subscriber(self.channel, dataArrivedCB=self.callback) + pub = Publisher(self.channel) + payload = 'hello' + data = any.to_any(payload) + pub.push(data) + time.sleep(1) + self.assertEquals(self.rec_data, payload) + pub.terminate() + sub.terminate() + class SBTestTest(scatest.CorbaTestCase): def setUp(self): sb.setDEBUG(False) From 22f1699c9c8624a84abeda94c6c234cb25d3fd8f Mon Sep 17 00:00:00 2001 From: Max Robert Date: Thu, 26 Jan 2017 16:36:02 -0500 Subject: [PATCH 0668/1644] Refs CF-1594. Removed reference to interactive mode in command-line help --- .../ossie/src/org/ossie/component/Resource.java | 14 +++++--------- .../src/base/framework/python/ossie/resource.py | 17 +---------------- 2 files changed, 6 insertions(+), 25 deletions(-) diff --git a/redhawk/src/base/framework/java/ossie/src/org/ossie/component/Resource.java b/redhawk/src/base/framework/java/ossie/src/org/ossie/component/Resource.java index 5dbff6955..c3f2c01ca 100644 --- a/redhawk/src/base/framework/java/ossie/src/org/ossie/component/Resource.java +++ b/redhawk/src/base/framework/java/ossie/src/org/ossie/component/Resource.java @@ -1240,15 +1240,11 @@ public static void start_component(final Class clazz, final } if ((nameContext == null) || (nameBinding == null)) { - if ((!Arrays.toString(args).contains("-i")) && (!Arrays.toString(args).contains("--interactive"))) { - System.out.println("usage: "+clazz+" [options] [execparams]\n"); - System.out.println("The set of execparams is defined in the .prf for the component"); - System.out.println("They are provided as arguments pairs ID VALUE, for example:"); - System.out.println(" "+clazz+" INT_PARAM 5 STR_PARAM ABCDED\n"); - System.out.println("Options:"); - System.out.println(" -i,--interactive Run the component in interactive test mode\n"); - System.exit(-1); - } + System.out.println("usage: "+clazz+" [options] [execparams]\n"); + System.out.println("The set of execparams is defined in the .prf for the component"); + System.out.println("They are provided as arguments pairs ID VALUE, for example:"); + System.out.println(" "+clazz+" INT_PARAM 5 STR_PARAM ABCDED\n"); + System.exit(-1); } logging.ComponentCtx ctx = new logging.ComponentCtx( nameBinding, identifier, dom_path ); diff --git a/redhawk/src/base/framework/python/ossie/resource.py b/redhawk/src/base/framework/python/ossie/resource.py index ee4a34e42..40b04c64a 100644 --- a/redhawk/src/base/framework/python/ossie/resource.py +++ b/redhawk/src/base/framework/python/ossie/resource.py @@ -1183,9 +1183,6 @@ def _getOptions(classtype): print "They are provided as arguments pairs ID VALUE, for example:" print " %s INT_PARAM 5 STR_PARAM ABCDED" % sys.argv[0] print - print "Options:" - print " -i,--interactive Run the component in interactive test mode" - print print classtype.__doc__ sys.exit(2) except getopt.GetoptError: @@ -1195,9 +1192,6 @@ def _getOptions(classtype): print "They are provided as arguments pairs ID VALUE, for example:" print " %s INT_PARAM 5 STR_PARAM ABCDED" % sys.argv[0] print - print "Options:" - print " -i,--interactive Run the component in interactive test mode" - print print classtype.__doc__ sys.exit(2) return opts, args @@ -1208,16 +1202,7 @@ def setupSignalHandlers(): signal.signal(signal.SIGTERM, __exit_handler) def _getInteractive(opts): - """ - If opts contains '-1' or '--interactive', return True, otherwise - return False. - """ - - interactive = False - for opt, unused in opts: - if opt == "-i" or opt == "--interactive": - interactive = True - return interactive + return False def parseCommandLineArgs(componentclass): opts, args = _getOptions(componentclass) From 91df7c6f5c4dee1298b57e4b41129a79d3141540 Mon Sep 17 00:00:00 2001 From: 8530 <8530@vm-131.vsi-corp.com> Date: Fri, 27 Jan 2017 09:27:30 -0500 Subject: [PATCH 0669/1644] added sri and timestamp parameters to DataSource's push method, CF-205 --- .../base/framework/python/ossie/properties.py | 3 + .../python/ossie/utils/sb/io_helpers.py | 239 +++++++++++++++--- redhawk/src/testing/tests/test_13_TestSB.py | 206 ++++++++++++++- 3 files changed, 405 insertions(+), 43 deletions(-) diff --git a/redhawk/src/base/framework/python/ossie/properties.py b/redhawk/src/base/framework/python/ossie/properties.py index 33c55e25b..d4b3c00a6 100644 --- a/redhawk/src/base/framework/python/ossie/properties.py +++ b/redhawk/src/base/framework/python/ossie/properties.py @@ -145,6 +145,9 @@ 'complexLong', 'complexLongLong', 'complexULongLong', 'utctime' ] +def getTypeMap(): + return __TYPE_MAP + def getPyType(type_, alt_map=None): if alt_map: try: diff --git a/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py b/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py index ae3653ab1..eb0b6f368 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py +++ b/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py @@ -46,6 +46,7 @@ import socket as _socket from omniORB import any as _any from omniORB import CORBA as _CORBA +import copy as _copy import omniORB as _omniORB import CosEventComm__POA import warnings as _warnings @@ -62,7 +63,7 @@ __all__ = ('DataSink', 'DataSource', 'FileSink', 'FileSource', 'MessageSink', 'MessageSource','MsgSupplierHelper', 'Plot', 'SRIKeyword', 'compareSRI', 'helperBase', 'probeBULKIO','createSDDSStreamDefinition', 'DataSourceSDDS', - 'DataSinkSDDS') + 'DataSinkSDDS', 'createTimeStamp', 'createSRI', 'compareKeywordLists') def compareSRI(a, b): ''' @@ -93,12 +94,25 @@ def compareSRI(a, b): if len(a.keywords) != len(b.keywords): return False for keyA, keyB in zip(a.keywords, b.keywords): + if keyA.id != keyB.id: + return False if keyA.value._t != keyB.value._t: return False if keyA.value._v != keyB.value._v: return False return True +def compareKeywordLists( a, b ): + for keyA, keyB in zip(a, b): + if keyA.id != keyB.id: + return False + if keyA.value._t != keyB.value._t: + return False + if keyA.value._v != keyB.value._v: + return False + return True + + def _checkComplex(data): for item in data: if isinstance(item, complex): @@ -1120,7 +1134,8 @@ def __init__(self, bytesPerPush = 512000, startTime = 0.0, blocking = True, - subsize = 0): + subsize = 0, + sri = None): self.threadExited = None @@ -1133,8 +1148,9 @@ def __init__(self, self._sampleRate = None self._onPushSampleRate = None self._complexData = None + self._streamID = None self._SRIKeywords = [] - self._sri = None + self._sri = sri self._startTime = startTime self._timePush = None self._blocking = blocking @@ -1170,14 +1186,50 @@ def start(self): self._runThread.setDaemon(True) self._runThread.start() + + def sri(self): + if self._sri != None: + return _copy.copy(self._sri) + else: + # make a default sri from the current state + keywords = [] + try: + for key in self._SRIKeywords: + keywords.append(_CF.DataType(key._name, _properties.to_tc_value(key._value,str(key._format)))) + except: + pass + candidateSri = _BULKIO.StreamSRI(1, 0.0, 1, 0, self._subsize, 0.0, 0, 0, 0, + "defaultStreamID", self._blocking, keywords) + if self._sampleRate > 0.0: + candidateSri.xdelta = 1.0/float(self._sampleRate) + + if self._complexData and self._complexData == True: + candidateSri.mode = 1 + + if self._startTime >= 0.0: + candidateSri.xstart = self._startTime + return candidateSri + + def sendEOS(self, streamID=None): + if streamID: + self.push([],EOS=True, streamID=streamID ) + else: + if self._sri: + self.push([],EOS=True, streamID=self._sri.streamID ) + else: + self.push([],EOS=True ) + + def push(self, data, EOS = False, - streamID = "defaultStreamID", + streamID = None, sampleRate = None, complexData = False, SRIKeywords = [], - loop = None): + loop = None, + sri = None, + ts = None ): """ Push an arbitrary data vector @@ -1189,7 +1241,7 @@ def push(self, # If complex values are present, interleave the data as scalar values # and set the complex flag - if _complexData: + if _complexData or ( self._sri and self._sri.mode == 1): if self._dataFormat in ('octet', 'short', 'ushort', 'long', 'ulong', 'longlong', 'ulonglong'): itemType = int else: @@ -1197,13 +1249,32 @@ def push(self, data = _bulkio_helpers.pythonComplexListToBulkioComplex(data, itemType) complexData = True - if sampleRate == None and self._onPushSampleRate != None: - sampleRate = self._onPushSampleRate - elif sampleRate == None and self._onPushSampleRate == None: - sampleRate = 1.0 - self._onPushSampleRate = sampleRate + # if no stream id is provided then try and use prior stream id + if streamID == None: + if self._sri == None and sri == None: + if self._streamID != None: + streamID = self._streamID + elif sri != None: + streamID = sri.streamID + elif self._sri != None: + streamID = self._sri.streamID + + # if no stream id is provided then use default + if streamID == None: + streamID = "defaultStreamID" + + if sampleRate == None: + # if no sample rate provide and no sri provide then use prior sample rate if available + if sri != None: + if sri.xdelta > 0.0: + self._onPushSampleRate = 1.0/sri.xdelta + if self._onPushSampleRate != None: + sampleRate = self._onPushSampleRate else: - self._onPushSampleRate = sampleRate + # if we are given a new sample rate then save this off + if self._onPushSampleRate == None or ( self._onPushSampleRate != sampleRate ): + # save off, data consumer thread can be slower so we can use sri + self._onPushSampleRate = sampleRate self._dataQueue.put((data, EOS, @@ -1211,7 +1282,9 @@ def push(self, sampleRate, complexData, SRIKeywords, - loop)) + loop, + sri, + ts)) self._packetQueued() def _packetQueued(self): @@ -1262,45 +1335,102 @@ def pushThread(self): complexData = dataset[4] SRIKeywords = dataset[5] loop = dataset[6] + sri = dataset[7] + ts = dataset[8] # If loop is set in method call, override class attribute if loop != None: self._loop = loop try: - self._sampleRate = sampleRate - self._complexData = complexData - self._SRIKeywords = SRIKeywords - self._streamID = streamID - candidateSri = None - # If any SRI info is set, call pushSRI - if streamID != None or \ - sampleRate != None or \ - complexData != None or \ - len(SRIKeywords) > 0: - keywords = [] - for key in self._SRIKeywords: - keywords.append(_CF.DataType(key._name, _properties.to_tc_value(key._value,str(key._format)))) - candidateSri = _BULKIO.StreamSRI(1, 0.0, 1, 0, self._subsize, 0.0, 0, 0, 0, - streamID, self._blocking, keywords) - - if sampleRate > 0.0: - candidateSri.xdelta = 1.0/float(sampleRate) + if sri == None and self._sri == None : + if sampleRate == None : sampleRate=1.0 + self._sampleRate = sampleRate + self._complexData = complexData + self._SRIKeywords = SRIKeywords + self._streamID = streamID + candidateSri = None + # If any SRI info is set, call pushSRI + if streamID != None or \ + sampleRate != None or \ + complexData != None or \ + len(SRIKeywords) > 0: + keywords = [] + for key in self._SRIKeywords: + keywords.append(_CF.DataType(key._name, _properties.to_tc_value(key._value,str(key._format)))) + candidateSri = _BULKIO.StreamSRI(1, 0.0, 1, 0, self._subsize, 0.0, 0, 0, 0, + streamID, self._blocking, keywords) + + if sampleRate > 0.0: + candidateSri.xdelta = 1.0/float(sampleRate) + self._onPushSampleRate = sampleRate + + if complexData == True: + candidateSri.mode = 1 + else: + candidateSri.mode = 0 + + if self._startTime >= 0.0: + candidateSri.xstart = self._startTime + + else: + candidateSri = _BULKIO.StreamSRI(1, 0.0, 1, 0, self._subsize, 0.0, 0, 0, 0, + "defaultStreamID", self._blocking, []) + else: + candidateSri = _copy.copy(self._sri) + if sri != None: + # user supplied sri + candidateSri = sri + + if streamID and streamID != candidateSri.streamID: + candidateSri.streamID = streamID + self._streamID = streamID + + if sampleRate == None: + sampleRate = 1.0/candidateSri.xdelta + self._sampleRate = sampleRate + self._onPushSampleRate = sampleRate + else: + if sampleRate > 0.0: + candidateSri.xdelta = 1.0/float(sampleRate) + self._sampleRate = sampleRate + self._onPushSampleRate = sampleRate if complexData == True: candidateSri.mode = 1 + self._complexData = 1 else: candidateSri.mode = 0 + self._complexData = 0 if self._startTime >= 0.0: candidateSri.xstart = self._startTime - else: - candidateSri = _BULKIO.StreamSRI(1, 0.0, 1, 0, self._subsize, 0.0, 0, 0, 0, - "defaultStreamID", self._blocking, []) + + # handle keywords + if len(SRIKeywords) > 0 : + self._SRIKeywords = SRIKeywords + # need to keep order for compareSRI + ckeys = [ x.name for x in candidateSri.keywords ] + keywords = candidateSri.keywords[:] + for key in self._SRIKeywords: + # if current sri contains they keyword then overwrite else append + kw=_CF.DataType(key._name, _properties.to_tc_value(key._value,str(key._format))) + if key._name in ckeys: + # replace that keyword + for x in range(len(keywords)): + if keywords[x].id == kw.id : + keywords[x] = kw + else: + keywords.append(kw) + candidateSri.keywords = keywords if self._sri==None or not compareSRI(candidateSri, self._sri): self._sri = candidateSri self._pushSRIAllConnectedPorts(sri = self._sri) + # if we are give a timestamp then use it as is + if ts != None: + self._currentSampleTime = ts + # Call pushPacket # If necessary, break data into chunks of pktSize for each # pushPacket @@ -1383,6 +1513,11 @@ def _pushPackets(self, packetEOS, streamID, srcPortType) + # covert time stamp if necessary + if isinstance(currentSampleTime,_BULKIO.PrecisionUTCTime): + self._currentSampleTime = currentSampleTime.twsec + currentSampleTime.tfsec + currentSampleTime = self._currentSampleTime + self._currentSampleTime += sampleTimeForPush currentSampleTime += sampleTimeForPush else: @@ -1413,11 +1548,14 @@ def _pushPacket(self, data = _bulkio_helpers.formatData(data, BULKIOtype=eval(srcPortType)) - T = _BULKIO.PrecisionUTCTime(_BULKIO.TCM_CPU, - _BULKIO.TCS_VALID, - 0.0, - int(currentSampleTime), - currentSampleTime - int(currentSampleTime)) + if isinstance(currentSampleTime,_BULKIO.PrecisionUTCTime): + T= currentSampleTime + else: + T = _BULKIO.PrecisionUTCTime(_BULKIO.TCM_CPU, + _BULKIO.TCS_VALID, + 0.0, + int(currentSampleTime), + currentSampleTime - int(currentSampleTime)) if srcPortType != "_BULKIO__POA.dataXML": _bulkio_data_helpers.ArraySource.pushPacket(arraySrcInst, data = data, @@ -1438,6 +1576,7 @@ def _pushSRIAllConnectedPorts(self, sri): def _pushSRI(self, arraySrcInst, srcPortType, sri): if srcPortType != "_BULKIO__POA.dataXML": + #print "_pushSRI ", sri _bulkio_data_helpers.ArraySource.pushSRI(arraySrcInst, sri) else: _bulkio_data_helpers.XmlArraySource.pushSRI(arraySrcInst, sri) @@ -1711,6 +1850,22 @@ class SRIKeyword(object): - boolean ''' def __init__(self, name, value, format): - self._name = name - self._value = value - self._format = format + # validate format is legal type to convert to + if format in _properties.getTypeMap().keys(): + self._name = name + self._value = value + self._format = format + else: + raise RuntimeError("Unsupported format type: " + format) + +def createTimeStamp(): + return _bulkio_helpers.createCPUTimestamp() + +def createSRI(streamID='defaultStreamID', sampleRate=1.0, mode=0, blocking=True ): + xd=1.0 + if sampleRate and sampleRate > 0.0: + xd = 1.0/float(sampleRate) + + return _BULKIO_.StreamSRI(hversion=1, xstart=0.0, xdelta=xd, + xunits=1, subsize=0, ystart=0.0, ydelta=0.0, + yunits=0, mode=mode, streamID=streamID, blocking=blocking, keywords=[]) diff --git a/redhawk/src/testing/tests/test_13_TestSB.py b/redhawk/src/testing/tests/test_13_TestSB.py index 302330fab..5c1481560 100644 --- a/redhawk/src/testing/tests/test_13_TestSB.py +++ b/redhawk/src/testing/tests/test_13_TestSB.py @@ -41,6 +41,7 @@ from ossie.events import ChannelManager, Subscriber, Publisher from _unitTestHelpers import scatest, runtestHelpers +import traceback globalsdrRoot = os.environ['SDRROOT'] java_support = runtestHelpers.haveJavaSupport('../Makefile') @@ -63,6 +64,17 @@ def _initSourceAndSink(dataFormat): return source, sink + +def compareKeywordLists( a, b ): + for keyA, keyB in zip(a, b): + if keyA.id != keyB.id: + return False + if keyA.value._t != keyB.value._t: + return False + if keyA.value._v != keyB.value._v: + return False + return True + @scatest.requireJava class InteractiveTestJava(scatest.CorbaTestCase): def setUp(self): @@ -1825,7 +1837,7 @@ def test_DataSourceTimeStamp(self): sink = sb.DataSink() source.connect(sink, usesPortName='floatOut') sb.start() - + # test default sample rate _srcData = [1,2,3,4] source.push(_srcData) @@ -1913,6 +1925,198 @@ def test_DataSourceTimeStamp(self): _round_time = int(round(_orig_time*10))/10.0 self.assertEquals(_round_time, toffset+len(_srcData)/_sampleRate) + + def test_DataSourceTimeStampParam(self): + """ + Verify that the time stamp param is honored + """ + _timeout = 1 + _startTime = 10 + _sampleRate = 1.0 + source = sb.DataSource(startTime=_startTime) + sink = sb.DataSink() + source.connect(sink, usesPortName='floatOut') + sb.start() + + # test default sample rate + _srcData = [1,2,3,4] + source.push(_srcData) + source.push(_srcData) + estimate = sink.getDataEstimate() + begin_time = time.time() + while estimate.num_timestamps != 2: + time.sleep(0.1) + estimate = sink.getDataEstimate() + if time.time() - begin_time > _timeout: + break + (_data, _tstamps) = sink.getData(tstamps=True) + self.assertEquals(len(_data), len(_srcData)*2) + self.assertEquals(sink.sri().xdelta, 1) + self.assertEquals(_tstamps[0][1].twsec, _startTime) + self.assertEquals(_tstamps[1][1].twsec, _startTime+len(_srcData)) + + _ts = sb.createTimeStamp() + begin_time = _ts.twsec+_ts.tfsec + _toffset =begin_time + source.push(_srcData, ts=_ts) + source.push(_srcData) + estimate = sink.getDataEstimate() + while estimate.num_timestamps != 2: + time.sleep(0.1) + estimate = sink.getDataEstimate() + if time.time() - begin_time > _timeout: + break + (_data, _tstamps) = sink.getData(tstamps=True) + self.assertEquals(len(_data), len(_srcData)*2) + self.assertEquals(sink.sri().xdelta, 1/_sampleRate) + _pkt_time = _tstamps[0][1].twsec+_tstamps[0][1].tfsec + _rnd_pkt_time = int(round(_pkt_time*10))/10.0 + _rnd_toffset = int(round(_toffset*10))/10.0 + self.assertEquals(_rnd_pkt_time,_rnd_toffset ) + _pkt_time = _tstamps[1][1].twsec+_tstamps[1][1].tfsec + _rnd_pkt_time = int(round(_pkt_time*10))/10.0 + _rnd_toffset = int(round( (_toffset+len(_srcData)/_sampleRate) *10))/10.0 + self.assertEquals(_rnd_pkt_time,_rnd_toffset ) + + + # test modified sample rate + _sampleRate = 10.0 + _ts = sb.createTimeStamp() + begin_time = _ts.twsec+_ts.tfsec + _toffset =begin_time + source.push(_srcData,sampleRate=_sampleRate, ts=_ts) + source.push(_srcData) + estimate = sink.getDataEstimate() + while estimate.num_timestamps != 2: + time.sleep(0.1) + estimate = sink.getDataEstimate() + if time.time() - begin_time > _timeout: + break + (_data, _tstamps) = sink.getData(tstamps=True) + self.assertEquals(len(_data), len(_srcData)*2) + self.assertEquals(sink.sri().xdelta, 1/_sampleRate) + _pkt_time = _tstamps[0][1].twsec+_tstamps[0][1].tfsec + _rnd_pkt_time = int(round(_pkt_time*10))/10.0 + _rnd_toffset = int(round(_toffset*10))/10.0 + self.assertEquals(_rnd_pkt_time,_rnd_toffset ) + _pkt_time = _tstamps[1][1].twsec+_tstamps[1][1].tfsec + _rnd_pkt_time = int(round(_pkt_time*10))/10.0 + _rnd_toffset = int(round( (_toffset+len(_srcData)/_sampleRate) *10))/10.0 + self.assertEquals(_rnd_pkt_time,_rnd_toffset ) + + + # test modified sample rate + _sampleRate=5.0 + _sri=source.sri() + _sri.xdelta = 1.0/_sampleRate + _ts = sb.createTimeStamp() + begin_time = _ts.twsec+_ts.tfsec + _toffset =begin_time + source.push(_srcData,sri=_sri, ts=_ts) + source.push(_srcData) + estimate = sink.getDataEstimate() + while estimate.num_timestamps != 2: + time.sleep(0.1) + estimate = sink.getDataEstimate() + if time.time() - begin_time > _timeout: + break + (_data, _tstamps) = sink.getData(tstamps=True) + self.assertEquals(len(_data), len(_srcData)*2) + self.assertEquals(sink.sri().xdelta, 1/_sampleRate) + _pkt_time = _tstamps[0][1].twsec+_tstamps[0][1].tfsec + _rnd_pkt_time = int(round(_pkt_time*10))/10.0 + _rnd_toffset = int(round(_toffset*10))/10.0 + self.assertEquals(_rnd_pkt_time,_rnd_toffset ) + _pkt_time = _tstamps[1][1].twsec+_tstamps[1][1].tfsec + _rnd_pkt_time = int(round(_pkt_time*10))/10.0 + _rnd_toffset = int(round( (_toffset+len(_srcData)/_sampleRate) *10))/10.0 + self.assertEquals(_rnd_pkt_time,_rnd_toffset ) + + + def test_DataSourceSRI(self): + """ + Verify that provide SRI is handled + """ + _timeout = 1 + _startTime = 10 + source = sb.DataSource(startTime=_startTime) + sink = sb.DataSink() + source.connect(sink, usesPortName='floatOut') + sb.start() + + # get an sri + _sri = source.sri() + + sid = 'test-sri-1' + _sri.streamID=sid + _sri.xdelta = 0.1234 + + # push samples down stream, with custom sri + _srcData = [1,2,3,4] + source.push(_srcData, sri=_sri ) + begin_time = time.time() + estimate = sink.getDataEstimate() + while estimate.num_timestamps != 1: + time.sleep(0.1) + estimate = sink.getDataEstimate() + if time.time() - begin_time > _timeout: + break + data=sink.getData() + rsri=sink.sri() + self.assertEquals(rsri.streamID, sid ) + self.assertAlmostEquals(rsri.xdelta, 0.1234) + + # add keywords as a param + kws=[] + kws.append(sb.SRIKeyword('kw1',1000,'long')) + kws.append(sb.SRIKeyword('kw2',12456.0,'float')) + kws.append(sb.SRIKeyword('kw3',16,'short')) + kws.append(sb.SRIKeyword('kw4', 200,'octet')) + kws.append(sb.SRIKeyword('kw5','this is a test','string')) + matchkws=[ CF.DataType(id='kw1', value=CORBA.Any(CORBA.TC_long, 1000)), + CF.DataType(id='kw2', value=CORBA.Any(CORBA.TC_float, 12456.0)), + CF.DataType(id='kw3', value=CORBA.Any(CORBA.TC_short, 16)), + CF.DataType(id='kw4', value=CORBA.Any(CORBA.TC_octet, 200)), + CF.DataType(id='kw5', value=CORBA.Any(CORBA.TC_string, 'this is a test')) + ] + _srcData = [1,2,3,4] + source.push(_srcData, SRIKeywords=kws ) + begin_time = time.time() + estimate = sink.getDataEstimate() + while estimate.num_timestamps != 1: + time.sleep(0.1) + estimate = sink.getDataEstimate() + if time.time() - begin_time > _timeout: + break + data=sink.getData() + rsri=sink.sri() + self.assertEquals(rsri.streamID, sid ) + self.assertAlmostEquals(rsri.xdelta, 0.1234) + self.assertEqual(True, compareKeywordLists( rsri.keywords, matchkws) ) + + # add new keywords to sri + matchkws=[ CF.DataType(id='kw1-1', value=CORBA.Any(CORBA.TC_long, 1000)), + CF.DataType(id='kw2-1', value=CORBA.Any(CORBA.TC_float, 12456.0)), + CF.DataType(id='kw3-1', value=CORBA.Any(CORBA.TC_short, 16)), + CF.DataType(id='kw4-1', value=CORBA.Any(CORBA.TC_octet, 200)), + CF.DataType(id='kw5-1', value=CORBA.Any(CORBA.TC_string, 'this is a test')) + ] + _sri.keywords=copy.copy(matchkws) + _srcData = [1,2,3,4] + source.push(_srcData, sri=_sri ) + begin_time = time.time() + estimate = sink.getDataEstimate() + while estimate.num_timestamps != 1: + time.sleep(0.1) + estimate = sink.getDataEstimate() + if time.time() - begin_time > _timeout: + break + data=sink.getData() + rsri=sink.sri() + self.assertEquals(rsri.streamID, sid ) + self.assertAlmostEquals(rsri.xdelta, 0.1234) + self.assertEqual(True, compareKeywordLists( rsri.keywords, matchkws) ) + def test_DataSinkSubsize(self): src=sb.DataSource(dataFormat='short',subsize=5) snk=sb.DataSink() From 3f79b0f9a92386bd11c4a262a95d2bf2653b4232 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Mon, 30 Jan 2017 14:17:57 -0500 Subject: [PATCH 0670/1644] Refs CF-1583. Additional helpers for event channel management --- .../python/ossie/utils/model/__init__.py | 1 + .../python/ossie/utils/redhawk/channels.py | 16 +++ .../python/ossie/utils/redhawk/core.py | 102 ++++++++++++++++-- .../python/ossie/utils/redhawk/model.py | 2 +- .../control/sdr/dommgr/DomainManager_impl.h | 1 + .../sdr/dommgr/EventChannelManager.cpp | 5 +- redhawk/src/idl/ossie/CF/StandardEvent.idl | 1 + 7 files changed, 120 insertions(+), 8 deletions(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/model/__init__.py b/redhawk/src/base/framework/python/ossie/utils/model/__init__.py index 86bc31df8..45a0e6428 100644 --- a/redhawk/src/base/framework/python/ossie/utils/model/__init__.py +++ b/redhawk/src/base/framework/python/ossie/utils/model/__init__.py @@ -614,6 +614,7 @@ def __init__(self, ref, profile, spd, scd, prf, instanceName, refid, impl): self._prf = prf self._impl = impl self._instanceName = instanceName + self.name = instanceName # Add mapping of services operations and attributes found = False diff --git a/redhawk/src/base/framework/python/ossie/utils/redhawk/channels.py b/redhawk/src/base/framework/python/ossie/utils/redhawk/channels.py index dd6ddfe7b..594724ee0 100644 --- a/redhawk/src/base/framework/python/ossie/utils/redhawk/channels.py +++ b/redhawk/src/base/framework/python/ossie/utils/redhawk/channels.py @@ -59,6 +59,20 @@ def disconnect(self): class ODMListener(ChannelListener): CHANNEL_NAME = 'ODM_Channel' + @notification + def eventChannelAdded(self, event): + """ + A event channel was added. + """ + log.trace('eventChannelAdded %s', event) + + @notification + def eventChannelRemoved(self, event): + """ + A event channel was removed. + """ + log.trace('eventChannelRemoved %s', event) + @notification def deviceManagerAdded(self, event): """ @@ -136,6 +150,7 @@ def __init__(self): StandardEvent.DEVICE: ODMListener.deviceAdded, StandardEvent.APPLICATION_FACTORY: ODMListener.applicationFactoryAdded, StandardEvent.APPLICATION: ODMListener.applicationAdded, + StandardEvent.EVENT_CHANNEL: ODMListener.eventChannelAdded, StandardEvent.SERVICE: ODMListener.serviceAdded }, StandardEvent._tc_DomainManagementObjectRemovedEventType: { @@ -143,6 +158,7 @@ def __init__(self): StandardEvent.DEVICE: ODMListener.deviceRemoved, StandardEvent.APPLICATION_FACTORY: ODMListener.applicationFactoryRemoved, StandardEvent.APPLICATION: ODMListener.applicationRemoved, + StandardEvent.EVENT_CHANNEL: ODMListener.eventChannelRemoved, StandardEvent.SERVICE: ODMListener.serviceRemoved }, } diff --git a/redhawk/src/base/framework/python/ossie/utils/redhawk/core.py b/redhawk/src/base/framework/python/ossie/utils/redhawk/core.py index e7fb31987..a79dd84cc 100644 --- a/redhawk/src/base/framework/python/ossie/utils/redhawk/core.py +++ b/redhawk/src/base/framework/python/ossie/utils/redhawk/core.py @@ -1190,8 +1190,7 @@ def deviceMgrEndPoint( self, devMgr_name, port_name ) : def objectRefEndPoint( self, obj_ref, port_name ) : restype = _CF.ConnectionManager.EndpointResolutionType(objectRef=obj_ref) return _CF.ConnectionManager.EndpointRequest(restype, port_name) - - + def connect( self, usesEndPoint, providesEndPoint, requesterId, connectionId ): retval=None if self.ref: @@ -1223,11 +1222,87 @@ def listConnections( self, count=0 ): return retval +class EventChannel(CorbaObject): + def __init__(self, ref, name): + CorbaObject.__init__(self, ref) + self.name = name + class EventChannelManager(CorbaObject): - def __init__(self, ref=None): + def __init__(self, ref=None, odmListener=None): CorbaObject.__init__(self, ref) + + self.__evtChannels = DomainObjectList(weakobj.boundmethod(self.__getEventChannels), + weakobj.boundmethod(self.__newEventChannel), + lambda x: x.name) + + self.__evtChannels.itemAdded.addListener(weakobj.boundmethod(self.eventChannelAdded)) + self.__evtChannels.itemRemoved.addListener(weakobj.boundmethod(self.eventChannelRemoved)) + + if odmListener: + weakobj.addListener(odmListener.eventChannelAdded, self.__eventChannelAddedEvent) + weakobj.addListener(odmListener.eventChannelRemoved, self.__eventChannelRemovedEvent) + self.__odmListener = odmListener + + def __inspectEventChannelManager(self, unique=None): + if type(unique) == EventChannel: + return [unique] + channels, _iter = self.ref.listChannels(0) + _retval = [] + status = True + while status: + status, _chans = _iter.next_n(100) + for _chan in _chans: + _chanref = self.ref.get(_chan.channel_name) + if not unique: + _retval.append(EventChannel(_chanref, _chan.channel_name)) + else: + if _chanref._is_equivalent(unique): + return [EventChannel(unique, _chan.channel_name)] + return _retval + + + def __getEventChannels(self): + # If the ODM channel is not connected, force an update to the list. + chans = self.__inspectEventChannelManager() + return chans + + def __newEventChannel(self, evtChannel): + retval = self.__inspectEventChannelManager(evtChannel) + if len(retval) == 1: + return retval[0] + return EventChannel(evtChannel, '') + + def __eventChannelAddedEvent(self, event): + try: + self.__evtChannels.add(event.sourceId, event.sourceIOR) + except Exception as e: + # The event channel is already gone or otherwise unavailable. + pass + + def __eventChannelRemovedEvent(self, event): + self.__evtChannels.remove(event.sourceId) + + @property + def eventChannels(self): + if not self.__odmListener: + self.__evtChannels.sync() + return self.__evtChannels.values() + @notification + def eventChannelAdded(self, evtChannel): + """ + The device manager 'deviceManager' was added to the system. + """ + pass + + @notification + def eventChannelRemoved(self, evtChannel): + """ + The device manager 'deviceManager' was added to the system. + """ + pass + def release( self, channelName ): if self.ref: try: @@ -1235,6 +1310,15 @@ def release( self, channelName ): except: raise + def get( self, channelName ): + retval=None + if self.ref: + try: + retval = self.ref.get(channelName) + except: + raise + return retval + def create( self, channelName ): retval=None if self.ref: @@ -1434,7 +1518,7 @@ def __init__(self, name="DomainName1", location=None, connectDomainEvents=True): super(Domain, self).__init__(prf, self.id) except Exception, e: pass - + self._buildAPI() self.__deviceManagers = DomainObjectList(weakobj.boundmethod(self._get_deviceManagers), @@ -1456,6 +1540,8 @@ def __init__(self, name="DomainName1", location=None, connectDomainEvents=True): if connectDomainEvents: self.__connectIDMChannel() self.__connectODMChannel() + + self.__eventChannelMgr = self.getEventChannelMgr() def _populateApps(self): self.__setattr__('_waveformsUpdated', True) @@ -1512,6 +1598,10 @@ def apps(self): self.__applications.sync() return self.__applications.values() + @property + def eventChannels(self): + return self.__eventChannelMgr.eventChannels + @property def devices(self): devs = [] @@ -1890,7 +1980,7 @@ def getConnectionMgr(self): def getEventChannelMgr(self): if self.ref and self.__eventChannelMgr == None : try: - self.__eventChannelMgr = EventChannelManager(self.ref._get_eventChannelMgr()) + self.__eventChannelMgr = EventChannelManager(self.ref._get_eventChannelMgr(), odmListener=self.__odmListener) except: raise return self.__eventChannelMgr @@ -1914,7 +2004,7 @@ def _get_connectionMgr(self): def _get_eventChannelMgr(self): if self.ref and self.__eventChannelMgr == None : try: - self.__eventChannelMgr = EventChannelManager(self.ref._get_eventChannelMgr()) + self.__eventChannelMgr = EventChannelManager(self.ref._get_eventChannelMgr(), odmListener=self.__odmListener) except: raise return self.__eventChannelMgr diff --git a/redhawk/src/base/framework/python/ossie/utils/redhawk/model.py b/redhawk/src/base/framework/python/ossie/utils/redhawk/model.py index da715d96b..529b5ada9 100644 --- a/redhawk/src/base/framework/python/ossie/utils/redhawk/model.py +++ b/redhawk/src/base/framework/python/ossie/utils/redhawk/model.py @@ -252,7 +252,7 @@ def values(self): self.lock() try: if not self.isCached: - self.sync() + self.sync(), self.__data return self.__data.values() finally: self.unlock() diff --git a/redhawk/src/control/sdr/dommgr/DomainManager_impl.h b/redhawk/src/control/sdr/dommgr/DomainManager_impl.h index a84ffcc34..66bf1056a 100644 --- a/redhawk/src/control/sdr/dommgr/DomainManager_impl.h +++ b/redhawk/src/control/sdr/dommgr/DomainManager_impl.h @@ -322,6 +322,7 @@ class DomainManager_impl: public virtual POA_CF::DomainManager, public PropertyS // // Handle to EventChannelManager for the Domain // + friend class EventChannelManager; EventChannelManager* _eventChannelMgr; diff --git a/redhawk/src/control/sdr/dommgr/EventChannelManager.cpp b/redhawk/src/control/sdr/dommgr/EventChannelManager.cpp index a7a73254d..d9152954a 100644 --- a/redhawk/src/control/sdr/dommgr/EventChannelManager.cpp +++ b/redhawk/src/control/sdr/dommgr/EventChannelManager.cpp @@ -340,7 +340,8 @@ const ossie::events::EventChannel_ptr EventChannelManager::findChannel( const st throw (CF::EventChannelManager::OperationFailed()); } - + _domainManager->sendRemoveEvent(channel_name.c_str(), channel_name.c_str(), channel_name.c_str(), StandardEvent::EVENT_CHANNEL); + ECM_DEBUG( "release", " Released EventChannel: " << cname ); } @@ -490,6 +491,8 @@ ossie::events::EventChannel_ptr EventChannelManager::get( const std::string &cha "ADD Channel Registration, Event Channel: "<< channel_name << " fqn:" << fqn ); ChannelRegistrationPtr reg __attribute__((unused)) = _addChannelRegistration( channel_name, fqn, event_channel, autoRelease ); + this->_domainManager->sendAddEvent(cname, cname, cname, event_channel, StandardEvent::EVENT_CHANNEL); + // // return pointer the channel... we maintain a separate copy // diff --git a/redhawk/src/idl/ossie/CF/StandardEvent.idl b/redhawk/src/idl/ossie/CF/StandardEvent.idl index 9bf6d2b9f..5051b200f 100644 --- a/redhawk/src/idl/ossie/CF/StandardEvent.idl +++ b/redhawk/src/idl/ossie/CF/StandardEvent.idl @@ -58,6 +58,7 @@ module StandardEvent { DEVICE_MANAGER, DEVICE, APPLICATION_FACTORY, + EVENT_CHANNEL, APPLICATION, SERVICE }; From 4c27fb8e21bc76dff58569e95c2f14626ab2f5bb Mon Sep 17 00:00:00 2001 From: Max Robert Date: Mon, 30 Jan 2017 14:22:44 -0500 Subject: [PATCH 0671/1644] Refs CF-1587. Added missing file --- .../ossie/utils/sb/prop_change_helpers.py | 109 ++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 redhawk/src/base/framework/python/ossie/utils/sb/prop_change_helpers.py diff --git a/redhawk/src/base/framework/python/ossie/utils/sb/prop_change_helpers.py b/redhawk/src/base/framework/python/ossie/utils/sb/prop_change_helpers.py new file mode 100644 index 000000000..8fe8ac69b --- /dev/null +++ b/redhawk/src/base/framework/python/ossie/utils/sb/prop_change_helpers.py @@ -0,0 +1,109 @@ +# +# This file is protected by Copyright. Please refer to the COPYRIGHT file +# distributed with this source distribution. +# +# This file is part of REDHAWK core. +# +# REDHAWK core is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation, either version 3 of the License, or (at your option) any +# later version. +# +# REDHAWK core is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +# details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/. +# + +from ossie.cf import CF__POA +from ossie import properties + +__all__ = ('PropertyChangeListener',) + +class PropertyChangeListener(CF__POA.PropertyChangeListener): + ''' + Container to process property change events + + Example usage: + def my_property_change_callback(event_id, registration_id, resource_id, properties, timestamp): + print event_id, registration_id, resource_id, properties, timestamp + + myl = sb.PropertyChangeListener(defaultCallback=my_property_change_callback) + regid=comp.registerPropertyListener( myl, ['prop1'], float(0.5)) + + Note: + - If no callbacks are provided, the contents of the event are directed to stdout + - Multiple properties associated with the same callback are triggered together when receive in the same event + ''' + def __init__(self, defaultCallback = None, changeCallbacks = {}): + ''' + defaultCallback is triggered when no callback matches + changeCallbacks is a dictionary of callbacks: + key: id (string) to trigger the callback + value: callback function + ''' + self._changeCallbacks = changeCallbacks + self._defaultCallback = defaultCallback + + def __del__(self): + pass + + def updateCallback(self, _prop_id, _callback=None): + ''' + _prop_id is the property id (string) + _callback is a function of the form: + fn(event_id, registration_id, resource_id, properties, timestamp) + ''' + if type(_prop_id) != str: + raise Exception('Invalid property id. It must be a strings') + if _callback == None: + if not self._changeCallbacks.has_key(_prop_id): + raise Exception('Invalid key:', _prop_id) + self._changeCallbacks.pop(_prop_id) + return + self._changeCallbacks.update({_prop_id:_callback}) + + def getCallback(self, _prop_id=''): + ''' + Set _prop_id for the unique key. Use an empty list to return all callbacks + ''' + if _prop_id == []: + return self._changeCallbacks + if self._changeCallbacks.has_key(_prop_id): + return self._changeCallbacks[_prop_id] + raise Exception('Invalid property id. No callback registered under that id') + + def propertyChange(self, _propChEv) : + if type(self._changeCallbacks) != dict: + print 'Invalid change callbacks (must be dictionary with property id as a key and a callback function as a value). Printing received event', _propChEv + + _tmp_props = _propChEv.properties + _triggers = {} + + for _prop_key in self._changeCallbacks: + for _prop_idx in range(len(_tmp_props)): + if _tmp_props[_prop_idx].id == _prop_key: + if not _triggers.has_key(self._changeCallbacks[_prop_key]): + _triggers[self._changeCallbacks[_prop_key]] = {} + _triggers[self._changeCallbacks[_prop_key]].update(properties.prop_to_dict(_tmp_props[_prop_idx])) + _tmp_props.pop(_prop_idx) + break + + if len(_triggers) != 0: + for _trigger in _triggers: + _trigger(_propChEv.evt_id, _propChEv.reg_id, _propChEv.resource_id, _triggers[_trigger], _propChEv.timestamp) + + if len(_tmp_props) != 0: + if self._defaultCallback: + self._defaultCallback(_propChEv.evt_id, _propChEv.reg_id, _propChEv.resource_id, properties.props_to_dict(_tmp_props), _propChEv.timestamp) + return + print 'Property Change Event:' + print ' event id:',_propChEv.evt_id + print ' registration id:',_propChEv.reg_id + print ' resource id:', _propChEv.resource_id + print ' properties:', properties.props_to_dict(_tmp_props) + print ' timestamp:', _propChEv.timestamp + From 1dc07d11b80b57cc2c05696400d259cbc0144356 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Mon, 30 Jan 2017 14:33:15 -0500 Subject: [PATCH 0672/1644] Added some comments --- .../src/base/framework/python/ossie/utils/redhawk/core.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/redhawk/src/base/framework/python/ossie/utils/redhawk/core.py b/redhawk/src/base/framework/python/ossie/utils/redhawk/core.py index a79dd84cc..1a8646b75 100644 --- a/redhawk/src/base/framework/python/ossie/utils/redhawk/core.py +++ b/redhawk/src/base/framework/python/ossie/utils/redhawk/core.py @@ -1385,11 +1385,19 @@ def listRegistrants( self, channelName="", count=0 ): return retval def registerConsumer(self, consumer, req): + ''' + consumer is an event consumer (i.e.: ossie.events.Receiver) + req is an EventRegistration (i.e.: CF.EventRegistration) + ''' if hassattr(consumer, '_this'): return self.ref.registerConsumer(consumer._this(), req) return self.ref.registerConsumer(consumer, req) def registerPublisher(self, req, disconnectReceiver): + ''' + req is an EventRegistration (i.e.: CF.EventRegistration) + disconnectReceiver is an optional event consumer (i.e.: ossie.events.Receiver) + ''' #if hassattr(disconnectReceiver, '_this'): # return self.ref.registerPublisher(req, disconnectReceiver._this()) return self.ref.registerPublisher(req, disconnectReceiver) From ed0559023575e1b2d2edc54a5d43105f5267a86e Mon Sep 17 00:00:00 2001 From: 8530 <8530@vm-131.vsi-corp.com> Date: Tue, 31 Jan 2017 08:40:15 -0500 Subject: [PATCH 0673/1644] added sad checks for collocation and devicerequires, additional device filtering with collocation and devicerequires, CF-1416 --- redhawk/src/base/framework/PropertyMap.cpp | 35 +++ .../base/framework/python/ossie/resource.py | 24 +- redhawk/src/base/include/ossie/PropertyMap.h | 3 + .../sdr/dommgr/AllocationManager_impl.cpp | 27 +- .../sdr/dommgr/AllocationManager_impl.h | 2 +- .../sdr/dommgr/ApplicationFactory_impl.cpp | 120 +++++++- .../sdr/dommgr/ApplicationValidator.cpp | 26 +- redhawk/src/control/sdr/dommgr/createHelper.h | 10 +- .../device_requires_green.sad.xml | 0 .../device_requires_multicolor.sad.xml | 0 .../device_requires_multicolor_colloc.sad.xml | 60 ++++ .../device_requires_nocolor.sad.xml | 51 ++++ .../device_requires_red.sad.xml | 0 .../device_requires_red_colloc.sad.xml | 60 ++++ ...e_requires_red_colloc_and_nocolloc.sad.xml | 69 +++++ ...ires_red_colloc_and_nocolloc_green.sad.xml | 63 +++++ ...quires_red_colloc_and_nocolloc_red.sad.xml | 64 +++++ .../testing/tests/test_08_DeployerRequires.py | 261 +++++++++++++++--- 18 files changed, 789 insertions(+), 86 deletions(-) rename redhawk/src/testing/sdr/dom/waveforms/{ => device_requires}/device_requires_green/device_requires_green.sad.xml (100%) rename redhawk/src/testing/sdr/dom/waveforms/{ => device_requires}/device_requires_multicolor/device_requires_multicolor.sad.xml (100%) create mode 100644 redhawk/src/testing/sdr/dom/waveforms/device_requires/device_requires_multicolor_colloc/device_requires_multicolor_colloc.sad.xml create mode 100644 redhawk/src/testing/sdr/dom/waveforms/device_requires/device_requires_nocolor/device_requires_nocolor.sad.xml rename redhawk/src/testing/sdr/dom/waveforms/{ => device_requires}/device_requires_red/device_requires_red.sad.xml (100%) create mode 100644 redhawk/src/testing/sdr/dom/waveforms/device_requires/device_requires_red_colloc/device_requires_red_colloc.sad.xml create mode 100644 redhawk/src/testing/sdr/dom/waveforms/device_requires/device_requires_red_colloc_and_nocolloc/device_requires_red_colloc_and_nocolloc.sad.xml create mode 100644 redhawk/src/testing/sdr/dom/waveforms/device_requires/device_requires_red_colloc_and_nocolloc_green/device_requires_red_colloc_and_nocolloc_green.sad.xml create mode 100644 redhawk/src/testing/sdr/dom/waveforms/device_requires/device_requires_red_colloc_and_nocolloc_red/device_requires_red_colloc_and_nocolloc_red.sad.xml diff --git a/redhawk/src/base/framework/PropertyMap.cpp b/redhawk/src/base/framework/PropertyMap.cpp index 9c97bb6ce..3e1f63dac 100644 --- a/redhawk/src/base/framework/PropertyMap.cpp +++ b/redhawk/src/base/framework/PropertyMap.cpp @@ -117,6 +117,41 @@ const Value& PropertyMap::get(const std::string& id, const Value& def) const } } +bool PropertyMap::operator==( const redhawk::PropertyMap &other ) const +{ + // + // perform simple matching of a property map against another map + // + if ( size() != other.size() ) { + return false; + } + + if ( size() == 0 ) { + return true; + } + + for ( const_iterator iter = begin(); iter != end(); ++iter) { + std::string pid(iter->getId()); + const_iterator other_prop = other.find( pid ); + if ( other_prop == other.end() ) { + return false; + } + // perform equal match values + std::string action("eq"); + if ( !ossie::compare_anys(iter->getValue(), other_prop->getValue(), action) ) { + return false; + } + } + + return true; +} + + +bool PropertyMap::operator!=( const redhawk::PropertyMap &other ) const +{ + return !(*this == other); +} + void PropertyMap::update(const CF::Properties& properties) { const PropertyMap& other = cast(properties); diff --git a/redhawk/src/base/framework/python/ossie/resource.py b/redhawk/src/base/framework/python/ossie/resource.py index 40b04c64a..f731f1824 100644 --- a/redhawk/src/base/framework/python/ossie/resource.py +++ b/redhawk/src/base/framework/python/ossie/resource.py @@ -499,11 +499,14 @@ def __loadPorts(self): # Common resource logging API # return logger assigned to resource - def getLogger(self): - return self._log + def getLogger(self, logid=None): + if logid != None: + return self._log + else: + return logging.getLogger(logid) # return a named logger - def getLogger(self, logid, assignToResource=False): + def getNamedLogger(self, logid, assignToResource=False): newLogger=logging.getLogger(logid) if assignToResource: self._logid = logid @@ -522,21 +525,6 @@ def setResourceContext(self, rscCtx ): rscCtx.apply(self.loggingMacros ) self.loggingCtx = rscCtx - def setLoggingContext(self, rscCtx ): - # apply resource context to macro definitions - if rscCtx: - rscCtx.apply(self.loggingMacros ) - self.loggingCtx = rscCtx - - elif self.loggingCtx : - self.loggingCtx.apply(self.loggingMacros ) - - # load logging configuration url to resource - self.setLogConfigURL( self.loggingURL ) - - # apply logging level - self.setLogLevel( self._logid, self.loglevel ) - # # set the logging context for the resouce. Use the contents of # of the url as the logging configuration data. If the diff --git a/redhawk/src/base/include/ossie/PropertyMap.h b/redhawk/src/base/include/ossie/PropertyMap.h index 241a0adbe..419b3890b 100644 --- a/redhawk/src/base/include/ossie/PropertyMap.h +++ b/redhawk/src/base/include/ossie/PropertyMap.h @@ -62,6 +62,9 @@ namespace redhawk { const Value& get(const std::string& id, const Value& def=Value()) const; + bool operator==( const redhawk::PropertyMap &other ) const; + bool operator!=( const redhawk::PropertyMap &other ) const; + void update(const CF::Properties& properties); void push_back (const CF::DataType& dt); diff --git a/redhawk/src/control/sdr/dommgr/AllocationManager_impl.cpp b/redhawk/src/control/sdr/dommgr/AllocationManager_impl.cpp index 6a371a833..064a9218f 100644 --- a/redhawk/src/control/sdr/dommgr/AllocationManager_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/AllocationManager_impl.cpp @@ -329,7 +329,8 @@ bool AllocationManager_impl::allocateDevice(const CF::Properties& requestedPrope } LOG_DEBUG(AllocationManager_impl, "allocateDevice::PartitionMatching " << node.requiresProps ); - if ( !checkPartitionMatching( node, devicerequires )) { + const redhawk::PropertyMap &devReqs = redhawk::PropertyMap::cast(devicerequires); + if ( !checkPartitionMatching( node, devReqs )) { LOG_TRACE(AllocationManager_impl, "Partition Matching failed"); return false; } @@ -494,26 +495,38 @@ bool AllocationManager_impl::checkDeviceMatching(ossie::Properties& prf, CF::Pro return true; } + bool AllocationManager_impl::checkPartitionMatching( ossie::DeviceNode& node, - const CF::Properties& devicerequires ) + const redhawk::PropertyMap& devicerequires ) { // // perform matching of a device's deployrequires property set against a componentplacment's devicerequires list // - // Check if the device has a required property set for deployment - if ( node.requiresProps.size() == 0 ) { - LOG_DEBUG(AllocationManager_impl, "Device: " << node.label << " has no required properties to filter deployments against."); + if ( node.requiresProps.size() == 0 and devicerequires.size() == 0 ) { + LOG_TRACE(AllocationManager_impl, "Device: " << node.label << " has no required properties to filter deployments against."); return true; } // Check if the device has a required property set for deployment - if ( devicerequires.length() == 0 ) { - LOG_DEBUG(AllocationManager_impl, "Device: " << node.label << " has required properties for deployment, component does not provide any properties."); + if ( devicerequires.size() == 0 and node.requiresProps.size() > 0 ) { + LOG_TRACE(AllocationManager_impl, "Device: " << node.label << " has required properties for deployment, component does not provide any properties."); + return false; + } + + // Check if the component provides a property set for deployment + if ( devicerequires.size() > 0 and node.requiresProps.size() == 0 ) { + LOG_TRACE(AllocationManager_impl, "Device: " << node.label << " has no required properties for deployment, component's contains deviicerequires properties."); return false; } + if ( node.requiresProps.size() != devicerequires.length()) { + LOG_TRACE(AllocationManager_impl, "Device: " << node.label << " has required properties for deployment, number of properties does not match."); + return false; + } + + const redhawk::PropertyMap &provided_props = redhawk::PropertyMap::cast( devicerequires ); redhawk::PropertyMap::iterator iter = node.requiresProps.begin(); for ( ; iter != node.requiresProps.end(); ++iter) { diff --git a/redhawk/src/control/sdr/dommgr/AllocationManager_impl.h b/redhawk/src/control/sdr/dommgr/AllocationManager_impl.h index 634f593c3..f66f557ce 100644 --- a/redhawk/src/control/sdr/dommgr/AllocationManager_impl.h +++ b/redhawk/src/control/sdr/dommgr/AllocationManager_impl.h @@ -127,7 +127,7 @@ class AllocationManager_impl: public virtual POA_CF::AllocationManager bool checkMatchingProperty(const ossie::Property* property, const CF::DataType& dependency); bool checkPartitionMatching( ossie::DeviceNode& node, - const CF::Properties& devicerequires ); + const redhawk::PropertyMap& devicerequires ); redhawk::PropertyMap getDeviceRequiredProperties( ossie::DeviceNode& node ); diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 9ce04a26b..4668bf57e 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -1,3 +1,4 @@ + /* * This file is protected by Copyright. Please refer to the COPYRIGHT file * distributed with this source distribution. @@ -335,14 +336,18 @@ bool createHelper::placeHostCollocation(redhawk::ApplicationDeployment& appDeplo const DeploymentList& components, DeploymentList::const_iterator current, ossie::DeviceList& deploymentDevices, + const redhawk::PropertyMap& deviceRequires, const ProcessorList& processorDeps, - const OSList& osDeps, - const CF::Properties& deviceRequires) + const OSList& osDeps) + { if (current == components.end()) { // Reached the end of the component deployments; all implementations // should be set, so give it a try - return allocateHostCollocation(appDeployment, components, deploymentDevices, processorDeps, osDeps, deviceRequires); + if ( !deviceRequires.empty() ) { + LOG_TRACE(ApplicationFactory_impl, "Collocation has devicerequires: " << deviceRequires ); + } + return allocateHostCollocation(appDeployment, components, deploymentDevices, processorDeps, osDeps, deviceRequires ); } // Try all of the implementations from the current component for matches @@ -374,11 +379,9 @@ bool createHelper::placeHostCollocation(redhawk::ApplicationDeployment& appDeplo continue; } - redhawk::PropertyMap devRequires(deviceRequires); - devRequires.update(deployment->getDeviceRequires()); // Set this implementation for deployment and recurse one more level deployment->setImplementation(implementation); - if (placeHostCollocation(appDeployment, components, current, deploymentDevices, proc_list, os_list, devRequires)) { + if (placeHostCollocation(appDeployment, components, current, deploymentDevices, deviceRequires, proc_list, os_list)) { return true; } } @@ -391,7 +394,7 @@ bool createHelper::allocateHostCollocation(redhawk::ApplicationDeployment& appDe ossie::DeviceList& deploymentDevices, const ProcessorList& processorDeps, const OSList& osDeps, - const CF::Properties& deviceRequires ) + const redhawk::PropertyMap& deviceRequires ) { // Consolidate the allocation properties into a single list CF::Properties allocationProperties = _consolidateAllocations(components); @@ -403,6 +406,10 @@ bool createHelper::allocateHostCollocation(redhawk::ApplicationDeployment& appDe << " implementation " << (*depl)->getImplementation()->getID()); } + if ( !deviceRequires.empty() ) { + LOG_TRACE(ApplicationFactory_impl, "Collocation has devicerequires: " << deviceRequires ); + } + const std::string requestid = ossie::generateUUID(); ossie::AllocationResult response = _allocationMgr->allocateDeployment(requestid, allocationProperties, deploymentDevices, appDeployment.getIdentifier(), processorDeps, osDeps, deviceRequires); if (!response.first.empty()) { @@ -462,6 +469,7 @@ void createHelper::_placeHostCollocation(redhawk::ApplicationDeployment& appDepl LOG_TRACE(ApplicationFactory_impl, "Placing host collocation " << collocation.getID() << " " << collocation.getName()); + std::pair < std::string, redhawk::PropertyMap > devReq(std::string(""), redhawk::PropertyMap()); // Keep track of devices to which some of the components have // been assigned. DeviceIDList assignedDevices; @@ -479,6 +487,13 @@ void createHelper::_placeHostCollocation(redhawk::ApplicationDeployment& appDepl if (device != devices.end()) { assignedDevices.push_back(device->second); } + + // check if collocation contains a devicerequires set + if ( !deployment->getDeviceRequires().empty() ) { + devReq.first = deployment->getIdentifier(); + devReq.second = deployment->getDeviceRequires(); + LOG_DEBUG(ApplicationFactory_impl, "Collocation contains devicerequires instance: " << devReq.first << " props :" << devReq.second); + } } } @@ -508,6 +523,24 @@ void createHelper::_placeHostCollocation(redhawk::ApplicationDeployment& appDepl } } } + + // if the collocation contains a deviceRequires then filter down the deployment list + if ( !devReq.first.empty() ) { + for (ossie::DeviceList::iterator node = deploymentDevices.begin(); node != deploymentDevices.end(); ) { + if ( (*node)->requiresProps != devReq.second ) { + node = deploymentDevices.erase(node); + } + node++; + } + } + + // no deployment devices available so we can stop + if ( deploymentDevices.size() == 0 ) { + ostringstream os; + os << "No ExecutableDevices available to satisfy collocation."; + throw redhawk::PlacementFailure(collocation, os.str() ); + } + // if there is a usesdevice in the collocation that filter out the GPPs that we can use. if ( req_usesDevices.size() > 0 ) { @@ -539,8 +572,9 @@ void createHelper::_placeHostCollocation(redhawk::ApplicationDeployment& appDepl } + LOG_TRACE(ApplicationFactory_impl, "Placing " << deployments.size() << " components"); - if (!placeHostCollocation(appDeployment, deployments, deployments.begin(), deploymentDevices)) { + if (!placeHostCollocation(appDeployment, deployments, deployments.begin(), deploymentDevices, devReq.second )) { if (_allDevicesBusy(deploymentDevices)) { throw redhawk::PlacementFailure(collocation, "all executable devices (GPPs) in the Domain are busy"); } @@ -1307,7 +1341,8 @@ void createHelper::_evaluateMATHinRequest(CF::Properties &request, const CF::Pro } /* Perform allocation/assignment of a particular component to the device. - * - First do allocation/assignment based on user provided DAS + * - Check if deployment has required device properties.. + * - next, do allocation/assignment based on user provided DAS * - If not specified in DAS, then iterate through devices looking for a device that satisfies * the allocation properties */ @@ -1317,6 +1352,28 @@ ossie::AllocationResult createHelper::allocateComponentToDevice(redhawk::Compone { const ossie::SPD::Implementation* implementation = deployment->getImplementation(); ossie::DeviceList devices = _registeredDevices; + const CF::Properties& deviceRequires = deployment->getDeviceRequires(); + + if ( deviceRequires.length() > 0 ) { + LOG_TRACE(ApplicationFactory_impl, "Compnent: '" << deployment->getSoftPkg()->getName() << "' has device requires"); + // filter out devices that only match devicerequires property set + ossie::DeviceList::iterator device; + for (device = devices.begin(); device != devices.end(); ) { + boost::shared_ptr devnode = *device; + LOG_DEBUG(ApplicationFactory_impl, "allocateDevice::PartitionMatching required props: " << devnode->requiresProps ); + if ( !checkPartitionMatching( *devnode, deviceRequires )) { + LOG_TRACE(ApplicationFactory_impl, "Partition Matching failed"); + device=devices.erase(device); + continue; + } + device++; + } + + if ( devices.size() == 0 ) { + throw redhawk::PlacementFailure(deployment->getInstantiation(), "failed to satisfy devicerequires specification."); + } + } + // First check to see if the component was assigned in the user provided DAS // See if a device was assigned in the DAS @@ -1376,7 +1433,7 @@ ossie::AllocationResult createHelper::allocateComponentToDevice(redhawk::Compone appIdentifier, implementation->getProcessors(), implementation->getOsDeps(), - deployment->getDeviceRequires()); + deviceRequires ); if (allocationProperties.contains("nic_allocation")) { if (!response.first.empty()) { redhawk::PropertyMap query_props; @@ -1398,6 +1455,49 @@ ossie::AllocationResult createHelper::allocateComponentToDevice(redhawk::Compone return response; } + +bool createHelper::checkPartitionMatching( ossie::DeviceNode& devnode, + const CF::Properties& devicerequires ) +{ + // + // perform matching of a device's deployrequires property set against a componentplacment's devicerequires list + // + + if ( devnode.requiresProps.size() != devicerequires.length()) { + LOG_TRACE(ApplicationFactory_impl, "Number of devicerequired properties for deployment does not match, Device: " << devnode.label ); + return false; + } + + // Check if the device has a required property set for deployment + if ( devicerequires.length() == 0 ) { + LOG_TRACE(ApplicationFactory_impl, "Component and Device have no devicerequires/deployerrequires property sets."); + return true; + } + + const redhawk::PropertyMap &devReqs = redhawk::PropertyMap::cast( devicerequires ); + for ( redhawk::PropertyMap::const_iterator iter=devReqs.begin(); iter != devReqs.end(); ++iter) { + std::string pid(iter->getId()); + LOG_TRACE(ApplicationFactory_impl, "checkPartitionMatching source devicerequires id: " << pid ); + redhawk::PropertyMap::const_iterator dev_prop = devnode.requiresProps.find( pid ); + if ( dev_prop == devnode.requiresProps.end() ) { + LOG_DEBUG(ApplicationFactory_impl, "Missing devicerequires property: " << pid << " for deployment from Device: " << devnode.label ); + return false; + } + + // Convert the input Any to the property's data type via string; if it came + // from the ApplicationFactory, it's already a string, but a remote request + // could be of any type + std::string action("eq"); + if ( !ossie::compare_anys(iter->getValue(), dev_prop->getValue(), action) ) { + return false; + } + } + + LOG_TRACE(ApplicationFactory_impl, "checkPartitionMatch PASSED, found match with device: " << devnode.label ); + return true; +} + + void createHelper::_castRequestProperties(CF::Properties& allocationProperties, const std::vector &prop_refs, unsigned int offset) { allocationProperties.length(offset+prop_refs.size()); diff --git a/redhawk/src/control/sdr/dommgr/ApplicationValidator.cpp b/redhawk/src/control/sdr/dommgr/ApplicationValidator.cpp index 3371bbd4f..15d991b6d 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationValidator.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationValidator.cpp @@ -24,7 +24,8 @@ #include #include - +#include +#include #include "ApplicationValidator.h" using namespace redhawk; @@ -203,8 +204,31 @@ void ApplicationValidator::validateImplementation(const SoftPkg* softpkg, void ApplicationValidator::validateHostCollocation(const SoftwareAssembly::HostCollocation& collocation) { + std::pair< std::string, redhawk::PropertyMap > devReq(std::string(""),redhawk::PropertyMap()); BOOST_FOREACH(const ComponentPlacement& placement, collocation.getComponents()) { validateComponentPlacement(placement); + + // check if placement has deviceRequires, if so there can only be one or all must match + BOOST_FOREACH(const ComponentInstantiation& instantiation, placement.getInstantiations()) { + redhawk::PropertyMap deviceRequires; + ossie::convertComponentProperties(instantiation.getDeviceRequires(),deviceRequires); + if (!deviceRequires.empty() ) { + if ( !devReq.first.empty() ) { + if ( devReq.first == instantiation.getID() ) { + throw validation_error("hostcollocation contains multiple devicerequires, componentinstantiation: " +instantiation.getID() ); + } + + if ( devReq.second != deviceRequires ) { + throw validation_error("hostcollocation contains multiple devicerequires that are different, componentinstantiation: " + instantiation.getID() ); + } + } + else { + devReq.first = instantiation.getID(); + devReq.second = deviceRequires; + LOG_TRACE(ApplicationValidator, "devicerequires collocation: " << collocation.getName() << " instantiation :" << devReq.first << " devicerequires: " << devReq.second); + } + } + } } } diff --git a/redhawk/src/control/sdr/dommgr/createHelper.h b/redhawk/src/control/sdr/dommgr/createHelper.h index a32a45854..74bea7a80 100644 --- a/redhawk/src/control/sdr/dommgr/createHelper.h +++ b/redhawk/src/control/sdr/dommgr/createHelper.h @@ -115,9 +115,10 @@ class createHelper const DeploymentList& components, DeploymentList::const_iterator current, ossie::DeviceList& deploymentDevices, + const redhawk::PropertyMap& deviceRequires=redhawk::PropertyMap(), const ProcessorList& processorDeps=ProcessorList(), - const OSList& osDeps=OSList(), - const CF::Properties& deviceRequires=CF::Properties()); + const OSList& osDeps=OSList()); + void _handleUsesDevices(redhawk::ApplicationDeployment& appDeployment, const std::string& appName); std::vector _getFailedUsesDevices(const std::vector& usesDevices, @@ -144,12 +145,15 @@ class createHelper const std::string& assignedDeviceId, const std::string& appIdentifier); + bool checkPartitionMatching( ossie::DeviceNode& node, + const CF::Properties& devicerequires ); + bool allocateHostCollocation(redhawk::ApplicationDeployment& appDeployment, const DeploymentList& components, ossie::DeviceList& deploymentDevices, const ProcessorList& processorDeps, const OSList& osDeps, - const CF::Properties& = CF::Properties() ); + const redhawk::PropertyMap &); bool resolveSoftpkgDependencies(redhawk::ApplicationDeployment& appDeployment, redhawk::SoftPkgDeployment* deployment, diff --git a/redhawk/src/testing/sdr/dom/waveforms/device_requires_green/device_requires_green.sad.xml b/redhawk/src/testing/sdr/dom/waveforms/device_requires/device_requires_green/device_requires_green.sad.xml similarity index 100% rename from redhawk/src/testing/sdr/dom/waveforms/device_requires_green/device_requires_green.sad.xml rename to redhawk/src/testing/sdr/dom/waveforms/device_requires/device_requires_green/device_requires_green.sad.xml diff --git a/redhawk/src/testing/sdr/dom/waveforms/device_requires_multicolor/device_requires_multicolor.sad.xml b/redhawk/src/testing/sdr/dom/waveforms/device_requires/device_requires_multicolor/device_requires_multicolor.sad.xml similarity index 100% rename from redhawk/src/testing/sdr/dom/waveforms/device_requires_multicolor/device_requires_multicolor.sad.xml rename to redhawk/src/testing/sdr/dom/waveforms/device_requires/device_requires_multicolor/device_requires_multicolor.sad.xml diff --git a/redhawk/src/testing/sdr/dom/waveforms/device_requires/device_requires_multicolor_colloc/device_requires_multicolor_colloc.sad.xml b/redhawk/src/testing/sdr/dom/waveforms/device_requires/device_requires_multicolor_colloc/device_requires_multicolor_colloc.sad.xml new file mode 100644 index 000000000..7f22f8d33 --- /dev/null +++ b/redhawk/src/testing/sdr/dom/waveforms/device_requires/device_requires_multicolor_colloc/device_requires_multicolor_colloc.sad.xml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + SimpleComponent_Red + + + + + + + + + + + + + SimpleComponent_Green + + + + + + + + + + + + + + diff --git a/redhawk/src/testing/sdr/dom/waveforms/device_requires/device_requires_nocolor/device_requires_nocolor.sad.xml b/redhawk/src/testing/sdr/dom/waveforms/device_requires/device_requires_nocolor/device_requires_nocolor.sad.xml new file mode 100644 index 000000000..44abca3a9 --- /dev/null +++ b/redhawk/src/testing/sdr/dom/waveforms/device_requires/device_requires_nocolor/device_requires_nocolor.sad.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + SimpleComponent_Red + + + + + + + + + SimpleComponent_Green + + + + + + + + + + diff --git a/redhawk/src/testing/sdr/dom/waveforms/device_requires_red/device_requires_red.sad.xml b/redhawk/src/testing/sdr/dom/waveforms/device_requires/device_requires_red/device_requires_red.sad.xml similarity index 100% rename from redhawk/src/testing/sdr/dom/waveforms/device_requires_red/device_requires_red.sad.xml rename to redhawk/src/testing/sdr/dom/waveforms/device_requires/device_requires_red/device_requires_red.sad.xml diff --git a/redhawk/src/testing/sdr/dom/waveforms/device_requires/device_requires_red_colloc/device_requires_red_colloc.sad.xml b/redhawk/src/testing/sdr/dom/waveforms/device_requires/device_requires_red_colloc/device_requires_red_colloc.sad.xml new file mode 100644 index 000000000..23081c3fd --- /dev/null +++ b/redhawk/src/testing/sdr/dom/waveforms/device_requires/device_requires_red_colloc/device_requires_red_colloc.sad.xml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + SimpleComponent_Red + + + + + + + + + + + + + C2_Red + + + + + + + + + + + diff --git a/redhawk/src/testing/sdr/dom/waveforms/device_requires/device_requires_red_colloc_and_nocolloc/device_requires_red_colloc_and_nocolloc.sad.xml b/redhawk/src/testing/sdr/dom/waveforms/device_requires/device_requires_red_colloc_and_nocolloc/device_requires_red_colloc_and_nocolloc.sad.xml new file mode 100644 index 000000000..03f25bc81 --- /dev/null +++ b/redhawk/src/testing/sdr/dom/waveforms/device_requires/device_requires_red_colloc_and_nocolloc/device_requires_red_colloc_and_nocolloc.sad.xml @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + SimpleComponent_Red + + + + + + + + + + + + + C2_Red_2 + + + + + + + + + + C2_Red + + + + + + + + + + diff --git a/redhawk/src/testing/sdr/dom/waveforms/device_requires/device_requires_red_colloc_and_nocolloc_green/device_requires_red_colloc_and_nocolloc_green.sad.xml b/redhawk/src/testing/sdr/dom/waveforms/device_requires/device_requires_red_colloc_and_nocolloc_green/device_requires_red_colloc_and_nocolloc_green.sad.xml new file mode 100644 index 000000000..37711eaef --- /dev/null +++ b/redhawk/src/testing/sdr/dom/waveforms/device_requires/device_requires_red_colloc_and_nocolloc_green/device_requires_red_colloc_and_nocolloc_green.sad.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + SimpleComponent_Red + + + + + + + + + + + + + + C2_Green + + + + + + + + + + + + + diff --git a/redhawk/src/testing/sdr/dom/waveforms/device_requires/device_requires_red_colloc_and_nocolloc_red/device_requires_red_colloc_and_nocolloc_red.sad.xml b/redhawk/src/testing/sdr/dom/waveforms/device_requires/device_requires_red_colloc_and_nocolloc_red/device_requires_red_colloc_and_nocolloc_red.sad.xml new file mode 100644 index 000000000..2c56edfef --- /dev/null +++ b/redhawk/src/testing/sdr/dom/waveforms/device_requires/device_requires_red_colloc_and_nocolloc_red/device_requires_red_colloc_and_nocolloc_red.sad.xml @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + SimpleComponent_Red + + + + + + + + + + + + + + C2_Red + + + + + + + + + + + + + + diff --git a/redhawk/src/testing/tests/test_08_DeployerRequires.py b/redhawk/src/testing/tests/test_08_DeployerRequires.py index a02c92a9f..e427df052 100644 --- a/redhawk/src/testing/tests/test_08_DeployerRequires.py +++ b/redhawk/src/testing/tests/test_08_DeployerRequires.py @@ -23,6 +23,7 @@ from ossie.cf import CF, ExtendedCF from omniORB import any, CORBA from ossie import properties +import traceback class DeviceRequires(scatest.CorbaTestCase): def setUp(self): @@ -47,12 +48,12 @@ def tearDown(self): # or failures will probably occur. scatest.CorbaTestCase.tearDown(self) - def _createApp(self, appName, exc=None): + def _createApp(self, appName, exc=None, appdir='device_requires'): self.assertNotEqual(self._domMgr, None) app=None try: - sadpath = '/waveforms/'+appName+'/'+appName+'.sad.xml' + sadpath = '/waveforms/'+ appdir + '/'+appName+'/'+appName+'.sad.xml' self._domMgr.installApplication(sadpath) except Exception, e: return app @@ -72,44 +73,91 @@ def _createApp(self, appName, exc=None): self.fail("Did not create application ") return app - def test_norequired_nocolor(self): + def test_nocolors_redprovided(self): domBooter, self._domMgr = self.launchDomainManager() - devBooter, self._devMgr = self.launchDeviceManager("/nodes/test_GPP_node/DeviceManager.dcd.xml") + redBooter, self._rednode = self.launchDeviceManager("/nodes/test_GPP_red/DeviceManager.dcd.xml") self.assertNotEqual(self._domMgr, None) - self.assertNotEqual(self._devMgr, None) + self.assertNotEqual(self._rednode, None) - self._app = self._createApp('device_requires_multicolor') + self._app = self._createApp('device_requires_nocolor', CF.ApplicationFactory.CreateApplicationError) - self.assertNotEqual(self._app, None) - xx=self._app.query([]) + self.assertEqual(self._app, None) + + def test_nocolors_greenprovided(self): + domBooter, self._domMgr = self.launchDomainManager() + greenBooter, self._greennode = self.launchDeviceManager("/nodes/test_GPP_green/DeviceManager.dcd.xml") + + self.assertNotEqual(self._domMgr, None) + self.assertNotEqual(self._greennode, None) + + self._app = self._createApp('device_requires_nocolor', CF.ApplicationFactory.CreateApplicationError) + self.assertEqual(self._app, None) - def test_norequired_redprovided(self): + def test_nocolors_redmix(self): domBooter, self._domMgr = self.launchDomainManager() - devBooter, self._devMgr = self.launchDeviceManager("/nodes/test_GPP_node/DeviceManager.dcd.xml") + redBooter, self._rednode = self.launchDeviceManager("/nodes/test_GPP_red/DeviceManager.dcd.xml") + plainBooter, self._plainnode = self.launchDeviceManager("/nodes/test_GPP_node/DeviceManager.dcd.xml") self.assertNotEqual(self._domMgr, None) - self.assertNotEqual(self._devMgr, None) + self.assertNotEqual(self._rednode, None) + self.assertNotEqual(self._plainnode, None) - self._app = self._createApp('device_requires_red') + self._app = self._createApp('device_requires_nocolor') self.assertNotEqual(self._app, None) xx=self._app.query([]) - def test_norequired_greeprovided(self): + def test_nocolors_greenmix(self): domBooter, self._domMgr = self.launchDomainManager() - devBooter, self._devMgr = self.launchDeviceManager("/nodes/test_GPP_node/DeviceManager.dcd.xml") + greenBooter, self._greennode = self.launchDeviceManager("/nodes/test_GPP_green/DeviceManager.dcd.xml") + plainBooter, self._plainnode = self.launchDeviceManager("/nodes/test_GPP_node/DeviceManager.dcd.xml") self.assertNotEqual(self._domMgr, None) - self.assertNotEqual(self._devMgr, None) + self.assertNotEqual(self._greennode, None) + self.assertNotEqual(self._plainnode, None) - self._app = self._createApp('device_requires_green') + self._app = self._createApp('device_requires_nocolor') self.assertNotEqual(self._app, None) xx=self._app.query([]) - def test_redrequired_redprovided(self): + def test_mixdevrequires_nocolor(self): + domBooter, self._domMgr = self.launchDomainManager() + plainBooter, self._plainnode = self.launchDeviceManager("/nodes/test_GPP_node/DeviceManager.dcd.xml") + + self.assertNotEqual(self._domMgr, None) + self.assertNotEqual(self._plainnode, None) + + self._app = self._createApp('device_requires_multicolor', CF.ApplicationFactory.CreateApplicationError) + + self.assertEqual(self._app, None) + + + def test_reddevrequires_nocolors(self): + domBooter, self._domMgr = self.launchDomainManager() + plainBooter, self._plainnode = self.launchDeviceManager("/nodes/test_GPP_node/DeviceManager.dcd.xml") + + self.assertNotEqual(self._domMgr, None) + self.assertNotEqual(self._plainnode, None) + + self._app = self._createApp('device_requires_red', CF.ApplicationFactory.CreateApplicationError) + + self.assertEqual(self._app, None) + + def test_greendevrequires_nocolors(self): + domBooter, self._domMgr = self.launchDomainManager() + plainBooter, self._plainnode = self.launchDeviceManager("/nodes/test_GPP_node/DeviceManager.dcd.xml") + + self.assertNotEqual(self._domMgr, None) + self.assertNotEqual(self._plainnode, None) + + self._app = self._createApp('device_requires_green', CF.ApplicationFactory.CreateApplicationError) + + self.assertEqual(self._app, None) + + def test_reddevrequires_redprovided(self): domBooter, self._domMgr = self.launchDomainManager() redBooter, self._rednode = self.launchDeviceManager("/nodes/test_GPP_red/DeviceManager.dcd.xml") @@ -121,7 +169,7 @@ def test_redrequired_redprovided(self): self.assertNotEqual(self._app, None) xx=self._app.query([]) - def test_redrequired_colormismatch(self): + def test_greendevrequires_colormismatch(self): domBooter, self._domMgr = self.launchDomainManager() redBooter, self._rednode = self.launchDeviceManager("/nodes/test_GPP_red/DeviceManager.dcd.xml") @@ -132,7 +180,7 @@ def test_redrequired_colormismatch(self): self.assertEqual(self._app, None) - def test_redrequired_nonocolors(self): + def test_mixdevrequires_redprovided(self): domBooter, self._domMgr = self.launchDomainManager() redBooter, self._rednode = self.launchDeviceManager("/nodes/test_GPP_red/DeviceManager.dcd.xml") @@ -143,7 +191,7 @@ def test_redrequired_nonocolors(self): self.assertEqual(self._app, None) - def test_greenrequired_nonocolors(self): + def test_mixdevrequires_greenprovided(self): domBooter, self._domMgr = self.launchDomainManager() greenBooter, self._greennode = self.launchDeviceManager("/nodes/test_GPP_green/DeviceManager.dcd.xml") @@ -153,17 +201,7 @@ def test_greenrequired_nonocolors(self): self._app = self._createApp('device_requires_multicolor', CF.ApplicationFactory.CreateApplicationError) self.assertEqual(self._app, None) - def test_greenrequired_redprovided(self): - domBooter, self._domMgr = self.launchDomainManager() - greenBooter, self._greennode = self.launchDeviceManager("/nodes/test_GPP_green/DeviceManager.dcd.xml") - - self.assertNotEqual(self._domMgr, None) - self.assertNotEqual(self._greennode, None) - - self._app = self._createApp('device_requires_red', CF.ApplicationFactory.CreateApplicationError) - self.assertEqual(self._app, None) - - def test_greenrequired_greenprovided(self): + def test_reddevrequires_greenprovided(self): domBooter, self._domMgr = self.launchDomainManager() greenBooter, self._greennode = self.launchDeviceManager("/nodes/test_GPP_green/DeviceManager.dcd.xml") @@ -173,7 +211,7 @@ def test_greenrequired_greenprovided(self): self._app = self._createApp('device_requires_red', CF.ApplicationFactory.CreateApplicationError) self.assertEqual(self._app, None) - def test_redmulti_redprovided(self): + def test_reddevrequires_redmulti(self): domBooter, self._domMgr = self.launchDomainManager() redBooter, self._rednode = self.launchDeviceManager("/nodes/test_GPP_red/DeviceManager.dcd.xml") plainBooter, self._plainnode = self.launchDeviceManager("/nodes/test_GPP_node/DeviceManager.dcd.xml") @@ -187,7 +225,7 @@ def test_redmulti_redprovided(self): self.assertNotEqual(self._app, None) xx=self._app.query([]) - def test_redmulti_greenprovided(self): + def test_greendevrequires_redmulti(self): domBooter, self._domMgr = self.launchDomainManager() redBooter, self._rednode = self.launchDeviceManager("/nodes/test_GPP_red/DeviceManager.dcd.xml") plainBooter, self._plainnode = self.launchDeviceManager("/nodes/test_GPP_node/DeviceManager.dcd.xml") @@ -196,13 +234,12 @@ def test_redmulti_greenprovided(self): self.assertNotEqual(self._rednode, None) self.assertNotEqual(self._plainnode, None) - self._app = self._createApp('device_requires_green') + self._app = self._createApp('device_requires_green', CF.ApplicationFactory.CreateApplicationError) - self.assertNotEqual(self._app, None) - xx=self._app.query([]) + self.assertEqual(self._app, None) - def test_redmulti_nocolors(self): + def test_mixdevrequires_redmulti(self): domBooter, self._domMgr = self.launchDomainManager() redBooter, self._rednode = self.launchDeviceManager("/nodes/test_GPP_red/DeviceManager.dcd.xml") plainBooter, self._plainnode = self.launchDeviceManager("/nodes/test_GPP_node/DeviceManager.dcd.xml") @@ -211,12 +248,10 @@ def test_redmulti_nocolors(self): self.assertNotEqual(self._rednode, None) self.assertNotEqual(self._plainnode, None) - self._app = self._createApp('device_requires_multicolor') - - self.assertNotEqual(self._app, None) - xx=self._app.query([]) + self._app = self._createApp('device_requires_multicolor', CF.ApplicationFactory.CreateApplicationError) + self.assertEqual(self._app, None) - def test_multidevices_nocolors(self): + def test_mixcolor_mixdevices(self): domBooter, self._domMgr = self.launchDomainManager() redBooter, self._rednode = self.launchDeviceManager("/nodes/test_GPP_red/DeviceManager.dcd.xml") greenBooter, self._greennode = self.launchDeviceManager("/nodes/test_GPP_green/DeviceManager.dcd.xml") @@ -233,7 +268,7 @@ def test_multidevices_nocolors(self): xx=self._app.query([]) - def test_multidevices_redprovided(self): + def test_reddevrequires_mixcolors(self): domBooter, self._domMgr = self.launchDomainManager() redBooter, self._rednode = self.launchDeviceManager("/nodes/test_GPP_red/DeviceManager.dcd.xml") greenBooter, self._greennode = self.launchDeviceManager("/nodes/test_GPP_green/DeviceManager.dcd.xml") @@ -247,7 +282,7 @@ def test_multidevices_redprovided(self): self.assertNotEqual(self._app, None) xx=self._app.query([]) - def test_multidevices_greenprovided(self): + def test_greendevrequires_mixcolors(self): domBooter, self._domMgr = self.launchDomainManager() redBooter, self._rednode = self.launchDeviceManager("/nodes/test_GPP_red/DeviceManager.dcd.xml") greenBooter, self._greennode = self.launchDeviceManager("/nodes/test_GPP_green/DeviceManager.dcd.xml") @@ -262,7 +297,7 @@ def test_multidevices_greenprovided(self): xx=self._app.query([]) - def test_multidevices_redgreenprovided(self): + def test_redgreendevrequires_mixcolors(self): domBooter, self._domMgr = self.launchDomainManager() redBooter, self._rednode = self.launchDeviceManager("/nodes/test_GPP_red/DeviceManager.dcd.xml") greenBooter, self._greennode = self.launchDeviceManager("/nodes/test_GPP_green/DeviceManager.dcd.xml") @@ -278,7 +313,7 @@ def test_multidevices_redgreenprovided(self): self.assertNotEqual(self._red_app, None) - def test_multidevices_mixedcolors(self): + def test_mixcolors_multidevices(self): domBooter, self._domMgr = self.launchDomainManager() redBooter, self._rednode = self.launchDeviceManager("/nodes/test_GPP_red/DeviceManager.dcd.xml") greenBooter, self._greennode = self.launchDeviceManager("/nodes/test_GPP_green/DeviceManager.dcd.xml") @@ -298,7 +333,141 @@ def test_multidevices_mixedcolors(self): self._red_app = self._createApp('device_requires_red') self.assertNotEqual(self._red_app, None) + def test_collocation_multidevicerequires_greenprovided(self): + domBooter, self._domMgr = self.launchDomainManager() + greenBooter, self._greennode = self.launchDeviceManager("/nodes/test_GPP_green/DeviceManager.dcd.xml") + + self.assertNotEqual(self._domMgr, None) + self.assertNotEqual(self._greennode, None) + + self._app = self._createApp('device_requires_multicolor_colloc', CF.ApplicationFactory.CreateApplicationError) + self.assertEqual(self._app, None) + + def test_collocation_multidevicerequires_nonprovided(self): + domBooter, self._domMgr = self.launchDomainManager() + plainBooter, self._plainnode = self.launchDeviceManager("/nodes/test_GPP_node/DeviceManager.dcd.xml") + + self.assertNotEqual(self._domMgr, None) + self.assertNotEqual(self._plainnode, None) + + self._app = self._createApp('device_requires_multicolor_colloc', CF.ApplicationFactory.CreateApplicationError) + self.assertEqual(self._app, None) + + def test_collocation_multidevicerequires_mixedcolors(self): + domBooter, self._domMgr = self.launchDomainManager() + redBooter, self._rednode = self.launchDeviceManager("/nodes/test_GPP_red/DeviceManager.dcd.xml") + greenBooter, self._greennode = self.launchDeviceManager("/nodes/test_GPP_green/DeviceManager.dcd.xml") + plainBooter, self._plainnode = self.launchDeviceManager("/nodes/test_GPP_node/DeviceManager.dcd.xml") + + self.assertNotEqual(self._domMgr, None) + self.assertNotEqual(self._rednode, None) + self.assertNotEqual(self._greennode, None) + self.assertNotEqual(self._plainnode, None) + + self._app = self._createApp('device_requires_multicolor_colloc', CF.ApplicationFactory.CreateApplicationError) + self.assertEqual(self._app, None) + + def test_collocation_requiresred_redprovided(self): + domBooter, self._domMgr = self.launchDomainManager() + redBooter, self._rednode = self.launchDeviceManager("/nodes/test_GPP_red/DeviceManager.dcd.xml") + + self.assertNotEqual(self._domMgr, None) + self.assertNotEqual(self._rednode, None) + + self._app = self._createApp('device_requires_red_colloc') + self.assertNotEqual(self._app, None) + xx=self._app.query([]) + + def test_collocation_requiresred_nocolloc_nocolors_redprovided(self): + domBooter, self._domMgr = self.launchDomainManager() + redBooter, self._rednode = self.launchDeviceManager("/nodes/test_GPP_red/DeviceManager.dcd.xml") + + self.assertNotEqual(self._domMgr, None) + self.assertNotEqual(self._rednode, None) + + self._app = self._createApp('device_requires_red_colloc_and_nocolloc', CF.ApplicationFactory.CreateApplicationError) + self.assertEqual(self._app, None) + + def test_collocation_requiresred_nocolloc_nocolors_mixprovided(self): + domBooter, self._domMgr = self.launchDomainManager() + redBooter, self._rednode = self.launchDeviceManager("/nodes/test_GPP_red/DeviceManager.dcd.xml") + plainBooter, self._plainnode = self.launchDeviceManager("/nodes/test_GPP_node/DeviceManager.dcd.xml") + + self.assertNotEqual(self._domMgr, None) + self.assertNotEqual(self._rednode, None) + self.assertNotEqual(self._plainnode, None) + + self._app = self._createApp('device_requires_red_colloc_and_nocolloc') + self.assertNotEqual(self._app, None) + xx=self._app.query([]) + + def test_collocation_requiresred_nocolloc_redrequired_redprovided(self): + domBooter, self._domMgr = self.launchDomainManager() + redBooter, self._rednode = self.launchDeviceManager("/nodes/test_GPP_red/DeviceManager.dcd.xml") + + self.assertNotEqual(self._domMgr, None) + self.assertNotEqual(self._rednode, None) + + self._app = self._createApp('device_requires_red_colloc_and_nocolloc_red') + self.assertNotEqual(self._app, None) + xx=self._app.query([]) + + def test_collocation_requiresred_nocolloc_redrequired_greenprovided(self): + domBooter, self._domMgr = self.launchDomainManager() + greenBooter, self._greennode = self.launchDeviceManager("/nodes/test_GPP_green/DeviceManager.dcd.xml") + + self.assertNotEqual(self._domMgr, None) + self.assertNotEqual(self._greennode, None) + + self._app = self._createApp('device_requires_red_colloc_and_nocolloc_red', CF.ApplicationFactory.CreateApplicationError) + self.assertEqual(self._app, None) + + def test_collocation_requiresred_nocolloc_redrequired_nocolors(self): + domBooter, self._domMgr = self.launchDomainManager() + plainBooter, self._plainnode = self.launchDeviceManager("/nodes/test_GPP_node/DeviceManager.dcd.xml") + self.assertNotEqual(self._domMgr, None) + self.assertNotEqual(self._plainnode, None) + + self._app = self._createApp('device_requires_red_colloc_and_nocolloc_red', CF.ApplicationFactory.CreateApplicationError) + self.assertEqual(self._app, None) + + def test_collocation_requiresred_nocolloc_greenrequired_redprovided(self): + domBooter, self._domMgr = self.launchDomainManager() + redBooter, self._rednode = self.launchDeviceManager("/nodes/test_GPP_red/DeviceManager.dcd.xml") + + self.assertNotEqual(self._domMgr, None) + self.assertNotEqual(self._rednode, None) + + self._app = self._createApp('device_requires_red_colloc_and_nocolloc_green', CF.ApplicationFactory.CreateApplicationError) + self.assertEqual(self._app, None) + + def test_collocation_requiresred_nocolloc_greenrequired_mixprovided(self): + domBooter, self._domMgr = self.launchDomainManager() + redBooter, self._rednode = self.launchDeviceManager("/nodes/test_GPP_red/DeviceManager.dcd.xml") + greenBooter, self._greennode = self.launchDeviceManager("/nodes/test_GPP_green/DeviceManager.dcd.xml") + plainBooter, self._plainnode = self.launchDeviceManager("/nodes/test_GPP_node/DeviceManager.dcd.xml") + + self.assertNotEqual(self._domMgr, None) + self.assertNotEqual(self._rednode, None) + self.assertNotEqual(self._greennode, None) + self.assertNotEqual(self._plainnode, None) + + self._app = self._createApp('device_requires_red_colloc_and_nocolloc_green') + self.assertNotEqual(self._app, None) + xx=self._app.query([]) + + def test_collocation_requiresred_nocolloc_greenrequired_mix1provided(self): + domBooter, self._domMgr = self.launchDomainManager() + redBooter, self._rednode = self.launchDeviceManager("/nodes/test_GPP_red/DeviceManager.dcd.xml") + plainBooter, self._plainnode = self.launchDeviceManager("/nodes/test_GPP_node/DeviceManager.dcd.xml") + + self.assertNotEqual(self._domMgr, None) + self.assertNotEqual(self._rednode, None) + self.assertNotEqual(self._plainnode, None) + + self._app = self._createApp('device_requires_red_colloc_and_nocolloc_green', CF.ApplicationFactory.CreateApplicationError) + self.assertEqual(self._app, None) class DeployerRequiresTest(scatest.CorbaTestCase): def setUp(self): From 98b820324ae748dad09a69a4c00255eef938c22e Mon Sep 17 00:00:00 2001 From: 8530 <8530@vm-131.vsi-corp.com> Date: Wed, 1 Feb 2017 09:27:05 -0500 Subject: [PATCH 0674/1644] fix issue with class attribute resolution between centos 7 and 6 when loading properties, CF-463 --- redhawk/src/testing/sdr/dev/services/S2/python/S2.py | 9 +++++++-- .../src/testing/sdr/dev/services/S2_pre/python/S2_pre.py | 9 +++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/redhawk/src/testing/sdr/dev/services/S2/python/S2.py b/redhawk/src/testing/sdr/dev/services/S2/python/S2.py index 78e0ef338..799825164 100755 --- a/redhawk/src/testing/sdr/dev/services/S2/python/S2.py +++ b/redhawk/src/testing/sdr/dev/services/S2/python/S2.py @@ -22,8 +22,13 @@ def __init__(self, name="S2", execparams={}): self.name = name self._log = logging.getLogger(self.name) self._props = properties.PropertyStorage(self, (), execparams) - self._props._addProperty( S2.p1 ) - self._props._addProperty( S2.p2) + try: + self._props._addProperty( S2.p1 ) + self._props._addProperty( S2.p2) + except KeyError, e: + pass + except Exceptiopn, e: + raise e self._props.initialize() def terminateService(self): diff --git a/redhawk/src/testing/sdr/dev/services/S2_pre/python/S2_pre.py b/redhawk/src/testing/sdr/dev/services/S2_pre/python/S2_pre.py index 8b4694388..daa0f9329 100755 --- a/redhawk/src/testing/sdr/dev/services/S2_pre/python/S2_pre.py +++ b/redhawk/src/testing/sdr/dev/services/S2_pre/python/S2_pre.py @@ -22,8 +22,13 @@ def __init__(self, name="S2_pre", execparams={}): self.name = name self._log = logging.getLogger(self.name) self._props = properties.PropertyStorage(self, (), execparams) - self._props._addProperty( S2_pre.p1 ) - self._props._addProperty( S2_pre.p2) + try: + self._props._addProperty( S2_pre.p1 ) + self._props._addProperty( S2_pre.p2) + except KeyError, e: + pass + except Exceptiopn, e: + raise e self._props.initialize() def terminateService(self): From bd3a28e4df255ef4ae8b99ccef7ca8298f972ade Mon Sep 17 00:00:00 2001 From: 8530 <8530@vm-131.vsi-corp.com> Date: Wed, 1 Feb 2017 16:34:53 -0500 Subject: [PATCH 0675/1644] ignore built test executable --- redhawk/src/testing/.gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/redhawk/src/testing/.gitignore b/redhawk/src/testing/.gitignore index 02e3a34a6..8eed791bb 100644 --- a/redhawk/src/testing/.gitignore +++ b/redhawk/src/testing/.gitignore @@ -64,4 +64,4 @@ sdr/dom/deps/cpp_dep1/cpp_dep1.spd.xml sdr/dom/deps/cpp_dep2/cpp_dep2.spd.xml sdr/dev/devices/LongDevice/cpp/LongDevice sdr/dev/nodes/LongDeviceCalls/DeviceManager.dcd.xml - +sdr/dev/services/BasicService_cpp/cpp/BasicService_cpp From f782e1c431a91b919477592ff372cffbd3d38fb2 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Sat, 4 Feb 2017 08:17:56 -0500 Subject: [PATCH 0676/1644] Refs CF-1596. Better message when DOMAIN_REFRESH cannot be supported --- redhawk/src/base/framework/PropertySet_impl.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/redhawk/src/base/framework/PropertySet_impl.cpp b/redhawk/src/base/framework/PropertySet_impl.cpp index e64d1a250..d0644217d 100644 --- a/redhawk/src/base/framework/PropertySet_impl.cpp +++ b/redhawk/src/base/framework/PropertySet_impl.cpp @@ -263,6 +263,8 @@ throw (CORBA::SystemException, CF::PropertySet::InvalidConfiguration, invalidProperties.length(count + 1); invalidProperties[count].id = CORBA::string_dup(configProperties[ii].id); invalidProperties[count].value = configProperties[ii].value; + } catch (CF::PropertySet::InvalidConfiguration& e) { + throw; } catch (CORBA::Exception& e) { LOG_ERROR(PropertySet_impl, "Setting property " << property->id << " failed. Cause: " << e._name()); CORBA::ULong count = invalidProperties.length(); From 2cf3c5fb101962932ce945dffa9d9197ea093325 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Sat, 4 Feb 2017 08:25:04 -0500 Subject: [PATCH 0677/1644] Refs CF-1594. Fixed interactive deprecation in Python --- redhawk/src/base/framework/python/ossie/resource.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/redhawk/src/base/framework/python/ossie/resource.py b/redhawk/src/base/framework/python/ossie/resource.py index f731f1824..f010cabb2 100644 --- a/redhawk/src/base/framework/python/ossie/resource.py +++ b/redhawk/src/base/framework/python/ossie/resource.py @@ -1190,7 +1190,11 @@ def setupSignalHandlers(): signal.signal(signal.SIGTERM, __exit_handler) def _getInteractive(opts): - return False + interactive = False + for opt, unused in opts: + if opt == '-i' or opt == '--interactive': + interactive = True + return interactive def parseCommandLineArgs(componentclass): opts, args = _getOptions(componentclass) From cf55fd81f2e13cdf8a33b16659aa5933047f4373 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Mon, 6 Feb 2017 12:16:34 -0500 Subject: [PATCH 0678/1644] Refs CF-1587. Changed time helper package name --- .../python/ossie/utils/rhtime/__init__.py | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 redhawk/src/base/framework/python/ossie/utils/rhtime/__init__.py diff --git a/redhawk/src/base/framework/python/ossie/utils/rhtime/__init__.py b/redhawk/src/base/framework/python/ossie/utils/rhtime/__init__.py new file mode 100644 index 000000000..0f7a0eb83 --- /dev/null +++ b/redhawk/src/base/framework/python/ossie/utils/rhtime/__init__.py @@ -0,0 +1,25 @@ +# +# This file is protected by Copyright. Please refer to the COPYRIGHT file +# distributed with this source distribution. +# +# This file is part of REDHAWK core. +# +# REDHAWK core is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation, either version 3 of the License, or (at your option) any +# later version. +# +# REDHAWK core is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +# details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/. +# + +# This is a stub file to provide the 'redhawk' namespace +# Python files generated for new IDLs will be added under this namespace +# e.g. 'redhawk.mynamespace' + +from helpers import * From 7f312f91416e53d02edeef4fae62d8ebc5282fc9 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Mon, 6 Feb 2017 12:17:06 -0500 Subject: [PATCH 0679/1644] Refs CF-1581. Python helpers for the connection manager --- .../base/framework/python/ossie/properties.py | 4 +- .../python/ossie/utils/model/__init__.py | 4 +- .../python/ossie/utils/redhawk/core.py | 9 +- .../utils/rhtime/helpers.py} | 0 .../python/ossie/utils/type_helpers.py | 2 +- .../framework/python/redhawk/time/__init__.py | 23 --- redhawk/src/base/framework/python/setup.py | 4 +- .../control/sdr/dommgr/DomainManager_impl.cpp | 20 ++- redhawk/src/testing/runtests.py | 1 + .../python/ServiceComponent_base.py | 45 ++++-- .../TestPythonProps/TestPythonProps.py | 4 +- .../waveforms/svc_connect/svc_connect.sad.xml | 44 ++++++ .../testing/tests/test_13_RedhawkModule.py | 58 +++++++ .../tests/test_16_ConnectionManager.py | 148 ++++++++++++++++-- 14 files changed, 304 insertions(+), 62 deletions(-) rename redhawk/src/base/framework/python/{redhawk/time/utils.py => ossie/utils/rhtime/helpers.py} (100%) delete mode 100644 redhawk/src/base/framework/python/redhawk/time/__init__.py create mode 100644 redhawk/src/testing/sdr/dom/waveforms/svc_connect/svc_connect.sad.xml diff --git a/redhawk/src/base/framework/python/ossie/properties.py b/redhawk/src/base/framework/python/ossie/properties.py index d4b3c00a6..b0d0b2a2c 100644 --- a/redhawk/src/base/framework/python/ossie/properties.py +++ b/redhawk/src/base/framework/python/ossie/properties.py @@ -33,7 +33,7 @@ import types import struct import inspect -import redhawk.time.utils +from ossie.utils import rhtime # numpy types to Corba Type codes __NP_ALT_MAP = { @@ -258,7 +258,7 @@ def to_xmlvalue(data, type_): elif type_ == "boolean": v = str(bool(data)).lower() elif type_ == "utctime": - v = redhawk.time.utils.toString(data) + v = rhtime.toString(data) elif type_ == "string": # Remove quotes added by repr v = v[1:-1] return v diff --git a/redhawk/src/base/framework/python/ossie/utils/model/__init__.py b/redhawk/src/base/framework/python/ossie/utils/model/__init__.py index 45a0e6428..466e636d4 100644 --- a/redhawk/src/base/framework/python/ossie/utils/model/__init__.py +++ b/redhawk/src/base/framework/python/ossie/utils/model/__init__.py @@ -40,7 +40,7 @@ from ossie.cf import ExtendedCF as _ExtendedCF from ossie.utils.formatting import TablePrinter from ossie.utils import prop_helpers -import redhawk.time.utils +from ossie.utils import rhtime import warnings as _warnings from connect import * @@ -108,7 +108,7 @@ def _convertType(propType, val): newValue = complex(real, imag) elif propType == 'utctime': if type(val) == str: - newValue = redhawk.time.utils.convert(val) + newValue = rhtime.convert(val) else: newValue = val else: diff --git a/redhawk/src/base/framework/python/ossie/utils/redhawk/core.py b/redhawk/src/base/framework/python/ossie/utils/redhawk/core.py index 1a8646b75..8d033dafe 100644 --- a/redhawk/src/base/framework/python/ossie/utils/redhawk/core.py +++ b/redhawk/src/base/framework/python/ossie/utils/redhawk/core.py @@ -26,6 +26,7 @@ from ossie.cf import CF__POA as _CF__POA from ossie.cf import ExtendedCF as _ExtendedCF from ossie.cf import StandardEvent +import CosEventChannelAdmin from omniORB import CORBA as _CORBA import CosNaming as _CosNaming import sys as _sys @@ -698,6 +699,7 @@ def __init__(self, name="", devMgr=None, dcd=None, domain=None, idmListener=None self.name = name self.ref = devMgr self.id = self.ref._get_identifier() + self._id = self.id self._domain = domain self._dcd = dcd self.fs = self.ref._get_fileSys() @@ -1191,7 +1193,7 @@ def objectRefEndPoint( self, obj_ref, port_name ) : restype = _CF.ConnectionManager.EndpointResolutionType(objectRef=obj_ref) return _CF.ConnectionManager.EndpointRequest(restype, port_name) - def connect( self, usesEndPoint, providesEndPoint, requesterId, connectionId ): + def connect(self, usesEndPoint, providesEndPoint, requesterId='default', connectionId=''): retval=None if self.ref: try: @@ -1201,12 +1203,9 @@ def connect( self, usesEndPoint, providesEndPoint, requesterId, connectionId ): return retval def disconnect( self, connectionRecordId ): - print 'core disconnect' if self.ref: try: - print 'begin core disconnect' self.ref.disconnect( connectionRecordId ) - print 'done core disconnect' except: raise @@ -1226,6 +1225,7 @@ class EventChannel(CorbaObject): def __init__(self, ref, name): CorbaObject.__init__(self, ref) self.name = name + self.ref = self.ref._narrow(CosEventChannelAdmin.EventChannel) class EventChannelManager(CorbaObject): @@ -1521,6 +1521,7 @@ def __init__(self, name="DomainName1", location=None, connectDomainEvents=True): raise StandardError('Domain Manager '+self.name+' is not available') self.id = self.ref._get_identifier() + self._id = self.id try: spd, scd, prf = _readProfile("/mgr/DomainManager.spd.xml", self.fileManager) super(Domain, self).__init__(prf, self.id) diff --git a/redhawk/src/base/framework/python/redhawk/time/utils.py b/redhawk/src/base/framework/python/ossie/utils/rhtime/helpers.py similarity index 100% rename from redhawk/src/base/framework/python/redhawk/time/utils.py rename to redhawk/src/base/framework/python/ossie/utils/rhtime/helpers.py diff --git a/redhawk/src/base/framework/python/ossie/utils/type_helpers.py b/redhawk/src/base/framework/python/ossie/utils/type_helpers.py index 7253911fa..6cc9185f0 100644 --- a/redhawk/src/base/framework/python/ossie/utils/type_helpers.py +++ b/redhawk/src/base/framework/python/ossie/utils/type_helpers.py @@ -114,7 +114,7 @@ def checkValidValue(value, dataType): return bool(value) elif dataType == 'utctime': if type(value) == str: - return redhawk.time.utils.convert(value) + return rhtime.convert(value) return value #this is used for structs #datatype is a list of (ID, propType) pairs, value is a dict mapping an ID to a value for validation diff --git a/redhawk/src/base/framework/python/redhawk/time/__init__.py b/redhawk/src/base/framework/python/redhawk/time/__init__.py deleted file mode 100644 index 5304a70ad..000000000 --- a/redhawk/src/base/framework/python/redhawk/time/__init__.py +++ /dev/null @@ -1,23 +0,0 @@ -# -# This file is protected by Copyright. Please refer to the COPYRIGHT file -# distributed with this source distribution. -# -# This file is part of REDHAWK core. -# -# REDHAWK core is free software: you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation, either version 3 of the License, or (at your option) any -# later version. -# -# REDHAWK core is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more -# details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with this program. If not, see http://www.gnu.org/licenses/. -# - -# This is a stub file to provide the 'redhawk' namespace -# Python files generated for new IDLs will be added under this namespace -# e.g. 'redhawk.mynamespace' diff --git a/redhawk/src/base/framework/python/setup.py b/redhawk/src/base/framework/python/setup.py index eb9c76936..4251ac8ea 100644 --- a/redhawk/src/base/framework/python/setup.py +++ b/redhawk/src/base/framework/python/setup.py @@ -74,8 +74,8 @@ 'ossie/utils/sca', 'ossie/utils/testing', 'ossie/utils/tools', - 'redhawk', - 'redhawk/time'] + 'ossie/utils/rhtime', + 'ossie/utils/rhconnection'] exec(open('ossie/version.py').read()) diff --git a/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp b/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp index 346181723..3ab6341dc 100644 --- a/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp @@ -2201,11 +2201,27 @@ CF::Resource_ptr DomainManager_impl::lookupComponentByInstantiationId(const std: // Search for a Component matching this id // This needs to reconcile the fact that the application id is :, the component id is : // and the unambiguous endpoint for a component is :: - std::size_t pos = identifier.find(":"); + std::size_t begin_pos = 0; + if (identifier.size() > 4) { + if (identifier.substr(0,3) == "DCE") { + begin_pos = 4; + } + } + std::size_t pos = identifier.find(":", begin_pos); if (pos != std::string::npos) { std::string appid = identifier.substr(pos+1); if (_applications.find(appid) == _applications.end()) { - return CF::Resource::_nil(); + // search by id substr instead of id + ApplicationTable::iterator it = _applications.begin(); + while (it != _applications.end()) { + if (appid == it->first.substr(it->first.size()-appid.size(),appid.size())) { + appid = it->first; + break; + } + it++; + } + if (it == _applications.end()) + return CF::Resource::_nil(); } std::string normalized_comp_id = identifier.substr(0,pos)+std::string(":")+appid.substr(appid.rfind(":")+1); for (Application_impl::ComponentList::iterator _comp=_applications[appid]->_components.begin(); _comp!=_applications[appid]->_components.end(); _comp++) {\ diff --git a/redhawk/src/testing/runtests.py b/redhawk/src/testing/runtests.py index 32583ca5f..9011904ce 100755 --- a/redhawk/src/testing/runtests.py +++ b/redhawk/src/testing/runtests.py @@ -80,6 +80,7 @@ def configureTestPaths(): from ossie.utils.idllib import IDLLibrary model._idllib = IDLLibrary() model._idllib.addSearchPath(os.path.join(topdir, 'idl')) + model._idllib.addSearchPath(os.path.join(topdir, '../../bulkioInterfaces/idl')) # Set up the system paths (LD_LIBRARY_PATH, PYTHONPATH, CLASSPATH), IDL paths # and SDRROOT to allow testing against an uninstalled framework. diff --git a/redhawk/src/testing/sdr/dom/components/ServiceComponent/python/ServiceComponent_base.py b/redhawk/src/testing/sdr/dom/components/ServiceComponent/python/ServiceComponent_base.py index 66b1e79b9..26a4c3b75 100644 --- a/redhawk/src/testing/sdr/dom/components/ServiceComponent/python/ServiceComponent_base.py +++ b/redhawk/src/testing/sdr/dom/components/ServiceComponent/python/ServiceComponent_base.py @@ -28,6 +28,8 @@ # Version:M.1.8.2 # Build id: v201211021737RC2 from ossie.cf import CF, CF__POA +from ossie.cf import ExtendedCF +from ossie.cf import ExtendedCF__POA from ossie.utils import uuid from ossie.resource import Resource @@ -166,7 +168,7 @@ def compareSRI(self, a, b): # 'CF/PropertySet' port - class PortCFPropertySetOut(CF__POA.Port): + class PortCFPropertySetOut(ExtendedCF__POA.QueryablePort): """This class is a port template for the output port and should not be instantiated nor modified. @@ -209,16 +211,25 @@ def disconnectPort(self, connectionId): self.outConnections.pop(str(connectionId), None) finally: self.port_lock.release() - + + def _get_connections(self): + self.port_lock.acquire() + try: + return [ExtendedCF.UsesConnection(name, port) for name, port in self.outConnections.iteritems()] + finally: + self.port_lock.release() + def configure(self, configProperties): self.port_lock.acquire() - try: - try: - for connId, port in self.outConnections.items(): - if port != None: port.configure(configProperties) - except Exception: - self.parent._log.exception("The call to configure failed on port %s connection %s instance %s", self.name, connId, port) + try: + for connId, port in self.outConnections.items(): + if port != None: + try: + port.configure(configProperties) + except Exception: + self.parent._log.exception("The call to configure failed on port %s connection %s instance %s", self.name, connId, port) + raise finally: self.port_lock.release() @@ -226,14 +237,18 @@ def query(self, configProperties): retVal = None self.port_lock.acquire() - try: - try: - for connId, port in self.outConnections.items(): - if port != None:retVal = port.query(configProperties) - except Exception: - self.parent._log.exception("The call to query failed on port %s connection %s instance %s", self.name, connId, port) + try: + for connId, port in self.outConnections.items(): + if port != None: + try: + retVal = port.query(configProperties) + except Exception: + self.parent._log.exception("The call to query failed on port %s connection %s instance %s", self.name, connId, port) + raise finally: self.port_lock.release() return retVal - + + + diff --git a/redhawk/src/testing/sdr/dom/components/TestPythonProps/TestPythonProps.py b/redhawk/src/testing/sdr/dom/components/TestPythonProps/TestPythonProps.py index a3a61278a..0f1a54132 100755 --- a/redhawk/src/testing/sdr/dom/components/TestPythonProps/TestPythonProps.py +++ b/redhawk/src/testing/sdr/dom/components/TestPythonProps/TestPythonProps.py @@ -25,7 +25,7 @@ from ossie.resource import Resource, start_component from ossie.properties import simple_property, simpleseq_property, struct_property, structseq_property from omniORB.any import from_any -import redhawk.time.utils +from ossie.utils import rhtime class TestPythonProps (CF__POA.Resource, Resource): @@ -115,7 +115,7 @@ def __init__(self, ip_address="", port=0): self.port = port def reset_utcCallback(self, id, old_value, new_value): - self.simple_utctime = redhawk.time.utils.now() + self.simple_utctime = rhtime.now() multicasts = structseq_property(id_="DCE:897a5489-f680-46a8-a698-e36fd8bbae80[]", name="multicasts", diff --git a/redhawk/src/testing/sdr/dom/waveforms/svc_connect/svc_connect.sad.xml b/redhawk/src/testing/sdr/dom/waveforms/svc_connect/svc_connect.sad.xml new file mode 100644 index 000000000..266522a82 --- /dev/null +++ b/redhawk/src/testing/sdr/dom/waveforms/svc_connect/svc_connect.sad.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + ServiceComponent_1 + + + + + + + + + + + diff --git a/redhawk/src/testing/tests/test_13_RedhawkModule.py b/redhawk/src/testing/tests/test_13_RedhawkModule.py index ebaab18d8..e4b2ea3e8 100644 --- a/redhawk/src/testing/tests/test_13_RedhawkModule.py +++ b/redhawk/src/testing/tests/test_13_RedhawkModule.py @@ -28,6 +28,7 @@ from ossie.cf import CF from ossie.utils import redhawk from ossie.utils import type_helpers +from ossie.utils import rhconnection from ossie.events import Subscriber, Publisher from ossie.cf import CF @@ -748,3 +749,60 @@ def test_connect(self): post.extend(comp.runTest(0, [])) self.assertTrue(len(post) > len(pre)) + + def test_connectionMgrApp(self): + """ + Tests that applications can make connections between their external ports + """ + self.launchDeviceManager('/nodes/test_PortTestDevice_node/DeviceManager.dcd.xml') + + app1 = self._rhDom.createApplication('/waveforms/PortConnectExternalPort/PortConnectExternalPort.sad.xml') + app2 = self._rhDom.createApplication('/waveforms/PortConnectExternalPort/PortConnectExternalPort.sad.xml') + + # Tally up the connections prior to making an app-to-app connection; + # the PortTest component's runTest method returns the identifiers of + # any connected Resources + pre = [] + for comp in app1.comps + app2.comps: + pre.extend(comp.runTest(0, [])) + + ep1=rhconnection.makeEndPoint(app1, 'resource_out') + ep2=rhconnection.makeEndPoint(app2, '') + cMgr = self._rhDom._get_connectionMgr() + cMgr.connect(ep1,ep2) + + # Tally up the connections to check that a new one has been made + post = [] + for comp in app1.comps + app2.comps: + post.extend(comp.runTest(0, [])) + + self.assertTrue(len(post) > len(pre)) + + def test_connectionMgrComp(self): + """ + Tests that applications can make connections between their external ports + """ + self.launchDeviceManager('/nodes/test_PortTestDevice_node/DeviceManager.dcd.xml') + + app1 = self._rhDom.createApplication('/waveforms/PortConnectExternalPort/PortConnectExternalPort.sad.xml') + app2 = self._rhDom.createApplication('/waveforms/PortConnectExternalPort/PortConnectExternalPort.sad.xml') + + for _comp in app1.comps: + print 'searching: ',_comp.name, _comp._id + if _comp._id[:50] == 'DCE:12ab27fb-01bd-4189-8d1d-0043b87c4f74:PortConne': + break + + for _port in _comp.ports: + if _port.name == 'resource_out': + break + + self.assertEquals(len(_port._get_connections()), 0) + + ep1=rhconnection.makeEndPoint(_comp, 'resource_out') + print ep1 + ep2=rhconnection.makeEndPoint(app2, '') + print ep2 + cMgr = self._rhDom._get_connectionMgr() + cMgr.connect(ep1,ep2) + + self.assertEquals(len(_port._get_connections()), 1) diff --git a/redhawk/src/testing/tests/test_16_ConnectionManager.py b/redhawk/src/testing/tests/test_16_ConnectionManager.py index df2a441ae..0e382d103 100644 --- a/redhawk/src/testing/tests/test_16_ConnectionManager.py +++ b/redhawk/src/testing/tests/test_16_ConnectionManager.py @@ -24,6 +24,7 @@ from ossie.cf import CF from ossie.cf import ExtendedCF from ossie import properties +from ossie.utils import redhawk, rhconnection class ConnectionManagerTest(scatest.CorbaTestCase): def setUp(self): @@ -194,18 +195,21 @@ def setUp(self): super(ConnectionManagerTestRedhawkUtils,self).setUp() nb, self._domMgr = self.launchDomainManager() nb, self._devMgr = self.launchDeviceManager('/nodes/test_PortTestDevice_node/DeviceManager.dcd.xml') - self._connMgr = self._domMgr._get_connectionMgr() # Device IDs taken from the DCD self.devId1 = 'DCE:322fb9b2-de57-42a2-ad03-217bcb244262' self.devId2 = 'DCE:47dc45d8-19b5-4b7e-bcd4-b165babe5b84' - from ossie.utils import redhawk - d=redhawk.Domain(self._domMgr._get_name() ) - self.assertNotEqual(d,None) - + self.dom=redhawk.attach(self._domMgr._get_name() ) + for dev in self.dom.devices: + if dev._get_identifier() == self.devId1: + self.dev1 = dev + if dev._get_identifier() == self.devId2: + self.dev2 = dev + self.assertNotEqual(self.dom,None) + # The DCD has one connection, verify that it is listed - self.cm = d.getConnectionMgr() + self.cm = self.dom.getConnectionMgr() self.assertNotEqual(self.cm, None ) def tearDown(self): @@ -255,7 +259,56 @@ def test_redhawkutils_DeviceConnections(self): # get connnections list clist, citer = self.cm.listConnections() - self.assertEqual(clist, [] ) + self.assertEqual(clist, [] ) + + conn=citer.next_one() + self.assertEqual(conn.usesEndpoint.portName, 'resource_out') + conn=citer.next_one() + self.assertEqual(conn.usesEndpoint.portName, 'resource_out') + conn=citer.next_one() + self.assertEqual(conn, None) + + + # The connection should have been resolved immediately + self.assertTrue(connection.connected) + self.assertEqual(connection.usesEndpoint.portName, 'resource_out') + self.assertEqual(connection.providesEndpoint.portName, '') + + # Verify that the connection was really made + connections = connection.usesEndpoint.endpointObject._get_connections() + self.assertTrue(len(connections) == 1) + self.assertEqual(connections[0].connectionId, 'test_connection') + self.assertEqual(connections[0].port._get_identifier(), self.devId1) + + # Break the connection and make sure the connection went away + self.cm.disconnect(connectionReportId) + connections = self.cm.connections + self.assertEqual(len(connections), 1) + + def test_connect_DeviceConnections(self): + + # The DCD has one connection, verify that it is listed + connections = self.cm.connections + self.assertEqual(len(connections), 1) + + # Use the first device's resource_out port as the uses endpoint + uses = rhconnection.makeEndPoint(self.dev2, 'resource_out') + + # Use the device itself as the provides endpoint + provides = rhconnection.makeEndPoint( self.dev1, '' ) + + # Create a new connection with a known ID + connectionReportId = self.cm.connect(uses, provides, 'test_environment', 'test_connection') + + # Make sure the new connection is listed + connections = self.cm.connections + self.assertEqual(len(connections), 2) + connection = self._findConnection(connections, 'test_connection') + self.assertFalse(connection is None) + + # get connnections list + clist, citer = self.cm.listConnections() + self.assertEqual(clist, [] ) conn=citer.next_one() self.assertEqual(conn.usesEndpoint.portName, 'resource_out') @@ -298,8 +351,52 @@ def test_redhawkutils_ComponentConnections(self): connections = connection.usesEndpoint.endpointObject._narrow(ExtendedCF.QueryablePort)._get_connections() self.assertTrue(len(connections) == 1) self.assertEqual(connections[0].connectionId, 'test_connection') - - + + def test_connect_ComponentConnections(self): + app_src = self.dom.createApplication('/waveforms/comp_src_w/comp_src_w.sad.xml', 'src_app', [], []) + app_snk = self.dom.createApplication('/waveforms/comp_snk_w/comp_snk_w.sad.xml', 'snk_app', [], []) + comp_src = app_src.comps[0] + comp_snk = app_snk.comps[0] + + uses = rhconnection.makeEndPoint( comp_src, 'dataFloat_out') + provides = rhconnection.makeEndPoint( comp_snk, 'dataFloat_in') + connectionReportId = self.cm.connect(uses, provides, 'test_environment', 'test_connection') + connections = self.cm.connections + self.assertEqual(len(connections), 2) + connection = self._findConnection(connections,'test_connection') + self.assertFalse(connection is None) + self.assertTrue(connection.connected) + self.assertEqual(connection.usesEndpoint.portName, 'dataFloat_out') + self.assertEqual(connection.providesEndpoint.portName, 'dataFloat_in') + connections = connection.usesEndpoint.endpointObject._narrow(ExtendedCF.QueryablePort)._get_connections() + out_connections = comp_src.ports[0].ref._get_connections() + self.assertTrue(connections[0].port._is_equivalent(out_connections[0].port)) + self.assertTrue(len(connections) == 1) + self.assertEqual(connections[0].connectionId, 'test_connection') + + def test_connect_ServicesConnections(self): + app_src = self.dom.createApplication('/waveforms/svc_connect/svc_connect.sad.xml', 'svc_connect', [], []) + nb, self._devMgrSvc = self.launchDeviceManager('/nodes/test_BasicService_node/DeviceManager.dcd.xml') + comp_src = app_src.comps[0] + for svc in self.dom.services: + if svc.name == 'BasicService1': + break + + uses = rhconnection.makeEndPoint( comp_src, 'output') + provides = rhconnection.makeEndPoint( svc, '') + connectionReportId = self.cm.connect(uses, provides, 'test_environment', 'test_connection') + connections = self.cm.connections + self.assertEqual(len(connections), 2) + connection = self._findConnection(connections,'test_connection') + self.assertFalse(connection is None) + self.assertTrue(connection.connected) + self.assertEqual(connection.usesEndpoint.portName, 'output') + connections = connection.usesEndpoint.endpointObject._narrow(ExtendedCF.QueryablePort)._get_connections() + out_connections = comp_src.ports[0].ref._get_connections() + self.assertTrue(connections[0].port._is_equivalent(out_connections[0].port)) + self.assertTrue(len(connections) == 1) + self.assertEqual(connections[0].connectionId, 'test_connection') + def test_redhawkutils_ApplicationConnections(self): app = self._createApp('/waveforms/PortConnectExternalPortRename/PortConnectExternalPortRename.sad.xml') @@ -332,6 +429,39 @@ def test_redhawkutils_ApplicationConnections(self): self.assertEqual(len(connections), 1) app.releaseObject() + + def test_connect_ApplicationConnections(self): + app = self.dom.createApplication('/waveforms/PortConnectExternalPortRename/PortConnectExternalPortRename.sad.xml') + + # Connect the application's external uses port to the first device's + # provides port + uses = rhconnection.makeEndPoint( app, 'rename_resource_out') + provides = rhconnection.makeEndPoint( self.dev1, 'resource_in') + connectionReportId = self.cm.connect(uses, provides, 'test_environment', 'test_connection') + + # Make sure the new connection is listed + connections = self.cm.connections + self.assertEqual(len(connections), 2) + connection = self._findConnection(connections,'test_connection') + self.assertFalse(connection is None) + + # The connection should have been resolved immediately + self.assertTrue(connection.connected) + self.assertEqual(connection.usesEndpoint.portName, 'rename_resource_out') + self.assertEqual(connection.providesEndpoint.portName, 'resource_in') + + # Verify that the connection was really made + connections = connection.usesEndpoint.endpointObject._get_connections() + self.assertTrue(len(connections) == 1) + self.assertEqual(connections[0].connectionId, 'test_connection') + self.assertEqual(connections[0].port._get_identifier(), self.devId1+'/resource_in') + + # Break the connection and make sure the connection went away + self.cm.disconnect(connectionReportId) + connections = self.cm.connections + self.assertEqual(len(connections), 1) + + app.releaseObject() def test_redhawkutils_DeferredConnections(self): app = self._createApp('/waveforms/PortConnectExternalPortRename/PortConnectExternalPortRename.sad.xml') From 7a09197404c275e5a02f88d5ecc7019ca83049e1 Mon Sep 17 00:00:00 2001 From: 8530 <8530@vm-131.vsi-corp.com> Date: Mon, 6 Feb 2017 14:32:52 -0500 Subject: [PATCH 0680/1644] add check for numa library support if available --- redhawk/src/base/framework/affinity.cpp | 50 ++++++++++++++++--------- 1 file changed, 32 insertions(+), 18 deletions(-) diff --git a/redhawk/src/base/framework/affinity.cpp b/redhawk/src/base/framework/affinity.cpp index 693d6269b..5ac5f55d4 100644 --- a/redhawk/src/base/framework/affinity.cpp +++ b/redhawk/src/base/framework/affinity.cpp @@ -78,6 +78,15 @@ namespace redhawk { namespace affinity { + bool check_numa() { +#ifdef HAVE_LIBNUMA + return (numa_available() != -1); +#else + return false; +#endif + } + + // // promote nic affinity to a socket if all associated cpus for the interface are blacklisted // @@ -93,7 +102,7 @@ namespace redhawk { // static SetAffinityFunc _affinity_override_func = NULL; - static rh_logger::LoggerPtr _affinity_logger = rh_logger::Logger::getLogger("redhawk::affinity"); + static rh_logger::LoggerPtr _affinity_logger = rh_logger::Logger::getLogger("redhawk.affinity"); // @@ -130,7 +139,7 @@ namespace redhawk { // bool is_disabled() { bool retval=false; - if ( !_affinity_enabled || std::getenv("REDHAWK_DISABLE_AFFINITY") != NULL ) { + if ( !_affinity_enabled || std::getenv("REDHAWK_DISABLE_AFFINITY") != NULL || check_numa() == false ) { //RH_DEBUG(_affinity_logger, "Affinity processing is disabled."); retval=true; } @@ -226,24 +235,29 @@ namespace redhawk { // Determine cpu list by interrupts assigned for the specified NIC CpuList cpulist = identify_cpus(iface); if ( cpulist.size() > 0 ) { - int psoc=-1; + if ( check_numa() ) { + int psoc=-1; #if HAVE_LIBNUMA - int soc=-1; - for( int i=0; i < (int)cpulist.size();i++ ) { - RH_DEBUG(_affinity_logger, "Finding (processor socket) for NIC:" << iface << " socket :" << numa_node_of_cpu(cpulist[i]) ); - if ( std::count( bl.begin(), bl.end(), cpulist[i] ) != 0 ) continue; - - soc = numa_node_of_cpu(cpulist[i]); - if ( soc != psoc && psoc != -1 && !findFirst ) { - RH_WARN(_affinity_logger, "More than 1 socket servicing NIC:" << iface); - psoc=-1; - break; - } - psoc=soc; - if( findFirst ) break; - } + int soc=-1; + for( int i=0; i < (int)cpulist.size();i++ ) { + RH_DEBUG(_affinity_logger, "Finding (processor socket) for NIC:" << iface << " socket :" << numa_node_of_cpu(cpulist[i]) ); + if ( std::count( bl.begin(), bl.end(), cpulist[i] ) != 0 ) continue; + + soc = numa_node_of_cpu(cpulist[i]); + if ( soc != psoc && psoc != -1 && !findFirst ) { + RH_WARN(_affinity_logger, "More than 1 socket servicing NIC:" << iface); + psoc=-1; + break; + } + psoc=soc; + if( findFirst ) break; + } #endif - retval=psoc; + retval=psoc; + } + else { + retval=0; + } } From b5d547d755cf529af0c55501591749e81d9c59f0 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Tue, 7 Feb 2017 08:30:44 -0500 Subject: [PATCH 0681/1644] Refs CF-1581. connectionManager helpers --- .../ossie/utils/rhconnection/__init__.py | 25 ++++ .../ossie/utils/rhconnection/helpers.py | 131 ++++++++++++++++++ 2 files changed, 156 insertions(+) create mode 100644 redhawk/src/base/framework/python/ossie/utils/rhconnection/__init__.py create mode 100644 redhawk/src/base/framework/python/ossie/utils/rhconnection/helpers.py diff --git a/redhawk/src/base/framework/python/ossie/utils/rhconnection/__init__.py b/redhawk/src/base/framework/python/ossie/utils/rhconnection/__init__.py new file mode 100644 index 000000000..0f7a0eb83 --- /dev/null +++ b/redhawk/src/base/framework/python/ossie/utils/rhconnection/__init__.py @@ -0,0 +1,25 @@ +# +# This file is protected by Copyright. Please refer to the COPYRIGHT file +# distributed with this source distribution. +# +# This file is part of REDHAWK core. +# +# REDHAWK core is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation, either version 3 of the License, or (at your option) any +# later version. +# +# REDHAWK core is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +# details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/. +# + +# This is a stub file to provide the 'redhawk' namespace +# Python files generated for new IDLs will be added under this namespace +# e.g. 'redhawk.mynamespace' + +from helpers import * diff --git a/redhawk/src/base/framework/python/ossie/utils/rhconnection/helpers.py b/redhawk/src/base/framework/python/ossie/utils/rhconnection/helpers.py new file mode 100644 index 000000000..5a42d2d41 --- /dev/null +++ b/redhawk/src/base/framework/python/ossie/utils/rhconnection/helpers.py @@ -0,0 +1,131 @@ +# +# This file is protected by Copyright. Please refer to the COPYRIGHT file +# distributed with this source distribution. +# +# This file is part of REDHAWK bulkioInterfaces. +# +# REDHAWK bulkioInterfaces is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation, either version 3 of the License, or (at your option) any +# later version. +# +# REDHAWK bulkioInterfaces is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +# details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/. +# + +from ossie.cf import CF +import ossie.utils.redhawk + +class CannotResolve(Exception): + pass + +class NotSandboxObject(Exception): + pass + +class CannotResolveRef(Exception): + pass + +def makeEndPoint(obj, port_name='', rsc_id=None, force=False): + ''' + obj: a sandbox or CORBA-accessible object + port_name: the port name (where applicable). Use an empty string for base supported interface + rsc_id: the unique domain id for the Domain object/resource. This string is optional (the function tries to figure out what it should be) + force: return an endpoint (objref) if nothing else matches + ''' + try: + return makeEndPointFromPy(obj, port_name, rsc_id) + except NotSandboxObject: + pass + except Exception as e: + raise + + try: + return makeEndPointFromRef(obj, port_name, rsc_id) + except CannotResolveRef: + pass + except Exception as e: + raise + + if not force: + raise CannotResolve('Object '+str(obj)+' could not be resolved to a sandbox object or CORBA-accessible Domain object') + + restype = CF.ConnectionManager.EndpointResolutionType(objectRef='') + return CF.ConnectionManager.EndpointRequest(restype, port_name) + +def makeEndPointFromPy(obj, port_name='', rsc_id=None): + + if isinstance(obj, ossie.utils.redhawk.device.DomainDevice): + _id = rsc_id + if not _id: + _id = obj._id + restype = CF.ConnectionManager.EndpointResolutionType(deviceId=_id) + return CF.ConnectionManager.EndpointRequest(restype, port_name) + elif isinstance(obj, ossie.utils.redhawk.core.App): + _id = rsc_id + if not _id: + _id = obj._id + restype = CF.ConnectionManager.EndpointResolutionType(applicationId=_id) + return CF.ConnectionManager.EndpointRequest(restype, port_name) + elif isinstance(obj, ossie.utils.redhawk.component.Component): + _id = rsc_id + if not _id: + _id = obj._id + restype = CF.ConnectionManager.EndpointResolutionType(componentId=_id) + return CF.ConnectionManager.EndpointRequest(restype, port_name) + elif isinstance(obj, ossie.utils.redhawk.core.EventChannel): + _id = rsc_id + if not _id: + _id = obj.name + restype = CF.ConnectionManager.EndpointResolutionType(channelName=_id) + return CF.ConnectionManager.EndpointRequest(restype, port_name) + elif isinstance(obj, ossie.utils.redhawk.core.Service): + _id = rsc_id + if not _id: + _id = obj.name + restype = CF.ConnectionManager.EndpointResolutionType(serviceName=_id) + return CF.ConnectionManager.EndpointRequest(restype, port_name) + elif isinstance(obj, ossie.utils.redhawk.core.DeviceManager): + _id = rsc_id + if not _id: + _id = obj._id + restype = CF.ConnectionManager.EndpointResolutionType(deviceMgrId=_id) + return CF.ConnectionManager.EndpointRequest(restype, port_name) + raise NotSandboxObject('Object '+str(obj)+' is not a sandbox object') + +def makeEndPointFromRef(obj, port_name='', rsc_id=None): + _id = rsc_id + try: + if hasattr(obj, '_this'): + repid = obj._this()._NP_RepositoryId + else: + repid = obj._NP_RepositoryId + except: + raise Exception('Object must have repository id') + + if not _id: # could just be object + try: + _id = obj._get_identifier() + except: + pass + + if repid == 'IDL:omni/omniEvents/EventChannel:1.0' and not _id: + raise CannotResolveRef('Object '+str(obj)+' is an Event Channel. An Event Channel name must be provided (rsc_id)') + + if 'Device' in repid and _id != None: # executable, loadable, base, or any of the aggregate devices + restype = CF.ConnectionManager.EndpointResolutionType(deviceId=_id) + return CF.ConnectionManager.EndpointRequest(restype, port_name) + elif repid == 'IDL:CF/Application:1.0' and _id != None: + restype = CF.ConnectionManager.EndpointResolutionType(applicationId=_id) + return CF.ConnectionManager.EndpointRequest(restype, port_name) + elif repid == 'IDL:CF/Resource:1.0' and _id != None: + restype = CF.ConnectionManager.EndpointResolutionType(componentId=_id) + return CF.ConnectionManager.EndpointRequest(restype, port_name) + elif repid == 'IDL:CF/DeviceManager:1.0' and name != None: + restype = CF.ConnectionManager.EndpointResolutionType(channelName=name) + return CF.ConnectionManager.EndpointRequest(restype, port_name) + raise CannotResolveRef('Object '+str(obj)+' cannot be resolved to a Device, Application, Component, Event Channel, or Device Manager. A reference is insufficient to resolve the object further') From 0c87ef9a25443895fd1f278188338cc3ba5894c5 Mon Sep 17 00:00:00 2001 From: 8530 <8530@vm-131.vsi-corp.com> Date: Tue, 7 Feb 2017 10:21:30 -0500 Subject: [PATCH 0682/1644] add api call to grab data from subscriber --- .../src/org/ossie/events/Subscriber.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/redhawk/src/base/framework/java/ossie/src/org/ossie/events/Subscriber.java b/redhawk/src/base/framework/java/ossie/src/org/ossie/events/Subscriber.java index a2b7f302a..a61c4a483 100644 --- a/redhawk/src/base/framework/java/ossie/src/org/ossie/events/Subscriber.java +++ b/redhawk/src/base/framework/java/ossie/src/org/ossie/events/Subscriber.java @@ -181,6 +181,25 @@ public int getData( Any ret ) { } + public Any getData() { + + Any retval=null; + try{ + + // check if callback method is enable.. it so then return + if ( dataArrivedCB != null ) return retval; + + // check if data is available + if ( events.size() < 1 ) return retval; + + return events.remove(); + } + catch( Throwable e) { + } + + return retval; + } + public void setDataArrivedListener( DataArrivedListener newListener ) { dataArrivedCB = newListener; } From bf84fbcd318816e62bb04167ccf68162714d49bf Mon Sep 17 00:00:00 2001 From: Max Robert Date: Thu, 9 Feb 2017 09:48:13 -0500 Subject: [PATCH 0683/1644] Restored installation of the redhawk directory to the python package --- redhawk/src/base/framework/python/setup.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/redhawk/src/base/framework/python/setup.py b/redhawk/src/base/framework/python/setup.py index 4251ac8ea..2cceafd7f 100644 --- a/redhawk/src/base/framework/python/setup.py +++ b/redhawk/src/base/framework/python/setup.py @@ -75,7 +75,8 @@ 'ossie/utils/testing', 'ossie/utils/tools', 'ossie/utils/rhtime', - 'ossie/utils/rhconnection'] + 'ossie/utils/rhconnection', + 'redhawk'] exec(open('ossie/version.py').read()) From 551a9a087d83291c0109632065dada3452a8f00f Mon Sep 17 00:00:00 2001 From: Ryan Bauman Date: Thu, 9 Feb 2017 16:13:45 -0500 Subject: [PATCH 0684/1644] RELENG-542 - add cppunit-devel BuildRequires --- redhawk/src/releng/redhawk.spec | 1 + 1 file changed, 1 insertion(+) diff --git a/redhawk/src/releng/redhawk.spec b/redhawk/src/releng/redhawk.spec index eff856a04..a4cb3d308 100644 --- a/redhawk/src/releng/redhawk.spec +++ b/redhawk/src/releng/redhawk.spec @@ -65,6 +65,7 @@ BuildRequires: omniORB-devel >= 4.1.0 BuildRequires: omniORBpy-devel >= 3.0 BuildRequires: libomniEvents2-devel BuildRequires: xsd >= 3.3.0 +BuildRequires: cppunit-devel %description REDHAWK is a Software Defined Radio framework. From 8025083bc008f103db90fe8f3a6488c757c9527e Mon Sep 17 00:00:00 2001 From: 8530 <8530@vm-131.vsi-corp.com> Date: Fri, 10 Feb 2017 08:10:19 -0500 Subject: [PATCH 0685/1644] change dtd to require at least 1 componentplacement with optional usesdeviceref for collocation --- redhawk/src/xml/dtd/softwareassembly.dtd | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/redhawk/src/xml/dtd/softwareassembly.dtd b/redhawk/src/xml/dtd/softwareassembly.dtd index 5adbfd422..a996a5966 100644 --- a/redhawk/src/xml/dtd/softwareassembly.dtd +++ b/redhawk/src/xml/dtd/softwareassembly.dtd @@ -191,8 +191,8 @@ with this program. If not, see http://www.gnu.org/licenses/. name CDATA #IMPLIED> Date: Mon, 13 Feb 2017 11:32:16 -0500 Subject: [PATCH 0686/1644] Refs CF-1582. Allocation Manager Python helpers --- .../base/framework/python/ossie/properties.py | 6 + .../ossie/utils/allocations/__init__.py | 27 ++ .../python/ossie/utils/allocations/helpers.py | 244 ++++++++++++++++++ redhawk/src/configure.ac | 1 + .../sdr/dommgr/AllocationManager_impl.cpp | 4 +- redhawk/src/testing/Makefile.am | 1 + .../dev/devices/dev_alloc_cpp/cpp/Makefile.am | 32 +++ .../devices/dev_alloc_cpp/cpp/Makefile.am.ide | 9 + .../dev_alloc_cpp/cpp/dev_alloc_cpp.cpp | 106 ++++++++ .../devices/dev_alloc_cpp/cpp/dev_alloc_cpp.h | 32 +++ .../dev_alloc_cpp/cpp/dev_alloc_cpp_base.cpp | 134 ++++++++++ .../dev_alloc_cpp/cpp/dev_alloc_cpp_base.h | 45 ++++ .../dev/devices/dev_alloc_cpp/cpp/main.cpp | 26 ++ .../devices/dev_alloc_cpp/cpp/struct_props.h | 124 +++++++++ .../dev_alloc_cpp/dev_alloc_cpp.prf.xml | 35 +++ .../dev_alloc_cpp/dev_alloc_cpp.scd.xml | 49 ++++ .../dev_alloc_cpp/dev_alloc_cpp.spd.xml | 27 ++ .../dev_alloc_node/DeviceManager.dcd.xml | 23 ++ .../testing/tests/test_13_RedhawkModule.py | 75 ++++++ 19 files changed, 998 insertions(+), 2 deletions(-) create mode 100644 redhawk/src/base/framework/python/ossie/utils/allocations/__init__.py create mode 100644 redhawk/src/base/framework/python/ossie/utils/allocations/helpers.py create mode 100644 redhawk/src/testing/sdr/dev/devices/dev_alloc_cpp/cpp/Makefile.am create mode 100644 redhawk/src/testing/sdr/dev/devices/dev_alloc_cpp/cpp/Makefile.am.ide create mode 100644 redhawk/src/testing/sdr/dev/devices/dev_alloc_cpp/cpp/dev_alloc_cpp.cpp create mode 100644 redhawk/src/testing/sdr/dev/devices/dev_alloc_cpp/cpp/dev_alloc_cpp.h create mode 100644 redhawk/src/testing/sdr/dev/devices/dev_alloc_cpp/cpp/dev_alloc_cpp_base.cpp create mode 100644 redhawk/src/testing/sdr/dev/devices/dev_alloc_cpp/cpp/dev_alloc_cpp_base.h create mode 100644 redhawk/src/testing/sdr/dev/devices/dev_alloc_cpp/cpp/main.cpp create mode 100644 redhawk/src/testing/sdr/dev/devices/dev_alloc_cpp/cpp/struct_props.h create mode 100644 redhawk/src/testing/sdr/dev/devices/dev_alloc_cpp/dev_alloc_cpp.prf.xml create mode 100644 redhawk/src/testing/sdr/dev/devices/dev_alloc_cpp/dev_alloc_cpp.scd.xml create mode 100644 redhawk/src/testing/sdr/dev/devices/dev_alloc_cpp/dev_alloc_cpp.spd.xml create mode 100644 redhawk/src/testing/sdr/dev/nodes/dev_alloc_node/DeviceManager.dcd.xml diff --git a/redhawk/src/base/framework/python/ossie/properties.py b/redhawk/src/base/framework/python/ossie/properties.py index b0d0b2a2c..73df21e3f 100644 --- a/redhawk/src/base/framework/python/ossie/properties.py +++ b/redhawk/src/base/framework/python/ossie/properties.py @@ -148,6 +148,12 @@ def getTypeMap(): return __TYPE_MAP +def getTypeNameFromTC(_tc): + for _key in __TYPE_MAP: + if __TYPE_MAP[_key][1] == _tc: + return _key + return None + def getPyType(type_, alt_map=None): if alt_map: try: diff --git a/redhawk/src/base/framework/python/ossie/utils/allocations/__init__.py b/redhawk/src/base/framework/python/ossie/utils/allocations/__init__.py new file mode 100644 index 000000000..18d89a780 --- /dev/null +++ b/redhawk/src/base/framework/python/ossie/utils/allocations/__init__.py @@ -0,0 +1,27 @@ +# +# This file is protected by Copyright. Please refer to the COPYRIGHT file +# distributed with this source distribution. +# +# This file is part of REDHAWK core. +# +# REDHAWK core is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation, either version 3 of the License, or (at your option) any +# later version. +# +# REDHAWK core is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +# details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/. +# + +# This is a stub file to provide the 'redhawk' namespace +# Python files generated for new IDLs will be added under this namespace +# e.g. 'redhawk.mynamespace' + +from helpers import * + +#__all__ = ['WrongInputType', 'MissingProperty', 'changeType', 'getType'] diff --git a/redhawk/src/base/framework/python/ossie/utils/allocations/helpers.py b/redhawk/src/base/framework/python/ossie/utils/allocations/helpers.py new file mode 100644 index 000000000..e541c655f --- /dev/null +++ b/redhawk/src/base/framework/python/ossie/utils/allocations/helpers.py @@ -0,0 +1,244 @@ +# +# This file is protected by Copyright. Please refer to the COPYRIGHT file +# distributed with this source distribution. +# +# This file is part of REDHAWK bulkioInterfaces. +# +# REDHAWK bulkioInterfaces is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation, either version 3 of the License, or (at your option) any +# later version. +# +# REDHAWK bulkioInterfaces is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +# details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/. +# +from ossie.cf import CF +import copy +from ossie import properties +import ossie.parsers.prf +from omniORB import tcInternal, CORBA, any + +class WrongInputType(Exception): + pass + +class BadValue(Exception): + pass + +class MissingProperty(Exception): + pass + +def tvCode(name): + if name == 'short': + return tcInternal.tv_short + elif name == 'long': + return tcInternal.tv_long + elif name == 'ushort': + return tcInternal.tv_ushort + elif name == 'ulong': + return tcInternal.tv_ulong + elif name == 'float': + return tcInternal.tv_float + elif name == 'double': + return tcInternal.tv_double + elif name == 'boolean': + return tcInternal.tv_boolean + elif name == 'char': + return tcInternal.tv_char + elif name == 'octet': + return tcInternal.tv_octet + elif name == 'string': + return tcInternal.tv_string + elif name == 'longlong': + return tcInternal.tv_longlong + elif name == 'ulonglong': + return tcInternal.tv_ulonglong + elif name == 'double': + return tcInternal.tv_longdouble + elif name == 'wchar': + return tcInternal.tv_wchar + raise BadValue('Could not find the sequence code for '+name) + +def createRequest(requestId=None, props={}, pools=[], devices=[], sourceId=''): + return CF.AllocationManager.AllocationRequestType(requestId, props, pools, devices, sourceId) + +def allTypes(): + retval = [] + for _t in properties.getTypeMap(): + retval.append(_t) + return retval + +def __typeCheck(props): + if not isinstance(props, list): + raise WrongInputType('The argument "props" must be a list of properties (i.e.: CF.DataType). Use properties.props_from_dict') + if len(props) == 0: + raise MissingProperty('The list of properties must be greater than zero') + for prop in props: + if not isinstance(prop, CF.DataType): + raise WrongInputType('The argument "props" must be a list of properties (i.e.: CF.DataType). Use properties.props_from_dict') + +def __getProp(props, prop_id): + for prop in props: + if prop.id == prop_id: + return prop + raise MissingProperty('Could not find the property with id: '+str(prop_id)) + +def __getPropIdx(props, prop_id): + idx = 0 + for prop in props: + if prop.id == prop_id: + return idx + idx = idx + 1 + raise MissingProperty('Could not find the property with id: '+str(prop_id)) + +def getType(props, prop_id, typeCheck=True): + ''' + return the property type for the element in the props sequence with id of prop_id + ''' + if typeCheck: + __typeCheck(props) + prop = __getProp(props, prop_id) + return properties.getTypeNameFromTC(prop.value._t) + +def setType(props, prop_id, _type, typeCheck=True): + ''' + change the property type for the element in the props sequence with id of prop_id + This method returns a copy of props (does not modify the props input) + ''' + if typeCheck: + __typeCheck(props) + if not properties.getTypeMap().has_key(_type): + raise BadValue('Type "'+_type+'" does not exist') + if _type == getType(props, prop_id, False): + return props + prop_idx = __getPropIdx(props, prop_id) + ret_props = copy.deepcopy(props) + if props[prop_idx].value._t._k == CORBA.tk_sequence: + ret_props[prop_idx].value._t._d = (props[prop_idx].value._t._d[0], tvCode(_type), props[prop_idx].value._t._d[2]) + else: + ret_props[prop_idx].value = properties.to_tc_value(props[prop_idx].value,_type) + return ret_props + +def matchTypes(props, prop_ids=[], prf=None): + ''' + match the property type for the element in the props sequence with id of prop_ids to the type specified in the prf file specified + This method returns a copy of props (does not modify the props input) + + if prop_ids is not length 0, only those properties are updated + if prop_ids is length 0, all matching properties (props vs prf xml string) are matched + + if prf file is one of the following: + - a Python open file handle; e.g.: fp = open('/data/rh/sdrroot/dom/foo.prf.xml','r') + - a CF::File object; e.g.: fp=fileMgr.open('/foo.prf.xml',True) + - a local filename; e.g.: '/data/rh/sdrroot/dom/foo.prf.xml' + ''' + __typeCheck(props) + + prfcontents='' + if prf: + if isinstance(prf, CF._objref_File): + _len = len(prfcontents) + while True: + prfcontents += fp.read(10000) + if _len == len(prfcontents): + break + _len = len(prfcontents) + prf.close() + elif isinstance(prf, file): + prfcontents = prf.read() + prf.close() + elif isinstance(prf, str): + fp = open(prf, 'r') + prfcontents = fp.read() + fp.close() + else: + raise WrongInputType('The prf argument must be: a string, a file object, or a CF.File object') + + parsedPrf = ossie.parsers.prf.parseString(prfcontents) + classes = {} + + structs = parsedPrf.get_struct()# + [_prop.get_struct() for _prop in parsedPrf.get_structsequence()] + structsseq = [_prop.get_struct() for _prop in parsedPrf.get_structsequence()] + for _prop in parsedPrf.get_struct(): + name = _prop.id_ + if _prop.name: + name = _prop.name + clazz = properties.xml_to_class(_prop) + classes[name] = clazz + for _prop in parsedPrf.get_structsequence(): + name = _prop.id_ + if _prop.name: + name = _prop.name + clazz = properties.xml_to_class(_prop.struct) + # mark as structseq by setting to length 1 list + classes[name] = [clazz] + for _prop in parsedPrf.get_simple(): + name = _prop.id_ + if _prop.name: + name = _prop.name + classes[name] = _prop + for _prop in parsedPrf.get_simplesequence(): + name = _prop.id_ + if _prop.name: + name = _prop.name + classes[name] = _prop + + if len(prop_ids) != 0: + for prop_id in prop_ids: + if not isinstance(prop_id, str): + raise WrongInputType('prop_id must be either a string or None') + if not classes.has_key(prop_id): + raise MissingProperty(prop_id+' is not defined in the given reference prf file') + props = setType(props, prop_id, classes[prop_id].type_, typeCheck=False) + return props + + for _prop in props: + if not classes.has_key(_prop.id): + raise MissingProperty('props contains property '+_prop.id+', but the given reference prf file does not have it defined') + if isinstance(classes[_prop.id], ossie.parsers.prf.simple) or isinstance(classes[_prop.id], ossie.parsers.prf.simpleSequence): + props = setType(props, _prop.id, classes[_prop.id].type_, typeCheck=False) + else: + if isinstance(classes[_prop.id], list): + _idx = __getPropIdx(props, _prop.id) + item_idx = 0 + for item in props[_idx].value._v: + for field in classes[_prop.id][0].__fields: + props[_idx].value._v[item_idx]._v = setType(props[_idx].value._v[item_idx]._v, field.id_, field.type_, typeCheck=False) + item_idx += 1 + else: + _idx = __getPropIdx(props, _prop.id) + for field in classes[_prop.id].__fields: + props[_idx].value._v = setType(props[_idx].value._v, field.id_, field.type_, typeCheck=False) + + return props + +def createProps(prop_dict, prf=None): + props = [] + for _key in prop_dict: + if isinstance(prop_dict[_key],dict): + vals = [] + for _subkey in prop_dict[_key]: + vals.append(CF.DataType(id=_subkey, value=any.to_any(prop_dict[_key][_subkey]))) + props.append(CF.DataType(id=_key, value = any.to_any(vals))) + elif isinstance(prop_dict[_key],list): + if len(prop_dict[_key]) == 0: + props.append(CF.DataType(id=_key, value=any.to_any(prop_dict[_key]))) + elif isinstance(prop_dict[_key][0],dict): + vals = [] + for _item in prop_dict[_key]: + subval = [] + for _subkey in _item: + subval.append(CF.DataType(id=_subkey, value=any.to_any(_item[_subkey]))) + vals.append(any.to_any(subval)) + props.append(CF.DataType(id=_key, value = any.to_any(vals))) + else: + props.append(CF.DataType(id=_key, value=any.to_any(prop_dict[_key]))) + else: + props.append(CF.DataType(id=_key, value=any.to_any(prop_dict[_key]))) + if prf: + props = matchTypes(props, prf=prf) + return props diff --git a/redhawk/src/configure.ac b/redhawk/src/configure.ac index 24972fc2e..17036c44e 100644 --- a/redhawk/src/configure.ac +++ b/redhawk/src/configure.ac @@ -342,6 +342,7 @@ AC_CONFIG_FILES(Makefile \ testing/sdr/dev/devices/GPP/cpp/Makefile \ testing/sdr/dev/devices/java_dev/java/Makefile \ testing/sdr/dev/devices/LongDevice/cpp/Makefile \ + testing/sdr/dev/devices/dev_alloc_cpp/cpp/Makefile \ testing/sdr/dev/services/BasicService_java/java/Makefile \ testing/sdr/dev/services/BasicService_cpp/cpp/Makefile \ testing/sdr/dom/deps/cpp_dep1/cpp/Makefile \ diff --git a/redhawk/src/control/sdr/dommgr/AllocationManager_impl.cpp b/redhawk/src/control/sdr/dommgr/AllocationManager_impl.cpp index 064a9218f..123be870c 100644 --- a/redhawk/src/control/sdr/dommgr/AllocationManager_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/AllocationManager_impl.cpp @@ -177,7 +177,7 @@ CF::AllocationManager::AllocationResponseSequence* AllocationManager_impl::alloc typedef std::list LocalAllocationList; LocalAllocationList local_allocations; - + for (unsigned int request_idx=0; request_idx Exclude from build. Re-include files +# by opening the Properties dialog of your project and choosing C/C++ Build -> +# Tool Chain Editor, and un-checking "Exclude resource from build " +redhawk_SOURCES_auto = dev_alloc_cpp.cpp +redhawk_SOURCES_auto += dev_alloc_cpp.h +redhawk_SOURCES_auto += dev_alloc_cpp_base.cpp +redhawk_SOURCES_auto += dev_alloc_cpp_base.h diff --git a/redhawk/src/testing/sdr/dev/devices/dev_alloc_cpp/cpp/dev_alloc_cpp.cpp b/redhawk/src/testing/sdr/dev/devices/dev_alloc_cpp/cpp/dev_alloc_cpp.cpp new file mode 100644 index 000000000..ccd3f9206 --- /dev/null +++ b/redhawk/src/testing/sdr/dev/devices/dev_alloc_cpp/cpp/dev_alloc_cpp.cpp @@ -0,0 +1,106 @@ +/************************************************************************** + + This is the device code. This file contains the child class where + custom functionality can be added to the device. Custom + functionality to the base class can be extended here. Access to + the ports can also be done from this class + +**************************************************************************/ + +#include "dev_alloc_cpp.h" + +PREPARE_LOGGING(dev_alloc_cpp_i) + +dev_alloc_cpp_i::dev_alloc_cpp_i(char *devMgr_ior, char *id, char *lbl, char *sftwrPrfl) : + dev_alloc_cpp_base(devMgr_ior, id, lbl, sftwrPrfl) +{ +} + +dev_alloc_cpp_i::dev_alloc_cpp_i(char *devMgr_ior, char *id, char *lbl, char *sftwrPrfl, char *compDev) : + dev_alloc_cpp_base(devMgr_ior, id, lbl, sftwrPrfl, compDev) +{ +} + +dev_alloc_cpp_i::dev_alloc_cpp_i(char *devMgr_ior, char *id, char *lbl, char *sftwrPrfl, CF::Properties capacities) : + dev_alloc_cpp_base(devMgr_ior, id, lbl, sftwrPrfl, capacities) +{ +} + +dev_alloc_cpp_i::dev_alloc_cpp_i(char *devMgr_ior, char *id, char *lbl, char *sftwrPrfl, CF::Properties capacities, char *compDev) : + dev_alloc_cpp_base(devMgr_ior, id, lbl, sftwrPrfl, capacities, compDev) +{ +} + +dev_alloc_cpp_i::~dev_alloc_cpp_i() +{ +} + +void dev_alloc_cpp_i::constructor() +{ + /*********************************************************************************** + This is the RH constructor. All properties are properly initialized before this function is called + ***********************************************************************************/ + this->setAllocationImpl(s_prop, this, &dev_alloc_cpp_i::alloc_s_prop, &dev_alloc_cpp_i::dealloc_s_prop); + this->setAllocationImpl(si_prop, this, &dev_alloc_cpp_i::alloc_si_prop, &dev_alloc_cpp_i::dealloc_si_prop); + this->setAllocationImpl(se_prop, this, &dev_alloc_cpp_i::alloc_se_prop, &dev_alloc_cpp_i::dealloc_se_prop); + this->setAllocationImpl(sq_prop, this, &dev_alloc_cpp_i::alloc_sq_prop, &dev_alloc_cpp_i::dealloc_sq_prop); +} + +/************************************************************************** + + This is called automatically after allocateCapacity or deallocateCapacity are called. + Your implementation should determine the current state of the device: + + setUsageState(CF::Device::IDLE); // not in use + setUsageState(CF::Device::ACTIVE); // in use, with capacity remaining for allocation + setUsageState(CF::Device::BUSY); // in use, with no capacity remaining for allocation + +**************************************************************************/ +void dev_alloc_cpp_i::updateUsageState() +{ +} + +bool dev_alloc_cpp_i::alloc_s_prop(const s_prop_struct &value) +{ + // perform logic + return true; // successful allocation +} +void dev_alloc_cpp_i::dealloc_s_prop(const s_prop_struct &value) +{ + // perform logic +} +bool dev_alloc_cpp_i::alloc_si_prop(const short &value) +{ + // perform logic + return true; // successful allocation +} +void dev_alloc_cpp_i::dealloc_si_prop(const short &value) +{ + // perform logic +} +bool dev_alloc_cpp_i::alloc_se_prop(const std::vector &value) +{ + // perform logic + return true; // successful allocation +} +void dev_alloc_cpp_i::dealloc_se_prop(const std::vector &value) +{ + // perform logic +} +bool dev_alloc_cpp_i::alloc_sq_prop(const std::vector &value) +{ + // perform logic + return true; // successful allocation +} +void dev_alloc_cpp_i::dealloc_sq_prop(const std::vector &value) +{ + // perform logic +} + +int dev_alloc_cpp_i::serviceFunction() +{ + LOG_DEBUG(dev_alloc_cpp_i, "serviceFunction() example log message"); + + return NOOP; +} + diff --git a/redhawk/src/testing/sdr/dev/devices/dev_alloc_cpp/cpp/dev_alloc_cpp.h b/redhawk/src/testing/sdr/dev/devices/dev_alloc_cpp/cpp/dev_alloc_cpp.h new file mode 100644 index 000000000..93f7376e8 --- /dev/null +++ b/redhawk/src/testing/sdr/dev/devices/dev_alloc_cpp/cpp/dev_alloc_cpp.h @@ -0,0 +1,32 @@ +#ifndef DEV_ALLOC_CPP_I_IMPL_H +#define DEV_ALLOC_CPP_I_IMPL_H + +#include "dev_alloc_cpp_base.h" + +class dev_alloc_cpp_i : public dev_alloc_cpp_base +{ + ENABLE_LOGGING + public: + dev_alloc_cpp_i(char *devMgr_ior, char *id, char *lbl, char *sftwrPrfl); + dev_alloc_cpp_i(char *devMgr_ior, char *id, char *lbl, char *sftwrPrfl, char *compDev); + dev_alloc_cpp_i(char *devMgr_ior, char *id, char *lbl, char *sftwrPrfl, CF::Properties capacities); + dev_alloc_cpp_i(char *devMgr_ior, char *id, char *lbl, char *sftwrPrfl, CF::Properties capacities, char *compDev); + ~dev_alloc_cpp_i(); + + void constructor(); + + int serviceFunction(); + bool alloc_s_prop(const s_prop_struct &value); + void dealloc_s_prop(const s_prop_struct &value); + bool alloc_si_prop(const short &value); + void dealloc_si_prop(const short &value); + bool alloc_se_prop(const std::vector &value); + void dealloc_se_prop(const std::vector &value); + bool alloc_sq_prop(const std::vector &value); + void dealloc_sq_prop(const std::vector &value); + + protected: + void updateUsageState(); +}; + +#endif // DEV_ALLOC_CPP_I_IMPL_H diff --git a/redhawk/src/testing/sdr/dev/devices/dev_alloc_cpp/cpp/dev_alloc_cpp_base.cpp b/redhawk/src/testing/sdr/dev/devices/dev_alloc_cpp/cpp/dev_alloc_cpp_base.cpp new file mode 100644 index 000000000..ab0be95e4 --- /dev/null +++ b/redhawk/src/testing/sdr/dev/devices/dev_alloc_cpp/cpp/dev_alloc_cpp_base.cpp @@ -0,0 +1,134 @@ +#include "dev_alloc_cpp_base.h" + +/******************************************************************************************* + + AUTO-GENERATED CODE. DO NOT MODIFY + + The following class functions are for the base class for the device class. To + customize any of these functions, do not modify them here. Instead, overload them + on the child class + +******************************************************************************************/ + +dev_alloc_cpp_base::dev_alloc_cpp_base(char *devMgr_ior, char *id, char *lbl, char *sftwrPrfl) : + Device_impl(devMgr_ior, id, lbl, sftwrPrfl), + ThreadedComponent() +{ + construct(); +} + +dev_alloc_cpp_base::dev_alloc_cpp_base(char *devMgr_ior, char *id, char *lbl, char *sftwrPrfl, char *compDev) : + Device_impl(devMgr_ior, id, lbl, sftwrPrfl, compDev), + ThreadedComponent() +{ + construct(); +} + +dev_alloc_cpp_base::dev_alloc_cpp_base(char *devMgr_ior, char *id, char *lbl, char *sftwrPrfl, CF::Properties capacities) : + Device_impl(devMgr_ior, id, lbl, sftwrPrfl, capacities), + ThreadedComponent() +{ + construct(); +} + +dev_alloc_cpp_base::dev_alloc_cpp_base(char *devMgr_ior, char *id, char *lbl, char *sftwrPrfl, CF::Properties capacities, char *compDev) : + Device_impl(devMgr_ior, id, lbl, sftwrPrfl, capacities, compDev), + ThreadedComponent() +{ + construct(); +} + +dev_alloc_cpp_base::~dev_alloc_cpp_base() +{ +} + +void dev_alloc_cpp_base::construct() +{ + loadProperties(); + +} + +/******************************************************************************************* + Framework-level functions + These functions are generally called by the framework to perform housekeeping. +*******************************************************************************************/ +void dev_alloc_cpp_base::start() throw (CORBA::SystemException, CF::Resource::StartError) +{ + Device_impl::start(); + ThreadedComponent::startThread(); +} + +void dev_alloc_cpp_base::stop() throw (CORBA::SystemException, CF::Resource::StopError) +{ + Device_impl::stop(); + if (!ThreadedComponent::stopThread()) { + throw CF::Resource::StopError(CF::CF_NOTSET, "Processing thread did not die"); + } +} + +void dev_alloc_cpp_base::releaseObject() throw (CORBA::SystemException, CF::LifeCycle::ReleaseError) +{ + // This function clears the device running condition so main shuts down everything + try { + stop(); + } catch (CF::Resource::StopError& ex) { + // TODO - this should probably be logged instead of ignored + } + + Device_impl::releaseObject(); +} + +void dev_alloc_cpp_base::loadProperties() +{ + addProperty(device_kind, + "DCE:cdc5ee18-7ceb-4ae6-bf4c-31f983179b4d", + "device_kind", + "readonly", + "", + "eq", + "allocation"); + + addProperty(device_model, + "DCE:0f99b2e4-9903-4631-9846-ff349d18ecfb", + "device_model", + "readonly", + "", + "eq", + "allocation"); + + addProperty(si_prop, + "si_prop", + "", + "readwrite", + "", + "external", + "allocation"); + + addProperty(se_prop, + "se_prop", + "", + "readwrite", + "", + "external", + "allocation"); + + addProperty(s_prop, + s_prop_struct(), + "s_prop", + "", + "readwrite", + "", + "external", + "allocation"); + + addProperty(sq_prop, + "sq_prop", + "", + "readwrite", + "", + "external", + "allocation"); + +} + + diff --git a/redhawk/src/testing/sdr/dev/devices/dev_alloc_cpp/cpp/dev_alloc_cpp_base.h b/redhawk/src/testing/sdr/dev/devices/dev_alloc_cpp/cpp/dev_alloc_cpp_base.h new file mode 100644 index 000000000..a76c98d73 --- /dev/null +++ b/redhawk/src/testing/sdr/dev/devices/dev_alloc_cpp/cpp/dev_alloc_cpp_base.h @@ -0,0 +1,45 @@ +#ifndef DEV_ALLOC_CPP_BASE_IMPL_BASE_H +#define DEV_ALLOC_CPP_BASE_IMPL_BASE_H + +#include +#include +#include + +#include "struct_props.h" + +class dev_alloc_cpp_base : public Device_impl, protected ThreadedComponent +{ + public: + dev_alloc_cpp_base(char *devMgr_ior, char *id, char *lbl, char *sftwrPrfl); + dev_alloc_cpp_base(char *devMgr_ior, char *id, char *lbl, char *sftwrPrfl, char *compDev); + dev_alloc_cpp_base(char *devMgr_ior, char *id, char *lbl, char *sftwrPrfl, CF::Properties capacities); + dev_alloc_cpp_base(char *devMgr_ior, char *id, char *lbl, char *sftwrPrfl, CF::Properties capacities, char *compDev); + ~dev_alloc_cpp_base(); + + void start() throw (CF::Resource::StartError, CORBA::SystemException); + + void stop() throw (CF::Resource::StopError, CORBA::SystemException); + + void releaseObject() throw (CF::LifeCycle::ReleaseError, CORBA::SystemException); + + void loadProperties(); + + protected: + // Member variables exposed as properties + /// Property: device_kind + std::string device_kind; + /// Property: device_model + std::string device_model; + /// Property: si_prop + short si_prop; + /// Property: se_prop + std::vector se_prop; + /// Property: s_prop + s_prop_struct s_prop; + /// Property: sq_prop + std::vector sq_prop; + + private: + void construct(); +}; +#endif // DEV_ALLOC_CPP_BASE_IMPL_BASE_H diff --git a/redhawk/src/testing/sdr/dev/devices/dev_alloc_cpp/cpp/main.cpp b/redhawk/src/testing/sdr/dev/devices/dev_alloc_cpp/cpp/main.cpp new file mode 100644 index 000000000..90fb539db --- /dev/null +++ b/redhawk/src/testing/sdr/dev/devices/dev_alloc_cpp/cpp/main.cpp @@ -0,0 +1,26 @@ +#include +#include "ossie/ossieSupport.h" + +#include "dev_alloc_cpp.h" + +dev_alloc_cpp_i *devicePtr; + +void signal_catcher(int sig) +{ + // IMPORTANT Don't call exit(...) in this function + // issue all CORBA calls that you need for cleanup here before calling ORB shutdown + if (devicePtr) { + devicePtr->halt(); + } +} +int main(int argc, char* argv[]) +{ + struct sigaction sa; + sa.sa_handler = signal_catcher; + sa.sa_flags = 0; + devicePtr = 0; + + Device_impl::start_device(&devicePtr, sa, argc, argv); + return 0; +} + diff --git a/redhawk/src/testing/sdr/dev/devices/dev_alloc_cpp/cpp/struct_props.h b/redhawk/src/testing/sdr/dev/devices/dev_alloc_cpp/cpp/struct_props.h new file mode 100644 index 000000000..de7f03b20 --- /dev/null +++ b/redhawk/src/testing/sdr/dev/devices/dev_alloc_cpp/cpp/struct_props.h @@ -0,0 +1,124 @@ +#ifndef STRUCTPROPS_H +#define STRUCTPROPS_H + +/******************************************************************************************* + + AUTO-GENERATED CODE. DO NOT MODIFY + +*******************************************************************************************/ + +#include +#include +#include + +struct s_prop_struct { + s_prop_struct () + { + } + + static std::string getId() { + return std::string("s_prop"); + } + + static const char* getFormat() { + return "sh[d]"; + } + + std::string s_prop__a; + short s_prop__b; + std::vector abc; +}; + +inline bool operator>>= (const CORBA::Any& a, s_prop_struct& s) { + CF::Properties* temp; + if (!(a >>= temp)) return false; + const redhawk::PropertyMap& props = redhawk::PropertyMap::cast(*temp); + if (props.contains("s_prop::a")) { + if (!(props["s_prop::a"] >>= s.s_prop__a)) return false; + } + if (props.contains("s_prop::b")) { + if (!(props["s_prop::b"] >>= s.s_prop__b)) return false; + } + if (props.contains("abc")) { + if (!(props["abc"] >>= s.abc)) return false; + } + return true; +} + +inline void operator<<= (CORBA::Any& a, const s_prop_struct& s) { + redhawk::PropertyMap props; + + props["s_prop::a"] = s.s_prop__a; + + props["s_prop::b"] = s.s_prop__b; + + props["abc"] = s.abc; + a <<= props; +} + +inline bool operator== (const s_prop_struct& s1, const s_prop_struct& s2) { + if (s1.s_prop__a!=s2.s_prop__a) + return false; + if (s1.s_prop__b!=s2.s_prop__b) + return false; + if (s1.abc!=s2.abc) + return false; + return true; +} + +inline bool operator!= (const s_prop_struct& s1, const s_prop_struct& s2) { + return !(s1==s2); +} + +struct sq_prop_s_struct { + sq_prop_s_struct () + { + } + + static std::string getId() { + return std::string("sq_prop_s"); + } + + static const char* getFormat() { + return "fs"; + } + + float sq_prop__a; + std::string sq_prop__b; +}; + +inline bool operator>>= (const CORBA::Any& a, sq_prop_s_struct& s) { + CF::Properties* temp; + if (!(a >>= temp)) return false; + const redhawk::PropertyMap& props = redhawk::PropertyMap::cast(*temp); + if (props.contains("sq_prop::a")) { + if (!(props["sq_prop::a"] >>= s.sq_prop__a)) return false; + } + if (props.contains("sq_prop::b")) { + if (!(props["sq_prop::b"] >>= s.sq_prop__b)) return false; + } + return true; +} + +inline void operator<<= (CORBA::Any& a, const sq_prop_s_struct& s) { + redhawk::PropertyMap props; + + props["sq_prop::a"] = s.sq_prop__a; + + props["sq_prop::b"] = s.sq_prop__b; + a <<= props; +} + +inline bool operator== (const sq_prop_s_struct& s1, const sq_prop_s_struct& s2) { + if (s1.sq_prop__a!=s2.sq_prop__a) + return false; + if (s1.sq_prop__b!=s2.sq_prop__b) + return false; + return true; +} + +inline bool operator!= (const sq_prop_s_struct& s1, const sq_prop_s_struct& s2) { + return !(s1==s2); +} + +#endif // STRUCTPROPS_H diff --git a/redhawk/src/testing/sdr/dev/devices/dev_alloc_cpp/dev_alloc_cpp.prf.xml b/redhawk/src/testing/sdr/dev/devices/dev_alloc_cpp/dev_alloc_cpp.prf.xml new file mode 100644 index 000000000..7d592111a --- /dev/null +++ b/redhawk/src/testing/sdr/dev/devices/dev_alloc_cpp/dev_alloc_cpp.prf.xml @@ -0,0 +1,35 @@ + + + + + This specifies the device kind + + + + + This specifies the specific device + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/redhawk/src/testing/sdr/dev/devices/dev_alloc_cpp/dev_alloc_cpp.scd.xml b/redhawk/src/testing/sdr/dev/devices/dev_alloc_cpp/dev_alloc_cpp.scd.xml new file mode 100644 index 000000000..125128ef1 --- /dev/null +++ b/redhawk/src/testing/sdr/dev/devices/dev_alloc_cpp/dev_alloc_cpp.scd.xml @@ -0,0 +1,49 @@ + + + + 2.2 + + device + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/redhawk/src/testing/sdr/dev/devices/dev_alloc_cpp/dev_alloc_cpp.spd.xml b/redhawk/src/testing/sdr/dev/devices/dev_alloc_cpp/dev_alloc_cpp.spd.xml new file mode 100644 index 000000000..9819b3354 --- /dev/null +++ b/redhawk/src/testing/sdr/dev/devices/dev_alloc_cpp/dev_alloc_cpp.spd.xml @@ -0,0 +1,27 @@ + + + + + + null + + + + + + + + + The implementation contains descriptive information about the template for a software resource. + + + cpp/dev_alloc_cpp + + + + + + + + + diff --git a/redhawk/src/testing/sdr/dev/nodes/dev_alloc_node/DeviceManager.dcd.xml b/redhawk/src/testing/sdr/dev/nodes/dev_alloc_node/DeviceManager.dcd.xml new file mode 100644 index 000000000..ed242e778 --- /dev/null +++ b/redhawk/src/testing/sdr/dev/nodes/dev_alloc_node/DeviceManager.dcd.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + dev_alloc_cpp_1 + + + + + + + diff --git a/redhawk/src/testing/tests/test_13_RedhawkModule.py b/redhawk/src/testing/tests/test_13_RedhawkModule.py index e4b2ea3e8..b6a47ae7e 100644 --- a/redhawk/src/testing/tests/test_13_RedhawkModule.py +++ b/redhawk/src/testing/tests/test_13_RedhawkModule.py @@ -29,6 +29,7 @@ from ossie.utils import redhawk from ossie.utils import type_helpers from ossie.utils import rhconnection +from ossie.utils import allocations from ossie.events import Subscriber, Publisher from ossie.cf import CF @@ -806,3 +807,77 @@ def test_connectionMgrComp(self): cMgr.connect(ep1,ep2) self.assertEquals(len(_port._get_connections()), 1) + +class RedhawkModuleAllocationMgrTest(scatest.CorbaTestCase): + def setUp(self): + domBooter, self._domMgr = self.launchDomainManager() + devBooter, self._devMgr = self.launchDeviceManager("/nodes/dev_alloc_node/DeviceManager.dcd.xml") + self._rhDom = redhawk.attach(scatest.getTestDomainName()) + self.am=self._rhDom._get_allocationMgr() + self.assertEquals(len(self._rhDom._get_applications()), 0) + + def tearDown(self): + # Do all application shutdown before calling the base class tearDown, + # or failures will probably occur. + redhawk.core._cleanUpLaunchedApps() + scatest.CorbaTestCase.tearDown(self) + # need to let event service clean up event channels...... + # cycle period is 10 milliseconds + time.sleep(0.1) + redhawk.setTrackApps(False) + + def test_allocMgrSimple(self): + """ + Tests that applications can make connections between their external ports + """ + prop = allocations.createProps({'si_prop':3}) + rq=self.am.createRequest('foo',prop) + resp = self.am.allocate([rq]) + self.assertEquals(len(resp),1) + self.assertEquals(self.am.listAllocations(CF.AllocationManager.LOCAL_ALLOCATIONS, 100)[0][0].allocationID, resp[0].allocationID) + self.am.deallocate([resp[0].allocationID]) + + def test_allocMgrSimSeq(self): + """ + Tests that applications can make connections between their external ports + """ + prop = allocations.createProps({'se_prop':[1.0,2.0]}) + rq=self.am.createRequest('foo',prop) + resp = self.am.allocate([rq]) + self.assertEquals(len(resp),0) + prop = allocations.createProps({'se_prop':[1.0,2.0]}, prf='sdr/dev/devices/dev_alloc_cpp/dev_alloc_cpp.prf.xml') + rq=self.am.createRequest('foo',prop) + resp = self.am.allocate([rq]) + self.assertEquals(len(resp),1) + self.assertEquals(self.am.listAllocations(CF.AllocationManager.LOCAL_ALLOCATIONS, 100)[0][0].allocationID, resp[0].allocationID) + self.am.deallocate([resp[0].allocationID]) + + def test_allocMgrStruct(self): + """ + Tests that applications can make connections between their external ports + """ + prop = allocations.createProps({'s_prop':{'s_prop::a':'hello','s_prop::b':5}}) + rq=self.am.createRequest('foo',prop) + resp = self.am.allocate([rq]) + self.assertEquals(len(resp),0) + prop = allocations.createProps({'s_prop':{'s_prop::a':'hello','s_prop::b':5}}, prf='sdr/dev/devices/dev_alloc_cpp/dev_alloc_cpp.prf.xml') + rq=self.am.createRequest('foo',prop) + resp = self.am.allocate([rq]) + self.assertEquals(len(resp),1) + self.assertEquals(self.am.listAllocations(CF.AllocationManager.LOCAL_ALLOCATIONS, 100)[0][0].allocationID, resp[0].allocationID) + self.am.deallocate([resp[0].allocationID]) + + def test_allocMgrStrSeq(self): + """ + Tests that applications can make connections between their external ports + """ + prop = allocations.createProps({'sq_prop':[{'sq_prop::b':'hello','sq_prop::a':5},{'sq_prop::b':'another','sq_prop::a':7}]}) + rq=self.am.createRequest('foo',prop) + resp = self.am.allocate([rq]) + self.assertEquals(len(resp),0) + prop = allocations.createProps({'sq_prop':[{'sq_prop::b':'hello','sq_prop::a':5},{'sq_prop::b':'another','sq_prop::a':7}]}, prf='sdr/dev/devices/dev_alloc_cpp/dev_alloc_cpp.prf.xml') + rq=self.am.createRequest('foo',prop) + resp = self.am.allocate([rq]) + self.assertEquals(len(resp),1) + self.assertEquals(self.am.listAllocations(CF.AllocationManager.LOCAL_ALLOCATIONS, 100)[0][0].allocationID, resp[0].allocationID) + self.am.deallocate([resp[0].allocationID]) From e74b053cb844801f64d818ec4f235dd27161b7ff Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 13 Feb 2017 12:40:25 -0500 Subject: [PATCH 0687/1644] CF-1438 Unit tests for BulkIO memory sharing API --- .../libsrc/testing/tests/cpp/LocalTest.cpp | 173 ++++++++++++++++++ .../libsrc/testing/tests/cpp/LocalTest.h | 56 ++++++ .../libsrc/testing/tests/cpp/Makefile.am | 1 + 3 files changed, 230 insertions(+) create mode 100644 bulkioInterfaces/libsrc/testing/tests/cpp/LocalTest.cpp create mode 100644 bulkioInterfaces/libsrc/testing/tests/cpp/LocalTest.h diff --git a/bulkioInterfaces/libsrc/testing/tests/cpp/LocalTest.cpp b/bulkioInterfaces/libsrc/testing/tests/cpp/LocalTest.cpp new file mode 100644 index 000000000..93b0524a5 --- /dev/null +++ b/bulkioInterfaces/libsrc/testing/tests/cpp/LocalTest.cpp @@ -0,0 +1,173 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK bulkioInterfaces. + * + * REDHAWK bulkioInterfaces is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK bulkioInterfaces is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +#include "LocalTest.h" +#include + +namespace { + template + bool overlaps(const redhawk::shared_buffer& lhs, const redhawk::shared_buffer& rhs) + { + const T* end; + const T* ptr; + if (lhs.data() < rhs.data()) { + end = lhs.data() + lhs.size(); + ptr = rhs.data(); + } else { + end = rhs.data() + rhs.size(); + ptr = lhs.data(); + } + return (ptr < end); + } +} + +template +void LocalTest::setUp() +{ + std::string name = getPortName(); + outPort = new OutPort("data" + name + "_out"); + inPort = new InPort("data" + name + "_in"); + + PortableServer::ObjectId_var oid = ossie::corba::RootPOA()->activate_object(inPort); + + CORBA::Object_var objref = inPort->_this(); + outPort->connectPort(objref, "local_connection"); +} + +template +void LocalTest::tearDown() +{ + outPort->disconnectPort("local_connection"); + + try { + PortableServer::ObjectId_var oid = ossie::corba::RootPOA()->servant_to_id(inPort); + ossie::corba::RootPOA()->deactivate_object(oid); + } catch (...) { + // Ignore CORBA exceptions + } + inPort->_remove_ref(); + + delete outPort; +} + +template +void LocalTest::testBasicWrite() +{ + // Create an output stream and write a buffer to it + OutStreamType out_stream = outPort->createStream("test_stream"); + redhawk::buffer data(1024); + out_stream.write(data, bulkio::time::utils::now()); + + // The corresponding input stream should exist and have data + InStreamType in_stream = inPort->getStream("test_stream"); + CPPUNIT_ASSERT(in_stream); + DataBlockType block = in_stream.tryread(); + CPPUNIT_ASSERT(block); + + // Check that the input stream is sharing the underlying memory + redhawk::shared_buffer result = block.buffer(); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Input stream received a copy of data", (const ScalarType*) data.data(), result.data()); + CPPUNIT_ASSERT_EQUAL(data.size(), result.size()); +} + +template +void LocalTest::testLargeWrite() +{ + // Create an output stream and write a buffer that is too large for a + // single CORBA transfer + OutStreamType out_stream = outPort->createStream("test_stream"); + size_t count = (2 * bulkio::Const::MaxTransferBytes()) / sizeof(ScalarType); + redhawk::buffer data(count); + out_stream.write(data, bulkio::time::utils::now()); + + // The corresponding input stream should exist and have data + InStreamType in_stream = inPort->getStream("test_stream"); + CPPUNIT_ASSERT(in_stream); + DataBlockType block = in_stream.tryread(); + CPPUNIT_ASSERT(block); + + // Make sure that the original buffer was preserved as a single transfer + redhawk::shared_buffer result = block.buffer(); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Input stream received a copy of data", (const ScalarType*) data.data(), result.data()); + CPPUNIT_ASSERT_EQUAL(data.size(), result.size()); +} + +template +void LocalTest::testReadSlice() +{ + // Create an output stream and write a buffer to it + OutStreamType out_stream = outPort->createStream("test_stream"); + redhawk::buffer data(1024); + out_stream.write(data, bulkio::time::utils::now()); + const ScalarType* start_pointer = data.data(); + + // The corresponding input stream should exist and have data + const size_t READ_SIZE = 500; + InStreamType in_stream = inPort->getStream("test_stream"); + CPPUNIT_ASSERT(in_stream); + DataBlockType block = in_stream.tryread(READ_SIZE); + CPPUNIT_ASSERT(block); + + // Check that the read buffer is a subset of the original buffer + redhawk::shared_buffer result = block.buffer(); + CPPUNIT_ASSERT_EQUAL(READ_SIZE, result.size()); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Input stream received a copy of data", start_pointer, result.data()); + + // The next read buffer should point to an offset into the original buffer + block = in_stream.tryread(READ_SIZE); + CPPUNIT_ASSERT(block); + result = block.buffer(); + CPPUNIT_ASSERT_EQUAL(READ_SIZE, result.size()); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Input stream received a copy of data", start_pointer + READ_SIZE, result.data()); + + // Write a new buffer (copy allocates a new memory block) + redhawk::shared_buffer data2 = data.copy(); + out_stream.write(data2, bulkio::time::utils::now()); + + // Read a buffer that we know spans two input buffers; it should still be + // able to read the full amount, but it'll have to make a copy + block = in_stream.tryread(READ_SIZE); + CPPUNIT_ASSERT(block); + result = block.buffer(); + CPPUNIT_ASSERT_EQUAL(READ_SIZE, result.size()); + CPPUNIT_ASSERT(!overlaps(data, result)); + CPPUNIT_ASSERT(!overlaps(data2, result)); +} + +#define CREATE_TEST(x) \ + class Local##x##Test : public LocalTest \ + { \ + typedef LocalTest TestBase; \ + CPPUNIT_TEST_SUB_SUITE(Local##x##Test, TestBase); \ + CPPUNIT_TEST_SUITE_END(); \ + virtual std::string getPortName() const { return #x; }; \ + }; \ + CPPUNIT_TEST_SUITE_REGISTRATION(Local##x##Test); + +CREATE_TEST(Octet); +CREATE_TEST(Char); +CREATE_TEST(Short); +CREATE_TEST(UShort); +CREATE_TEST(Long); +CREATE_TEST(ULong); +CREATE_TEST(LongLong); +CREATE_TEST(ULongLong); +CREATE_TEST(Float); +CREATE_TEST(Double); diff --git a/bulkioInterfaces/libsrc/testing/tests/cpp/LocalTest.h b/bulkioInterfaces/libsrc/testing/tests/cpp/LocalTest.h new file mode 100644 index 000000000..62e5ec383 --- /dev/null +++ b/bulkioInterfaces/libsrc/testing/tests/cpp/LocalTest.h @@ -0,0 +1,56 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK bulkioInterfaces. + * + * REDHAWK bulkioInterfaces is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK bulkioInterfaces is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ +#ifndef BULKIO_LOCALTEST_H +#define BULKIO_LOCALTEST_H + +#include +#include + +template +class LocalTest : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE(LocalTest); + CPPUNIT_TEST(testBasicWrite); + CPPUNIT_TEST(testLargeWrite); + CPPUNIT_TEST(testReadSlice); + CPPUNIT_TEST_SUITE_END(); + +public: + void setUp(); + void tearDown(); + + void testBasicWrite(); + void testLargeWrite(); + + void testReadSlice(); + +protected: + typedef typename OutPort::StreamType OutStreamType; + typedef typename InPort::StreamType InStreamType; + typedef typename OutStreamType::ScalarType ScalarType; + typedef typename InStreamType::DataBlockType DataBlockType; + + virtual std::string getPortName() const = 0; + + OutPort* outPort; + InPort* inPort; +}; + +#endif // BULKIO_LOCALTEST_H diff --git a/bulkioInterfaces/libsrc/testing/tests/cpp/Makefile.am b/bulkioInterfaces/libsrc/testing/tests/cpp/Makefile.am index 93ffb26a3..ea32f1ab9 100644 --- a/bulkioInterfaces/libsrc/testing/tests/cpp/Makefile.am +++ b/bulkioInterfaces/libsrc/testing/tests/cpp/Makefile.am @@ -24,5 +24,6 @@ check_PROGRAMS = $(TESTS) Bulkio_SOURCES = Bulkio.cpp Bulkio_Helper_Fixture.cpp Bulkio_InPort_Fixture.cpp Bulkio_OutPort_Fixture.cpp Bulkio_MultiOut_Port.cpp Bulkio_SOURCES += InStreamTest.h InStreamTest.cpp Bulkio_SOURCES += OutStreamTest.h OutStreamTest.cpp +Bulkio_SOURCES += LocalTest.h LocalTest.cpp Bulkio_CXXFLAGS = $(BULKIO_CFLAGS) $(BOOST_CPPFLAGS) $(OSSIE_CFLAGS) $(CPPUNIT_CFLAGS) Bulkio_LDADD = $(BULKIO_LIBS) $(BOOST_LDFLAGS) $(BOOST_SYSTEM_LIB) $(OSSIE_LIBS) $(CPPUNIT_LIBS) $(LOG4CXX_LIBS) From eadf392a5774a72e2aee175e3395a30dec85967d Mon Sep 17 00:00:00 2001 From: Max Robert Date: Mon, 13 Feb 2017 12:59:10 -0500 Subject: [PATCH 0688/1644] Fixed failing tests --- redhawk/src/base/framework/python/ossie/events/Subscriber.py | 5 ++--- .../src/testing/sdr/dom/components/ECM_PY/python/ECM_PY.py | 5 +++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/redhawk/src/base/framework/python/ossie/events/Subscriber.py b/redhawk/src/base/framework/python/ossie/events/Subscriber.py index 131f58b20..11defdb40 100644 --- a/redhawk/src/base/framework/python/ossie/events/Subscriber.py +++ b/redhawk/src/base/framework/python/ossie/events/Subscriber.py @@ -86,13 +86,12 @@ def __init__(self,parent): Receiver.__init__(self) def push(self, data): - _data = any.from_any(data) if self.parent.dataArrivedCB != None: self.parent.logger.trace('Received (callback) DATA: ' + str(data)) - self.parent.dataArrivedCB(_data) + self.parent.dataArrivedCB(data) else: self.parent.logger.trace('Received (queue) DATA: ' + str(data)) - self.parent.events.put(_data) + self.parent.events.put(data) class Subscriber: diff --git a/redhawk/src/testing/sdr/dom/components/ECM_PY/python/ECM_PY.py b/redhawk/src/testing/sdr/dom/components/ECM_PY/python/ECM_PY.py index 77e0db9a9..3c64093c9 100755 --- a/redhawk/src/testing/sdr/dom/components/ECM_PY/python/ECM_PY.py +++ b/redhawk/src/testing/sdr/dom/components/ECM_PY/python/ECM_PY.py @@ -162,8 +162,9 @@ def mycallback(self, id, old_value, new_value): time.sleep(.10) if self.msg_limit > self.msg_recv: msgin=0; - msgin = self.sub.getData() - if msgin != None: + inany = self.sub.getData() + if inany != None: + msgin = any.from_any(inany) self._log.info("Received MSG msgid =" +str(msgin)) if msgin == self.p_msgid : self.msg_recv = self.msg_recv + 1 From 84933e588bc9ca72c79095f60064a13a477c68c2 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 13 Feb 2017 14:18:32 -0500 Subject: [PATCH 0689/1644] CF-1671 Fix a problem with locating the generated headers and consolidate path variables --- bulkioInterfaces/configure.ac | 9 ++++----- bulkioInterfaces/libsrc/Makefile.am | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/bulkioInterfaces/configure.ac b/bulkioInterfaces/configure.ac index d63410e3e..203d8579a 100644 --- a/bulkioInterfaces/configure.ac +++ b/bulkioInterfaces/configure.ac @@ -63,9 +63,8 @@ if test "$enable_base_classes" != "no"; then OSSIE_ENABLE_LOG4CXX CHECK_VECTOR_IMPL - AC_SUBST(BULKIO_INF_INCLUDES, "-I../src/cpp -I../src/cpp/ossie") - AC_SUBST(BULKIO_INF_CFLAGS, ) - AC_SUBST(BULKIO_INF_LIBS, ) + AC_SUBST(BULKIOINTERFACES_CFLAGS, "-I \$(top_srcdir)/src/cpp -I \$(top_srcdir)/src/cpp/ossie") + AC_SUBST(BULKIOINTERFACES_LIBS, "-L\$(top_srcdir) -lbulkioInterfaces") fi # Optionally include java support @@ -145,8 +144,8 @@ AM_PATH_CPPUNIT(1.12.1) # the top-level include directory ("bulkio/bulkio.h") and the bulkio # directory inside of include ("bulkio.h"). bulkio_includedir="\$(top_srcdir)/libsrc/cpp/include" -AC_SUBST(BULKIO_CFLAGS, "-I \$(top_srcdir)/src/cpp -I ${bulkio_includedir} -I ${bulkio_includedir}/bulkio") -AC_SUBST(BULKIO_LIBS, "-L\$(top_srcdir)/libsrc -lbulkio-${BULKIO_API_VERSION} -L\$(top_srcdir) -lbulkioInterfaces") +AC_SUBST(BULKIO_CFLAGS, "-I ${bulkio_includedir} -I ${bulkio_includedir}/bulkio ${BULKIOINTERFACES_CFLAGS}") +AC_SUBST(BULKIO_LIBS, "-L\$(top_srcdir)/libsrc -lbulkio-${BULKIO_API_VERSION} ${BULKIOINTERFACES_LIBS}") AC_CONFIG_FILES([bulkioInterfaces.pc setup.py Makefile jni/Makefile]) if test "$enable_base_classes" != "no"; then diff --git a/bulkioInterfaces/libsrc/Makefile.am b/bulkioInterfaces/libsrc/Makefile.am index 080dc77eb..8aa399d98 100644 --- a/bulkioInterfaces/libsrc/Makefile.am +++ b/bulkioInterfaces/libsrc/Makefile.am @@ -82,7 +82,7 @@ library_include_HEADERS = cpp/include/bulkio/bulkio.h \ ## shipped with the source tarball. #bulkio_libincludedir = $(libdir)/bulkio-$(BULKIO_API_VERSION)/include -libbulkio_@BULKIO_API_VERSION@_la_CXXFLAGS = -Wall -I $(srcdir)/cpp -I $(srcdir)/cpp/include/bulkio -DLOGGING $(BULKIO_INF_INCLUDES) $(BOOST_CPPFLAGS) $(OMNIORB_CFLAGS) $(OSSIE_CFLAGS) +libbulkio_@BULKIO_API_VERSION@_la_CXXFLAGS = -Wall -I $(srcdir)/cpp -I $(srcdir)/cpp/include/bulkio -DLOGGING $(BULKIOINTERFACES_CFLAGS) $(BOOST_CPPFLAGS) $(OMNIORB_CFLAGS) $(OSSIE_CFLAGS) ############################################################################### # Python From c18236197b7b099dea78d11b42be0f22704f5f68 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 13 Feb 2017 15:03:56 -0500 Subject: [PATCH 0690/1644] CF-884 Test component should be an Executable, not a SharedLibrary --- .../sdr/dom/components/check_cwd_cpp/check_cwd_cpp.spd.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GPP/tests/sdr/dom/components/check_cwd_cpp/check_cwd_cpp.spd.xml b/GPP/tests/sdr/dom/components/check_cwd_cpp/check_cwd_cpp.spd.xml index d33ba93d1..abbdb7733 100644 --- a/GPP/tests/sdr/dom/components/check_cwd_cpp/check_cwd_cpp.spd.xml +++ b/GPP/tests/sdr/dom/components/check_cwd_cpp/check_cwd_cpp.spd.xml @@ -13,7 +13,7 @@ The implementation contains descriptive information about the template for a software resource. - + cpp/check_cwd_cpp From 522b806d0581c1e01199e983e2c817dbc7cdae21 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 13 Feb 2017 16:48:45 -0500 Subject: [PATCH 0691/1644] Fix indentation --- burstioInterfaces/src/cpp/include/burstio/InPortDecl.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/burstioInterfaces/src/cpp/include/burstio/InPortDecl.h b/burstioInterfaces/src/cpp/include/burstio/InPortDecl.h index d6b7bc01b..5cb593917 100644 --- a/burstioInterfaces/src/cpp/include/burstio/InPortDecl.h +++ b/burstioInterfaces/src/cpp/include/burstio/InPortDecl.h @@ -42,7 +42,7 @@ namespace burstio { ENABLE_INSTANCE_LOGGING; public: - typedef typename Traits::PortType PortType; + typedef typename Traits::PortType PortType; typedef typename Traits::BurstType BurstType; typedef typename Traits::BurstSequenceType BurstSequenceType; typedef typename Traits::ElementType ElementType; @@ -124,7 +124,7 @@ namespace burstio { // Support function for automatic component-managed stop. virtual void stopPort (); - std::string getRepid() const; + std::string getRepid() const; protected: // Wait timeout seconds for a burst to become available; the caller From 0a91b80170bdbc29d78fb65e5ddbdab8060f9049 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 14 Feb 2017 10:42:16 -0500 Subject: [PATCH 0692/1644] CF-1527 C++ unit tests for BurstIO local transport Added a little extra tracing to diagnose a problem that turned out to be a mistake in the test --- burstioInterfaces/src/cpp/lib/OutPortImpl.h | 6 +- .../testing/tests/cpp/LocalTest.cpp | 214 ++++++++++++++++++ .../testing/tests/cpp/LocalTest.h | 64 ++++++ .../testing/tests/cpp/Makefile.am | 1 + 4 files changed, 283 insertions(+), 2 deletions(-) create mode 100644 burstioInterfaces/testing/tests/cpp/LocalTest.cpp create mode 100644 burstioInterfaces/testing/tests/cpp/LocalTest.h diff --git a/burstioInterfaces/src/cpp/lib/OutPortImpl.h b/burstioInterfaces/src/cpp/lib/OutPortImpl.h index e7d027a01..1b69a6064 100644 --- a/burstioInterfaces/src/cpp/lib/OutPortImpl.h +++ b/burstioInterfaces/src/cpp/lib/OutPortImpl.h @@ -524,11 +524,13 @@ namespace burstio { boost::mutex::scoped_lock lock(updatingPortsLock); for (TransportIterator ii = _transports.begin(); ii != _transports.end(); ++ii) { TransportType* connection = *ii; - - if (!isStreamRoutedToConnection(streamID, connection->connectionId())) { + const std::string& connection_id = connection->connectionId(); + if (!isStreamRoutedToConnection(streamID, connection_id)) { + RH_TRACE(logger, "Stream " << streamID << " is not routed to connection " << connection_id); continue; } + RH_TRACE(logger, "Pushing " << const_bursts.length() << " bursts to connection " << connection_id); connection->pushBursts(const_bursts, startTime, queueDepth); } } diff --git a/burstioInterfaces/testing/tests/cpp/LocalTest.cpp b/burstioInterfaces/testing/tests/cpp/LocalTest.cpp new file mode 100644 index 000000000..62176d85e --- /dev/null +++ b/burstioInterfaces/testing/tests/cpp/LocalTest.cpp @@ -0,0 +1,214 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK burstioInterfaces. + * + * REDHAWK burstioInterfaces is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK burstioInterfaces is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +#include "LocalTest.h" + +#include +#include + +template +void LocalTest::setUp() +{ + rootLogger = rh_logger::Logger::getLogger("Local"+getPortName()+"Test"); + + std::string name = "burst" + getPortName(); + outPort = new OutPort(name + "_out"); + outPort->setLogger(rh_logger::Logger::getLogger(rootLogger->getName() + "." + outPort->getName())); + inPort = new InPort(name + "_in"); + inPort->setLogger(rh_logger::Logger::getLogger(rootLogger->getName() + "." + inPort->getName())); + + _activatePort(inPort); + + CORBA::Object_var objref = inPort->_this(); + outPort->connectPort(objref, "local_connection"); + + inPort->start(); + outPort->start(); +} + +template +void LocalTest::tearDown() +{ + inPort->stop(); + outPort->stop(); + + ExtendedCF::UsesConnectionSequence_var connections = outPort->connections(); + for (CORBA::ULong index = 0; index < connections->length(); ++index) { + outPort->disconnectPort(connections[index].connectionId); + } + + for (typename std::vector::iterator servant = servants.begin(); servant != servants.end(); ++servant) { + _deactivatePort(*servant); + (*servant)->_remove_ref(); + } + + delete outPort; +} + +template +void LocalTest::_activatePort(InPort* port) +{ + PortableServer::ObjectId_var oid = ossie::corba::RootPOA()->activate_object(port); + servants.push_back(port); +} + +template +void LocalTest::_deactivatePort(InPort* port) +{ + try { + PortableServer::ObjectId_var oid = ossie::corba::RootPOA()->servant_to_id(port); + ossie::corba::RootPOA()->deactivate_object(oid); + } catch (...) { + // Ignore CORBA exceptions + } +} + +template +void LocalTest::testPushBurst() +{ + // Queue up a bunch of bursts + const size_t BURST_COUNT = 16; + for (size_t ii = 0; ii < BURST_COUNT; ++ii) { + BurstType burst; + burst.SRI = burstio::utils::createSRI("test_stream"); + burst.data.length(50); + std::fill(burst.data.get_buffer(), burst.data.get_buffer() + burst.data.length(), ii); + burst.T = burstio::utils::now(); + burst.EOS = false; + outPort->pushBurst(burst); + } + + // Force the output port to send the bursts + outPort->flush(); + + // Read the bursts one at a time and check that they look reasonable + for (size_t ii = 0; ii < BURST_COUNT; ++ii) { + boost::scoped_ptr burst(inPort->getBurst(0.0)); + CPPUNIT_ASSERT(burst); + CPPUNIT_ASSERT_EQUAL(std::string("test_stream"), burst->getStreamID()); + CPPUNIT_ASSERT_EQUAL((size_t) 50, burst->getSize()); + CPPUNIT_ASSERT(*(burst->getData()) == ii); + } +} + +template +void LocalTest::testPushBursts() +{ + // Build up a sequence of bursts + BurstSequenceType bursts; + for (size_t ii = 0; ii < 24; ++ii) { + BurstType burst; + burst.SRI = burstio::utils::createSRI("test_stream"); + burst.data.length(100); + std::fill(burst.data.get_buffer(), burst.data.get_buffer() + burst.data.length(), ii); + burst.T = burstio::utils::now(); + burst.EOS = false; + ossie::corba::push_back(bursts, burst); + } + + // Push the entire sequence (skips buffering) and make sure the other port + // didn't steal the bursts + outPort->pushBursts(bursts); + CPPUNIT_ASSERT_EQUAL((CORBA::ULong) 24, bursts.length()); + + // Read the bursts (in bulk) and check them against the originals + BurstSequenceVar results = inPort->getBursts(0.0); + CPPUNIT_ASSERT_EQUAL(bursts.length(), results->length()); + for (CORBA::ULong ii = 0; ii < results->length(); ++ii) { + CPPUNIT_ASSERT_EQUAL(std::string("test_stream"), std::string(results[ii].SRI.streamID)); + CPPUNIT_ASSERT_EQUAL((CORBA::ULong) 100, results[ii].data.length()); + CPPUNIT_ASSERT(bursts[ii].data[0] == ii); + CPPUNIT_ASSERT_EQUAL(bursts[ii].T, results[ii].T); + CPPUNIT_ASSERT(!results[ii].EOS); + } +} + +template +void LocalTest::testFanOut() +{ + // Create a second input port to check 1:2 fan out + InPort* inPort2 = new InPort("burst" + getPortName() + "_in_2"); + inPort2->setLogger(rh_logger::Logger::getLogger(rootLogger->getName() + "." + inPort2->getName())); + _activatePort(inPort2); + inPort2->start(); + + CORBA::Object_var objref = inPort2->_this(); + outPort->connectPort(objref, "local_connection_2"); + + // Build up a sequence of bursts + BurstSequenceType bursts; + for (size_t ii = 0; ii < 24; ++ii) { + BurstType burst; + burst.SRI = burstio::utils::createSRI("test_stream"); + burst.data.length(100); + std::fill(burst.data.get_buffer(), burst.data.get_buffer() + burst.data.length(), ii); + burst.T = burstio::utils::now(); + burst.EOS = false; + ossie::corba::push_back(bursts, burst); + } + + // Push the entire sequence (skips buffering) and make sure the other ports + // didn't steal the bursts + outPort->pushBursts(bursts); + CPPUNIT_ASSERT_EQUAL((CORBA::ULong) 24, bursts.length()); + + // Read the bursts (in bulk) and check them against the originals + BurstSequenceVar results = inPort->getBursts(0.0); + CPPUNIT_ASSERT_EQUAL(bursts.length(), results->length()); + for (CORBA::ULong ii = 0; ii < results->length(); ++ii) { + CPPUNIT_ASSERT_EQUAL(std::string("test_stream"), std::string(results[ii].SRI.streamID)); + CPPUNIT_ASSERT_EQUAL((CORBA::ULong) 100, results[ii].data.length()); + CPPUNIT_ASSERT(bursts[ii].data[0] == ii); + CPPUNIT_ASSERT_EQUAL(bursts[ii].T, results[ii].T); + CPPUNIT_ASSERT(!results[ii].EOS); + } + + // Repeat with the second port; the results should be the same + BurstSequenceVar results2 = inPort2->getBursts(0.0); + CPPUNIT_ASSERT_EQUAL(bursts.length(), results2->length()); + for (CORBA::ULong ii = 0; ii < results2->length(); ++ii) { + CPPUNIT_ASSERT_EQUAL(std::string("test_stream"), std::string(results2[ii].SRI.streamID)); + CPPUNIT_ASSERT_EQUAL((CORBA::ULong) 100, results2[ii].data.length()); + CPPUNIT_ASSERT(bursts[ii].data[0] == ii); + CPPUNIT_ASSERT_EQUAL(bursts[ii].T, results2[ii].T); + CPPUNIT_ASSERT(!results2[ii].EOS); + } +} + +#define CREATE_TEST(x) \ + class Local##x##Test : public LocalTest \ + { \ + typedef LocalTest TestBase; \ + CPPUNIT_TEST_SUB_SUITE(Local##x##Test, TestBase); \ + CPPUNIT_TEST_SUITE_END(); \ + virtual std::string getPortName() const { return #x; }; \ + }; \ + CPPUNIT_TEST_SUITE_REGISTRATION(Local##x##Test); + +CREATE_TEST(Byte); +CREATE_TEST(Ubyte); +CREATE_TEST(Short); +CREATE_TEST(Ushort); +CREATE_TEST(Long); +CREATE_TEST(Ulong); +CREATE_TEST(LongLong); +CREATE_TEST(UlongLong); +CREATE_TEST(Float); +CREATE_TEST(Double); diff --git a/burstioInterfaces/testing/tests/cpp/LocalTest.h b/burstioInterfaces/testing/tests/cpp/LocalTest.h new file mode 100644 index 000000000..adca8d2d1 --- /dev/null +++ b/burstioInterfaces/testing/tests/cpp/LocalTest.h @@ -0,0 +1,64 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK burstioInterfaces. + * + * REDHAWK burstioInterfaces is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK burstioInterfaces is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ +#ifndef BURSTIO_LOCALTEST_H +#define BURSTIO_LOCALTEST_H + +#include + +#include +#include + +template +class LocalTest : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE(LocalTest); + CPPUNIT_TEST(testPushBurst); + CPPUNIT_TEST(testPushBursts); + CPPUNIT_TEST(testFanOut); + CPPUNIT_TEST_SUITE_END(); + +public: + void setUp(); + void tearDown(); + + void testPushBurst(); + void testPushBursts(); + void testFanOut(); + +protected: + typedef typename OutPort::BurstType BurstType; + typedef typename OutPort::BurstSequenceType BurstSequenceType; + typedef typename InPort::PacketType PacketType; + typedef typename InPort::BurstSequenceVar BurstSequenceVar; + + virtual std::string getPortName() const = 0; + + OutPort* outPort; + InPort* inPort; + + void _activatePort(InPort* port); + void _deactivatePort(InPort* port); + + std::vector servants; + + rh_logger::LoggerPtr rootLogger; +}; + +#endif // BURSTIO_LOCALTEST_H diff --git a/burstioInterfaces/testing/tests/cpp/Makefile.am b/burstioInterfaces/testing/tests/cpp/Makefile.am index dddcd4420..2dd7e155f 100644 --- a/burstioInterfaces/testing/tests/cpp/Makefile.am +++ b/burstioInterfaces/testing/tests/cpp/Makefile.am @@ -20,6 +20,7 @@ burstio_include=$(top_srcdir)/src/cpp/include Burstio_SOURCES = Burstio.cpp Burstio_InPort.cpp Burstio_OutPort.cpp Burstio_PushTest.cpp Burstio_Utils_Test.cpp +Burstio_SOURCES += LocalTest.h LocalTest.cpp Burstio_INCLUDES = -I$(burstio_include) -I$(burstio_include)/burstio -I$(top_builddir)/src/cpp -I$(top_builddir)/src/cpp/redhawk Burstio_CXXFLAGS = $(CPPUNIT_CFLAGS) $(Burstio_INCLUDES) $(BOOST_CPPFLAGS) $(BULKIO_CFLAGS) Burstio_LDADD = $(BULKIO_LIBS) $(BOOST_LDFLAGS) $(BOOST_SYSTEM_LIB) $(CPPUNIT_LIBS) -llog4cxx -ldl From bec4c4053a0b0b7c8861e739e04092e86309f202 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 14 Feb 2017 14:50:54 -0500 Subject: [PATCH 0693/1644] CF-205 Fix a regression with multiple DataSource.push calls and keywords --- .../framework/python/ossie/utils/sb/io_helpers.py | 2 +- redhawk/src/testing/tests/test_13_TestSB.py | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py b/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py index eb0b6f368..646cf9c9c 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py +++ b/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py @@ -1409,7 +1409,7 @@ def pushThread(self): if len(SRIKeywords) > 0 : self._SRIKeywords = SRIKeywords # need to keep order for compareSRI - ckeys = [ x.name for x in candidateSri.keywords ] + ckeys = [ x.id for x in candidateSri.keywords ] keywords = candidateSri.keywords[:] for key in self._SRIKeywords: # if current sri contains they keyword then overwrite else append diff --git a/redhawk/src/testing/tests/test_13_TestSB.py b/redhawk/src/testing/tests/test_13_TestSB.py index 5c1481560..ce99921fb 100644 --- a/redhawk/src/testing/tests/test_13_TestSB.py +++ b/redhawk/src/testing/tests/test_13_TestSB.py @@ -2094,6 +2094,18 @@ def test_DataSourceSRI(self): self.assertAlmostEquals(rsri.xdelta, 0.1234) self.assertEqual(True, compareKeywordLists( rsri.keywords, matchkws) ) + # Repeat, making sure that a second push with keywords does not fail + source.push(_srcData, SRIKeywords=kws) + begin_time = time.time() + estimate = sink.getDataEstimate() + while estimate.num_timestamps != 1: + time.sleep(0.1) + estimate = sink.getDataEstimate() + if time.time() - begin_time > _timeout: + break + data=sink.getData() + self.assertTrue(data) + # add new keywords to sri matchkws=[ CF.DataType(id='kw1-1', value=CORBA.Any(CORBA.TC_long, 1000)), CF.DataType(id='kw2-1', value=CORBA.Any(CORBA.TC_float, 12456.0)), From 5ba5f50c987d79395f4742b22c4f45738c190f75 Mon Sep 17 00:00:00 2001 From: Ryan Bauman Date: Tue, 14 Feb 2017 15:26:04 -0500 Subject: [PATCH 0694/1644] RELENG-542 - add cppunit-devel build requirement to bulkio/burstioInterfaces --- bulkioInterfaces/bulkioInterfaces.spec | 1 + burstioInterfaces/burstioInterfaces.spec | 2 ++ 2 files changed, 3 insertions(+) diff --git a/bulkioInterfaces/bulkioInterfaces.spec b/bulkioInterfaces/bulkioInterfaces.spec index fa6244418..8daed1ff2 100644 --- a/bulkioInterfaces/bulkioInterfaces.spec +++ b/bulkioInterfaces/bulkioInterfaces.spec @@ -42,6 +42,7 @@ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot Requires: redhawk >= 2.0 BuildRequires: redhawk-devel >= 2.0 +BuildRequires: cppunit-devel %description Libraries and interface definitions for bulkio interfaces. diff --git a/burstioInterfaces/burstioInterfaces.spec b/burstioInterfaces/burstioInterfaces.spec index 186613453..9f53f8114 100644 --- a/burstioInterfaces/burstioInterfaces.spec +++ b/burstioInterfaces/burstioInterfaces.spec @@ -46,6 +46,8 @@ BuildRequires: redhawk-devel >= 2.0 Requires: bulkioInterfaces >= 2.0 BuildRequires: bulkioInterfaces >= 2.0 +BuildRequires: cppunit-devel + %description BURSTIO interfaces for REDHAWK * Commit: __REVISION__ From 1e7bf43bc7d857548dc863cdba13566d1fb966f6 Mon Sep 17 00:00:00 2001 From: 8530 <8530@vm-131.vsi-corp.com> Date: Tue, 14 Feb 2017 15:43:52 -0500 Subject: [PATCH 0695/1644] fix dtd for usesdeviceref --- redhawk/src/xml/dtd/softwareassembly.dtd | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/redhawk/src/xml/dtd/softwareassembly.dtd b/redhawk/src/xml/dtd/softwareassembly.dtd index a996a5966..b65fa6ace 100644 --- a/redhawk/src/xml/dtd/softwareassembly.dtd +++ b/redhawk/src/xml/dtd/softwareassembly.dtd @@ -192,8 +192,8 @@ with this program. If not, see http://www.gnu.org/licenses/. + , usesdeviceref* + )> Date: Mon, 13 Feb 2017 14:40:58 -0500 Subject: [PATCH 0696/1644] Refs CF-1667. Rename 'overloaded' Python function definitions --- frontendInterfaces/libsrc/python/tuner_device.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontendInterfaces/libsrc/python/tuner_device.py b/frontendInterfaces/libsrc/python/tuner_device.py index 79000d18d..635f77f5b 100644 --- a/frontendInterfaces/libsrc/python/tuner_device.py +++ b/frontendInterfaces/libsrc/python/tuner_device.py @@ -86,7 +86,7 @@ def floatingPointCompare(lhs, rhs, places = 1): true if the value requested_val falls within the range [available_min:available_max] False is returned if min > max ''' -def validateRequest(available_min, available_max, requested_val): +def validateRequestSingle(available_min, available_max, requested_val): if floatingPointCompare(requested_val,available_min) < 0: return False if floatingPointCompare(requested_val,available_max) > 0: return False if floatingPointCompare(available_min,available_max) > 0: return False @@ -165,7 +165,7 @@ def validateRequestVsSRI(request,upstream_sri,output_mode): If the CHAN_RF and FRONTEND.BANDWIDTH keywords are not found in the sri, FRONTEND.BadParameterException is thrown. ''' -def validateRequestVsDevice(request, upstream_sri, output_mode, min_device_center_freq, max_device_center_freq, max_device_bandwidth, max_device_sample_rate): +def validateRequestVsDeviceStream(request, upstream_sri, output_mode, min_device_center_freq, max_device_center_freq, max_device_bandwidth, max_device_sample_rate): # check if request can be satisfied using the available upstream data if not validateRequestVsSRI(request,upstream_sri, output_mode): From 934c749607cd35cc153cd9b6067b2003c3c74ffd Mon Sep 17 00:00:00 2001 From: Max Robert Date: Mon, 13 Feb 2017 16:39:37 -0500 Subject: [PATCH 0697/1644] Refs CF-1669. Populate CF.Device.InvalidCapacity with the correct arguments --- .../.RX_Digitizer_Sim.wavedev | 6 + .../sdr/dev/devices/RX_Digitizer_Sim/.md5sums | 2 + .../RX_Digitizer_Sim/RX_Digitizer_Sim.prf.xml | 129 ++++++ .../RX_Digitizer_Sim/RX_Digitizer_Sim.scd.xml | 73 ++++ .../RX_Digitizer_Sim/RX_Digitizer_Sim.spd.xml | 25 ++ .../devices/RX_Digitizer_Sim/python/.md5sums | 6 + .../python/RX_Digitizer_Sim.py | 385 +++++++++++++++++ .../RX_Digitizer_Sim/python/Waveform.py | 304 ++++++++++++++ .../RX_Digitizer_Sim/python/data_generator.py | 132 ++++++ .../tests/test_RX_Digitizer_Sim.py | 396 ++++++++++++++++++ .../tests/test_RX_Digitizer_Sim_FEI.py | 80 ++++ .../libsrc/python/tuner_device.py | 17 +- redhawk/src/base/framework/python/setup.py | 1 + 13 files changed, 1548 insertions(+), 8 deletions(-) create mode 100644 codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/.RX_Digitizer_Sim.wavedev create mode 100644 codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/.md5sums create mode 100644 codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/RX_Digitizer_Sim.prf.xml create mode 100644 codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/RX_Digitizer_Sim.scd.xml create mode 100644 codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/RX_Digitizer_Sim.spd.xml create mode 100644 codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/python/.md5sums create mode 100755 codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/python/RX_Digitizer_Sim.py create mode 100644 codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/python/Waveform.py create mode 100644 codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/python/data_generator.py create mode 100644 codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/tests/test_RX_Digitizer_Sim.py create mode 100644 codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/tests/test_RX_Digitizer_Sim_FEI.py diff --git a/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/.RX_Digitizer_Sim.wavedev b/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/.RX_Digitizer_Sim.wavedev new file mode 100644 index 000000000..d1ea167e5 --- /dev/null +++ b/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/.RX_Digitizer_Sim.wavedev @@ -0,0 +1,6 @@ + + + + + + diff --git a/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/.md5sums b/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/.md5sums new file mode 100644 index 000000000..54e1f9ba6 --- /dev/null +++ b/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/.md5sums @@ -0,0 +1,2 @@ +240cf9a66910ade2818854253acf38f6 build.sh +1ba61a4cc571613d3eb6e37e4685ec88 RX_Digitizer_Sim.spec diff --git a/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/RX_Digitizer_Sim.prf.xml b/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/RX_Digitizer_Sim.prf.xml new file mode 100644 index 000000000..a8de80de7 --- /dev/null +++ b/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/RX_Digitizer_Sim.prf.xml @@ -0,0 +1,129 @@ + + + + + This specifies the device kind + FRONTEND::TUNER + + + + + This specifies the specific device + + + + + Status of each tuner, including entries for both allocated and un-allocated tuners. Each entry represents a single tuner. + + + Comma separated list of current Allocation IDs. + + + Available bandwidth (Hz) in range (XX-YY) or csv (X,Y,Z) format. Do not put units in field. + Hz + + + Available frequencies (Hz) in range (XX-YY) or csv (X,Y,Z) format. Do not put units in field. + Hz + + + Available gain (dB) in range (XX-YY) or csv (X,Y,Z) format. Do not put units in field. + dB + + + Available sample_rate (sps) in range (XX-YY) or csv (X,Y,Z) format. Do not put units in field. + sps + + + Current bandwidth in Hz + Hz + + + Current center frequency in Hz. + Hz + + + Current decimation of tuner. For DDC tuners, this is the ratio of input sample rate to output sample rate regardless of data format. + + + Indicates if tuner is enabled, in reference to the output state of the tuner. + + + Current gain in dB. + dB + + + Unique ID that specifies a group of Device. + + + Specifies a certain RF flow to allocate against. + + + Current sample rate in samples per second. + sps + + + Physical tuner ID. + + + Example Tuner Types: TX, RX, CHANNELIZER, DDC, RX_DIGITIZER, RX_DIGTIZIER_CHANNELIZER + + + + + + + Frontend Interfaces v2 listener allocation structure + + + + + + Frontend Interfaces v2 main allocation structure + + Example Tuner Types: TX, RX, CHANNELIZER, DDC, RX_DIGITIZER, RX_DIGTIZIER_CHANNELIZER + + + The allocation_id set by the caller. Used by the caller to reference the allocation uniquely + + + Requested center frequency + Hz + + + Requested bandwidth (+/- the tolerance) + Hz + + + Allowable Percent above requested bandwidth (ie - 100 would be up to twice) + percent + + + Requested sample rate (+/- the tolerance). This can be ignored for such devices as analog tuners + Hz + + + Allowable Percent above requested sample rate (ie - 100 would be up to twice) + percent + + + True: Has control over the device to make changes +False: Does not need control and can just attach to any currently tasked device that satisfies the parameters (essentually a listener) + + + Unique identifier that specifies the group a device must be in. Must match group_id on the device + + + Optional. Specifies the RF flow of a specific input source to allocate against. If left empty, it will match all FrontEnd devices. + + + + + + + + + + + + diff --git a/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/RX_Digitizer_Sim.scd.xml b/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/RX_Digitizer_Sim.scd.xml new file mode 100644 index 000000000..1b932fdc5 --- /dev/null +++ b/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/RX_Digitizer_Sim.scd.xml @@ -0,0 +1,73 @@ + + + + 2.2 + + device + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/RX_Digitizer_Sim.spd.xml b/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/RX_Digitizer_Sim.spd.xml new file mode 100644 index 000000000..4eeb6887a --- /dev/null +++ b/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/RX_Digitizer_Sim.spd.xml @@ -0,0 +1,25 @@ + + + + + + null + + + + + + + + + The implementation contains descriptive information about the template for a software resource. + + + python/RX_Digitizer_Sim.py + + + + + + + diff --git a/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/python/.md5sums b/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/python/.md5sums new file mode 100644 index 000000000..cacf81c03 --- /dev/null +++ b/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/python/.md5sums @@ -0,0 +1,6 @@ +b1139cb052c7e855dc8e0d9daeb9ae41 RX_Digitizer_Sim.py +8bfcd22353c3a57fee561ad86ee2a56b reconf +1dc23ee4edb38a3ac1e4bea610d4334e configure.ac +77735ac9d958acdca4cf52727c42a652 RX_Digitizer_Sim_base.py +9506fe5bbdeb899b120123613b655f93 Makefile.am.ide +0184c25415022e8035f6618a80392374 Makefile.am diff --git a/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/python/RX_Digitizer_Sim.py b/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/python/RX_Digitizer_Sim.py new file mode 100755 index 000000000..870cba2bf --- /dev/null +++ b/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/python/RX_Digitizer_Sim.py @@ -0,0 +1,385 @@ +#!/usr/bin/env python +# +# +# AUTO-GENERATED +# +# Source: RX_Digitizer_Sim.spd.xml +from ossie.device import start_device +import logging +from frontend.tuner_device import validateRequestSingle, floatingPointCompare, validateRequestVsRFInfo +from redhawk.frontendInterfaces import FRONTEND + +from data_generator import DataGenerator + +from RX_Digitizer_Sim_base import * + +class RX_Digitizer_Sim_i(RX_Digitizer_Sim_base): + """""" + MINFREQ = 50000000.0 + MAXFREQ = 3000000000.0 + AVAILABLE_BW_SR = ((2000000,2500000.0,8),(4000000,5000000.0,4),(8000000,10000000.0,2)) + + + def constructor(self): + """ + This is called by the framework immediately after your device registers with the system. + + In general, you should add customization here and not in the __init__ constructor. If you have + a custom port implementation you can override the specific implementation here with a statement + similar to the following: + self.some_port = MyPortImplementation() + + For a tuner device, the structure frontend_tuner_status needs to match the number + of tuners that this device controls and what kind of device it is. + The options for devices are: TX, RX, RX_DIGITIZER, CHANNELIZER, DDC, RC_DIGITIZER_CHANNELIZER + + For example, if this device has 5 physical + tuners, each an RX_DIGITIZER, then the code in the construct function should look like this: + + self.setNumChannels(5, "RX_DIGITIZER"); + + The incoming request for tuning contains a string describing the requested tuner + type. The string for the request must match the string in the tuner status. + """ + # TODO add customization here. + self.setNumChannels(2, "RX_DIGITIZER"); + + self.datagenerators =[] + self.datagenerators.append(DataGenerator(self.port_dataShort_out)) + self.datagenerators.append(DataGenerator(self.port_dataShort_out)) + + self.rfinfo = self._createEmptyRFInfo() + + for datagenerator in self.datagenerators: + datagenerator.keyword_dict['FRONTEND::DEVICE_ID'] = self._get_identifier() + datagenerator.keyword_dict['FRONTEND::RF_FLOW_ID'] = self.rfinfo.rf_flow_id + datagenerator.waveform_type = "Sine" + + + def process(self): + # TODO fill in your code here + self._log.debug("process() example log message") + return NOOP + + ''' + ************************************************************* + Functions supporting tuning allocation + *************************************************************''' + def deviceEnable(self, fts, tuner_id): + ''' + ************************************************************ + modify fts, which corresponds to self.frontend_tuner_status[tuner_id] + Make sure to set the 'enabled' member of fts to indicate that tuner as enabled + ************************************************************''' + print "deviceEnable(): Enable the given tuner *********" + try: + self.datagenerators[tuner_id].enableDataFlow() + fts.enabled = True + + except Exception, e: + self._log.exception("Got exception % s" %str(e)) + return False + + return True + + def deviceDisable(self,fts, tuner_id): + ''' + ************************************************************ + modify fts, which corresponds to self.frontend_tuner_status[tuner_id] + Make sure to reset the 'enabled' member of fts to indicate that tuner as disabled + ************************************************************''' + self._log.debug( "deviceDisable(): Disable the given tuner *********") + self.datagenerators[tuner_id].disableDataFlow() + fts.enabled = False + + return + + def deviceSetTuning(self,request, fts, tuner_id): + ''' + ************************************************************ + modify fts, which corresponds to self.frontend_tuner_status[tuner_id] + + The bandwidth, center frequency, and sampling rate that the hardware was actually tuned + to needs to populate fts (to make sure that it meets the tolerance requirement. For example, + if the tuned values match the requested values, the code would look like this: + + fts.bandwidth = request.bandwidth + fts.center_frequency = request.center_frequency + fts.sample_rate = request.sample_rate + + return True if the tuning succeeded, and False if it failed + ************************************************************''' + self._log.debug( "deviceSetTuning(): Evaluate whether or not a tuner is added *********") + + self._log.debug( "allocating tuner_id %s" % tuner_id) + + # Check that allocation can be satisfied + if self.rfinfo.rf_flow_id !="": + try: + validateRequestVsRFInfo(request,self.rfinfo,1) + except FRONTEND.BadParameterException , e: + self._log.info("ValidateRequestVsRFInfo Failed: %s" %(str(e))) + return False + + + #Convert CF based on RFInfo. + tuneFreq = self.convert_rf_to_if(request.center_frequency) + + # Check the CF + + if not(validateRequestSingle(self.MINFREQ,self.MAXFREQ,tuneFreq)): + self._log.debug( "Center Freq Does not fit %s, %s, %s" %(tuneFreq, self.MINFREQ , self.MAXFREQ)) + return False + # Check the BW/SR + + + bw,sr,decimation = self.findBestBWSR(request.bandwidth,request.sample_rate) + if not bw: + self._log.debug( "Can't Satisfy BW and SR request") + return False + + # Update Tuner Status + fts.bandwidth = bw + fts.center_frequency = request.center_frequency + fts.sample_rate = sr + fts.decimation = decimation + print "deviceSetTuning(): 5" + #Update output multiPort to add this allocation. Make Allocation ID the same as StreamID + self.matchAllocationIdToStreamId(request.allocation_id, request.allocation_id,"dataShort_out") + + # Setup data Generator and start data for that tuner + self.datagenerators[tuner_id].stream_id = request.allocation_id + self.datagenerators[tuner_id].sr = sr + self.datagenerators[tuner_id].cf = tuneFreq + self.datagenerators[tuner_id].keyword_dict['FRONTEND::BANDWIDTH'] = bw + self.datagenerators[tuner_id].keyword_dict['COL_RF'] = request.center_frequency + self.datagenerators[tuner_id].keyword_dict['CHAN_RF'] = request.center_frequency + self.datagenerators[tuner_id].start() + + print "Done with deviceSetTuning():" + return True + + + def deviceDeleteTuning(self, fts, tuner_id): + ''' + ************************************************************ + modify fts, which corresponds to self.frontend_tuner_status[tuner_id] + return True if the tune deletion succeeded, and False if it failed + ************************************************************''' + + self._log.debug( "deviceDeleteTuning(): Deallocate an allocated tuner *********") + self.datagenerators[tuner_id].stop() + print dir(fts) + controlAllocationID = fts.allocation_id_csv.split(',')[0] + self.removeStreamIdRouting(controlAllocationID, controlAllocationID) + return True + + ''' + ************************************************************* + Functions servicing the tuner control port + *************************************************************''' + def getTunerType(self,allocation_id): + idx = self.getTunerMapping(allocation_id) + if idx < 0: raise FRONTEND.FrontendException("Invalid allocation id") + return self.frontend_tuner_status[idx].tuner_type + + def getTunerDeviceControl(self,allocation_id): + idx = self.getTunerMapping(allocation_id) + if idx < 0: raise FRONTEND.FrontendException("Invalid allocation id") + if self.getControlAllocationId(idx) == allocation_id: + return True + return False + + def getTunerGroupId(self,allocation_id): + idx = self.getTunerMapping(allocation_id) + if idx < 0: raise FRONTEND.FrontendException("Invalid allocation id") + return self.frontend_tuner_status[idx].group_id + + def getTunerRfFlowId(self,allocation_id): + idx = self.getTunerMapping(allocation_id) + if idx < 0: raise FRONTEND.FrontendException("Invalid allocation id") + return self.frontend_tuner_status[idx].rf_flow_id + + + def setTunerCenterFrequency(self,allocation_id, freq): + idx = self.getTunerMapping(allocation_id) + if idx < 0: raise FRONTEND.FrontendException("Invalid allocation id") + if allocation_id != self.getControlAllocationId(idx): + raise FRONTEND.FrontendException(("ID "+str(allocation_id)+" does not have authorization to modify the tuner")) + if freq<0: raise FRONTEND.BadParameterException("Bad CF") + # set hardware to new value. Raise an exception if it's not possible + + #Check Frequency again min/max Range + #Convert CF based on RFInfo. + tuneFreq = self.convert_rf_to_if(freq) + + # Check the CF + if not(validateRequestSingle(self.MINFREQ,self.MAXFREQ,tuneFreq)): + self._log.debug( "Center Freq Does not fit %s, %s, %s" %(tuneFreq, self.MINFREQ , self.MAXFREQ)) + raise FRONTEND.BadParameterException("Radio Center Freq of %s Does not fit in %s, %s" %(tuneFreq, self.MINFREQ , self.MAXFREQ)) + + #set tuner new freq + self.datagenerators[idx].cf = tuneFreq + self.datagenerators[idx].keyword_dict['COL_RF'] = freq + self.datagenerators[idx].keyword_dict['CHAN_RF'] = freq + self.datagenerators[idx].updateandPushSRI() + self.frontend_tuner_status[idx].center_frequency = freq + + def getTunerCenterFrequency(self,allocation_id): + idx = self.getTunerMapping(allocation_id) + if idx < 0: raise FRONTEND.FrontendException("Invalid allocation id") + return self.frontend_tuner_status[idx].center_frequency + + def setTunerBandwidth(self,allocation_id, bw): + idx = self.getTunerMapping(allocation_id) + if idx < 0: raise FRONTEND.FrontendException("Invalid allocation id") + if allocation_id != self.getControlAllocationId(idx): + raise FRONTEND.FrontendException(("ID "+str(allocation_id)+" does not have authorization to modify the tuner")) + if bw<0: raise FRONTEND.BadParameterException("Invalid BW") + + newbw,newsr,decimation = self.findBestBWSR(bw,0) + if not newbw: + self._log.debug( "Can't Satisfy BW and SR request") + raise FRONTEND.BadParameterException("Can't Satisfy BW and SR request") + + # set hardware to new value. Raise an exception if it's not possible + self.datagenerators[idx].keyword_dict['FRONTEND::BANDWIDTH'] = newbw + self.datagenerators[idx].updateandPushSRI() + self.frontend_tuner_status[idx].bandwidth = newsr + self.frontend_tuner_status[idx].bandwidth = newbw + self.frontend_tuner_status[idx].decimation = decimation + + def getTunerBandwidth(self,allocation_id): + idx = self.getTunerMapping(allocation_id) + if idx < 0: raise FRONTEND.FrontendException("Invalid allocation id") + return self.frontend_tuner_status[idx].bandwidth + + def setTunerAgcEnable(self,allocation_id, enable): + raise FRONTEND.NotSupportedException("setTunerAgcEnable not supported") + + def getTunerAgcEnable(self,allocation_id): + raise FRONTEND.NotSupportedException("getTunerAgcEnable not supported") + + def setTunerGain(self,allocation_id, gain): + idx = self.getTunerMapping(allocation_id) + if idx < 0: raise FRONTEND.FrontendException("Invalid allocation id") + if allocation_id != self.getControlAllocationId(idx): + raise FRONTEND.FrontendException(("ID "+str(allocation_id)+" does not have authorization to modify the tuner")) + if (gain<0 or gain>10) : raise FRONTEND.BadParameterException("Invalid Gain") + gain = round(gain,1) + # magnitude on data generators is 100+gain*10 + self.datagenerators[idx].magnitude = 100+gain*10 + self.frontend_tuner_status[idx].gain = gain + + def getTunerGain(self,allocation_id): + idx = self.getTunerMapping(allocation_id) + if idx < 0: raise FRONTEND.FrontendException("Invalid allocation id") + return self.frontend_tuner_status[idx].gain + def setTunerReferenceSource(self,allocation_id, source): + raise FRONTEND.NotSupportedException("setTunerReferenceSource not supported") + + def getTunerReferenceSource(self,allocation_id): + raise FRONTEND.NotSupportedException("getTunerReferenceSource not supported") + + def setTunerEnable(self,allocation_id, enable): + idx = self.getTunerMapping(allocation_id) + if idx < 0: raise FRONTEND.FrontendException("Invalid allocation id") + if allocation_id != self.getControlAllocationId(idx): + raise FRONTEND.FrontendException(("ID "+str(allocation_id)+" does not have authorization to modify the tuner")) + # set hardware to new value. Raise an exception if it's not possible + self.frontend_tuner_status[idx].enabled = enable + + def getTunerEnable(self,allocation_id): + idx = self.getTunerMapping(allocation_id) + if idx < 0: raise FRONTEND.FrontendException("Invalid allocation id") + return self.frontend_tuner_status[idx].enabled + + + def setTunerOutputSampleRate(self,allocation_id, sr): + idx = self.getTunerMapping(allocation_id) + if idx < 0: raise FRONTEND.FrontendException("Invalid allocation id") + if allocation_id != self.getControlAllocationId(idx): + raise FRONTEND.FrontendException(("ID "+str(allocation_id)+" does not have authorization to modify the tuner")) + if sr<0: raise FRONTEND.BadParameterException("Invalid SR") + + newbw,newsr,decimation = self.findBestBWSR(0,sr) + if not newbw: + self._log.debug( "Can't Satisfy BW and SR request") + raise FRONTEND.BadParameterException( "Can't Satisfy BW and SR request") + + self._log.debug("Setting BW and Sample Rate %s, %s " %(newbw,newsr)) + #set new SR + self.datagenerators[idx].sr = sr + self.datagenerators[idx].keyword_dict['FRONTEND::BANDWIDTH'] = newbw + self.datagenerators[idx].updateandPushSRI() + self.frontend_tuner_status[idx].sample_rate = newsr + self.frontend_tuner_status[idx].bandwidth = newbw + self.frontend_tuner_status[idx].decimation = decimation + + def getTunerOutputSampleRate(self,allocation_id): + idx = self.getTunerMapping(allocation_id) + if idx < 0: raise FRONTEND.FrontendException("Invalid allocation id") + return self.frontend_tuner_status[idx].sample_rate + + ''' + ************************************************************* + Functions servicing the RFInfo port(s) + - port_name is the port over which the call was received + *************************************************************''' + def get_rf_flow_id(self,port_name): + return self.rfinfo.rf_flow_id + + def set_rf_flow_id(self,port_name, id): + pass + + def get_rfinfo_pkt(self,port_name): + return self.rfinfo + + def _createEmptyRFInfo(self): + _antennainfo=FRONTEND.AntennaInfo('','','','') + _freqrange=FRONTEND.FreqRange(0,0,[]) + _feedinfo=FRONTEND.FeedInfo('','',_freqrange) + _sensorinfo=FRONTEND.SensorInfo('','','',_antennainfo,_feedinfo) + _rfcapabilities=FRONTEND.RFCapabilities(_freqrange,_freqrange) + _rfinfopkt=FRONTEND.RFInfoPkt('',0.0,0.0,0.0,False,_sensorinfo,[],_rfcapabilities,[]) + return _rfinfopkt + + def set_rfinfo_pkt(self,port_name, pkt): + self.rfinfo = pkt + for tuner in self.frontend_tuner_status: + tuner.rf_flow_id=self.rfinfo.rf_flow_id + for datagenerator in self.datagenerators: + datagenerator.keyword_dict['FRONTEND::RF_FLOW_ID'] = self.rfinfo.rf_flow_id + + ''' + ************************************************************* + Helper Functions + *************************************************************''' + + def convert_rf_to_if(self,rf_freq): + #Convert freq based on RF/IF of Analog Tuner + + if self.rfinfo.if_center_freq > 0: + ifoffset = rf_freq - self.rfinfo.rf_center_freq + if_freq =self.rfinfo.if_center_freq+ifoffset + else: + if_freq = rf_freq + + self._log.debug("Converted RF Freq of %s to IF Freq %s based on Input RF of %s, IF of %s, and spectral inversion %s" %(rf_freq,if_freq,self.rfinfo.rf_center_freq,self.rfinfo.if_center_freq,self.rfinfo.spectrum_inverted)) + return float(if_freq) + + #Start with smallest possible and see if that can satisfy request. + # Sending 0 for don't care should pass because we are looking for requested to be less than available + def findBestBWSR(self,requestedBW,requestedSR): + self._log.debug("findBestBWSR") + for bw,sr,decimation in self.AVAILABLE_BW_SR: + self._log.debug("findBestBWSR. Requested: " + str(requestedBW) +" "+ str(requestedSR) + " evaluating: " + str(bw)+" "+ str(sr)) + if bw>= requestedBW and sr>=requestedSR: + return (bw,sr,decimation) + return (False,False,False) + +if __name__ == '__main__': + logging.getLogger().setLevel(logging.INFO) + logging.debug("Starting Device") + start_device(RX_Digitizer_Sim_i) + diff --git a/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/python/Waveform.py b/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/python/Waveform.py new file mode 100644 index 000000000..5928a3ae7 --- /dev/null +++ b/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/python/Waveform.py @@ -0,0 +1,304 @@ +# +# This file is protected by Copyright. Please refer to the COPYRIGHT file distributed with this +# source distribution. +# +# This file is part of REDHAWK Basic Components SigGen. +# +# REDHAWK Basic Components SigGen is free software: you can redistribute it and/or modify it under the terms of +# the GNU Lesser General Public License as published by the Free Software Foundation, either +# version 3 of the License, or (at your option) any later version. +# +# REDHAWK Basic Components SigGen is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; +# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +# PURPOSE. See the GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License along with this +# program. If not, see http://www.gnu.org/licenses/. +# +''' +Waveform class produces the following types of waveforms: + - whitenoise + - sincos + - square + - triangle + - sawtooth + - pulse + - constant + - lrs + - ramp +''' +import math +import numpy as np + +class Waveform: + A = 67081293.0 + B=14181771.0 + T26=67108864.0 + + BI = B/T26 + seed = 123456789 + + TWOPI = math.pi * 2.0 + HALFPI = math.pi / 2.0 + + # Binary variant of a Giga. Note that this differs from the typical version + # (the decimal) version of Giga which is 10^9 + # Value: = 1G = 2^30 + B1G = 1073741824. + + def setSeed(self, value): + if value > 0: self.seed = value + + # Create a white noise array of given magnitude + # @param fbuf The output array + # @param sdev Standard deviation + # @param n Number of elements + # @param spa Scalars per atom, 2 for Complex + # @return the new data buffer + def whitenoise(self, sdev, n, spa=1): + outbuff = range(n*spa) + v1 = 0.0; v2 = 0.0; sum1 = 0.0 + fdev = float(sdev) + factor = -2.0 / math.log(10.0) + sis = float(self.seed)/self.T26 + + maxIndex = n*spa + #Do this is in a while loop instead of a for loop + #because we don't know how many times the sum1 is invalid + #we are forced to continue + i=0 + while i < maxIndex: + sis = sis*self.A + self.BI; + sis = sis - float(int(sis)) + v1 = float(sis) + v1 = v1+v1-1 + + sis = sis*self.A + self.BI; + sis = sis - float(int(sis)) + v2 = float(sis) + v2 = v2+v2-1 + + sum1 = v1*v1 + v2*v2 + if sum1 >= 1.0 or sum1 <1e-20: continue + sum1 = fdev * float(math.sqrt(factor*math.log(sum1)/sum1)) + outbuff[i] = float(np.float32(v1*sum1)) + if (i+1) < maxIndex: + outbuff[i+1] = float(np.float32(v2*sum1)) + i+=2 + + self.seed = int(sis*self.T26) + + return outbuff + + # Create a SIN or COSINE array of given magnitude + # @param fbuf The output array + # @param amp Amplitude + # @param p Phase + # @param dp Delta Phase + # @param n Number of elements + # @param spa Scalars per atom, 2 for Complex + # @return the new data buffer + + # fast algorithm based on: sin(x+dp) = sin(x)*cos(dp) + cos(x)*sin(dp) + # cos(x+dp) = cos(x)*cos(dp) - sin(x)*sin(dp) + def sincos(self, amp, p, dp, n, spa): + outbuff = range(n*spa) + cxr = amp*math.cos(p*self.TWOPI) + cxi = amp*math.sin(p*self.TWOPI) + dxr = math.cos(dp*self.TWOPI) + dxi = math.sin(dp*self.TWOPI) + if spa==2: + for i in range(0, n*2, 2): + outbuff[i] = float(np.float32(cxr)) + outbuff[i+1] = float(np.float32(cxi)) + axr = (cxr*dxr) - (cxi*dxi) + axi = (cxr*dxi) + (cxi*dxr) + cxr=axr + cxi=axi + elif spa==1: + for i in range(n): + outbuff[i] = float(np.float32(cxi)) + axr = (cxr*dxr) - (cxi*dxi) + axi = (cxr*dxi) + (cxi*dxr) + cxr=axr + cxi=axi + elif spa==-1: + for i in range(n): + outbuff[i] = float(np.float32(amp*math.sin(p*self.TWOPI))) + p += dp + elif spa==-2: + for i in range(0, n*2, 2): + outbuff[i] = float(np.float32(amp*math.cos(p*self.TWOPI))) + outbuff[i+1] = float(np.float32(amp*math.sin(p*self.TWOPI))) + p += dp + + return outbuff + + # Create a SQUARE array of given amplitude + # @param fbuf The output array + # @param amp Amplitude + # @param p Phase + # @param dp Delta Phase + # @param n Number of elements + # @param spa Scalars per atom, 2 for Complex + # @return the new data buffer + def square(self, amp, p, dp, n, spa): + outbuff = range(n*spa) + value = 0.0 + famp = float(amp) + famp2 = -famp + + for i in range(0, n*spa, spa): + value = famp2 + if p >= 1.0: + p -= 1.0 + elif p >= 0.5: + value = famp + outbuff[i] = float(np.float32(value)) + if spa == 2: + outbuff[i+1] = float(np.float32(value)) + p += dp + + return outbuff + + # Create a TRIANGLE array of given amplitude + # @param fbuf The output array + # @param amp Amplitude + # @param p Phase + # @param dp Delta Phase + # @param n Number of elements + # @param spa Scalars per atom, 2 for Complex + # @return the new data buffer + def triangle(self, amp, p, dp, n, spa): + outbuff = range(n*spa) + value = 0.0 + famp = float(amp) + famp2 = 4*famp + fp = float(p) - 0.5 + + for i in range(0, n*spa, spa): + if fp >= 0.5: + fp -= 1.0 + if fp > 0: + value = float(famp - fp*famp2) + else: + value = float(famp + fp*famp2) + outbuff[i] = float(np.float32(value)) + if spa == 2: + outbuff[i+1] = float(np.float32(value)) + fp += dp + + return outbuff + + # Create a SAWTOOTH array of given amplitude + # @param fbuf The output array + # @param amp Amplitude + # @param p Phase + # @param dp Delta Phase + # @param n Number of elements + # @param spa Scalars per atom, 2 for Complex + # @return the new data buffer + def sawtooth(self, amp, p, dp, n, spa): + outbuff = range(n*spa) + value = 0.0 + famp = float(amp) + famp2 = 2*famp + fp = float(p) - 0.5 + + for i in range(0, n*spa, spa): + if fp >= 0.5: + fp -= 1.0 + value = float(fp*famp2) + outbuff[i] = float(np.float32(value)) + if spa == 2: + outbuff[i+1] = float(np.float32(value)) + fp += dp + + return outbuff + + # Create a PULSE array of given amplitude + # @param fbuf The output array + # @param amp Amplitude + # @param p Phase + # @param dp Delta Phase + # @param n Number of elements + # @param spa Scalars per atom, 2 for Complex + # @return the new data buffer + def pulse(self, amp, p, dp, n, spa): + outbuff = range(n*spa) + value = 0.0 + famp = float(amp) + + for i in range(0, n*spa, spa): + if p >= 1.0: + value = famp + p -= 1.0 + else: + value = 0 + outbuff[i] = float(np.float32(value)) + if spa == 2: + outbuff[i+1] = float(np.float32(value)) + p += dp + + return outbuff + + # Create a CONSTANT array of given amplitude + # @param fbuf The output array + # @param amp Amplitude + # @param n Number of elements + # @param spa Scalars per atom, 2 for Complex + # @return the new data buffer + def constant(self, amp, n, spa): + outbuff = range(n*spa) + + for i in range(n*spa): + outbuff[i] = float(np.float32(amp)) + + return outbuff + + # Create an LRS noise array of given magnitude + # @param fbuf The output array + # @param amp Amplitude + # @param n Number of elements + # @param spa Scalars per atom, 2 for Complex + # @param lrs LRS seed from previous call + # @return the new data buffer and the LRS at end of array + def lrs(self, amp, n, spa, lrs): + outbuff = range(n*spa) + factor = (amp/2.0/self.B1G) + + for i in range(0, n*spa, spa): + data = (factor * lrs) + outbuff[i] = float(np.float32(data)) + if spa == 2: + outbuff[i+1] = float(np.float32(data)) + + bit0 = (~(lrs ^ (lrs>>1) ^ (lrs>>5) ^ (lrs>>25)))&0x1 + lrs <<= 1 + lrs |= bit0 + # Correct for python not overflowing int_32s + lrs &= 0xffffffff + if lrs >= 2**31 -1: + lrs &= 0x7fffffff + lrs -= 2**31 + + return outbuff + + # Create an RAMP array of given magnitude + # @param fbuf The output array + # @param amp Amplitude + # @param n Number of elements + # @param spa Scalars per atom, 2 for Complex + # @param data RAMP seed from previous call + # @return the new data buffer and the RAMP value at end of array + def ramp(self, amp, n, spa, data): + outbuff = range(n*spa) + for i in range(0, n*spa, spa): + outbuff[i] = float(np.float32(data)) + if spa == 2: + outbuff[i+1] = float(np.float32(data)) + data = data + 1 + if data >= amp: + data = int(-amp) + + return outbuff, data diff --git a/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/python/data_generator.py b/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/python/data_generator.py new file mode 100644 index 000000000..e7e0ed3ed --- /dev/null +++ b/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/python/data_generator.py @@ -0,0 +1,132 @@ + +import Waveform +import math +import time +from bulkio.bulkioInterfaces import BULKIO +from omniORB import any +from ossie.cf import CF +import threading +import bulkio + + +class DataGenerator(object): + + def __init__(self,outputPort,stream_id="stream_id",cf=100e6,sr=10e6): + self.outputPort = outputPort + self.stream_id = stream_id + self.cf = cf + self.sr = sr + self._waveform = Waveform.Waveform() + self.enable = False + self.phase = 0 + self.chirp = 0 + self.sample_time_delta = 0.0 + self.delta_phase = 0.0 + self.delta_phase_offset = 0.0 + self.magnitude = 100 + self.xfer_len = 100000 + self.last_xfer_len = self.xfer_len + self.next_time = None + self.throttle = True + self.terminate = False + self.thread = None + self.firstTime = True + self.keyword_dict = {} + self.sri = BULKIO.StreamSRI(1, 0.0, 0.0, BULKIO.UNITS_TIME, 0, 0.0, 0.0, BULKIO.UNITS_NONE, 0, self.stream_id, False, []) + + + def start(self): + + if not self.thread: + print "Starting Thread" + self.thread = threading.Thread(target = self._run) + self.thread.start() + + + + def stop(self): + if self.thread: + print "Stopping Thread" + self.terminate = True + self.thread.join(2) + else: + print "No Thread to Stop" + + + def _run(self): + while True: + if self.terminate: + return + self._push_data() + + def enableDataFlow(self): + self.next_time = bulkio.timestamp.now() + self.updateandPushSRI() + self.enable = True + + def disableDataFlow(self): + print "Disable Data Flow" + self.enable = False + self.outputPort.pushPacket([], self.next_time, True, self.stream_id) + + def _push_data(self): + if self.enable: + + self.sample_time_delta = 1.0/self.sr + + self.delta_phase = self.cf * self.sample_time_delta + self.delta_phase_offset = self.chirp * self.sample_time_delta * self.sample_time_delta + + data = self._waveform.sincos(self.magnitude, self.phase, self.delta_phase, self.last_xfer_len, 1) + data = [int(i) for i in data] + self.phase += self.delta_phase*self.last_xfer_len # increment phase + self.phase -= math.floor(self.phase) # module 1.0 + + self.outputPort.pushPacket(data, self.next_time, False, self.stream_id) + + # Advance time + self.next_time.tfsec += self.last_xfer_len * self.sample_time_delta + if self.next_time.tfsec > 1.0: + self.next_time.tfsec -= 1.0 + self.next_time.twsec += 1.0 + + # If we are throttling, wait...otherwise run at full speed + if self.throttle: + wait_amt = self.last_xfer_len * self.sample_time_delta + try: + time.sleep(wait_amt) + finally: + return + return + def updateandPushSRI(self): + self.sri.xdelta =1.0/self.sr + self.sri.streamID = self.stream_id + keywords = [] + for keyword in self.keyword_dict.keys(): + keywords.append(CF.DataType(keyword, any.to_any(self.keyword_dict[keyword]))) + self.sri.keywords = keywords + self.sri.mode = 1 + try: + self.outputPort.pushSRI(self.sri) + except Exception, e: + print "Exception on pushSRI" , str(e) + +class TestPort(object): + + def pushPacket(self,data,sometime,EOS,stream_id): + print "Pusing Data of length" , len(data) + +if __name__ == "__main__": + + aport = TestPort() + generator = DataGenerator(aport) + generator.start() + time.sleep(2) + generator.enableDataFlow() + time.sleep(2) + generator.stop() + print "complete" + + + + \ No newline at end of file diff --git a/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/tests/test_RX_Digitizer_Sim.py b/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/tests/test_RX_Digitizer_Sim.py new file mode 100644 index 000000000..4bcc95c89 --- /dev/null +++ b/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/tests/test_RX_Digitizer_Sim.py @@ -0,0 +1,396 @@ +#!/usr/bin/env python + +import ossie.utils.testing +from ossie.utils import sb +from ossie.cf import CF +from omniORB import any +from omniORB import CORBA +from ossie.utils.bulkio.bulkio_data_helpers import SDDSSink +from redhawk.frontendInterfaces import FRONTEND +from ossie.utils import uuid +from ossie import properties +import time +from ossie.utils.bluefile.bluefile_helpers import sri_to_hdr + +DEBUG_LEVEL = 2 + +class DeviceTests(ossie.utils.testing.RHTestCase): + # Path to the SPD file, relative to this file. This must be set in order to + # launch the device. + SPD_FILE = '../RX_Digitizer_Sim.spd.xml' + + # setUp is run before every function preceded by "test" is executed + # tearDown is run after every function preceded by "test" is executed + + # self.comp is a device using the sandbox API + # to create a data source, the package sb contains data sources like DataSource or FileSource + # to create a data sink, there are sinks like DataSink and FileSink + # to connect the component to get data from a file, process it, and write the output to a file, use the following syntax: + # src = sb.FileSource('myfile.dat') + # snk = sb.DataSink() + # src.connect(self.comp) + # self.comp.connect(snk) + # sb.start() + # + # components/sources/sinks need to be started. Individual components or elements can be started + # src.start() + # self.comp.start() + # + # every component/elements in the sandbox can be started + # sb.start() + + def setUp(self): + # Launch the device, using the selected implementation + self.comp = sb.launch(self.spd_file, impl=self.impl,execparams={'DEBUG_LEVEL': DEBUG_LEVEL}) + + def tearDown(self): + # Clean up all sandbox artifacts created during test + sb.release() + + def testBasicBehavior(self): + ####################################################################### + # Make sure start and stop can be called without throwing exceptions + self.comp.start() + self.comp.stop() + + def testSingleTunerAllocation(self): + + #self.comp.start() + + sink = sb.DataSink() + + + alloc = self._generateAlloc(cf=110e6,sr=2.5e6,bw=2e6) + allocationID = properties.props_to_dict(alloc)['FRONTEND::tuner_allocation']['FRONTEND::tuner_allocation::allocation_id'] + self.comp.connect(sink,connectionId=allocationID) + sink.start() + + try: + retval = self.comp.allocateCapacity(alloc) + except Exception, e: + print "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%" + print "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%" + print "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%" + print str(e) + self.assertFalse("Exception thrown on allocateCapactiy %s" % str(e)) + if not retval: + self.assertFalse("Allocation Failed") + + time.sleep(1) + + sri = sink.sri() + self.assertEqual(sri.streamID, allocationID) + self.assertAlmostEqual(sri.xdelta, 1.0/2.5e6,5) + #time.sleep(1) + + data= sink.getData() + self.assertTrue(len(data)>0) + + self.comp.deallocateCapacity(alloc) + time.sleep(1) + + sri = sink.sri() + self.assertTrue( sink.eos()) + + def testDoubleTunerAllocation(self): + + #self.comp.start() + + #Create Allocation and Sink for Tuner 1 + sink = sb.DataSink() + alloc = self._generateAlloc(cf=110e6,sr=2.5e6,bw=2e6) + allocationID = properties.props_to_dict(alloc)['FRONTEND::tuner_allocation']['FRONTEND::tuner_allocation::allocation_id'] + self.comp.connect(sink,connectionId=allocationID) + sink.start() + + + + #Allocate a Tuner + try: + retval = self.comp.allocateCapacity(alloc) + except Exception, e: + self.assertFalse("Exception thrown on allocateCapactiy %s" % str(e)) + if not retval: + self.assertFalse("Allocation Failed") + + #Sleep and let data and SRI flow + time.sleep(1) + + #Check Tuner 1 SRI + sri = sink.sri() + print "SRI 1 1st Time" , sri + self.assertEqual(sri.streamID, allocationID, "SRI 1 Did not Match") + self.assertAlmostEqual(sri.xdelta, 1.0/2.5e6,5) + + #Create Allocation and Sink for Tuner 2 + sink2 = sb.DataSink() + alloc2 = self._generateAlloc(cf=110e6,sr=5e6,bw=4e6) + allocationID2 = properties.props_to_dict(alloc2)['FRONTEND::tuner_allocation']['FRONTEND::tuner_allocation::allocation_id'] + self.comp.connect(sink2,connectionId=allocationID2) + sink2.start() + + #Allocate a Second Tuner + try: + retval = self.comp.allocateCapacity(alloc2) + except Exception, e: + print str(e) + self.assertFalse("Exception thrown on allocateCapactiy on second Tuner %s" % str(e)) + if not retval: + self.assertFalse("Allocation Failed on second Tuner") + + #Sleep and let data and SRI flow + time.sleep(1) + + #Check Tuner 1 SRI Again (should not change) + sri = sink.sri() + print "SRI 1 2nd Time" , sri + self.assertEqual(sri.streamID, allocationID, "SRI 1 Did not Match Second Time") + self.assertAlmostEqual(sri.xdelta, 1.0/2.5e6,5) + + #Check Tuner 2 SRI + sri2 = sink2.sri() + print "SRI 2 " , sri2 + print "allocationID2", allocationID2 + self.assertEqual(sri2.streamID, allocationID2,"SRI 2 Did not MAtch") + self.assertAlmostEqual(sri2.xdelta, 1.0/5.0e6,5) + + #Check Tuner 1 Data + data= sink.getData() + self.assertTrue(len(data)>0) + + #Check Tuner 2 Data + data2= sink2.getData() + self.assertTrue(len(data2)>0) + + #Deallocate Tuners + self.comp.deallocateCapacity(alloc) + self.comp.deallocateCapacity(alloc2) + time.sleep(1) + + #Check that they sent EOS + self.assertTrue(sink.eos()) + self.assertTrue(sink2.eos()) + + def testValidRFInfoPacket(self): + + #Create Allocation and Sink for Tuner 1 + sink = sb.DataSink() + alloc = self._generateAlloc(cf=110e6,sr=2.5e6,bw=2e6,rf_flow_id="testRFInfoPacket_FlowID") + allocationID = properties.props_to_dict(alloc)['FRONTEND::tuner_allocation']['FRONTEND::tuner_allocation::allocation_id'] + self.comp.connect(sink,connectionId=allocationID) + sink.start() + + #Send an RF Info Packet + rfInfo_port = self.comp.getPort("RFInfo_in") + rf_info_pkt = self._generateRFInfoPkt(rf_freq=100e6,rf_bw=100e6,if_freq=0,rf_flow_id="testRFInfoPacket_FlowID") + rfInfo_port._set_rfinfo_pkt(rf_info_pkt) + + + #Allocate a Tuner + try: + retval = self.comp.allocateCapacity(alloc) + except Exception, e: + self.assertFalse("Exception thrown on allocateCapactiy %s" % str(e)) + if not retval: + self.assertFalse("Allocation Failed") + + self.comp.deallocateCapacity(alloc) + + def testInValidRFInfoPacket(self): + + #Create Allocation and Sink for Tuner 1 + sink = sb.DataSink() + alloc = self._generateAlloc(cf=110e6,sr=2.5e6,bw=2e6,rf_flow_id="invalid_FlowID") + allocationID = properties.props_to_dict(alloc)['FRONTEND::tuner_allocation']['FRONTEND::tuner_allocation::allocation_id'] + self.comp.connect(sink,connectionId=allocationID) + sink.start() + + #Send an RF Info Packet + rfInfo_port = self.comp.getPort("RFInfo_in") + rf_info_pkt = self._generateRFInfoPkt(rf_freq=100e6,rf_bw=100e6,if_freq=0,rf_flow_id="testRFInfoPacket_FlowID") + rfInfo_port._set_rfinfo_pkt(rf_info_pkt) + + + #Allocate a Tuner + try: + retval = self.comp.allocateCapacity(alloc) + except Exception, e: + self.assertFalse("Exception thrown on allocateCapactiy %s" % str(e)) + if retval: + self.assertFalse("Allocation Succeeded but should have failed") + + try: + self.comp.deallocateCapacity(alloc) + except CF.Device.InvalidCapacity, e: + # Deallocating shouldn't be required if the allocation failed so we would expect this deallocation to be invalid + pass + + def testValidRFInfoFreq(self): + """ Ask for a Allocation outside the range of the REceiver but should still work because the RFInfo packet tells the receiver a frequency down conversation has already occured""" + + #Create Allocation and Sink for Tuner 1 + sink = sb.DataSink() + alloc = self._generateAlloc(cf=9001e6,sr=2.5e6,bw=2e6,rf_flow_id="testRFInfoPacket_FlowID") + allocationID = properties.props_to_dict(alloc)['FRONTEND::tuner_allocation']['FRONTEND::tuner_allocation::allocation_id'] + self.comp.connect(sink,connectionId=allocationID) + sink.start() + + #Send an RF Info Packet + rfInfo_port = self.comp.getPort("RFInfo_in") + rf_info_pkt = self._generateRFInfoPkt(rf_freq=9000e6,rf_bw=100e6,if_freq=100e6,rf_flow_id="testRFInfoPacket_FlowID") + rfInfo_port._set_rfinfo_pkt(rf_info_pkt) + + + #Allocate a Tuner + try: + retval = self.comp.allocateCapacity(alloc) + except Exception, e: + self.assertFalse("Exception thrown on allocateCapactiy %s" % str(e)) + if not retval: + self.assertFalse("Allocation Failed") + + try: + self.comp.deallocateCapacity(alloc) + except CF.Device.InvalidCapacity, e: + # Deallocating shouldn't be required if the allocation failed so we would expect this deallocation to be invalid + pass + + def testInValidRFInfoFreq(self): + """ Ask for a Allocation outside the range of the REceiver but should still work because the RFInfo packet tells the receiver a frequency down conversation has already occured""" + + #Create Allocation and Sink for Tuner 1 + sink = sb.DataSink() + alloc = self._generateAlloc(cf=100e6,sr=2.5e6,bw=2e6,rf_flow_id="testRFInfoPacket_FlowID") + allocationID = properties.props_to_dict(alloc)['FRONTEND::tuner_allocation']['FRONTEND::tuner_allocation::allocation_id'] + self.comp.connect(sink,connectionId=allocationID) + sink.start() + + #Send an RF Info Packet + rfInfo_port = self.comp.getPort("RFInfo_in") + rf_info_pkt = self._generateRFInfoPkt(rf_freq=9000e6,rf_bw=100e6,if_freq=100e6,rf_flow_id="testRFInfoPacket_FlowID") + rfInfo_port._set_rfinfo_pkt(rf_info_pkt) + + + #Allocate a Tuner + try: + retval = self.comp.allocateCapacity(alloc) + except Exception, e: + self.assertFalse("Exception thrown on allocateCapactiy %s" % str(e)) + if retval: + self.assertFalse("Allocation Succeeded but should have failed") + + try: + self.comp.deallocateCapacity(alloc) + except CF.Device.InvalidCapacity, e: + # Deallocating shouldn't be required if the allocation failed so we would expect this deallocation to be invalid + pass + + def testInValidRFInfoBW(self): + """ Ask for a Allocation outside the range of the REceiver but should still work because the RFInfo packet tells the receiver a frequency down conversation has already occured""" + + #Create Allocation and Sink for Tuner 1 + sink = sb.DataSink() + alloc = self._generateAlloc(cf=9049.1e6,sr=0,bw=2e6,rf_flow_id="testRFInfoPacket_FlowID") + allocationID = properties.props_to_dict(alloc)['FRONTEND::tuner_allocation']['FRONTEND::tuner_allocation::allocation_id'] + self.comp.connect(sink,connectionId=allocationID) + sink.start() + + #Send an RF Info Packet + rfInfo_port = self.comp.getPort("RFInfo_in") + rf_info_pkt = self._generateRFInfoPkt(rf_freq=9000e6,rf_bw=100e6,if_freq=100e6,rf_flow_id="testRFInfoPacket_FlowID") + rfInfo_port._set_rfinfo_pkt(rf_info_pkt) + + + #Allocate a Tuner + try: + retval = self.comp.allocateCapacity(alloc) + except Exception, e: + self.assertFalse("Exception thrown on allocateCapactiy %s" % str(e)) + if retval: + self.assertFalse("Allocation Succeeded but should have failed") + + try: + self.comp.deallocateCapacity(alloc) + except CF.Device.InvalidCapacity, e: + # Deallocating shouldn't be required if the allocation failed so we would expect this deallocation to be invalid + pass + + def testInValidRFInfoSR(self): + """ Ask for a Allocation outside the range of the REceiver but should still work because the RFInfo packet tells the receiver a frequency down conversation has already occured""" + + #Create Allocation and Sink for Tuner 1 + sink = sb.DataSink() + alloc = self._generateAlloc(cf=9049.1e6,sr=2.5e6,bw=0,rf_flow_id="testRFInfoPacket_FlowID") + allocationID = properties.props_to_dict(alloc)['FRONTEND::tuner_allocation']['FRONTEND::tuner_allocation::allocation_id'] + self.comp.connect(sink,connectionId=allocationID) + sink.start() + + #Send an RF Info Packet + rfInfo_port = self.comp.getPort("RFInfo_in") + rf_info_pkt = self._generateRFInfoPkt(rf_freq=9000e6,rf_bw=100e6,if_freq=100e6,rf_flow_id="testRFInfoPacket_FlowID") + rfInfo_port._set_rfinfo_pkt(rf_info_pkt) + + + #Allocate a Tuner + try: + retval = self.comp.allocateCapacity(alloc) + except Exception, e: + self.assertFalse("Exception thrown on allocateCapactiy %s" % str(e)) + if retval: + self.assertFalse("Allocation Succeeded but should have failed") + + try: + self.comp.deallocateCapacity(alloc) + except CF.Device.InvalidCapacity, e: + # Deallocating shouldn't be required if the allocation failed so we would expect this deallocation to be invalid + pass + + def testInvalidAllocation(self): + alloc = self._generateAlloc(cf=110e6,sr=2.5e6,bw=2e6) + retval = self.comp.allocateCapacity(alloc) + self.assertRaises(CF.Device.InvalidCapacity, self.comp.allocateCapacity,alloc) + + def _generateAlloc(self,cf=100e6,sr=25e6,bw=20e6,rf_flow_id=''): + + value = {} + value['ALLOC_ID'] = str(uuid.uuid4()) + value['TYPE'] = 'RX_DIGITIZER' + value['BW_TOLERANCE'] = 100.0 + value['SR_TOLERANCE'] = 100.0 + value['RF_FLOW_ID'] = rf_flow_id + value['GROUP_ID'] = '' + value['CONTROL'] = True + value['CF'] = cf + value['SR'] = sr + value['BW'] = bw + + #generate the allocation + allocationPropDict = {'FRONTEND::tuner_allocation':{ + 'FRONTEND::tuner_allocation::tuner_type': value['TYPE'], + 'FRONTEND::tuner_allocation::allocation_id': value['ALLOC_ID'], + 'FRONTEND::tuner_allocation::center_frequency': float(value['CF']), + 'FRONTEND::tuner_allocation::bandwidth': float(value['BW']), + 'FRONTEND::tuner_allocation::bandwidth_tolerance': float(value['BW_TOLERANCE']), + 'FRONTEND::tuner_allocation::sample_rate': float(value['SR']), + 'FRONTEND::tuner_allocation::sample_rate_tolerance': float(value['SR_TOLERANCE']), + 'FRONTEND::tuner_allocation::device_control': value['CONTROL'], + 'FRONTEND::tuner_allocation::group_id': value['GROUP_ID'], + 'FRONTEND::tuner_allocation::rf_flow_id': value['RF_FLOW_ID'], + }} + return properties.props_from_dict(allocationPropDict) + + def _generateRFInfoPkt(self,rf_freq=1e9,rf_bw=1e9,if_freq=0,spec_inverted=False,rf_flow_id="testflowID"): + antenna_info = FRONTEND.AntennaInfo("antenna_name","antenna_type","antenna.size","description") + freqRange= FRONTEND.FreqRange(0,1e12,[] ) + feed_info = FRONTEND.FeedInfo("feed_name", "polarization",freqRange) + sensor_info = FRONTEND.SensorInfo("msn_name", "collector_name", "receiver_name",antenna_info,feed_info) + delays = []; + cap = FRONTEND.RFCapabilities(freqRange,freqRange); + add_props = []; + rf_info_pkt = FRONTEND.RFInfoPkt(rf_flow_id,rf_freq, rf_bw, if_freq, spec_inverted, sensor_info, delays, cap, add_props) + + return rf_info_pkt + + +if __name__ == "__main__": + ossie.utils.testing.main() # By default tests all implementations diff --git a/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/tests/test_RX_Digitizer_Sim_FEI.py b/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/tests/test_RX_Digitizer_Sim_FEI.py new file mode 100644 index 000000000..e0075359a --- /dev/null +++ b/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/tests/test_RX_Digitizer_Sim_FEI.py @@ -0,0 +1,80 @@ +#!/usr/bin/env python + + +import sys, os +script_dir = os.path.dirname(os.path.abspath(__file__)) +project_dir = os.path.abspath(os.path.join(script_dir, '..')) +lib_dir = os.path.join(script_dir, 'fei_base') +sys.path.append(lib_dir) +import frontend_tuner_unit_test_base as fe + +''' TODO: + 1) set the desired DEBUG_LEVEL (typical values include 0, 1, 2, 3, 4 and 5) + 2) set DUT correctly to specify the USRP under test + 3) set IMPL_ID to the implementation that should be tested. + 4) Optional: set dut_execparams if it is necessary to specify a particular + USRP. Default behavior is to target the first device of the type specified. + 5) Optional: set dut_capabilities to reflect the hardware capabilities of + the dut if different from what is provided below. +''' + +DEBUG_LEVEL = 4 +dut_name = 'RX_Digitizer_Sim' +IMPL_ID = 'python' +dut_execparams = {} +dut_configure = {} +dut_capabilities = {'RX_DIGITIZER':{'COMPLEX': True, + 'CF_MAX': 3000e6, + 'CF_MIN': 50e6, + 'BW_MAX': 8000000.0, + 'BW_MIN': 2000000.0, + 'SR_MAX': 10000000.0, + 'SR_MIN': 2500000.0, + 'GAIN_MIN' :0, + 'GAIN_MAX' :10}} + + + +DEVICE_INFO = {} +DEVICE_INFO[dut_name] = dut_capabilities +DEVICE_INFO[dut_name]['SPD'] = os.path.join(project_dir, 'RX_Digitizer_Sim.spd.xml') +DEVICE_INFO[dut_name]['execparams'] = dut_execparams +DEVICE_INFO[dut_name]['configure'] = dut_configure +#******* DO NOT MODIFY ABOVE **********# + + + +class FrontendTunerTests(fe.FrontendTunerTests): + + def __init__(self,*args,**kwargs): + import ossie.utils.testing + super(FrontendTunerTests,self).__init__(*args,**kwargs) + fe.set_debug_level(DEBUG_LEVEL) + fe.set_device_info(DEVICE_INFO[dut_name]) + fe.set_impl_id(IMPL_ID) + + # Use functions below to add pre-/post-launch commands if your device has special startup requirements + @classmethod + def devicePreLaunch(self): + pass + @classmethod + def devicePostLaunch(self): + pass + + # Use functions below to add pre-/post-release commands if your device has special shutdown requirements + @classmethod + def devicePreRelease(self): + pass + @classmethod + def devicePostRelease(self): + pass + + +if __name__ == '__main__': + fe.set_debug_level(DEBUG_LEVEL) + fe.set_device_info(DEVICE_INFO[dut_name]) + fe.set_impl_id(IMPL_ID) + + # run using nose + import nose + nose.main(defaultTest=__name__) diff --git a/frontendInterfaces/libsrc/python/tuner_device.py b/frontendInterfaces/libsrc/python/tuner_device.py index 635f77f5b..fe2bc4591 100644 --- a/frontendInterfaces/libsrc/python/tuner_device.py +++ b/frontendInterfaces/libsrc/python/tuner_device.py @@ -27,6 +27,7 @@ from ossie.properties import simple_property from ossie.properties import struct_property from ossie.properties import structseq_property +from ossie.properties import struct_to_props from ossie.utils import model import threading @@ -603,12 +604,12 @@ def allocate_frontend_tuner_allocation(self, frontend_tuner_allocation): # Check allocation_id if not frontend_tuner_allocation.allocation_id: self._log.info("allocate_frontend_tuner_allocation: MISSING ALLOCATION_ID") - raise CF.Device.InvalidCapacity("MISSING ALLOCATION_ID", frontend_tuner_allocation) + raise CF.Device.InvalidCapacity("MISSING ALLOCATION_ID", struct_to_props(frontend_tuner_allocation)) # Check if allocation ID has already been used if self.getTunerMapping(frontend_tuner_allocation.allocation_id) >= 0: self._log.info("allocate_frontend_tuner_allocation: ALLOCATION_ID "+frontend_tuner_allocation.allocation_id+" ALREADY IN USE") - raise CF.Device.InvalidCapacity("ALLOCATION_ID "+frontend_tuner_allocation.allocation_id+" ALREADY IN USE", frontend_tuner_allocation) + raise CF.Device.InvalidCapacity("ALLOCATION_ID "+frontend_tuner_allocation.allocation_id+" ALREADY IN USE", struct_to_props(frontend_tuner_allocation)) self.allocation_id_mapping_lock.acquire() # Next, try to allocate a new tuner @@ -661,7 +662,7 @@ def allocate_frontend_tuner_allocation(self, frontend_tuner_allocation): if frontend_tuner_allocation.tuner_type == "CHANNELIZER" or frontend_tuner_allocation.tuner_type == "TX": eout = str(frontend_tuner_allocation.tuner_type) + " allocation with device_control=false is invalid." self._log.debug(eout) - raise CF.Device.InvalidCapacity(eout, frontend_tuner_allocation) + raise CF.Device.InvalidCapacity(eout, struct_to_props(frontend_tuner_allocation)) # listener if len(self.tuner_allocation_ids[tuner_id].control_allocation_id) == 0 or not listenerRequestValidation(frontend_tuner_allocation, tuner_id): # either not allocated or can't support listener request @@ -741,7 +742,7 @@ def deallocate_frontend_tuner_allocation(self, frontend_tuner_allocation): tuner_id = self.getTunerMapping(frontend_tuner_allocation.allocation_id) if tuner_id < 0: self._log.debug("deallocate_frontend_tuner_allocation: ALLOCATION_ID NOT FOUND: [" + str(frontend_tuner_allocation.allocation_id) + "]") - raise CF.Device.InvalidCapacity("ALLOCATION_ID NOT FOUND: [" + str(frontend_tuner_allocation.allocation_id) + "]",frontend_tuner_allocation) + raise CF.Device.InvalidCapacity("ALLOCATION_ID NOT FOUND: [" + str(frontend_tuner_allocation.allocation_id) + "]",struct_to_props(frontend_tuner_allocation)) self.allocation_id_mapping_lock.acquire() try: @@ -777,16 +778,16 @@ def allocate_frontend_listener_allocation(self, frontend_listener_allocation): # Check validity of allocation_id's if not frontend_listener_allocation.existing_allocation_id: self._log.info("allocate_frontend_listener_allocation: MISSING EXISTING ALLOCATION ID") - raise CF.Device.InvalidCapacity("MISSING EXISTING ALLOCATION ID", frontend_listener_allocation) + raise CF.Device.InvalidCapacity("MISSING EXISTING ALLOCATION ID", struct_to_props(frontend_listener_allocation)) if not frontend_listener_allocation.listener_allocation_id: self._log.info("allocate_frontend_listener_allocation: MISSING LISTENER ALLOCATION ID") - raise CF.Device.InvalidCapacity("MISSING LISTENER ALLOCATION ID", frontend_listener_allocation) + raise CF.Device.InvalidCapacity("MISSING LISTENER ALLOCATION ID", struct_to_props(frontend_listener_allocation)) # Check if listener allocation ID has already been used if self.getTunerMapping(frontend_listener_allocation.listener_allocation_id) >= 0: self._log.info("allocate_frontend_listener_allocation: LISTENER ALLOCATION ID ALREADY IN USE") - raise CF.Device.InvalidCapacity("LISTENER ALLOCATION ID ALREADY IN USE", frontend_listener_allocation) + raise CF.Device.InvalidCapacity("LISTENER ALLOCATION ID ALREADY IN USE", struct_to_props(frontend_listener_allocation)) #self.tuner_allocation_ids[tuner_id].lock.acquire() # Check if listener allocation ID has already been used @@ -804,7 +805,7 @@ def allocate_frontend_listener_allocation(self, frontend_listener_allocation): if self.frontend_tuner_status[tuner_id].tuner_type == "CHANNELIZER" or self.frontend_tuner_status[tuner_id].tuner_type == "TX": eout = "allocate_frontend_listener_allocation: listener allocations are not permitted for " + str(self.frontend_tuner_status[tuner_id].tuner_type) + " tuner type" self._log.debug(eout) - raise CF.Device.InvalidCapacity(eout, frontend_listener_allocation) + raise CF.Device.InvalidCapacity(eout, struct_to_props(frontend_listener_allocation)) self.allocation_id_mapping_lock.acquire() try: diff --git a/redhawk/src/base/framework/python/setup.py b/redhawk/src/base/framework/python/setup.py index 2cceafd7f..d99d31d17 100644 --- a/redhawk/src/base/framework/python/setup.py +++ b/redhawk/src/base/framework/python/setup.py @@ -76,6 +76,7 @@ 'ossie/utils/tools', 'ossie/utils/rhtime', 'ossie/utils/rhconnection', + 'ossie/utils/allocations', 'redhawk'] exec(open('ossie/version.py').read()) From b6844c85d606e17a4fb60df05cdfe4c69b7a990a Mon Sep 17 00:00:00 2001 From: Max Robert Date: Tue, 14 Feb 2017 14:02:18 -0500 Subject: [PATCH 0698/1644] Refs CF-1672. Add object reference for call on listenerRequestValidation --- .../tests/test_RX_Digitizer_Sim.py | 8 ++++++ .../libsrc/python/tuner_device.py | 26 ++++++++++++++----- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/tests/test_RX_Digitizer_Sim.py b/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/tests/test_RX_Digitizer_Sim.py index 4bcc95c89..337d37cfb 100644 --- a/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/tests/test_RX_Digitizer_Sim.py +++ b/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/tests/test_RX_Digitizer_Sim.py @@ -350,6 +350,14 @@ def testInvalidAllocation(self): retval = self.comp.allocateCapacity(alloc) self.assertRaises(CF.Device.InvalidCapacity, self.comp.allocateCapacity,alloc) + def testFalseControl(self): + alloc = self._generateAlloc(cf=110e6,sr=2.5e6,bw=2e6) + for _prop in alloc[0].value._v: + if _prop.id == 'FRONTEND::tuner_allocation::device_control': + _prop.value._v = False + retval = self.comp.allocateCapacity(alloc) + self.comp.deallocateCapacity(alloc) + def _generateAlloc(self,cf=100e6,sr=25e6,bw=20e6,rf_flow_id=''): value = {} diff --git a/frontendInterfaces/libsrc/python/tuner_device.py b/frontendInterfaces/libsrc/python/tuner_device.py index fe2bc4591..d844a9694 100644 --- a/frontendInterfaces/libsrc/python/tuner_device.py +++ b/frontendInterfaces/libsrc/python/tuner_device.py @@ -605,7 +605,7 @@ def allocate_frontend_tuner_allocation(self, frontend_tuner_allocation): if not frontend_tuner_allocation.allocation_id: self._log.info("allocate_frontend_tuner_allocation: MISSING ALLOCATION_ID") raise CF.Device.InvalidCapacity("MISSING ALLOCATION_ID", struct_to_props(frontend_tuner_allocation)) - + # Check if allocation ID has already been used if self.getTunerMapping(frontend_tuner_allocation.allocation_id) >= 0: self._log.info("allocate_frontend_tuner_allocation: ALLOCATION_ID "+frontend_tuner_allocation.allocation_id+" ALREADY IN USE") @@ -653,7 +653,7 @@ def allocate_frontend_tuner_allocation(self, frontend_tuner_allocation): self.frontend_tuner_status[tuner_id].center_frequency = frontend_tuner_allocation.center_frequency self.frontend_tuner_status[tuner_id].bandwidth = frontend_tuner_allocation.bandwidth self.frontend_tuner_status[tuner_id].sample_rate = frontend_tuner_allocation.sample_rate - + self.tuner_allocation_ids[tuner_id].control_allocation_id = frontend_tuner_allocation.allocation_id self.allocation_id_to_tuner_id[frontend_tuner_allocation.allocation_id] = tuner_id self.frontend_tuner_status[tuner_id].allocation_id_csv = self.createAllocationIdCsv(tuner_id) @@ -664,11 +664,12 @@ def allocate_frontend_tuner_allocation(self, frontend_tuner_allocation): self._log.debug(eout) raise CF.Device.InvalidCapacity(eout, struct_to_props(frontend_tuner_allocation)) # listener - if len(self.tuner_allocation_ids[tuner_id].control_allocation_id) == 0 or not listenerRequestValidation(frontend_tuner_allocation, tuner_id): + if len(self.tuner_allocation_ids[tuner_id].control_allocation_id) == 0 or not self.listenerRequestValidation(frontend_tuner_allocation, tuner_id): # either not allocated or can't support listener request self._log.debug("allocate_frontend_tuner_allocation: Tuner["+str(tuner_id)+"] is either not available or can not support listener request ") continue self.tuner_allocation_ids[tuner_id].listener_allocation_ids.append(frontend_tuner_allocation.allocation_id) + self.allocation_id_to_tuner_id[frontend_tuner_allocation.allocation_id] = tuner_id self.frontend_tuner_status[tuner_id].allocation_id_csv = self.createAllocationIdCsv(tuner_id) self.assignListener(frontend_tuner_allocation.allocation_id,self.tuner_allocation_ids[tuner_id].control_allocation_id) @@ -746,15 +747,27 @@ def deallocate_frontend_tuner_allocation(self, frontend_tuner_allocation): self.allocation_id_mapping_lock.acquire() try: - while self.frontend_tuner_status[self.allocation_id_to_tuner_id[frontend_tuner_allocation.allocation_id]].allocation_id_csv != frontend_tuner_allocation.allocation_id: + if self.frontend_tuner_status[self.allocation_id_to_tuner_id[frontend_tuner_allocation.allocation_id]].allocation_id_csv.split(',')[0] == frontend_tuner_allocation.allocation_id: + # remove if it is controlling + while self.frontend_tuner_status[self.allocation_id_to_tuner_id[frontend_tuner_allocation.allocation_id]].allocation_id_csv != frontend_tuner_allocation.allocation_id: + split_id = self.frontend_tuner_status[self.allocation_id_to_tuner_id[frontend_tuner_allocation.allocation_id]].allocation_id_csv.split(',') + for idx in range(len(split_id)): + if split_id[idx] == frontend_tuner_allocation.allocation_id: + continue + else: + self.removeTunerMappingByAllocationId(split_id[idx]) + self.removeListenerId(tuner_id, split_id[idx]) + break + else: + # remove if it is not controlling split_id = self.frontend_tuner_status[self.allocation_id_to_tuner_id[frontend_tuner_allocation.allocation_id]].allocation_id_csv.split(',') for idx in range(len(split_id)): - if split_id[idx] == frontend_tuner_allocation.allocation_id: + if split_id[idx] != frontend_tuner_allocation.allocation_id: continue else: self.removeTunerMappingByAllocationId(split_id[idx]) self.removeListenerId(tuner_id, split_id[idx]) - break + return finally: self.allocation_id_mapping_lock.release() @@ -921,6 +934,7 @@ def listenerRequestValidation(self, request, tuner_id): def getTunerMapping(self, _allocation_id): NO_VALID_TUNER = -1 + print 'self.allocation_id_to_tuner_id:',self.allocation_id_to_tuner_id self.allocation_id_mapping_lock.acquire() try: for key in self.allocation_id_to_tuner_id: From e6bec787e9ade86839bcc147c812d01e53037457 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Tue, 14 Feb 2017 14:05:59 -0500 Subject: [PATCH 0699/1644] Refs CF-1672 and CF-1673. Added tests for listener allocation/deallocation --- .../RX_Digitizer_Sim/python/RX_Digitizer_Sim.py | 1 - .../tests/test_RX_Digitizer_Sim.py | 16 ++++++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/python/RX_Digitizer_Sim.py b/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/python/RX_Digitizer_Sim.py index 870cba2bf..a334feff2 100755 --- a/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/python/RX_Digitizer_Sim.py +++ b/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/python/RX_Digitizer_Sim.py @@ -169,7 +169,6 @@ def deviceDeleteTuning(self, fts, tuner_id): self._log.debug( "deviceDeleteTuning(): Deallocate an allocated tuner *********") self.datagenerators[tuner_id].stop() - print dir(fts) controlAllocationID = fts.allocation_id_csv.split(',')[0] self.removeStreamIdRouting(controlAllocationID, controlAllocationID) return True diff --git a/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/tests/test_RX_Digitizer_Sim.py b/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/tests/test_RX_Digitizer_Sim.py index 337d37cfb..1bbd5b5bf 100644 --- a/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/tests/test_RX_Digitizer_Sim.py +++ b/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/tests/test_RX_Digitizer_Sim.py @@ -11,6 +11,7 @@ from ossie import properties import time from ossie.utils.bluefile.bluefile_helpers import sri_to_hdr +import frontend DEBUG_LEVEL = 2 @@ -351,11 +352,18 @@ def testInvalidAllocation(self): self.assertRaises(CF.Device.InvalidCapacity, self.comp.allocateCapacity,alloc) def testFalseControl(self): - alloc = self._generateAlloc(cf=110e6,sr=2.5e6,bw=2e6) - for _prop in alloc[0].value._v: - if _prop.id == 'FRONTEND::tuner_allocation::device_control': - _prop.value._v = False + center_frequency = 110e6 + sample_rate = 2.5e6 + bandwidth = 2e6 + alloc = self._generateAlloc(cf=center_frequency,sr=sample_rate,bw=2e6) retval = self.comp.allocateCapacity(alloc) + self.assertEquals(retval, True) + _type = properties.props_to_dict(alloc)['FRONTEND::tuner_allocation']['FRONTEND::tuner_allocation::tuner_type'] + _alloc_id = properties.props_to_dict(alloc)['FRONTEND::tuner_allocation']['FRONTEND::tuner_allocation::allocation_id'] + listen_alloc = [frontend.createTunerGenericListenerAllocation(_type, allocation_id='foo', center_frequency=center_frequency, bandwidth=bandwidth, sample_rate=sample_rate,returnDict=False)] + retval = self.comp.allocateCapacity(listen_alloc) + self.assertEquals(retval, True) + self.comp.deallocateCapacity(listen_alloc) self.comp.deallocateCapacity(alloc) def _generateAlloc(self,cf=100e6,sr=25e6,bw=20e6,rf_flow_id=''): From 8c87749cb9e860563890b8ee4a1c2b6280d0ceeb Mon Sep 17 00:00:00 2001 From: Max Robert Date: Tue, 14 Feb 2017 14:33:03 -0500 Subject: [PATCH 0700/1644] Refs CF-1666. Use correct port name in matchAllocationIdToStreamId when the given port value is an empty string --- .../jinja/python/component/frontend/templates/resource_base.py | 2 +- redhawk-codegen/redhawk/codegen/jinja/python/ports/mapping.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/redhawk-codegen/redhawk/codegen/jinja/python/component/frontend/templates/resource_base.py b/redhawk-codegen/redhawk/codegen/jinja/python/component/frontend/templates/resource_base.py index dcfe9213a..94e7120be 100644 --- a/redhawk-codegen/redhawk/codegen/jinja/python/component/frontend/templates/resource_base.py +++ b/redhawk-codegen/redhawk/codegen/jinja/python/component/frontend/templates/resource_base.py @@ -164,7 +164,7 @@ def matchAllocationIdToStreamId(self,allocation_id, stream_id, port_name): tmp = bulkio.connection_descriptor_struct() #{% for port in component.ports if port.multiout %} tmp.connection_id = allocation_id - tmp.port_name = "${port.pyname}" + tmp.port_name = "${port.portname}" tmp.stream_id = stream_id self.connectionTable.append(tmp) #{% endfor %} diff --git a/redhawk-codegen/redhawk/codegen/jinja/python/ports/mapping.py b/redhawk-codegen/redhawk/codegen/jinja/python/ports/mapping.py index b73ae8dd3..155f91fd3 100644 --- a/redhawk-codegen/redhawk/codegen/jinja/python/ports/mapping.py +++ b/redhawk-codegen/redhawk/codegen/jinja/python/ports/mapping.py @@ -26,6 +26,7 @@ class PythonPortMapper(PortMapper): def _mapPort(self, port, generator): pyport = {} pyport['pyname'] = python.identifier('port_'+port.name()) + pyport['portname'] = python.identifier(port.name()) pyport['constructor'] = generator.constructor(port) pyport['multiout'] = generator.supportsMultiOut() return pyport From 4981fa2cd3a443135bdc9f5f601ecc98afb60543 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Tue, 14 Feb 2017 15:19:32 -0500 Subject: [PATCH 0701/1644] Refs CF-1668. Do not hide user errors when tuning or enabling the tuner --- .../python/RX_Digitizer_Sim.py | 6 +++- .../tests/test_RX_Digitizer_Sim.py | 6 +++- frontendInterfaces/libsrc/python/fe_types.py | 3 ++ .../libsrc/python/tuner_device.py | 32 +++++++++---------- 4 files changed, 28 insertions(+), 19 deletions(-) diff --git a/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/python/RX_Digitizer_Sim.py b/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/python/RX_Digitizer_Sim.py index a334feff2..1c2b119e1 100755 --- a/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/python/RX_Digitizer_Sim.py +++ b/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/python/RX_Digitizer_Sim.py @@ -54,7 +54,6 @@ def constructor(self): datagenerator.keyword_dict['FRONTEND::DEVICE_ID'] = self._get_identifier() datagenerator.keyword_dict['FRONTEND::RF_FLOW_ID'] = self.rfinfo.rf_flow_id datagenerator.waveform_type = "Sine" - def process(self): # TODO fill in your code here @@ -80,6 +79,8 @@ def deviceEnable(self, fts, tuner_id): self._log.exception("Got exception % s" %str(e)) return False + #print self.getTunerStatus(fts.allocation_id_csv) + return True def deviceDisable(self,fts, tuner_id): @@ -113,6 +114,9 @@ def deviceSetTuning(self,request, fts, tuner_id): self._log.debug( "allocating tuner_id %s" % tuner_id) + if fts.center_frequency == 111e6: + raise Exception('bad center frequency') + # Check that allocation can be satisfied if self.rfinfo.rf_flow_id !="": try: diff --git a/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/tests/test_RX_Digitizer_Sim.py b/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/tests/test_RX_Digitizer_Sim.py index 1bbd5b5bf..64b9aec24 100644 --- a/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/tests/test_RX_Digitizer_Sim.py +++ b/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/tests/test_RX_Digitizer_Sim.py @@ -351,11 +351,15 @@ def testInvalidAllocation(self): retval = self.comp.allocateCapacity(alloc) self.assertRaises(CF.Device.InvalidCapacity, self.comp.allocateCapacity,alloc) + def testTuningException(self): + alloc = self._generateAlloc(cf=111e6,sr=2.5e6,bw=2e6) + self.assertEquals(self.comp.allocateCapacity(alloc), False) + def testFalseControl(self): center_frequency = 110e6 sample_rate = 2.5e6 bandwidth = 2e6 - alloc = self._generateAlloc(cf=center_frequency,sr=sample_rate,bw=2e6) + alloc = self._generateAlloc(cf=center_frequency,sr=sample_rate,bw=bandwidth) retval = self.comp.allocateCapacity(alloc) self.assertEquals(retval, True) _type = properties.props_to_dict(alloc)['FRONTEND::tuner_allocation']['FRONTEND::tuner_allocation::tuner_type'] diff --git a/frontendInterfaces/libsrc/python/fe_types.py b/frontendInterfaces/libsrc/python/fe_types.py index dd7f20052..e9de590c8 100644 --- a/frontendInterfaces/libsrc/python/fe_types.py +++ b/frontendInterfaces/libsrc/python/fe_types.py @@ -28,6 +28,9 @@ J1970 = 2 JCY = 3 +class allocationException(Exception): + pass + class tuner_allocation_ids_struct(object): def __init__(self): self.reset() diff --git a/frontendInterfaces/libsrc/python/tuner_device.py b/frontendInterfaces/libsrc/python/tuner_device.py index d844a9694..997a6b0e3 100644 --- a/frontendInterfaces/libsrc/python/tuner_device.py +++ b/frontendInterfaces/libsrc/python/tuner_device.py @@ -600,6 +600,7 @@ def setNumChannels(self,num,tuner_type='RX_DIGITIZER'): """ Allocation handlers """ def allocate_frontend_tuner_allocation(self, frontend_tuner_allocation): + exception_raised = False try: # Check allocation_id if not frontend_tuner_allocation.allocation_id: @@ -683,7 +684,7 @@ def allocate_frontend_tuner_allocation(self, frontend_tuner_allocation): floatingPointCompare(self.frontend_tuner_status[tuner_id].sample_rate,frontend_tuner_allocation.sample_rate+frontend_tuner_allocation.sample_rate * frontend_tuner_allocation.sample_rate_tolerance/100.0)>0 ): eout = "allocate_frontend_tuner_allocation(" + str(int(tuner_id)) +"): returned sr "+str(self.frontend_tuner_status[tuner_id].sample_rate)+" does not meet tolerance criteria of "+str(frontend_tuner_allocation.sample_rate_tolerance)+" percent" self._log.info(eout) - raise RuntimeError(eout) + raise allocationException(eout) self._log.debug(" allocate_frontend_tuner_allocation - BW requested: " + str(frontend_tuner_allocation.bandwidth) + " BW got: " +str(self.frontend_tuner_status[tuner_id].bandwidth)) # Only check when bandwidth was not set to don't care @@ -692,31 +693,29 @@ def allocate_frontend_tuner_allocation(self, frontend_tuner_allocation): floatingPointCompare(self.frontend_tuner_status[tuner_id].bandwidth,frontend_tuner_allocation.bandwidth+frontend_tuner_allocation.bandwidth * frontend_tuner_allocation.bandwidth_tolerance/100.0)>0 ): eout = "allocate_frontend_tuner_allocation("<= 0: + self.deallocate_frontend_tuner_allocation(frontend_tuner_allocation) return False except AllocationAlreadyExists, e: @@ -732,7 +731,7 @@ def allocate_frontend_tuner_allocation(self, frontend_tuner_allocation): return False except Exception, e: - self._log.info('The following error occurred on allocation:',e) + self._log.exception('The following error occurred on allocation:',e) #self.deallocateCapacity([frontend_tuner_allocation.getProp()]) raise e @@ -934,7 +933,6 @@ def listenerRequestValidation(self, request, tuner_id): def getTunerMapping(self, _allocation_id): NO_VALID_TUNER = -1 - print 'self.allocation_id_to_tuner_id:',self.allocation_id_to_tuner_id self.allocation_id_mapping_lock.acquire() try: for key in self.allocation_id_to_tuner_id: From b37d03ad68afd010c4e1453e3dc306d48f4c8c8c Mon Sep 17 00:00:00 2001 From: Max Robert Date: Tue, 14 Feb 2017 15:30:33 -0500 Subject: [PATCH 0702/1644] Refs CF-1684. Fix return value in getTunerStatus --- .../dev/devices/RX_Digitizer_Sim/python/RX_Digitizer_Sim.py | 5 +++-- .../devices/RX_Digitizer_Sim/tests/test_RX_Digitizer_Sim.py | 4 ++++ .../python/component/frontend/templates/resource_base.py | 3 ++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/python/RX_Digitizer_Sim.py b/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/python/RX_Digitizer_Sim.py index 1c2b119e1..0a167c020 100755 --- a/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/python/RX_Digitizer_Sim.py +++ b/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/python/RX_Digitizer_Sim.py @@ -78,8 +78,9 @@ def deviceEnable(self, fts, tuner_id): except Exception, e: self._log.exception("Got exception % s" %str(e)) return False - - #print self.getTunerStatus(fts.allocation_id_csv) + + if fts.center_frequency == 112e6: + print self.getTunerStatus(fts.allocation_id_csv) return True diff --git a/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/tests/test_RX_Digitizer_Sim.py b/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/tests/test_RX_Digitizer_Sim.py index 64b9aec24..00f86bcec 100644 --- a/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/tests/test_RX_Digitizer_Sim.py +++ b/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/tests/test_RX_Digitizer_Sim.py @@ -355,6 +355,10 @@ def testTuningException(self): alloc = self._generateAlloc(cf=111e6,sr=2.5e6,bw=2e6) self.assertEquals(self.comp.allocateCapacity(alloc), False) + def testBasicOkAllocation(self): + alloc = self._generateAlloc(cf=112e6,sr=2.5e6,bw=2e6) + self.assertEquals(self.comp.allocateCapacity(alloc), True) + def testFalseControl(self): center_frequency = 110e6 sample_rate = 2.5e6 diff --git a/redhawk-codegen/redhawk/codegen/jinja/python/component/frontend/templates/resource_base.py b/redhawk-codegen/redhawk/codegen/jinja/python/component/frontend/templates/resource_base.py index 94e7120be..293bf0118 100644 --- a/redhawk-codegen/redhawk/codegen/jinja/python/component/frontend/templates/resource_base.py +++ b/redhawk-codegen/redhawk/codegen/jinja/python/component/frontend/templates/resource_base.py @@ -22,6 +22,7 @@ import frontend #{% if 'FrontendTuner' in component.implements %} from frontend import FRONTEND +from ossie.properties import struct_to_props BOOLEAN_VALUE_HERE=False #{% endif %} #{% endblock %} @@ -40,7 +41,7 @@ def getTunerStatus(self,allocation_id): tuner_id = self.getTunerMapping(allocation_id) if tuner_id < 0: raise FRONTEND.FrontendException(("ERROR: ID: " + str(allocation_id) + " IS NOT ASSOCIATED WITH ANY TUNER!")) - return [CF.DataType(id=self.frontend_tuner_status[tuner_id].getId(),value=self.frontend_tuner_status[tuner_id]._toAny())] + return struct_to_props(self.frontend_tuner_status[tuner_id]) def assignListener(self,listen_alloc_id, allocation_id): # find control allocation_id From e8a7e431d459d0ca036d7748f76d4d11dd626063 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Tue, 14 Feb 2017 15:40:52 -0500 Subject: [PATCH 0703/1644] Refs CF-1683. Fixed tuner_device typos in error messages --- .../tests/test_RX_Digitizer_Sim.py | 16 ++++++++++++++++ frontendInterfaces/libsrc/python/tuner_device.py | 14 ++++---------- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/tests/test_RX_Digitizer_Sim.py b/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/tests/test_RX_Digitizer_Sim.py index 00f86bcec..5a5fcded6 100644 --- a/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/tests/test_RX_Digitizer_Sim.py +++ b/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/tests/test_RX_Digitizer_Sim.py @@ -359,6 +359,22 @@ def testBasicOkAllocation(self): alloc = self._generateAlloc(cf=112e6,sr=2.5e6,bw=2e6) self.assertEquals(self.comp.allocateCapacity(alloc), True) + def testTypoErrorAllocation(self): + center_frequency = 110e6 + sample_rate = 2.5e6 + bandwidth = 2e6 + alloc = self._generateAlloc(cf=center_frequency,sr=sample_rate,bw=bandwidth) + retval = self.comp.allocateCapacity(alloc) + self.assertEquals(retval, True) + _type = properties.props_to_dict(alloc)['FRONTEND::tuner_allocation']['FRONTEND::tuner_allocation::tuner_type'] + _alloc_id = properties.props_to_dict(alloc)['FRONTEND::tuner_allocation']['FRONTEND::tuner_allocation::allocation_id'] + listen_alloc = [frontend.createTunerListenerAllocation(_alloc_id, listener_allocation_id='foo',returnDict=False)] + retval = self.comp.allocateCapacity(listen_alloc) + self.assertEquals(retval, True) + self.assertRaises(CF.Device.InvalidCapacity, self.comp.allocateCapacity, listen_alloc) + self.comp.deallocateCapacity(listen_alloc) + self.comp.deallocateCapacity(alloc) + def testFalseControl(self): center_frequency = 110e6 sample_rate = 2.5e6 diff --git a/frontendInterfaces/libsrc/python/tuner_device.py b/frontendInterfaces/libsrc/python/tuner_device.py index 997a6b0e3..0dbec7304 100644 --- a/frontendInterfaces/libsrc/python/tuner_device.py +++ b/frontendInterfaces/libsrc/python/tuner_device.py @@ -691,7 +691,7 @@ def allocate_frontend_tuner_allocation(self, frontend_tuner_allocation): if floatingPointCompare(frontend_tuner_allocation.bandwidth,0)!=0 and \ (floatingPointCompare(self.frontend_tuner_status[tuner_id].bandwidth,frontend_tuner_allocation.bandwidth)<0 or \ floatingPointCompare(self.frontend_tuner_status[tuner_id].bandwidth,frontend_tuner_allocation.bandwidth+frontend_tuner_allocation.bandwidth * frontend_tuner_allocation.bandwidth_tolerance/100.0)>0 ): - eout = "allocate_frontend_tuner_allocation("<= 0: - self._log.info("allocate_frontend_listener_allocation: LISTENER ALLOCATION ID ALREADY IN USE") - raise CF.Device.InvalidCapacity("LISTENER ALLOCATION ID ALREADY IN USE", struct_to_props(frontend_listener_allocation)) - #self.tuner_allocation_ids[tuner_id].lock.acquire() # Check if listener allocation ID has already been used if self.getTunerMapping(frontend_listener_allocation.listener_allocation_id) >= 0: - self._log.info("allocate_frontend_listener_allocation: LISTENER ALLOCATION ID ALREADY IN USE: [" + str(frontend_listener_allocation.listener_allocation_id << "]")) + self._log.info("allocate_frontend_listener_allocation: LISTENER ALLOCATION ID ALREADY IN USE: [" + str(frontend_listener_allocation.listener_allocation_id + "]")) raise AllocationAlreadyExists("LISTENER ALLOCATION ID ALREADY IN USE", frontend_listener_allocation) # Do not allocate if existing allocation ID does not exist @@ -835,7 +829,7 @@ def allocate_frontend_listener_allocation(self, frontend_listener_allocation): except AllocationAlreadyExists, e: # Don't call deallocateCapacity if the allocationId already exists # - Would end up deallocating a valid tuner/listener - raise CF.Device.InvalidCapacity(e) + raise CF.Device.InvalidCapacity(e.message, struct_to_props(frontend_listener_allocation)) except CF.Device.InvalidCapacity, e: raise e @@ -1053,7 +1047,7 @@ def printSRI(self, sri, strHeader = "DEBUG SRI"): print "\tmode:", sri.mode print "\tstreamID:", sri.streamID for keyword in sri.keywords: - print "\t KEYWORD KEY/VAL ::", keywords.id << ":", any.from_any(keywords.value) + print "\t KEYWORD KEY/VAL ::", keywords.id + ":", any.from_any(keywords.value) ###################################################################### # PROPERTIES From decfb357465e4e91c8bb42bf940c36e5d75408f0 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Tue, 14 Feb 2017 15:56:01 -0500 Subject: [PATCH 0704/1644] Refs CF-1674. Correct sample rate logic in validateRequestVsRFInfo --- frontendInterfaces/libsrc/python/tuner_device.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/frontendInterfaces/libsrc/python/tuner_device.py b/frontendInterfaces/libsrc/python/tuner_device.py index 0dbec7304..3ac13c40c 100644 --- a/frontendInterfaces/libsrc/python/tuner_device.py +++ b/frontendInterfaces/libsrc/python/tuner_device.py @@ -227,9 +227,9 @@ def validateRequestVsRFInfo(request, rfinfo, mode): raise FRONTEND.BadParameterException("INVALID REQUEST -- analog freq range (RFinfo) cannot support freq/bw request") # check sample rate - scaling_factor = 2 - if mode == 1: - scaling_factor = 4 # adjust for complex data + scaling_factor = 4 + if mode: + scaling_factor = 2 # adjust for complex data min_requested_freq = request.center_frequency-(request.sample_rate/scaling_factor) max_requested_freq = request.center_frequency+(request.sample_rate/scaling_factor) From cbc44ce44780fe432442bc2566a05f7c39162aee Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 14 Feb 2017 15:39:43 -0500 Subject: [PATCH 0705/1644] CF-1438 Fix BulkIO input stream regression with end-of-stream and sized read --- .../libsrc/cpp/bulkio_in_stream.cpp | 5 ++++- .../libsrc/testing/tests/cpp/InStreamTest.cpp | 22 +++++++++++++++++-- .../libsrc/testing/tests/cpp/InStreamTest.h | 21 +++++++++++++++++- 3 files changed, 44 insertions(+), 4 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp index 1bd0d02bb..608f988c2 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp @@ -625,7 +625,10 @@ class BufferedInputStream::Impl : public Base::Impl { if (_queue.empty() || _canBridge(packet)) { _queuePacket(packet); - return true; + // The packet may not have actually extended the queue, if it was + // an emtpy end-of-stream packet; if the queue is empty, return + // false to indicate that the fetch effectively failed + return !_queue.empty(); } else { _pending = packet; return false; diff --git a/bulkioInterfaces/libsrc/testing/tests/cpp/InStreamTest.cpp b/bulkioInterfaces/libsrc/testing/tests/cpp/InStreamTest.cpp index 055400f17..c8ae7ae5f 100644 --- a/bulkioInterfaces/libsrc/testing/tests/cpp/InStreamTest.cpp +++ b/bulkioInterfaces/libsrc/testing/tests/cpp/InStreamTest.cpp @@ -120,10 +120,28 @@ void InStreamTest::testGetCurrentStreamDataEos() CPPUNIT_ASSERT(stream.eos()); } +template +void BufferedInStreamTest::testReadSizeEos() +{ + // Create a new stream and push an end-of-stream packet with no data + BULKIO::StreamSRI sri = bulkio::sri::create("empty_eos"); + port->pushSRI(sri); + PortSequenceType data; + data.length(0); + port->pushPacket(data, bulkio::time::utils::notSet(), true, sri.streamID); + + // Try to read a single element; this should return a null block + StreamType stream = port->getStream("empty_eos"); + CPPUNIT_ASSERT(stream); + DataBlockType block = stream.read(1); + CPPUNIT_ASSERT(!block); + CPPUNIT_ASSERT(stream.eos()); +} + #define CREATE_TEST(x) \ - class In##x##StreamTest : public InStreamTest \ + class In##x##StreamTest : public BufferedInStreamTest \ { \ - CPPUNIT_TEST_SUB_SUITE(In##x##StreamTest, InStreamTest); \ + CPPUNIT_TEST_SUB_SUITE(In##x##StreamTest, BufferedInStreamTest); \ CPPUNIT_TEST_SUITE_END(); \ virtual std::string getPortName() const { return #x; }; \ }; \ diff --git a/bulkioInterfaces/libsrc/testing/tests/cpp/InStreamTest.h b/bulkioInterfaces/libsrc/testing/tests/cpp/InStreamTest.h index df5a6aca1..2bd1ed98a 100644 --- a/bulkioInterfaces/libsrc/testing/tests/cpp/InStreamTest.h +++ b/bulkioInterfaces/libsrc/testing/tests/cpp/InStreamTest.h @@ -38,10 +38,29 @@ class InStreamTest : public CppUnit::TestFixture void testGetCurrentStreamEmptyEos(); void testGetCurrentStreamDataEos(); -private: +protected: virtual std::string getPortName() const = 0; Port* port; }; +template +class BufferedInStreamTest : public InStreamTest +{ + typedef InStreamTest TestBase; + CPPUNIT_TEST_SUB_SUITE(BufferedInStreamTest, TestBase); + CPPUNIT_TEST(testReadSizeEos); + CPPUNIT_TEST_SUITE_END(); + +public: + void testReadSizeEos(); + +private: + typedef typename Port::PortSequenceType PortSequenceType; + typedef typename Port::StreamType StreamType; + typedef typename StreamType::DataBlockType DataBlockType; + + using TestBase::port; +}; + #endif // BULKIO_INSTREAMTEST_H From a21845766adf96311d14332c8bb715284c834fe0 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Tue, 14 Feb 2017 17:13:03 -0500 Subject: [PATCH 0706/1644] Refs CF-1566. Update the minimum Java version for RH to 1.7. Also raised the minimum Java version for Java components from 1.6 to 1.7 --- redhawk-codegen/redhawk/codegen/versions.py | 2 +- redhawk/src/configure.ac | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/redhawk-codegen/redhawk/codegen/versions.py b/redhawk-codegen/redhawk/codegen/versions.py index 04d5baf27..aad9263e0 100644 --- a/redhawk-codegen/redhawk/codegen/versions.py +++ b/redhawk-codegen/redhawk/codegen/versions.py @@ -23,7 +23,7 @@ boost = '1.41' omniORB4 = '4.1.0' python = '2.4' -java = '1.6' +java = '1.7' log4j = '1.2.15' octave = '3.4.3' diff --git a/redhawk/src/configure.ac b/redhawk/src/configure.ac index 17036c44e..e0e225d0e 100644 --- a/redhawk/src/configure.ac +++ b/redhawk/src/configure.ac @@ -171,7 +171,7 @@ if test "x$enable_java" != "xno"; then RH_JAVA_HOME # Minimum Java version - java_source_version=1.8 + java_source_version=1.7 # Locate tools we need based on JAVA_HOME RH_PROG_JAVAC([$java_source_version]) From e12df3e02a87545bdf468ef8b074663772186ea6 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Tue, 14 Feb 2017 17:55:10 -0500 Subject: [PATCH 0707/1644] Refs CF-1690. If the correct version of Java is not installed, then exit configure gracefully --- redhawk/src/acinclude/java.m4 | 1 + 1 file changed, 1 insertion(+) diff --git a/redhawk/src/acinclude/java.m4 b/redhawk/src/acinclude/java.m4 index 38762d99c..ed8fc9953 100644 --- a/redhawk/src/acinclude/java.m4 +++ b/redhawk/src/acinclude/java.m4 @@ -83,6 +83,7 @@ EOF else AC_MSG_RESULT([no]) AC_SUBST([JAVAC], [no]) + AS_EXIT(1) fi rm -f Test.java Test.class fi From e6258f9de6ef83f9cd2b584de2926e00ef5a3870 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Wed, 15 Feb 2017 11:16:01 -0500 Subject: [PATCH 0708/1644] Refs CF-1566. Make Javas 8 a requirement for RH 2.1 --- redhawk-codegen/redhawk/codegen/versions.py | 2 +- redhawk/src/configure.ac | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/redhawk-codegen/redhawk/codegen/versions.py b/redhawk-codegen/redhawk/codegen/versions.py index aad9263e0..cd989455c 100644 --- a/redhawk-codegen/redhawk/codegen/versions.py +++ b/redhawk-codegen/redhawk/codegen/versions.py @@ -23,7 +23,7 @@ boost = '1.41' omniORB4 = '4.1.0' python = '2.4' -java = '1.7' +java = '1.8' log4j = '1.2.15' octave = '3.4.3' diff --git a/redhawk/src/configure.ac b/redhawk/src/configure.ac index e0e225d0e..17036c44e 100644 --- a/redhawk/src/configure.ac +++ b/redhawk/src/configure.ac @@ -171,7 +171,7 @@ if test "x$enable_java" != "xno"; then RH_JAVA_HOME # Minimum Java version - java_source_version=1.7 + java_source_version=1.8 # Locate tools we need based on JAVA_HOME RH_PROG_JAVAC([$java_source_version]) From d0a0deb9c91f968678fbde6a9388a5e7cd48bb28 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Wed, 15 Feb 2017 11:17:43 -0500 Subject: [PATCH 0709/1644] Refs CF-1566. Make Java 8 a requirement for RH 2.1 --- frontendInterfaces/configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontendInterfaces/configure.ac b/frontendInterfaces/configure.ac index fa9d81ecb..1e92e47bb 100644 --- a/frontendInterfaces/configure.ac +++ b/frontendInterfaces/configure.ac @@ -68,7 +68,7 @@ HAVE_JAVASUPPORT=no if test "x$enable_java" != "xno"; then # Ensure JAVA_HOME is set RH_JAVA_HOME - RH_PROG_JAVAC([1.6]) + RH_PROG_JAVAC([1.8]) RH_PROG_JAR RH_PROG_IDLJ From e6917c91242a12cf550521c05d36aa100e22a2ba Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 15 Feb 2017 11:07:53 -0500 Subject: [PATCH 0710/1644] CF-205 Don't force conversion of input data in DataSource.push() based on SRI state (restores 2.0 behavior) This should resolve problems with the Core Asset tests that were pushing data that was assumed to be already interleaved, where the second (and subsequent) pushes ended up sending twice as much data. --- redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py b/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py index 646cf9c9c..8cf70481f 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py +++ b/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py @@ -1241,7 +1241,7 @@ def push(self, # If complex values are present, interleave the data as scalar values # and set the complex flag - if _complexData or ( self._sri and self._sri.mode == 1): + if _complexData: if self._dataFormat in ('octet', 'short', 'ushort', 'long', 'ulong', 'longlong', 'ulonglong'): itemType = int else: From 277618e7646a9c890e68e5285538d4e503eca9cb Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 15 Feb 2017 14:28:37 -0500 Subject: [PATCH 0711/1644] CF-1437 Add a shared library test component to the codegenTesting SDRROOT Running the test to ensure that the component was launchable also required creating a link back to the real SDRROOT to find ComponentHost. --- codegenTesting/.gitignore | 53 ++----------------- codegenTesting/runtests.py | 9 +++- .../BasicShared/.BasicShared.wavedev | 6 +++ .../BasicShared/BasicShared.prf.xml | 3 ++ .../BasicShared/BasicShared.scd.xml | 45 ++++++++++++++++ .../BasicShared/BasicShared.spd.xml | 27 ++++++++++ 6 files changed, 93 insertions(+), 50 deletions(-) create mode 100644 codegenTesting/sdr/dom/components/BasicShared/.BasicShared.wavedev create mode 100644 codegenTesting/sdr/dom/components/BasicShared/BasicShared.prf.xml create mode 100644 codegenTesting/sdr/dom/components/BasicShared/BasicShared.scd.xml create mode 100644 codegenTesting/sdr/dom/components/BasicShared/BasicShared.spd.xml diff --git a/codegenTesting/.gitignore b/codegenTesting/.gitignore index 8d05759d8..8e4e92b89 100644 --- a/codegenTesting/.gitignore +++ b/codegenTesting/.gitignore @@ -1,54 +1,9 @@ -Makefile -build -Makefile.in -.deps -.libs +*.class +*.jar *.lo *.la *.o *.pyc *~ -aclocal.m4 -acinclude.m4 -autom4te.cache -config.guess -config.log -config.status -config.sub -configure -depcomp -install-sh -libtool -ltmain.sh -missing -ossie.pc -*.class -py-compile -reconf -configure.ac -Makefile.am -struct_props.h -*_base.cpp -*_base.h -build.sh -main.cpp -port_impl.h -port_impl.cpp -startJava.sh -*_base.py -*.spec -*.jar - -sdr/dom/components/basic/basic_cpp_impl1/basic_cpp_impl1 -sdr/dom/components/bulkio_ports/bulkio_ports_cpp_impl1/bulkio_ports_cpp_impl1 -sdr/dom/components/event_props/cpp/event_props -sdr/dom/components/props/props_cpp_impl1/props_cpp_impl1 -sdr/dom/components/sri/sri_cpp_impl1/sri_cpp_impl1 -sdr/dom/components/bulkio_ports/bulkio_ports_java_impl1/src/bulkio_ports_java_impl1/ports/ -sdr/dom/components/sri/sri_java_impl1/src/sri_java_impl1/ports/ -sdr/dev/devices/basic_device/cpp/basic_device -sdr/dev/devices/basic_loadable_device/cpp/basic_loadable_device -sdr/dev/devices/basic_executable_device/cpp/basic_executable_device -sdr/dev/devices/basic_aggregate_device/cpp/basic_aggregate_device -sdr/dev/services/basic_service/python/ -TEST-*.xml +build/ +sdr/dom/mgr diff --git a/codegenTesting/runtests.py b/codegenTesting/runtests.py index 7cd598703..7bfac150d 100755 --- a/codegenTesting/runtests.py +++ b/codegenTesting/runtests.py @@ -25,8 +25,15 @@ from _unitTestHelpers import scatest from _unitTestHelpers import runtestHelpers +# Create a symbolic link to $SDRROOT/dom/mgr so that the sandbox can find +# ComponentHost for shared library components +sdrroot = os.path.join(os.getcwd(), "sdr") +mgrpath = os.path.join(sdrroot, 'dom/mgr') +if not os.path.islink(mgrpath): + os.symlink(os.path.join(os.environ['SDRROOT'], 'dom/mgr'), mgrpath) + # Point to the testing SDR folder -os.environ['SDRROOT'] = os.path.join(os.getcwd(), "sdr") +os.environ['SDRROOT'] = sdrroot os.environ['CODEGENTESTHOME'] = os.path.join(os.getcwd()) def removeAll( src, items): diff --git a/codegenTesting/sdr/dom/components/BasicShared/.BasicShared.wavedev b/codegenTesting/sdr/dom/components/BasicShared/.BasicShared.wavedev new file mode 100644 index 000000000..f7936e04b --- /dev/null +++ b/codegenTesting/sdr/dom/components/BasicShared/.BasicShared.wavedev @@ -0,0 +1,6 @@ + + + + + + diff --git a/codegenTesting/sdr/dom/components/BasicShared/BasicShared.prf.xml b/codegenTesting/sdr/dom/components/BasicShared/BasicShared.prf.xml new file mode 100644 index 000000000..8f537d89f --- /dev/null +++ b/codegenTesting/sdr/dom/components/BasicShared/BasicShared.prf.xml @@ -0,0 +1,3 @@ + + + diff --git a/codegenTesting/sdr/dom/components/BasicShared/BasicShared.scd.xml b/codegenTesting/sdr/dom/components/BasicShared/BasicShared.scd.xml new file mode 100644 index 000000000..df94ceaf5 --- /dev/null +++ b/codegenTesting/sdr/dom/components/BasicShared/BasicShared.scd.xml @@ -0,0 +1,45 @@ + + + + 2.2 + + resource + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/codegenTesting/sdr/dom/components/BasicShared/BasicShared.spd.xml b/codegenTesting/sdr/dom/components/BasicShared/BasicShared.spd.xml new file mode 100644 index 000000000..9e172ff96 --- /dev/null +++ b/codegenTesting/sdr/dom/components/BasicShared/BasicShared.spd.xml @@ -0,0 +1,27 @@ + + + + + + null + + + + + + + + + The implementation contains descriptive information about the template for a software resource. + + + cpp/BasicShared.so + + + + + + + + + From a7f9763d1ed753e342d70a6e76e7b4ab79daa14c Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 15 Feb 2017 14:53:36 -0500 Subject: [PATCH 0712/1644] CF-1437 Only generate a "make_component" function for components to fix codegen tests for Persona device --- .../redhawk/codegen/jinja/cpp/component/base/templates/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/redhawk-codegen/redhawk/codegen/jinja/cpp/component/base/templates/main.cpp b/redhawk-codegen/redhawk/codegen/jinja/cpp/component/base/templates/main.cpp index ce9658adb..e82d6a53c 100644 --- a/redhawk-codegen/redhawk/codegen/jinja/cpp/component/base/templates/main.cpp +++ b/redhawk-codegen/redhawk/codegen/jinja/cpp/component/base/templates/main.cpp @@ -40,7 +40,7 @@ void signal_catcher(int sig) } } /*{% endif %}*/ -/*{% if component.impl.module %}*/ +/*{% if not component is device and component.impl.module %}*/ extern "C" { Resource_impl* make_component(const std::string& uuid, const std::string& identifier) { From cc95f4a5cbad9a8cc7432f88817af77ae66616bf Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 15 Feb 2017 16:40:49 -0500 Subject: [PATCH 0713/1644] CF-1671 Don't include Java test components in the build if Java is not enabled. Prior to integrating the test components into the main Autotools build, each component was built individually from a script, so even if Java components failed, the rest built. Since the components are now part of a Makefile, the Java components need to be excluded to ensure that the C++ components still build. --- bulkioInterfaces/libsrc/testing/Makefile.am | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/bulkioInterfaces/libsrc/testing/Makefile.am b/bulkioInterfaces/libsrc/testing/Makefile.am index 080a7f3e1..b203caa45 100644 --- a/bulkioInterfaces/libsrc/testing/Makefile.am +++ b/bulkioInterfaces/libsrc/testing/Makefile.am @@ -18,9 +18,15 @@ # along with this program. If not, see http://www.gnu.org/licenses/. # -SUBDIRS = components/CPP_Ports/cpp components/sri_changed_cpp/cpp components/Java_Ports/java -SUBDIRS += components/TestLargePush/cpp components/TestLargePush/java -SUBDIRS += components/multiout_attachable/cpp components/multiout_attachable/java -SUBDIRS += components/Oversized_framedata/cpp components/Oversized_framedata/java +SUBDIRS = components/CPP_Ports/cpp components/sri_changed_cpp/cpp +SUBDIRS += components/TestLargePush/cpp +SUBDIRS += components/multiout_attachable/cpp +SUBDIRS += components/Oversized_framedata/cpp +if HAVE_JAVASUPPORT +SUBDIRS += components/TestLargePush/java +SUBDIRS += components/Java_Ports/java +SUBDIRS += components/multiout_attachable/java +SUBDIRS += components/Oversized_framedata/java SUBDIRS += devices/dev_src/java devices/dev_snk/java +endif SUBDIRS += tests/cpp From 344e2ba75a0f68a8f70ce399cc467cc7b86c5d41 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 16 Feb 2017 16:26:10 -0500 Subject: [PATCH 0714/1644] CF-1582 Return to performing property type conversion in AllocationManager, and implement the conversion for struct sequence values. This fixes problems with arguably broken tests that were depending on an allocation dependency in CommandWrapper to succeed in spite of a failed __MATH__ expression. Several tests have been relaxed to assume that even if the input type isn't an exact match, the AllocationManager will do the right thing. --- redhawk/src/base/framework/prop_helpers.cpp | 4 ++++ redhawk/src/control/framework/prop_utils.cpp | 12 +++++++++++- .../control/sdr/dommgr/AllocationManager_impl.cpp | 2 +- redhawk/src/testing/tests/test_13_RedhawkModule.py | 9 ++++++--- 4 files changed, 22 insertions(+), 5 deletions(-) diff --git a/redhawk/src/base/framework/prop_helpers.cpp b/redhawk/src/base/framework/prop_helpers.cpp index 9c44adae1..465c7efe6 100644 --- a/redhawk/src/base/framework/prop_helpers.cpp +++ b/redhawk/src/base/framework/prop_helpers.cpp @@ -668,6 +668,10 @@ std::string ossie::simpleAnyToString(const CORBA::Any& value) CORBA::TypeCode_var typeValue = value.type(); switch (typeValue->kind()) { + case CORBA::tk_null: + result << "(null)"; + break; + case CORBA::tk_boolean: { CORBA::Boolean tmp; value >>= CORBA::Any::to_boolean(tmp); diff --git a/redhawk/src/control/framework/prop_utils.cpp b/redhawk/src/control/framework/prop_utils.cpp index 25a309119..7cfb34fdf 100644 --- a/redhawk/src/control/framework/prop_utils.cpp +++ b/redhawk/src/control/framework/prop_utils.cpp @@ -632,7 +632,17 @@ CORBA::Any ossie::convertAnyToPropertyType(const CORBA::Any& value, const Struct CORBA::Any ossie::convertAnyToPropertyType(const CORBA::Any& value, const StructSequenceProperty* property) { - return CORBA::Any(); + CORBA::Any result; + const CORBA::AnySeq* seq; + if (value >>= seq) { + CORBA::AnySeq tmp_seq; + const StructProperty& structdef = property->getStruct(); + for (CORBA::ULong index = 0; index < seq->length(); ++index) { + ossie::corba::push_back(tmp_seq, convertAnyToPropertyType((*seq)[index], &structdef)); + } + result <<= tmp_seq; + } + return result; } diff --git a/redhawk/src/control/sdr/dommgr/AllocationManager_impl.cpp b/redhawk/src/control/sdr/dommgr/AllocationManager_impl.cpp index 123be870c..5cf8ffc8c 100644 --- a/redhawk/src/control/sdr/dommgr/AllocationManager_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/AllocationManager_impl.cpp @@ -480,7 +480,7 @@ bool AllocationManager_impl::checkDeviceMatching(ossie::Properties& prf, CF::Pro // Collect properties with an action of "external" for a later // allocateCapacity() call LOG_TRACE(AllocationManager_impl, "Adding external property " << propId); - ossie::corba::push_back(externalProperties, dependency); + ossie::corba::push_back(externalProperties, ossie::convertDataTypeToPropertyType(dependency, property)); } else { // Evaluate matching properties right now if (!checkMatchingProperty(property, dependency)) { diff --git a/redhawk/src/testing/tests/test_13_RedhawkModule.py b/redhawk/src/testing/tests/test_13_RedhawkModule.py index b6a47ae7e..422ad31d0 100644 --- a/redhawk/src/testing/tests/test_13_RedhawkModule.py +++ b/redhawk/src/testing/tests/test_13_RedhawkModule.py @@ -844,7 +844,8 @@ def test_allocMgrSimSeq(self): prop = allocations.createProps({'se_prop':[1.0,2.0]}) rq=self.am.createRequest('foo',prop) resp = self.am.allocate([rq]) - self.assertEquals(len(resp),0) + self.assertEquals(len(resp),1) + self.am.deallocate([resp[0].allocationID]) prop = allocations.createProps({'se_prop':[1.0,2.0]}, prf='sdr/dev/devices/dev_alloc_cpp/dev_alloc_cpp.prf.xml') rq=self.am.createRequest('foo',prop) resp = self.am.allocate([rq]) @@ -859,7 +860,8 @@ def test_allocMgrStruct(self): prop = allocations.createProps({'s_prop':{'s_prop::a':'hello','s_prop::b':5}}) rq=self.am.createRequest('foo',prop) resp = self.am.allocate([rq]) - self.assertEquals(len(resp),0) + self.assertEquals(len(resp),1) + self.am.deallocate([resp[0].allocationID]) prop = allocations.createProps({'s_prop':{'s_prop::a':'hello','s_prop::b':5}}, prf='sdr/dev/devices/dev_alloc_cpp/dev_alloc_cpp.prf.xml') rq=self.am.createRequest('foo',prop) resp = self.am.allocate([rq]) @@ -874,7 +876,8 @@ def test_allocMgrStrSeq(self): prop = allocations.createProps({'sq_prop':[{'sq_prop::b':'hello','sq_prop::a':5},{'sq_prop::b':'another','sq_prop::a':7}]}) rq=self.am.createRequest('foo',prop) resp = self.am.allocate([rq]) - self.assertEquals(len(resp),0) + self.assertEquals(len(resp),1) + self.am.deallocate([resp[0].allocationID]) prop = allocations.createProps({'sq_prop':[{'sq_prop::b':'hello','sq_prop::a':5},{'sq_prop::b':'another','sq_prop::a':7}]}, prf='sdr/dev/devices/dev_alloc_cpp/dev_alloc_cpp.prf.xml') rq=self.am.createRequest('foo',prop) resp = self.am.allocate([rq]) From d3a5984cd7779e3adff824f63d9ed5fd42888f53 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 16 Feb 2017 18:14:37 -0500 Subject: [PATCH 0715/1644] Fix failing tests, get rid of some delays and remove unused methods --- .../testing/tests/test_13_RedhawkModule.py | 29 +++++++------ redhawk/src/testing/tests/test_13_TestSB.py | 43 +++++++------------ 2 files changed, 32 insertions(+), 40 deletions(-) diff --git a/redhawk/src/testing/tests/test_13_RedhawkModule.py b/redhawk/src/testing/tests/test_13_RedhawkModule.py index 422ad31d0..d50fc2bff 100644 --- a/redhawk/src/testing/tests/test_13_RedhawkModule.py +++ b/redhawk/src/testing/tests/test_13_RedhawkModule.py @@ -25,6 +25,7 @@ from omniORB import any as _any from xml.dom import minidom import os as _os +import Queue from ossie.cf import CF from ossie.utils import redhawk from ossie.utils import type_helpers @@ -51,15 +52,22 @@ def tearDown(self): pass scatest.CorbaTestCase.tearDown(self) + def _waitData(self, sub, timeout): + end = time.time() + timeout + while time.time() < end: + data = sub.getData() + if data: + return data._v + return None + def test_eventChannelPull(self): sub = Subscriber(self._domMgr, self.channelName) pub = Publisher(self._domMgr, self.channelName) payload = 'hello' data = _any.to_any(payload) pub.push(data) - time.sleep(1) - self.rec_data = sub.getData() - self.assertEquals(self.rec_data, payload) + rec_data = self._waitData(sub, 1.0) + self.assertEquals(rec_data, payload) pub.terminate() sub.terminate() @@ -69,23 +77,20 @@ def test_eventChannelForceDelete(self): payload = 'hello' data = _any.to_any(payload) pub.push(data) - time.sleep(1) - self.rec_data = sub.getData() - self.assertEquals(self.rec_data, payload) + rec_data = self._waitData(sub, 1.0) + self.assertEquals(rec_data, payload) self.ecm.forceRelease(self.channelName) self.assertRaises(CF.EventChannelManager.ChannelDoesNotExist, self.ecm.release, self.channelName) - def callback(self, data): - self.rec_data = data - def test_eventChannelCB(self): - sub = Subscriber(self._domMgr, self.channelName, dataArrivedCB=self.callback) + queue = Queue.Queue() + sub = Subscriber(self._domMgr, self.channelName, dataArrivedCB=queue.put) pub = Publisher(self._domMgr, self.channelName) payload = 'hello' data = _any.to_any(payload) pub.push(data) - time.sleep(1) - self.assertEquals(self.rec_data, payload) + rec_data = queue.get(timeout=1.0) + self.assertEquals(rec_data._v, payload) pub.terminate() sub.terminate() diff --git a/redhawk/src/testing/tests/test_13_TestSB.py b/redhawk/src/testing/tests/test_13_TestSB.py index ce99921fb..91e4d318d 100644 --- a/redhawk/src/testing/tests/test_13_TestSB.py +++ b/redhawk/src/testing/tests/test_13_TestSB.py @@ -44,7 +44,6 @@ import traceback globalsdrRoot = os.environ['SDRROOT'] -java_support = runtestHelpers.haveJavaSupport('../Makefile') def _initSourceAndSink(dataFormat): @@ -143,20 +142,9 @@ class SBEventChannelTest(scatest.CorbaTestCase): def setUp(self): orb = CORBA.ORB_init() self.chanMgr = ChannelManager(orb) - self._app=None - self.rec_data = None # Force creation self.channel = self.chanMgr.createEventChannel("TestChan", force=True) sb.setDEBUG(False) - self.test_comp = "Sandbox" - # Flagrant violation of sandbox API: if the sandbox singleton exists, - # clean up previous state and dispose of it. - if sb.domainless._sandbox: - sb.domainless._sandbox.shutdown() - sb.domainless._sandbox = None - - def assertComponentCount(self, count): - self.assertEquals(len(sb.domainless._getSandbox().getComponents()), count) def tearDown(self): try: @@ -168,29 +156,34 @@ def tearDown(self): sb.setDEBUG(False) os.environ['SDRROOT'] = globalsdrRoot + def _waitData(self, sub, timeout): + end = time.time() + timeout + while time.time() < end: + data = sub.getData() + if data: + return data._v + return None + def test_PublishSubscribePull(self): sub = Subscriber( self.channel ) pub = Publisher( self.channel ) payload = 'hello' data = any.to_any(payload) pub.push(data) - time.sleep(1) - self.rec_data = sub.getData() - self.assertEquals(self.rec_data, payload) + rec_data = self._waitData(sub, 1.0) + self.assertEquals(rec_data, payload) pub.terminate() sub.terminate() - def callback(self, data): - self.rec_data = data - def test_PublishSubscribeCB(self): - sub = Subscriber(self.channel, dataArrivedCB=self.callback) + queue = Queue.Queue() + sub = Subscriber(self.channel, dataArrivedCB=queue.put) pub = Publisher(self.channel) payload = 'hello' data = any.to_any(payload) pub.push(data) - time.sleep(1) - self.assertEquals(self.rec_data, payload) + rec_data = queue.get(timeout=1.0) + self.assertEquals(rec_data._v, payload) pub.terminate() sub.terminate() @@ -2297,15 +2290,9 @@ def test_DataSinkOctetSignedData(self): class MessagePortTest(scatest.CorbaTestCase): def setUp(self): sb.setDEBUG(True) - self.test_comp = "Sandbox" - # Flagrant violation of sandbox API: if the sandbox singleton exists, - # clean up previous state and dispose of it. - if sb.domainless._sandbox: - sb.domainless._sandbox.shutdown() - sb.domainless._sandbox = None def tearDown(self): - sb.domainless._getSandbox().shutdown() + sb.release() sb.setDEBUG(False) os.environ['SDRROOT'] = globalsdrRoot From dcc1e73275d48e72af2186d723bf530b4694b0ce Mon Sep 17 00:00:00 2001 From: Max Robert Date: Fri, 17 Feb 2017 12:38:44 -0500 Subject: [PATCH 0716/1644] Change connection manager test component to not rely on bulkio --- .../dom/components/comp_snk/comp_snk.prf.xml | 19 ------------ .../dom/components/comp_snk/comp_snk.scd.xml | 31 ++++--------------- .../dom/components/comp_snk/comp_snk.spd.xml | 23 ++------------ .../components/comp_snk/python/comp_snk.py | 21 +------------ .../comp_snk/python/comp_snk_base.py | 29 +++-------------- .../dom/components/comp_src/comp_src.prf.xml | 19 ------------ .../dom/components/comp_src/comp_src.scd.xml | 31 ++++--------------- .../dom/components/comp_src/comp_src.spd.xml | 23 ++------------ .../components/comp_src/python/comp_src.py | 21 +------------ .../comp_src/python/comp_src_base.py | 29 +++-------------- .../tests/test_16_ConnectionManager.py | 16 +++++----- 11 files changed, 36 insertions(+), 226 deletions(-) diff --git a/redhawk/src/testing/sdr/dom/components/comp_snk/comp_snk.prf.xml b/redhawk/src/testing/sdr/dom/components/comp_snk/comp_snk.prf.xml index 3624eb818..8f537d89f 100644 --- a/redhawk/src/testing/sdr/dom/components/comp_snk/comp_snk.prf.xml +++ b/redhawk/src/testing/sdr/dom/components/comp_snk/comp_snk.prf.xml @@ -1,22 +1,3 @@ - diff --git a/redhawk/src/testing/sdr/dom/components/comp_snk/comp_snk.scd.xml b/redhawk/src/testing/sdr/dom/components/comp_snk/comp_snk.scd.xml index f78d4af11..1a7d502e3 100644 --- a/redhawk/src/testing/sdr/dom/components/comp_snk/comp_snk.scd.xml +++ b/redhawk/src/testing/sdr/dom/components/comp_snk/comp_snk.scd.xml @@ -1,23 +1,4 @@ - 2.2 @@ -35,7 +16,7 @@ with this program. If not, see http://www.gnu.org/licenses/. - + @@ -62,11 +43,11 @@ with this program. If not, see http://www.gnu.org/licenses/. - - - + + + - - + + diff --git a/redhawk/src/testing/sdr/dom/components/comp_snk/comp_snk.spd.xml b/redhawk/src/testing/sdr/dom/components/comp_snk/comp_snk.spd.xml index 09b6b4a94..ddbf6ae67 100644 --- a/redhawk/src/testing/sdr/dom/components/comp_snk/comp_snk.spd.xml +++ b/redhawk/src/testing/sdr/dom/components/comp_snk/comp_snk.spd.xml @@ -1,25 +1,6 @@ - - + null @@ -31,7 +12,7 @@ with this program. If not, see http://www.gnu.org/licenses/. - The implementation contains descriptive information about the template for a software component. + The implementation contains descriptive information about the template for a software resource. python/comp_snk.py diff --git a/redhawk/src/testing/sdr/dom/components/comp_snk/python/comp_snk.py b/redhawk/src/testing/sdr/dom/components/comp_snk/python/comp_snk.py index 3b3155a22..9d6c0ba8f 100755 --- a/redhawk/src/testing/sdr/dom/components/comp_snk/python/comp_snk.py +++ b/redhawk/src/testing/sdr/dom/components/comp_snk/python/comp_snk.py @@ -1,24 +1,5 @@ #!/usr/bin/env python # -# This file is protected by Copyright. Please refer to the COPYRIGHT file -# distributed with this source distribution. -# -# This file is part of REDHAWK core. -# -# REDHAWK core is free software: you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation, either version 3 of the License, or (at your option) any -# later version. -# -# REDHAWK core is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more -# details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with this program. If not, see http://www.gnu.org/licenses/. -# -# # # AUTO-GENERATED # @@ -52,7 +33,7 @@ def process(self): StreamSRI: To create a StreamSRI object, use the following code (this generates a normalized SRI that does not flush the queue when full): - self.sri = bulkio.sri.create(self.stream_id) + sri = bulkio.sri.create("my_stream_id") PrecisionUTCTime: To create a PrecisionUTCTime object, use the following code: diff --git a/redhawk/src/testing/sdr/dom/components/comp_snk/python/comp_snk_base.py b/redhawk/src/testing/sdr/dom/components/comp_snk/python/comp_snk_base.py index 3df90b956..801985b48 100644 --- a/redhawk/src/testing/sdr/dom/components/comp_snk/python/comp_snk_base.py +++ b/redhawk/src/testing/sdr/dom/components/comp_snk/python/comp_snk_base.py @@ -1,24 +1,5 @@ #!/usr/bin/env python # -# This file is protected by Copyright. Please refer to the COPYRIGHT file -# distributed with this source distribution. -# -# This file is part of REDHAWK core. -# -# REDHAWK core is free software: you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation, either version 3 of the License, or (at your option) any -# later version. -# -# REDHAWK core is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more -# details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with this program. If not, see http://www.gnu.org/licenses/. -# -# # AUTO-GENERATED CODE. DO NOT MODIFY! # # Source: comp_snk.spd.xml @@ -31,7 +12,7 @@ import Queue, copy, time, threading from ossie.resource import usesport, providesport -import bulkio +from ossie.events import MessageConsumerPort class comp_snk_base(CF__POA.Resource, Component, ThreadedComponent): # These values can be altered in the __init__ of your derived class @@ -50,7 +31,7 @@ def __init__(self, identifier, execparams): # in future releases self.auto_start = False # Instantiate the default implementations for all ports on this component - self.port_dataFloat_in = bulkio.InFloatPort("dataFloat_in", maxsize=self.DEFAULT_QUEUE_SIZE) + self.port_input = MessageConsumerPort(thread_sleep=0.1, parent = self) def start(self): Component.start(self) @@ -74,9 +55,9 @@ def releaseObject(self): # DO NOT ADD NEW PORTS HERE. You can add ports in your derived class, in the SCD xml file, # or via the IDE. - port_dataFloat_in = providesport(name="dataFloat_in", - repid="IDL:BULKIO/dataFloat:1.0", - type_="control") + port_input = providesport(name="input", + repid="IDL:ExtendedEvent/MessageEvent:1.0", + type_="control") ###################################################################### # PROPERTIES diff --git a/redhawk/src/testing/sdr/dom/components/comp_src/comp_src.prf.xml b/redhawk/src/testing/sdr/dom/components/comp_src/comp_src.prf.xml index 3624eb818..8f537d89f 100644 --- a/redhawk/src/testing/sdr/dom/components/comp_src/comp_src.prf.xml +++ b/redhawk/src/testing/sdr/dom/components/comp_src/comp_src.prf.xml @@ -1,22 +1,3 @@ - diff --git a/redhawk/src/testing/sdr/dom/components/comp_src/comp_src.scd.xml b/redhawk/src/testing/sdr/dom/components/comp_src/comp_src.scd.xml index ae645f2c5..62a50f70f 100644 --- a/redhawk/src/testing/sdr/dom/components/comp_src/comp_src.scd.xml +++ b/redhawk/src/testing/sdr/dom/components/comp_src/comp_src.scd.xml @@ -1,23 +1,4 @@ - 2.2 @@ -35,7 +16,7 @@ with this program. If not, see http://www.gnu.org/licenses/. - + @@ -62,11 +43,11 @@ with this program. If not, see http://www.gnu.org/licenses/. - - - + + + - - + + diff --git a/redhawk/src/testing/sdr/dom/components/comp_src/comp_src.spd.xml b/redhawk/src/testing/sdr/dom/components/comp_src/comp_src.spd.xml index 272b11fc1..4e49aa7a1 100644 --- a/redhawk/src/testing/sdr/dom/components/comp_src/comp_src.spd.xml +++ b/redhawk/src/testing/sdr/dom/components/comp_src/comp_src.spd.xml @@ -1,25 +1,6 @@ - - + null @@ -31,7 +12,7 @@ with this program. If not, see http://www.gnu.org/licenses/. - The implementation contains descriptive information about the template for a software component. + The implementation contains descriptive information about the template for a software resource. python/comp_src.py diff --git a/redhawk/src/testing/sdr/dom/components/comp_src/python/comp_src.py b/redhawk/src/testing/sdr/dom/components/comp_src/python/comp_src.py index 15a423a72..768583f31 100755 --- a/redhawk/src/testing/sdr/dom/components/comp_src/python/comp_src.py +++ b/redhawk/src/testing/sdr/dom/components/comp_src/python/comp_src.py @@ -1,24 +1,5 @@ #!/usr/bin/env python # -# This file is protected by Copyright. Please refer to the COPYRIGHT file -# distributed with this source distribution. -# -# This file is part of REDHAWK core. -# -# REDHAWK core is free software: you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation, either version 3 of the License, or (at your option) any -# later version. -# -# REDHAWK core is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more -# details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with this program. If not, see http://www.gnu.org/licenses/. -# -# # # AUTO-GENERATED # @@ -52,7 +33,7 @@ def process(self): StreamSRI: To create a StreamSRI object, use the following code (this generates a normalized SRI that does not flush the queue when full): - self.sri = bulkio.sri.create(self.stream_id) + sri = bulkio.sri.create("my_stream_id") PrecisionUTCTime: To create a PrecisionUTCTime object, use the following code: diff --git a/redhawk/src/testing/sdr/dom/components/comp_src/python/comp_src_base.py b/redhawk/src/testing/sdr/dom/components/comp_src/python/comp_src_base.py index f361673a7..d6d0396fb 100644 --- a/redhawk/src/testing/sdr/dom/components/comp_src/python/comp_src_base.py +++ b/redhawk/src/testing/sdr/dom/components/comp_src/python/comp_src_base.py @@ -1,24 +1,5 @@ #!/usr/bin/env python # -# This file is protected by Copyright. Please refer to the COPYRIGHT file -# distributed with this source distribution. -# -# This file is part of REDHAWK core. -# -# REDHAWK core is free software: you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation, either version 3 of the License, or (at your option) any -# later version. -# -# REDHAWK core is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more -# details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with this program. If not, see http://www.gnu.org/licenses/. -# -# # AUTO-GENERATED CODE. DO NOT MODIFY! # # Source: comp_src.spd.xml @@ -31,7 +12,7 @@ import Queue, copy, time, threading from ossie.resource import usesport, providesport -import bulkio +from ossie.events import MessageSupplierPort class comp_src_base(CF__POA.Resource, Component, ThreadedComponent): # These values can be altered in the __init__ of your derived class @@ -50,7 +31,7 @@ def __init__(self, identifier, execparams): # in future releases self.auto_start = False # Instantiate the default implementations for all ports on this component - self.port_dataFloat_out = bulkio.OutFloatPort("dataFloat_out") + self.port_output = MessageSupplierPort() def start(self): Component.start(self) @@ -74,9 +55,9 @@ def releaseObject(self): # DO NOT ADD NEW PORTS HERE. You can add ports in your derived class, in the SCD xml file, # or via the IDE. - port_dataFloat_out = usesport(name="dataFloat_out", - repid="IDL:BULKIO/dataFloat:1.0", - type_="control") + port_output = usesport(name="output", + repid="IDL:ExtendedEvent/MessageEvent:1.0", + type_="control") ###################################################################### # PROPERTIES diff --git a/redhawk/src/testing/tests/test_16_ConnectionManager.py b/redhawk/src/testing/tests/test_16_ConnectionManager.py index 0e382d103..eb9683dba 100644 --- a/redhawk/src/testing/tests/test_16_ConnectionManager.py +++ b/redhawk/src/testing/tests/test_16_ConnectionManager.py @@ -338,16 +338,16 @@ def test_connect_DeviceConnections(self): def test_redhawkutils_ComponentConnections(self): app_src = self._domMgr.createApplication('/waveforms/comp_src_w/comp_src_w.sad.xml', 'src_app', [], []) app_snk = self._domMgr.createApplication('/waveforms/comp_snk_w/comp_snk_w.sad.xml', 'snk_app', [], []) - uses = self.cm.componentEndPoint( 'comp_src_1:'+app_src._get_identifier(), 'dataFloat_out') - provides = self.cm.componentEndPoint( 'comp_snk_1:'+app_snk._get_identifier(), 'dataFloat_in') + uses = self.cm.componentEndPoint( 'comp_src_1:'+app_src._get_identifier(), 'output') + provides = self.cm.componentEndPoint( 'comp_snk_1:'+app_snk._get_identifier(), 'input') connectionReportId = self.cm.connect(uses, provides, 'test_environment', 'test_connection') connections = self.cm.connections self.assertEqual(len(connections), 2) connection = self._findConnection(connections,'test_connection') self.assertFalse(connection is None) self.assertTrue(connection.connected) - self.assertEqual(connection.usesEndpoint.portName, 'dataFloat_out') - self.assertEqual(connection.providesEndpoint.portName, 'dataFloat_in') + self.assertEqual(connection.usesEndpoint.portName, 'output') + self.assertEqual(connection.providesEndpoint.portName, 'input') connections = connection.usesEndpoint.endpointObject._narrow(ExtendedCF.QueryablePort)._get_connections() self.assertTrue(len(connections) == 1) self.assertEqual(connections[0].connectionId, 'test_connection') @@ -358,16 +358,16 @@ def test_connect_ComponentConnections(self): comp_src = app_src.comps[0] comp_snk = app_snk.comps[0] - uses = rhconnection.makeEndPoint( comp_src, 'dataFloat_out') - provides = rhconnection.makeEndPoint( comp_snk, 'dataFloat_in') + uses = rhconnection.makeEndPoint( comp_src, 'output') + provides = rhconnection.makeEndPoint( comp_snk, 'input') connectionReportId = self.cm.connect(uses, provides, 'test_environment', 'test_connection') connections = self.cm.connections self.assertEqual(len(connections), 2) connection = self._findConnection(connections,'test_connection') self.assertFalse(connection is None) self.assertTrue(connection.connected) - self.assertEqual(connection.usesEndpoint.portName, 'dataFloat_out') - self.assertEqual(connection.providesEndpoint.portName, 'dataFloat_in') + self.assertEqual(connection.usesEndpoint.portName, 'output') + self.assertEqual(connection.providesEndpoint.portName, 'input') connections = connection.usesEndpoint.endpointObject._narrow(ExtendedCF.QueryablePort)._get_connections() out_connections = comp_src.ports[0].ref._get_connections() self.assertTrue(connections[0].port._is_equivalent(out_connections[0].port)) From 72267ba4aa46a7210abe5d4d205f19681edad351 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 17 Feb 2017 11:36:13 -0500 Subject: [PATCH 0717/1644] Rename test implementation methods so that nose doesn't try to run them, too --- .../tests/test_08_PropertyChangeListener.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/redhawk/src/testing/tests/test_08_PropertyChangeListener.py b/redhawk/src/testing/tests/test_08_PropertyChangeListener.py index d150b8107..ee6f745fd 100644 --- a/redhawk/src/testing/tests/test_08_PropertyChangeListener.py +++ b/redhawk/src/testing/tests/test_08_PropertyChangeListener.py @@ -71,7 +71,7 @@ def tearDown(self): # class tearDown, or failures will occur. scatest.CorbaTestCase.tearDown(self) - def baseline_test_PropertyChangeListener(self, app_name, comp_name): + def _test_PropertyChangeListener(self, app_name, comp_name): self.localEvent = threading.Event() self.eventFlag = False @@ -131,14 +131,14 @@ def baseline_test_PropertyChangeListener(self, app_name, comp_name): self._app=None def test_PropertyChangeListener_CPP(self): - self.baseline_test_PropertyChangeListener("/waveforms/PropertyChangeListenerNoJava/PropertyChangeListenerNoJava.sad.xml", 'PropertyChange_C1') + self._test_PropertyChangeListener("/waveforms/PropertyChangeListenerNoJava/PropertyChangeListenerNoJava.sad.xml", 'PropertyChange_C1') def test_PropertyChangeListener_PYTHON(self): - self.baseline_test_PropertyChangeListener("/waveforms/PropertyChangeListenerNoJava/PropertyChangeListenerNoJava.sad.xml", 'PropertyChange_P1') + self._test_PropertyChangeListener("/waveforms/PropertyChangeListenerNoJava/PropertyChangeListenerNoJava.sad.xml", 'PropertyChange_P1') @scatest.requireJava def test_PropertyChangeListener_JAVA(self): - self.baseline_test_PropertyChangeListener("/waveforms/PropertyChangeListener/PropertyChangeListener.sad.xml", 'PropertyChange_J1') + self._test_PropertyChangeListener("/waveforms/PropertyChangeListener/PropertyChangeListener.sad.xml", 'PropertyChange_J1') def test_PropertyChangeListener_APP(self): self.localEvent = threading.Event() @@ -257,7 +257,7 @@ def tearDown(self): scatest.CorbaTestCase.tearDown(self) - def base_test_PropertyChangeListener_EC_Comps(self, app_name, comp_name): + def _test_PropertyChangeListener_EC_Comps(self, app_name, comp_name): self.localEvent = threading.Event() self.eventFlag = False @@ -309,14 +309,14 @@ def base_test_PropertyChangeListener_EC_Comps(self, app_name, comp_name): self._app=None def test_PropertyChangeListener_EC_CPP(self): - self.base_test_PropertyChangeListener_EC_Comps("/waveforms/PropertyChangeListenerNoJava/PropertyChangeListenerNoJava.sad.xml", 'PropertyChange_C1') + self._test_PropertyChangeListener_EC_Comps("/waveforms/PropertyChangeListenerNoJava/PropertyChangeListenerNoJava.sad.xml", 'PropertyChange_C1') def test_PropertyChangeListener_EC_PYTHON(self): - self.base_test_PropertyChangeListener_EC_Comps("/waveforms/PropertyChangeListenerNoJava/PropertyChangeListenerNoJava.sad.xml", 'PropertyChange_P1') + self._test_PropertyChangeListener_EC_Comps("/waveforms/PropertyChangeListenerNoJava/PropertyChangeListenerNoJava.sad.xml", 'PropertyChange_P1') @scatest.requireJava def test_PropertyChangeListener_EC_JAVA(self): - self.base_test_PropertyChangeListener_EC_Comps("/waveforms/PropertyChangeListener/PropertyChangeListener.sad.xml", 'PropertyChange_J1') + self._test_PropertyChangeListener_EC_Comps("/waveforms/PropertyChangeListener/PropertyChangeListener.sad.xml", 'PropertyChange_J1') def test_PropertyChangeListener_EC_APP(self): self.localEvent = threading.Event() From b49ebe7f0b2515fc9509a3b928d24ad39324d8f3 Mon Sep 17 00:00:00 2001 From: 8530 <8530@vm-131.vsi-corp.com> Date: Fri, 17 Feb 2017 17:25:48 -0500 Subject: [PATCH 0718/1644] added devicerequires to componethost container, CF-1416 --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 3 ++ redhawk/src/control/sdr/dommgr/Deployment.cpp | 5 ++ redhawk/src/control/sdr/dommgr/Deployment.h | 1 + .../device_requires_red_so.sad.xml | 46 +++++++++++++++++++ .../testing/tests/test_08_DeployerRequires.py | 12 +++++ 5 files changed, 67 insertions(+) create mode 100644 redhawk/src/testing/sdr/dom/waveforms/device_requires/device_requires_red_so/device_requires_red_so.sad.xml diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 4668bf57e..3399d5ec4 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -298,6 +298,9 @@ void createHelper::assignPlacementsToDevices(redhawk::ApplicationDeployment& app << " is a shared library"); redhawk::ContainerDeployment* container = appDeployment.createContainer(_profileCache, deployment->getAssignedDevice()); if (!container->getAssignedDevice()) { + + const redhawk::PropertyMap& devReqs = deployment->getDeviceRequires(); + if ( devReqs.size() ) container->setDeviceRequires(devReqs); // Use whether the device is assigned as a sentinel to check // whether the container was already created, and if not, // allocate it to the device diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index e267218bd..a76451f7a 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -424,6 +424,11 @@ redhawk::PropertyMap ComponentDeployment::getDeviceRequires() const { return deviceRequires; } +void ComponentDeployment::setDeviceRequires( const redhawk::PropertyMap &devReqs ) { + deviceRequires = devReqs; +} + + redhawk::PropertyMap ComponentDeployment::getAllocationContext() const { redhawk::PropertyMap properties; diff --git a/redhawk/src/control/sdr/dommgr/Deployment.h b/redhawk/src/control/sdr/dommgr/Deployment.h index 636f80fc5..f1edb3888 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.h +++ b/redhawk/src/control/sdr/dommgr/Deployment.h @@ -160,6 +160,7 @@ namespace redhawk { std::string getLoggingConfiguration() const; redhawk::PropertyMap getDeviceRequires() const; + void setDeviceRequires( const redhawk::PropertyMap &devRequires ); redhawk::ApplicationComponent* getApplicationComponent(); void setApplicationComponent(redhawk::ApplicationComponent* appComponent); diff --git a/redhawk/src/testing/sdr/dom/waveforms/device_requires/device_requires_red_so/device_requires_red_so.sad.xml b/redhawk/src/testing/sdr/dom/waveforms/device_requires/device_requires_red_so/device_requires_red_so.sad.xml new file mode 100644 index 000000000..06d2ffa8a --- /dev/null +++ b/redhawk/src/testing/sdr/dom/waveforms/device_requires/device_requires_red_so/device_requires_red_so.sad.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + SF1_Red + + + + + + + + + + + + + + diff --git a/redhawk/src/testing/tests/test_08_DeployerRequires.py b/redhawk/src/testing/tests/test_08_DeployerRequires.py index e427df052..91d7ae0dc 100644 --- a/redhawk/src/testing/tests/test_08_DeployerRequires.py +++ b/redhawk/src/testing/tests/test_08_DeployerRequires.py @@ -169,6 +169,18 @@ def test_reddevrequires_redprovided(self): self.assertNotEqual(self._app, None) xx=self._app.query([]) + def test_reddevrequires_redprovided_so(self): + domBooter, self._domMgr = self.launchDomainManager() + redBooter, self._rednode = self.launchDeviceManager("/nodes/test_GPP_red/DeviceManager.dcd.xml") + + self.assertNotEqual(self._domMgr, None) + self.assertNotEqual(self._rednode, None) + + self._app = self._createApp('device_requires_red_so') + + self.assertNotEqual(self._app, None) + xx=self._app.query([]) + def test_greendevrequires_colormismatch(self): domBooter, self._domMgr = self.launchDomainManager() redBooter, self._rednode = self.launchDeviceManager("/nodes/test_GPP_red/DeviceManager.dcd.xml") From 2dfe8188062d1e4be2d064173f4a304ddbc0ecd1 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 21 Feb 2017 16:43:13 -0500 Subject: [PATCH 0719/1644] CF-1707 Update the generated component comment header to use shared buffers Also use getStream() instead of keeping a member variable, and remove statement about string-type port support for streams, which was also added in 2.1 --- .../cpp/component/pull/templates/resource.cpp | 54 +++++++++---------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/redhawk-codegen/redhawk/codegen/jinja/cpp/component/pull/templates/resource.cpp b/redhawk-codegen/redhawk/codegen/jinja/cpp/component/pull/templates/resource.cpp index 88a9d56b9..a464ea30c 100644 --- a/redhawk-codegen/redhawk/codegen/jinja/cpp/component/pull/templates/resource.cpp +++ b/redhawk-codegen/redhawk/codegen/jinja/cpp/component/pull/templates/resource.cpp @@ -151,8 +151,7 @@ void ${className}::updateUsageState() Data is passed to the serviceFunction through by reading from input streams (BulkIO only). The input stream class is a port-specific class, so each port implementing the BulkIO interface will have its own type-specific input stream. - UDP multicast (dataSDDS and dataVITA49) and string-based (dataString, dataXML and - dataFile) do not support streams. + UDP multicast (dataSDDS and dataVITA49) ports do not support streams. The input stream from which to read can be requested with the getCurrentStream() method. The optional argument to getCurrentStream() is a floating point number that @@ -180,15 +179,18 @@ void ${className}::updateUsageState() // An output (uses) port of type bulkio::OutFloatPort called dataFloat_out // The mapping between the port and the class is found // in the ${artifactType} base class header file - // The ${artifactType} class must have an output stream member; add to - // ${component.userclass.header}: - // bulkio::OutFloatStream outputStream; bulkio::InShortStream inputStream = dataShort_in->getCurrentStream(); if (!inputStream) { // No streams are available return NOOP; } + // Get the output stream, creating it if it doesn't exist yet + bulkio::OutFloatStream outputStream = dataFloat_out->getStream(inputStream.streamID()); + if (!outputStream) { + outputStream = dataFloat_out->createStream(inputStream.sri()); + } + bulkio::ShortDataBlock block = inputStream.read(); if (!block) { // No data available // Propagate end-of-stream @@ -198,42 +200,40 @@ void ${className}::updateUsageState() return NOOP; } - short* inputData = block.data(); - std::vector outputData; - outputData.resize(block.size()); - for (size_t index = 0; index < block.size(); ++index) { - outputData[index] = (float) inputData[index]; - } - - // If there is no output stream open, create one - if (!outputStream) { - outputStream = dataFloat_out->createStream(block.sri()); - } else if (block.sriChanged()) { + if (block.sriChanged()) { // Update output SRI outputStream.sri(block.sri()); } - // Write to the output stream - outputStream.write(outputData, block.getTimestamps()); + // Get read-only access to the input data + redhawk::shared_buffer inputData = block.buffer(); + + // Acquire a new buffer to hold the output data + redhawk::buffer outputData(inputData.size()); - // Propagate end-of-stream - if (inputStream.eos()) { - outputStream.close(); + // Transform input data into output data + for (size_t index = 0; index < inputData.size(); ++index) { + outputData[index] = (float) inputData[index]; } + // Write to the output stream; outputData must not be modified after + // this method call + outputStream.write(outputData, block.getStartTime()); + return NORMAL; If working with complex data (i.e., the "mode" on the SRI is set to true), the data block's complex() method will return true. Data blocks - provide functions that return the correct interpretation of the data - buffer and number of complex elements: + provide a cxbuffer() method that returns a complex interpretation of the + buffer without making a copy: if (block.complex()) { - std::complex* data = block.cxdata(); - for (size_t index = 0; index < block.cxsize(); ++index) { - data[index] = std::abs(data[index]); + redhawk::shared_buffer > inData = block.cxbuffer(); + redhawk::buffer > outData(inData.size()); + for (size_t index = 0; index < inData.size(); ++index) { + outData[index] = inData[index]; } - outputStream.write(data, block.cxsize(), bulkio::time::utils::now()); + outputStream.write(outData, block.getStartTime()); } Interactions with non-BULKIO ports are left up to the ${artifactType} developer's discretion From d9380a5fbd9b3af623999eee873b63b91879aa9b Mon Sep 17 00:00:00 2001 From: Max Robert Date: Tue, 21 Feb 2017 17:53:51 -0500 Subject: [PATCH 0720/1644] Refs CF-1709. Fix problem with tuner status return value --- codegenTesting/helpers/scatest.py | 20 +- .../fei_base/frontend_tuner_unit_test_base.py | 2959 +++++++++++++++++ .../frontend/templates/resource_base.py | 4 +- 3 files changed, 2974 insertions(+), 9 deletions(-) create mode 100644 codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/tests/fei_base/frontend_tuner_unit_test_base.py diff --git a/codegenTesting/helpers/scatest.py b/codegenTesting/helpers/scatest.py index 060872883..f8ceac83c 100755 --- a/codegenTesting/helpers/scatest.py +++ b/codegenTesting/helpers/scatest.py @@ -188,16 +188,20 @@ def runUnitTests(self): spd_file = "../"+self.base_name+'.spd.xml' os.chdir(self.test_dir) - retval = ossie.utils.testing.ScaComponentTestProgram(spd_file, - module='test_'+self.base_name, + _files = os.listdir(self.build_dir+'/tests') + for _file in _files: + if len(_file) > 8: + if _file[-3:] == '.py' and _file[:5] == 'test_': + retval = ossie.utils.testing.ScaComponentTestProgram(spd_file, + module=_file[:-3], impl=impl_id) - if self.octave_test_dir: - os.chdir(start_dir) + if self.octave_test_dir: + os.chdir(start_dir) - for result in retval.results: - if result.errors or result.failures: - if not lang in failures: - failures.append(lang) + for result in retval.results: + if result.errors or result.failures: + if not lang in failures: + failures.append(lang) self.assertEqual(len(failures), 0, msg='failed for ' + ', '.join(failures)) diff --git a/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/tests/fei_base/frontend_tuner_unit_test_base.py b/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/tests/fei_base/frontend_tuner_unit_test_base.py new file mode 100644 index 000000000..c4f1ffe56 --- /dev/null +++ b/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/tests/fei_base/frontend_tuner_unit_test_base.py @@ -0,0 +1,2959 @@ +# This file is protected by Copyright. Please refer to the COPYRIGHT file +# distributed with this source distribution. +# +# This file is part of USRP_UHD Device. +# +# USRP_UHD Device is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# USRP_UHD Device is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see http://www.gnu.org/licenses/. + +import unittest +import nose +from ossie.utils import sb#, testing +import ossie.utils.testing +from ossie.utils.testing import PRFParser, SPDParser, SCDParser + +import os, sys, time, inspect, random, copy, signal +from pprint import pprint as pp +from pprint import pformat as pf + +from omniORB import any +from omniORB import CORBA + +from ossie import properties +from ossie.cf import CF, CF__POA +from ossie.utils import uuid +#from ossie.cf import ExtendedCF +#from ossie.resource import usesport, providesport + +from redhawk.frontendInterfaces import FRONTEND, FRONTEND__POA, TunerControl_idl +from bulkio.bulkioInterfaces import BULKIO, BULKIO__POA +from ossie.utils.bulkio import bulkio_data_helpers +from gtk._gtk import RESPONSE_ACCEPT + +DEBUG_LEVEL = 0 +def set_debug_level(lvl=0): + global DEBUG_LEVEL + DEBUG_LEVEL = lvl +def get_debug_level(): + return DEBUG_LEVEL + +# Define device under test below +DEVICE_INFO = {'SPD':None} +def set_device_info(dev_info): + global DEVICE_INFO + DEVICE_INFO = dev_info +def get_device_info(): + return DEVICE_INFO + +IMPL_ID = None +def set_impl_id(id): + global IMPL_ID + IMPL_ID = id +def get_impl_id(): + return IMPL_ID + +# execparams {'prop_name':'value',...} +DEVICE_INFO['execparams'] = {} + + +#class FrontendTunerTests: +#class FrontendTunerTests(ossie.utils.testing.ScaComponentTestCase): +class FrontendTunerTests(unittest.TestCase): + ''' FrontEnd device compatibility tests + Define DUT using the global DEVICE_INFO dict + Customize deviceStartup function if your device has special start up requirements + Customize deviceShutdown function if your device has special shut down requirements + ''' + + dut = None + dut_ref = None + device_discovery = {'TX':0, 'RX':0, 'CHANNELIZER':0, 'DDC':0, 'RX_DIGITIZER':0, + 'RX_DIGITIZER_CHANNELIZER':0, 'UNKNOWN':0} + testReport = [] + testReportStats = {} + + # mapping of required/optional frontend tuner status elements and the allowable data types + FE_tuner_status_fields_req = {'FRONTEND::tuner_status::tuner_type':[str], + 'FRONTEND::tuner_status::allocation_id_csv':[str], + 'FRONTEND::tuner_status::center_frequency':[float], + 'FRONTEND::tuner_status::bandwidth':[float], + 'FRONTEND::tuner_status::sample_rate':[float], + 'FRONTEND::tuner_status::group_id':[str], + 'FRONTEND::tuner_status::rf_flow_id':[str], + 'FRONTEND::tuner_status::enabled':[bool]} + FE_tuner_status_fields_opt = {'FRONTEND::tuner_status::bandwidth_tolerance':[float], + 'FRONTEND::tuner_status::sample_rate_tolerance':[float], + 'FRONTEND::tuner_status::complex':[bool], + 'FRONTEND::tuner_status::gain':[float], + 'FRONTEND::tuner_status::agc':[bool], + 'FRONTEND::tuner_status::valid':[bool], + 'FRONTEND::tuner_status::available_frequency':[str], + 'FRONTEND::tuner_status::available_bandwidth':[str], + 'FRONTEND::tuner_status::available_gain':[str], + 'FRONTEND::tuner_status::available_sample_rate':[str], + 'FRONTEND::tuner_status::reference_source':[int,long], + 'FRONTEND::tuner_status::output_format':[str], + 'FRONTEND::tuner_status::output_multicast':[str], + 'FRONTEND::tuner_status::output_vlan':[int,long], + 'FRONTEND::tuner_status::output_port':[int,long], + 'FRONTEND::tuner_status::decimation':[int,long], + 'FRONTEND::tuner_status::tuner_number':[int,long]} + + # get lists of all methods/functions defined in digital tuner idl + digital_tuner_idl = filter(lambda x: x[0]!='_', dir(TunerControl_idl._0_FRONTEND._objref_DigitalTuner)) + # In future, could also do this: + #import frontend + #digital_tuner_idl = filter(lambda x: x[0]!='_', dir(frontend.InDigitalTunerPort)) + + # map data types to DataSink port names + port_map = {'dataShort':'shortIn', + 'dataFloat':'floatIn', + 'dataUlong':'uLongIn', + 'dataDouble':'doubleIn', + 'dataUshort':'ushortIn', + 'dataLong':'longIn', + 'dataUlongLong':'ulonglongIn', + 'dataLongLong':'longlongIn', + 'dataOctet':'octetIn', + 'dataXML':'xmlIn', + 'dataChar':'charIn', + 'dataFile':'fileIn'} + + @classmethod + def devicePreLaunch(self): + pass + @classmethod + def devicePostLaunch(self): + pass + + @classmethod + def devicePreRelease(self): + pass + @classmethod + def devicePostRelease(self): + pass + + @classmethod + def getToBasicState(self, execparams={}, configure={}, initialize=True): + ''' Function used to launch device before each test case + With no arguments, uses execparams defined in global DEVICE_INFO['execparams'] dict, + configures props with values from prf, and initializes device. + If specified, execparams overrides those specified in DEVICE_INFO dict, and configure + overrides those specified in the prf. + Add special start-up commands for your device to deviceStartup() function + ''' + if not execparams: + #execparams = self.getPropertySet(kinds=('execparam',), modes=('readwrite', 'writeonly'), includeNil=False) + execparams = getPropertySet(DEVICE_INFO['SPD'],kinds=('execparam',), modes=('readwrite', 'writeonly'), includeNil=False) + execparams = dict([(x.id, any.from_any(x.value)) for x in execparams]) + execparams['DEBUG_LEVEL'] = DEBUG_LEVEL + #Add custom execparams here + for param,val in DEVICE_INFO['execparams'].items(): + execparams[param] = val + + #Add custom configure here + for param,val in DEVICE_INFO['configure'].items(): + configure[param] = val + + ### device-specific pre-launch commands + self.devicePreLaunch() + + print 'Launching device --',DEVICE_INFO['SPD'] + print '\texecparams:',str(execparams) + print '\tconfigure:',str(configure) + print '\tinitialize:',str(initialize) + + try: + # new method, use in versions >= 1.9 + self.dut = sb.launch(DEVICE_INFO['SPD'],execparams=execparams,configure=configure,initialize=initialize,impl=IMPL_ID) + except: + # deprecated, use in 1.8.x versions + self.dut = sb.Component(DEVICE_INFO['SPD'],execparams=execparams,configure=configure,initialize=initialize,impl=IMPL_ID) + + self.dut_ref = self.dut.ref._narrow(CF.Device) + + ### device-specific post-launch commands + self.devicePostLaunch() + + @classmethod + def getToShutdownState(self): + ''' Function used to release device after each test case + Add special shut-down commands for your device to deviceShutdown() function + ''' + + ### device-specific pre-release commands + self.devicePreRelease() + + if self.dut_ref: + self.dut_ref = None + if self.dut: + self.dut.releaseObject() + self.dut = None + + ### device-specific post-release commands + self.devicePostRelease() + + @classmethod + def setUpClass(self): + + self.spd_file = DEVICE_INFO['SPD'] + self.spd = SPDParser.parse(self.spd_file) + + try: + self.prf_file = self.spd.get_propertyfile().get_localfile().get_name() + if (self.prf_file[0] != '/'): + self.prf_file = os.path.join(os.path.dirname(self.spd_file), self.prf_file) + self.prf = PRFParser.parse(self.prf_file) + except: + self.prf_file = None + self.prf = None + + self.scd_file = self.spd.get_descriptor().get_localfile().get_name() + if (self.scd_file[0] != '/'): + self.scd_file = os.path.join(os.path.dirname(self.spd_file), self.scd_file) + self.scd = SCDParser.parse(self.scd_file) + + # create a map between prop ids and names + #if self.prf: + # self._props = prop_helpers.getPropNameDict(self.prf) + + self.testReport = ['\nDiscovering Tuner Types'] + self.getToBasicState() + + #Count # of each tuner type + props = self.dut.query([]) + props = properties.props_to_dict(props) + for tuner in props['FRONTEND::tuner_status']: + if tuner['FRONTEND::tuner_status::tuner_type'] in self.device_discovery.keys(): + self.device_discovery[tuner['FRONTEND::tuner_status::tuner_type']] += 1 + else: + self.device_discovery['UNKNOWN'] += 1 + + for k,v in self.device_discovery.items(): + if v > 0: + self.testReport.append(' Found %s %s'%(v,k)) + + self.getToShutdownState() + self.testReport.append('Completed discovery') + + def setUp(self): + + signal.signal(signal.SIGINT, self.tearDown) + signal.signal(signal.SIGTERM, self.tearDown) + signal.signal(signal.SIGQUIT, self.tearDown) + + self.getToBasicState() + + def tearDown(self): + self.getToShutdownState() + #self.testReport.append('\n%s - STOP'%test_name) + #ossie.utils.testing.ScaComponentTestCase.tearDown(self) + + @classmethod + def tearDownClass(self): + self.testReport.append('\nFRONTEND Test - Completed') + for line in self.testReport: + print >> sys.stderr, line + + print >> sys.stderr, '\nReport Statistics:' + MAX_LHS_WIDTH=40 + MIN_SEPARATION=5 + total_nonsilent_checks=0 + for key in sorted(self.testReportStats.keys()): + if key == 'Total checks made': + continue + total_nonsilent_checks+=self.testReportStats[key] + print >> sys.stderr, ' ',key[:MAX_LHS_WIDTH], '.'*(MIN_SEPARATION+MAX_LHS_WIDTH-len(key[:MAX_LHS_WIDTH])), self.testReportStats[key] + if 'Total checks made' not in self.testReportStats: + self.testReportStats['Total checks made'] = 0 + key='Checks with silent results' + total_silent_checks=self.testReportStats['Total checks made']-total_nonsilent_checks + print >> sys.stderr, ' ',key[:MAX_LHS_WIDTH], '.'*(MIN_SEPARATION+MAX_LHS_WIDTH-len(key[:MAX_LHS_WIDTH])), total_silent_checks + key='Total checks made' + print >> sys.stderr, ' ',key[:MAX_LHS_WIDTH], '.'*(MIN_SEPARATION+MAX_LHS_WIDTH-len(key[:MAX_LHS_WIDTH])), self.testReportStats[key] + + #self.printTestReport() + + def skipTest(self, msg=None, silent=False): + if msg == None: + msg = 'Skipping test %s'%(self.id().split('.')[-1]) + if not silent: + self.testReport.append(msg) + raise nose.SkipTest + + def attachChanInput(self): + pass + + def detachChanInput(self): + pass + + def testFRONTEND_6(self): + ''' TX 0 - Not Implemented + ''' + self.testReport.append('\nFRONTEND Test 6 - TX - Not implemented!') + #self.testReport.append('\nFRONTEND Test 6 - TX') + #self.testReport.append('\nFRONTEND Test 6 - Completed') + + def testFRONTEND_1_1(self): + ''' ALL 1.1 Verify device_kind property + ''' + props = self.dut.query([]) + props = properties.props_to_dict(props) + #pp(props) + self.check(props.has_key('DCE:cdc5ee18-7ceb-4ae6-bf4c-31f983179b4d'), True, 'Has device_kind property') + self.check(props['DCE:cdc5ee18-7ceb-4ae6-bf4c-31f983179b4d'], 'FRONTEND::TUNER', 'device_kind = FRONTEND::TUNER') + + def testFRONTEND_1_2(self): + ''' ALL 1.2 Verify that there is a device_model property + ''' + props = self.dut.query([]) + props = properties.props_to_dict(props) + self.check(props.has_key('DCE:0f99b2e4-9903-4631-9846-ff349d18ecfb'), True, 'Has device_model property') + + def testFRONTEND_1_3(self): + ''' ALL 1.3 Verify that there is a FRONTEND Status property + ''' + props = self.dut.query([]) + props = properties.props_to_dict(props) + self.check(props.has_key('FRONTEND::tuner_status'), True, 'Has tuner_status property') + # check for required fields + #pp(props['FRONTEND::tuner_status']) + if (len(props['FRONTEND::tuner_status']) == 0): + print '\nERROR - tuner_status is empty. Check that the unit test is configured to reach the target device hardware.\n' + self.check(False,True,'\nERROR - tuner_status is empty. Check that the unit test is configured to reach the target device hardware.') + + success = True + for field in self.FE_tuner_status_fields_req: + if not self.check(props['FRONTEND::tuner_status'][-1].has_key(field), True, 'tuner_status has %s required field'%field): + success = False + if not success: + self.check(False,True,'\nERROR - tuner_status does not have all required fields.') + + + def testFRONTEND_1_4(self): + ''' ALL 1.4 Verify there is a tuner port + ''' + #Attempt to get both ports and compare if None, then xor (^) the boolean result + reason = 'both' + try: + + DigitalTuner = self.dut.getPort('DigitalTuner_in') + print "&&&&&&&&", DigitalTuner + except: + print "%%%%%%%%%%%" + DigitalTuner= None + reason = 'analog' + try: + AnalogTuner = self.dut.getPort('AnalogTuner_in') + print "&&&&&&&&", AnalogTuner + except: + print "%%%%%%%%%%%" + AnalogTuner = None + reason = 'digital' + if (DigitalTuner==None) and (AnalogTuner==None): + reason = 'none' + self.check( (DigitalTuner== None)^(AnalogTuner== None), True, 'Has an analog or digital tuner input port (%s)'%reason) + + + + def testFRONTEND_3_1_1(self): + ''' RX_DIG 1.1 Allocate a single tuner + ''' + t1 = self._generateRD() + t1Alloc = self._generateAlloc(t1) + if not self.check(self.dut_ref.allocateCapacity(t1Alloc), True, 'Can allocate single RX_DIGITIZER') and DEBUG_LEVEL >= 4: + # Do some DEBUG + print 'RX_DIG 1.1 FAILURE - Can allocate single RX_DIGITIZER' + pp(t1) + pp(t1Alloc) + + # Deallocate the tuner + self.dut_ref.deallocateCapacity(t1Alloc) + self.check(True, True, 'Deallocated RX_DIGITIZER without error') + + def testFRONTEND_3_1_2(self): + ''' RX_DIG 1.2 Allocate to max tuners + ''' + ts = [] + for t in range(0,self.device_discovery['RX_DIGITIZER']): + ts.append(self._generateRD()) + tAlloc = self._generateAlloc(ts[-1]) + if not self.check(self.dut_ref.allocateCapacity(tAlloc), True, 'Allocating RX_DIGITIZER number: %s'%(t), silentSuccess=True) and DEBUG_LEVEL >= 4: + # Do some DEBUG + print 'RX_DIG 1.2 FAILURE - Allocating RX_DIGITIZER number: %s'%(t) + pp(ts) + pp(tAlloc) + self.check(True, True, 'Allocated to max RX_DIGITIZERs') + + # deallocate everything + for t in ts: + tAlloc = self._generateAlloc(t) + self.dut_ref.deallocateCapacity(tAlloc) + self.check(True, True, 'Deallocated all RX_DIGITIZER tuners') + + def testFRONTEND_3_1_3(self): + ''' RX_DIG 1.3 Verify over-allocation failure + ''' + + # Allocate to max tuners + ts = [] + for t in range(0,self.device_discovery['RX_DIGITIZER']): + ts.append(self._generateRD()) + tAlloc = self._generateAlloc(ts[-1]) + if not self.check(self.dut_ref.allocateCapacity(tAlloc), True, 'Allocating RX_DIGITIZER number: %s'%(t), silentSuccess=True) and DEBUG_LEVEL >= 4: + # Do some DEBUG + print 'RX_DIG 1.3 FAILURE - Allocating RX_DIGITIZER number: %s'%(t) + pp(ts) + pp(tAlloc) + self.check(True, True, 'Allocated to max RX_DIGITIZERs') + + # Verify over-allocation failure + over_t = self._generateRD() + over_tAlloc = self._generateAlloc(over_t) + if not self.check(self.dut_ref.allocateCapacity(over_tAlloc), False, 'Over-allocate RX_DIGITIZER check') and DEBUG_LEVEL >= 4: + # Do some DEBUG + print 'RX_DIG 1.3 FAILURE - Over-allocate RX_DIGITIZER check' + pp(ts) + pp(over_t) + pp(over_tAlloc) + try: + self.dut_ref.deallocateCapacity(over_tAlloc) + except CF.Device.InvalidCapacity, e: + # Deallocating shouldn't be required if the allocation failed so we would expect this deallocation to be invalid + pass + + # deallocate everything + for t in ts: + tAlloc = self._generateAlloc(t) + self.dut_ref.deallocateCapacity(tAlloc) + self.check(True, True, 'Deallocated all RX_DIGITIZER tuners') + + def testFRONTEND_3_2_01(self): + ''' RX_DIG 2.1 Verify InvalidCapacityException on repeat Alloc ID + ''' + ttype = 'RX_DIGITIZER' + tuner = self._generateRD() + alloc_id = tuner['ALLOC_ID'] + tAlloc = self._generateAlloc(tuner) + if not self.check(self.dut_ref.allocateCapacity(tAlloc), True, 'Allocate single %s with alloc id: %s'%(ttype,alloc_id)) and DEBUG_LEVEL >= 4: + # Do some DEBUG + print 'RX_DIG 2.1 FAILURE - Allocate single %s with alloc id: %s'%(ttype,alloc_id) + pp(tuner) + pp(tAlloc) + try: + retval = self.dut_ref.allocateCapacity(tAlloc) + except CF.Device.InvalidCapacity: + self.check(True, True, 'Allocate second %s with same alloc id check (produces InvalidCapacity exception)'%(ttype)) + except Exception, e: + self.check(False, True, 'Allocate second %s with same alloc id check (produces %s exception, should produce InvalidCapacity exception)'%(ttype,e.__class__.__name__)) + else: + self.check(False, True, 'Allocate second %s with same alloc id check (returns %s, should produce InvalidCapacity exception)'%(ttype,retval)) + self.dut_ref.deallocateCapacity(tAlloc) # this will deallocate the original successful allocation + + def testFRONTEND_3_2_02(self): + ''' RX_DIG 2.2 Verify InvalidCapacityException on malformed request (missing alloc ID) + ''' + ttype = 'RX_DIGITIZER' + tuner = self._generateRD() + # First, check empty string + tuner['ALLOC_ID'] = '' + tAlloc = self._generateAlloc(tuner) + try: + retval = self.dut_ref.allocateCapacity(tAlloc) + except CF.Device.InvalidCapacity: + self.check(True, True, 'Allocate %s with malformed request (alloc_id="") check (produces InvalidCapcity exception)'%(ttype)) + except Exception, e: + self.check(False, True, 'Allocate %s with malformed request (alloc_id="") check (produces %s exception, should produce InvalidCapacity exception)'%(ttype,e.__class__.__name__)) + else: + self.check(False, True, 'Allocate %s with malformed request (alloc_id="") check (returns %s, should produce InvalidCapacity exception)'%(ttype,retval)) + try: + self.dut_ref.deallocateCapacity(tAlloc) + except CF.Device.InvalidCapacity, e: + # Deallocating shouldn't be required if the allocation failed so we would expect this deallocation to be invalid + pass + + + def testFRONTEND_3_2_03(self): + ''' RX_DIG 2.3 Verify InvalidCapacityException on malformed request (missing alloc ID) + ''' + ttype = 'RX_DIGITIZER' + tuner = self._generateRD() + # now try None + tuner['ALLOC_ID'] = None + tAlloc = self._generateAlloc(tuner) + try: + retval = self.dut_ref.allocateCapacity(tAlloc) + except CF.Device.InvalidCapacity: + self.check(True, True, 'Allocate %s with malformed request (alloc_id=None) check (produces InvalidCapcity exception)'%(ttype)) + except Exception, e: + self.check(False, True, 'Allocate %s with malformed request (alloc_id=None) check (produces %s exception, should produce InvalidCapacity exception)'%(ttype,e.__class__.__name__)) + else: + self.check(False, True, 'Allocate %s with malformed request (alloc_id=None) check (returns %s, should produce InvalidCapacity exception)'%(ttype,retval)) + try: + self.dut_ref.deallocateCapacity(tAlloc) + except CF.Device.InvalidCapacity, e: + # Deallocating shouldn't be required if the allocation failed so we would expect this deallocation to be invalid + pass + + def testFRONTEND_3_2_04(self): + ''' RX_DIG 2.4 Verify failure on alloc with invalid group id (generate new uuid) + ''' + ttype = 'RX_DIGITIZER' + tuner = self._generateRD() + tuner['GROUP_ID'] = str(uuid.uuid4()) + tAlloc = self._generateAlloc(tuner) + try: + retval = self.dut_ref.allocateCapacity(tAlloc) + except Exception, e: + self.check(False, True, 'Allocate %s with invalid GROUP_ID check (produces %s exception, should return False)'%(ttype,e.__class__.__name__)) + else: + self.check(False, retval, 'Allocate %s with invalid GROUP_ID check'%(ttype)) + try: + self.dut_ref.deallocateCapacity(tAlloc) + except CF.Device.InvalidCapacity, e: + # Deallocating shouldn't be required if the allocation failed so we would expect this deallocation to be invalid + pass + + def testFRONTEND_3_2_05(self): + ''' RX_DIG 2.5 Verify failure on alloc with invalid rf flow id (generate new uuid) + ''' + ttype = 'RX_DIGITIZER' + tuner = self._generateRD() + tuner['RF_FLOW_ID'] = str(uuid.uuid4()) + tAlloc = self._generateAlloc(tuner) + try: + retval = self.dut_ref.allocateCapacity(tAlloc) + except Exception, e: + self.check(False, True, 'Allocate %s with invalid RF_FLOW_ID check (produces %s exception, should return False)'%(ttype,e.__class__.__name__)) + else: + self.check(False, retval, 'Allocate %s with invalid RF_FLOW_ID check'%(ttype)) + try: + self.dut_ref.deallocateCapacity(tAlloc) + except CF.Device.InvalidCapacity, e: + # Deallocating shouldn't be required if the allocation failed so we would expect this deallocation to be invalid + pass + + + def testFRONTEND_3_2_06(self): + ''' RX_DIG 2.6 Allocate Listener via listener struct + ''' + tuner = self._generateRD() + ttype='RX_DIGITIZER' + tAlloc = self._generateAlloc(tuner) + #self.dut_ref.allocateCapacity(tAlloc) + if not self.check(self.dut_ref.allocateCapacity(tAlloc), True, 'Allocate controller %s'%(ttype)) and DEBUG_LEVEL >= 4: + # Do some DEBUG + print 'RX_DIG 2.6 FAILURE - Allocate controller %s'%(ttype) + pp(tuner) + pp(tAlloc) + + tListener = self._generateListener(tuner) + tListenerAlloc = self._generateListenerAlloc(tListener) + if not self.check(self.dut_ref.allocateCapacity(tListenerAlloc), True, 'Allocate listener %s using listener allocation struct'%(ttype)) and DEBUG_LEVEL >= 4: + # Do some DEBUG + print 'RX_DIG 2.6 FAILURE - Allocate listener %s using listener allocation struct'%(ttype) + pp(tuner) + pp(tAlloc) + pp(tListener) + pp(tListenerAlloc) + + print "DEBUG -- done with allocations, now time to deallocate" + + # Deallocate listener using listener allocation struct + try: + self.dut_ref.deallocateCapacity(tListenerAlloc) + except Exception,e: + self.check(False, True, 'Deallocated listener %s using listener allocation struct without error'%(ttype)) + else: + self.check(True, True, 'Deallocated listener %s using listener allocation struct without error'%(ttype)) + + print "DEBUG -- done with deallocation of listener, now time to deallocate the controller" + self.dut_ref.deallocateCapacity(tAlloc) + + def testFRONTEND_3_2_07(self): + ''' RX_DIG 2.7 Allocate Listener via tuner allocation struct + ''' + tuner = self._generateRD() + ttype='RX_DIGITIZER' + tAlloc = self._generateAlloc(tuner) + + + pp(tuner) + if not self.dut_ref.allocateCapacity(tAlloc) and DEBUG_LEVEL >= 4: + # Do some DEBUG + print 'RX_DIG 2.7 FAILURE - Allocate controller %s'%(ttype) + pp(tuner) + pp(tAlloc) + + tunerStatusProp = self._getTunerStatusProp(tuner['ALLOC_ID']) + tListener = copy.deepcopy(tuner) + tListener['ALLOC_ID'] = str(uuid.uuid4()) + tListener['CONTROL'] = False + tListener['CF'] = tunerStatusProp['FRONTEND::tuner_status::center_frequency'] + tListener['BW'] = tunerStatusProp['FRONTEND::tuner_status::bandwidth'] + tListenerAlloc = self._generateAlloc(tListener) + + if not self.check(self.dut_ref.allocateCapacity(tListenerAlloc), True, 'Allocate listener %s using tuner allocation struct'%(ttype)) and DEBUG_LEVEL >= 4: + # Do some DEBUG + print 'RX_DIG 2.7 FAILURE - Allocate listener %s using tuner allocation struct'%(ttype) + pp(tuner) + pp(tAlloc) + pp(tListener) + pp(tListenerAlloc) + + # Deallocate listener using tuner allocation struct + try: + self.dut_ref.deallocateCapacity(tListenerAlloc) + except Exception,e: + self.check(False, True, 'Deallocated listener %s using tuner allocation struct without error'%(ttype)) + else: + self.check(True, True, 'Deallocated listener %s using tuner allocation struct without error'%(ttype)) + self.dut_ref.deallocateCapacity(tAlloc) + + def testFRONTEND_3_2_08(self): + ''' RX_DIG 2.8 Verify failure on listener alloc w/o matching existing alloc id + ''' + tuner = self._generateRD() + ttype='RX_DIGITIZER' + tAlloc = self._generateAlloc(tuner) + if not self.dut_ref.allocateCapacity(tAlloc) and DEBUG_LEVEL >= 4: + # Do some DEBUG + print 'RX_DIG 2.8 FAILURE - Controller allocation' + pp(tuner) + pp(tAlloc) + tListener = self._generateListener(tuner) + tListener['ALLOC_ID'] = str(uuid.uuid4()) + tListenerAlloc = self._generateListenerAlloc(tListener) + if not self.check(self.dut_ref.allocateCapacity(tListenerAlloc), False, 'Allocate listener %s using listener allocation struct with bad allocation id check'%(ttype)) and DEBUG_LEVEL >= 4: + # Do some DEBUG + print 'RX_DIG 2.8 FAILURE - Allocate listener %s using listener allocation struct with bad allocation id check'%(ttype) + pp(tuner) + pp(tAlloc) + pp(tListener) + pp(tListenerAlloc) + try: + self.dut_ref.deallocateCapacity(tListenerAlloc) + except CF.Device.InvalidCapacity, e: + # Deallocating shouldn't be required if the allocation failed so we would expect this deallocation to be invalid + pass + + self.dut_ref.deallocateCapacity(tAlloc) + + def testFRONTEND_3_2_09(self): + ''' RX_DIG 2.9 Verify failure on listener alloc w/o suitable existing channel (bad freq) + ''' + tuner = self._generateRD() + ttype='RX_DIGITIZER' + tAlloc = self._generateAlloc(tuner) + self.dut_ref.allocateCapacity(tAlloc) + tListener = copy.deepcopy(tuner) + tListener['ALLOC_ID'] = str(uuid.uuid4()) + tListener['CF'] = tuner['CF'] * 2.0 + #tListener['BW'] = tuner['BW'] * 2.0 + tListener['SR'] = tuner['SR'] * 2.0 + #rdListener = self._generateRD() + tListener['CONTROL'] = False + tListenerAlloc = self._generateAlloc(tListener) + self.check(self.dut_ref.allocateCapacity(tListenerAlloc), False, 'Allocate listener %s using tuner allocation struct without suitable controller %s check'%(ttype,ttype)) + try: + self.dut_ref.deallocateCapacity(tListenerAlloc) + except CF.Device.InvalidCapacity, e: + # Deallocating shouldn't be required if the allocation failed so we would expect this deallocation to be invalid + pass + self.dut_ref.deallocateCapacity(tAlloc) + + def testFRONTEND_3_2_10(self): + ''' RX_DIG 2.10 Verify listener allocations are deallocated following deallocation of controlling allocation + ''' + tuner = self._generateRD() + ttype='RX_DIGITIZER' + tAlloc = self._generateAlloc(tuner) + self.dut_ref.allocateCapacity(tAlloc) + tListener = self._generateListener(tuner) + tListenerAlloc = self._generateListenerAlloc(tListener) + self.check(self.dut_ref.allocateCapacity(tListenerAlloc), True, 'Allocate listener %s using listener allocation struct'%(ttype)) + try: + self.dut_ref.deallocateCapacity(tAlloc) + except Exception, e: + self.check(False, True, 'Deallocated controller %s which has a listener allocation'%(ttype)) + else: + self.check(True, True, 'Deallocated controller %s which has a listener allocation'%(ttype)) + has_listener = self._tunerStatusHasAllocId(tListener['LISTENER_ID']) + self.check(has_listener, False, 'Listener %s deallocated as result of controller %s deallocation'%(ttype,ttype)) + try: + self.dut_ref.deallocateCapacity(tListenerAlloc) + except CF.Device.InvalidCapacity, e: + # Deallocating shouldn't be required if the allocation failed so we would expect this deallocation to be invalid + pass + + def testFRONTEND_3_2_11(self): + ''' RX_DIG 2.11 allocate below minimum center frequency + ''' + tuner = self._generateRD() + ttype='RX_DIGITIZER' + low=DEVICE_INFO['RX_DIGITIZER']['CF_MIN'] + + tuner['CF'] = float(int(low / 2.0)) + tAlloc = self._generateAlloc(tuner) + self.check(self.dut_ref.allocateCapacity(tAlloc), False, 'Allocate %s below lowest frequency in range(%s < %s)'%(ttype,tuner['CF'],low)) + try: + self.dut_ref.deallocateCapacity(tAlloc) + except CF.Device.InvalidCapacity, e: + # Deallocating shouldn't be required if the allocation failed so we would expect this deallocation to be invalid + pass + + def testFRONTEND_3_2_12(self): + ''' RX_DIG 2.12 allocate above maximum center frequency + ''' + tuner = self._generateRD() + ttype='RX_DIGITIZER' + high=DEVICE_INFO['RX_DIGITIZER']['CF_MAX'] + + tuner['CF'] = float(high * 2.0) + tAlloc = self._generateAlloc(tuner) + self.check(self.dut_ref.allocateCapacity(tAlloc), False, 'Allocate %s above highest frequency in range(%s > %s)'%(ttype,tuner['CF'],high)) + try: + self.dut_ref.deallocateCapacity(tAlloc) + except CF.Device.InvalidCapacity, e: + # Deallocating shouldn't be required if the allocation failed so we would expect this deallocation to be invalid + pass + + def testFRONTEND_3_2_13a(self): + ''' RX_DIG 2.13a allocate at minimum center frequency + ''' + tuner = self._generateRD() + ttype='RX_DIGITIZER' + low=DEVICE_INFO['RX_DIGITIZER']['CF_MIN'] + + tuner['CF'] = float(low) + tAlloc = self._generateAlloc(tuner) + if not self.check(self.dut_ref.allocateCapacity(tAlloc), True, 'Allocate %s at lowest center frequency in range (%s)'%(ttype,low)) and DEBUG_LEVEL >= 4: + # Do some DEBUG + print 'RX_DIG 2.13a FAILURE' + pp(tuner) + pp(tAlloc) + try: + self.dut_ref.deallocateCapacity(tAlloc) + except CF.Device.InvalidCapacity, e: + # Deallocating shouldn't be required if the allocation failed so we would expect this deallocation to be invalid + pass + + def testFRONTEND_3_2_13b(self): + ''' RX_DIG 2.13b allocate just below minimum center frequency (partial coverage, should fail) + ''' + tuner = self._generateRD() + ttype='RX_DIGITIZER' + low=DEVICE_INFO['RX_DIGITIZER']['CF_MIN'] + bw=DEVICE_INFO['RX_DIGITIZER']['BW_MIN'] + sr=DEVICE_INFO['RX_DIGITIZER']['SR_MIN'] + bw_sr = max(bw,sr) + print low,bw,sr + tuner['CF'] = float(low-bw_sr/2.0) + tuner['BW'] = float(bw) + tuner['SR'] = float(sr) + tAlloc = self._generateAlloc(tuner) + if not self.check(self.dut_ref.allocateCapacity(tAlloc), False, 'Check failure when allocating partially covered %s channel at lowest frequency in range (%s)'%(ttype,low)) and DEBUG_LEVEL >= 4: + # Do some DEBUG + print 'RX_DIG 2.13b FAILURE' + pp(tuner) + pp(tAlloc) + try: + self.dut_ref.deallocateCapacity(tAlloc) + except CF.Device.InvalidCapacity, e: + # Deallocating shouldn't be required if the allocation failed so we would expect this deallocation to be invalid + pass + + def testFRONTEND_3_2_14a(self): + ''' RX_DIG 2.14a allocate at maximum center frequency + ''' + tuner = self._generateRD() + ttype='RX_DIGITIZER' + high=DEVICE_INFO['RX_DIGITIZER']['CF_MAX'] + + tuner['CF'] = float(high) + tAlloc = self._generateAlloc(tuner) + if not self.check(self.dut_ref.allocateCapacity(tAlloc), True, 'Allocate %s at highest center frequency in range(%s)'%(ttype,high)) and DEBUG_LEVEL >= 4: + # Do some DEBUG + print 'RX_DIG 2.14a FAILURE' + pp(tuner) + pp(tAlloc) + self.dut_ref.deallocateCapacity(tAlloc) + + def testFRONTEND_3_2_14b(self): + ''' RX_DIG 2.14b allocate just above maximum center frequency (partial coverage, should fail) + ''' + tuner = self._generateRD() + ttype='RX_DIGITIZER' + high=DEVICE_INFO['RX_DIGITIZER']['CF_MAX'] + bw=DEVICE_INFO['RX_DIGITIZER']['BW_MIN'] + sr=DEVICE_INFO['RX_DIGITIZER']['SR_MIN'] + bw_sr = max(bw,sr) + + tuner['CF'] = float(high+bw_sr/2.0) + tuner['BW'] = float(bw) + tuner['SR'] = float(sr) + tAlloc = self._generateAlloc(tuner) + if not self.check(self.dut_ref.allocateCapacity(tAlloc), False, 'Check failure when allocating partially covered %s channel at highest frequency in range (%s)'%(ttype,high)) and DEBUG_LEVEL >= 4: + # Do some DEBUG + print 'RX_DIG 2.14b FAILURE' + pp(tuner) + pp(tAlloc) + try: + self.dut_ref.deallocateCapacity(tAlloc) + except CF.Device.InvalidCapacity, e: + # Deallocating shouldn't be required if the allocation failed so we would expect this deallocation to be invalid + pass + + def testFRONTEND_3_2_15(self): + ''' RX_DIG 2.15 allocate with bandwidth = 0 (succeed) + ''' + ttype='RX_DIGITIZER' + tuner = self._generateRD() + + tuner['BW'] = float(0.0) + tAlloc = self._generateAlloc(tuner) + self.check(self.dut_ref.allocateCapacity(tAlloc), True, 'Allocate %s without specifying bandwidth (BW=0)'%(ttype)) + self.dut_ref.deallocateCapacity(tAlloc) + + def testFRONTEND_3_2_16(self): + ''' RX_DIG 2.16 allocate with sample rate = 0 (succeed) + ''' + ttype='RX_DIGITIZER' + tuner = self._generateRD() + + tuner['SR'] = float(0.0) + tAlloc = self._generateAlloc(tuner) + self.check(self.dut_ref.allocateCapacity(tAlloc), True, 'Allocate %s without specifying sample rate (SR=0)'%(ttype)) + self.dut_ref.deallocateCapacity(tAlloc) + + def testFRONTEND_3_2_17(self): + ''' RX_DIG 2.17 allocate below minimum bandwidth capable (succeed) + ''' + ttype='RX_DIGITIZER' + tuner = self._generateRD() + low=DEVICE_INFO['RX_DIGITIZER']['BW_MIN'] + + tuner['BW'] = float(int(low / 1.333333333)) + tuner['SR'] = float(0) + tAlloc = self._generateAlloc(tuner) + self.check(self.dut_ref.allocateCapacity(tAlloc), True, 'Allocate %s below lowest bandwidth in range(%s < %s)'%(ttype,tuner['BW'],low)) + self.dut_ref.deallocateCapacity(tAlloc) + + def testFRONTEND_3_2_18(self): + ''' RX_DIG 2.18 allocate above maximum bandwidth capable (fail) + ''' + ttype='RX_DIGITIZER' + tuner = self._generateRD() + high=DEVICE_INFO['RX_DIGITIZER']['BW_MAX'] + + if self.check(high, 0, 'Upper bandwidth range set to 0, cannot test above highest bandwidth', silentFailure=True, successMsg='info'): + return + + tuner['BW'] = float(high * 2.0) + tuner['SR'] = float(0) + tAlloc = self._generateAlloc(tuner) + failed = not self.check(self.dut_ref.allocateCapacity(tAlloc), False, 'Allocate %s above highest bandwidth in range(%s > %s)'%(ttype,tuner['BW'],high)) + # DEBUG + ''' + if failed: + print 'DEBUG - failed max bw alloc test' + print 'alloc request:' + pp(tuner) + print 'tuner status:' + pp(self._getTunerStatusProp(tuner['ALLOC_ID'])) + print 'END DEBUG - failed max bw alloc test' + ''' + try: + self.dut_ref.deallocateCapacity(tAlloc) + except CF.Device.InvalidCapacity, e: + # Deallocating shouldn't be required if the allocation failed so we would expect this deallocation to be invalid + pass + + def testFRONTEND_3_2_19(self): + ''' RX_DIG 2.19 allocate outside of bandwidth tolerance (fail) + ''' + ttype='RX_DIGITIZER' + tuner = self._generateRD() + low=DEVICE_INFO['RX_DIGITIZER']['BW_MIN'] + + if self.check(low, 0, 'Lower bandwidth range set to 0, cannot test tolerance below lowest bandwidth', silentFailure=True, successMsg='info'): + return + + tuner['BW'] = float(int(low / 2.0)) + tuner['BW_TOLERANCE'] = float(10.0) + tuner['SR'] = float(0) + tAlloc = self._generateAlloc(tuner) + failed = not self.check(self.dut_ref.allocateCapacity(tAlloc), False, 'Allocate %s outside of bandwidth tolerance (%s + %s%% < %s'%(ttype,tuner['BW'],tuner['BW_TOLERANCE'],low)) + # DEBUG + ''' + if failed: + print 'DEBUG - failed outside bw tolerance test' + print 'alloc request:' + pp(tuner) + print 'tuner status:' + pp(self._getTunerStatusProp(tuner['ALLOC_ID'])) + print 'END DEBUG - failed outside bw tolerance test' + ''' + try: + self.dut_ref.deallocateCapacity(tAlloc) + except CF.Device.InvalidCapacity, e: + # Deallocating shouldn't be required if the allocation failed so we would expect this deallocation to be invalid + pass + + def testFRONTEND_3_2_20(self): + ''' RX_DIG 2.20 allocate below minimum sample rate capable (succeed) + ''' + ttype='RX_DIGITIZER' + tuner = self._generateRD() + low=DEVICE_INFO['RX_DIGITIZER']['SR_MIN'] + + tuner['SR'] = float(int(low / 1.333333333)) + tuner['BW'] = float(0) + tAlloc = self._generateAlloc(tuner) + self.check(self.dut_ref.allocateCapacity(tAlloc), True, 'Allocate %s below lowest sample rate in range(%s < %s)'%(ttype,tuner['SR'],low)) + self.dut_ref.deallocateCapacity(tAlloc) + + def testFRONTEND_3_2_21(self): + ''' RX_DIG 2.21 allocate above maximum sample rate capable (fail) + ''' + ttype='RX_DIGITIZER' + tuner = self._generateRD() + high=DEVICE_INFO['RX_DIGITIZER']['SR_MAX'] + + tuner['SR'] = float(high * 2.0) + tuner['BW'] = float(0) + tAlloc = self._generateAlloc(tuner) + self.check(self.dut_ref.allocateCapacity(tAlloc), False, 'Allocate %s above highest sample rate in range(%s > %s)'%(ttype,tuner['SR'],high)) + try: + self.dut_ref.deallocateCapacity(tAlloc) + except CF.Device.InvalidCapacity, e: + # Deallocating shouldn't be required if the allocation failed so we would expect this deallocation to be invalid + pass + + def testFRONTEND_3_2_22(self): + ''' RX_DIG 2.22 allocate outside of sample rate tolerance (fail) + ''' + ttype='RX_DIGITIZER' + tuner = self._generateRD() + low=DEVICE_INFO['RX_DIGITIZER']['SR_MIN'] + + tuner['SR'] = float(int(low / 2.0)) + tuner['SR_TOLERANCE'] = float(10.0) + tuner['BW'] = float(0) + tAlloc = self._generateAlloc(tuner) + failed = not self.check(self.dut_ref.allocateCapacity(tAlloc), False, 'Allocate %s outside of sample rate tolerance (%s + %s%% < %s'%(ttype,tuner['SR'],tuner['SR_TOLERANCE'],low)) + # DEBUG + ''' + if failed: + print 'DEBUG - failed outside sr tolerance test' + print 'alloc request:' + pp(tuner) + print 'tuner status:' + pp(self._getTunerStatusProp(tuner['ALLOC_ID'])) + print 'END DEBUG - failed outside sr tolerance test' + ''' + try: + self.dut_ref.deallocateCapacity(tAlloc) + except CF.Device.InvalidCapacity, e: + # Deallocating shouldn't be required if the allocation failed so we would expect this deallocation to be invalid + pass + + def testFRONTEND_3_3_01(self): + ''' RX_DIG 3.1 Verify connection to Tuner port + ''' + port_name = 'DigitalTuner_in' + tuner_control = self.dut.getPort('DigitalTuner_in') + tuner_control._narrow(FRONTEND.FrontendTuner) + + # Verify connection to Tuner port + self.check(tuner_control != None, True, 'Can get %s port'%(port_name)) + self.check(CORBA.is_nil(tuner_control), False, 'Port reference is not nil') + + def testFRONTEND_3_3_02(self): + ''' RX_DIG 3.2 Verify digital tuner port functions exist + ''' + port_name = 'DigitalTuner_in' + tuner_control = self.dut.getPort('DigitalTuner_in') + tuner_control._narrow(FRONTEND.FrontendTuner) + function_list = self.digital_tuner_idl + + for attr in function_list: + try: + self.check(callable(getattr(tuner_control,attr)), True, '%s port has function %s'%(port_name,attr)) + except AttributeError, e: + self.check(False, True, '%s port has function %s'%(port_name,attr)) + + def testFRONTEND_3_3_03(self): + ''' RX_DIG 3.3 Verify digital tuner port getTunerType function + ''' + port_name = 'DigitalTuner_in' + tuner_control = self.dut.getPort('DigitalTuner_in') + tuner_control._narrow(FRONTEND.FrontendTuner) + controller = self._generateRD() + + # make allocations + controller_id = controller['ALLOC_ID'] + controller_alloc = self._generateAlloc(controller) + self.check(self.dut_ref.allocateCapacity(controller_alloc),True,'ERROR -- could not allocate controller',throwOnFailure=True,silentSuccess=True) + + try: + status_val = self._getTunerStatusProp(controller_id, 'FRONTEND::tuner_status::tuner_type') + except KeyError: + status_val = None + + try: + resp = tuner_control.getTunerType(controller_id) + except FRONTEND.NotSupportedException: + self.check(True,True,'%s.getTunerType produces NotSupportedException'%(port_name)) + except Exception, e: + self.check(True,False,'%s.getTunerType produces exception %s'%(port_name,e)) + else: + self.check(type(resp), str, '%s.getTunerType has correct return type'%(port_name)) + self.check(resp in ['RX','TX','RX_DIGITIZER','CHANNELIZER','RX_DIGITIZER_CHANNELIZER','DDC'], True, '%s.getTunerType return value is within expected results'%(port_name)) + self.check(resp, 'RX_DIGITIZER', '%s.getTunerType return value is correct for RX_DIGITIZER'%(port_name)) + if status_val!=None: + self.check(resp, status_val, '%s.getTunerType matches frontend tuner status prop'%(port_name)) + + self.dut_ref.deallocateCapacity(controller_alloc) + + def testFRONTEND_3_3_04(self): + ''' RX_DIG 3.4 Verify digital tuner port getTunerDeviceControl function w/ controller + ''' + port_name = 'DigitalTuner_in' + tuner_control = self.dut.getPort('DigitalTuner_in') + tuner_control._narrow(FRONTEND.FrontendTuner) + controller = self._generateRD() + + # make allocations + controller_id = controller['ALLOC_ID'] + controller_alloc = self._generateAlloc(controller) + self.check(self.dut_ref.allocateCapacity(controller_alloc),True,'%s.getTunerDeviceControl(controller_id) ERROR -- could not allocate controller'%(port_name),throwOnFailure=True,silentSuccess=True) + + try: + resp = tuner_control.getTunerDeviceControl(controller_id) + except FRONTEND.NotSupportedException: + self.check(True,True,'%s.getTunerDeviceControl(controller_id) produces NotSupportedException'%(port_name)) + except Exception, e: + self.check(True,False,'%s.getTunerDeviceControl(controller_id) produces exception %s'%(port_name,e)) + else: + self.check(type(resp), bool, '%s.getTunerDeviceControl(controller_id) has correct return type'%(port_name)) + self.check(resp in [True,False], True, '%s.getTunerDeviceControl(controller_id) return value is within expected results'%(port_name)) + self.check(resp, True, '%s.getTunerDeviceControl(controller_id) return True for controller alloc_id'%(port_name)) + + self.dut_ref.deallocateCapacity(controller_alloc) + + def testFRONTEND_3_3_05(self): + ''' RX_DIG 3.5 Verify digital tuner port getTunerDeviceControl function w/ listener + ''' + port_name = 'DigitalTuner_in' + tuner_control = self.dut.getPort('DigitalTuner_in') + tuner_control._narrow(FRONTEND.FrontendTuner) + + controller = self._generateRD() + pp(controller) + listener = self._generateListener(controller) + + # make allocations + controller_id = controller['ALLOC_ID'] + controller_alloc = self._generateAlloc(controller) + self.check(self.dut_ref.allocateCapacity(controller_alloc),True,'%s.getTunerDeviceControl(listener_id) ERROR -- could not allocate controller'%(port_name),throwOnFailure=True,silentSuccess=True) + listener_id = listener['LISTENER_ID'] + listener_alloc = self._generateListenerAlloc(listener) + self.check(self.dut_ref.allocateCapacity(listener_alloc),True,'%s.getTunerDeviceControl(listener_id) ERROR -- could not allocate listener'%(port_name),throwOnFailure=True,silentSuccess=True) + + try: + resp = tuner_control.getTunerDeviceControl(listener_id) + except FRONTEND.NotSupportedException: + self.check(True,True,'%s.getTunerDeviceControl(listener_id) produces NotSupportedException'%(port_name)) + except Exception, e: + self.check(True,False,'%s.getTunerDeviceControl(listener_id) produces exception %s'%(port_name,e)) + else: + self.check(type(resp), bool, '%s.getTunerDeviceControl(listener_id) has correct return type'%(port_name)) + self.check(resp in [True,False], True, '%s.getTunerDeviceControl(listener_id) return value is within expected results'%(port_name)) + self.check(resp, False, '%s.getTunerDeviceControl(listener_id) returns False for listener alloc_id'%(port_name)) + + self.dut_ref.deallocateCapacity(listener_alloc) + self.dut_ref.deallocateCapacity(controller_alloc) + + def testFRONTEND_3_3_06(self): + ''' RX_DIG 3.6 Verify digital tuner port getTunerGroupId function + ''' + port_name = 'DigitalTuner_in' + tuner_control = self.dut.getPort('DigitalTuner_in') + tuner_control._narrow(FRONTEND.FrontendTuner) + controller = self._generateRD() + + # make allocations + controller_id = controller['ALLOC_ID'] + controller_alloc = self._generateAlloc(controller) + self.check(self.dut_ref.allocateCapacity(controller_alloc),True,'ERROR -- could not allocate controller',throwOnFailure=True,silentSuccess=True) + + try: + status_val = self._getTunerStatusProp(controller_id, 'FRONTEND::tuner_status::group_id') + except KeyError: + status_val = None + + try: + resp = tuner_control.getTunerGroupId(controller_id) + except FRONTEND.NotSupportedException: + self.check(True,True,'%s.getTunerGroupId produces NotSupportedException'%(port_name)) + except Exception, e: + self.check(True,False,'%s.getTunerGroupId produces exception %s'%(port_name,e)) + else: + self.check(type(resp), str, '%s.getTunerGroupId has correct return type'%(port_name)) + self.check(type(resp), str, '%s.getTunerGroupId return value is within expected results'%(port_name)) + if status_val!=None: + print "###################################" + print resp + print status_val + self.check(resp, status_val, '%s.getTunerGroupId matches frontend tuner status prop'%(port_name)) + + self.dut_ref.deallocateCapacity(controller_alloc) + + def testFRONTEND_3_3_07(self): + ''' RX_DIG 3.7 Verify digital tuner port getTunerRfFlowId function + ''' + port_name = 'DigitalTuner_in' + tuner_control = self.dut.getPort('DigitalTuner_in') + tuner_control._narrow(FRONTEND.FrontendTuner) + controller = self._generateRD() + + # make allocations + controller_id = controller['ALLOC_ID'] + controller_alloc = self._generateAlloc(controller) + self.check(self.dut_ref.allocateCapacity(controller_alloc),True,'ERROR -- could not allocate controller',throwOnFailure=True,silentSuccess=True) + + try: + status_val = self._getTunerStatusProp(controller_id, 'FRONTEND::tuner_status::rf_flow_id') + except KeyError: + status_val = None + + try: + resp = tuner_control.getTunerRfFlowId(controller_id) + except FRONTEND.NotSupportedException: + self.check(True,True,'%s.getTunerRfFlowId produces NotSupportedException'%(port_name)) + except Exception, e: + self.check(True,False,'%s.getTunerRfFlowId produces exception %s'%(port_name,e)) + else: + self.check(type(resp), str, '%s.getTunerRfFlowId has correct return type'%(port_name)) + self.check(type(resp), str, '%s.getTunerRfFlowId return value is within expected results'%(port_name)) + if status_val!=None: + print "###################################" + print resp + print status_val + self.check(resp, status_val, '%s.getTunerRfFlowId matches frontend tuner status prop'%(port_name)) + + self.dut_ref.deallocateCapacity(controller_alloc) + + def testFRONTEND_3_3_08(self): + ''' RX_DIG 3.8 Verify digital tuner port getTunerCenterFrequency function + ''' + port_name = 'DigitalTuner_in' + tuner_control = self.dut.getPort('DigitalTuner_in') + tuner_control._narrow(FRONTEND.FrontendTuner) + controller = self._generateRD() + + # make allocations + controller_id = controller['ALLOC_ID'] + controller_alloc = self._generateAlloc(controller) + self.check(self.dut_ref.allocateCapacity(controller_alloc),True,'ERROR -- could not allocate controller',throwOnFailure=True,silentSuccess=True) + + try: + status_val = self._getTunerStatusProp(controller_id, 'FRONTEND::tuner_status::center_frequency') + except KeyError: + status_val = None + + try: + resp = tuner_control.getTunerCenterFrequency(controller_id) + except FRONTEND.NotSupportedException: + self.check(True,True,'%s.getTunerCenterFrequency produces NotSupportedException'%(port_name)) + except Exception, e: + self.check(True,False,'%s.getTunerCenterFrequency produces exception %s'%(port_name,e)) + else: + self.check(type(resp), float, '%s.getTunerCenterFrequency has correct return type'%(port_name)) + self.check(resp >= 0.0, True, '%s.getTunerCenterFrequency return value is within expected results'%(port_name)) + if status_val!=None: + print "###################################" + print resp + print status_val + self.checkAlmostEqual(resp, status_val, '%s.getTunerCenterFrequency matches frontend tuner status prop'%(port_name),places=0) + + self.dut_ref.deallocateCapacity(controller_alloc) + + def testFRONTEND_3_3_09(self): + ''' RX_DIG 3.9 Verify digital tuner port getTunerBandwidth function + ''' + port_name = 'DigitalTuner_in' + tuner_control = self.dut.getPort('DigitalTuner_in') + tuner_control._narrow(FRONTEND.FrontendTuner) + controller = self._generateRD() + + # make allocations + controller_id = controller['ALLOC_ID'] + controller_alloc = self._generateAlloc(controller) + self.check(self.dut_ref.allocateCapacity(controller_alloc),True,'ERROR -- could not allocate controller',throwOnFailure=True,silentSuccess=True) + + try: + status_val = self._getTunerStatusProp(controller_id, 'FRONTEND::tuner_status::bandwidth') + except KeyError: + status_val = None + + # getTunerBandwidth + # double: >= 0? + try: + resp = tuner_control.getTunerBandwidth(controller_id) + except FRONTEND.NotSupportedException: + self.check(True,True,'%s.getTunerBandwidth produces NotSupportedException'%(port_name)) + except Exception, e: + self.check(True,False,'%s.getTunerBandwidth produces exception %s'%(port_name,e)) + else: + self.check(type(resp), float, '%s.getTunerBandwidth has correct return type'%(port_name)) + self.check(resp >= 0.0, True, '%s.getTunerBandwidth return value is within expected results'%(port_name)) + if status_val!=None: + self.checkAlmostEqual(resp, status_val, '%s.getTunerBandwidth matches frontend tuner status prop'%(port_name),places=0) + + self.dut_ref.deallocateCapacity(controller_alloc) + + def testFRONTEND_3_3_10(self): + ''' RX_DIG 3.10 Verify digital tuner port getTunerOutputSampleRate function + ''' + port_name = 'DigitalTuner_in' + tuner_control = self.dut.getPort('DigitalTuner_in') + tuner_control._narrow(FRONTEND.FrontendTuner) + controller = self._generateRD() + + # make allocations + controller_id = controller['ALLOC_ID'] + controller_alloc = self._generateAlloc(controller) + self.check(self.dut_ref.allocateCapacity(controller_alloc),True,'ERROR -- could not allocate controller',throwOnFailure=True,silentSuccess=True) + + try: + status_val = self._getTunerStatusProp(controller_id, 'FRONTEND::tuner_status::sample_rate') + except KeyError: + status_val = None + + try: + resp = tuner_control.getTunerOutputSampleRate(controller_id) + except FRONTEND.NotSupportedException: + self.check(True,True,'%s.getTunerOutputSampleRate produces NotSupportedException'%(port_name)) + except Exception, e: + self.check(True,False,'%s.getTunerOutputSampleRate produces exception %s'%(port_name,e)) + else: + self.check(type(resp), float, '%s.getTunerOutputSampleRate has correct return type'%(port_name)) + self.check(resp >= 0.0, True, '%s.getTunerOutputSampleRate return value is within expected results'%(port_name)) + if status_val!=None: + self.checkAlmostEqual(resp, status_val, '%s.getTunerOutputSampleRate matches frontend tuner status prop'%(port_name),places=0) + + self.dut_ref.deallocateCapacity(controller_alloc) + + def testFRONTEND_3_3_11(self): + ''' RX_DIG 3.11 Verify digital tuner port getTunerAgcEnable function + ''' + port_name = 'DigitalTuner_in' + tuner_control = self.dut.getPort('DigitalTuner_in') + tuner_control._narrow(FRONTEND.FrontendTuner) + controller = self._generateRD() + + # make allocations + controller_id = controller['ALLOC_ID'] + controller_alloc = self._generateAlloc(controller) + self.check(self.dut_ref.allocateCapacity(controller_alloc),True,'ERROR -- could not allocate controller',throwOnFailure=True,silentSuccess=True) + + try: + status_val = self._getTunerStatusProp(controller_id, 'FRONTEND::tuner_status::agc') + except KeyError: + status_val = None + + try: + resp = tuner_control.getTunerAgcEnable(controller_id) + except FRONTEND.NotSupportedException: + self.check(True,True,'%s.getTunerAgcEnable produces NotSupportedException'%(port_name)) + except Exception, e: + self.check(True,False,'%s.getTunerAgcEnable produces exception %s'%(port_name,e)) + else: + self.check(type(resp), bool, '%s.getTunerAgcEnable has correct return type'%(port_name)) + self.check(resp in [True,False], True, '%s.getTunerAgcEnable return value is within expected results'%(port_name)) + if status_val!=None: + self.check(resp, status_val, '%s.getTunerAgcEnable matches frontend tuner status prop'%(port_name)) + + self.dut_ref.deallocateCapacity(controller_alloc) + + def testFRONTEND_3_3_12(self): + ''' RX_DIG 3.12 Verify digital tuner port getTunerGain function + ''' + port_name = 'DigitalTuner_in' + tuner_control = self.dut.getPort('DigitalTuner_in') + tuner_control._narrow(FRONTEND.FrontendTuner) + controller = self._generateRD() + + # make allocations + controller_id = controller['ALLOC_ID'] + controller_alloc = self._generateAlloc(controller) + self.check(self.dut_ref.allocateCapacity(controller_alloc),True,'ERROR -- could not allocate controller',throwOnFailure=True,silentSuccess=True) + + try: + status_val = self._getTunerStatusProp(controller_id, 'FRONTEND::tuner_status::gain') + except KeyError: + status_val = None + + try: + resp = tuner_control.getTunerGain(controller_id) + except FRONTEND.NotSupportedException: + self.check(True,True,'%s.getTunerGain produces NotSupportedException'%(port_name)) + except Exception, e: + self.check(True,False,'%s.getTunerGain produces exception %s'%(port_name,e)) + else: + self.check(type(resp), float, '%s.getTunerGain has correct return type'%(port_name)) + self.check(type(resp), float, '%s.getTunerGain return value is within expected results'%(port_name)) + if status_val!=None: + self.checkAlmostEqual(resp, status_val, '%s.getTunerGain matches frontend tuner status prop'%(port_name),places=2) + + self.dut_ref.deallocateCapacity(controller_alloc) + + def testFRONTEND_3_3_13(self): + ''' RX_DIG 3.13 Verify digital tuner port getTunerReferenceSource function + ''' + port_name = 'DigitalTuner_in' + tuner_control = self.dut.getPort('DigitalTuner_in') + tuner_control._narrow(FRONTEND.FrontendTuner) + controller = self._generateRD() + + # make allocations + controller_id = controller['ALLOC_ID'] + controller_alloc = self._generateAlloc(controller) + self.check(self.dut_ref.allocateCapacity(controller_alloc),True,'ERROR -- could not allocate controller',throwOnFailure=True,silentSuccess=True) + + try: + status_val = self._getTunerStatusProp(controller_id, 'FRONTEND::tuner_status::reference_source') + except KeyError: + status_val = None + + try: + resp = tuner_control.getTunerReferenceSource(controller_id) + except FRONTEND.NotSupportedException: + self.check(True,True,'%s.getTunerReferenceSource produces NotSupportedException'%(port_name)) + except Exception, e: + self.check(True,False,'%s.getTunerReferenceSource produces exception %s'%(port_name,e)) + else: + self.check(type(resp) in [int,long], True, '%s.getTunerReferenceSource returns correct type'%(port_name)) + self.check(resp in [0,1], True, '%s.getTunerReferenceSource return value within expected results'%(port_name)) + if status_val!=None: + self.check(resp, status_val, '%s.getTunerReferenceSource matches frontend tuner status prop'%(port_name)) + + self.dut_ref.deallocateCapacity(controller_alloc) + + def testFRONTEND_3_3_14(self): + ''' RX_DIG 3.14 Verify digital tuner port getTunerEnable function + ''' + port_name = 'DigitalTuner_in' + tuner_control = self.dut.getPort('DigitalTuner_in') + tuner_control._narrow(FRONTEND.FrontendTuner) + controller = self._generateRD() + + # make allocations + controller_id = controller['ALLOC_ID'] + controller_alloc = self._generateAlloc(controller) + self.check(self.dut_ref.allocateCapacity(controller_alloc),True,'ERROR -- could not allocate controller',throwOnFailure=True,silentSuccess=True) + + try: + status_val = self._getTunerStatusProp(controller_id, 'FRONTEND::tuner_status::enabled') + except KeyError: + status_val = None + + try: + resp = tuner_control.getTunerEnable(controller_id) + except FRONTEND.NotSupportedException: + self.check(True,True,'%s.getTunerEnable produces NotSupportedException'%(port_name)) + except Exception, e: + self.check(True,False,'%s.getTunerEnable produces exception %s'%(port_name,e)) + else: + self.check(type(resp), bool, '%s.getTunerEnable has correct return type'%(port_name)) + self.check(resp in [True,False], True, '%s.getTunerEnable return value is within expected results'%(port_name)) + if status_val!=None: + self.check(resp, status_val, '%s.getTunerEnable matches frontend tuner status prop'%(port_name)) + + self.dut_ref.deallocateCapacity(controller_alloc) + + def testFRONTEND_3_3_15(self): + ''' RX_DIG 3.15 Verify digital tuner port getTunerStatus function + ''' + port_name = 'DigitalTuner_in' + tuner_control = self.dut.getPort('DigitalTuner_in') + tuner_control._narrow(FRONTEND.FrontendTuner) + controller = self._generateRD() + + # make allocations + controller_id = controller['ALLOC_ID'] + controller_alloc = self._generateAlloc(controller) + self.check(self.dut_ref.allocateCapacity(controller_alloc),True,'ERROR -- could not allocate controller',throwOnFailure=True,silentSuccess=True) + + try: + status_val = self._getTunerStatusProp(controller_id) + except KeyError: + status_val = None + props_type = type(properties.props_from_dict({})) + + try: + resp = tuner_control.getTunerStatus(controller_id) + except FRONTEND.NotSupportedException: + self.check(True,True,'%s.getTunerStatus produces NotSupportedException'%(port_name)) + except Exception, e: + self.check(True,False,'%s.getTunerStatus produces exception %s'%(port_name,e)) + else: + self.check(type(resp), props_type, '%s.getTunerStatus has correct return type'%(port_name)) + self.check(type(resp), props_type, '%s.getTunerStatus return value is within expected results'%(port_name)) + resp = properties.props_to_dict(resp) + #pp(resp) + self.check(controller_id in resp['FRONTEND::tuner_status::allocation_id_csv'].split(','), True, '%s.getTunerStatus return value has correct tuner status for allocation ID requested'%(port_name)) + if status_val!=None: + print "###################################" + print resp + print status_val + self.check(resp, status_val, '%s.getTunerStatus matches frontend tuner status prop'%(port_name)) + + self.dut_ref.deallocateCapacity(controller_alloc) + + # Verify setter functions + # for each of the following, do bounds checking in addition to simple setter checking + # setTunerCenterFrequency + # setTunerBandwidth + # setTunerOutputSampleRate + # setTunerGain + + # Verify in-bounds retune + + def testFRONTEND_3_3_16(self): + ''' RX_DIG 3.16 Verify digital tuner port setTunerCenterFrequency function in-bounds retune + ''' + tuner_info=DEVICE_INFO['RX_DIGITIZER'] + port_name = 'DigitalTuner_in' + tuner_control = self.dut.getPort('DigitalTuner_in') + tuner_control._narrow(FRONTEND.FrontendTuner) + controller = self._generateRD() + + # make allocations + controller_id = controller['ALLOC_ID'] + controller_alloc = self._generateAlloc(controller) + self.check(self.dut_ref.allocateCapacity(controller_alloc),True,'ERROR -- could not allocate controller',throwOnFailure=True,silentSuccess=True) + + #check Center Freq: tune to min, max, then orig + try: + cf = tuner_control.getTunerCenterFrequency(controller_id) + except FRONTEND.NotSupportedException: + self.check(True,True,'%s.getTunerCenterFrequency produces NotSupportedException -- cannot verify setTunerCenterFrequency function'%(port_name), successMsg='info') + try: + tuner_control.setTunerCenterFrequency(controller_id, tuner_info['CF_MIN']) + except FRONTEND.NotSupportedException: + self.check(True,True,'%s.setTunerCenterFrequency produces NotSupportedException'%(port_name)) + else: + self.check(True,True,'%s.setTunerCenterFrequency executes without throwing exception'%(port_name)) + except Exception, e: + self.check(False, True,'%s.getTunerCenterFrequency produces Exception -- cannot verify setTunerCenterFrequency function',failureMsg='WARN') + try: + tuner_control.setTunerCenterFrequency(controller_id, tuner_info['CF_MIN']) + except FRONTEND.NotSupportedException: + self.check(True,True,'%s.setTunerCenterFrequency produces NotSupportedException'%(port_name)) + else: + self.check(True,True,'%s.setTunerCenterFrequency executes without throwing exception'%(port_name)) + else: + try: + tuner_control.setTunerCenterFrequency(controller_id, tuner_info['CF_MIN']) + except FRONTEND.NotSupportedException: + self.check(True,True,'%s.setTunerCenterFrequency produces NotSupportedException'%(port_name)) + except FRONTEND.BadParameterException, e: + self.check(False, True,'In-bounds setting of frequency - set to minimum CF (%s) produces BadParameterException'%tuner_info['CF_MIN'] ) + raise + except FRONTEND.FrontendException, e: + self.check(False, True,'In-bounds setting of frequency - set to minimum CF (%s) produces FrontendException'%tuner_info['CF_MIN'] ) + raise + except Exception, e: + self.check(False, True,'In-bounds setting of frequency - set to minimum CF (%s) produces Exception'%tuner_info['CF_MIN']) + raise + else: + self.checkAlmostEqual(tuner_info['CF_MIN'],tuner_control.getTunerCenterFrequency(controller_id),'In-bounds re-tune of frequency - tuned to minimum CF (%s)'%(tuner_info['CF_MIN']),places=0) + tuner_control.setTunerCenterFrequency(controller_id, tuner_info['CF_MAX']) + self.checkAlmostEqual(tuner_info['CF_MAX'],tuner_control.getTunerCenterFrequency(controller_id),'In-bounds re-tune of frequency - tuned to maximum CF (%s)'%(tuner_info['CF_MAX']),places=0) + tuner_control.setTunerCenterFrequency(controller_id, cf) + self.checkAlmostEqual(cf,tuner_control.getTunerCenterFrequency(controller_id),'In-bounds re-tune of frequency - tuned back to original CF (%s)'%(cf),places=0) + + self.dut_ref.deallocateCapacity(controller_alloc) + + def testFRONTEND_3_3_17(self): + ''' RX_DIG 3.17 Verify digital tuner port setTunerBandwidth function in-bounds retune + ''' + tuner_info=DEVICE_INFO['RX_DIGITIZER'] + port_name = 'DigitalTuner_in' + tuner_control = self.dut.getPort('DigitalTuner_in') + tuner_control._narrow(FRONTEND.FrontendTuner) + controller = self._generateRD() + + # make allocations + controller_id = controller['ALLOC_ID'] + controller_alloc = self._generateAlloc(controller) + self.check(self.dut_ref.allocateCapacity(controller_alloc),True,'ERROR -- could not allocate controller',throwOnFailure=True,silentSuccess=True) + + #Check Bandwidth: tune to min, max, then orig + try: + bw = tuner_control.getTunerBandwidth(controller_id) + except FRONTEND.NotSupportedException: + self.check(True,True,'%s.getTunerBandwidth produces NotSupportedException -- cannot verify setTunerBandwidth function'%(port_name), successMsg='info') + try: + tuner_control.setTunerBandwidth(controller_id, tuner_info['BW_MIN']) + except FRONTEND.NotSupportedException: + self.check(True,True,'%s.setTunerBandwidth produces NotSupportedException'%(port_name)) + else: + self.check(True,True,'%s.setTunerBandwidth executes without throwing exception'%(port_name)) + except Exception, e: + self.check(False, True,'%s.getTunerBandwidth produces Exception -- cannot verify setTunerBandwidth function',failureMsg='WARN') + try: + tuner_control.setTunerBandwidth(controller_id, tuner_info['BW_MIN']) + except FRONTEND.NotSupportedException: + self.check(True,True,'%s.setTunerBandwidth produces NotSupportedException'%(port_name)) + else: + self.check(True,True,'%s.setTunerBandwidth executes without throwing exception'%(port_name)) + else: + try: + tuner_control.setTunerBandwidth(controller_id, tuner_info['BW_MIN']) + except FRONTEND.NotSupportedException: + self.check(True,True,'%s.setTunerBandwidth produces NotSupportedException'%(port_name)) + except FRONTEND.BadParameterException, e: + self.check(False, True,'In-bounds setting of bandwidth - set to minimum BW (%s) produces BadParameterException'%tuner_info['BW_MIN'] ) + raise + except FRONTEND.FrontendException, e: + self.check(False, True,'In-bounds setting of bandwidth - set to minimum BW (%s) produces FrontendException'%tuner_info['BW_MIN'] ) + raise + except Exception, e: + self.check(False, True,'In-bounds setting of bandwidth - set to minimum BW (%s) produces Exception'%tuner_info['BW_MIN']) + raise + else: + self.checkAlmostEqual(tuner_info['BW_MIN'],tuner_control.getTunerBandwidth(controller_id),'In-bounds re-tune of bandwidth - set to minimum BW (%s)'%tuner_info['BW_MIN'],places=0) + tuner_control.setTunerBandwidth(controller_id, tuner_info['BW_MAX']) + self.checkAlmostEqual(tuner_info['BW_MAX'],tuner_control.getTunerBandwidth(controller_id),'In-bounds re-tune of bandwidth - set to maximum BW (%s)'%tuner_info['BW_MAX'],places=0) + tuner_control.setTunerBandwidth(controller_id, bw) + self.checkAlmostEqual(bw,tuner_control.getTunerBandwidth(controller_id),'In-bounds re-tune of bandwidth - set to original BW (%s)'%bw,places=0) + + self.dut_ref.deallocateCapacity(controller_alloc) + + def testFRONTEND_3_3_18(self): + ''' RX_DIG 3.18 Verify digital tuner port setTunerOutputSampleRate function in-bounds retune + ''' + + tuner_info=DEVICE_INFO['RX_DIGITIZER'] + port_name = 'DigitalTuner_in' + tuner_control = self.dut.getPort('DigitalTuner_in') + tuner_control._narrow(FRONTEND.FrontendTuner) + controller = self._generateRD() + + # make allocations + controller_id = controller['ALLOC_ID'] + controller_alloc = self._generateAlloc(controller) + self.check(self.dut_ref.allocateCapacity(controller_alloc),True,'ERROR -- could not allocate controller',throwOnFailure=True,silentSuccess=True) + + #Check SR: tune to min, max, then orig + try: + sr = tuner_control.getTunerOutputSampleRate(controller_id) + except FRONTEND.NotSupportedException: + self.check(True,True,'%s.getTunerOutputSampleRate produces NotSupportedException -- cannot verify setTunerOutputSampleRate function'%(port_name), successMsg='info') + try: + tuner_control.setTunerOutputSampleRate(controller_id, tuner_info['SR_MIN']) + except FRONTEND.NotSupportedException: + self.check(True,True,'%s.setTunerOutputSampleRate produces NotSupportedException'%(port_name)) + else: + self.check(True,True,'%s.setTunerOutputSampleRate executes without throwing exception'%(port_name)) + except Exception, e: + self.check(False, True,'%s.getTunerOutputSampleRate produces Exception -- cannot verify setTunerOutputSampleRate function',failureMsg='WARN') + try: + tuner_control.setTunerOutputSampleRate(controller_id, tuner_info['SR_MIN']) + except FRONTEND.NotSupportedException: + self.check(True,True,'%s.setTunerOutputSampleRate produces NotSupportedException'%(port_name)) + else: + self.check(True,True,'%s.setTunerOutputSampleRate executes without throwing exception'%(port_name)) + else: + try: + tuner_control.setTunerOutputSampleRate(controller_id, tuner_info['SR_MIN']) + except FRONTEND.NotSupportedException: + self.check(True,True,'%s.setTunerOutputSampleRate produces NotSupportedException'%(port_name)) + except FRONTEND.BadParameterException, e: + self.check(False, True,'In-bounds setting of sample rate - set to minimum SR (%s) produces BadParameterException'%tuner_info['SR_MIN'] ) + raise + except FRONTEND.FrontendException, e: + self.check(False, True,'In-bounds setting of sample rate - set to minimum SR (%s) produces FrontendException'%tuner_info['SR_MIN'] ) + raise + except Exception, e: + self.check(False, True,'In-bounds setting of sample rate - set to minimum SR (%s) produces Exception'%tuner_info['SR_MIN']) + raise + else: + self.checkAlmostEqual(tuner_info['SR_MIN'],tuner_control.getTunerOutputSampleRate(controller_id),'In-bounds re-tune of sample rate - set to minimum SR (%s)'%tuner_info['SR_MIN'],places=0) + tuner_control.setTunerOutputSampleRate(controller_id, tuner_info['SR_MAX']) + self.checkAlmostEqual(tuner_info['SR_MAX'],tuner_control.getTunerOutputSampleRate(controller_id),'In-bounds re-tune of sample rate - set to maximum SR (%s)'%tuner_info['SR_MAX'],places=0) + tuner_control.setTunerOutputSampleRate(controller_id, sr) + self.checkAlmostEqual(sr,tuner_control.getTunerOutputSampleRate(controller_id),'In-bounds re-tune of sample rate - set to original SR (%s)'%sr,places=0) + + self.dut_ref.deallocateCapacity(controller_alloc) + + def testFRONTEND_3_3_19(self): + ''' RX_DIG 3.19 Verify digital tuner port setTunerGain function in-bounds retune + ''' + + tuner_info=DEVICE_INFO['RX_DIGITIZER'] + port_name = 'DigitalTuner_in' + tuner_control = self.dut.getPort('DigitalTuner_in') + tuner_control._narrow(FRONTEND.FrontendTuner) + controller = self._generateRD() + + # make allocations + controller_id = controller['ALLOC_ID'] + controller_alloc = self._generateAlloc(controller) + self.check(self.dut_ref.allocateCapacity(controller_alloc),True,'ERROR -- could not allocate controller',throwOnFailure=True,silentSuccess=True) + + # check gain: set to min, max, then orig + try: + gain = tuner_control.getTunerGain(controller_id) + except FRONTEND.NotSupportedException: + self.check(True,True,'%s.getTunerGain produces NotSupportedException -- cannot verify setTunerGain function'%(port_name), successMsg='info') + try: + tuner_control.setTunerGain(controller_id, tuner_info['GAIN_MIN']) + except FRONTEND.NotSupportedException: + self.check(True,True,'%s.setTunerGain produces NotSupportedException'%(port_name)) + else: + self.check(True,True,'%s.setTunerGain executes without throwing exception'%(port_name)) + except Exception, e: + self.check(False, True,'%s.getTunerGain produces Exception -- cannot verify setTunerGain function',failureMsg='WARN') + try: + tuner_control.setTunerGain(controller_id, tuner_info['GAIN_MIN']) + except FRONTEND.NotSupportedException: + self.check(True,True,'%s.setTunerGain produces NotSupportedException'%(port_name)) + else: + self.check(True,True,'%s.setTunerGain executes without throwing exception'%(port_name)) + else: + try: + tuner_control.setTunerGain(controller_id, tuner_info['GAIN_MIN']) + except FRONTEND.NotSupportedException: + self.check(True,True,'%s.setTunerGain produces NotSupportedException'%(port_name)) + except FRONTEND.BadParameterException, e: + self.check(False, True,'In-bounds setting of gain - set to minimum gain (%s) produces BadParameterException'%tuner_info['GAIN_MIN']) + raise + except FRONTEND.FrontendException, e: + self.check(False, True,'In-bounds setting of gain - set to minimum gain (%s) produces FrontendException'%tuner_info['GAIN_MIN']) + raise + except Exception, e: + self.check(False, True,'In-bounds setting of gain - set to minimum gain (%s) produces Exception'%tuner_info['GAIN_MIN']) + raise + else: + self.checkAlmostEqual(tuner_info['GAIN_MIN'],tuner_control.getTunerGain(controller_id),'In-bounds setting of gain - set to minimum gain (%s)'%tuner_info['GAIN_MIN'],places=2) + tuner_control.setTunerGain(controller_id, tuner_info['GAIN_MAX']) + self.checkAlmostEqual(tuner_info['GAIN_MAX'],tuner_control.getTunerGain(controller_id),'In-bounds setting of gain - set to maximum gain (%s)'%tuner_info['GAIN_MAX'],places=2) + tuner_control.setTunerGain(controller_id, gain) + self.checkAlmostEqual(gain,tuner_control.getTunerGain(controller_id),'In-bounds setting of gain - set to original gain (%s)'%gain,places=2) + + self.dut_ref.deallocateCapacity(controller_alloc) + + def testFRONTEND_3_3_20(self): + ''' RX_DIG 3.20 Verify digital tuner port setTunerCenterFrequency function out of bounds retune + ''' + + tuner_info=DEVICE_INFO['RX_DIGITIZER'] + port_name = 'DigitalTuner_in' + tuner_control = self.dut.getPort('DigitalTuner_in') + tuner_control._narrow(FRONTEND.FrontendTuner) + controller = self._generateRD() + + # make allocations + controller_id = controller['ALLOC_ID'] + controller_alloc = self._generateAlloc(controller) + self.check(self.dut_ref.allocateCapacity(controller_alloc),True,'ERROR -- could not allocate controller',throwOnFailure=True,silentSuccess=True) + + #Verify outside-bounds retune + #check Center Freq: + try: + cf = tuner_control.getTunerCenterFrequency(controller_id) + except FRONTEND.NotSupportedException: + self.check(True,True,'%s.getTunerCenterFrequency produces NotSupportedException -- cannot verify out-of-bounds frequency tuning'%(port_name), successMsg='info') + except Exception, e: + self.check(False, True,'%s.getTunerCenterFrequency produces Exception -- cannot verify out-of-bounds frequency tuning',failureMsg='WARN') + else: + try: + tuner_control.setTunerCenterFrequency(controller_id, tuner_info['CF_MAX'] + cf) + except FRONTEND.NotSupportedException: + self.check(True,True,'%s.setTunerCenterFrequency produces NotSupportedException -- cannot verify out-of-bounds frequency tuning'%(port_name)) + except FRONTEND.BadParameterException, e: + self.check(True, True,'Out-of-bounds re-tune of frequency produces BadParameterException') + except FRONTEND.FrontendException, e: + self.check(False, True,'Out-of-bounds re-tune of frequency produces BadParameterException (produces FrontendException instead)') + raise + except Exception, e: + self.check(False, True,'Out-of-bounds re-tune of frequency produces BadParameterException (produces another Exception instead)') + raise + else: + self.check(False, True,'Out-of-bounds re-tune of frequency produces BadParameterException') + if not self.checkAlmostEqual(cf, tuner_control.getTunerCenterFrequency(controller_id),'Out-of-bounds re-tune of frequency - CF unchanged',places=0): + try: + tuner_control.setTunerCenterFrequency(controller_id, cf) + except: + pass + + self.dut_ref.deallocateCapacity(controller_alloc) + + def testFRONTEND_3_3_21(self): + ''' RX_DIG 3.21 Verify digital tuner port setTunerBandwidth function out of bounds retune + ''' + + tuner_info=DEVICE_INFO['RX_DIGITIZER'] + port_name = 'DigitalTuner_in' + tuner_control = self.dut.getPort('DigitalTuner_in') + tuner_control._narrow(FRONTEND.FrontendTuner) + controller = self._generateRD() + + # make allocations + controller_id = controller['ALLOC_ID'] + controller_alloc = self._generateAlloc(controller) + self.check(self.dut_ref.allocateCapacity(controller_alloc),True,'ERROR -- could not allocate controller',throwOnFailure=True,silentSuccess=True) + + #Check Bandwidth + try: + bw = tuner_control.getTunerBandwidth(controller_id) + except FRONTEND.NotSupportedException: + self.check(True,True,'%s.getTunerBandwidth produces NotSupportedException -- cannot verify out-of-bounds bandwidth tuning'%(port_name), successMsg='info') + except Exception, e: + self.check(False, True,'%s.getTunerBandwidth produces Exception -- cannot verify out-of-bounds bandwidth tuning',failureMsg='WARN') + else: + try: + tuner_control.setTunerBandwidth(controller_id, tuner_info['BW_MAX'] + bw) + except FRONTEND.NotSupportedException: + self.check(True,True,'%s.setTunerBandwidth produces NotSupportedException -- cannot verify out-of-bounds bandwidth tuning'%(port_name)) + except FRONTEND.BadParameterException, e: + self.check(True, True,'Out-of-bounds re-tune of bandwidth produces BadParameterException') + except FRONTEND.FrontendException, e: + self.check(False, True,'Out-of-bounds re-tune of bandwidth produces BadParameterException (produces FrontendException instead)') + raise + except Exception, e: + self.check(False, True,'Out-of-bounds re-tune of bandwidth produces BadParameterException (produces another Exception instead)') + raise + else: + self.check(False, True,'Out-of-bounds re-tune of bandwidth produces BadParameterException') + # DEBUG + ''' + print 'DEBUG - out of bounds retune of bw did not produce exception' + print 'DEBUG - tuned bw: %s'%(tuner_info['BW_MAX'] + bw) + print 'DEBUG - tuner status:' + pp(self._getTunerStatusProp(controller_id)) + ''' + new_bw = tuner_control.getTunerBandwidth(controller_id) + if not self.checkAlmostEqual(bw, new_bw,'Out-of-bounds re-tune of bandwidth - BW unchanged',places=0): + # DEBUG + ''' + print 'DEBUG - out of bounds retune of bw incorrectly caused change in bw' + print 'DEBUG - orig bw: %s new bw: %s tuned bw: %s'%(bw,new_bw,tuner_info['BW_MAX'] + bw) + # end DEBUG + ''' + try: + tuner_control.setTunerBandwidth(controller_id, bw) + except: + pass + + self.dut_ref.deallocateCapacity(controller_alloc) + + def testFRONTEND_3_3_22(self): + ''' RX_DIG 3.22 Verify digital tuner port setTunerOutputSampleRate function out of bounds retune + ''' + + tuner_info=DEVICE_INFO['RX_DIGITIZER'] + port_name = 'DigitalTuner_in' + tuner_control = self.dut.getPort('DigitalTuner_in') + tuner_control._narrow(FRONTEND.FrontendTuner) + controller = self._generateRD() + + # make allocations + controller_id = controller['ALLOC_ID'] + controller_alloc = self._generateAlloc(controller) + self.check(self.dut_ref.allocateCapacity(controller_alloc),True,'ERROR -- could not allocate controller',throwOnFailure=True,silentSuccess=True) + + #Check SR + try: + sr = tuner_control.getTunerOutputSampleRate(controller_id) + except FRONTEND.NotSupportedException: + self.check(True,True,'%s.getTunerOutputSampleRate produces NotSupportedException -- cannot verify out-of-bounds sample rate tuning'%(port_name), successMsg='info') + except Exception, e: + self.check(False, True,'%s.getTunerOutputSampleRate produces Exception -- cannot verify out-of-bounds sample rate tuning',failureMsg='WARN') + else: + try: + tuner_control.setTunerOutputSampleRate(controller_id, tuner_info['SR_MAX'] + sr) + except FRONTEND.NotSupportedException: + self.check(True,True,'%s.setTunerOutputSampleRate produces NotSupportedException -- cannot verify out-of-bounds sample rate tuning'%(port_name)) + except FRONTEND.BadParameterException, e: + self.check(True, True,'Out-of-bounds re-tune of sample rate produces BadParameterException') + except FRONTEND.FrontendException, e: + self.check(False, True,'Out-of-bounds re-tune of sample rate produces BadParameterException (produces FrontendException instead)') + raise + except Exception, e: + self.check(False, True,'Out-of-bounds re-tune of sample rate produces BadParameterException (produces another Exception instead)') + raise + else: + self.check(False, True,'Out-of-bounds re-tune of sample rate produces BadParameterException') + new_sr = tuner_control.getTunerOutputSampleRate(controller_id) + if not self.checkAlmostEqual(sr, new_sr,'Out-of-bounds re-tune of sample rate - SR unchanged',places=0): + # DEBUG + ''' + print 'DEBUG - out of bounds retune of sr incorrectly caused change in sr' + print 'DEBUG - orig sr: %s new sr: %s tuned sr: %s'%(sr,new_sr,DEVICE_INFO['RX_DIGITIZER']['SR_MAX'] + sr) + # end DEBUG + ''' + try: + tuner_control.setTunerOutputSampleRate(controller_id, sr) + except: + pass + + self.dut_ref.deallocateCapacity(controller_alloc) + + def testFRONTEND_3_3_23(self): + ''' RX_DIG 3.23 Verify digital tuner port setTunerGain function out of bounds retune + ''' + + tuner_info=DEVICE_INFO['RX_DIGITIZER'] + port_name = 'DigitalTuner_in' + tuner_control = self.dut.getPort('DigitalTuner_in') + tuner_control._narrow(FRONTEND.FrontendTuner) + controller = self._generateRD() + + # make allocations + controller_id = controller['ALLOC_ID'] + controller_alloc = self._generateAlloc(controller) + self.check(self.dut_ref.allocateCapacity(controller_alloc),True,'ERROR -- could not allocate controller',throwOnFailure=True,silentSuccess=True) + + #Check gain + try: + gain = tuner_control.getTunerGain(controller_id) + except FRONTEND.NotSupportedException: + self.check(True,True,'%s.getTunerGain produces NotSupportedException -- cannot verify out-of-bounds gain setting'%(port_name), successMsg='info') + except Exception, e: + self.check(False, True,'%s.getTunerGain produces Exception -- cannot verify out-of-bounds gain tuning',failureMsg='WARN') + else: + try: + tuner_control.setTunerGain(controller_id, tuner_info['GAIN_MAX'] + abs(tuner_info['GAIN_MAX']-tuner_info['GAIN_MIN']) + 1) + except FRONTEND.NotSupportedException: + self.check(True,True,'%s.setTunerGain produces NotSupportedException -- cannot verify out-of-bounds gain setting'%(port_name)) + except FRONTEND.BadParameterException, e: + self.check(True, True,'Out-of-bounds setting of gain produces BadParameterException') + except FRONTEND.FrontendException, e: + self.check(False, True,'Out-of-bounds setting of gain produces BadParameterException (produces FrontendException instead)') + raise + except Exception, e: + self.check(False, True,'Out-of-bounds re-tune of gain produces BadParameterException (produces another Exception instead)') + raise + else: + self.check(False, True,'Out-of-bounds setting of gain produces BadParameterException') + new_gain = tuner_control.getTunerGain(controller_id) + if not self.checkAlmostEqual(gain, new_gain,'Out-of-bounds setting of gain - gain unchanged',places=2): + + # DEBUG + print 'DEBUG - out of bounds retune of gain incorrectly caused change in gain' + print 'DEBUG - orig gain: %s new gain: %s tuned gain: %s'%(gain,new_gain,tuner_info['GAIN_MAX'] + abs(tuner_info['GAIN_MAX']-tuner_info['GAIN_MIN']) + 1) + # end DEBUG + + try: + tuner_control.setTunerGain(controller_id, gain) + except: + pass + + self.dut_ref.deallocateCapacity(controller_alloc) + + def testFRONTEND_3_3_24(self): + ''' RX_DIG 3.24 Verify digital tuner port setTunerAgcEnable function + ''' + + port_name = 'DigitalTuner_in' + tuner_control = self.dut.getPort('DigitalTuner_in') + tuner_control._narrow(FRONTEND.FrontendTuner) + controller = self._generateRD() + + # make allocations + controller_id = controller['ALLOC_ID'] + controller_alloc = self._generateAlloc(controller) + self.check(self.dut_ref.allocateCapacity(controller_alloc),True,'ERROR -- could not allocate controller',throwOnFailure=True,silentSuccess=True) + + # test changing values for the rest + # setTunerAgcEnable + try: + orig = tuner_control.getTunerAgcEnable(controller_id) + except FRONTEND.NotSupportedException: + self.check(True,True,'%s.getTunerAgcEnable produces NotSupportedException -- cannot test setTunerAgcEnable function'%(port_name)) + try: + tuner_control.setTunerAgcEnable(controller_id, False) + except FRONTEND.NotSupportedException: + self.check(True,True,'%s.setTunerAgcEnable produces NotSupportedException'%(port_name)) + else: + self.check(True,True,'%s.setTunerAgcEnable executes without throwing exception'%(port_name)) + else: + try: + tuner_control.setTunerAgcEnable(controller_id, not orig) + except FRONTEND.NotSupportedException: + self.check(True,True,'%s.setTunerAgcEnable produces NotSupportedException'%(port_name)) + else: + self.check(not orig,tuner_control.getTunerAgcEnable(controller_id),'setting agc enable -- set to new value') + tuner_control.setTunerAgcEnable(controller_id, orig) + self.check(orig,tuner_control.getTunerAgcEnable(controller_id),'setting agc enable -- set back to original value') + + self.dut_ref.deallocateCapacity(controller_alloc) + + def testFRONTEND_3_3_25(self): + ''' RX_DIG 3.25 Verify digital tuner port setTunerReferenceSource function + ''' + + port_name = 'DigitalTuner_in' + tuner_control = self.dut.getPort('DigitalTuner_in') + tuner_control._narrow(FRONTEND.FrontendTuner) + controller = self._generateRD() + + # make allocations + controller_id = controller['ALLOC_ID'] + controller_alloc = self._generateAlloc(controller) + self.check(self.dut_ref.allocateCapacity(controller_alloc),True,'ERROR -- could not allocate controller',throwOnFailure=True,silentSuccess=True) + + # setTunerReferenceSource + try: + orig = tuner_control.getTunerReferenceSource(controller_id) + except FRONTEND.NotSupportedException: + self.check(True,True,'%s.getTunerReferenceSource produces NotSupportedException -- cannot test setTunerReferenceSource function'%(port_name)) + try: + tuner_control.setTunerReferenceSource(controller_id, False) + except FRONTEND.NotSupportedException: + self.check(True,True,'%s.setTunerReferenceSource produces NotSupportedException'%(port_name)) + else: + self.check(True,True,'%s.setTunerReferenceSource executes without throwing exception'%(port_name)) + else: + try: + tuner_control.setTunerReferenceSource(controller_id, int(not orig)) + except FRONTEND.NotSupportedException: + self.check(True,True,'%s.setTunerReferenceSource produces NotSupportedException'%(port_name)) + else: + self.check(int(not orig),tuner_control.getTunerReferenceSource(controller_id),'setting tuner reference source -- set to new value') + tuner_control.setTunerReferenceSource(controller_id, orig) + self.check(orig,tuner_control.getTunerReferenceSource(controller_id),'setting tuner reference source -- set back to original value') + + self.dut_ref.deallocateCapacity(controller_alloc) + + def testFRONTEND_3_3_26(self): + ''' RX_DIG 3.26 Verify digital tuner port setTunerEnable function + ''' + + port_name = 'DigitalTuner_in' + tuner_control = self.dut.getPort('DigitalTuner_in') + tuner_control._narrow(FRONTEND.FrontendTuner) + controller = self._generateRD() + + # make allocations + controller_id = controller['ALLOC_ID'] + controller_alloc = self._generateAlloc(controller) + self.check(self.dut_ref.allocateCapacity(controller_alloc),True,'ERROR -- could not allocate controller',throwOnFailure=True,silentSuccess=True) + + # setTunerEnable + try: + orig = tuner_control.getTunerEnable(controller_id) + except FRONTEND.NotSupportedException: + self.check(True,True,'%s.getTunerEnable produces NotSupportedException -- cannot test setTunerEnable function'%(port_name)) + try: + tuner_control.setTunerEnable(controller_id, True) + except FRONTEND.NotSupportedException: + self.check(True,True,'%s.setTunerEnable produces NotSupportedException'%(port_name)) + else: + self.check(True,True,'%s.setTunerEnable executes without throwing exception'%(port_name)) + else: + try: + tuner_control.setTunerEnable(controller_id, not orig) + except FRONTEND.NotSupportedException: + self.check(True,True,'%s.setTunerEnable produces NotSupportedException'%(port_name)) + else: + self.check(not orig,tuner_control.getTunerEnable(controller_id),'setting tuner enable -- set to new value') + tuner_control.setTunerEnable(controller_id, orig) + self.check(orig,tuner_control.getTunerEnable(controller_id),'setting tuner enable -- set back to original value') + + self.dut_ref.deallocateCapacity(controller_alloc) + + def testFRONTEND_3_3_27(self): + ''' RX_DIG 3.27 Verify digital tuner port getter functions w/ bad alloc id + ''' + + port_name = 'DigitalTuner_in' + tuner_control = self.dut.getPort('DigitalTuner_in') + tuner_control._narrow(FRONTEND.FrontendTuner) + controller = self._generateRD() + function_list = self.digital_tuner_idl + + # make allocations + controller_id = controller['ALLOC_ID'] + controller_alloc = self._generateAlloc(controller) + self.check(self.dut_ref.allocateCapacity(controller_alloc),True,'ERROR -- could not allocate controller',throwOnFailure=True,silentSuccess=True) + + # verify invalid alloc_id -> FrontendException + bad_id = str(uuid.uuid4()) + for attr in filter(lambda x: x.startswith('get'),function_list): + f = getattr(tuner_control,attr) + try: + resp = f(bad_id) + except FRONTEND.NotSupportedException: + self.check(True,True,'%s.%s called with bad alloc_id produces NotSupportedException'%(port_name,attr)) + except FRONTEND.FrontendException: + self.check(True,True,'%s.%s called with bad alloc_id (should produce FrontendException)'%(port_name,attr)) + except Exception, e: + self.check(False,True,'%s.%s called with bad alloc_id (produces %s exception, should produce FrontendException)'%(port_name,attr,e.__class__.__name__)) + else: + self.check(False,True,'%s.%s called with bad alloc_id (does not produce exception, should produce FrontendException)'%(port_name,attr)) + + self.dut_ref.deallocateCapacity(controller_alloc) + + def testFRONTEND_3_3_28(self): + ''' RX_DIG 3.28 Verify digital tuner port setTunerCenterFrequency function w/ bad alloc id + ''' + + tuner_info=DEVICE_INFO['RX_DIGITIZER'] + port_name = 'DigitalTuner_in' + tuner_control = self.dut.getPort('DigitalTuner_in') + tuner_control._narrow(FRONTEND.FrontendTuner) + controller = self._generateRD() + + # make allocations + controller_id = controller['ALLOC_ID'] + controller_alloc = self._generateAlloc(controller) + self.check(self.dut_ref.allocateCapacity(controller_alloc),True,'ERROR -- could not allocate controller',throwOnFailure=True,silentSuccess=True) + + # setTunerCenterFrequency + bad_id = str(uuid.uuid4()) + try: + tuner_control.setTunerCenterFrequency(bad_id, float(tuner_info['CF_MIN'])) + except FRONTEND.NotSupportedException: + self.check(True,True,'%s.setTunerCenterFrequency called with bad alloc_id produces NotSupportedException'%(port_name)) + except FRONTEND.FrontendException: + self.check(True,True,'%s.setTunerCenterFrequency called with bad alloc_id produces FrontendException'%(port_name)) + except Exception, e: + self.check(False,True,'%s.setTunerCenterFrequency called with bad alloc_id (produces %s exception, should produce FrontendException)'%(port_name,e.__class__.__name__)) + else: + self.check(False,True,'%s.setTunerCenterFrequency called with bad alloc_id produces FrontendException (no exception)'%(port_name)) + + self.dut_ref.deallocateCapacity(controller_alloc) + + def testFRONTEND_3_3_29(self): + ''' RX_DIG 3.29 Verify digital tuner port setTunerBandwidth function w/ bad alloc id + ''' + + tuner_info=DEVICE_INFO['RX_DIGITIZER'] + port_name = 'DigitalTuner_in' + tuner_control = self.dut.getPort('DigitalTuner_in') + tuner_control._narrow(FRONTEND.FrontendTuner) + controller = self._generateRD() + + # make allocations + controller_id = controller['ALLOC_ID'] + controller_alloc = self._generateAlloc(controller) + self.check(self.dut_ref.allocateCapacity(controller_alloc),True,'ERROR -- could not allocate controller',throwOnFailure=True,silentSuccess=True) + + # setTunerBandwidth + bad_id = str(uuid.uuid4()) + try: + tuner_control.setTunerBandwidth(bad_id, float(tuner_info['BW_MIN'])) + except FRONTEND.NotSupportedException: + self.check(True,True,'%s.setTunerBandwidth called with bad alloc_id produces NotSupportedException'%(port_name)) + except FRONTEND.FrontendException: + self.check(True,True,'%s.setTunerBandwidth called with bad alloc_id produces FrontendException'%(port_name)) + except Exception, e: + self.check(False,True,'%s.setTunerBandwidth called with bad alloc_id (produces %s exception, should produce FrontendException)'%(port_name,e.__class__.__name__)) + else: + self.check(False,True,'%s.setTunerBandwidth called with bad alloc_id produces FrontendException (no exception)'%(port_name)) + + self.dut_ref.deallocateCapacity(controller_alloc) + + def testFRONTEND_3_3_30(self): + ''' RX_DIG 3.30 Verify digital tuner port setTunerOutputSampleRate function w/ bad alloc id + ''' + + tuner_info=DEVICE_INFO['RX_DIGITIZER'] + port_name = 'DigitalTuner_in' + tuner_control = self.dut.getPort('DigitalTuner_in') + tuner_control._narrow(FRONTEND.FrontendTuner) + controller = self._generateRD() + + # make allocations + controller_id = controller['ALLOC_ID'] + controller_alloc = self._generateAlloc(controller) + self.check(self.dut_ref.allocateCapacity(controller_alloc),True,'ERROR -- could not allocate controller',throwOnFailure=True,silentSuccess=True) + + # setTunerOutputSampleRate + bad_id = str(uuid.uuid4()) + try: + tuner_control.setTunerOutputSampleRate(bad_id, float(tuner_info['SR_MIN'])) + except FRONTEND.NotSupportedException: + self.check(True,True,'%s.setTunerOutputSampleRate called with bad alloc_id produces NotSupportedException'%(port_name)) + except FRONTEND.FrontendException: + self.check(True,True,'%s.setTunerOutputSampleRate called with bad alloc_id produces FrontendException'%(port_name)) + except Exception, e: + self.check(False,True,'%s.setTunerOutputSampleRate called with bad alloc_id (produces %s exception, should produce FrontendException)'%(port_name,e.__class__.__name__)) + else: + self.check(False,True,'%s.setTunerOutputSampleRate called with bad alloc_id produces FrontendException (no exception)'%(port_name)) + + self.dut_ref.deallocateCapacity(controller_alloc) + + def testFRONTEND_3_3_31(self): + ''' RX_DIG 3.31 Verify digital tuner port setTunerGain function w/ bad alloc id + ''' + + tuner_info=DEVICE_INFO['RX_DIGITIZER'] + port_name = 'DigitalTuner_in' + tuner_control = self.dut.getPort('DigitalTuner_in') + tuner_control._narrow(FRONTEND.FrontendTuner) + controller = self._generateRD() + + # make allocations + controller_id = controller['ALLOC_ID'] + controller_alloc = self._generateAlloc(controller) + self.check(self.dut_ref.allocateCapacity(controller_alloc),True,'ERROR -- could not allocate controller',throwOnFailure=True,silentSuccess=True) + + # setTunerGain + bad_id = str(uuid.uuid4()) + try: + tuner_control.setTunerGain(bad_id, float(tuner_info['GAIN_MIN'])) + except FRONTEND.NotSupportedException: + self.check(True,True,'%s.setTunerGain called with bad alloc_id produces NotSupportedException'%(port_name)) + except FRONTEND.FrontendException: + self.check(True,True,'%s.setTunerGain called with bad alloc_id produces FrontendException'%(port_name)) + except Exception, e: + self.check(False,True,'%s.setTunerGain called with bad alloc_id (produces %s exception, should produce FrontendException)'%(port_name,e.__class__.__name__)) + else: + self.check(False,True,'%s.setTunerGain called with bad alloc_id produces FrontendException (no exception)'%(port_name)) + + self.dut_ref.deallocateCapacity(controller_alloc) + + def testFRONTEND_3_3_32(self): + ''' RX_DIG 3.32 Verify digital tuner port setTunerAgcEnable function w/ bad alloc id + ''' + + port_name = 'DigitalTuner_in' + tuner_control = self.dut.getPort('DigitalTuner_in') + tuner_control._narrow(FRONTEND.FrontendTuner) + controller = self._generateRD() + + # make allocations + controller_id = controller['ALLOC_ID'] + controller_alloc = self._generateAlloc(controller) + self.check(self.dut_ref.allocateCapacity(controller_alloc),True,'ERROR -- could not allocate controller',throwOnFailure=True,silentSuccess=True) + + # setTunerAgcEnable + bad_id = str(uuid.uuid4()) + try: + tuner_control.setTunerAgcEnable(bad_id, False) + except FRONTEND.NotSupportedException: + self.check(True,True,'%s.setTunerAgcEnable called with bad alloc_id produces NotSupportedException'%(port_name)) + except FRONTEND.FrontendException: + self.check(True,True,'%s.setTunerAgcEnable called with bad alloc_id produces FrontendException'%(port_name)) + except Exception, e: + self.check(False,True,'%s.setTunerAgcEnable called with bad alloc_id (produces %s exception, should produce FrontendException)'%(port_name,e.__class__.__name__)) + else: + self.check(False,True,'%s.setTunerAgcEnable called with bad alloc_id produces FrontendException (no exception)'%(port_name)) + + self.dut_ref.deallocateCapacity(controller_alloc) + + def testFRONTEND_3_3_33(self): + ''' RX_DIG 3.33 Verify digital tuner port setTunerReferenceSource function w/ bad alloc id + ''' + + port_name = 'DigitalTuner_in' + tuner_control = self.dut.getPort('DigitalTuner_in') + tuner_control._narrow(FRONTEND.FrontendTuner) + controller = self._generateRD() + + # make allocations + controller_id = controller['ALLOC_ID'] + controller_alloc = self._generateAlloc(controller) + self.check(self.dut_ref.allocateCapacity(controller_alloc),True,'ERROR -- could not allocate controller',throwOnFailure=True,silentSuccess=True) + + # setTunerReferenceSource + bad_id = str(uuid.uuid4()) + try: + tuner_control.setTunerReferenceSource(bad_id, 0) + except FRONTEND.NotSupportedException: + self.check(True,True,'%s.setTunerReferenceSource called with bad alloc_id produces NotSupportedException'%(port_name)) + except FRONTEND.FrontendException: + self.check(True,True,'%s.setTunerReferenceSource called with bad alloc_id produces FrontendException'%(port_name)) + except Exception, e: + self.check(False,True,'%s.setTunerReferenceSource called with bad alloc_id (produces %s exception, should produce FrontendException)'%(port_name,e.__class__.__name__)) + else: + self.check(False,True,'%s.setTunerReferenceSource called with bad alloc_id produces FrontendException (no exception)'%(port_name)) + + self.dut_ref.deallocateCapacity(controller_alloc) + + def testFRONTEND_3_3_34(self): + ''' RX_DIG 3.34 Verify digital tuner port setTunerEnable function w/ bad alloc id + ''' + + port_name = 'DigitalTuner_in' + tuner_control = self.dut.getPort('DigitalTuner_in') + tuner_control._narrow(FRONTEND.FrontendTuner) + controller = self._generateRD() + + # make allocations + controller_id = controller['ALLOC_ID'] + controller_alloc = self._generateAlloc(controller) + self.check(self.dut_ref.allocateCapacity(controller_alloc),True,'ERROR -- could not allocate controller',throwOnFailure=True,silentSuccess=True) + + # setTunerEnable + bad_id = str(uuid.uuid4()) + try: + tuner_control.setTunerEnable(bad_id, False) + except FRONTEND.NotSupportedException: + self.check(True,True,'%s.setTunerEnable called with bad alloc_id produces NotSupportedException'%(port_name)) + except FRONTEND.FrontendException: + self.check(True,True,'%s.setTunerEnable called with bad alloc_id produces FrontendException'%(port_name)) + except Exception, e: + self.check(False,True,'%s.setTunerEnable called with bad alloc_id (produces %s exception, should produce FrontendException)'%(port_name,e.__class__.__name__)) + else: + self.check(False,True,'%s.setTunerEnable called with bad alloc_id produces FrontendException (no exception)'%(port_name)) + + self.dut_ref.deallocateCapacity(controller_alloc) + + # TODO - noseify + def testFRONTEND_3_4_DataFlow(self): + ''' RX_DIG 4 DataFlow + ''' + + ttype='RX_DIGITIZER' + controller = self._generateRD() + #controller['CF'] = float(DEVICE_INFO[ttype]['CF_MIN'] + max(DEVICE_INFO[ttype]['BW_MIN'],DEVICE_INFO[ttype]['SR_MIN'])) + controller['BW'] = float(DEVICE_INFO[ttype]['BW_MIN']) + controller['SR'] = float(DEVICE_INFO[ttype]['SR_MIN']) + listener1 = self._generateListener(controller) + listener2 = self._generateListener(controller) + + tuner_control = self.dut.getPort('DigitalTuner_in') + scd = SCDParser.parse(self.scd_file) + for port in sorted(self.scd.get_componentfeatures().get_ports().get_uses(),reverse=True): + comp_port_type = port.get_repid().split(':')[1].split('/')[-1] + comp_port_name = port.get_usesname() + if comp_port_type not in self.port_map: + print 'WARNING - skipping %s port named %s, not supported BULKIO port type'%(comp_port_type,comp_port_name) + continue + self._testBULKIO(tuner_control,comp_port_name,comp_port_type,ttype,controller,listener1,listener2) + + def _testBULKIO(self,tuner_control,comp_port_name,comp_port_type,ttype,controller,listener1=None,listener2=None): + if comp_port_type == 'dataSDDS': + print 'WARNING - dataSDDS output port testing not supported' + return + print 'Testing data flow on port:',comp_port_type,comp_port_name + pp(controller) + comp_port_obj = self.dut.getPort(str(comp_port_name)) + dataSink1 = sb.DataSink() + dataSink2 = sb.DataSink() + dataSink3 = sb.DataSink() + dataSink4 = sb.DataSink() + dataSink1_port_obj = dataSink1.getPort(self.port_map[comp_port_type]) + dataSink2_port_obj = dataSink2.getPort(self.port_map[comp_port_type]) + dataSink3_port_obj = dataSink3.getPort(self.port_map[comp_port_type]) + dataSink4_port_obj = dataSink4.getPort(self.port_map[comp_port_type]) + + #sb.start() + + # alloc a tuner + controller['ALLOC_ID'] = "control:"+str(uuid.uuid4()) # unique for each loop + tAlloc = self._generateAlloc(controller) + pp(controller) + pp(tAlloc) + comp_port_obj.connectPort(dataSink1_port_obj, controller['ALLOC_ID']) + self.dut_ref.allocateCapacity(tAlloc) + + # verify basic data flow + print >> sys.stderr,'attempting to get data from tuner' + for attempt in xrange(10): + time.sleep(1.0) + data1 = dataSink1.getData() + print >> sys.stderr,'attempt',attempt,'len(data1)=',len(data1) + if len(data1)>0: + break + self.check(len(data1)>0,True,'%s: Received data from tuner allocation'%(comp_port_name)) + + # verify SRI + #try: + # status = properties.props_to_dict(tuner_control.getTunerStatus(controller['ALLOC_ID'])) + #except FRONTEND.NotSupportedException, e: + status = self._getTunerStatusProp(controller['ALLOC_ID']) + pp(status) + if ttype=='DDC': + # get tuner status of parent CHAN/RDC... may be ambiguous + chan_props = {'FRONTEND::tuner_status::group_id':status['FRONTEND::tuner_status::group_id'], + 'FRONTEND::tuner_status::rf_flow_id':status['FRONTEND::tuner_status::rf_flow_id']} + ddc_props = {'FRONTEND::tuner_status::tuner_type':'DDC'} + try: + chan_status = self._findTunerStatusProps(match=chan_props,notmatch=ddc_props) + except KeyError: + chan_status = None + else: + if len(chan_status) != 1: + # ambiguous or no match found, can't be sure we're checking correct COL_RF + chan_status = None + else: + chan_status = chan_status[0] + + sri1 = dataSink1.sri() + print 'sri1',sri1 + self.checkAlmostEqual(status['FRONTEND::tuner_status::sample_rate'], 1.0/sri1.xdelta, '%s: SRI xdelta has correct value'%(comp_port_name),places=0) + + #complex is an optional property but if it is present check that it matches sri. + if 'FRONTEND::tuner_status::complex' in status: + self.check(status['FRONTEND::tuner_status::complex'],sri1.mode,'%s: SRI mode has correct value'%(comp_port_name)) + + # verify SRI keywords + keywords = properties.props_to_dict(sri1.keywords) + if 'COL_RF' in keywords: + self.check(True,True,'%s: SRI has COL_RF keyword'%(comp_port_name)) + if ttype == 'DDC': + if chan_status != None: + self.checkAlmostEqual(chan_status['FRONTEND::tuner_status::center_frequency'],keywords['COL_RF'],'%s: SRI keyword COL_RF has correct value'%(comp_port_name),places=0) + else: + print 'WARNING - could not determine center frequency of collector to compare with COL_RF keyword' + else: + self.checkAlmostEqual(status['FRONTEND::tuner_status::center_frequency'],keywords['COL_RF'],'%s: SRI keyword COL_RF has correct value'%(comp_port_name),places=0) + else: + self.check(False,True,'%s: SRI has COL_RF keyword'%(comp_port_name)) + + if 'CHAN_RF' in keywords: + self.check(True,True,'%s: SRI has CHAN_RF keyword'%(comp_port_name)) + self.checkAlmostEqual(status['FRONTEND::tuner_status::center_frequency'],keywords['CHAN_RF'],'%s: SRI keyword CHAN_RF has correct value'%(comp_port_name),places=0) + else: + self.check(False,True,'%s: SRI has CHAN_RF keyword'%(comp_port_name)) + + if 'FRONTEND::BANDWIDTH' in keywords: + self.check(True,True,'%s: SRI has FRONTEND::BANDWIDTH keyword'%(comp_port_name)) + if not self.checkAlmostEqual(status['FRONTEND::tuner_status::bandwidth'],keywords['FRONTEND::BANDWIDTH'],'%s: SRI keyword FRONTEND::BANDWIDTH has correct value'%(comp_port_name),places=0): + self.checkAlmostEqual(status['FRONTEND::tuner_status::sample_rate'],keywords['FRONTEND::BANDWIDTH'],'%s: SRI keyword FRONTEND::BANDWIDTH has sample rate value'%(comp_port_name),places=0, silentFailure=True, successMsg='WARN') + else: + self.check(False,True,'%s: SRI has FRONTEND::BANDWIDTH keyword'%(comp_port_name)) + + if 'FRONTEND::RF_FLOW_ID' in keywords: + self.check(True,True,'%s: SRI has FRONTEND::RF_FLOW_ID keyword'%(comp_port_name)) + self.check(status['FRONTEND::tuner_status::rf_flow_id'],keywords['FRONTEND::RF_FLOW_ID'],'%s: SRI keyword FRONTEND::RF_FLOW_ID has correct value'%(comp_port_name)) + else: + self.check(False,True,'%s: SRI has FRONTEND::RF_FLOW_ID keyword'%(comp_port_name)) + + if 'FRONTEND::DEVICE_ID' in keywords: + self.check(True,True,'%s: SRI has FRONTEND::DEVICE_ID keyword'%(comp_port_name)) + #self.check(1,keywords['FRONTEND::DEVICE_ID'],'SRI keyword FRONTEND::DEVICE_ID has correct value') + else: + self.check(False,True,'%s: SRI has FRONTEND::DEVICE_ID keyword'%(comp_port_name)) + + # verify multi-out port + bad_conn_id = "bad:"+str(uuid.uuid4()) + comp_port_obj.connectPort(dataSink2_port_obj, bad_conn_id) + for attempt in xrange(5): + time.sleep(1.0) + data2 = dataSink2.getData() + #print >> sys.stderr,'attempt',attempt,'len(data2)=',len(data2) + if len(data2)>0: + break + #print 'data2',len(data2) + self.check(len(data2)>0,False,'%s: Did not receive data from tuner allocation with wrong alloc_id (multiport test)'%(comp_port_name)) + sri1 = dataSink1.sri() + sri2 = dataSink2.sri() + print 'sri2',sri2 + self.check(sri1.streamID==sri2.streamID,False,'%s: Did not receive correct SRI from tuner allocation with wrong alloc_id (multiport test)'%(comp_port_name)) + + if self.device_discovery[ttype] < 2: + self.check(True,True,'%s: Cannot fully test multiport because only single %s tuner capability'%(comp_port_name,ttype),successMsg='info') + else: + pass # TODO - additional multiport tests here + + if listener1: + # verify listener + listener1 = self._generateListener(controller) # unique for each loop + listener1['LISTENER_ID'] = "listener1:"+listener1['LISTENER_ID'] + listenerAlloc1 = self._generateListenerAlloc(listener1) + comp_port_obj.connectPort(dataSink3_port_obj, listener1['LISTENER_ID']) + self.dut_ref.allocateCapacity(listenerAlloc1) + + for attempt in xrange(5): + time.sleep(1.0) + data3 = dataSink3.getData() + #print >> sys.stderr,'attempt',attempt,'len(data3)=',len(data3) + if len(data3)>0: + break + #print 'data3',len(data3) + self.check(len(data3)>0,True,'%s: Received data from listener allocation'%(comp_port_name)) + sri1 = dataSink1.sri() + sri3 = dataSink3.sri() + print 'sri3',sri3 + self.check(sri1.streamID==sri3.streamID,True,'%s: Received correct SRI from listener allocation'%(comp_port_name)) + + # verify EOS + if listener2: + listener2 = self._generateListener(controller) # unique for each loop + listener2['LISTENER_ID'] = "listener2:"+listener2['LISTENER_ID'] + listenerAlloc2 = self._generateListenerAlloc(listener2) + comp_port_obj.connectPort(dataSink4_port_obj, listener2['LISTENER_ID']) + self.dut_ref.allocateCapacity(listenerAlloc2) + time.sleep(1.0) + #for port_dict in port_list: + #data4 = dataSink4.getData() + self.dut_ref.deallocateCapacity(listenerAlloc1) + self.check(dataSink3.eos(),True,'%s: Listener received EOS after deallocation of listener'%(comp_port_name)) + self.check(dataSink1.eos(),False,'%s: Controller did not receive EOS after deallocation of listener'%(comp_port_name)) + self.dut_ref.deallocateCapacity(tAlloc) + self.check(dataSink1.eos(),True,'%s: Controller did receive EOS after deallocation of tuner'%(comp_port_name)) + if listener2: + self.check(dataSink4.eos(),True,'%s: Listener received EOS after deallocation of tuner'%(comp_port_name)) + # cleanup listener2 + comp_port_obj.disconnectPort(listener2['LISTENER_ID']) + try: + self.dut_ref.deallocateCapacity(listenerAlloc2) + except CF.Device.InvalidCapacity, e: + # Deallocating shouldn't be required if the allocation failed so we would expect this deallocation to be invalid + pass + # cleanup listener1 + comp_port_obj.disconnectPort(listener1['LISTENER_ID']) + # cleanup controller + comp_port_obj.disconnectPort(controller['ALLOC_ID']) + comp_port_obj.disconnectPort(bad_conn_id) + + # TODO - noseify + def testFRONTEND_3_5_TunerStatusProperties(self): + ''' RX_DIG 5 TunerStatusProperties + ''' + #self.testReport.append('\nTest 3.5 - Tuner Status Properties') + #self.getToBasicState() + + tuner_control = self.dut.getPort('DigitalTuner_in') + tuner_control._narrow(FRONTEND.FrontendTuner) + + controller = self._generateRD() + listener1 = self._generateListener(controller) + listener2 = self._generateListener(controller) + + # make allocations + controller_id = controller['ALLOC_ID'] + controller_alloc = self._generateAlloc(controller) + self.check(self.dut_ref.allocateCapacity(controller_alloc),True,'ERROR -- could not allocate controller',throwOnFailure=True,silentSuccess=True) + + listener1_id = listener1['LISTENER_ID'] + listener1_alloc = self._generateListenerAlloc(listener1) + retval = self.dut_ref.allocateCapacity(listener1_alloc) + if not retval: + self.testReport.append('Could not allocate listener1 -- limited test') + listener1 = None + else: + listener2_id = listener2['LISTENER_ID'] + listener2_alloc = self._generateListenerAlloc(listener2) + retval = self.dut_ref.allocateCapacity(listener2_alloc) + if not retval: + self.testReport.append('Could not allocate listener2 -- limited test') + listener2 = None + + # Verify correct tuner status structure (fields, types) + # check presence of tuner status property + # check that it contains the required fields of correct data type + # check which optional fields it contains, and that they are of correct data type + # check for unknown/undefined fields + try: + status = self._getTunerStatusProp(controller_id) + except KeyError: + self.check(False, True, 'Device has FRONTEND::tuner_status property (failure, cannot complete test)') + else: + if status == None: + self.check(False, True, 'Device has FRONTEND::tuner_status property (failure, cannot complete test)') + else: + self.check(True, True, 'Device has FRONTEND::tuner_status property') + for name,dtype in self.FE_tuner_status_fields_req.items(): + if status.has_key(name): + self.check(True, True, 'tuner_status has required field %s'%name) + self.check(type(status[name]) in dtype, True, 'value has correct data type for %s'%(name)) + else: + self.check(False, True, 'tuner_status has required field %s'%name) + for name,dtype in self.FE_tuner_status_fields_opt.items(): + if status.has_key(name): + self.check(True, True, 'tuner_status has OPTIONAL field %s'%name)#, successMsg='yes') + self.check(type(status[name]) in dtype, True, 'value has correct data type for %s'%(name)) + else: + self.check(False, True, 'tuner_status has OPTIONAL field %s'%name, failureMsg='no') + all_names = self.FE_tuner_status_fields_req.keys()+self.FE_tuner_status_fields_opt.keys() + for name in filter(lambda x: x not in all_names,status.keys()): + self.check(False, True, 'tuner_status has UNKNOWN field %s'%name, failureMsg='WARN') + + # Verify alloc_id_csv is populated after controller allocation + try: + status_val = self._getTunerStatusProp(controller_id,'FRONTEND::tuner_status::allocation_id_csv') + except KeyError: + pass + else: + if status_val == None: + self.check(True, False, 'controller allocation id added to tuner status after allocation of controller (could not get tuner status prop)') + else: + self.check(controller_id, status_val.split(',')[0], 'controller allocation id added to tuner status after allocation of controller (must be first in CSV list)') + + # Verify tuner is enabled following allocation + try: + status_val = self._getTunerStatusProp(controller_id,'FRONTEND::tuner_status::enabled') + except KeyError: + pass + else: + if status_val == None: + self.check(True, False, 'Tuner is enabled in tuner status after tuner allocation (could not get tuner status prop)') + else: + self.check(True, status_val, 'Tuner is enabled in tuner status after tuner allocation') + + if listener1: + # Verify listener allocation id is added after allocation of listener + try: + status_val = self._getTunerStatusProp(controller_id,'FRONTEND::tuner_status::allocation_id_csv') + except KeyError: + pass + else: + if status_val == None: + self.check(True, False, 'listener allocation id added to tuner status after allocation of listener (could not get tuner status prop)') + else: + self.check(listener1_id in status_val.split(',')[1:], True, 'listener allocation id added to tuner status after allocation of listener (must not be first in CSV list)') + + if tuner_control: + # Verify frequency prop + try: + val = tuner_control.getTunerCenterFrequency(controller_id) + except FRONTEND.NotSupportedException, e: + pass + else: + try: + status_val = self._getTunerStatusProp(controller_id,'FRONTEND::tuner_status::center_frequency') + except KeyError: + pass + else: + self.checkAlmostEqual(status_val, val, 'correct value for FRONTEND::tuner_status::center_frequency property',places=0) + #setTunerCenterFrequency + + # Verify bandwidth prop + try: + val = tuner_control.getTunerBandwidth(controller_id) + except FRONTEND.NotSupportedException, e: + pass + else: + try: + status_val = self._getTunerStatusProp(controller_id,'FRONTEND::tuner_status::bandwidth') + except KeyError: + pass + else: + self.checkAlmostEqual(status_val, val, 'correct value for FRONTEND::tuner_status::bandwidth property',places=0) + #setTunerBandwidth + + # Verify sample rate prop + try: + val = tuner_control.getTunerOutputSampleRate(controller_id) + except FRONTEND.NotSupportedException, e: + pass + else: + try: + status_val = self._getTunerStatusProp(controller_id,'FRONTEND::tuner_status::sample_rate') + except KeyError: + pass + else: + self.checkAlmostEqual(status_val, val, 'correct value for FRONTEND::tuner_status::sample_rate property',places=0) + #setTunerOutputSampleRate + + # Verify group id prop + try: + val = tuner_control.getTunerGroupId(controller_id) + except FRONTEND.NotSupportedException, e: + pass + else: + try: + status_val = self._getTunerStatusProp(controller_id,'FRONTEND::tuner_status::group_id') + except KeyError: + pass + else: + self.check(status_val, val, 'correct value for FRONTEND::tuner_status::group_id property') + + # Verify rf flow id prop + try: + val = tuner_control.getTunerRfFlowId(controller_id) + except FRONTEND.NotSupportedException, e: + pass + else: + try: + status_val = self._getTunerStatusProp(controller_id,'FRONTEND::tuner_status::rf_flow_id') + except KeyError: + pass + else: + self.check(status_val, val, 'correct value for FRONTEND::tuner_status::rf_flow_id property') + + if listener1: + # Verify listener allocation id is removed after deallocation of listener + self.dut_ref.deallocateCapacity(listener1_alloc) + try: + status_val = self._getTunerStatusProp(controller_id,'FRONTEND::tuner_status::allocation_id_csv') + except KeyError: + pass + else: + self.check(listener1_id in status_val, False, 'listener allocation id removed from tuner status after deallocation of listener') + + # Verify controller allocation id is removed after deallocation of controller + self.dut_ref.deallocateCapacity(controller_alloc) + try: + status = self._getTunerStatusProp(controller_id) + except KeyError: + pass + else: + self.check(None, status, 'controller allocation id removed from tuner status after deallocation of controller') + + if listener2: + # Verify listener allocation id is removed after deallocation of controller + #self.dut_ref.deallocateCapacity(controllerAlloc) + try: + status = self._getTunerStatusProp(listener2_id) + except KeyError: + pass + else: + self.check(None, status, 'listener allocation id removed from tuner status after deallocation of controller') + + @classmethod + def printTestReport(self): + sys.stderr.writelines(self.testReport) + + #Helpers + def check(self, A, B, message, throwOnFailure=False, silentFailure=False, silentSuccess=False, indent_width=0, failureMsg='FAILURE', successMsg='ok'): + # successMsg suggestions: PASS, YES, ok, u'\u2714' (check mark) + # failureMsg suggestions: FAIL, NO, u'\u2718' (x mark) + if 'Total checks made' in self.testReportStats: self.testReportStats['Total checks made']+=1 + else: self.testReportStats['Total checks made']=1 + if A == B: + if not silentSuccess: + self.testReport.append(self._buildRow(message,successMsg,indent_width)) + tmp = 'Checks that returned "%s"'%successMsg[:4] + if tmp in self.testReportStats: self.testReportStats[tmp]+=1 + else: self.testReportStats[tmp]=1 + return True # success! + else: + if not silentFailure: + self.testReport.append(self._buildRow(message,failureMsg,indent_width)) + tmp = 'Checks that returned "%s"'%failureMsg[:4] + if tmp in self.testReportStats: self.testReportStats[tmp]+=1 + else: self.testReportStats[tmp]=1 + if throwOnFailure: + #self.testReport.append('Terminal error, stopping current test...') + self.getToShutdownState() + self.assertFalse(failureMsg+'::'+message) + return False # failure! + + def checkAlmostEqual(self, A, B, message, throwOnFailure=False, silentFailure=False, silentSuccess=False, indent_width=0, failureMsg='FAILURE', successMsg='ok', places=7): + # successMsg suggestions: PASS, YES, ok, u'\u2714' (check mark) + # failureMsg suggestions: FAIL, NO, u'\u2718' (x mark) + #print "DEBUG","A=",A,"B=",B + if 'Total checks made' in self.testReportStats: self.testReportStats['Total checks made']+=1 + else: self.testReportStats['Total checks made']=1 + if round(B-A, places) == 0: + if not silentSuccess: + self.testReport.append(self._buildRow(message,successMsg,indent_width)) + tmp = 'Checks that returned "%s"'%successMsg[:4] + if tmp in self.testReportStats: self.testReportStats[tmp]+=1 + else: self.testReportStats[tmp]=1 + return True # success! + else: + if not silentFailure: + self.testReport.append(self._buildRow(message,failureMsg,indent_width)) + tmp = 'Checks that returned "%s"'%failureMsg[:4] + if tmp in self.testReportStats: self.testReportStats[tmp]+=1 + else: self.testReportStats[tmp]=1 + if throwOnFailure: + #self.testReport.append('Terminal error, stopping current test...') + self.getToShutdownState() + self.assertFalse(failureMsg+'::'+message) + return False # failure! + + def _buildRow(self, lhs, rhs, indent_width=0, filler='.', len_total=80, rhs_width=4, depth=1): + ''' builds a row (or multiple rows, if required) that fit within len_total columns + format: + -will be split over multiple lines if necessary + -pads rhs text to number of characters specified by rhs_width using spaces + -truncates rhs text to number of characters specified by rhs_width + ''' + min_filler = 3 + max_lines = 5 + filler_width = len_total - (indent_width + len(lhs) + rhs_width) + if filler_width >= min_filler: + return (' '*indent_width + lhs + filler*filler_width + rhs)[0:len_total] + else: + lhs1_width = len_total - (indent_width + min_filler + rhs_width) + idx = lhs.rfind(' ',0,lhs1_width) # try to split on a space + if idx == -1: + idx = (lhs+' ').find(' ') # split at first space, if any, or take the whole string + line1 = ' '*indent_width + lhs[:idx] + if depth==1: + indent_width += 4 + if depth >= max_lines: + return line1 + else: + line2 = self._buildRow(lhs[idx:], rhs, indent_width, filler, len_total, rhs_width, depth=depth+1) + return line1 + '\n' + line2 + + def _tunerStatusHasAllocId(self,alloc_id): + props = self.dut.query([]) + props = properties.props_to_dict(props) + for tuner in props['FRONTEND::tuner_status']: + if alloc_id in tuner['FRONTEND::tuner_status::allocation_id_csv'].split(','): + return True + return False + + def _findTunerStatusProps(match={},notmatch={}): + ''' query latest props, find tuner status associated with key/value pairs + in "match" dict where the key/value pairs of "notmatch" dict don't match + return a list of tuner status prop dicts + return empty list no tuner status satisfies the criteria + if FRONTEND::tuner_status prop not found, raises KeyError + if any key in match or notmatch not found, raises KeyError + ''' + props = self.dut.query([]) + props = properties.props_to_dict(props) + tuners = copy.deepcopy(props['FRONTEND::tuner_status']) + for k,v in match.items(): + bad = [] + for tuner in tuners: + if tuner[k] != v: + bad.append(tuner) + tuners = [x for x in tuners if x not in bad] + #tuners = filter(lambda x: x not in bad, tuners) + for k,v in notmatch.items(): + bad = [] + for tuner in tuners: + if tuner[k] == v: + bad.append(tuner) + tuners = [x for x in tuners if x not in bad] + #tuners = filter(lambda x: x not in bad, tuners) + return tuners + + def _getTunerStatusProp(self,alloc_id,name=None): + ''' query latest props, find tuner status associated with alloc_id + if name arg is specified, return the tuner status property of that name + otherwise, return the tuner status prop as a dict + return None if either alloc_id or name not found + if FRONTEND::tuner_status prop not found, raises KeyError + ''' + props = self.dut.query([]) + props = properties.props_to_dict(props) + for tuner in props['FRONTEND::tuner_status']: + if alloc_id in tuner['FRONTEND::tuner_status::allocation_id_csv'].split(','): + break + else: + return None + + if name!=None: + try: + return tuner[name] + except KeyError: + return None + else: + return tuner + + def _generateRD(self): + #Pick a random set for CF,BW,SR and return + value = {} + value['ALLOC_ID'] = str(uuid.uuid4()) + value['TYPE'] = 'RX_DIGITIZER' + value['BW_TOLERANCE'] = 100.0 + value['SR_TOLERANCE'] = 100.0 + value['RF_FLOW_ID'] = '' + value['GROUP_ID'] = '' + value['CONTROL'] = True + + if (DEVICE_INFO['RX_DIGITIZER']['CF_MIN'] != DEVICE_INFO['RX_DIGITIZER']['CF_MAX']): + #value['CF'] = float(random.randrange(DEVICE_INFO['RX_DIGITIZER']['CF_MIN'], DEVICE_INFO['RX_DIGITIZER']['CF_MAX'], 1.0e3)) + value['CF'] = float(int(random.uniform(DEVICE_INFO['RX_DIGITIZER']['CF_MIN'], DEVICE_INFO['RX_DIGITIZER']['CF_MAX']))) + else: + value['CF'] = float(DEVICE_INFO['RX_DIGITIZER']['CF_MIN']) + + if (DEVICE_INFO['RX_DIGITIZER']['SR_MIN'] != DEVICE_INFO['RX_DIGITIZER']['SR_MAX']): + #value['SR'] = float(random.randrange(DEVICE_INFO['RX_DIGITIZER']['SR_MIN'], DEVICE_INFO['RX_DIGITIZER']['SR_MAX'], 1.0e3)) + value['SR'] = float(random.uniform(DEVICE_INFO['RX_DIGITIZER']['SR_MIN'], DEVICE_INFO['RX_DIGITIZER']['SR_MAX'])) + else: + value['SR'] = float(DEVICE_INFO['RX_DIGITIZER']['SR_MIN']) + + + if (DEVICE_INFO['RX_DIGITIZER']['BW_MIN'] != DEVICE_INFO['RX_DIGITIZER']['BW_MAX']): + #value['BW'] = float(random.randrange(DEVICE_INFO['RX_DIGITIZER']['BW_MIN'], DEVICE_INFO['RX_DIGITIZER']['BW_MAX'], 1.0e3)) + #value['BW'] = float(random.uniform(DEVICE_INFO['RX_DIGITIZER']['BW_MIN'], DEVICE_INFO['RX_DIGITIZER']['BW_MAX'])) + # calculate a random BW value that is + # a) within bandwidth limits of device + # b) within 100% tolerance of the usable bandwidth given the SR chosen above (usable BW = SR if complex, else usable BW = SR*0.5) + if DEVICE_INFO['RX_DIGITIZER']['COMPLEX']: + bw_min = max(value['SR']*0.8,DEVICE_INFO['RX_DIGITIZER']['BW_MIN']) + bw_max = min(value['SR']*0.8,DEVICE_INFO['RX_DIGITIZER']['BW_MAX']) + #value['BW'] = float(value['SR']) + else: + bw_min = max(value['SR']*0.5*0.5,DEVICE_INFO['RX_DIGITIZER']['BW_MIN']) + bw_max = min(value['SR']*0.5,DEVICE_INFO['RX_DIGITIZER']['BW_MAX']) + #value['BW'] = float(value['SR']*0.5) + value['BW'] = float(random.uniform(bw_min, bw_max)) + else: + value['BW'] = float(DEVICE_INFO['RX_DIGITIZER']['BW_MIN']) + + return value + + def _generateListener(self, c): + value = {} + value['LISTENER_ID'] = str(uuid.uuid4()) + value['ALLOC_ID'] = c['ALLOC_ID'] + return value + + def _generateListenerAlloc(self, value): + allocationPropDict = {'FRONTEND::listener_allocation':{ + 'FRONTEND::listener_allocation::existing_allocation_id': value['ALLOC_ID'], + 'FRONTEND::listener_allocation::listener_allocation_id': value['LISTENER_ID'], + }} + return properties.props_from_dict(allocationPropDict) + + def _generateAlloc(self, value): + #generate the allocation + allocationPropDict = {'FRONTEND::tuner_allocation':{ + 'FRONTEND::tuner_allocation::tuner_type': value['TYPE'], + 'FRONTEND::tuner_allocation::allocation_id': value['ALLOC_ID'], + 'FRONTEND::tuner_allocation::center_frequency': float(value['CF']), + 'FRONTEND::tuner_allocation::bandwidth': float(value['BW']), + 'FRONTEND::tuner_allocation::bandwidth_tolerance': float(value['BW_TOLERANCE']), + 'FRONTEND::tuner_allocation::sample_rate': float(value['SR']), + 'FRONTEND::tuner_allocation::sample_rate_tolerance': float(value['SR_TOLERANCE']), + 'FRONTEND::tuner_allocation::device_control': value['CONTROL'], + 'FRONTEND::tuner_allocation::group_id': value['GROUP_ID'], + 'FRONTEND::tuner_allocation::rf_flow_id': value['RF_FLOW_ID'], + }} + return properties.props_from_dict(allocationPropDict) + + +######################################################### +## CODE FROM unit_test_helpers with @classmethod added ## +######################################################### + +def isMatch(prop, modes, kinds, actions): + if prop.get_mode() == None: + m = "readwrite" + else: + m = prop.get_mode() + matchMode = (m in modes) + if prop.__class__ in (PRFParser.simple, PRFParser.simpleSequence): + if prop.get_action() == None: + a = "external" + else: + a = prop.get_action().get_type() + matchAction = (a in actions) + + matchKind = False + if prop.get_kind() == None: + k = ["configure"] + else: + k = prop.get_kind() + for kind in k: + if kind.get_kindtype() in kinds: + matchKind = True + + elif prop.__class__ in (PRFParser.struct, PRFParser.structSequence): + matchAction = True # There is no action, so always match + + matchKind = False + if prop.get_configurationkind() == None: + k = ["configure"] + else: + k = prop.get_configurationkind() + for kind in k: + if kind.get_kindtype() in kinds: + matchKind = True + + if k in kinds: + matchKind = True + + + return matchMode and matchKind and matchAction + +def getPropertySet(spd_file, kinds=("configure",), \ + modes=("readwrite", "writeonly", "readonly"), \ + action="external", \ + includeNil=True): + """ + A useful utility function that extracts specified property types from + the PRF file and turns them into a CF.PropertySet + """ + propertySet = [] + + spd = SPDParser.parse(spd_file) + prf_file = spd.get_propertyfile().get_localfile().get_name() + if (prf_file[0] != '/'): + prf_file = os.path.join(os.path.dirname(spd_file), prf_file) + prf = PRFParser.parse(prf_file) + + # Simples + for prop in prf.get_simple(): + if isMatch(prop, modes, kinds, (action,)): + if prop.get_value() is not None: + dt = properties.to_tc_value(prop.get_value(), prop.get_type()) + elif not includeNil: + continue + else: + dt = any.to_any(None) + p = CF.DataType(id=str(prop.get_id()), value=dt) + propertySet.append(p) + + # Simple Sequences + for prop in prf.get_simplesequence(): + if isMatch(prop, modes, kinds, (action,)): + if prop.get_values() is not None: + seq = [] + for v in prop.get_values().get_value(): + seq.append(properties.to_pyvalue(v, prop.get_type())) + dt = any.to_any(seq) + elif not includeNil: + continue + else: + dt = any.to_any(None) + p = CF.DataType(id=str(prop.get_id()), value=dt) + propertySet.append(p) + + # Structures + for prop in prf.get_struct(): + if isMatch(prop, modes, kinds, (action,)): + if prop.get_simple() is not None: + fields = [] + hasValue = False + for s in prop.get_simple(): + if s.get_value() is not None: + hasValue = True + dt = properties.to_tc_value(s.get_value(), s.get_type()) + fields.append(CF.DataType(id=str(s.get_id()), value=dt)) + if not hasValue and not includeNil: + continue + dt = any.to_any(fields) + else: + dt = any.to_any(None) + p = CF.DataType(id=str(prop.get_id()), value=dt) + propertySet.append(p) + # Structures + + for prop in prf.get_structsequence(): + if isMatch(prop, modes, kinds, (action,)): + baseProp = [] + if prop.get_struct() != None: + fields = [] + for internal_prop in prop.get_struct().get_simple(): + fields.append(CF.DataType(id=str(internal_prop.get_id()), value=any.to_any(None))) + for val in prop.get_structvalue(): + baseProp.append(copy.deepcopy(fields)) + for entry in val.get_simpleref(): + val_type = None + for internal_prop in prop.get_struct().get_simple(): + if str(internal_prop.get_id()) == entry.refid: + val_type = internal_prop.get_type() + for subfield in baseProp[-1]: + if subfield.id == entry.refid: + subfield.value = properties.to_tc_value(entry.get_value(), val_type) + anybp = [] + for bp in baseProp: + anybp.append(properties.props_to_any(bp)) + p = CF.DataType(id=str(prop.get_id()), value=any.to_any(anybp)) + propertySet.append(p) + # Struct Sequence + + return propertySet diff --git a/redhawk-codegen/redhawk/codegen/jinja/python/component/frontend/templates/resource_base.py b/redhawk-codegen/redhawk/codegen/jinja/python/component/frontend/templates/resource_base.py index 293bf0118..d71aee3b5 100644 --- a/redhawk-codegen/redhawk/codegen/jinja/python/component/frontend/templates/resource_base.py +++ b/redhawk-codegen/redhawk/codegen/jinja/python/component/frontend/templates/resource_base.py @@ -20,6 +20,7 @@ #% extends "pull/resource_base.py" #{% block baseadditionalimports %} import frontend +from omniORB import any as _any #{% if 'FrontendTuner' in component.implements %} from frontend import FRONTEND from ossie.properties import struct_to_props @@ -41,7 +42,8 @@ def getTunerStatus(self,allocation_id): tuner_id = self.getTunerMapping(allocation_id) if tuner_id < 0: raise FRONTEND.FrontendException(("ERROR: ID: " + str(allocation_id) + " IS NOT ASSOCIATED WITH ANY TUNER!")) - return struct_to_props(self.frontend_tuner_status[tuner_id]) + _props = self.query([CF.DataType(id='FRONTEND::tuner_status',value=_any.to_any(None))]) + return _props[0].value._v[tuner_id]._v def assignListener(self,listen_alloc_id, allocation_id): # find control allocation_id From 7320f65dc906c3467326911e6cfac41eebb922d1 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 22 Feb 2017 10:35:48 -0500 Subject: [PATCH 0721/1644] CF-1706 Fix BulkIO's Java unit tests to work without BulkIO installed, both with and without ant --- bulkioInterfaces/configure.ac | 5 +++ .../libsrc/testing/tests/java/.gitignore | 2 +- .../libsrc/testing/tests/java/Makefile | 38 ----------------- .../libsrc/testing/tests/java/Makefile.am | 41 +++++++++++++++++++ .../libsrc/testing/tests/java/build.xml | 6 ++- 5 files changed, 51 insertions(+), 41 deletions(-) delete mode 100644 bulkioInterfaces/libsrc/testing/tests/java/Makefile create mode 100644 bulkioInterfaces/libsrc/testing/tests/java/Makefile.am diff --git a/bulkioInterfaces/configure.ac b/bulkioInterfaces/configure.ac index 203d8579a..08f01d45c 100644 --- a/bulkioInterfaces/configure.ac +++ b/bulkioInterfaces/configure.ac @@ -137,6 +137,10 @@ AM_CONDITIONAL(HAVE_JAVASUPPORT, test $HAVE_JAVASUPPORT = yes) # C++ unit testing support. May want to conditionally enable/disable this. AM_PATH_CPPUNIT(1.12.1) +AS_IF([test "x$HAVE_JAVASUPPORT" == "xyes"], [ + dnl Use RPM location hard-coded for now + AC_SUBST([JUNIT_CLASSPATH], "/usr/share/java/junit4.jar") +]) # For C++ test components, provide BULKIO_CFLAGS and BULKIO_LIBS so they build # without modifying their Makefile.am to change the paths. In order to pick up @@ -162,6 +166,7 @@ if test "$enable_base_classes" != "no"; then libsrc/bulkio.pc \ libsrc/testing/Makefile \ libsrc/testing/tests/cpp/Makefile \ + libsrc/testing/tests/java/Makefile \ libsrc/testing/components/CPP_Ports/cpp/Makefile \ libsrc/testing/components/Java_Ports/java/Makefile \ libsrc/testing/components/Oversized_framedata/cpp/Makefile \ diff --git a/bulkioInterfaces/libsrc/testing/tests/java/.gitignore b/bulkioInterfaces/libsrc/testing/tests/java/.gitignore index 96966d7c4..49df7be9f 100644 --- a/bulkioInterfaces/libsrc/testing/tests/java/.gitignore +++ b/bulkioInterfaces/libsrc/testing/tests/java/.gitignore @@ -1,2 +1,2 @@ *.class -!Makefile +Bulkio diff --git a/bulkioInterfaces/libsrc/testing/tests/java/Makefile b/bulkioInterfaces/libsrc/testing/tests/java/Makefile deleted file mode 100644 index 597217fc8..000000000 --- a/bulkioInterfaces/libsrc/testing/tests/java/Makefile +++ /dev/null @@ -1,38 +0,0 @@ - -bulkio_top_dir=../../../.. -bulkio_idl_dir=$(bulkio_top_dir) -bulkio_idl_java_dir=$(bulkio_top_dir) -bulkio_libsrc_dir=$(bulkio_top_dir)/libsrc -bulkio_libsrc_java_dir=$(bulkio_libsrc_dir)/java -OSSIE_HOME=$(shell echo $(OSSIEHOME)) -BULKIO_JARS=$(OSSIE_HOME)/lib/CFInterfaces.jar:$(OSSIE_HOME)/lib/log4j-1.2.15.jar:$(OSSIE_HOME)/lib/ossie.jar:$(bulkio_libsrc_dir)/bulkio.jar:$(bulkio_idl_java_dir)/BULKIOInterfaces.jar - -JAVA = $(JAVA_HOME)/bin/java -JAVAC = $(JAVA_HOME)/bin/javac -JAVA_CP=$(CLASSPATH):.:/usr/share/java/junit4.jar:$(BULKIO_JARS) - -.SUFFIXES: .java .class -.PHONEY: all check build-all clean tcheck - -IN_PORTS= InVectorPort_Test.class InStringPort_Test.class InSDDSPort_Test.class BulkioHelpers_Test.class -OUT_PORTS= OutVectorPort_Test.class OutStringPort_Test.class OutSDDSPort_Test.class -MULTIOUT_PORTS=MultiOutInt8_Test.class MultiOutInt16_Test.class MultiOutInt32_Test.class MultiOutInt64_Test.class MultiOutFloat_Test.class MultiOutDouble_Test.class MultiOutUInt8_Test.class MultiOutUInt16_Test.class MultiOutUInt32_Test.class MultiOutUInt64_Test.class - -JTESTS=$(IN_PORTS:.class=) $(OUT_PORTS:.class=) $(MULTIOUT_PORTS:.class=) -.java.class: - $(JAVAC) -cp $(JAVA_CP) $^ - -all: build-all check - -build-all: $(IN_PORTS) $(OUT_PORTS) $(MULTIOUT_PORTS) - -tcheck: - $(JAVA) -cp $(JAVA_CP) org.junit.runner.JUnitCore OutVectorPort_Test - -check: - @for jtest in "$(JTESTS)" ; do \ - $(JAVA) -cp $(JAVA_CP) -Dlog4j.configuration=file:log4j_config.txt org.junit.runner.JUnitCore $$jtest ; \ - done - -clean: - -rm *.class diff --git a/bulkioInterfaces/libsrc/testing/tests/java/Makefile.am b/bulkioInterfaces/libsrc/testing/tests/java/Makefile.am new file mode 100644 index 000000000..ec81e35a4 --- /dev/null +++ b/bulkioInterfaces/libsrc/testing/tests/java/Makefile.am @@ -0,0 +1,41 @@ +# +# This file is protected by Copyright. Please refer to the COPYRIGHT file +# distributed with this source distribution. +# +# This file is part of REDHAWK bulkioInterfaces. +# +# REDHAWK burstioInterfaces is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation, either version 3 of the License, or (at your option) any +# later version. +# +# REDHAWK burstioInterfaces is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +# details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/. +# + +Bulkio_CLASSES = InVectorPort_Test.class InStringPort_Test.class InSDDSPort_Test.class BulkioHelpers_Test.class +Bulkio_CLASSES += OutVectorPort_Test.class OutStringPort_Test.class OutSDDSPort_Test.class +Bulkio_CLASSES += MultiOutInt8_Test.class MultiOutInt16_Test.class MultiOutInt32_Test.class MultiOutInt64_Test.class MultiOutFloat_Test.class MultiOutDouble_Test.class MultiOutUInt8_Test.class MultiOutUInt16_Test.class MultiOutUInt32_Test.class MultiOutUInt64_Test.class + +Bulkio_CLASSPATH = $(BULKIO_CLASSPATH):$(OSSIE_CLASSPATH):$(JUNIT_CLASSPATH) + +TEST_CLASSES = $(patsubst %.class,%,$(Bulkio_CLASSES)) + +TESTS = Bulkio +check_SCRIPTS = Bulkio + +%.class : %.java + $(AM_V_at)$(JAVAC) -d $(builddir) -cp $(Bulkio_CLASSPATH) -g -Xlint $< + +Bulkio : $(Bulkio_CLASSES) Makefile.am + @echo "#!/bin/sh" > $@ + @echo "export LD_LIBRARY_PATH=$(top_builddir)/jni/.libs:${LD_LIBRARY_PATH}" >> $@ + @echo "exec java -cp $(Bulkio_CLASSPATH):. -Dlog4j.configuration=file:$(srcdir)/log4j_config.txt org.junit.runner.JUnitCore $(TEST_CLASSES)" >> $@ + @chmod +x $@ + +CLEANFILES = Bulkio $(BUILT_SOURCES) *.class diff --git a/bulkioInterfaces/libsrc/testing/tests/java/build.xml b/bulkioInterfaces/libsrc/testing/tests/java/build.xml index 161ae294b..04ce33451 100644 --- a/bulkioInterfaces/libsrc/testing/tests/java/build.xml +++ b/bulkioInterfaces/libsrc/testing/tests/java/build.xml @@ -26,6 +26,7 @@ with this program. If not, see http://www.gnu.org/licenses/. + @@ -34,8 +35,8 @@ with this program. If not, see http://www.gnu.org/licenses/. - - + + @@ -53,6 +54,7 @@ with this program. If not, see http://www.gnu.org/licenses/. + From 201352cb4758db5e93503ffa397a1f0d26ef184a Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 22 Feb 2017 11:34:07 -0500 Subject: [PATCH 0722/1644] CF-1706 Include BULKIOInterfaces.jar in CLASSPATH for BulkIO runtests, and slightly modify dev_src test to not require the BulkIO IDL to be installed --- .../libsrc/testing/devices/dev_src/tests/test_dev_src.py | 6 +++++- bulkioInterfaces/libsrc/testing/tests/runtests | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/bulkioInterfaces/libsrc/testing/devices/dev_src/tests/test_dev_src.py b/bulkioInterfaces/libsrc/testing/devices/dev_src/tests/test_dev_src.py index 4b6821f6a..482143e53 100644 --- a/bulkioInterfaces/libsrc/testing/devices/dev_src/tests/test_dev_src.py +++ b/bulkioInterfaces/libsrc/testing/devices/dev_src/tests/test_dev_src.py @@ -57,7 +57,11 @@ def testRHBasicBehavior(self): ####################################################################### # Make sure start and stop can be called without throwing exceptions self.comp.connect(self.comp_snk) - self.assertTrue(self.comp.ports[0]._get_connections()[0].port._is_equivalent(self.comp_snk.ports[0].ref)) + # Explicitly get the CORBA port references for comparison because the + # IDL may not be installed, throwing exceptions on comp.ports + src = self.comp.getPort('dataFloat_out') + sink = self.comp_snk.getPort('dataFloat_in') + self.assertTrue(src._get_connections()[0].port._is_equivalent(sink)) if __name__ == "__main__": ossie.utils.testing.main("../dev_src.spd.xml") # By default tests all implementations diff --git a/bulkioInterfaces/libsrc/testing/tests/runtests b/bulkioInterfaces/libsrc/testing/tests/runtests index 8e53084fa..298359e3c 100755 --- a/bulkioInterfaces/libsrc/testing/tests/runtests +++ b/bulkioInterfaces/libsrc/testing/tests/runtests @@ -8,7 +8,7 @@ bulkio_top=$(cd ../../..;pwd) bulkio_libsrc_top=$bulkio_top/libsrc export LD_LIBRARY_PATH=$bulkio_libsrc_top/.libs:$bulkio_top/.libs:$bulkio_top/jni/.libs:${LD_LIBRARY_PATH} export PYTHONPATH=$bulkio_libsrc_top/build/lib:${PYTHONPATH} -export CLASSPATH=${bulkio_libsrc_top}/bulkio.jar:${CLASSPATH} +export CLASSPATH=${bulkio_libsrc_top}/bulkio.jar:${bulkio_top}/BULKIOInterfaces.jar:${CLASSPATH} # Limit the number of threads Java uses for the garbage collector to avoid # misleading Java "out of memory" errors that in all actuality appear to be From 7184a035c1a871aa49ffb4910abf1fef5a0a2585 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Wed, 22 Feb 2017 13:54:26 -0500 Subject: [PATCH 0723/1644] Refs CF-1684. Fixed testing issue to work in CentOS 6 --- .../tests/fei_base/frontend_tuner_unit_test_base.py | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/tests/fei_base/frontend_tuner_unit_test_base.py b/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/tests/fei_base/frontend_tuner_unit_test_base.py index c4f1ffe56..026d2170d 100644 --- a/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/tests/fei_base/frontend_tuner_unit_test_base.py +++ b/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/tests/fei_base/frontend_tuner_unit_test_base.py @@ -2232,14 +2232,11 @@ def testFRONTEND_3_4_DataFlow(self): listener2 = self._generateListener(controller) tuner_control = self.dut.getPort('DigitalTuner_in') - scd = SCDParser.parse(self.scd_file) - for port in sorted(self.scd.get_componentfeatures().get_ports().get_uses(),reverse=True): - comp_port_type = port.get_repid().split(':')[1].split('/')[-1] - comp_port_name = port.get_usesname() - if comp_port_type not in self.port_map: - print 'WARNING - skipping %s port named %s, not supported BULKIO port type'%(comp_port_type,comp_port_name) - continue - self._testBULKIO(tuner_control,comp_port_name,comp_port_type,ttype,controller,listener1,listener2) + for port in self.dut.ports: + if port._direction == 'Uses': + comp_port_name = port.name + comp_port_type = port._using.name + self._testBULKIO(tuner_control,comp_port_name,comp_port_type,ttype,controller,listener1,listener2) def _testBULKIO(self,tuner_control,comp_port_name,comp_port_type,ttype,controller,listener1=None,listener2=None): if comp_port_type == 'dataSDDS': From 155f94d3cd550582da8aa52bc6570b903207db55 Mon Sep 17 00:00:00 2001 From: 8530 <8530@vm-131.vsi-corp.com> Date: Wed, 22 Feb 2017 15:58:56 -0500 Subject: [PATCH 0724/1644] make copy of provided sri when saving off to datasource, CF-205 --- .../python/ossie/utils/sb/io_helpers.py | 11 ++- redhawk/src/testing/tests/test_13_TestSB.py | 83 +++++++++++++------ 2 files changed, 61 insertions(+), 33 deletions(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py b/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py index 8cf70481f..567b60117 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py +++ b/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py @@ -1379,7 +1379,7 @@ def pushThread(self): candidateSri = _copy.copy(self._sri) if sri != None: # user supplied sri - candidateSri = sri + candidateSri = sri if streamID and streamID != candidateSri.streamID: candidateSri.streamID = streamID @@ -1398,9 +1398,8 @@ def pushThread(self): if complexData == True: candidateSri.mode = 1 self._complexData = 1 - else: - candidateSri.mode = 0 - self._complexData = 0 + + self._complexData = candidateSri.mode if self._startTime >= 0.0: candidateSri.xstart = self._startTime @@ -1424,7 +1423,7 @@ def pushThread(self): candidateSri.keywords = keywords if self._sri==None or not compareSRI(candidateSri, self._sri): - self._sri = candidateSri + self._sri = _copy.copy(candidateSri) self._pushSRIAllConnectedPorts(sri = self._sri) # if we are give a timestamp then use it as is @@ -1866,6 +1865,6 @@ def createSRI(streamID='defaultStreamID', sampleRate=1.0, mode=0, blocking=True if sampleRate and sampleRate > 0.0: xd = 1.0/float(sampleRate) - return _BULKIO_.StreamSRI(hversion=1, xstart=0.0, xdelta=xd, + return _BULKIO.StreamSRI(hversion=1, xstart=0.0, xdelta=xd, xunits=1, subsize=0, ystart=0.0, ydelta=0.0, yunits=0, mode=mode, streamID=streamID, blocking=blocking, keywords=[]) diff --git a/redhawk/src/testing/tests/test_13_TestSB.py b/redhawk/src/testing/tests/test_13_TestSB.py index 91e4d318d..71f8ca249 100644 --- a/redhawk/src/testing/tests/test_13_TestSB.py +++ b/redhawk/src/testing/tests/test_13_TestSB.py @@ -2030,6 +2030,15 @@ def test_DataSourceSRI(self): """ Verify that provide SRI is handled """ + def wait_on_data( sink ): + begin_time = time.time() + estimate = sink.getDataEstimate() + while estimate.num_timestamps != 1: + time.sleep(0.1) + estimate = sink.getDataEstimate() + if time.time() - begin_time > _timeout: + break + _timeout = 1 _startTime = 10 source = sb.DataSource(startTime=_startTime) @@ -2047,13 +2056,7 @@ def test_DataSourceSRI(self): # push samples down stream, with custom sri _srcData = [1,2,3,4] source.push(_srcData, sri=_sri ) - begin_time = time.time() - estimate = sink.getDataEstimate() - while estimate.num_timestamps != 1: - time.sleep(0.1) - estimate = sink.getDataEstimate() - if time.time() - begin_time > _timeout: - break + wait_on_data(sink) data=sink.getData() rsri=sink.sri() self.assertEquals(rsri.streamID, sid ) @@ -2075,12 +2078,7 @@ def test_DataSourceSRI(self): _srcData = [1,2,3,4] source.push(_srcData, SRIKeywords=kws ) begin_time = time.time() - estimate = sink.getDataEstimate() - while estimate.num_timestamps != 1: - time.sleep(0.1) - estimate = sink.getDataEstimate() - if time.time() - begin_time > _timeout: - break + wait_on_data(sink) data=sink.getData() rsri=sink.sri() self.assertEquals(rsri.streamID, sid ) @@ -2089,13 +2087,7 @@ def test_DataSourceSRI(self): # Repeat, making sure that a second push with keywords does not fail source.push(_srcData, SRIKeywords=kws) - begin_time = time.time() - estimate = sink.getDataEstimate() - while estimate.num_timestamps != 1: - time.sleep(0.1) - estimate = sink.getDataEstimate() - if time.time() - begin_time > _timeout: - break + wait_on_data(sink) data=sink.getData() self.assertTrue(data) @@ -2109,19 +2101,56 @@ def test_DataSourceSRI(self): _sri.keywords=copy.copy(matchkws) _srcData = [1,2,3,4] source.push(_srcData, sri=_sri ) - begin_time = time.time() - estimate = sink.getDataEstimate() - while estimate.num_timestamps != 1: - time.sleep(0.1) - estimate = sink.getDataEstimate() - if time.time() - begin_time > _timeout: - break + wait_on_data(sink) data=sink.getData() rsri=sink.sri() self.assertEquals(rsri.streamID, sid ) self.assertAlmostEquals(rsri.xdelta, 0.1234) self.assertEqual(True, compareKeywordLists( rsri.keywords, matchkws) ) + # try pushing using the same sri object with changing attributes + _sri = sb.createSRI() + _sri.streamID=sid + _srcData = [1,2,3,4] + source.push(_srcData, sri=_sri ) + wait_on_data(sink) + data=sink.getData() + rsri=sink.sri() + self.assertEquals(rsri.streamID, sid ) + + _sri.streamID='anewsri' + _srcData = [1,2,3,4] + source.push(_srcData, sri=_sri ) + wait_on_data(sink) + data=sink.getData() + rsri=sink.sri() + self.assertEquals(rsri.streamID, 'anewsri' ) + + _sri.mode=1 + _srcData = [1,2,3,4] + source.push(_srcData, sri=_sri ) + wait_on_data(sink) + data=sink.getData() + rsri=sink.sri() + self.assertEquals(rsri.mode, 1 ) + + _sri.mode=0 + _srcData = [1,2,3,4] + source.push(_srcData, sri=_sri ) + wait_on_data(sink) + data=sink.getData() + rsri=sink.sri() + self.assertEquals(rsri.mode, 0 ) + + _sri.hversion=100 + _srcData = [1,2,3,4] + source.push(_srcData, sri=_sri ) + wait_on_data(sink) + data=sink.getData() + rsri=sink.sri() + self.assertEquals(rsri.hversion, 100 ) + + def test_DataSinkSubsize(self): src=sb.DataSource(dataFormat='short',subsize=5) snk=sb.DataSink() From fc4ffa4cb2d5d24d7358b07800ae45b645e8ad95 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 23 Feb 2017 14:05:42 -0500 Subject: [PATCH 0725/1644] CF-884 Use symbolic links instead of copying DomainManager and DeviceManager, and rely on the GPP build to copy its executable, to avoid occasional "Text file busy" error messages --- GPP/tests/.gitignore | 4 +- .../mgr/DeviceManager.Linux.armv7l.prf.xml | 47 ---------- .../dev/mgr/DeviceManager.Linux.x86.prf.xml | 47 ---------- .../mgr/DeviceManager.Linux.x86_64.prf.xml | 47 ---------- GPP/tests/sdr/dev/mgr/DeviceManager.prf.xml | 69 --------------- GPP/tests/sdr/dev/mgr/DeviceManager.scd.xml | 38 -------- GPP/tests/sdr/dev/mgr/DeviceManager.spd.xml | 57 ------------ GPP/tests/sdr/dom/mgr/DomainManager.prf.xml | 87 ------------------- GPP/tests/sdr/dom/mgr/DomainManager.scd.xml | 38 -------- GPP/tests/sdr/dom/mgr/DomainManager.spd.xml | 43 --------- GPP/tests/test_GPP.py | 15 ++-- 11 files changed, 9 insertions(+), 483 deletions(-) delete mode 100644 GPP/tests/sdr/dev/mgr/DeviceManager.Linux.armv7l.prf.xml delete mode 100644 GPP/tests/sdr/dev/mgr/DeviceManager.Linux.x86.prf.xml delete mode 100644 GPP/tests/sdr/dev/mgr/DeviceManager.Linux.x86_64.prf.xml delete mode 100644 GPP/tests/sdr/dev/mgr/DeviceManager.prf.xml delete mode 100644 GPP/tests/sdr/dev/mgr/DeviceManager.scd.xml delete mode 100644 GPP/tests/sdr/dev/mgr/DeviceManager.spd.xml delete mode 100644 GPP/tests/sdr/dom/mgr/DomainManager.prf.xml delete mode 100644 GPP/tests/sdr/dom/mgr/DomainManager.scd.xml delete mode 100644 GPP/tests/sdr/dom/mgr/DomainManager.spd.xml diff --git a/GPP/tests/.gitignore b/GPP/tests/.gitignore index f8310f91b..2bc764e80 100644 --- a/GPP/tests/.gitignore +++ b/GPP/tests/.gitignore @@ -1,6 +1,6 @@ sdr/dev/devices/GPP/ -sdr/dev/mgr/DeviceManager -sdr/dom/mgr/DomainManager +sdr/dev/mgr +sdr/dom/mgr sdr/dom/components/check_cwd_cpp/cpp/check_cwd_cpp sdr/dom/components/check_cwd_java/java/bin/ sdr/dom/components/check_cwd_java/java/check_cwd_java.jar diff --git a/GPP/tests/sdr/dev/mgr/DeviceManager.Linux.armv7l.prf.xml b/GPP/tests/sdr/dev/mgr/DeviceManager.Linux.armv7l.prf.xml deleted file mode 100644 index 22cb8b01b..000000000 --- a/GPP/tests/sdr/dev/mgr/DeviceManager.Linux.armv7l.prf.xml +++ /dev/null @@ -1,47 +0,0 @@ - - - - - - - - - SCA required property describing the Operating System - - Linux - - - - - - SCA required property describing the CPU type - - armv7l - - - - diff --git a/GPP/tests/sdr/dev/mgr/DeviceManager.Linux.x86.prf.xml b/GPP/tests/sdr/dev/mgr/DeviceManager.Linux.x86.prf.xml deleted file mode 100644 index 811169cbb..000000000 --- a/GPP/tests/sdr/dev/mgr/DeviceManager.Linux.x86.prf.xml +++ /dev/null @@ -1,47 +0,0 @@ - - - - - - - - - SCA required property describing the Operating System - - Linux - - - - - - SCA required property describing the CPU type - - x86 - - - - diff --git a/GPP/tests/sdr/dev/mgr/DeviceManager.Linux.x86_64.prf.xml b/GPP/tests/sdr/dev/mgr/DeviceManager.Linux.x86_64.prf.xml deleted file mode 100644 index 37070a752..000000000 --- a/GPP/tests/sdr/dev/mgr/DeviceManager.Linux.x86_64.prf.xml +++ /dev/null @@ -1,47 +0,0 @@ - - - - - - - - - SCA required property describing the Operating System - - Linux - - - - - - SCA required property describing the CPU type - - x86_64 - - - - diff --git a/GPP/tests/sdr/dev/mgr/DeviceManager.prf.xml b/GPP/tests/sdr/dev/mgr/DeviceManager.prf.xml deleted file mode 100644 index 8ff2ea4f7..000000000 --- a/GPP/tests/sdr/dev/mgr/DeviceManager.prf.xml +++ /dev/null @@ -1,69 +0,0 @@ - - - - - - These are the properties to configure the device manager - - - - A URI that points to a log4j configuration file used - for the device manager and all devices spawned by this device. - - - - - - Path to the Device Configuration Descriptor (DCD) XML file.. - - - - - - - The name of the domain in which this device manager will operate. - During startup, the device manager will attempt to connect to the - domain manager for the given domain. - - - - - - - The amount of time (in seconds) that the Device Manager will wait for a Device to exit before issuing a kill signal - - 0.5 - - - - - The location where files from remote SCA filesystems will be cached. - - - - - - - Name of the host where this device manager is running - - - - diff --git a/GPP/tests/sdr/dev/mgr/DeviceManager.scd.xml b/GPP/tests/sdr/dev/mgr/DeviceManager.scd.xml deleted file mode 100644 index 4fdd8ceb1..000000000 --- a/GPP/tests/sdr/dev/mgr/DeviceManager.scd.xml +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - 2.2 - - devicemanager - - - - - - - - - - - - diff --git a/GPP/tests/sdr/dev/mgr/DeviceManager.spd.xml b/GPP/tests/sdr/dev/mgr/DeviceManager.spd.xml deleted file mode 100644 index c5f1b76e0..000000000 --- a/GPP/tests/sdr/dev/mgr/DeviceManager.spd.xml +++ /dev/null @@ -1,57 +0,0 @@ - - - - - - - - - - - - - - - - x86 Implementation of a Device Manager - - - - - - DeviceManager - - - - - - x86_64 Implementation of a Device Manager - - - - - - DeviceManager - - - - - diff --git a/GPP/tests/sdr/dom/mgr/DomainManager.prf.xml b/GPP/tests/sdr/dom/mgr/DomainManager.prf.xml deleted file mode 100644 index 3c48097d9..000000000 --- a/GPP/tests/sdr/dom/mgr/DomainManager.prf.xml +++ /dev/null @@ -1,87 +0,0 @@ - - - - - - These are the properties to configure the domain manager - - - - A URI on the SCA FileManager that points to a log4j configuration file used - for the domain manager and the entire domain. - - - - - - - Path to the Domain Manager Descriptor (DMD) XML file.. - - - - - - - The name of the domain to which this domain manager will be bound. - - - - - - - Enable CORBA persistence for the domain manager. - - true - - - - - - The URL to a database for domain persistence information. - - - - - - - Replace any existing name binding for the domain manager. - - false - - - - - - The amount of time, in seconds, to wait for a component to bind to the name service after being launched. - - 60 - seconds - - - - - - Current version of REDHAWK that this Domain Manager is running - - - - - diff --git a/GPP/tests/sdr/dom/mgr/DomainManager.scd.xml b/GPP/tests/sdr/dom/mgr/DomainManager.scd.xml deleted file mode 100644 index 4c1c5b8ff..000000000 --- a/GPP/tests/sdr/dom/mgr/DomainManager.scd.xml +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - 2.2 - - domainmanager - - - - - - - - - - - - diff --git a/GPP/tests/sdr/dom/mgr/DomainManager.spd.xml b/GPP/tests/sdr/dom/mgr/DomainManager.spd.xml deleted file mode 100644 index 1e871939e..000000000 --- a/GPP/tests/sdr/dom/mgr/DomainManager.spd.xml +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - - REDHAWK test author - - - - - - - - - implementation of a Domain Manager - - - /mgr/DomainManager - - - - - - diff --git a/GPP/tests/test_GPP.py b/GPP/tests/test_GPP.py index fe49a2148..a53961d3e 100755 --- a/GPP/tests/test_GPP.py +++ b/GPP/tests/test_GPP.py @@ -1305,6 +1305,11 @@ def _waitRegisteredDevices(self, devMgr, numDevices, timeout=5.0, pause=0.1): time.sleep(pause) return False + def _makeLink(self, src, dest): + if os.path.exists(dest): + os.unlink(dest) + os.symlink(src, dest) + def setUp(self): super(DomainSupport,self).setUp() self.child_pids=[] @@ -1316,14 +1321,8 @@ def setUp(self): print "\n-----------------------" print "Running: ", self.id().split('.')[-1] print "-----------------------\n" - copyfile(self.orig_sdrroot+'/dom/mgr/DomainManager', 'sdr/dom/mgr/DomainManager') - os.chmod('sdr/dom/mgr/DomainManager',0777) - copyfile(self.orig_sdrroot+'/dev/mgr/DeviceManager', 'sdr/dev/mgr/DeviceManager') - os.chmod('sdr/dev/mgr/DeviceManager',0777) - if not os.path.exists('sdr/dev/devices/GPP/cpp'): - os.makedirs('sdr/dev/devices/GPP/cpp') - copyfile('../cpp/GPP', 'sdr/dev/devices/GPP/cpp/GPP') - os.chmod('sdr/dev/devices/GPP/cpp/GPP',0777) + self._makeLink(self.orig_sdrroot+'/dom/mgr', 'sdr/dom/mgr') + self._makeLink(self.orig_sdrroot+'/dev/mgr', 'sdr/dev/mgr') print 'done staging DomainManager' def tearDown(self): From 1a7cd1529d5e5f5b45b35078bd9e509d787425ce Mon Sep 17 00:00:00 2001 From: Max Robert Date: Sat, 25 Feb 2017 09:22:32 -0500 Subject: [PATCH 0726/1644] Refs CF-1709. Fixed intermittent errors in RX_Digitizer_Sim tests --- .../RX_Digitizer_Sim/python/Waveform.py | 85 +++++++++++++------ .../tests/test_RX_Digitizer_Sim.py | 5 +- 2 files changed, 62 insertions(+), 28 deletions(-) diff --git a/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/python/Waveform.py b/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/python/Waveform.py index 5928a3ae7..66ce75c7b 100644 --- a/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/python/Waveform.py +++ b/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/python/Waveform.py @@ -28,7 +28,7 @@ - ramp ''' import math -import numpy as np +import numpy as _np class Waveform: A = 67081293.0 @@ -81,9 +81,13 @@ def whitenoise(self, sdev, n, spa=1): sum1 = v1*v1 + v2*v2 if sum1 >= 1.0 or sum1 <1e-20: continue sum1 = fdev * float(math.sqrt(factor*math.log(sum1)/sum1)) - outbuff[i] = float(np.float32(v1*sum1)) + try: + a = _np.float32(5) + except: + import numpy as _np + outbuff[i] = float(_np.float32(v1*sum1)) if (i+1) < maxIndex: - outbuff[i+1] = float(np.float32(v2*sum1)) + outbuff[i+1] = float(_np.float32(v2*sum1)) i+=2 self.seed = int(sis*self.T26) @@ -102,6 +106,10 @@ def whitenoise(self, sdev, n, spa=1): # fast algorithm based on: sin(x+dp) = sin(x)*cos(dp) + cos(x)*sin(dp) # cos(x+dp) = cos(x)*cos(dp) - sin(x)*sin(dp) def sincos(self, amp, p, dp, n, spa): + try: + a = _np.float32(5) + except: + import numpy as _np outbuff = range(n*spa) cxr = amp*math.cos(p*self.TWOPI) cxi = amp*math.sin(p*self.TWOPI) @@ -109,27 +117,27 @@ def sincos(self, amp, p, dp, n, spa): dxi = math.sin(dp*self.TWOPI) if spa==2: for i in range(0, n*2, 2): - outbuff[i] = float(np.float32(cxr)) - outbuff[i+1] = float(np.float32(cxi)) + outbuff[i] = float(_np.float32(cxr)) + outbuff[i+1] = float(_np.float32(cxi)) axr = (cxr*dxr) - (cxi*dxi) axi = (cxr*dxi) + (cxi*dxr) cxr=axr cxi=axi elif spa==1: for i in range(n): - outbuff[i] = float(np.float32(cxi)) + outbuff[i] = float(_np.float32(cxi)) axr = (cxr*dxr) - (cxi*dxi) axi = (cxr*dxi) + (cxi*dxr) cxr=axr cxi=axi elif spa==-1: for i in range(n): - outbuff[i] = float(np.float32(amp*math.sin(p*self.TWOPI))) + outbuff[i] = float(_np.float32(amp*math.sin(p*self.TWOPI))) p += dp elif spa==-2: for i in range(0, n*2, 2): - outbuff[i] = float(np.float32(amp*math.cos(p*self.TWOPI))) - outbuff[i+1] = float(np.float32(amp*math.sin(p*self.TWOPI))) + outbuff[i] = float(_np.float32(amp*math.cos(p*self.TWOPI))) + outbuff[i+1] = float(_np.float32(amp*math.sin(p*self.TWOPI))) p += dp return outbuff @@ -147,16 +155,19 @@ def square(self, amp, p, dp, n, spa): value = 0.0 famp = float(amp) famp2 = -famp - + try: + a = _np.float32(5) + except: + import numpy as _np for i in range(0, n*spa, spa): value = famp2 if p >= 1.0: p -= 1.0 elif p >= 0.5: value = famp - outbuff[i] = float(np.float32(value)) + outbuff[i] = float(_np.float32(value)) if spa == 2: - outbuff[i+1] = float(np.float32(value)) + outbuff[i+1] = float(_np.float32(value)) p += dp return outbuff @@ -175,7 +186,10 @@ def triangle(self, amp, p, dp, n, spa): famp = float(amp) famp2 = 4*famp fp = float(p) - 0.5 - + try: + a = _np.float32(5) + except: + import numpy as _np for i in range(0, n*spa, spa): if fp >= 0.5: fp -= 1.0 @@ -183,9 +197,9 @@ def triangle(self, amp, p, dp, n, spa): value = float(famp - fp*famp2) else: value = float(famp + fp*famp2) - outbuff[i] = float(np.float32(value)) + outbuff[i] = float(_np.float32(value)) if spa == 2: - outbuff[i+1] = float(np.float32(value)) + outbuff[i+1] = float(_np.float32(value)) fp += dp return outbuff @@ -204,14 +218,17 @@ def sawtooth(self, amp, p, dp, n, spa): famp = float(amp) famp2 = 2*famp fp = float(p) - 0.5 - + try: + a = _np.float32(5) + except: + import numpy as _np for i in range(0, n*spa, spa): if fp >= 0.5: fp -= 1.0 value = float(fp*famp2) - outbuff[i] = float(np.float32(value)) + outbuff[i] = float(_np.float32(value)) if spa == 2: - outbuff[i+1] = float(np.float32(value)) + outbuff[i+1] = float(_np.float32(value)) fp += dp return outbuff @@ -228,16 +245,19 @@ def pulse(self, amp, p, dp, n, spa): outbuff = range(n*spa) value = 0.0 famp = float(amp) - + try: + a = _np.float32(5) + except: + import numpy as _np for i in range(0, n*spa, spa): if p >= 1.0: value = famp p -= 1.0 else: value = 0 - outbuff[i] = float(np.float32(value)) + outbuff[i] = float(_np.float32(value)) if spa == 2: - outbuff[i+1] = float(np.float32(value)) + outbuff[i+1] = float(_np.float32(value)) p += dp return outbuff @@ -250,9 +270,12 @@ def pulse(self, amp, p, dp, n, spa): # @return the new data buffer def constant(self, amp, n, spa): outbuff = range(n*spa) - + try: + a = _np.float32(5) + except: + import numpy as _np for i in range(n*spa): - outbuff[i] = float(np.float32(amp)) + outbuff[i] = float(_np.float32(amp)) return outbuff @@ -266,12 +289,16 @@ def constant(self, amp, n, spa): def lrs(self, amp, n, spa, lrs): outbuff = range(n*spa) factor = (amp/2.0/self.B1G) + try: + a = _np.float32(5) + except: + import numpy as _np for i in range(0, n*spa, spa): data = (factor * lrs) - outbuff[i] = float(np.float32(data)) + outbuff[i] = float(_np.float32(data)) if spa == 2: - outbuff[i+1] = float(np.float32(data)) + outbuff[i+1] = float(_np.float32(data)) bit0 = (~(lrs ^ (lrs>>1) ^ (lrs>>5) ^ (lrs>>25)))&0x1 lrs <<= 1 @@ -293,10 +320,14 @@ def lrs(self, amp, n, spa, lrs): # @return the new data buffer and the RAMP value at end of array def ramp(self, amp, n, spa, data): outbuff = range(n*spa) + try: + a = _np.float32(5) + except: + import numpy as _np for i in range(0, n*spa, spa): - outbuff[i] = float(np.float32(data)) + outbuff[i] = float(_np.float32(data)) if spa == 2: - outbuff[i+1] = float(np.float32(data)) + outbuff[i+1] = float(_np.float32(data)) data = data + 1 if data >= amp: data = int(-amp) diff --git a/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/tests/test_RX_Digitizer_Sim.py b/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/tests/test_RX_Digitizer_Sim.py index 5a5fcded6..688c3503f 100644 --- a/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/tests/test_RX_Digitizer_Sim.py +++ b/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/tests/test_RX_Digitizer_Sim.py @@ -160,7 +160,10 @@ def testDoubleTunerAllocation(self): self.assertTrue(len(data)>0) #Check Tuner 2 Data - data2= sink2.getData() + data2= sink2.getData() + if len(data2) == 0: + time.sleep(1) + data2 = sink2.getData() self.assertTrue(len(data2)>0) #Deallocate Tuners From 0707bd28b9053c53e0f6d0f13c29f5559c853f43 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 28 Feb 2017 15:13:21 -0500 Subject: [PATCH 0727/1644] CF-1710 ComponentHost issues a warn when a module cannot be unloaded (usually due to boost::function symbols) --- .../src/control/sdr/ComponentHost/ModuleLoader.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/redhawk/src/control/sdr/ComponentHost/ModuleLoader.cpp b/redhawk/src/control/sdr/ComponentHost/ModuleLoader.cpp index 76b579b81..17967a4e9 100644 --- a/redhawk/src/control/sdr/ComponentHost/ModuleLoader.cpp +++ b/redhawk/src/control/sdr/ComponentHost/ModuleLoader.cpp @@ -62,11 +62,13 @@ const std::string& Module::path() const void Module::load() { + LOG_TRACE(ModuleLoader, "Incrementing reference count for " << _path); ++_refcount; } void Module::unload() { + LOG_TRACE(ModuleLoader, "Decrementing reference count for " << _path); _refcount--; if (_refcount == 0) { ModuleLoader::Instance().unloaded(this); @@ -76,7 +78,13 @@ void Module::unload() void Module::close() { - dlclose(_handle); + if (dlclose(_handle)) { + LOG_ERROR(ModuleLoader, "Error closing dynamic library " << _path << ": " << dlerror()); + } + _handle = dlopen(_path.c_str(), RTLD_LAZY | RTLD_NOLOAD); + if (_handle) { + LOG_WARN(ModuleLoader, "Dynamic library " << _path << " could not be unloaded, some symbols may still be in use"); + } _handle = 0; } @@ -182,8 +190,6 @@ void ModuleBundle::loadDirectory(const std::string& path, ModuleLoader::LoadBind void ModuleBundle::unload() { // Unload modules in reverse order of loading - for (ModuleList::reverse_iterator module = _modules.rbegin(); module != _modules.rend(); ++module) { - (*module)->unload(); - } + std::for_each(_modules.rbegin(), _modules.rend(), std::mem_fun(&Module::unload)); _modules.clear(); } From 11ac60cd54cd1973cae4550530c9d23978ed501b Mon Sep 17 00:00:00 2001 From: Max Robert Date: Wed, 1 Mar 2017 12:47:56 -0500 Subject: [PATCH 0728/1644] Refs CF-1690. Fail to configure if Java was never installed but is required --- redhawk/src/acinclude/java.m4 | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/redhawk/src/acinclude/java.m4 b/redhawk/src/acinclude/java.m4 index ed8fc9953..0df1eaa8f 100644 --- a/redhawk/src/acinclude/java.m4 +++ b/redhawk/src/acinclude/java.m4 @@ -87,6 +87,10 @@ EOF fi rm -f Test.java Test.class fi + if test "$JAVAC" == "no"; then + echo "Java set for required, but no Java is installed" + AS_EXIT(1) + fi ]) dnl RH_PROG_JAR From baac32d93dfb954f3cf172d115a05c632817a285 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Wed, 1 Mar 2017 13:25:10 -0500 Subject: [PATCH 0729/1644] Refs CF-1711. Failed allocatedCapacity do not throw exception from the subsequent deallocateCapacity call --- .../tests/test_fei_exception_through.py | 6 ++++++ .../libsrc/cpp/fe_tuner_device.cpp | 18 ++++++++++++++---- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/codegenTesting/sdr/dev/devices/fei_exception_through/tests/test_fei_exception_through.py b/codegenTesting/sdr/dev/devices/fei_exception_through/tests/test_fei_exception_through.py index 38499c7fc..652ca50a3 100644 --- a/codegenTesting/sdr/dev/devices/fei_exception_through/tests/test_fei_exception_through.py +++ b/codegenTesting/sdr/dev/devices/fei_exception_through/tests/test_fei_exception_through.py @@ -27,6 +27,7 @@ from omniORB import CORBA import ossie.utils.sandbox import logging +import frontend class varLog(logging.Handler): @@ -75,6 +76,11 @@ def tearDown(self): ossie.utils.sandbox.local.log.removeHandler(self.var) sb.release() + def testAllocation(self): + frontend_alloc = frontend.createTunerAllocation(returnDict=False) + retval = self.comp.allocateCapacity([frontend_alloc]) + self.assertEquals(retval, False) + def testBasicBehavior(self): self.assertEquals(self.got_logmsg, False) ####################################################################### diff --git a/frontendInterfaces/libsrc/cpp/fe_tuner_device.cpp b/frontendInterfaces/libsrc/cpp/fe_tuner_device.cpp index 4a6001b48..a93b3be4e 100644 --- a/frontendInterfaces/libsrc/cpp/fe_tuner_device.cpp +++ b/frontendInterfaces/libsrc/cpp/fe_tuner_device.cpp @@ -563,7 +563,9 @@ namespace frontend { } } catch(const std::logic_error &e) { - deallocateCapacity(capacities); + try { + deallocateCapacity(capacities); + } catch ( ... ) {} return false; } catch(AllocationAlreadyExists &e) { @@ -572,15 +574,21 @@ namespace frontend { throw static_cast(e); } catch(CF::Device::InvalidCapacity &e) { - deallocateCapacity(capacities); + try { + deallocateCapacity(capacities); + } catch ( ... ) {} throw e; } catch(FRONTEND::BadParameterException &e) { - deallocateCapacity(capacities); + try { + deallocateCapacity(capacities); + } catch ( ... ) {} return false; } catch(...){ - deallocateCapacity(capacities); + try { + deallocateCapacity(capacities); + } catch ( ... ) {} throw; }; @@ -653,9 +661,11 @@ namespace frontend { } } catch(CF::Device::InvalidCapacity &e){ + _usageState = updateUsageState(); throw; } catch(...){ + _usageState = updateUsageState(); LOG_DEBUG(FrontendTunerDevice,"ERROR WHEN DEALLOCATING. SKIPPING..."); } } From 8052de2583230f3ff47bc72047d9104b252297d3 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 28 Feb 2017 15:13:21 -0500 Subject: [PATCH 0730/1644] CF-1710 ComponentHost issues a warn when a module cannot be unloaded (usually due to boost::function symbols) --- .../src/control/sdr/ComponentHost/ModuleLoader.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/redhawk/src/control/sdr/ComponentHost/ModuleLoader.cpp b/redhawk/src/control/sdr/ComponentHost/ModuleLoader.cpp index 76b579b81..17967a4e9 100644 --- a/redhawk/src/control/sdr/ComponentHost/ModuleLoader.cpp +++ b/redhawk/src/control/sdr/ComponentHost/ModuleLoader.cpp @@ -62,11 +62,13 @@ const std::string& Module::path() const void Module::load() { + LOG_TRACE(ModuleLoader, "Incrementing reference count for " << _path); ++_refcount; } void Module::unload() { + LOG_TRACE(ModuleLoader, "Decrementing reference count for " << _path); _refcount--; if (_refcount == 0) { ModuleLoader::Instance().unloaded(this); @@ -76,7 +78,13 @@ void Module::unload() void Module::close() { - dlclose(_handle); + if (dlclose(_handle)) { + LOG_ERROR(ModuleLoader, "Error closing dynamic library " << _path << ": " << dlerror()); + } + _handle = dlopen(_path.c_str(), RTLD_LAZY | RTLD_NOLOAD); + if (_handle) { + LOG_WARN(ModuleLoader, "Dynamic library " << _path << " could not be unloaded, some symbols may still be in use"); + } _handle = 0; } @@ -182,8 +190,6 @@ void ModuleBundle::loadDirectory(const std::string& path, ModuleLoader::LoadBind void ModuleBundle::unload() { // Unload modules in reverse order of loading - for (ModuleList::reverse_iterator module = _modules.rbegin(); module != _modules.rend(); ++module) { - (*module)->unload(); - } + std::for_each(_modules.rbegin(), _modules.rend(), std::mem_fun(&Module::unload)); _modules.clear(); } From d69aeb9822df861121bc14fcc230006dd20a1458 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Wed, 1 Mar 2017 12:47:56 -0500 Subject: [PATCH 0731/1644] Refs CF-1690. Fail to configure if Java was never installed but is required --- redhawk/src/acinclude/java.m4 | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/redhawk/src/acinclude/java.m4 b/redhawk/src/acinclude/java.m4 index ed8fc9953..0df1eaa8f 100644 --- a/redhawk/src/acinclude/java.m4 +++ b/redhawk/src/acinclude/java.m4 @@ -87,6 +87,10 @@ EOF fi rm -f Test.java Test.class fi + if test "$JAVAC" == "no"; then + echo "Java set for required, but no Java is installed" + AS_EXIT(1) + fi ]) dnl RH_PROG_JAR From e20e3afc931ef4b4db58a7d0c5887eecffa8d62e Mon Sep 17 00:00:00 2001 From: Max Robert Date: Wed, 1 Mar 2017 13:25:10 -0500 Subject: [PATCH 0732/1644] Refs CF-1711. Failed allocatedCapacity do not throw exception from the subsequent deallocateCapacity call --- .../tests/test_fei_exception_through.py | 6 ++++++ .../libsrc/cpp/fe_tuner_device.cpp | 18 ++++++++++++++---- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/codegenTesting/sdr/dev/devices/fei_exception_through/tests/test_fei_exception_through.py b/codegenTesting/sdr/dev/devices/fei_exception_through/tests/test_fei_exception_through.py index 38499c7fc..652ca50a3 100644 --- a/codegenTesting/sdr/dev/devices/fei_exception_through/tests/test_fei_exception_through.py +++ b/codegenTesting/sdr/dev/devices/fei_exception_through/tests/test_fei_exception_through.py @@ -27,6 +27,7 @@ from omniORB import CORBA import ossie.utils.sandbox import logging +import frontend class varLog(logging.Handler): @@ -75,6 +76,11 @@ def tearDown(self): ossie.utils.sandbox.local.log.removeHandler(self.var) sb.release() + def testAllocation(self): + frontend_alloc = frontend.createTunerAllocation(returnDict=False) + retval = self.comp.allocateCapacity([frontend_alloc]) + self.assertEquals(retval, False) + def testBasicBehavior(self): self.assertEquals(self.got_logmsg, False) ####################################################################### diff --git a/frontendInterfaces/libsrc/cpp/fe_tuner_device.cpp b/frontendInterfaces/libsrc/cpp/fe_tuner_device.cpp index 4a6001b48..a93b3be4e 100644 --- a/frontendInterfaces/libsrc/cpp/fe_tuner_device.cpp +++ b/frontendInterfaces/libsrc/cpp/fe_tuner_device.cpp @@ -563,7 +563,9 @@ namespace frontend { } } catch(const std::logic_error &e) { - deallocateCapacity(capacities); + try { + deallocateCapacity(capacities); + } catch ( ... ) {} return false; } catch(AllocationAlreadyExists &e) { @@ -572,15 +574,21 @@ namespace frontend { throw static_cast(e); } catch(CF::Device::InvalidCapacity &e) { - deallocateCapacity(capacities); + try { + deallocateCapacity(capacities); + } catch ( ... ) {} throw e; } catch(FRONTEND::BadParameterException &e) { - deallocateCapacity(capacities); + try { + deallocateCapacity(capacities); + } catch ( ... ) {} return false; } catch(...){ - deallocateCapacity(capacities); + try { + deallocateCapacity(capacities); + } catch ( ... ) {} throw; }; @@ -653,9 +661,11 @@ namespace frontend { } } catch(CF::Device::InvalidCapacity &e){ + _usageState = updateUsageState(); throw; } catch(...){ + _usageState = updateUsageState(); LOG_DEBUG(FrontendTunerDevice,"ERROR WHEN DEALLOCATING. SKIPPING..."); } } From fcb098573f2b739fa91b57ea4ba704bc37a10e03 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Thu, 2 Mar 2017 15:35:13 -0500 Subject: [PATCH 0733/1644] Refs CF-1705. Added unit test for updateUsageStage call in deallocateCapacity --- .../sdr/dev/devices/fei_cap/.fei_cap.wavedev | 6 + .../sdr/dev/devices/fei_cap/.md5sums | 2 + .../sdr/dev/devices/fei_cap/cpp/.md5sums | 12 + .../sdr/dev/devices/fei_cap/cpp/fei_cap.cpp | 489 ++++++++++++++++++ .../sdr/dev/devices/fei_cap/fei_cap.prf.xml | 118 +++++ .../sdr/dev/devices/fei_cap/fei_cap.scd.xml | 73 +++ .../sdr/dev/devices/fei_cap/fei_cap.spd.xml | 27 + .../sdr/dev/devices/fei_cap/tests/.md5sums | 1 + .../dev/devices/fei_cap/tests/test_fei_cap.py | 68 +++ 9 files changed, 796 insertions(+) create mode 100644 codegenTesting/sdr/dev/devices/fei_cap/.fei_cap.wavedev create mode 100644 codegenTesting/sdr/dev/devices/fei_cap/.md5sums create mode 100644 codegenTesting/sdr/dev/devices/fei_cap/cpp/.md5sums create mode 100644 codegenTesting/sdr/dev/devices/fei_cap/cpp/fei_cap.cpp create mode 100644 codegenTesting/sdr/dev/devices/fei_cap/fei_cap.prf.xml create mode 100644 codegenTesting/sdr/dev/devices/fei_cap/fei_cap.scd.xml create mode 100644 codegenTesting/sdr/dev/devices/fei_cap/fei_cap.spd.xml create mode 100644 codegenTesting/sdr/dev/devices/fei_cap/tests/.md5sums create mode 100644 codegenTesting/sdr/dev/devices/fei_cap/tests/test_fei_cap.py diff --git a/codegenTesting/sdr/dev/devices/fei_cap/.fei_cap.wavedev b/codegenTesting/sdr/dev/devices/fei_cap/.fei_cap.wavedev new file mode 100644 index 000000000..a4ab6869a --- /dev/null +++ b/codegenTesting/sdr/dev/devices/fei_cap/.fei_cap.wavedev @@ -0,0 +1,6 @@ + + + + + + diff --git a/codegenTesting/sdr/dev/devices/fei_cap/.md5sums b/codegenTesting/sdr/dev/devices/fei_cap/.md5sums new file mode 100644 index 000000000..01429cefa --- /dev/null +++ b/codegenTesting/sdr/dev/devices/fei_cap/.md5sums @@ -0,0 +1,2 @@ +dbfc3cebd831532baed806dce5204a76 fei_cap.spec +f80c57cbc896864bf8b5ad4b4ac9f4e3 build.sh diff --git a/codegenTesting/sdr/dev/devices/fei_cap/cpp/.md5sums b/codegenTesting/sdr/dev/devices/fei_cap/cpp/.md5sums new file mode 100644 index 000000000..6d7556c6a --- /dev/null +++ b/codegenTesting/sdr/dev/devices/fei_cap/cpp/.md5sums @@ -0,0 +1,12 @@ +499598b9e45d3fe9f6569b417711b344 fei_cap_base.cpp +ea99c415bd1006108aec0ce919f57569 main.cpp +5924d37c326a1fb0f29fe4c1c0170f90 fei_cap.cpp +8bfcd22353c3a57fee561ad86ee2a56b reconf +409f8ff93b2fae9a4c2b1adeda8f4efb fei_cap_base.h +937186ec5399597bdcae32d4f37c3a96 fei_cap.h +3794d396cf0a13810b91e7ae16e1bdf1 template_impl.cpp +815788af04eb7334f3ed6537a89c3ff6 configure.ac +c8462474e92c7be4c196d1ed70885f2b Makefile.am +d499fb62071813c9aee70ef9f76a6c87 struct_props.h +e092da2a91e617d80670af47361f2c91 Makefile.am.ide +2b2faa5cfc83438427491f4be5d6ee59 build.sh diff --git a/codegenTesting/sdr/dev/devices/fei_cap/cpp/fei_cap.cpp b/codegenTesting/sdr/dev/devices/fei_cap/cpp/fei_cap.cpp new file mode 100644 index 000000000..45f829c5d --- /dev/null +++ b/codegenTesting/sdr/dev/devices/fei_cap/cpp/fei_cap.cpp @@ -0,0 +1,489 @@ +/************************************************************************** + + This is the device code. This file contains the child class where + custom functionality can be added to the device. Custom + functionality to the base class can be extended here. Access to + the ports can also be done from this class + +**************************************************************************/ + +#include "fei_cap.h" + +PREPARE_LOGGING(fei_cap_i) + +fei_cap_i::fei_cap_i(char *devMgr_ior, char *id, char *lbl, char *sftwrPrfl) : + fei_cap_base(devMgr_ior, id, lbl, sftwrPrfl) +{ +} + +fei_cap_i::fei_cap_i(char *devMgr_ior, char *id, char *lbl, char *sftwrPrfl, char *compDev) : + fei_cap_base(devMgr_ior, id, lbl, sftwrPrfl, compDev) +{ +} + +fei_cap_i::fei_cap_i(char *devMgr_ior, char *id, char *lbl, char *sftwrPrfl, CF::Properties capacities) : + fei_cap_base(devMgr_ior, id, lbl, sftwrPrfl, capacities) +{ +} + +fei_cap_i::fei_cap_i(char *devMgr_ior, char *id, char *lbl, char *sftwrPrfl, CF::Properties capacities, char *compDev) : + fei_cap_base(devMgr_ior, id, lbl, sftwrPrfl, capacities, compDev) +{ +} + +fei_cap_i::~fei_cap_i() +{ +} + +void fei_cap_i::constructor() +{ + /*********************************************************************************** + This is the RH constructor. All properties are properly initialized before this function is called + + For a tuner device, the structure frontend_tuner_status needs to match the number + of tuners that this device controls and what kind of device it is. + The options for devices are: TX, RX, RX_DIGITIZER, CHANNELIZER, DDC, RC_DIGITIZER_CHANNELIZER + + For example, if this device has 5 physical + tuners, each an RX_DIGITIZER, then the code in the construct function should look like this: + + this->setNumChannels(5, "RX_DIGITIZER"); + + The incoming request for tuning contains a string describing the requested tuner + type. The string for the request must match the string in the tuner status. + ***********************************************************************************/ + this->setNumChannels(2, "RX_DIGITIZER"); +} + +/*********************************************************************************************** + + Basic functionality: + + The service function is called by the serviceThread object (of type ProcessThread). + This call happens immediately after the previous call if the return value for + the previous call was NORMAL. + If the return value for the previous call was NOOP, then the serviceThread waits + an amount of time defined in the serviceThread's constructor. + + SRI: + To create a StreamSRI object, use the following code: + std::string stream_id = "testStream"; + BULKIO::StreamSRI sri = bulkio::sri::create(stream_id); + + To create a StreamSRI object based on tuner status structure index 'idx' and collector center frequency of 100: + std::string stream_id = "my_stream_id"; + BULKIO::StreamSRI sri = this->create(stream_id, this->frontend_tuner_status[idx], 100); + + Time: + To create a PrecisionUTCTime object, use the following code: + BULKIO::PrecisionUTCTime tstamp = bulkio::time::utils::now(); + + + Ports: + + Data is passed to the serviceFunction through by reading from input streams + (BulkIO only). The input stream class is a port-specific class, so each port + implementing the BulkIO interface will have its own type-specific input stream. + UDP multicast (dataSDDS and dataVITA49) and string-based (dataString, dataXML and + dataFile) do not support streams. + + The input stream from which to read can be requested with the getCurrentStream() + method. The optional argument to getCurrentStream() is a floating point number that + specifies the time to wait in seconds. A zero value is non-blocking. A negative value + is blocking. Constants have been defined for these values, bulkio::Const::BLOCKING and + bulkio::Const::NON_BLOCKING. + + More advanced uses of input streams are possible; refer to the REDHAWK documentation + for more details. + + Input streams return data blocks that automatically manage the memory for the data + and include the SRI that was in effect at the time the data was received. It is not + necessary to delete the block; it will be cleaned up when it goes out of scope. + + To send data using a BulkIO interface, create an output stream and write the + data to it. When done with the output stream, the close() method sends and end-of- + stream flag and cleans up. + + NOTE: If you have a BULKIO dataSDDS or dataVITA49 port, you must manually call + "port->updateStats()" to update the port statistics when appropriate. + + Example: + // This example assumes that the device has two ports: + // An input (provides) port of type bulkio::InShortPort called dataShort_in + // An output (uses) port of type bulkio::OutFloatPort called dataFloat_out + // The mapping between the port and the class is found + // in the device base class header file + // The device class must have an output stream member; add to + // fei_cap.h: + // bulkio::OutFloatStream outputStream; + + bulkio::InShortStream inputStream = dataShort_in->getCurrentStream(); + if (!inputStream) { // No streams are available + return NOOP; + } + + bulkio::ShortDataBlock block = inputStream.read(); + if (!block) { // No data available + // Propagate end-of-stream + if (inputStream.eos()) { + outputStream.close(); + } + return NOOP; + } + + short* inputData = block.data(); + std::vector outputData; + outputData.resize(block.size()); + for (size_t index = 0; index < block.size(); ++index) { + outputData[index] = (float) inputData[index]; + } + + // If there is no output stream open, create one + if (!outputStream) { + outputStream = dataFloat_out->createStream(block.sri()); + } else if (block.sriChanged()) { + // Update output SRI + outputStream.sri(block.sri()); + } + + // Write to the output stream + outputStream.write(outputData, block.getTimestamps()); + + // Propagate end-of-stream + if (inputStream.eos()) { + outputStream.close(); + } + + return NORMAL; + + If working with complex data (i.e., the "mode" on the SRI is set to + true), the data block's complex() method will return true. Data blocks + provide functions that return the correct interpretation of the data + buffer and number of complex elements: + + if (block.complex()) { + std::complex* data = block.cxdata(); + for (size_t index = 0; index < block.cxsize(); ++index) { + data[index] = std::abs(data[index]); + } + outputStream.write(data, block.cxsize(), bulkio::time::utils::now()); + } + + Interactions with non-BULKIO ports are left up to the device developer's discretion + + Messages: + + To receive a message, you need (1) an input port of type MessageEvent, (2) a message prototype described + as a structure property of kind message, (3) a callback to service the message, and (4) to register the callback + with the input port. + + Assuming a property of type message is declared called "my_msg", an input port called "msg_input" is declared of + type MessageEvent, create the following code: + + void fei_cap_i::my_message_callback(const std::string& id, const my_msg_struct &msg){ + } + + Register the message callback onto the input port with the following form: + this->msg_input->registerMessage("my_msg", this, &fei_cap_i::my_message_callback); + + To send a message, you need to (1) create a message structure, (2) a message prototype described + as a structure property of kind message, and (3) send the message over the port. + + Assuming a property of type message is declared called "my_msg", an output port called "msg_output" is declared of + type MessageEvent, create the following code: + + ::my_msg_struct msg_out; + this->msg_output->sendMessage(msg_out); + + Accessing the Device Manager and Domain Manager: + + Both the Device Manager hosting this Device and the Domain Manager hosting + the Device Manager are available to the Device. + + To access the Domain Manager: + CF::DomainManager_ptr dommgr = this->getDomainManager()->getRef(); + To access the Device Manager: + CF::DeviceManager_ptr devmgr = this->getDeviceManager()->getRef(); + + Properties: + + Properties are accessed directly as member variables. For example, if the + property name is "baudRate", it may be accessed within member functions as + "baudRate". Unnamed properties are given the property id as its name. + Property types are mapped to the nearest C++ type, (e.g. "string" becomes + "std::string"). All generated properties are declared in the base class + (fei_cap_base). + + Simple sequence properties are mapped to "std::vector" of the simple type. + Struct properties, if used, are mapped to C++ structs defined in the + generated file "struct_props.h". Field names are taken from the name in + the properties file; if no name is given, a generated name of the form + "field_n" is used, where "n" is the ordinal number of the field. + + Example: + // This example makes use of the following Properties: + // - A float value called scaleValue + // - A boolean called scaleInput + + if (scaleInput) { + dataOut[i] = dataIn[i] * scaleValue; + } else { + dataOut[i] = dataIn[i]; + } + + Callback methods can be associated with a property so that the methods are + called each time the property value changes. This is done by calling + addPropertyListener(, this, &fei_cap_i::) + in the constructor. + + The callback method receives two arguments, the old and new values, and + should return nothing (void). The arguments can be passed by value, + receiving a copy (preferred for primitive types), or by const reference + (preferred for strings, structs and vectors). + + Example: + // This example makes use of the following Properties: + // - A float value called scaleValue + // - A struct property called status + + //Add to fei_cap.cpp + fei_cap_i::fei_cap_i(const char *uuid, const char *label) : + fei_cap_base(uuid, label) + { + addPropertyListener(scaleValue, this, &fei_cap_i::scaleChanged); + addPropertyListener(status, this, &fei_cap_i::statusChanged); + } + + void fei_cap_i::scaleChanged(float oldValue, float newValue) + { + LOG_DEBUG(fei_cap_i, "scaleValue changed from" << oldValue << " to " << newValue); + } + + void fei_cap_i::statusChanged(const status_struct& oldValue, const status_struct& newValue) + { + LOG_DEBUG(fei_cap_i, "status changed"); + } + + //Add to fei_cap.h + void scaleChanged(float oldValue, float newValue); + void statusChanged(const status_struct& oldValue, const status_struct& newValue); + + Allocation: + + Allocation callbacks are available to customize the Device's response to + allocation requests. For example, if the Device contains the allocation + property "my_alloc" of type string, the allocation and deallocation + callbacks follow the pattern (with arbitrary function names + my_alloc_fn and my_dealloc_fn): + + bool fei_cap_i::my_alloc_fn(const std::string &value) + { + // perform logic + return true; // successful allocation + } + void fei_cap_i::my_dealloc_fn(const std::string &value) + { + // perform logic + } + + The allocation and deallocation functions are then registered with the Device + base class with the setAllocationImpl call. Note that the variable for the property is used rather + than its id: + + this->setAllocationImpl(my_alloc, this, &fei_cap_i::my_alloc_fn, &fei_cap_i::my_dealloc_fn); + + + +************************************************************************************************/ +int fei_cap_i::serviceFunction() +{ + LOG_DEBUG(fei_cap_i, "serviceFunction() example log message"); + + return NOOP; +} + +/************************************************************* +Functions supporting tuning allocation +*************************************************************/ +void fei_cap_i::deviceEnable(frontend_tuner_status_struct_struct &fts, size_t tuner_id){ + /************************************************************ + modify fts, which corresponds to this->frontend_tuner_status[tuner_id] + Make sure to set the 'enabled' member of fts to indicate that tuner as enabled + ************************************************************/ + fts.enabled = true; + return; +} +void fei_cap_i::deviceDisable(frontend_tuner_status_struct_struct &fts, size_t tuner_id){ + /************************************************************ + modify fts, which corresponds to this->frontend_tuner_status[tuner_id] + Make sure to reset the 'enabled' member of fts to indicate that tuner as disabled + ************************************************************/ + fts.enabled = false; + return; +} +bool fei_cap_i::deviceSetTuning(const frontend::frontend_tuner_allocation_struct &request, frontend_tuner_status_struct_struct &fts, size_t tuner_id){ + /************************************************************ + modify fts, which corresponds to this->frontend_tuner_status[tuner_id] + At a minimum, bandwidth, center frequency, and sample_rate have to be set + If the device is tuned to exactly what the request was, the code should be: + fts.bandwidth = request.bandwidth; + fts.center_frequency = request.center_frequency; + fts.sample_rate = request.sample_rate; + + return true if the tuning succeeded, and false if it failed + ************************************************************/ + return true; +} +bool fei_cap_i::deviceDeleteTuning(frontend_tuner_status_struct_struct &fts, size_t tuner_id) { + /************************************************************ + modify fts, which corresponds to this->frontend_tuner_status[tuner_id] + return true if the tune deletion succeeded, and false if it failed + ************************************************************/ + return true; +} + +/************************************************************* +Functions servicing the tuner control port +*************************************************************/ +std::string fei_cap_i::getTunerType(const std::string& allocation_id) { + long idx = getTunerMapping(allocation_id); + if (idx < 0) throw FRONTEND::FrontendException("Invalid allocation id"); + return frontend_tuner_status[idx].tuner_type; +} + +bool fei_cap_i::getTunerDeviceControl(const std::string& allocation_id) { + long idx = getTunerMapping(allocation_id); + if (idx < 0) throw FRONTEND::FrontendException("Invalid allocation id"); + if (getControlAllocationId(idx) == allocation_id) + return true; + return false; +} + +std::string fei_cap_i::getTunerGroupId(const std::string& allocation_id) { + long idx = getTunerMapping(allocation_id); + if (idx < 0) throw FRONTEND::FrontendException("Invalid allocation id"); + return frontend_tuner_status[idx].group_id; +} + +std::string fei_cap_i::getTunerRfFlowId(const std::string& allocation_id) { + long idx = getTunerMapping(allocation_id); + if (idx < 0) throw FRONTEND::FrontendException("Invalid allocation id"); + return frontend_tuner_status[idx].rf_flow_id; +} + +void fei_cap_i::setTunerCenterFrequency(const std::string& allocation_id, double freq) { + long idx = getTunerMapping(allocation_id); + if (idx < 0) throw FRONTEND::FrontendException("Invalid allocation id"); + if(allocation_id != getControlAllocationId(idx)) + throw FRONTEND::FrontendException(("ID "+allocation_id+" does not have authorization to modify the tuner").c_str()); + if (freq<0) throw FRONTEND::BadParameterException(); + // set hardware to new value. Raise an exception if it's not possible + this->frontend_tuner_status[idx].center_frequency = freq; +} + +double fei_cap_i::getTunerCenterFrequency(const std::string& allocation_id) { + long idx = getTunerMapping(allocation_id); + if (idx < 0) throw FRONTEND::FrontendException("Invalid allocation id"); + return frontend_tuner_status[idx].center_frequency; +} + +void fei_cap_i::setTunerBandwidth(const std::string& allocation_id, double bw) { + long idx = getTunerMapping(allocation_id); + if (idx < 0) throw FRONTEND::FrontendException("Invalid allocation id"); + if(allocation_id != getControlAllocationId(idx)) + throw FRONTEND::FrontendException(("ID "+allocation_id+" does not have authorization to modify the tuner").c_str()); + if (bw<0) throw FRONTEND::BadParameterException(); + // set hardware to new value. Raise an exception if it's not possible + this->frontend_tuner_status[idx].bandwidth = bw; +} + +double fei_cap_i::getTunerBandwidth(const std::string& allocation_id) { + long idx = getTunerMapping(allocation_id); + if (idx < 0) throw FRONTEND::FrontendException("Invalid allocation id"); + return frontend_tuner_status[idx].bandwidth; +} + +void fei_cap_i::setTunerAgcEnable(const std::string& allocation_id, bool enable) +{ + throw FRONTEND::NotSupportedException("setTunerAgcEnable not supported"); +} + +bool fei_cap_i::getTunerAgcEnable(const std::string& allocation_id) +{ + throw FRONTEND::NotSupportedException("getTunerAgcEnable not supported"); +} + +void fei_cap_i::setTunerGain(const std::string& allocation_id, float gain) +{ + throw FRONTEND::NotSupportedException("setTunerGain not supported"); +} + +float fei_cap_i::getTunerGain(const std::string& allocation_id) +{ + throw FRONTEND::NotSupportedException("getTunerGain not supported"); +} + +void fei_cap_i::setTunerReferenceSource(const std::string& allocation_id, long source) +{ + throw FRONTEND::NotSupportedException("setTunerReferenceSource not supported"); +} + +long fei_cap_i::getTunerReferenceSource(const std::string& allocation_id) +{ + throw FRONTEND::NotSupportedException("getTunerReferenceSource not supported"); +} + +void fei_cap_i::setTunerEnable(const std::string& allocation_id, bool enable) { + long idx = getTunerMapping(allocation_id); + if (idx < 0) throw FRONTEND::FrontendException("Invalid allocation id"); + if(allocation_id != getControlAllocationId(idx)) + throw FRONTEND::FrontendException(("ID "+allocation_id+" does not have authorization to modify the tuner").c_str()); + // set hardware to new value. Raise an exception if it's not possible + this->frontend_tuner_status[idx].enabled = enable; +} + +bool fei_cap_i::getTunerEnable(const std::string& allocation_id) { + long idx = getTunerMapping(allocation_id); + if (idx < 0) throw FRONTEND::FrontendException("Invalid allocation id"); + return frontend_tuner_status[idx].enabled; +} + +void fei_cap_i::setTunerOutputSampleRate(const std::string& allocation_id, double sr) { + long idx = getTunerMapping(allocation_id); + if (idx < 0) throw FRONTEND::FrontendException("Invalid allocation id"); + if(allocation_id != getControlAllocationId(idx)) + throw FRONTEND::FrontendException(("ID "+allocation_id+" does not have authorization to modify the tuner").c_str()); + if (sr<0) throw FRONTEND::BadParameterException(); + // set hardware to new value. Raise an exception if it's not possible + this->frontend_tuner_status[idx].sample_rate = sr; +} + +double fei_cap_i::getTunerOutputSampleRate(const std::string& allocation_id){ + long idx = getTunerMapping(allocation_id); + if (idx < 0) throw FRONTEND::FrontendException("Invalid allocation id"); + return frontend_tuner_status[idx].sample_rate; +} + +/************************************************************* +Functions servicing the RFInfo port(s) +- port_name is the port over which the call was received +*************************************************************/ +std::string fei_cap_i::get_rf_flow_id(const std::string& port_name) +{ + return std::string("none"); +} + +void fei_cap_i::set_rf_flow_id(const std::string& port_name, const std::string& id) +{ +} + +frontend::RFInfoPkt fei_cap_i::get_rfinfo_pkt(const std::string& port_name) +{ + frontend::RFInfoPkt pkt; + return pkt; +} + +void fei_cap_i::set_rfinfo_pkt(const std::string& port_name, const frontend::RFInfoPkt &pkt) +{ +} + diff --git a/codegenTesting/sdr/dev/devices/fei_cap/fei_cap.prf.xml b/codegenTesting/sdr/dev/devices/fei_cap/fei_cap.prf.xml new file mode 100644 index 000000000..92ec0f88b --- /dev/null +++ b/codegenTesting/sdr/dev/devices/fei_cap/fei_cap.prf.xml @@ -0,0 +1,118 @@ + + + + + This specifies the device kind + FRONTEND::TUNER + + + + + This specifies the specific device + + + + + Status of each tuner, including entries for both allocated and un-allocated tuners. Each entry represents a single tuner. + + + Comma separated list of current Allocation IDs. + + + Current bandwidth in Hz + Hz + + + Current center frequency in Hz. + Hz + + + Indicates if tuner is enabled, in reference to the output state of the tuner. + + + Unique ID that specifies a group of Device. + + + Specifies a certain RF flow to allocate against. + + + Current sample rate in samples per second. + sps + + + Example Tuner Types: TX, RX, CHANNELIZER, DDC, RX_DIGITIZER, RX_DIGTIZIER_CHANNELIZER + + + + + + Allocates a listener (subscriber) based off a previous allocation + + + + + + + + + + Frontend Interfaces v2 main allocation structure + + Example Tuner Types: TX, RX, CHANNELIZER, DDC, RX_DIGITIZER, RX_DIGTIZIER_CHANNELIZER + + + The allocation_id set by the caller. Used by the caller to reference the allocation uniquely + + + Requested center frequency + 0.0 + Hz + + + Requested bandwidth (+/- the tolerance) + 0.0 + Hz + + + Allowable Percent above requested bandwidth (ie - 100 would be up to twice) + 10.0 + percent + + + Requested sample rate (+/- the tolerance). This can be ignored for such devices as analog tuners + 0.0 + Hz + + + Allowable Percent above requested sample rate (ie - 100 would be up to twice) + 10.0 + percent + + + True: Has control over the device to make changes +False: Does not need control and can just attach to any currently tasked device that satisfies the parameters (essentually a listener) + true + + + Unique identifier that specifies the group a device must be in. Must match group_id on the device + + + Optional. Specifies the RF flow of a specific input source to allocate against. If left empty, it will match all FrontEnd devices. + + + + + + + + + + + + + + + + + + diff --git a/codegenTesting/sdr/dev/devices/fei_cap/fei_cap.scd.xml b/codegenTesting/sdr/dev/devices/fei_cap/fei_cap.scd.xml new file mode 100644 index 000000000..42a732fe2 --- /dev/null +++ b/codegenTesting/sdr/dev/devices/fei_cap/fei_cap.scd.xml @@ -0,0 +1,73 @@ + + + + 2.2 + + device + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/codegenTesting/sdr/dev/devices/fei_cap/fei_cap.spd.xml b/codegenTesting/sdr/dev/devices/fei_cap/fei_cap.spd.xml new file mode 100644 index 000000000..59a8bd872 --- /dev/null +++ b/codegenTesting/sdr/dev/devices/fei_cap/fei_cap.spd.xml @@ -0,0 +1,27 @@ + + + + + + null + + + + + + + + + The implementation contains descriptive information about the template for a software resource. + + + cpp/fei_cap + + + + + + + + + diff --git a/codegenTesting/sdr/dev/devices/fei_cap/tests/.md5sums b/codegenTesting/sdr/dev/devices/fei_cap/tests/.md5sums new file mode 100644 index 000000000..d364fb25f --- /dev/null +++ b/codegenTesting/sdr/dev/devices/fei_cap/tests/.md5sums @@ -0,0 +1 @@ +47307e51a6bd577b7ddab297a0796b84 test_fei_cap.py diff --git a/codegenTesting/sdr/dev/devices/fei_cap/tests/test_fei_cap.py b/codegenTesting/sdr/dev/devices/fei_cap/tests/test_fei_cap.py new file mode 100644 index 000000000..dac9c5c16 --- /dev/null +++ b/codegenTesting/sdr/dev/devices/fei_cap/tests/test_fei_cap.py @@ -0,0 +1,68 @@ +#!/usr/bin/env python + +import ossie.utils.testing +from ossie.utils import sb +import frontend +from ossie.cf import CF + +class DeviceTests(ossie.utils.testing.RHTestCase): + # Path to the SPD file, relative to this file. This must be set in order to + # launch the device. + SPD_FILE = '../fei_cap.spd.xml' + + # setUp is run before every function preceded by "test" is executed + # tearDown is run after every function preceded by "test" is executed + + # self.comp is a device using the sandbox API + # to create a data source, the package sb contains data sources like DataSource or FileSource + # to create a data sink, there are sinks like DataSink and FileSink + # to connect the component to get data from a file, process it, and write the output to a file, use the following syntax: + # src = sb.FileSource('myfile.dat') + # snk = sb.DataSink() + # src.connect(self.comp) + # self.comp.connect(snk) + # sb.start() + # + # components/sources/sinks need to be started. Individual components or elements can be started + # src.start() + # self.comp.start() + # + # every component/elements in the sandbox can be started + # sb.start() + + def setUp(self): + # Launch the device, using the selected implementation + self.comp = sb.launch(self.spd_file, impl=self.impl) + + def tearDown(self): + # Clean up all sandbox artifacts created during test + sb.release() + + def testBasicBehavior(self): + ####################################################################### + # Make sure start and stop can be called without throwing exceptions + self.comp.start() + self.comp.stop() + a=frontend.createTunerAllocation(tuner_type='RX_DIGITIZER',allocation_id='1',returnDict=False) + b=frontend.createTunerAllocation(tuner_type='RX_DIGITIZER',allocation_id='2',returnDict=False) + c=frontend.createTunerAllocation(tuner_type='RX_DIGITIZER',allocation_id='3',returnDict=False) + a_bad=frontend.createTunerAllocation(tuner_type='RX_DIGITIZER',allocation_id='1',returnDict=False) + a_bad.id = 'foo' + self.assertEquals(self.comp._get_usageState(), CF.Device.IDLE) + self.assertEquals(self.comp.allocateCapacity([a]), True) + self.assertEquals(self.comp._get_usageState(), CF.Device.ACTIVE) + self.assertEquals(self.comp.allocateCapacity([b]), True) + self.assertEquals(self.comp._get_usageState(), CF.Device.BUSY) + self.assertEquals(self.comp.allocateCapacity([c]), False) + self.assertEquals(self.comp._get_usageState(), CF.Device.BUSY) + try: + self.comp.deallocateCapacity([b, a_bad]) + except: + pass + self.assertEquals(self.comp._get_usageState(), CF.Device.ACTIVE) + self.comp.deallocateCapacity([a]) + self.assertEquals(self.comp._get_usageState(), CF.Device.IDLE) + + +if __name__ == "__main__": + ossie.utils.testing.main() # By default tests all implementations From 66fb7e778f80fa27bf0178bf5ce2fb9d4719fb8c Mon Sep 17 00:00:00 2001 From: 8530 <8530@vm-131.vsi-corp.com> Date: Fri, 3 Mar 2017 11:41:00 -0500 Subject: [PATCH 0734/1644] save off sri when srichanges are triggered for read operations, CF-1715 --- .../libsrc/cpp/bulkio_in_stream.cpp | 11 ++++- .../libsrc/testing/tests/cpp/InStreamTest.cpp | 49 +++++++++++++++++++ .../libsrc/testing/tests/cpp/InStreamTest.h | 2 + 3 files changed, 61 insertions(+), 1 deletion(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp index 608f988c2..51b6bb968 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp @@ -523,8 +523,17 @@ class BufferedInputStream::Impl : public Base::Impl { // Allocate empty data block and propagate the SRI change and input queue // flush flags + DataBlockType _tblk(*this); + this->_setBlockFlags(_tblk, front); + if (_tblk.sriChanged()) { + StreamDescriptor::operator=(front.SRI); + } + + // set data block's sri DataBlockType data(*this); - this->_setBlockFlags(data, front); + // assign back any state changes from _setBlockFlags + data.sriChangeFlags(_tblk.sriChangeFlags()); + data.inputQueueFlushed(_tblk.inputQueueFlushed()); // Clear flags from packet, since they've been reported front.sriChanged = false; diff --git a/bulkioInterfaces/libsrc/testing/tests/cpp/InStreamTest.cpp b/bulkioInterfaces/libsrc/testing/tests/cpp/InStreamTest.cpp index c8ae7ae5f..ded085ba5 100644 --- a/bulkioInterfaces/libsrc/testing/tests/cpp/InStreamTest.cpp +++ b/bulkioInterfaces/libsrc/testing/tests/cpp/InStreamTest.cpp @@ -120,6 +120,54 @@ void InStreamTest::testGetCurrentStreamDataEos() CPPUNIT_ASSERT(stream.eos()); } +template +void InStreamTest::testSriModeChanges() +{ + typedef typename Port::PortSequenceType PortSequenceType; + typedef typename Port::StreamType StreamType; + typedef typename StreamType::DataBlockType DataBlockType; + + // Create a new stream and push some data to it + BULKIO::StreamSRI sri = bulkio::sri::create("empty_eos"); + port->pushSRI(sri); + PortSequenceType data; + data.length(1024); + port->pushPacket(data, bulkio::time::utils::now(), false, sri.streamID); + + // Get the input stream and read the first packet + StreamType stream = port->getStream("empty_eos"); + CPPUNIT_ASSERT_EQUAL(!stream, false); + DataBlockType block = stream.read(); + CPPUNIT_ASSERT(block); + CPPUNIT_ASSERT_EQUAL((size_t) 1024, block.size()); + CPPUNIT_ASSERT(!stream.eos()); + CPPUNIT_ASSERT_EQUAL(block.complex(),false); + + // check mode....true + sri.mode=1; + port->pushSRI(sri); + data.length(1024); + port->pushPacket(data, bulkio::time::utils::now(), false, sri.streamID); + block = stream.read(); + CPPUNIT_ASSERT(block); + CPPUNIT_ASSERT_EQUAL((size_t) 1024, block.size()); + CPPUNIT_ASSERT(!stream.eos()); + CPPUNIT_ASSERT_EQUAL(block.complex(),true); + + // check mode....false + sri.mode=0; + port->pushSRI(sri); + data.length(1024); + port->pushPacket(data, bulkio::time::utils::now(), false, sri.streamID); + block = stream.read(); + CPPUNIT_ASSERT(block); + CPPUNIT_ASSERT_EQUAL((size_t) 1024, block.size()); + CPPUNIT_ASSERT(!stream.eos()); + CPPUNIT_ASSERT_EQUAL(block.complex(),false); +} + + + template void BufferedInStreamTest::testReadSizeEos() { @@ -138,6 +186,7 @@ void BufferedInStreamTest::testReadSizeEos() CPPUNIT_ASSERT(stream.eos()); } + #define CREATE_TEST(x) \ class In##x##StreamTest : public BufferedInStreamTest \ { \ diff --git a/bulkioInterfaces/libsrc/testing/tests/cpp/InStreamTest.h b/bulkioInterfaces/libsrc/testing/tests/cpp/InStreamTest.h index 2bd1ed98a..e4a7d926a 100644 --- a/bulkioInterfaces/libsrc/testing/tests/cpp/InStreamTest.h +++ b/bulkioInterfaces/libsrc/testing/tests/cpp/InStreamTest.h @@ -29,6 +29,7 @@ class InStreamTest : public CppUnit::TestFixture CPPUNIT_TEST_SUITE(InStreamTest); CPPUNIT_TEST(testGetCurrentStreamEmptyEos); CPPUNIT_TEST(testGetCurrentStreamDataEos); + CPPUNIT_TEST(testSriModeChanges); CPPUNIT_TEST_SUITE_END(); public: @@ -37,6 +38,7 @@ class InStreamTest : public CppUnit::TestFixture void testGetCurrentStreamEmptyEos(); void testGetCurrentStreamDataEos(); + void testSriModeChanges(); protected: virtual std::string getPortName() const = 0; From 9803347a9f33083080b7b9a0f0811b44f769085d Mon Sep 17 00:00:00 2001 From: Ryan Bauman Date: Fri, 3 Mar 2017 12:39:01 -0500 Subject: [PATCH 0735/1644] RELENG-580 - bump specfile release --- bulkioInterfaces/bulkioInterfaces.spec | 2 +- burstioInterfaces/burstioInterfaces.spec | 2 +- frontendInterfaces/frontendInterfaces.spec | 2 +- redhawk-codegen/redhawk-codegen.spec | 2 +- redhawk/src/releng/redhawk.spec | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/bulkioInterfaces/bulkioInterfaces.spec b/bulkioInterfaces/bulkioInterfaces.spec index 8daed1ff2..e2c48b74c 100644 --- a/bulkioInterfaces/bulkioInterfaces.spec +++ b/bulkioInterfaces/bulkioInterfaces.spec @@ -29,7 +29,7 @@ Prefix: %{_prefix} Name: bulkioInterfaces Version: 2.1.0 -Release: 1%{?dist} +Release: 2%{?dist} Summary: The bulkio library for REDHAWK Group: Applications/Engineering diff --git a/burstioInterfaces/burstioInterfaces.spec b/burstioInterfaces/burstioInterfaces.spec index 9f53f8114..f91e08722 100644 --- a/burstioInterfaces/burstioInterfaces.spec +++ b/burstioInterfaces/burstioInterfaces.spec @@ -29,7 +29,7 @@ Prefix: %{_prefix} Name: burstioInterfaces Version: 2.1.0 -Release: 1%{?dist} +Release: 2%{?dist} Summary: BURSTIO interfaces for REDHAWK Group: Applications/Engineering diff --git a/frontendInterfaces/frontendInterfaces.spec b/frontendInterfaces/frontendInterfaces.spec index 8f97a8fa5..9b1844163 100644 --- a/frontendInterfaces/frontendInterfaces.spec +++ b/frontendInterfaces/frontendInterfaces.spec @@ -35,7 +35,7 @@ Prefix: %{_prefix} Summary: The frontend library for REDHAWK Name: frontendInterfaces Version: 2.4.0 -Release: 1%{?dist} +Release: 2%{?dist} License: LGPLv3+ Group: REDHAWK/Interfaces Source: %{name}-%{version}.tar.gz diff --git a/redhawk-codegen/redhawk-codegen.spec b/redhawk-codegen/redhawk-codegen.spec index 519387ae4..1e072c644 100644 --- a/redhawk-codegen/redhawk-codegen.spec +++ b/redhawk-codegen/redhawk-codegen.spec @@ -24,7 +24,7 @@ Prefix: %{_prefix} Name: redhawk-codegen Version: 2.1.0 -Release: 1%{?dist} +Release: 2%{?dist} Summary: Redhawk Code Generators Group: Applications/Engineering diff --git a/redhawk/src/releng/redhawk.spec b/redhawk/src/releng/redhawk.spec index a4cb3d308..7de6d88fd 100644 --- a/redhawk/src/releng/redhawk.spec +++ b/redhawk/src/releng/redhawk.spec @@ -27,7 +27,7 @@ Prefix: %{_sysconfdir} Name: redhawk Version: 2.1.0 -Release: 1%{?dist} +Release: 2%{?dist} Summary: REDHAWK is a Software Defined Radio framework Group: Applications/Engineering From eb159c5dab457395618e3c45f55555f5008cf7f6 Mon Sep 17 00:00:00 2001 From: Ryan Bauman Date: Fri, 3 Mar 2017 15:06:23 -0500 Subject: [PATCH 0736/1644] RELENG-580 - bump GPP specfile release --- GPP/GPP.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GPP/GPP.spec b/GPP/GPP.spec index 1b6d54c09..d569a4214 100644 --- a/GPP/GPP.spec +++ b/GPP/GPP.spec @@ -32,7 +32,7 @@ Prefix: %{_prefix} Name: GPP Version: 2.1.0 -Release: 1%{?dist} +Release: 2%{?dist} Summary: REDHAWK GPP Group: Applications/Engineering From bc64a83a06155e74fa3de3880078fd7cff52b333 Mon Sep 17 00:00:00 2001 From: Ryan Bauman Date: Fri, 3 Mar 2017 18:19:17 -0500 Subject: [PATCH 0737/1644] RELENG-580 - bump specfile release field post RC --- GPP/GPP.spec | 2 +- bulkioInterfaces/bulkioInterfaces.spec | 2 +- burstioInterfaces/burstioInterfaces.spec | 2 +- frontendInterfaces/frontendInterfaces.spec | 2 +- redhawk-codegen/redhawk-codegen.spec | 2 +- redhawk/src/releng/redhawk.spec | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/GPP/GPP.spec b/GPP/GPP.spec index d569a4214..84d88cf77 100644 --- a/GPP/GPP.spec +++ b/GPP/GPP.spec @@ -32,7 +32,7 @@ Prefix: %{_prefix} Name: GPP Version: 2.1.0 -Release: 2%{?dist} +Release: 3%{?dist} Summary: REDHAWK GPP Group: Applications/Engineering diff --git a/bulkioInterfaces/bulkioInterfaces.spec b/bulkioInterfaces/bulkioInterfaces.spec index e2c48b74c..578102a3a 100644 --- a/bulkioInterfaces/bulkioInterfaces.spec +++ b/bulkioInterfaces/bulkioInterfaces.spec @@ -29,7 +29,7 @@ Prefix: %{_prefix} Name: bulkioInterfaces Version: 2.1.0 -Release: 2%{?dist} +Release: 3%{?dist} Summary: The bulkio library for REDHAWK Group: Applications/Engineering diff --git a/burstioInterfaces/burstioInterfaces.spec b/burstioInterfaces/burstioInterfaces.spec index f91e08722..a91fcfa8d 100644 --- a/burstioInterfaces/burstioInterfaces.spec +++ b/burstioInterfaces/burstioInterfaces.spec @@ -29,7 +29,7 @@ Prefix: %{_prefix} Name: burstioInterfaces Version: 2.1.0 -Release: 2%{?dist} +Release: 3%{?dist} Summary: BURSTIO interfaces for REDHAWK Group: Applications/Engineering diff --git a/frontendInterfaces/frontendInterfaces.spec b/frontendInterfaces/frontendInterfaces.spec index 9b1844163..3b09344c1 100644 --- a/frontendInterfaces/frontendInterfaces.spec +++ b/frontendInterfaces/frontendInterfaces.spec @@ -35,7 +35,7 @@ Prefix: %{_prefix} Summary: The frontend library for REDHAWK Name: frontendInterfaces Version: 2.4.0 -Release: 2%{?dist} +Release: 3%{?dist} License: LGPLv3+ Group: REDHAWK/Interfaces Source: %{name}-%{version}.tar.gz diff --git a/redhawk-codegen/redhawk-codegen.spec b/redhawk-codegen/redhawk-codegen.spec index 1e072c644..30af01add 100644 --- a/redhawk-codegen/redhawk-codegen.spec +++ b/redhawk-codegen/redhawk-codegen.spec @@ -24,7 +24,7 @@ Prefix: %{_prefix} Name: redhawk-codegen Version: 2.1.0 -Release: 2%{?dist} +Release: 3%{?dist} Summary: Redhawk Code Generators Group: Applications/Engineering diff --git a/redhawk/src/releng/redhawk.spec b/redhawk/src/releng/redhawk.spec index 7de6d88fd..30e4d8c0c 100644 --- a/redhawk/src/releng/redhawk.spec +++ b/redhawk/src/releng/redhawk.spec @@ -27,7 +27,7 @@ Prefix: %{_sysconfdir} Name: redhawk Version: 2.1.0 -Release: 2%{?dist} +Release: 3%{?dist} Summary: REDHAWK is a Software Defined Radio framework Group: Applications/Engineering From bde2729e239772bb9af7d9c8da8264875f83e308 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Mon, 6 Mar 2017 16:27:43 -0500 Subject: [PATCH 0738/1644] Refs CF-1709. Removed numpy dependency from test --- .../RX_Digitizer_Sim/python/Waveform.py | 82 +++++-------------- 1 file changed, 22 insertions(+), 60 deletions(-) diff --git a/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/python/Waveform.py b/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/python/Waveform.py index 66ce75c7b..d620dd174 100644 --- a/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/python/Waveform.py +++ b/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/python/Waveform.py @@ -27,8 +27,7 @@ - lrs - ramp ''' -import math -import numpy as _np +import math, os class Waveform: A = 67081293.0 @@ -81,13 +80,9 @@ def whitenoise(self, sdev, n, spa=1): sum1 = v1*v1 + v2*v2 if sum1 >= 1.0 or sum1 <1e-20: continue sum1 = fdev * float(math.sqrt(factor*math.log(sum1)/sum1)) - try: - a = _np.float32(5) - except: - import numpy as _np - outbuff[i] = float(_np.float32(v1*sum1)) + outbuff[i] = float(v1*sum1) if (i+1) < maxIndex: - outbuff[i+1] = float(_np.float32(v2*sum1)) + outbuff[i+1] = float(v2*sum1) i+=2 self.seed = int(sis*self.T26) @@ -106,10 +101,6 @@ def whitenoise(self, sdev, n, spa=1): # fast algorithm based on: sin(x+dp) = sin(x)*cos(dp) + cos(x)*sin(dp) # cos(x+dp) = cos(x)*cos(dp) - sin(x)*sin(dp) def sincos(self, amp, p, dp, n, spa): - try: - a = _np.float32(5) - except: - import numpy as _np outbuff = range(n*spa) cxr = amp*math.cos(p*self.TWOPI) cxi = amp*math.sin(p*self.TWOPI) @@ -117,27 +108,27 @@ def sincos(self, amp, p, dp, n, spa): dxi = math.sin(dp*self.TWOPI) if spa==2: for i in range(0, n*2, 2): - outbuff[i] = float(_np.float32(cxr)) - outbuff[i+1] = float(_np.float32(cxi)) + outbuff[i] = float(cxr) + outbuff[i+1] = float(cxi) axr = (cxr*dxr) - (cxi*dxi) axi = (cxr*dxi) + (cxi*dxr) cxr=axr cxi=axi elif spa==1: for i in range(n): - outbuff[i] = float(_np.float32(cxi)) + outbuff[i] = float(cxi) axr = (cxr*dxr) - (cxi*dxi) axi = (cxr*dxi) + (cxi*dxr) cxr=axr cxi=axi elif spa==-1: for i in range(n): - outbuff[i] = float(_np.float32(amp*math.sin(p*self.TWOPI))) + outbuff[i] = float(amp*math.sin(p*self.TWOPI)) p += dp elif spa==-2: for i in range(0, n*2, 2): - outbuff[i] = float(_np.float32(amp*math.cos(p*self.TWOPI))) - outbuff[i+1] = float(_np.float32(amp*math.sin(p*self.TWOPI))) + outbuff[i] = float(amp*math.cos(p*self.TWOPI)) + outbuff[i+1] = float(amp*math.sin(p*self.TWOPI)) p += dp return outbuff @@ -155,19 +146,15 @@ def square(self, amp, p, dp, n, spa): value = 0.0 famp = float(amp) famp2 = -famp - try: - a = _np.float32(5) - except: - import numpy as _np for i in range(0, n*spa, spa): value = famp2 if p >= 1.0: p -= 1.0 elif p >= 0.5: value = famp - outbuff[i] = float(_np.float32(value)) + outbuff[i] = float(value) if spa == 2: - outbuff[i+1] = float(_np.float32(value)) + outbuff[i+1] = float(value) p += dp return outbuff @@ -186,10 +173,6 @@ def triangle(self, amp, p, dp, n, spa): famp = float(amp) famp2 = 4*famp fp = float(p) - 0.5 - try: - a = _np.float32(5) - except: - import numpy as _np for i in range(0, n*spa, spa): if fp >= 0.5: fp -= 1.0 @@ -197,9 +180,9 @@ def triangle(self, amp, p, dp, n, spa): value = float(famp - fp*famp2) else: value = float(famp + fp*famp2) - outbuff[i] = float(_np.float32(value)) + outbuff[i] = float(value) if spa == 2: - outbuff[i+1] = float(_np.float32(value)) + outbuff[i+1] = float(value) fp += dp return outbuff @@ -218,17 +201,13 @@ def sawtooth(self, amp, p, dp, n, spa): famp = float(amp) famp2 = 2*famp fp = float(p) - 0.5 - try: - a = _np.float32(5) - except: - import numpy as _np for i in range(0, n*spa, spa): if fp >= 0.5: fp -= 1.0 value = float(fp*famp2) - outbuff[i] = float(_np.float32(value)) + outbuff[i] = float(value) if spa == 2: - outbuff[i+1] = float(_np.float32(value)) + outbuff[i+1] = float(value) fp += dp return outbuff @@ -245,19 +224,15 @@ def pulse(self, amp, p, dp, n, spa): outbuff = range(n*spa) value = 0.0 famp = float(amp) - try: - a = _np.float32(5) - except: - import numpy as _np for i in range(0, n*spa, spa): if p >= 1.0: value = famp p -= 1.0 else: value = 0 - outbuff[i] = float(_np.float32(value)) + outbuff[i] = float(value) if spa == 2: - outbuff[i+1] = float(_np.float32(value)) + outbuff[i+1] = float(value) p += dp return outbuff @@ -270,12 +245,8 @@ def pulse(self, amp, p, dp, n, spa): # @return the new data buffer def constant(self, amp, n, spa): outbuff = range(n*spa) - try: - a = _np.float32(5) - except: - import numpy as _np for i in range(n*spa): - outbuff[i] = float(_np.float32(amp)) + outbuff[i] = float(amp) return outbuff @@ -289,16 +260,11 @@ def constant(self, amp, n, spa): def lrs(self, amp, n, spa, lrs): outbuff = range(n*spa) factor = (amp/2.0/self.B1G) - try: - a = _np.float32(5) - except: - import numpy as _np - for i in range(0, n*spa, spa): data = (factor * lrs) - outbuff[i] = float(_np.float32(data)) + outbuff[i] = float(data) if spa == 2: - outbuff[i+1] = float(_np.float32(data)) + outbuff[i+1] = float(data) bit0 = (~(lrs ^ (lrs>>1) ^ (lrs>>5) ^ (lrs>>25)))&0x1 lrs <<= 1 @@ -320,14 +286,10 @@ def lrs(self, amp, n, spa, lrs): # @return the new data buffer and the RAMP value at end of array def ramp(self, amp, n, spa, data): outbuff = range(n*spa) - try: - a = _np.float32(5) - except: - import numpy as _np for i in range(0, n*spa, spa): - outbuff[i] = float(_np.float32(data)) + outbuff[i] = float(data) if spa == 2: - outbuff[i+1] = float(_np.float32(data)) + outbuff[i+1] = float(data) data = data + 1 if data >= amp: data = int(-amp) From 25dd96fd627b15b7538479b357f79eab534a6375 Mon Sep 17 00:00:00 2001 From: Ryan Bauman Date: Wed, 8 Mar 2017 10:58:56 -0500 Subject: [PATCH 0739/1644] CF-1422 - Add shared address component documentation [ci skip] --- docs/shared-address/component-examples.md | 168 +++++++++++++++ docs/shared-address/component-model.md | 61 ++++++ docs/shared-address/images/component_exe.png | Bin 0 -> 6464 bytes docs/shared-address/images/component_so.png | Bin 0 -> 12872 bytes docs/shared-address/images/current.png | Bin 0 -> 46926 bytes docs/shared-address/images/mixed.png | Bin 0 -> 53514 bytes .../images/process_per_component.png | Bin 0 -> 58855 bytes docs/shared-address/images/shared_address.png | Bin 0 -> 50764 bytes .../shared-address-components-howto.md | 193 ++++++++++++++++++ 9 files changed, 422 insertions(+) create mode 100644 docs/shared-address/component-examples.md create mode 100644 docs/shared-address/component-model.md create mode 100644 docs/shared-address/images/component_exe.png create mode 100644 docs/shared-address/images/component_so.png create mode 100644 docs/shared-address/images/current.png create mode 100644 docs/shared-address/images/mixed.png create mode 100644 docs/shared-address/images/process_per_component.png create mode 100644 docs/shared-address/images/shared_address.png create mode 100644 docs/shared-address/shared-address-components-howto.md diff --git a/docs/shared-address/component-examples.md b/docs/shared-address/component-examples.md new file mode 100644 index 000000000..64bd85d41 --- /dev/null +++ b/docs/shared-address/component-examples.md @@ -0,0 +1,168 @@ +# Component Examples + +Transforming Component +---------------------- + +A component that takes some input stream(s), and produces output data. E.g., TuneFilterDecimate, AmFmPmBasebandDemod, etc. + +### Service Function + +The following example is from the modified FM demodulator I'm using to do resource utilization measurement in shared address space components, versus a comparable 2.0 application. This is the basic flow I'm expecting for new components that are doing some sort of data transformation; other than the use of the shared buffer data types, this is almost a valid 2.0 flow as well–much of it is intrinsic to the BulkIO stream API. The one thing missing in 2.0 is the getStream() method on +output ports. You have to track the output streams yourself in 2.0, which was an oversight. + +``` +int FmDemod_i::serviceFunction() +{ + // InFloatPort::getCurrentStream() returns the first input stream that has data available to be read, + // blocking if none are currently ready. + bulkio::InFloatStream input = dataFloat_in->getCurrentStream(); + if (!input) { + // No streams are available (typically due to a stop). + return NOOP; + } + + // If an output stream has already been created, OutFloatPort::getStream() finds it by streamID. + bulkio::OutFloatStream output = dataFloat_out->getStream(input.s + treamID()); + if (!output) { + // Otherwise, create a new stream. + output = dataFloat_out->createStream(input.streamID()); + // configureStream() is a user-defined method to apply any transformations from the input SRI to the + // output SRI + configureStream(output, input.sri()); + } + + // Blocking read from the input stream. The default behavior returns exactly one packet worth of data, + // but a sample count and consume length (for overlap) can be provided as well. + bulkio::FloatDataBlock block = input.read(); + if (!block) { + // There are two reasons why InFloatStream::read() might return a "null" block: + if (input.eos()) { + // 1. End-of-stream; close the output stream. + LOG_DEBUG(FmDemod_i, "Stream " << input.streamID() << " got an EOS"); + output.close(); + return NORMAL; + } else { + // 2. The component was stopped. + return NOOP; + } + } + + // Handle an input queue flush. Depending on your algorithm, this may require resetting state, etc. + if (block.inputQueueFlushed()) { + LOG_WARN(FmDemod_i, "Input queue flushed"); + } + + // Handle SRI changes. The configureStream() method is also used on output stream creation; the SRI change flag + // is not set for a new stream. + // Optionally, FloatDataBlock::sriChangeFlags() returns a set of bit flags to check which parts of the SRI changed, + // if only certain fields are relevant. + if (block.sriChanged()) { + LOG_INFO(FmDemod_i, "SRI changed"); + configureStream(output, block.sri()); + } + + // Update any internal variables or properties. This a user-defined method, and the behavior is up to the + // implementer. In this case, the algorithm depends on the sample rate of the input SRI. + updateParameters(block.sri()); + + // Run the algorithm here (FM demodulation, in this case), taking into account whether the input is complex or + // real. In this example, the output is always real regardless of the input, but this can differ on a per-component + // basis. The actual work is done in a private templatized member function, doFmDemod(). + redhawk::buffer buffer; + if (block.complex()) { + buffer = doFmDemod(block.cxbuffer()); + } else { + buffer = doFmDemod(block.buffer()); + } + + // Write the processed data to the output stream. After calling OutFloatStream::write(), the buffer is now shared + // with an unknown number of consumers. No more modifications should be made. + // Regarding the BULKIO::PrecisionUTCTime, a block can contain multiple timestamps, if you explicitly request + // a read size; here, we are just taking the data in the block sizes it comes in, so we can just use the starting + // timestamp for the entire block. Algorithms that affect the time basis should compute a new block time. + output.write(buffer, block.getStartTime()); + return NORMAL; +} +``` + +### Algorithm + +Here's what `doFmDemod()` looks like. You wouldn't necessarily have to +do it this way, it's just an example of using functional programming to +do your algorithm. By making the method templatized, the same code can +be used (inline) for both real and complex input. + +``` +template +redhawk::shared_buffer FmDemod_i::doFmDemod(const redhawk::shared_buffer& input) +{ + redhawk::buffer output(input.size()); + dsp::process(input.begin(), input.end(), output.begin(), demod); + return output; +} +``` + +It's not taking different streams into account, but that's relatively +easy to fix–you could keep a map of stream IDs to demodulator objects. + +Quick implementation notes: + +- `dsp::process()` is basically `std::transform()`, but it allows the + `demod` object to be stateful (i.e., it remembers the last phase) +- `demod` is a small functor that is applied to each input, storing + the result to the output + +Generative Component +-------------------- + +A component that creates BulkIO output data based on parameters or +files, instead of BulkIO input. E.g., SigGen, FileReader. + +### Service Function + +Generative components can be simpler, because there is no input to be +concerned with. The following example is for a component that generates +a waveform (like SigGen, but more trivial). + +``` +int Waveform_i::serviceFunction() +{ + // Update any internal variables or properties. This a user-defined method, and the behavior is up to the + // implementer. In this case, the waveform parameters could be copied from properties to shadow variables + // while holding the properties lock (propertySetAccess). + updateParameters(); + + // For this example, the output stream is a member variable on the Waveform_i class. If it's not already + // created, do it here. Another option would be to create it inthe constructor() method. + if (!_outputStream) { + _outputStream = dataFloat_out->createStream(_streamID); + _sriChanged = true; + } + + // If the SRI needs to be updated, based on the properties (or some other reason), one option is to set an + // internal flag; another possibility might be to update the SRI in updateParameters()--if the stream is only + // used from within serviceFunction(), there are no threading concerns. + // configureStream() is a user-defined method to apply any changes to the output stream SRI. + if (_sriChanged) { + configureStream(_outputStream); + } + + // Create a buffer of the desired size. The redhawk::buffer class is the mutable version, and it gracefullly + // "degrades" to the immutable redhawk::shared_buffer class. + redhawk::buffer data(1024); + + // The implementation of the generator function is left as an exercise to the reader. + doWaveform(data.begin(), data.end()); + + // This example keeps a running BULKIO::PrecisionUTCTime for the first sample of each block. There are overloaded + // arithmetic operators to make it easier to modify. + _currentTimestamp += _outputStream.xdelta() * data.size(); + + // After calling OutFloatStream::write(), the buffer is now shared with an unknown number of consumers. No more + // modifications should be made. + _outputStream.write(data, _currentTimestamp); + + return NORMAL; +} +``` diff --git a/docs/shared-address/component-model.md b/docs/shared-address/component-model.md new file mode 100644 index 000000000..fb2c5792d --- /dev/null +++ b/docs/shared-address/component-model.md @@ -0,0 +1,61 @@ +# Component Model Overview  + +REDHAWK 2.0 C++ Components +-------------------------- + +Historically in REDHAWK, a C++ component is an executable which contains +both the component-specific implementation class (e.g., "TuneFilterDecimate\_i") and a small `main()` driver that creates and executes the component. + +![component_exe](/docs/shared-address/images/component_exe.png) + +Most of the actual work of `main()` is done inside of the core libraries, in the `Resource_impl::start_component()` function, so the generated `main.cpp` contains very little code. + +Shared Address Space C++ Components +----------------------------------- + +In order to support creating arbitrary components in the same address space, the creation of the component is separated from the management of the process. + +![component_so](/docs/shared-address/images/component_so.png) + + +The component code provides a factory function, `make_component()`, that implements creation of an instance of the specific component (this is a subset of what `main()` used to do). The rest of the component implementation remains the same. + +A new meta-component handles the normal `main()` responsibilites, and provides an interface for the system to create a component inside its process space. This is called the ComponentHost. + +REDHAWK 2.0 Process Model +------------------------- + +The classic REDHAWK model is a 1:1 mapping of processes to components. + +![current](/docs/shared-address/images/current.png) + +The component's executable is either run by the ApplicationFactory via the GPP, or directly within the Sandbox/Chalkboard. Either does a fork-and-exec; the component executable creates a single instance of the component, which then registers back with the ApplicationFactory or Sandbox. + +Shared Address Space Process Model +---------------------------------- + +The way to remove IPC costs is, naturally, to do away with the P (at least in part). This means a 1:N process-to-component mapping. + +![shared_address](/docs/shared-address/images/shared_address.png) + +The Sandbox/Chalkboard or ApplicationFactory executes the component host, then launches the components into the host. The component host is capable of dynamically loading and unloading components and their dependencies; this allows the set of components running in the component host to change arbitrarily at run-time. The Sandbox benefits from this behavior now, since it doesn't know the future. Applications, on the other hand, do not support dynamic deployment *yet*. + +Mixing Shared Libraries and Executables +--------------------------------------- + +The shared address space model does not affect existing components. Executable-based C++ components will still compile and run as-is; however, without updating and re-generating a component, it will not be able to take advantage of shared address space benefits. + +![mixed](/docs/shared-address/images/mixed.png) + +The ability to generate executable components is not going away. Although I would expect it to be rare, there may be particular reasons why a given component cannot be run in a shared address space–perhaps due to the requirements of an external library, for example. + +Process Per Component +--------------------- + +While the intent is to run all shared library components from an application in a single component host in order to take advantage of the benefits of memory sharing, the design does not require it (1 is a perfectly reasonable N in 1:N). + +![process_per_component](/docs/shared-address/images/process_per_component.png) + +Each component can be launched in its own component host, giving the exact same behavior as REDHAWK 2.0 and prior. Or, a few troublesome components could be isolated from the rest by running them in their own component hosts, while the rest of the components share a host. + +A further enhancement could allow an application designer to choose arbitrary groupings of components to be run in a set of component hosts, though I have my doubts as to how valuable this is when balanced against the complexity. diff --git a/docs/shared-address/images/component_exe.png b/docs/shared-address/images/component_exe.png new file mode 100644 index 0000000000000000000000000000000000000000..9dedcbbf8790941819df37fb0b138dace1f329b1 GIT binary patch literal 6464 zcmZXZ1x#Guv&Vtr4vUs8g+g(6ZShj1rAVQ;E{ntB+8=I<6?b>H#ogUm+#MEZ@dD-1 z-~YXrm%L0)Zf;H{=iJHUGvApTs`BXr9`;LYBqSufkMc6A&(GlJm4S(lgoJD-%slb@ zf@LrN%@GL+zxR3dAw#*|Ya=01{Q4*(sqVIf(8JPI*C2l)xPKE)e?x&xSA+TVfg3GE}zyn3KK)PfczM9w;+bGCC5%}p=Wkh5$-%0gI0?m_F3c^ zb}}y5%))PYSRqbRy@WKYKH9xQPrdLcYQ*v$quZ7r%4mZaHL|k_O7kOzWioKu3Yi=h zq}a}m!MP`;=Eas%AKULo0{h8T;bU{y*-J$RV(uoYuWz4T1=d*y9%+5%WGqYJrO4e! zt9hI}%anOa6f|*r?+SdEsMQu-iPBvneyD2QT!Mr`Dv^ak@%DGV300{Cim|}0g zj3rN%iH}*)*QK02>G#RfTEQv2c(zEeu0!y$!16tdaHWsf;o=naPYbjnLcZ3B{9iS3 zCpkgf*Q!#HN8j5g1MIIBWCEc_%lL&kJce|2Lm!g^BUnwJ-1D=Ba1@R|45c5yTY3P~ z>BE{#{oQzsG08e1bCu#yI~2|$b=u9)F8vV2Av4QbZCaMqCR=PNx_FntJc4U=&tIpp z)kkrBfsrl;kSd(+ zm6AW>X?O_36x&)(xGL&3NFTu@k|cb+M)Ah2yf`-coHbO$+s*gyaXzc7&I%#mK*8TL zVuED=uT{jkg(3YgD@$~;CdAHkXFu10T}JC{_ABqGoSl||Ywy~qZ)q<7gIKyD8=v7s z)OBCdo$o@88{gh{a;W2%Vz7yMC~nhq1-|YbY8ksypf}oyPI77Us>}S|=qYfz^hE*g zm0W_Mr$>vh`f6!snVBR%0CL%?nn=GgEGr*S<8bei2!UGPes?XZ0EE&g>DK8S>kt#2 z#2P3W>y!hh6jS2?kjnDg#sGChz`;^jWegz)U0O8gGp2JAnbNPWFofp$keWDA`j4p0 zNL_P1j40Ur?W0@k(ZjD~pWE{&dx0mZ?eE+74Ff+z_}DV$bLX>vzQp1d-yK-xF@o~^vb zcDuELI(+$}Ur!rzTp~s>DOSdcm+n{vAx88sQemo#J$@EV_0^ejBF_0AWlSL)%a$Tf z8Kz&4x6?JxGO9RI4|QyYl?v;FJRWkylwKVK{YigCqZzkl;!AgilNs#8>MS{!Y?TZ} zLc!X(n)PyWsWzHPEiWHi;KWm2ah7`cylU97T2cVJA91<%O$D(r$T;tTU*pf(pgNb;r+pw1 zB4$0R&oR)&6>HN3%{-U%;Gy1#O$x2h+uIX1;58>9ZG6Tt0Omnj;V77KgM zVeuMK{0FM2dOKWF55N9FPW8wxwXSjeukvH6%}hh4JWh_TolzHZhRah-m&ZrYaPC95 zO9bMi^-{Y$pzHym6j6o~+BgJDp?)h~9l~PP9}F*lPe=hNgWVJd;b4%JS6tmQ-c*Dg`YE ziz4Oe&G$W0-p7*Fr(Y)ew|`XFsIC}acXYk8SwOna!w{j_a3W460K6jDe>bIZ%k`x> zF`CbvXz%k$fiWig=Qn2`nORuk#Qk)Hk8Cgd%y#X$xJ!?`nWK_ZD5?+fY;I;I0og@$ zX^&wUR~Ve?2GVcwb%soDvWDf&nJtp%5;kODp;~pa%=|g7g>K?asbL(2aNE7&wlt?< zslAI!W`5;(G8YQED~gW)xFB&j?+#p? ze{9Mtx%&6w+JcuDvW@i^cjvO?Zj?hMcaaX&10XqD6x7Pw&bp_tQc7pb)Po$=GC@k< z?Al#DVu2}==@$jMt#OQdXROhw;U!crdL6K4+FRi@O^^uKJ=ish+C`ybE{=xXPxOIm zW#5t5uzzk0G9HUh)ZB_i%D;yd0C3q+bIRNAj8Bs&5wFQeCeT+Wc8df#^`tEKkO#Qo@`PveVwYom~HI#7{!(KbmT9h<0y7%jWN~_^@Pf zbC?35=Oq$iDXh6p6}&K1#v-(tLW;;tRNbz}^jF_{rG__&^N2>;1)@I4hVhl#c7x=K(Xo$Kt^z9h0{4kva&H( zUi?8z<=A{7d8WcPqJg}W%QG#NrBUl?+;x`d1W(Zo88J#F*-4;xR{l|;A*xm%sa&$) zlKv5-<9$jFZ?=GGr*M49i=*lZ@w7DOGZPvG**Jx^XQxrJuL2Et$}t3}n<522xEjIG zjm9xKAKo%4e4yfuu7D~H_kp|GvuHX@XT9kcUQIvtA0f9H2PG=9`Vu*?S#Np`;Y_`} z6Q*l3Gy`?}5d<^tWThHPq=$~1a(;3Na9XFK_s8X&73UpH(xzRYTgQ3~YUp<>9kr;Tvu0QRR)zAzucAT#3|}Hn3~a~cR&iW6bn3^@ zusV>HQ&D^aW0>{{07p(dUir;?uce$9#Pj<9Kg;doq2p)AfHZY?8l*ROU)hJ%a|!ag z6)v2lwf_Ey?i#kcF}g7d<`~V=wR7J6Z8bkyG-k1Tm`#0t3=V$Wx7!4}vEcAYjZQkL zPsuVFrgP;A6vnS+58WcP#MY>f$C7BI;ZYu2!98#*WlyFG zKLK$1RDL?1K)Sp{g$mlr@`@+jSq6`PjxlHQ+Ka`zw`{e?tyrtLnUwXy<&&tjm=<~3 zHjykV;~R41=IG`@YrJ&&2W$O|c@U8O(8k}Z{xvQy5Sz~)GTEK-{wU^eYvS-ux$G_U zwss9Gx8@00nkD7|h}!yS?~6+7t{7)EZpi5;)Cypf1CGn4^yXVW>1~7_ zKQe$EVMO~&ZUSfWWx=P5l<`;EJ?-(rkY9GeOY^vT4SQF?+&8J)3zuDBu_iHjt0p{S zIfFBp+s&~_h|;Jr^k98#*9F|1DYbD}f~)L$;>W{6g*P5;$B4H;c>Mqfula@T)htY+ zC$eCL7w*c%=c{+22^JImM0+&e&Zvy`^;g_BJcuUD=xek>X)j@MTOP;(3?^{AC@ zU0bxs0q_OLPTG@pfFxwB0}9NE4&)8<(B!3I8$wUkTS7r8-;(9uB)E$$dU+#*f;Zr&- zgEg77{InvGjGVkbQP`K4eH;FwQ6FkMgSW&MvQ)EA^4)`#WfRuNC6Kr&e4W$PEJ8BzM@~LL@NGm_Qq35@ogRL?Kd|zy1V|@ z51#`F)D;pEYPA2m17_%!KmIImhV=^%#UcjCkEbZk18uFC7-Mp zBWcnDwxHBmT0cd$OyC(QV-+5$70lZHGG?$-?C{h((R1mui5mr<3Y^|=$RFq)_= zGyMXa=r`>eAC8kfiBcK|oGSJLZdhm1Z!;BSq*74Qm+Orey-_|f7Q3lvQuYdJV<A zJXFKDB#j(|Th_7ydgiAC_?Z{cobLk&0Ut*m>JW!|pi|GutNL64V~k0m!UmnYT-o(^sG z>*!Fx@9*N?$U$>r;tl*R92U==YyAryS#b|f133M2h%yV<{10-{L`Vvl#3UpAwraFT zXh`BQyH$|M&JEzo72^SP%KFeerNHy-rLBi6w({fD=azEeB~#d`T5OwC^jc{-S-h1n z!whD4k$Yf_lFPl)+oQ(^2s>6(oGf!x1F@y(E*3!YOZYoHsEormckyAcq`*LP8=Om7 zrL;8jaLn&oCE^RFOnjZ*iU46#4qPh{>|&#OSXv52Ycd|97pSy7_tiupG&49Lu6Q}$En@77rv7&_}vqykAuPagpyr)JB zvK*-)-`v>SlO)VQiICYRyoV z7V~HEm6+X${EQfq0zaB5i3DAqJ*laG(yhl9I|2FqK4y7|OF|gV?BYw>wT6vOdN%tO zZ2maG8J%heAXV$6##xm5YJY>L$VwM>tg(?O_i6%p@la^1v4E{49iB1Cj;Z8vbTrL;V^%-yh@y@_)YG3p*GF$wCh5IF= zLni}}HMp2{2UkJpC1BL- zS;H*oq*hQa;0oD5n*sj%OiRO6#hQe-r@YUM7$XPG)QLMaau63I}>LgAb9#T3Sl3EfTw97i!Ly#QI?3*VKBmEIaqK(ydyKlg*De{To$x z^O?H*e^HJ9_nTcMg{FCTRhYtr;VIk@M^Y6zx)}a)dy*aU>Inbm9QF@{K64%ZFP#4k z4)|jd&n%U=i11c!rnGjDy~^mgCgXMg0dl&bl}*rd#VA`R3VNOoHB5Xyh#-0t?e3aK zq5LIv^8QsYo+n3fLCcdiFJ;F`)IW)(;w=?*ttiNhIn}$98eX@T{uGm|Xm_&tw?=kC ze=FOm@O6j9t;M>TTl3Op%sX2y0fFwr5R$T61RvyAIMwAzW*|ftSk7&mMb0*+Y){L8 zr|5$%=@IFtCv8M$06Y$^ej&d3Jh;&LhPL3s7iRP3h{e2TWndEC!rtO?;-BFLaVM-; zEjndXh1VYFC3J9M)@q(=uCC9FV7(uw@=QqDC+%7wozi5B;g-BBTb{91{6&zR` zs3)fId>A>b;^OTRHF#}ufuXlLP5hRTzr~IX!6=^JpQ8GW%AbT2){b`_#D6w+K9#lR zc+7ah19M%;85#1)O{O&lLN+fta6nJN*Dh-4R-~47B<6H#KOevb&x0C?+bdibw(C6v zkRhyup11nrTvSYF(Qv4$>t%$}pz*|orQL+3l6R&zzofW2y#;g09cl@J{#+ekKqx>Y zHN{0#r%~wQ5~3Ib|MtmSW!*e~pTv096ZzKaiauf9YSvR!BfE}D>P(L`5@+gANt}S# zvg%es!T)M?WfK!Sv}dZS*K!|=;2IqK(5-@dwS=kh z*Vvh5@aCXeoZ(>V^7-D*J3o@oAb}6oH9!OOfXz`-vk32lh;ldOs*ir}QhS#k)w3UQ za3i~_8Xg@Ahwz3f++F*}vl1-(ng(Os zcMh~z2B)}Igl(pp?B2FCpL|w{&ajlh9Tgl&;@uc8^cPjn%-e+e33!8DO_tt>e!j~d zV8=97J_U8j(Y2HnAGDeH*X7j#tza2usRGd?mE=nsR~m>a0cZxf7DDTJ?p}&0G-EA! zMc1-zE2eWnJuN}yVqm`x!o)q=3M4Qxkc<8Hy--Gf8p?(lc+%+%cZAEu_d zy7oT(u*lK$oJ(8k5MsH|0!(eHtxA# zLUzY^dwGyBH>YrRcAm}?flW(KC!wZ>H#0N4ytxTZPX6kCzOHp67x1d85Rxkw7FDxseQ{Em1?AY#uHHc6@Yu9wznd8y9o-LJAX%FF@U6DC77h;X?^$?w_^ORJ=tEw0 z)&DScF6OzK-}CbKdA+|K3@q&KdaFx|<92V%NJDB=3@Pq@O(Xl^8LOO9!I+JuB^AAX z2b_e&&@*2+NX{G^=YnLd-GiYT0|VpZ^QwsbY8uB`VQEWN&@4qOwS$90VR7;1qg=Cl z{ZMP6?d{1P3J)zJ((yqVZyG?eg{x`CesO6D8#gA@fbp))s?BIeaQ3F+V>cpU-_E7RqX)O;|$%D<&r9y#JhE?nnAkfbTsqO18}Q)b5tHL7A+{ zIwMoSyRUv20C1Jz|Fb6}g*~6itgY*;@8+sZQnJl<{yuM+P|khs17{B2fL5-IC#i{q zt(Ki|rYmoJV&bwlo8T|V5ZVV%W?zjkxG*}DrLL^i%*ral|Lxi6;e4ZGYH$#SkdW|I zdaKb!V}gV4V~I*1J2}PVmaeNU6R3z=AMx$!(rQ1nIe-f=S(S~uXU@mRmynYa8yShv zCDiCA84sKs9W8h7V~ZSWN-XOrjgMV*q)NvoWu`6>vd^&B1ZZzqOlC1HyI0oBK3E<` zCSGZ+;~L-s)vi;S5%Ki&VUcm65D}xKW7fI1ST`82j-Mq9cy%RW@wXdk=4RJ_Wu{~T zd(-&+AMYHU3$~E%_OE>MOW|G~F1lMY*$0s^8p~R(IW~T+h82^|F~nWOd<_sMrDOS6 zU8@bIJm_GAD<}b0&8Mhlnj`l_e`9IUD`mD@W%a$Ck#K82W>~_ncz2JMt9I>swi^i* z{s@i8uy5&E4M*;YX<%`vVW!E*mV|A(VFwMc)H&zP?0q})K3i+%09`~yMX~74yjSr> zdy^FvnTb~&HQBAP$3S6wr=q6bR>B0uw)#FX zXJuz6WM@x^JT)~n`N}#uF=f7W`aBHQnhb$7W~|9E%CrC-q6VWq#RaJ}$pz9B?{9rh z8~lwjCFFVR0+yxH1VGZ#U-0Foy^7e%cFF6+r`Oc*1kFZHq(k$GSnRIWJh@Xihq z|3w3unWm$nVqQfp>d8u^Q~=+J^UZ}8x{~ME>qP~e@#z8y)Pi^ZH~-O0b%LI%>=hkL zNeu;esk5~iWFjDc)UUd0thZ8+(`EE3on~{qR-I;hTaH9%WgQK#0+8hbxy{nIvuW~` z<$HE4Dq0Q^FEO#Gs-v_t9R2VDi8%JDR3m?-^o}>{3QLo?Mx4w{f;IFTAo@2R_sYpW zU=OYLBb^<3W)`%72dt~Z1w0}mi!44tkWX>dz^sS3$!f17euOL_EQ)~Mra@lNW~zg+9+LNPO!wfQ6E9Y{}g((k_MUL&xvGvg5t9jpuxmNA`{QbkjA=3`eMMvU>IfZ=I zupg1dRL=eie0g`=>WJz^jlxigsfj^Ilgs`IqaDLK!H2e6l~#G{ffd{Ngc}Tl zU~*+nlmWApR+|gEge5aFU4NI~i#46jlJr3&`#zJ1*fR{Beg~&+#@6f*39BbLp3h!p z#>Qap!~`-B2o!(w1O2p3jP=H=|5X;0X+5tq4>&R{GZmuI0)JM}FeQR|nSCEcQNi0{ z;9+fN*^Kzl7=*xC$Iqo9kDk+Hi_6V|4X>_g9aOjdvmQNO^w~uKf%WYhS4M`8LuWE& znqou9>#MIj0V4;;Av%_JSXfy7*eAC7GKJvKmSLk%3hkNKLK2bC%Zz7UDo+S#Q0d4< z$DnjmEwhADM3YDeO$1F#b_rxL!;Jgov?aXTtKz4)xSZ3n3c+&2-jPM=!x+)TM&_Hy z%w*THJSt}w7dL$gRi)g0dI)43R_mJ>f99Qc>NUR1ZS_t2KqK;;6X`WeMmBhE(!thHFm zP0N$O8``-@d0>Y1Px&ArV=Y~xN{l5E_FtyXiiK$U0KjT%_pO$J0EaYr z^>XH)lVpvh=Z4$S1qrpUd+oAOqcQ3=tm1_Ol*vCN$z{kt8fja*_{Zr2laesmC+son zl4RLx?RJ@J^aBF(6~3l!#NG)JEWJ9V^<|t$*qYB z{+iRuhgP+5dine-@o26Gd1%Ulq`DLn>%g3fw)#&tUuUb=+p_|tjxInkm-&uJMb%d1 z_IM6943)@U_oR1mH0Xtf3aJHTWB}n-MP6N6DW+Z%sok@OmY9&Bbj*XxW~D0i{#}-* zRxtp_>V1%E!=l`CC*_a&@|v((`1`Qr0s;ka$-|bF=V?rCCO^E0X*ML;cGN|3m_bf} zG)l6r6fsXr?K;{5#_(XrZ=&lizX~Ip!SzU_OXcY0#Zh&>pXmkeH}aWZ3Hl+^gAO^1K=G*KDVSA+xuOvXi*=IT+`x ze7}HYFx(vLGb~`0bw+I1HBjx@w7-{}nCA9Xyijx0;qc{g`|i6=a5=s~!j@I<#mYbY z7P;Qk=6*IhH%`Uz#mK^9DDREO<9z%bd+$g%mQl4QiKk3I`Stw+WnR*Ucp_V{HQO=)+rY)|iY?X4cLFdNDYS~in(7s4OoJH26tdFOgOw6FU^%MD zpK!YFJNKgZ^{eGVdGZJ%FfY$3xHl_RL-Qg;iVivh%Ovz7@nM`9dF z$ktp4%?Jw${Xc_fn$2Nt&)IU+y`wEmKu-HPKI;?t#Et|Xb17ZQSr^sEhW76x49uLQ z!FcL^2|p8e4%Q?qPA;w$&)(C0<1r!J*g-4Ug#|`36!w&sMiJUra{mXqu4QLlXa!`% zKRaiKZgV@wni4uP{Y3}P4af*ELRUuj;`)Q96746Sg%w|M5FD;wvk5LI7BzFu6_JiD7|?amdKX`=*K@ zCrtem;X1`=JQ|uEX3_(FbXaod$)Z>WBB!|ca2re1LXmf+m zCm}0i1EDP500P;d)^vB)v&Y|75m$Ye3KYJ%ah_N<5Qt*+S!!)vLxo_+u6V6nSmMgCeomLuCdFEyV=&3rRR7(Y8JR5m$ z>Ux*YURlHClzE$3_QvNicZWnpC{-{^S7hDDd^LTm5mW={+!3&1-b(YuHZbQsN1kNT zgH+M)c*_;>Xy)>9e_E#%R8cC6)oH_7x9|n^axM%I&3*S_8BXC#{4Mn04onU@>tL*d zlqhlWsDsh^ib}hGP!%U?X@P3XlRT<)eB11TC?i&$0mn=*jGithIS{Juq8)!GE4Pt3)@vWpl1H1P6ru?k{O z&CbrsqB~|#UV;5(Hvq?Y~02BN~ETEH|<)z^i`?XN9 zq2r#1EX1y*K&$Jo+&a*q?8*GR>b*g6p+D>1hB4r2Y%Bk2b=mMVTCz`I$hFspcB%&L z7vsqxDmi`eq06o9D33QI1tcB{CE4&$gEibl-`jF7MbFz-v!R!h7}0@3swOY5%rOt%YLtj=#qS$}3GzbI@G{uGceG%P3m3nr}* z9+V-(?Y~1hcZSLAClmQNo8CM9-WUs`DE$R;g6!00S7snDuQ!Cgbas4WV;^ZP1=BlT z9RTm4?Cd!4{3|p|ssW-d(0j78{Z)H)aSofU?K}FOVRbH|$71BD(3DtwOk5YFpBkl~ z^NlKrO8+#|;PmM1C(L(TWI+{qNFxxdSq5Sv8w=F`cz}S+yjqn*RzxHJ-3Wg;f#mS* z=7xa>JcZrk_I9JgE77#fOeg7_DRumwXVf9%Q@j&L!x@vTCJV*5#mD_P7tOoP&PU@r zrmS$Op~BiuMz?Kx+w2G8oU}K*lx`lFK7FmgEq=lZL5;`qJ9g+04K)+=ugL!T<*hLLA%>A`Y>?MOU5W8zqV?^8?~8 z&pBQP-~P#wmW!^J7KilEVQL+eJHu!krXU|0ecvmw@oXM!lfmeo3^p6rn^*A|+yN5U z%F0U59a_2O3{EFfEC&5(SR!9ES`A=7xa`&%_I#Gj;r&)`F~tsKjKiBnC;Gwl^Aba< z!*A;kisyxd-O?Ck08y`S-SHnUJ^w`&r__Xu^f>ynbuXU{`?KFeXU&fV3KkBsPtLFw z*Ipi1{7}zrmmW#p5l0&%na~b{9zI4kc7a3Yb|H;LUX9GH(BxF~baU{`Opp8f9mVsq zReS`M@Pq32_{8#;(Ius@M;W)$DlC0Iha^(aUzR*oRPJ|T__l-dd5(axwGzc)QUoz!3?H-V9`xTxvo zl(QJQNK9(U6;&RYx*RFFjQV6FD;IUqGgo+`lwvT2PN(6H$EEn3=WUABOKk%M5wXG* z<;|G}y!rM4(?sO9PV6^eLQbwsiZf)MGHk&*7%aJRE#jN-3<=Yfl99{KkOWbClhn`M#FEmI)$ za(^cG93U}Qi^NwG%2rQ0T+GjtIg6Z0Q_Ro8LrFPgsEtsY4sG=bAqcLXIGhpj-_ZL5 zj&wZee-HnDriQ;+FY(zv%)YvGY!d30w@>S=^ZE`$gmX$l;!rK(=*Y;ESX5Z}TPBsB z)AzAPX@_#@ZWENb(5TfA_5&I{z{FQ0so*nFC4ba6RFB;Y?*^BF zEH;a)dl9|bcSUBzwU;=L!=qe2NL?;>7kwkEM!{VcBKV$!WmzQ9PT+$^b|6JJRDt)4 zp{R!g|I~T?@xo~I#a3u)Idv?+M$!HRtjDeo!RE%LYd}!P*=mDTUmnC{uE10-|Ig1cb62gct(;CfP(E#UCrfcA z92E&dcVlQty+J$nrE4+t<6tIAV@GLWnYiKm=!x2KFJLzuh?;v87_`G&xt#dZ4K~pc zOeFAA(?5qMGODZ}81yn+UyrEpU7cUUVJ()8Ua2nju1Akm3MBQ9RXlhMrgjhfuB;3i zi~sXQZLBnK43Ghx9wJ5*sUzg{V_3m+38)8$gk;)7wso}8?%`tSgz!mZXqMlZ#m&WK z_d>Gt*a(Nyk(fvZ370jzyMXz&#uYRl@qkLmtEnN5EC@89prMImbMb>}-R#v>`Q;sn zUnm@?BbgSF|I1l-^hf2DudD9wW=PUR7f+r8W%|_?jr)?~o5lyHKg0U`E%ha+!`Y4H zTta5j(qp2=Hi6^t3=GxQFH({$%*>B0W))xqZYShi4Y0YmsIC!8>>)e5`usjnUaSF7 zM!ps{llCE3+te@fr&GI#V({2V-@;GA# zdOH-cr`(*#$k%1ddP#0-dm}i|=GvIpb}t@b@5O!_lds3}sB1P&3|1CA62NJLEi6O= zqNwYJI_FldXDU`j`%A<3Fq$&oo~|T9Cy*kQA=BgG;URrv4uS5>&%ckyFHEO~M@`2! zg-nb`!D0Lo@6Ky%hzT!HD=|=5KX%{J&yUutVp%tFhMD8TdMP$ z$mr(V3?he<*<4-qQt&Kn2;FN~VIu{>E!A3Pt1a}8_i>yZ{PZ{%R55>MnjcADZMjiL z72DX}>}rEEHBYp(aWT~q94hXmUY?$=EJ>@%jHLA3=WUdfm5p(G*L#MP(D!a6JCqfr z;^9HDnY?Xer5n1+>al;>Cpppl0MM!87kG z#2(40f;zSEekDCkJhH86_ke44G+T#27<=ztyRRe+x+`s?Vh-yZu>1(xl>y!i3o|1WIe#YmvuOnRCUws2-`lXi>vJ)Dbykj> z00*#UHbwkKxK{<6$ksT7+^&+Tgh5!dM|T7{_9^Tv$iLCbi7WWNRoq*_^5p|jOe#8_ z3)B%S`qn^A)2v4irfAj*Fi*;*g(W2?;$Ih3Q7IL0mw1ylk$PNl%ao!23s}KG`hNiH zKbQsMZ3CK-yxdrjc%s9OK(_9cEXz|tErD+|ve$M(wQKe-?bTJyOkd@(@k;!}H#^Lo z(WIGNa(_Lel)@A`JSl5xI4}|Ur-&@S^~xH3o}@6}_0`^V8{_|9DhL_lPnyenG{rcX zx95#;?ID%Dvy)XTecOK+QcD!&Ke}70&yOEV{3^?>%mzpfN>;h-&)eX2a>!i_mm2Bm zomizltzO3nnc@(S+QW&+2#VFw(J4^K<;VY_6hk5rh$@v<0fXx>(<@t>Nc~#bp4dna zTn`DfZeW? z=`dzux@=_X`FVIX`+y+9a2cH@mzb!xhcMhbZ#Kp3f^1EF{qEy=Zkmu-q-e7$KN*mD214G6_<8dK56EM6hs)7(2dn}~gWexIBxQ5Xt>Mr8E5HXYC5!;9m+h6B^BP;7nAz&HXnYs@bg z7+fy2Pl7~T&i$UfzA}^yuP+q@oE}WU(5((NsEF>?;{2O${zR)Ut&Xh(LycC`!({2N zzvzJ6tJPZ=QL}ZoIlevmwWJ1cPS61!22j5eLAa>i`=T>~Ekyd@Y9_&!(y z_-`k6e~hb*B_*exK&4aB&=34U6R1RtGZJEV&2<{VO<2}mt}{cd29s-hC>WTXR0Dq@ zcXxKgrjioMp>jABltJ)gYsHsKoyFdBKU*~#`9*%Z+hIO|d+$LZR2*hJS1hMn9Psg; z#^pj0ki%pW>I6vtBCUN?q**mR#b_034No~XN>h$sy+I+TtKuyEWwspZk@My`&x3tl zQ=BNn#B=MG@gIYRynImjD81tcWaQOoeEquc5qEPqbvX5~?h@DI<)<2Y0H-{<{Vxi_ z#=i0Y;yJrhqF_@pHS^G~Vc=(`%d)HKire&dNYcUTfY%k^hbc_?)?0lcVPW528Igy> z?B!K8w6(zSX{<@2&dcdANv+Zh*7XL^S@re3eLJbgB!zZ=&6|g;x&|tsy#h}^y}MI8 z{k2zFY_3^&DmF*6kqqIj{W;&nM&pz>Asp8>FxlI9(t97AE@V}{S^ie za|3{EkOEJlF9Ir1>1k{>Sk--feO_;K3IbQ!0t!vuNbq&<-uu#3NM#41&wnHxLWx-c zi~-G84fAz|xM12Xj&Z>M(JZ?96eRS{m!D>5TcxO~Ny#ZsqV18oj+t|Z*Vrnv?_w##CQ%4>A=+QrIB2u1*+xFn7 zS#Y`MyZR9%x6j|ecRNQWzT5|L-N~WSO@1809e{_1=uzdBR$M4mO8Yl|zO3lJ+HZ~? zbv-v^Yh+i>5dM!hzS%&z%R5?{nmbV%lp)hU1Dgnm60qC4%CXK_>Jgg(IySe6&O?!% z*yy<_aj{*oo>cQhHusbuP+rr`bmQx~Z31vU4jfw}M2@yp63;)8G&h(+yS%@8>9)C+ ztv*0QLoe4`D6j$c&d+0qhb8w84thsM;Cp&{e0^^{2#36{G9J6Sx`}_ODAs`5Y zA?IRjWJE|%@YCztTdl(ue>NK-F79Y#?5Lu@n>Y3C(M<4|%57ttZszY3jH|0FNhzto zm>6X5hx3@|Xe9pFqv<@zW)#cJ^9r>J^`rSRjQoNEw>!l(uOsdGy5G;Wb#=m4R@5Kn ziOS=X?kVdr3F#Wm2VbZe>uLnHaAF>Bc{fv&ON0Q%asn*8Xt4Q>(r3$0KeD}`yRn3umb><0l43Ju_^PoQQwhb?{UE;x&-2*(OFOd?D#54|eID|P z_y-~lV8GwCUgIDZ6Dx5S(ADh4huI zst&1tsAD>DDQc^eZ14(q)-*L8u(|2XLu+VgG}Xir@C+iz@ugG_+HbVgekP*|A*VJY z<>E^J%0jJkhqEe?CoNU`D_@1As5B>7IOA775NTh7h|Uc z%I&6K%1`}5j;lygMSr6+vX+5MA^Bu?Bg_C@D-mhPUaf`?$Z5FLGY^a*cE1>HG%_3-`;8~l1{NsmM_be z(dc*gb?>lgkrZoxWVwZD|rO5K>nD@?qX669N?5z#AAC;B*72W>1PB ztk29OVArk3m~r84(3%WvLh0Y;y>Cwpsgx%d3H2s>nYbZ%2oaqFSe_15}XcIvwF7uA8x`1s$n^&S_Scx~=-OC|h9ji?zh z?ch}T_Tq3jfegGFILglG8u$ShL>z9+KFrgdmGaR+%nG4aWwOlxOdAoS2b1>pLinKR z%lM^`sw%t2^Up!g5k7aIfw$%Punn~MsGR!xdZ}mq%xL4L2FAXP=Et4Id;6N^T0v)V z2zGpVaa(C%&-LWJIxn1ry_fqU*1z7Hi&olYf9Z;rVBc)UXLWQGJAX1kra^ZU}+Iu?mv}9Cg%@ZU5AQKRX^vN zaQDougz{1A<1gg>B4TL;LVI%kS)I)qo4@CKqDJgBK)==}o{BpWdLM;^K@tRqo<$Ix z%KebAD0@O28J_tUVU^mOh0`O~#Sz4;Pa;1K%%y!CVE1#)LT}2v+WhvgUw3n{ky0p& z-oP1-X5g=({{1Y{dpQaRapg*>$VNE?e@_nw^>h2!#Z$Sfms%O$m=iw+xB#_b>#8bR zk$_C|Pap+elG4oJ*DCl7CP^09cGu%xz3+Q!LW``ez3JQ(d1)gCX~pIqR=brqOcaRj zvw8$hoa`zb1@eG45-RqgA)~{1Z#NjCC*|h58Vdt!4@#RHh?aB1FATo?X6ZMk3hJPl zRA=kA&FLf;Av79VLlDr>#ie2|Q+5M;&p__IcRoOO0owlZZ%^ekvK$@u!1_296@A}r zu7Z&)kwFI!Nytl@)hO#gFXQ~7j2<2)T6h~7zU>b$aZG z_h4z<)9Ffmo7LYvL^%uvNiCJEnDWJDs)K{eIC@%%e;x*s(t=p5vHEmAs+*Fmf%8OO z2m4rR7si+-8ZZxrgc-_BKsDPoA4X`lIsA@^9cfFKIOCd}wEN4$y zwx1o-%y~yX$H&LW75@lPh`ITHpG`9+73CI7ALRC#brf<~Vl6GH-g{z@VNghDC@HuB z4O}?$(=vHP+Ps~F2bcVLXABRs7;ES#9gB2--VNw-K@^RZ#UDzc;f8=)XCepIztl7~ z{Y)-O&xeA5)sewWO)}XD7i{6yGP?=U4Rq$!k%H>_@Ts-6%tMtD!f5V{@Gqp~ z3cn4#Z!fkCQv2erFQ1;CNT{gbR#sLz7$_-WAs`?wA0CFldw~s*CJMc*3Ij=7=iN(u`vufW%PAX@24s5CAoYUK1ydW;5h0Dg}eA(@!g!<2!D zmv@@zK5_?UeAycL%EJh-(ldnq#?!i6kF1o1uEQt3#ZAuuo2$WRAz>h~jEH5`J4Gd{GJ3pt# za&aM@UV~uRA_!sN5Hs1|gxYww+HE`H*U&xFVdUrz#8{dpGE(2q5_PijDq^m9pfn!! z%Vq)^;Q6CJwyxAd)4>(XiiwG3-=ovh(;qEVV8;>(#DW>@#yj}_EuL`CCeMtw{L-t` zZ2#KQ*ohZV3=C=ac@a)DKw`kg<6PAyrDwy2%?JMd=Z6gBK$-4g83|gT-ku$Www@%J zCl{B~Gt`6iW=Y$H-__kIiUT0{Mr;8nL(S4xX( z@icO9whA1Xs6b9vSD=Fb{FhtEB{kMz?5clbr-%l@Sz|$GE~5R#87d;8%V}Io$jZlB zT;+N`UfaF#J}>_{N()B=uKjW7^{TmlkSou!+qCh z2_2=n7rasWofyro*E@A4FbzYy7jL1ZA)p?eXPB42Q|XRD3e2D*rdh)6{I_+XRA(baYDjZz_}A8cp2z7Gcm z2I4RoLrKJwQL(d7zqGV)^1j{9;YXz(t<+Ou(P{SwUQ`IbPl$vfZKLJ662yoHgUkHi zzdgaPe0l+|k5`WenGUW)Dva+D7?j2XkzYA|?oZvOjOrp+MmBME4*9~l1c>@eH8gJc zX~mqz{q2cuD}SIly(7?8K2^l-Pqtxhsf{8?Q6qSCe6GX(ZmO!g~%&@+<&CNox4YO(OhSA9{r?|~lG+P@WIL6KXB z{6DupH1pQO#ImaiRy*0ieh0yamRHhP$CIhRc)-3pFS`x67*{=V_`jS`ufIGua=bPS zJsVG)zA(O5-F5hN-gGc}&|)bN0T8KI*tEy9*P42RsL2?eCe5=V=U@m+8r1l>JstHF zvlsU{;D!B2ik{ydwsyhc<=)xLMK_TG?-f)R*fl{JdjeHd8-q9C<7xer>ri~Y|J&Wt z)r#z?}od6 zJWU0-zDUFo#*8FV?t(p*KgV+=T$v*>44olc0Uy~@e74Js;G{T}a&LYgpQ0ko2imKS z&5QIvTUk{ZX$~v&=Fq6~^~tBs^p4Ay{wsz=7;#HgraZ&|g#ltkx7}S zfRxL|%{*W@D*ZLc=NV}K>U?wKCwVfeB4COZ#x3&raBrBocQppIE87wpDAVKKcpN(F**a{Y`m+> zvuCA9CwiEuEZDd(Ih-Ab$BxRFZAOxHSVF@uzbzEJIxo8yI-RJXSqJ}61p$wiYfZ?D z#Mdxg(v>9}trrmV_4SuKyjU1$96Il?Xh+E;V&{*!3k^B!R#nS7Iy?D18mGsCe!m7y z@xT1=e?F#^SGpU-bNIXF(7k`F;>H&yMRSn#YK)ZLfuBfp6f@yM^q2o&`8#r#rVA46 zq-9lG4+BGAp;PDO+R$#R0xKICs!g8><7+OhJ$F0ooyo^b0)I=p!6%NJhwQG9cFd^y znif?p+=ErG$OV~0uk+3GWk!o1yn1I^-!8aw!WqJzty`&ZsHj6NPP><2$S_{1Gtt_(>D^R)aU-CyDnB+}-4yqnj<>t27DqzsHq(~a zu|DqQPBZ#?A5b}McM;VR!my;Oer^=`tEh+qbe##6$3LFQQN7wlr_*$q?}LR&+W_ja zt{N|p@G7evlUIr@Cq1MeTh@HN8X`&_jW?6uAhI^_P@_VO^rygN$8>R~$$s!YWV9Ms vS6#oVR=fTVA7rQ;PE`NDDrFw~I}s_UXl7ivg%bQ~$R{Z=c~PLSVbK2vo7`jr literal 0 HcmV?d00001 diff --git a/docs/shared-address/images/current.png b/docs/shared-address/images/current.png new file mode 100644 index 0000000000000000000000000000000000000000..2fb79edfcd97c6b88b7557b870c2eab9e0791c41 GIT binary patch literal 46926 zcmZs?18}6#x9&ZY$;7s8+Y{S1CbsQ~ZF^!nnb@||amO|$PHxZto^!tY)xA}_->R~3%r!1sPdODU_@WOd{u#h0A1Z@!#qGAKs!ikIe+;D ze$D0c)%krdrwyQ51m1XIr(QML!o$NnaOww3Fu@wO$QrVUMwI?CCCwC;(?YKOW*i@% z9q{MDrGB@H@?B3y54&FKMC@ZP$vZb#Fh0OIjv~Kh73|nDQ!t}6)Wr{G3w%>JEOgKD zxG$aLJ%$IBf|#BMra3g`S3x8UOCk!g(*aEX<%Tdt-sc{i7H7{|JsAn4Z8@T@(z#21@y&3Y_(=4-CCht5B}+}SA6TA3l~zZet* z%yzBXWFnJH^Gqj1JPTm+i(0*(c$^hjhJ%@7XHhl{Ds_Bmzr@C)z4K1p;5fk^E32@K z9DVAos?K2f??hJj7%lY{%+h?4;Z2`k|2nsMXsMzFsmztn?On>Hsuuw?#Cel zV$Y9C!d{%7k+3kJw;1@*EGLy~HItv>xCNhuEwBi<0cZghHUcI;=U4`L*zl?5MT1&{R z1&)*ud-wRbb#Q*(NpJbq+OAEFIVa5I?vEy21n;Np<(t@qzthB7Mo68G_%QZ-zDSsB zf$8+1HpU3_%Gw$MA)iN`hws67N+3F|I@S2gRk$6d@JKBFm@E2Q>duV^%m%a>huy~0 z-e>};HHJi}Lk4p|l;r5-=xEuXskk&VdUs$NE-IeRzx-^&D zT}Iz2@%OQKS7V*t2N5)FKzSg1T315i^hoDd_-(?3@CgP&Q!g+T@0z2Vie2-!w!R{}s(v&--5;WXJ>Z9T2r0@#8N-tc7KppWk4}`Ikf=U_n z-SuMz=d7ZNFo5Fac)2RG&h&`^MK9}g!lu=XurUNG?xt@&o_8CzAuQ_AwhOIAzlQ$a zQOAA*?(x8Xfp}9+^W|UB#m^Wi_a-g zi!}3lplp#DRNYfBFGmdLK=V;PQ*EtIk?b+R4BM`~x@6*UgR@XBXJ<6oBdffkDuC*S zXsiFm=|&jmP9@Qh$E}k~gylOJ+0&~?VJdX?uvXz+TNJRzbiOspzyN`Lwl+0YJMn|*0G=_PiP+Hp_V+ji)u4tTG0eIr&`0VMh zdVTU>adOx=HMqyBz(BB)dp>%CW5WBP>XrNavHqc_Q)0SBg~v+_Syi!R#f|vCVoCyE z#~$~*@5KKm8^-CS5*No4i)sp(LDNnk#SRZ^Td0*rE^4SX1p62*{}$I6BoEmO0eWT- z0vEmLKnG1g!ygU}$QxR(&<*!Es%7P8tOI!wM`VYWIiu=&#Rwi1uung zC(8{K1U)4p%!)uwNb}Ukf%4a@x; zX`RHPXn%b2>4tIdy*HvpCMRd{(fw&=hQZ@;y={ceFAt+kghb`|fa3%YqicqClB%?Q z<1u7aGQ_+hK&fkHvVYV^G#%gHdEVXOnVw&hs@;u?=x=+4nU$DYrk3rR&IzcI?`pXO z28C1)P&I!ZG!e0)!hFYHmU{yB%j}Rbj80qzB3#JJ>@4`+@m6IGj&}y);;p(LFWdU2 zNSdMj?XvUJ8KbPJ<||c~!gj?u!+g2g=Tw1twM%pG{OHsnzg>ZcxocpmDxW$fKBypQ zFg21Xe{AW}#`v1vU8C zmtH{*{w*1eXOee+oZRsWJAW>_?Ru;2hd*}Wo$23iaZorW-!p2W1X;+~e+YRXcF-k^ z)sq|OCr$p=PBTvDBsMo29ik`Y*3$@?k5ArrDbrA=#>EjP$O-Yh=Xad$$qf!06xJ{( zRHW33pFZhFxR_=ys_49Lm(j=bKF0_PW#gC|==e?5ZlkS-TblNOj(8LsD-)nrD_-Zh zt@m4?prj(fdRlP)6(pR(DP>oiuD|Z0hB&8Jt#K+-V4BaiGM~Diz>K_q&ONj#;Kg5y zJvE%p))Bk-dZ$eTXONW4kihtd3ijwu3^zfut-nA@LVF*tRfdJMQkp@wu`O*9$Ag4q ztE*5*bUJFLO`f%gYM}jYy$)4R(NKc*h?7+^s=2N(gZ;k3FVk_)44zzTa*ZDLmi5lv z4>zFLm;M<$G#8lKv0+(J9w8KwD=4UV15d}qG*35Y9RU@?n7W5!sm?HW1{I_5^e14E ztwP%lPITtC50<1WJp3~=5=2n5F;)XJ5=+i&|6aeosM6!w9d@!yUGzaO#+C9YwPsMJs9ZdjScM%gC5wU2ba{BZ#}RP5+R|p06#2$upHz zxO|=9kinzHH>+G}NILlJv2b~?9d(pnRt2^v6hthk5Ek@A?ura2YJ%4^mb|o?t>NEs z%xMHw0PGUpy&f4mS1N6A$W}xX9Tp-Q7DB>?6mm+o(FdC1HD?iVx;KwZ`M>~+t zro9bc&+P{({Y&mX@%$|0dMrpB&9vIE5H^=>k=~V`9@GX5j(W`><*6zvgyS=5Vxu+% zMGds1e{YcQYSD^#iH&f@Wi6!#@$@q@;% z<0N~_ZD17{U5~BD0*g>;ZDvZB_o3OIz&u&-?Bd1 z(A3tm_MU4SiAF~SrA0kX079TUGR+-9Acss~5v*gh$JPJ@?X6ksv75kG0KX zKw2N^9!<-^Q(Hsa#0y5y?kIUG4xVisrn^>*eI? z&}bEJZijk34^!(|BVizp^s9U%=K*(&nEUs85b(Gp{UeY#YLz6+%1ULbt$rZ%DXF@C;znsZnwwZn#lz^HLRFZ-& z!RMI;GEBX{uS3i`Uxr-eQZXY0-mNRJ`5+qM1@pr)q>gVkxE%eu`jC$f+Qz@m4!shJ z4yyBc+*WSGFv0^*a75bD?T{XLymof@P0aXjvR3DI&ZnjW1`-R%O17z>O?LX~RnLg* z?CcioHd-BtYJt+TrD?KM3IO2}woz;E&yV-g7R!ahpAp!SPEHNE`x`JM;g6FIZY_RC z+MN??&G+Z4D&sl%gU!b&Wr0jI76OufWYHV8o?6tz6B!nVBXNWa%F4LhB*r{A9p949X zNoEeH(IfPGy=d`D>~UTvX|sLN0_Zx$VND|)2h$T16JxMjFT0GbsdMPS!(z-@?=1F5 zvqC&p*_vMRaEX*LY9k;Z{Hao_OeJlp-q&GH43944BVviY{lbipu_PpY_o}P)I4}uZ z(d$*imoE0CIrB@Oe-Uqae}X>aoymSEO~yPen4DG99GwuleZ-8mdwo47fOp5(lFdRfB&kiOasz%cD6k040*ZCQw300BanvqhN=sXL9Qd~l))Z%& znlEAtATunKqCIOCWW0?k4z;@LL)CXB`hWA>X0XMx9$_n;9-G8HHZ&Q@T+HBoc97Of z2`f_NM?*(13*)?nui4C+xrU1^w!3litI(Ps7V<#Z^_ znTG9hD$b&lKa^hx+PtM+>V0=u-V}0vMaCjjxL!*8AC*@I0N8R{FA?zfHyY)th2`qBH*B;_!d8N*s#XPX z-aF*O((+hOm#jhti!_5Jz84szS++j!6UDUTWk*z~MI$}4t1?Xc&W6ghzKoDW^ZJ45 zyI*cU3`M2;?0_L45CnT7$geE7p&s%(4*q3GecIgm%G>USF|xb75uw7x?05bMzrT_v zkb!96_XAjL{xN~QvBrfqm=cbnkN|O8(3YEk0DvKy((9G%VTpmpHFFVXU8oRXL#oM` zWV9-o!u>SpIOqu5*NMZlISueP(LSe&e=(m!w(GH3drJYx-~MRcEg z^4*R)rzm=bFXs{nWi~xt6Oub~ZC78kCJst%>kvrE%gsG1`V{>k8h*G;ac7Ad?lrs8 zKpGPfDLEYc`SLgg;HGNMag$~^)JPn{)$>d@%^-^6Y`zZ+F_03G2Rnl*!`p$DY#hSMu};~LNL zdI^t5B#frh{5RZ@EW;aUcQ_k!@Yj|+!#PF72x^~u4pu>ObOJB|%H7jO#b9yDwDAxG ztDel)*NNYQDq>kY1HG8n35f(FIawSyi^ri03T8irA4$1BEI_*IYM6TjIJeTuDSN-Z zJze>*;c7qpTzbb;bM}>oFG2Q+5z)CVDwIHbEn8v|7t!OR1A;vaE=0X>*rUahbnWUn zF4o|}<(3UU!pw1-NssfC^NZTlRQ^I|h>du1b^EpYIcsRN48E12>_{=gk9UYED@&C< zra3?_C_Z)3t%wc1Mi&;AhIp@T0)=TpdvJaa7y(tRp0j2!3TG5TbN{`gQ-Rio_;Y+_sLQ>d;mem`*6WNx6wINTXC++4wUx=V(1 zMQ)JnM>^jU6>LmoamTcZXkllY4_09Qi|K>N!jOW-c5^u!uM(YnAFOLBddgICM=<@R zYVOY^RC~_3@sMqjiBX&}mls)>L;U|9Z zS+wOYaNgMH+UVn|j9Zc`MSZjwHiR=C@RgYjNnILFaGKj8gUAvO=tQ8ZJxnaT|1$6( z@<${W)9+|#g2a_;kBJvxzmH5NWr-CA_1N=?!g$0Md#u4|iIkQS?1&_qC$sOuKS)!K z9vn+4zjxwcoq=CF3-J$5Zsj|=WK1r|m+Y!5DT``{3gV@qTb(wGN+w_5NF7>IsyHT% z)0NkT8+nHDS>cJp5=K}-gu3LqDFf;Vd7$(d4T>ENH-4e72{y4O4^7aF_b13ypQ#4G zJ{}_vnSOU|wy}p9Bm#w6ypEi|a<~{^O>RSiZYMu^zqEY68zdA#H$`|9#tk>Y-{0R8 z+_|H-*3n`?Fx)&&5IxX-dT$-28jo}gKP5?wO9S`c*{DgF(bbZ`E==Yf$C?zx`lnIN zh@y8{;u9Y|q}C3GSOL18Hy%>)xV34Md!{?o({V!+O#m5)${?n3rj)Zqboca>^Z?mY zL+O!UHm$qx-GaZ$o|;&)0=lL!W`%?>b1&0=s+0Lq)s2~h!xO8h#bz?`6_!?|n5v@FY^2-~FyK`7EV*qjGa?G&ySXz_!T zw;pVXAn!*x9{dn)+XUc zTRUYcB3bgb+*Q`TboF*|Dvw)zQfAu)|~NA&orpo;~i*@g84k zW%2*;&y1b?Veo_F)xf>fMlSvbQ7|mDeHT)g{|VRvf9GB9OQGy`xm*adTebJ^NXH&{zMwR@ z{;sIBPfShzZJ>j_cWC6w@ONcw_%WFkp2^x|?3C4P(-1VZq;U|$B3Bd5nbIB+6nK9? zS9R9C=^d#tqZ8*>CiiE6ku*d?CXYRFGM|Xxp`x)T9K2-nH9kV-t-d+7*yyQC>}J>dVngX3 zGcKP6)|n`e-H(LOPNHGrK&;uv`SHX!3!@fbUU~=jG!vAmV>_ zbD8pItgc#FCZAl?rNL;&ekYBlK_O`6v3~@9PXJVLYcgGC5&|SN)JrrD*ue zrIi^kWuwKK*7qWWg}x}LUZb0F6qft``k1#>B9|3pN{u=`(cIeBCfDJ(HyqIEr&Dhf zA{>DuIg|Ut(9$x)x}&hLP+zM<2Gom;lJd+kG#=m@oYor1v_cx%_YCG+-Nb@aF^$kE?D{l4@+@V!Z`&Du-9&v_r*Chpk1<{^@$hbeHGl?}bc> zS$3D>o_OExP*m|^>^jC!idMc)7g{?)KXxE-DaL8GHW^CLHl1p3PO!X|&$LtM&;Ifd znomD?6jf8x1F~r@G=Be&jcDF{ zmiGz`DJkj{R)mncx;nRPM?S_0fG`2Mu5Tf6DGk5VT;vW-^?@1Q7Y$2aeS(^xO6#Z5 z{b56RZt-sT{WsD)1J2dX6*Uz9R*5t1G>*w*T^sh^(%RaoRuB8L?!?wqvj<+i96pna z?OmRaT>h>CmEAoVlf-z-G+Vjm3Jt_$miS3os;18amk9Y7n@1K8ted~@Bk699VeZy- z8mS`;mXH&7x+x|r~q1^&A8T#K~j zfg`jZ{P|D8XgKy$;YIpU+6nkdaVxR5VhLP zC?Tyj+QlREWsH1i0{KM^0U1C%6XyGbyj*$jPPA59E0wPOH*9k#aF6$ASUtZ^-*t}q zkklqeq>583^a)3qH7+Qe%nBCX<#+hA&qB`XKrn4wb=p1oqy zEN-&%7zv34lvD_{<3ZN?stnqzYgSg7cf9lfCQys)6V%R77wY-5RDT$#k?=WcF`>4i(1P_?v>yQ&+}W)m-Z6x5ENDEWljHjU;q3$_Y*I1!DySnqie7x$Riep z&l^JMXlCrbHS~vfzH$r>6qhH7KLm-B{|n7_#0Bd@nfv_OD096c?`16c7BKMVk7M(F37wgAU(G{L^)u1cab$>>-)4LoxGtr^4zXB zBAU0}0Yu+%^vbMNO^c-^XGTB7JV{1=X$azSi*OL9xUo^X04wbOcRHN92zhXTwYy13E&6!$cagXxZXte2QF79&#h<534qF! z>QeM!qx1MQtVj_5Y2s4YlFG_7i%V(~Lt^BVCHaY=FtnS(iKQa>n6zG-L6%QK4-&rI{-9SaLJxm07mW9@^4jXz`{hPDSJ*Gd*b~@bhDxhc%%iozYNLlxCYocQ+vCYCjshCfCX0_@_%QJMM>kY}slFeWI}u z5<1eaX;$-oLm)p+UM`E)Ul>pp8_^iB(LdQ|=CB(bFj>E~IvI{5afBg$Uz}smSl!|9#kk4ux_ zW7}O>AfJFI*r}IS8K4a|v7m5>S*Y2`RF=y&=v(&9+pJ)!TwQv@OY6jrJvmVvCi1II zh`l`sF@OLlomnT!XeO~l?VIm`PEXQERJaa8zYN8&P>gA#1OI(UmUm=~ z1WSps{$wbza9g66u+ZbGz;D7BLfduez2D|DgFT+Q%_)%)tiRr{Am16xewMaNEN44# zi-w9MFYD1)p7dq`TAB{feld=sT}z*7o3P_^QRCg-C|l}D0R7ct(FKfhFIv<)Pmei6 zu%siFAuB9j^z~Wmy6NKDJQH%}C)^RM<@F4FOUP=ABU6R08?cXLO*|*(SrVTW^w8Q~ zVBb5WGqPR6yK9WU{Et`V)`5ZiJ*J*-p{QnPs(fJik@4b=N=_|}GkS6oPfGwhsE>*b zh=xRO>uLfs{y0QQSxQ10WKc4#)ztvQ!aDIN!t_H;v1D9KMeKXvtv-d%*Lm=_H&{ts z8mDvDw5Alg|npp?|ZDO9V%U95RPZVNu2 zr+vXR#tu3mBdaFeY#r3St?L($p8gc6!nV8o(LLg~8&bAhUPQ*jX(21sWKfToyjPO* zztxH8NORyBB$pjw3z}?N6#s%vN%_46%PZ9s^c&~1(>hmp^sA2X3hdN%kI2W@qYa&= za-9%)dx`liZ~WNefvoV-DNTP5d9^D{2z=JM|l zDgVybr!RZ$_(iB;C=_l2ksyE1PN}+#!_ksg4PQzB%_gzzrK2$4_wCWxb%&3WPF>4W z$0Nl#aM8_CtT{%5-Mgd_mrcuThu^FjMT@_6+3SrysH^NS>2Sl97%$P^- z$KMkn6CNx^RB{V`SAKk14>C1u5Sw1foxkFtRsF3@N3p{cxkg1R5}i#^zyr_w*iDR< z6bw|lJv(J_SWZkT!EYnnm} z@Dylr$ywW!*%1+W$-F%V@AcPVmeR65zww_xd|9(fX9BCER!j*U<;D1 z5&Mt@&IpRVlvuCGQxP*kEhWIz8Az)o8i;9N z+O}K;{<2dv790<{KGbNuX{v&kRr5D;tsfd?hGbX&a9|0hpb+T zDqOUT-B5VSrGyoIhTc}w-G}4wCG8Y&7!xYwL53R@zwHiq{tEsy{w?pEBqPKm5UmmV| zH`4kKZUZ1dW47f%xyJ2=(@M>D>flqy!l4;Od5w$REHx?gtdZnJmSzbbMGP+D;yg=%x!{xcxB?k}I&cauw>HyfOp5dC?j zd=_-4Wa#uVHLNDE2Jx{VUKj}wtMvtj{m2gx)L%s*>#9jOn7{5g@v$?)$0g@f8|6#)O+J zOjK;J5j0!)$thUAj!DTCRvf(SehVZS-}gMjwn#m5ih!c`2Gi0LDb!7qvhV@3?gwq& zC{+QYnGACGCwzplSKYmWr6{uZOZB@pmsf^RT~lxlz#m{axMzh5G9o-Eu0TBlb)zA{ zMs0xwZsD!a4KZ|h<6~>UzzHR*lP{u(g(*+4p9P@lP{BgaoT^|q$l>fjJ2ir3*rQi) zk$@E=zr{|l(2U-K-6Fgcb>!fMAoM4T5!(CgbQ$o=BEb(F=&xTL3_jeSQIX);$$8dP z+4AH6gtFjZTN;M9B`iKNQC@r-dR46{5-o+nnyrCotS|z3ER$k6(B4Zec5 z`-QQ{Q~7LNerqBi$W+2E^ZaW6k>{Y#hDZ zF`4}s8hoU{7=Qi|ZIK(FjryJ0Wa9t#UM(Hx-($=2(GVOjxLS!6)Vjmh*&=RC@|$qC z3Bdq8!W&~Wn(JoP|9-5Ycrc^YF(SC<=yo7OOp82!n-2S;Fs8}Lcr8BA*pY1E6NLzngQ>nngTzpU(+`a`AR zx+kZufdH0Bs{TN;YtWqgjp-!eDug{4Nq)s-P(va~4d2aF%HiOA9y?@r?*+bUwzg3&Pqu}kcZBWMo|M+V2rvNs z^xM6CYrzD<(#QVz<_^w9Z1tUKYC@LxSNm<{1^y>4=woW-nFEugwqj5A2cg zeSpZyTr;cLW_MH)>WJ~KCGPp@(zhPnj)1T%PN708HMWa&M2>}0qf1l?o5u6-Rrf1n zgPuI*gI#hwJU*yTofl4@ycHG1AaQz~-J95pbTe=CurS1dCR&Ype?bA4EMCMsz90ET z6)?FCD10`y&c)c?_goB9ulQrk%)58l#*bJdRpQ3CAyF$^LnuL8;kYXUy)LxE+`+|r*I3WYiyf)0AWZm>^Ip{*+{Ms5?v7J zQo*)s@C@)0=fPSjXHX|}&+oC#Tn&L4rBC~kd3bpz*uGhzL8`0IU@OYKaQz*O`iAJJ zZTDKGto)kEY)S4^*Q$@e`ya*hvGc@lsZwq!!H(6}3I##3a*xHzrAX8y0c6xqYz|Jq zfZ$AUiT7P!!Z4U01jw&x6%DQtr=v??wtX9vQ&wXDc{ugDyKxb7-y$WVuJYB<+dHnr z^I86ByiR6)$HU8`bJ25Oc3@^-CPD};6unLas1t^Q;MjRq-7SCGB)~q`geGTjJ7(UcFxvK zhojJHv)y9Z|I1~Ko`^qgtKT>Dc=s0j1-7ln;0267*zB2&K}yO;39K={X3|g)jpd{5 z-W$QBt*p41?dT|xXzKJjk&>o!gKE3pIpcJwzIs0FG%mit=AGvrj?@NongNGaKSXTs zLlhp|7D9}_p{N8K^X0bsC$BNIb0L zck1kDo2XgOY1Q%5U#s~d=RX5FoLn5^p1yOefEjhTDe9>Q3)7TSlaEfc(dGDsrpRE>j9W?FIuNKZ>YJG+epgT<4}l3! z@H6#K#lH>9m4{bna0>mCfJ~c|Xazb;K$;&E1`rd1{j)0vM=fhxRYEp)qBi_>I2%=`80S1zS|wg*v=ljUH_M0@AB>HcWK01l^} zPsV}U2NW!VSR9*l(dAiWZyITZ;_jc(bX@)p#N#sO04;t)%(iLf^KI z=L%tcvN>$mW(B$2&NWv+){2Kz20d*lAtBiML=#=)tO%U~&%Ga-gWK5*wg%&=WaA+~wOV^Ai^?{Y zX>u>vkd_i|c6m8fdITCi4;6=ik}ZjjjxN?QKud$Ups)~?hz3(0tHi0_As!Xt`1Dk| zcrTbD2^HtNyoKLhu$lYW^5l|;V}5x#HU$l;JeIg~|IY#FZy*RwkrIoF;~@M^-XhgO zxG|veAuWzSp0F>Xp97^KlOnFIL<+N}jdVMchqJ9@nuy^p9X$msn+lJFxYE)o$~yCH zkp8x0EIqq({?5ovv z+*m$uXK&?aPMMI&X6Kp{HRXjjnk(}chr5!^T1LHWJ>)^7!>RSq)An{`AX>cJf`Ud_ zJ$m4z>`;yK^vK*Kw$0zi{qCvd@jcIJ;7WC1jOUoDX1ntj*Xi~8rQf~--ZNR`_U5g{ zL7pMFVNJEbnSE;mwhy2}>FYQsB=R#F_AFhg2b-N<;YNp2m0f{|NS!?z%C2&; zm0>YG3A8~s)&V)eKUiSviDjvdu?*d|ojUNzSRO)6zh%z&FeMyS(oCz`T%{Jp<8&hW zmVR+7lXx~<(vCh3X^wPryybE zz>(*Iec-HtgPH6CWv=RsOjJ7IBg9})@vC~?5GKUg`kIdn9d2U>wa*SgR+|tlTl}i- z?U2D_I5-QPZ#h}Vd-X@=8(z=Qv=W>_SwIaxV2|Wj2e;9qjD`Vl70jRfIuo8$vuCr@g<@r5B zeSf&jU15S;eXM6QLqmIi3%TFSX==?9eW-fn}qz2}(dqeO<)0kvjlt>PA(oazN zgm8_nc<)KlvBx*Ut2tTCiDfZRLjYl2~u4P?Xb*4zmEjVd$-8iNZCK#$rH1sbIuMBQvNu0 zBO&r(*t5Y4v?N-OUHiVBVb2DF_#*G8nINCUZ_An=h{Zd#hB1b(bjgvBCyh8OH4ywh zkuxcwPykR$!RUqv>81?oSiOe4nIOltQ2x{rFN`2Me*$FY%IEA10(|A#{(^(!dUWdt zwkZ!T8b22HzV6EwZ~M5}(oZ>=iyF$h5mbO(VF}oqH&N^(4uDFEnt`Sv$k-6LgD`IE ze4GURkp`fIb#PaRXm_r7j4^wbD@Eo82|AQaln*Lr#vt%LKES2zEXDdh^l`N@D)hAL zwbyXpp*;sG{MSs_zU~ka>60}#-(&TuSw{xAGVh-AzE{#$GT3aM90a+`~ql|DGj7iV1n#2EIXzh)j6p)(7HU~iw-By&1|e$5a1ZNG{Q zZ#FINHK_qAYl8$~qugjLX>0tzdzZ}N-R;L5D?k2# zTY1u_`61ntLVZ4o>jRlGb{j7AtfKgMzPL(ryRVz-)yVIs#fngiOLKNJ{3cEXVjt@D z4*{JB;rT)+%D9@I{N8j!G!dqNM-)L2%8)jUf{{tI7WLaEJ8%8Sy4m5fTY@QGOK)cAP7 zN0FJ3!(E5qz~g+j2cOz$=Xl}I{UJ;VNF1`UeXDQNDio0by%ID3wfmEgANfxvONzO% zEhY6=`9ZsEMOwnb`mafu-vh#7p@A}cCiFkLEX0*jvMJ?$=9Ixfh{*FQVgJ{uNJa3~ z^8)#oJVp$yEJRVUX>!CJ+zV33aCL=7y3@|xchgu`X!<`-%QAI_IERHq%&3MnPResJvPM=+gJ&%}0WGOKk*Y>1^zl#e3A==eI z5V`Z?Eu-6X${lt1pbfDyZ;Y65OY|S`+65K6`4(#%W-)JK z<>EO%Bj@-Qi<#>kmNxobb*Uz}>&|;OGKkTJz@rf*<>zgDv&Sw49{JjY5gkE$ZeQ5% zH1gXPNKhzguqO~yS_V#@%X0bS$23f^G04N`;W-`3kfo3wY)%`Pyn!sN{4-hk5uIk$yI>bg!(b8 zwq1xSFLtBl49E|{kb&24!atOx)VO*Mu8bdzM#{BTI@KBRs`K0-X&({7vn)6;*>1BVi8t8q%~C6p&NLmIN>i7q@)N zmg|t+9?luEa3t5oL*3#GLg1)R1D>>MJrML~J_yKbwZp0OOxg2CRp-#AQ6AZaJQ5&l zU4535#yg6qp*#B$l{utTsbU%)Hu+fO_6bj~<9JQ1V6pg!VS)E#>&=1X)S9T^ zPzC|lzSLMTckS9HOS80mu?I-f_BQ8+8TGQJf;Gr|kc-&T=d}C!TkA>I<$@*|l)+xe z9?Q9bKiX<>vgW=nCUNEA#9v_hV-ln>{=-5+xfnXq%~Vd14nkPSL8{s-(Oa{K$7)<& zUf~S^?v4)rvlpd8|dmTdt7WR)1+Fsdl(%WxmkOtMvyi)xE(h> z31h^X5&JK<`foiQ#h(l}+A>%z=up5D;-C0ENxHd3dk&fzP!QYczTF(x|J<=}f)?4p za^Q561=SF`iPdQHZ}1Ci$mogLb><^;LV$8n5t5QG+SMd!69SD4IF@QPG?*$)s0LJ! zkccpmQBbvN2@@vcLoyF8(b4aNzC>|u(M1o11kQ{;F$&TP<&qhWW}d**hnULNiM_V! zmj@VE9%bYZlh}t#`R16+A1N(&nP%Qg!5l4+@K6z-Z>y~&DPz|;9bQ>Y)}MkK!DAV{ zcCS!3=^MS*t>WGcJ=%{POznEo+M!;aqrcWdwYT1R7P*gF#N*rY-o_ zcicdMF6+F^+yW(n@nUWCy+_;3zucy)UZa-{PSXpu`nA;Bv9I^#f8HJKc3j=i7myI5Q{0|haVnh4*?uQ#LS|cI=FT-u zGdq1HG2WYu2AN~hq#fKN5Q)s76xhH&68k@JR$L1ciJcvtiZ;#PHX=@eM&+oos=pFR z{!h|GyZ|A&m{{5Ec#p`-;Qjp@EL2=66gh*6OViSXZRp@2d1{+81@LP^!`!SYbx$Zx zp8D{3a7RR|Q+buP-vk*yef72+maROW6^f%~DywY1d1y=?hvLcZ<05VZZm$Ur;{J*H-Pk^(L2rvC;DzI{A+I z;kUJA!6S+nkMn2j7JWZqOuOf!<)xjcOISD;nm$njeA;QR`KHY*H4%GO5uYctxI(wD zilEd;ZN40lAO)!S9RW;;f`@ZiA}=)*DoTF1yQ5oiU-S&5{Q8c}jW$j5?K841L$$FM z>b6(TV9d)zCILIM->h%E6pLn4$Q6{ZNqKGmmCPUI9QIY*5r8}QEG^rI!A`^eG;M>e zxl-sm+w+w@cEbuV(C=OB#WTnE6Os1fn>>pXTF@34AiaiooaKT%WB7kaaHh&1NHv7= zd$yySx|Z$iSuv+-I0LLt93WUuBl{oG{Z|As0#KOyqp-f9fo1J#9nrz}W=Dso-1gR4#OsNZ5}1JygFPF!11{G2F#9z>iXX7zLje+g9&>08wAPzxG8ux ze?;tvJW2lta`emJFpyDJGA2^kwvxGw-G%Ed7GLOi3b$>ZEwkkdk6hNy-h;Iy)HNga z*Yc8T2*_GS<@I?M@L5H*g68-k%8hc1cpPcHf$@LN-ar48w?%{f|E^XNG&ZJxb6pF9 z`Co*+V|XRewl&-x+qUhFZQD-AwrzK8cWm3XZQJTt-|mC^p6}ilzp|fNRSUazt&BP5 zn4`kW>WG%qS%&kF1+SsbhnjxB#W4&27Ii|A_3O-D?_#H(%n`y?LL5yadj>=s8(w;Z zmiQj&WQymr8f<4lS7LStyX}YrkQVLlh6da@w?b7~hWYUh~dh|+^*sy5A$@Xa4QQbI_ zCUB|vo zAj&<@e%B>gd|jui>+&r zr8;2`hbABcN6jwkU3uOZ^b$UMRz4AzqGd zM|?s!qiz@_PaK#p%F)X#mXcYCuG|(|nJZ;N^O8;x&d8Uk4|J=TQCsBiHYx}h5fSBN zqM#uBbK(OAe%nUUtje`ZC<%A_h%6g!b@-cPwapz4;mUPn-Q zDgEPLPy}r@zdu!eQ-Kvu<Q4~p3E`G65LFc>0dt54MSIitq+R8d)50w09o@^d0B1p^sr@qOJ^oIuoz}756=f-@ zPCO%el2SDZ966PF^u%i^o`u?ck5CLmraeT_I?G~Gjd=&=RR>%OQc%YYtXvOO zxycQ@T!GAQQtbre!I7eooyWJgi45*1Li10&S&%Vqk&5Xv;L*{3Hbiy4D$wN2KP7fU zXV_N*kPhI#u3aET&1-Ay-=l2!9?g)3oVNNQ?Z5yjWU%t7|BQPs84^5yk_hUEgtD3f zz97l)xUfIJjLb?-XPK}2FLs~lY>U^(Uad0a}0IZVwFyAi)(+^5%r|^XYyw1pAEg;4qL-R$rufa|GT^rrM1m zr81Y=yLYY9{qRS0+=Pqzqkv`Cc{i|ORq!a6mE_n!0A^!APSl`ku7FKL|2$R)-unm5KHlb6-EQprvJ2t;|OAQ$G97u zzg=>0*R4SI@BNv`^ZnG?q{o850m41Dho3C4xigYfGKJtpr^)7J?j{-OFdX z;e@qj%0CAU^)9iX21XpWEVer&gZ{%VWP0InC4`E?#X#Ihm4Xvf?0xad|e#Y z82-uq6qT%rjvGjb4O7l6==KX<$LA#OgBApn`>{JY((d>{v<(jxA0iTLpP^=xiu?98 zrW}$t?(Y=}P9xuHS6l@NpVnG*JF;N#EFYhkIy5@t;iRQ*p2Rjsm1Zsa$(}FP{O#I9 z70>ew6QRG~9@}``zj}m)$@E_2oa;|p@1AeJF0$C4Ng(XS&nc9baXuL-^)8y`GRMvq z8MU+@a3Z3FTtIxC$?!E10}s45YeZw)l%Kc|Zywd$Z$uR=RL?AzK~G99nneW#N$^BF zvY^_QIulXAtRkF0poMgL5T6=CXjW;2F8h8-G^;UMO7IOyMMj61e1OUSU^uWK2{k+M z`b5H2Cu@}jDcpb%2hb&)NlCT#9hh)DBY2M2lPns4>yWD<&9zz9@RdBEx-kg^9nK^O zo(`n?_j;oS05?)lv_N$V>)rWjQS|mPwqzM&-klyvk;s19`$uIILRc*KUJxno%a0J( z6%t*5DuF3eM@BCP?lZ43iY8C5Ew?{zU;O0`GyAJb;J$GD#Dzr&n2LrHao4QbF~+S^ zn?)a@fIbieF^`RbdfFHs#}hl=^Z8y>%hp6?P<-mUA>g z@IQ}FC6I?T$5p#H-g!-3#9!Cz4-Wp%gbe^C{x?O!f8pSNio#-nzZ2Tf5b+KZu(Fm8 z$Ob(Jz0A^F)sc{rR!XC(TR9QMBP&W>TvOT|#%lx|#wRB$6paNQOr#_l4HTwi@=yx; zd)U&{GL7z_OY@_kd{aS1Juxd!(K`I4Fe2=BfAyX>eY{c&m_!0!fWHBr@z`lwWRw;&`OcB9s|>G^N?ZUoAjoHQi)%z_y3P#Ex98l7_fhIFGk?(f1R!@-v_uw ztuWP+q9RCaGYIpOJhcvei1zgfz}CJ{IpPyof}~;E-Ee+G--2wYWJ3aoW`0^!|4`;9 z@$N_X9=8!12J;V?1prmaadk8azhIs(RzbJ>!2!M}I5?tkVgSat#83P+gb;|R6&?{2 zY0YLm9R2<%ahgopqU~EwS5erq<7>zZ8o+I3qAns1V0s0Biv#Bz-u+(ler{zn_Yvp0 z8GkVf!L5hvHp8}{f=uP!AOC|tu>G;{4zD5liM)VwM}Q0I2mpT(`2OlNifu9Wz(W+; z04E8(_b6k0*Kp=t|B5{K)CZpqFswFzr`=|Ve|z^l#jXEs&@;5Fc3UTRLX3s)!4NXE zeFsb2I_+NUPJ?XxYkWas?@;dPdUnNUgdfXyobA^EFW_HJH9HGHtD)ec{~!8B7_j^b zXmJArC|G|1M4Hfpu!RK}FSy8je?t6%ThQm!SbpGtXmtKl6Z!8f=RckhRCRt;=`+71 zu`G?#QA}0ul%As{k7PuL0lD$y{i!pRLSh2nD3;LvjF^+zHnixCKLZ0f8GWA*VrL*_ zDjyarE?cn6ORz&b-Bo?gUl`K5zUaxczkc5LV56(S_f$z$?_9ls)`K+%~Oeaz!;9%T*#Bqnw{YuGJaZ$aiC8HS7Y=quM)!3xwiJ9p{+C+y>7YU!05+sX=i z5*&Hye08u}Ai{zwY2e1BBHHeIk^R1ZdK+Y(YF*MvKR2#p&s&Vs5Wlp((es%$n9YDb zWy$3g2eWYVu?r{&AUaz#^{BM-sI%_lEL}ABC5yPM*ju2bFI|3nLr1SQI+NI_*^cp> zVFM_YsiIfuhR?RE4908C)wvHTKG(M3sZDeSbcXZY@DD*D&(!#on zvikC9I~@ya8`oh;v!Qsv1&aK#k9Y98i5Mm#sgY5y*o@iR^@efIH&?t(;D%teqxaRm zMx8h6B(M2CgSr!l&s?wJQu4)q^6C=-R2_~kV}T0e$!;BnTtzyq5kmbTKf4lsOi5=1 zv}Mukx?ItaW%0m=^0XtK?S3D}{9$)FO`7WbMkgza6BAx+T~n?G|L$-JmW{_5_WO8x zM*mKEL#G|f@d9r@b}+{Ol|vt; zfY3_X3OJmBRm|?+UuP^WU4N>zhiM!9U``d`zp@>I13f8p@c+s@9N9SZ=O^ft`LB53 z_h3Zbh`VoNga?*M0KO-M=W4hgW*eQ(GJgx(UfS`Ai8vv@aO_31u-5*tX^H7!H6MV4 zhs^;DwGi;K!VW{TeplwEQ_BcCa6TlGo(@g{!*8m*7B0U=o%O`&X2W}Dms9XglZ*MR+LA$$}cYs z0WelKuu%dI79QE=cL5hdIaA}+rj?e&yo~FZQ%})ac!&_sp!DchPZKzxLU)-~^UBKt zES;LqD5o(C4F_H+(5s;}pEqv1Z8o$dg#(dakAQ2oMkdDFGy0y!gN}TsJbzuqLq1Tc z{I*oYj`Q&mmy-NcP%zzwChH3wn4QfZI4`v)+WqXchbAI87?n$>$4yrq2ACe4BxKQ) zms9TVJh1Ui)ZBhq1~mICwA|Am(0dV?Mg6S+sz~2J)bZg;q5dd`&#|{1xBI2#3BB%f z8Nyg@bLhSy+UR6XYcPIMmD+ZTH?{imJNf(5A4!Sfpq%u%bXimx6&PI)RDccCezfBc zy?>a=7TgT^mq~*nr09e$u_-{Hn&@(E;;8#loR4 ze(+hu0_VtrD+7yL!NULsO^!Qsl&^FLcfw4fVWxKQL~c90+t1vfSwTib0-;&Bv^B1E?Mx_4DgOj)llI_@VfuB@6t zp>M@PU0(LUdEI*UGW9nz5l`;VuU8n~BZ1}*p+d{Urjx%ScnpVkK0mz~n##le6p%3E z@&bjLN{2>=GdBIXj@c`uZ(G=X{$d7wu=nk%g$^K)tfosa;%CvnU4V^IcrQltG z#N)~dMgrTf3COIY%1`Nc6RsGM^VjY+Fjiw(I%Z#)YiTW0mH!&T@%bJ9?+}*;nP7$*wc||IXW$E_JPkIogyaaME=hDZU{QpzMp8_-=CPs zZ8VoFBcCT-@UT4}KO!gUcBh0AKO)qYC0%qoGDzn1|E}Y! z9+(g!;F$uhV15DEXcK9qW3h7tg7lZO4p#!8B@c%xwzWSaN>(Oi_6bE2qmxTIbFFf5 z#N8-7UTC~}c*2&+=)~4290zV-L7ppdLjG=Mo)PZYpGLu9hLtJez@J7y2P1%B#2*1f z04|6C!hrxpAolNw6lriq`$JKTxw*NbgHd|9g2Chfolv!q$ivn+X?#*7Ws+1lRf3%= z*%4{0G;a&=?v!C~0O(+Jx7lponiHjWtOH}A1EsyOf$rRRP#eR)dc}bdKsexs2p|9# z{O<$)vuO+de7X7w9v;3r)wR8_@DRJu(As)3r$z}ScB;SDaCoVh$m_>nw?`so=7zgB zDs*V*$YH=d%cYWi@|kXpjQ4K3#s(%PCJgrm!etA`{D0x|ZP}d8721b{guGg5-097~ zyq;G(R#s~^Qb|%Jjg7d!v!!m9y#o#+YHDg0C6LScm>$*vv{_*T1H#S@cweQ`WnZ6f z*S%$BWyt_l(j^ylf=mW$u&9X0X(#>h?N&QOz3DV-huiI*+ywO}gX59($;tausoMVj zeyziyq|?>LO9~pT=DTdlrf+Cc@JplRvPrFj2B-BJ^U3-7*KtF9eEiM2ZFjCtyNl&| zlXZJo#oKl&uXkHxM#egcDp`54bQ%ybasF4Ps)Yp=z|IED)b!YQ=ojXXdgT~@r;{0d zy7C+9WO_Y-7m~4*)7ipl)I7WWp76|OyQ_8A*QX~BENm1>+r}22D%vB=^9Xtmx{$Y!g<9AI=qV_0NnFj{6SHeV#O%xtw{H$Khxm8o5=%Oi2U)w#_c zC6z)K+}6^fUMHFdWLZNjd5Iw|+tApUk4~dbpzq!3*=)OAHH{-sYlQVBO7X*_t+KKb zo@*s3Te2*x(MswUtTs3Pn|vp-oy< zHU@~oj(y*6hv5LaFV`c2JGfP_xG0dfcrw-9|9|sR8ifF4icHtX1&fzi&jk@>6%^f z}uDuBBc$|~Jxu{br6!>1SA z=tc=J%S+eueo*ORmo5zw785(aUy7qEgcmB5Oww-YOsf+&7!!OuukM~QeXG=J1`7=d zNx!)>tjr6jc=V}lYU-LC52B1zFQS0~$N*!jrBf9ljbt|ilESH|kzc^or1AS1-uDdW zq|XP!k+IXTF#Fq>XJ%&jB_*K%H+kyq*!M>xQzTt3JpB34Nj8tC3n+C;X}!s0KyotL z+}vCXw`c;HO!P0nN{BR0`4NiT=$*SX313dW-sOvE0>utHYg`S2N|@ z5UWTm2G4N4!Tf%nzWaS|`oQiz5}h9A85hWe;MHwftN?KRyk?_CqZ2^3r(dCsq|tf; zcmyUz_4N2sEAH*hw!1#w0YC8yBV(k=F_Pe<@W(_-r7|o`%om>p#*7$ijG_sk7HPxE zEvlvJY{3-CQGPWww#=0Av>&Fbbq;BgXfMwUEEowYYN|C%X{tz5r32h!Q<^*uc%-pa zI_>fI6#h`P1)0#D&_W0x90>nwy9#r-;;*viPS&`Z)&4;0)!eb)nz-d3nbz^Np=*wksc@k@`K$#mO zDL(z@dp~|>-ZzmnFHSZVp3$A2ZtA7`nF5!T%fNQuFJlQlQ*+6>tutBNeH4dQNevog zbIFLU!EIlyNudWg+^45^_ffxP&RAG6{Lhw$gM`*Y5g*)^3y$5`$mJC+?2yEhstwZS z&L7cwx?h&=lqu_SQ_(FS2iv>UUG2&S)JOTmVndl)kK;pkie%a7^j@EyktPx5%eF@z zQ34wF$(K%At~(LS&v#3q3FD|`GD8>28(Yi`!c74ht;l?vC>*wvbB5d zO$GxPWmMvGt-zovz#|C`DC8sUC(8oJa3KGwrsp_2ZT zP~T^1y#pn(EoL2`AXN(bnQ+l|3#kHUEF?AEfhX+9XO%%k#N6 zzJu$0sV+1w*Cs7V|Lm;HY+oCij%_3E-a^Ow=Cdw-kDspfa+D1<%Ni9K1H(LN)nV6S zxipt0dlMcpLBiPacBx8(wAY`T)8pX0W4&QfIkzkiNDMiFNsDf)wl+*kX8dpkACH$= zmOa+Gc(Z#Nb9F_$TAC{+v%x(3P}l(hBTjyCNqhU)FlYUC9NU3|30EhI>5|)FZ=nZD z?i%#?bjqE%w%(!RgK_$NV@{9t(5A5UOg=EMRw0cp#zIuo4G}%`BymA|U2m&xkwb60 zPIgj~f~`h3Gdmj%30V)*WIUYw9^GfrKv;rH72uCgloMM^hJs&&Z`6N~2?9hSWdv11= zg{h+8q~kBoQ2;8r-A*D(^ZO5A@?Q{QD-IZQt_?|9g`{O4 znKs#%>&(B!$UOX6NRu;tH(l)NT0!PS6E=zZ#Na48)VK{{eKGwTDyoWGa7)CY5SuA6 zC2gB%PEZ(8Q0Qs zo%+4oteRCUUdet^X_HYY}4-5(urWNlc4%^U#4pPLk7Y0 zh~IipEm2m7JQ{fb^i6QBu1GFjBDzF!UidHHIA`sM=R?_WS23n>@y;H0P{O#9 zpKk56eUwQebEyd>Gey=uh3fTadH5UXN0H_E3Rb4DCK2xkG$gS()!PxZ>%`bZvO1SD_}9 zNHR`kmj1*x0%n?%DEbrT3pKOoI;rWX(7ss%y_)b}OpLv#kk@x3j@)<|>AE#PVr$v! zKc|!l+R~Y?GR7fC6lZ@s;BP#v=D5e5sn5ne z47IRc?Z?`2$Gppi(T!6VYTOKxq?p#&m>orqYu}=zAYL{lYaA0+EhnNVV=*AmyIxNy zlCajC^L^XWYVN5s6e9r#>1h!Fe*U~?lg?nKWX9cZd)R5Vjj`kYE(RA)7pZ8Brr3*G zalXe%;OO91a&1#;WLAP{WYG zz4eA2Mk;i1@S+=^viX)y`SE%hJe!Dpnx!EUzlTDE)CZs$OCh8JKR4UnpT@&t;!LWdN6c17@E0}Pk4UkJ)asn>Bn|v+uvoCiiuASAdN`KI`F~cc^J}C_L~DmMvj=32v_06 zoP6U8h>V&vp(eIJNK)F=8|a@3cvpu_i$`N#%)jQBhurt@Q^ws7Cc3%p?yh29nr?4{ zGYw%}y&frXqfb5yM5wQq?7;hn=^V-;b*fss-Qv8xT+-iDdDObyt#P`;+9i*BcLU2; zUs9a$rm_-jGp3vPL`H^OkNG4+i4%R43n0=g1VhgILyr{E*+jk5s5>wA>*o(-PmfX+ zs-uukU8GLA>uv#A%^#a z+^N;B@bI3dBQdiQB%86e#MA~1cCoH}P05(4BPI~WlWQ`H}iPG!pMO=!`>bkyI4Dvu%60Urj4*h$)DQ)y}?Vu*2j^)Yaw#@Ae} zR|>P@agvTDRR-*_6KHb&>rWm0iQJ@jd*hY4|%m;Av-BLb(3*S86pMR(}Sl#yC;rX7y zL{GiK0WaJ3jHynM4*M4rNZ3EQ15E1F@Ik}39jRaYe-MDxv$Yu*J*{CZ)PjBTzM-5) zbEDwLa&|Sq_Zh@9ydVGA>sJs<_5w2x!SO!ELmsw$>!QZ7iehk{G;ZO6o@~yZT-l!5 zU2E%gGDhRq^nmL4_+eV)d*&$g{>lDA5zyCJ`!NFKWWfkyjrG(|+RVd#SO;oRc9zO! zgKvP`SL-mWe%q;Y6=YNgL$jL6!S&qSztq3hLDhuwj+gD@dSB`I9GZ_-aUPnu0MfFt zDhC<|Z0-OBbhU{*PT!`B+>I=oBhr#W9zC5Fc%Vy0Kjb5nv6SCd{j-APn^WCQXP;1)6`>85zx$o5VNn+L& zz$MD^>xltdpRJl;Q3-{FQ`7gzt0C{!j+!z0unj#`fjb{@YcIhdMflTmEjJC>BCqwi z_u1HQoW-9h!gJ3 zHsPv)mi+SwmM1#!CrWq3Tu=XykG zpS!2|?4wQ5eiRyUAjmkYC|8>WEc}6C#!PtADu%_O+9~opV$;5I3+kPn5@yekCMO<# zAn)yqGb)FulFfb_{<-ES`t0a}PP66$OkUMJ()iiKwbzMSRokVS<}RzPBLmEeT1Kdo z9%4Seez>MK*hH88wuLyZ`}w3lp6M^Sgg$CCG0N>}FU1~zI6rNyOJT)9F#!$WL;Dix zm-L@X3jqPMbd~dVj~YIhl0MbJF(o;pr}47uUGvE)hDc&ClfwK$ko&{gh`7w)HEsIg znyFGXuWs8W()g$Ab)H}pR^O@-7v?thaxn4B(jZIytjQV4#y!WHHy5f9tLJ8$|!aTsHcTeksc4Akg6B#_7ENM4QPuc(N$~`zY#Zl!sWFS|B zmb!xHo!?8E>Yga!x7v7FUtGh4B7t`8O6s}(U{^bl-LS(pHTN>7E5&uB<|A42_%H1# zaWVdrd!VNm5N^SF&P@cg2c+nvjJ<+!laYF|kzJiw6DxdIl5Jy3gerCEs0#aoJuJi) zLwCeyioe~g(!4w_a5>`Pa7hg_DbQh>n?rc2-Yla6<8O#v;_)CJow5QiH-&Gz7A^iO_GO$1rN-F z?Adwwkx)I9RxjfRd?Jc*5+2-hzRSll=~SiFjkkL3VOwmblg9Ja z%rECwh-)ZE@X%0;zr@;I6I?+>%~{6drqo#LLgm&GLXtRHzsD3kV)N<+7F*ZIt1HwJ zcx>Vm(JWS6=dsGTF}PGU^aEVlywhp)5sm>m0M%H>>uQl z-sR$NC1Ku9SGBEoW89T=P{w3V5vKs}GTS$FoHW^&j1||zfr<_kCB9Jh_-4%%$+f?t z#w7l^uP{1vvK(|xA?35dcxEEwtx(jUPoejiz+I~`DMtFR3D8(9izx<>U#qX~eAO#G zJr>5D(wx40$LE}#yzB9KtoZBh7Xo%Z(jYn#7ax~Nu7(@L6v1g(pkq|N>9*$gy zn;eC@h{RNEzp5O3vPYXytfHiu0TR&m4K}OY1Yz)SkO1x(@JZb7?}R}FfB*@z z|IG^iAI;zYroIqB6huM8f`UU-WM(?rASn%XV&L0_On*-C!$jZqTZX#O(0ijVGl?(wgVvsOUWYgu(#nK;6)M_DRMPzeC#0c)^ zXz%b>q0HG`r%F|z;!5DiFjnTFAIrcsj}5L>-X>t_sq@Q_SKsYd4$tHY6TofQRJ&`A zsaA`)6*k*w*A{Rh%cq-m1~vykfVf5<>Mbb-bzSB$xOTQ1Bnd|DtXO5|$E5;*jFX z>_QL7$X0lH6dNku4b_RcXK8Ds!uomL_zgsaJU_1#4y>^$FvFBNdJC@a{d*%p3bow; ztvEyq8q35?bt|po$f$u9zY$X#bB%E58fuMQPP>DX@$Jr9g&bvXI9D%#3WQbimicw6 z4eB39x#BX~tnTh8{0RjLh+z70ugx&dN(>!b!QDVeYxbFf`%Go5XC``4-m2dE>ABM$ zj2>=U9Yt{3FiRSQ6i)5dH8RWy16IY=qyX>zU_#8HSO;jCYeb!3+C`sgEq4vNK5j?# zSM1%LvPE5CE+(*hA5O`H$vT2s1yCC*IpC%P>1)p~@nLK_!JvY1*s`zvd=GTk*PMi< zhT|Y&?oHlYYb-B7u~bfD+8%jo$BhF3D^XvU*;}5pMDGyP4t_pe`^j3~+{ON7W?XxB zWOVGi{lw4_ptJH|6_6c;PQ-AAsGV(tVxO*tAA-etsll1C>h4}^*-fU&5k2&9yq*Z~ z!os!TLgwKbC=3#m(!n>!lpx|&0P~#V$SVK21PwvM^Aw^BmxYL57@n@DGn6v;Jg(Ttz7Pl9v*ibaEre!U_GzGL=vqR(%MsH@VzZZx9DvPIh0r)w6GsU_t6qiDC>Gbn?KJ}1{?$>LAY|xON_SI>&Y!I z!q!|i?cN^+g9hDA4$px~X<%{BrTuMNu;&WGMT!!#<0gbTtJxIWL{yf7+iGiDKKg8% zQNW3pfw!w#PG$$rKpzh@L8z$-Z?#b-2To_A0g?P-*;^e3 z$>9KQ{{;T6*O+cLQxD1Ei`WSjM5`NVl z*6_QLiv9ZwwK#FzOG=Y1B6|1l?h+2idBuexP$8PtbTg^SG+Y#SBMM8;Ud+|a8 z5JKK>)9U*kDhp8^H(+YtIo^q{P+R!!Ipd9Vq9Q8J)spF>JN&FE>ZVF4o>16q<5ILA z)5nr{3@pA8>sTIMr4D?3ZKakKtb-|2|#5HjRZ2S1>B%Mj~-ST(Vy9_C*MqAi0L za`3>J+R)RyxKA2WOv|F`7w(S7h#JM?ARNPcGLaT~fJ~TqoKaxJ>h*lVln9@xRzzjx z@uUGC`*IGO+Lnq_59DjpfRHAHM2l4)IlfN-dF5y<3iFmtm2u zXKed#b;B%I?Bk((acvKzs$V~RrxV!5+H2lpw&BnSGy0nYghxWUZ|~n~k8LxjhJ3w8 z#uJs?geHV!--)gwLU`!k^;PidZehDg1zFp5$Pc+p#$O0qmlEdk?yZr5h;M-KUU1ch zUXI6B{?V(g`z6Y*%H{@Lz@1mB8@to_8=LI$pH5Pz+eBjS#4(Rw!|1mtuKVtuRv(KYR^4n@ zNdO%a5!<_-B?3C0?Q=gg1o-bSbF@izlTXB z=Ora@U@5cqRg2|BhELrwH94waoLYp9c0FrRKB77?loaB+=sbjq{p?63_$3E(bjK{% z(YTP;hN;P(zE}JqH)vU3y`Cd}?~Fj2sVbYVZ@TnNji-r-g9WVdqV0Et2sBQ|OIGRu z4gDsT4?GX;kCql&VMz}hDh!UWRnh8}YBBx;U>NgGRcXZ`F&TE*Cfr@Kbx6-@pZ+tc zATJQ-Z zuDr&xB*aAsH>%&#Mp^t8+XrR0H&v)ov*vUC)OjB}P`v1TJVWIt*1>LYdWVv2%1W%y zM{CR>0C<$em7rDY?>c%c=+&XXA5DZDx2aXHv1%l|RFVM_09yN9sy55Dl@Ot|`#(1e zGaOtN@*WeuQThYYhA2vDF)syWseh zYth?k!LlA9Ff0`hw=Co3H6I`f@sLrs z2=l3~rF@Z)5t9bWeX~u(Wm=8By&3fbG!-1-a*)XNg?H6=cgBV~TB>4TVH}*loGJz% zn^=bXCp}YAlT@lk5FCSVFcn`e3R#PsXOj+9R(t{|!UtO0Bh4qyC$uPzFeD(M1D%(v zYOJ;qUAwYqO!OxuB+VdDn9`o9==GKw>jOVx^$mCtthKaiH|@uipRK;2XI*U~H6-VW z@`d3wlarzLUt#54Kl=oq<{`u($*xIE-N}*1UtX=fB2a#~a!)i~VP<-QwY2jxwk}Qc zK_UD1n@VTZehB2gLFN@CxCYdBAcr4%J+N}nq5)E-$(B46oKNQ$TZC$km3%imL;(bh z-?ZpqXuSY8SN=}cZb*#PA=>7^>mhks@NBMIuFBa5o0Qz3?HT78e}x<~wWJin3>F8xQJFo7gJ6&2Dg z>Ce3nLQ?@99oXI8TOtHyy|8x*6eP2f5&{NB1(3Wyd1Ghc7qDle*pLXQ;UJXeiYsb$ zepykN8tsXD_$U%UcS6jXGzAhrpm5|#^i{hT zAapcS=!f}8U+?21(y)RKlNL<@OFofr2SU4Y6jQVS8*-_FBG!Su=sb!EN`zTao9X?X z?6Ts#i2tNF5ax6r?HA^S0#)lX%!L)gd6v4d`5jLHk_b0|0`~tDD-Fp^){5@e-^?X9tSUg4cV3a`CT9 zhV)?74eKcpvvY5Yg9@OSW!}C+M{&UPYO)b1Sf^D7yet*)C?j5d6%i0M$4p9VaC_CU?j z)AM@i#}U21@T896kq8R?-@0liUIvY+q+`Sh`E7p0?V!gcwqClEa4t6bRhF`5|LCm= zg^Zedpk@4REOKI2Qip+b)0}3h#;gn#8{pP+*LsLanw*b3Z$Hf@iX((j2$?g3U176< zIR5Y0fJj*UvFSC*vwz~ZL($Klefa`OU1mD>mS$z=5wCrvMqA>P{7`!$E3m5Dbm50V zi4cg*@$QCH-}00ZcF!V4wAcn6Zqnuj{el?d5UyXiE!Qzu9`L_?lr1uW_Wxs>MzE01 zgkj;~G3H^kT$2WLM)Y1rEjaZ-ovhT~FQTpF0u$wzi1a)ntZM{nl~CiG1OS(%8Nf@K zkA0u#-^aY`U)fR9jY5S{`WGs|{xR$LMt()pw`i)B=*jE) z*?HnYnSz=~B9IvEq1f}FHNzU6t0eQkHsQvxOPQq#dQN-|urZ;2!D&B+yuJBB+Km6X zrwYnR!G@P&8c_uN94HQgv{#%gOHyZDY81&Y1CC9^0wu<^G_%AYAk8AXA{t|(%q5f- zANe`kl%@W!ZB9HgBB-g7b^#WaFe(z@A4Zh`WOU2>aH#`u4DE$WR-)~C^1YBlC3&I9@!I2Yu>RQLL4!Jo$gwX!*R@ay z=%M4dWibSZ!dxrIYq{5Y)t}QO%dE)A%ysS8Ck49V;Q@l9-F`3g18<1N-(Fr#ACy4< z_w7lz6per>P5WI`beNb$MbjiIudGk6nzlVSJ27$W^SBy*{w?Mj*?oz64YIa0wkTz@ zxrBs@N`7SACRjoyd2a9>Z!{a1kcGc% zFh##g0G8=qWt`-XV{mZ^S#*DbFrYJuWH%WDSan4(8CUu2-&zcyPp2ogB!8K)|F#?b z&#e?c=ku~GU)5NN=Jgy5upLGGHV)jXsdpH-Qj!|Q08xN=czXyno=j)I-`~3<=Vx9} zX6TahcCuB)1Z%^(f%?^32K)rbQLdDKbe`usCP*?c&IlT5L&GPu7TX17~a!f||w`Tl%=fUI20D*Oh9 znp;*Dka0!$Y(6YAKvvYLu;p9pL?h!oJKsvxz_NJL!-WI=+2J3yVuUEBA`&pmbM`yb z5j7RdjF_1d(vzMSoiHPBZWWN6Wvqr9rTINLdC#$2|F$+`9l0r%8&b?RH;boce?H1a{wjeD(Cz{AeM|l9H0W)@$4go_ZV!N_*SHCywOkaDUMB zg;OXQXX_3KuU|UkDFk$kiUYgmt}b}dWR2}iIX?qZpY2+u zB09O_C+mDfl&h@iY>~skujE{wBZI?7#nZ*?!qwjd`Z76`1!bg_1foVoz zhoV_*$_qxg8~+VPO<7P$tRF;`sl1`^u;~nl{@&2pSxM zLvVL@x8UyX5ZvVe!49s$LV)1z?!jGxySux~?R@VybJxt8b?4vZ4>WyFpRVess!lz7 z?`H=d0TqrJhFjJ9GkM-OoGcjv41RoG5Tup_G$DaN5O0fn&M>mzFXbt7DTOaxQDr*k z>+2AXBimP4j?PO4OeM-6W)|xM!;5M3SDSBoRGGHPtFXFNSyEBKol{HWVNSdWMs-dNY{7v2Fz z7Hv$nc=b{i(~my3KWKMgetmEXy7V~Wab@<{qQHOJ@b=JaRxQ1H`2{Hk;KY0C*Zq^} zcKa+_zvlDDa9=Vd8cdPIF;Cl-vW@gz*9isEUGEc>yyv>})ZR}x9{NhLZW}w*NX*bP znXF(Ee|FK_0-4)i8!)qTsC1K9qG3k(t zIigj7sNjvrT2p_Im(oGx%L)GLV>^O=NFNptr1HFBVt}Yj2?o#=OzGy4_!MgBj>MdIH!%aVhvJ$5-S6_&>ZJQyg~b7@nK)0q87g zX1`=>N?cGxP6Z)LVTJj0+p4kj^?jPaQ4wEsM1b@jgP|=J1xK#(K?L4fc#pquy z#;2$|PAo=IIT-{=^D&hE6xHf}4ewi$$$pq`$fpQ#%1yznw{rO7w+urVzePKKH=-9* z?j}SlPEAm`ttO_YJDx95m)5j?>3J}{z1wfu^qXh?N(BI4%p2EQ%lFQ-9Cxp>sq+0e ztjyML!e3unGc_4$(%aDcOa_t!QBUrwCs1QIw|5**@gdLF`jcDkHZO}4yClYP+CSYY zM27*{9$!TW<+V=T>v|$DNvehm3D7LGM%8k;uXt5vjO_Myv?R8KTLq#dFFK!Z+=9&| zT(sJ$g8cB$&^}70Hx7m`-w#Zqs!g{xu;?#KtWC(gUVBHM03^Je%cnLt#?axu@B@~b zkC+h#!WVJs4Soqs)q0j7dnw(x0}SxyE+%SPfE_FH#<4vp6-A|TCs1lUw&UUfjVOr* z^C*0^p7H3wq8snVR&qCDhX<+bJ1IK%#brl~Jbg&#Y!`%Yr$TT2!~oXNi`79YI%J4g z>ta$yT@*sv*H$eaZn%$E7!O*hYN(`yy`#KL)1(^s0*hUeOx14^48_e{$XGe>3sPig z>O?b!M%FQvg~{UiD!SgEC@b!Jr08_#6hi4!`Q9VU-J0A;JofF$_+WoMn!{>4`3*+a zpFy83BuZn|q0_LL;&3+YI#Dm*dOlkfuVL&E3C3kdx!ew$|8&!}r?&JxUW>AE-lLA* z`Fk2?;{w$3s2)sLhIi=mNQru2beMG26_WQY-QPRQE-y>G;p9NcF76#rqKh1HTqzO~ zmqW}?q$M4iYZ!0|w;12tNyNqpi{cl=gp5GQMC2DRb5ro!x_U8$-2SE!)R_3Ey1uSj zNyP}$y*pB#%e5N|>+ET7Y1~R_7(R?znGb|>qmE^*LMiiSYMeT>@!h3ySFZy9Yx*{5 zoK-jX;V5H?>-f?dc3#r}-RH8sF}IeJ$6}CoV7Ms02wN_-@e&ePqc^I}QQCE#pb209 zoIU%5x%VT?q9j5@J<0o(-=c6vC7EPHo^(JW=r zXK&C`3G{M(If_sxs(@m|tOup%RYzQb=l(NMf8I-^6sgr zf(_S)`1x^38Yd2~+tD;qdS+&Wz?b}ab}JIE$A$Un5=JP+pav{ecD7aNRpZ*=JWt17 zdk>fG8L7JZIOgBwE#Dg(-PIMs(~^S|&_lkihQD8vHTEl@Xm4`CX^{Z+Ld{>f`?jBn z`IC_q{G~snELT7rMctu~``<(L8r@_)HQul}Z)e@)@~2D`2*}f)(Pnf5wZ6KHH0)jO z-7=kC-`?Q;#!Mf7_3h7&=r3P3U66?_hfB$gzsqEP)!R=0PJ?+6d8!4|pL`qA6c=sT zqelp3eAD@4@6!Ivog8eyy>+I(P8is0kvHkAawF&ay+ z*!Tjt_oOI&FC%Qvbamzd?JVhgt=Pz`0q6BsUiIbE^>P0oiTlm_#He$h)P)qYjds>L;nITGeYekR35|}b> z`W{$6$1(b>SGyrTFE5Mz6kKc&FLB&rzP*>;$Ht4;LnS2Q4`5H{-LS>`^!ii!sc33_ zI*)dmjs45eblSexQO@0LM`MrFdMAjQpj7*aJwUncrU8dc6r=^O%l5 zb+Vp=%dC6hd|_OpZEdz$gz;W)=7}Yc*}}e&3LEvQcW^$_zqcM2SYBw8;iJ4NAG=G3 zL%HaeHoFIn6QIHe-1TXkbWn;I0fu1??Y4j@XQYmhFyW^?o*&XSXgmE5TOhvrVxJUs zl_H&17OFP$^6*6-@;_B~e5yy01+B3g^@6KJcwkR6>FW$v~4{MEHF5 zzDnjuoGKDfv+gZ%*m}0;9#z4iKGYAI;+&D6wf3LKeP`8p!`QH$+#oR=D^^H6B5ZGP z+#Jf+?Z-%*>zH#7{d;Beu{Qxw4zR>I@JlQ7=OxmLQJrg>wO!DbyrE<~GLoGd8OpQGMmgV_xO29uE7%^_t&$N^c zN5c7^LpLwPW10Z>I~f$Q4VNDeD^P?3XgxL`{$Ub8{WqBYKQcN0CK^D&#p37Y=i@fF zv>+RHP@K^s+uEM&|6sQ{otm7?W^6-MH7IOHQB^3+hNdY5-eISy4s_SDLY(eB-5TXV(eT z{)eO2srT7Cpuq@tU=S+&f~IN^u4a(k_>LF>T~$F}MUgz?|(Gof8Ry@ zE1ebl&eJ4UxdTH4*C#cD6w82u0t+8SMU)E0XWd(82oZAWRt3oS@6%SAoGk)G zvSL*W6@{n2#b_$fMHExYvUT?NQ+^A>;IF4C(ylwyQdhX0fF1A-Dw^6B4urnh9j>aX zN<=2)YrFy+TGKL((?ZV2L(X^2nO<*;hd=?#XKefk4r2UFK=?_W7kiC<>h6P z@pN8`-;%b+$H#=Ar;`RzL`1}wB8;#*#1iCcz#~CnlbD-(;TbS+(9z;Q7?dQ^Zm^@b z0tCTX>C4Dk3S4)mD}Qyfk@c!HGsXn)}8<~&kwrIDP!=Pj|zO;g@ESs@0sZ~!XY8$P3 zsYle8h1sRQPZKHf&9y@!s+d%9% zfEXR;m?R2tnP9URQd#>Hg~3Z}Mt z-5lC4m}lt~G3RAhQgU)1oL9dA9?LamNUD?B;t?HyPWL4c5Tbwo z;!lM*U8uA*Ka$Eis^WvO1e8KqfNsIpWi#d{>~5iR5*Eo`q;% z^Vd?uWxmpAYG!6eWhh&2_}ZpXmObC~VA2d1S(ZtYsk71+kof97yx3D<6s+Ye4zyLzrU7WFBC2RnhUf7$Zp91@)fC zW&d|3HMN`9GdC55rHHPc9<3?dkEfAuoZF(yrncF&U5A0KX2VIt9)t8+aEf@3K)CB;KYjckaf zRKMpVHq$RbgXqXem+hNi?m=iED#C%NkUpHNFxanB$lwd(ciaqub{^x|-QE2IR2Vqw z0#^?fi)o3fsIYF-j0-%4gXiZppMa5eqFZem#_C7CnV=vL$7VH|I{|LZ6!gpZE!Iu~ zjA;Kl$_pS$4m<6mk|>`NhrgPOL>safVo>pC++p3^> ze0U(QiJ)c|5LgYO{!`l-2!m`obPcJ-o!x3=ZobRxc03>Av(VpPfIuY8=XG6}2aJnC zMoe1uZREOq);KgQ0s`CeoScL|z@ta?8Te5u`5h}VGEzSppSzme!2Coq4Vb3hK#$i} zy!`z97s_J5FuWHnd-m+4y0wYBQ9NqAd=B?)%7mL496UflepXwsnJXU!2K07D*-^EaFeCH=Q_;(yTY{&TsPA|}iGg4kseZ>v0I z#$!4eADB_^)tZ{+R#~5~ji!~e9h;Pqjg^dTl`!Tzh)WKG=vqc53c3=KLp%|y?(3HX z1gUA*I9BNy-%W*Psf4qIWoWh5mieSaH8@`b;bSd)|3ta{1U;_wdcVGGI|b8Vic`B( zThmyrq-i{OYho1`oX~yb8zec4iIrMgOtw2o^?X|h?qu-{;nB*y2IRmLWoOgA_Tc=$ zWSvxvtikEk_skFwNbYX0tWz)3gBvVGstI(;kFkY?0|bk8g7Yr(=VqUxqutk1-*LMy z*{@%&G|U01$<(-18NmY_r%_UkHp#2sb7iuwFS|(g0?kDUJD$~JOIOo-5-}hPzcuVk zY%950suzb1kGYp+EWUGBkY2*XIIjYp#!}XdQuUZ$|JztPl11`!ExQ0&Pe!TIqtd_* z&0jtF*n5LH4z|ccCfh#K{;_oTj;ePXId~EEEB8m!a%)DWi!7@$F<*+=9Cw19eI6pl zD|9Hku^wog%#WId6{mTm!;` z1cbD7%k4DZuF6i9c4NthIH(;R^C_`LmU;uXDAV2D(>dQ{)Ld__Nj?nJv!2$>5qg~? zq*gv(jCYKiAM@RPecX(r2fNyucL1HnHg`ru;J3a!LiR2iL^%yZB;NHT7EQTy}kgqQ$QbXqJ* zC3bc-O)c#1zRFe%%^i=q1Rd6<}HL+Tm)@PlY%;mR1KWRgf2C@`5( zr8gtm#ewhPeP#`W>G=FxC1p3$Gi)jY;oQg6$t9;aynXEVgIk|^!^Q=d^ULz1r$17= zOwYunWFUbM5y^535}0LRy-N8!n$9nQ8oi!bVT_NTf|sICYBJNgUwT8+TWo9qHZ}DJ zDO25WwKHx>&}1&l$sCUoCY&|bJj)+pWb$NOP2Pfv0(y~|p(JA!OU;k1J^=>anZbe% z%dUN$v0F0U8k3WXG8Cfiz?OY*y&v)Yi}EB|RJc=ql3R#~2TERkvyhCW9uxu|sES^I z;)AenRVg!lYoAyT6wipk6tB7QaVUg#K+)N`^SCEuEpSEw=rLIshp)iL|j*dxzKkDitw%$cb#*Eq-wooHLr8ofy`Dte61x(Kq;0nfn zl-P3JIyeG_>MxF(p`s4eF&nf(tAop;aISA$&(Fi`vm7D2(D85eeFQuW!MG)Z#=m!# zya5CVtmdWn^9z#s#LV1hlSJlwsigX79-mBcjKyIYsqiW;_pMAK9$w_PD!!$|i>jO) z($==4PwbbSc$GYuvRM*cIn&)T6FA{Fzjj{GcNm^q~(E zw}0hHyW)~TNME;QF=rxOi@<~d0CCe;P(?O#N~6N3%M7ERj5cDgEJWc6VLKyA%K2wR zauSa9OCFKE&fCYZ%gIF6c*?+qy)> zK~*?p(=rqZ&%;9|Fhmt!dWk6ah34ARTL6Lpgb?zstxF802j+}A0d5HN5dROCd^1q= z-<<6KH}Vu3PcC#noQ_!Xi|gr|t{RVX95noCO1P z+^ig{$n9Eej}I;D8E3>)7)~sTMa2|onzgntCGzQ6I!!F9?Cf!$aJ~)bG_3nM2+95Bt3^k;Kr>ii8r>3;n0Y!tlr7A?$w zg>i$@*9lR;dgZUGhX6l&OU3!PNxRW@ai-k=i#gA{^C;1Ywc6*LM5n*f;=cg-&BCXj zjV)Yr0`CbBK3X=Ry`s81E`a!PXpxugp7BUDmN_wwRn?}MTUS2uUGjDwPIC^OoY*Lc zb?gp1toO;X7*lsvn@~=tTqE+$RrCfnHMJij+0xRo>2<&<*)^$m; z9guf6*f?1Si-_lo)o`n6oHPx*a_P~1CF)zZxo~-+{s4@@0=5EA-HA9%vA%(cNw=oX zyUY6@a96Z35i9Ss-vwkRDE(1|3DjQd9A(9ow1+Wz_1BIa#^mbqdem*KEi~%;38r@* z`WG*}8XIx{H|}om({f@CZ3N7m`O6nL`DM61f=tVlLmOk+JsQ|Z+0J^I_THg1(n}30 zhf^c$QxC~*MM;8$7T({aRNn}asWAj>tOL!F^5@-Gh-2&f|x&Dz#d(g|kr7HQyNg{~rrL{zqE7fn*05WUQ&c~=MKwb%P?rsGCF9)%oU zXt&*{^+y+U5_J8p&gA*JTV&`4eNwO6|B)Pibo9TH!)yKvIlL0vYGQ^( z7^q-@ihTpipun20b9LC=6B=|hHG16II`3+LUWPBZ^>}6bg%=|csUbZqgJ4rxBr9*s z>no1*g9MwY6ZLB|7l{I;Hl&H0t}2PE{}%-7{|{tw`Tv0|{`z)1_MR?0Cu+;j3l*vd zi9}9Vd>R%_m945DTPGXXm*@QHNl7suwFs-4D^xNuHjZh_rV5`I7NYZ?OmjKq;`+Ar z2x@un?x1`ci4C!L$9LtxThmf=w>mQBx9Yy2)uLU}EKOv1XaUWUODGtA{JVsyx?ZAT z=IFP#15s6nE%_4{h=ZUE8p(L9265cj#BgST;H2Xj{vuLJaZz~6Q*(*Ex`C2|#c~;Y zGMi-AyW|etQ5eE5c|l=r0>z7hqVn|g8^9JIJ-s8S*yRLaQrdpaR_J1U=tV2LwScjn zHL1Q4;Zx?$qdmaHxXNn0!BBbP{!G^Ha_$?e>t9%qXTt>5>k#%1&IHChsf0EXssm7r<8l$ zWl!)ebSeP5!hRW{bXp+r%5N2ui)ssq@!Q*Coi83*p z`gs#zz}4yWwz($ATdqA4{6x?Zf%<@e2e8ydTn&@YQtSQFx5>?663!82T)f_)e!kG+ zRO_$w)FY6{wlaZX`9&Kx+&UH-c4P)3Mt3*9HFTJ3GX2HL!8WJq?(4`is4xU)USAP6 z9!!qE>lH9jpDKAEJ3EAF=XTb~`4z|M-qGx4HAsv?BNEn z=^q}koeegm^d%%SsF{k9o*f8V{~Pf_9j&-?1U$Px&@$$~%=syhcgM}3#OVgn9h*Xp z7Oe|DM8tw_;0L#sn?KkM=v{JOO^TBUIi(2eddlwR$y7dB(v7759P}?Iqy7AD0U~b? z#Wa`HcTT?X#U2i4A8`cFrnKeWs_1^S4TPYj!H~TA=Ik8jeMC{}?Ga}iA)jve)ak&d z$%Q;_Y%E1c%Va7-%rlmbZ0CSN795N_PKpWpD|Rp|R;m_WscMyMmehDTn|#5%L!k}z zbCVCMvnV=~@h|RE$_vF_sEnou&DgZrty+shJ1glOgs#MXjUBjHwYY+-<>9@|wH%)p zh~Qb*&wgxJLRz_Nb(7FPXl+;w&;VZ>ew)+6OO{0Bl!2ldx`vl($ zzGMFqe|!b*yAnE$u|pZ1?CjDL_2`8m%xYY1Z`T)b4Yh3Bm0X6V(vax9>m-g4vz*!D z&F5^kpRliSsOuyrV^@&(Ekyy2FaHXBV2GP*!Z?dn-4nHfiKP*o3Z9OdqoXwq zTv(-uSjm;;w>Vc7P1gfR`3V9iUydC?FR@mJbSy@3-yTtng4}5kL|63!Cz6SGeP;-@ z9%{lx2ZyG?0I#4Q$|N( zgBV@u?YXs4?IDk>EUoQ=9NQL|x~MWk-zO~=@=_OIH{@`WZ9A3HeeVwOmbk4nGPhNJ zb|hCiI>P*-$(zc;s)v3aK~6I+Ew0Ini?d&}i2bA+r6R*xoj!!h#Od&8s0Z4V-B&n2 zIOm>1LT284LA}rq&FhuLtES9=bldeKeokgldI}1nf_6=hI8s_lZNJ8#r_-Hin8K26 z5eN&|j7)C+RFK3^jDf{6=KvEWrxX7z?PbKI2SUbnI$aN?TUOvX^^A|8A^VLi>t`PY z{rZY88kDgBD%>JT92^cW_pdNdoy{mEFL_l?Zhq2yL3@)&Q?hc2uiw69z-eo_swUPD zVmJNt!aI6@=l4u_VlgVQreYDs8IZms6A@u}x(}6R)Sa5@heSyKS~TsAg(EG3VJAp0 zF;bDH_&xq(1QNl<8RyLQp0rr+D~b#3MxPtRs|RSDMrpya;N}Mf zLei}+&s|{CN?p5E`gr}+ zDsi=bj8IlqOwLXrfb6KJMR{p+D-j+g$wb(SOf3lH+ntFsp9uzO-gpFqNR{EGl&hcT zx4!g0SKehk#`J!i9p9^h>UVN1J5Ggj%Osb~)-OCgJiJ33CX*gKi2WGF*(7yK5Rb z?*_+qJG+*@FIGb&BzEUW6q3VVh8x*g$s+#oAKZg4MAb(N6N&bzLK(&TQAq8MI@C3xh8a>T+@n8(4iKNp*u4rx^f7 z9o%NjbK7tXSJM0()Fz{XjXn7~i4yx|M=ESbgf82rZ~BMaj?*?mutzMZNPqq;8J%d+ z-d4D3NFg5shPDKCoiA*i7?p&B=Euk=#Er!<=qM}AeEoO>#i041kDU%9q5b!-dTHsK?>Earg|^E-vd|&4ATe)cU)Zgnk$- zwNLw^^?V(T(05oI;!7r$CKpi{CL7a_2v-tJEF6Zou?#Qdhsyot=GY{0*dLyaF%ZP2 zKUbI}QO1$73navSO*RjTpecG@;^zARh}4`~dQj=fe(2 z+yEK6*^6m#P2}f*%Os3eQ34CgBy5^9|p`=Pi7ABHqDWOV2{P*`h ztunRPuZ)7`lKCtru~x!=LS?8V)kX!K?K~3mCJI_?Y_~=%rHjEyg7Yh0j!;h8YK*>_m`3igd^w}KAy?^>{x$?n-3kjxYB1yU^ zZd{@)NT)^L+S51;1*ZuP7FHm1Keq+3wqoDt_Y(TX&Z_|3$PZw{C9XM5uG?ON?DRno zHa2@KwC-qQxgbV6LyStyPM1#P_C(xCQ8Dm&6`F$LJoN@s_wfc?75pKb3!krPAH3f2 z7ND!`t}mih!1wv$;31`QS%F?52Ir?j1%4+iD&g*FtJcnXnIe^;km1rxf%?8^GyC;KpKRv z2~=q6tTmx@aNUB2Vv!!4$V@gF>J**7y5OP_suicu_*Ezd`Tph774msDDnN*;H*W$1 zN^nd}mIgV3!aGX=OXs=zjKO%yV}D{6cR1f`>-a?MtH3AuXr1dYEU%U&!<#G=hf5iz z@(u)O&)VL8K?5OeJK}btB?3~PpH;?hdSVn#8ykxO_%*Lm*z#+#{!K;1MNd8sEEmd^ zCDJjcQ%FR&w%`qfF(HzKIn6QJ(&w)Fz~r0*f&gWkfgP6bq2a$OEPf5?@Ek#jZK5sv zq4}q5E0W0fA-zJ_jkP&!Z}OOK_vFaQU`6`*L5Pq%J8(Gga@&2ZQJ|!>$M0x`dlq5v zX^xTLob%Oeu%Kytz`XfyQJIJeTX?28l@!$kBYgHnj3Tfw^nen2 zrvjAedCJ#A4%u`6MEY>5x6QI?x*ibhaCq|mO^r4d4-1@BPQYY(fhP8t(S1YT5x)gJ zW&qp2+J;)`h8WJ(w9ny&uM7RLr#);-DK;b8z5NC0v|EyCPcy7^K&tlQ+%Q_p|F;|- zisSCb$dM7|sXM-mdp)81KcuD*oOen&6K2zv&)n8frf61CfW7yPFUk5vrL9oMB*f|f zY)F2-!~O!o$zywSKM#Sy60bovd02M(gNPi z^*!hM^7mh(1W6Ja$r!%DfPE3Bxu}ZXFiH(K_t}b`8MP*u>&%fx0kOE6Z?cyLuYH2oHC>xLs?+^i`%8q@adM4!ljgt*N)~EV)wr%FPvl ziliW=FKoo%ApET;N1cge8xl8F^LNWI%zUjM^kmJ}fB^VqHnwMTIv?TD!zZW=Y)(o} z8ophXg~IWX&8&w-tY_tOHW(ANJX&A2V?aXp3)k3(Q$;v@b+Q@N@~|vW{uaTwlD#LdU2OC#^23^#k99cIZ7EGL z3`fumNCbM6xh3d$N@$!d&AvULd!ZnMm7gtXDq^^nG$kgMG#5rorPJo0Ex6rWH?)i4 zJ5|A&%GpgF-(6F}cf5GiDin*C`;hDluM;ZE~=g!)u8i4_+HxaV?Lkwcf>k$iG9k@djJk85{34JJ72I8y1Ud zXE$Y5+GNE#HR-Zf?yI-N+gmjiC1U=lt<%_HsVB}tQTG`jGd_NGP<_BQwT}UETB!fN z?@-Sxz`W@ATjTGNTtbdKmTdBb1^es#QL*0+XlVL=c#bYUrEjZCNH9m??;aYKBSwjd zHSPIIw)AZpW;Lt)bgobOI?DSXW7#$T_y^UwL?XPKJ(@^e!fKT zK*(Vd>fx zPW&XP!_g~sB+fG_wM93VT$#3sX-CCHX$n{n+i~6aY!JWWQ~R9zhO{vXkd=Xl=N{qL zk>?}-F_hUq@f$m$gDd2I+I!yJjXDxh4ww|{d~SbSqy)L@d*dB2t!Hw!Wx8OqY#ScW z_*dOL@a6`C6Ho>VZ}2u6zEX3A!BslC_s71`3!fXbbjnCWAXA6(xqr&xwC~)Rp}nAE zML&&X+Go249lx29OcDw71a9>+S#F4+1sHX6C2??g+%26cjSP1W+VA~d9gaYS?%3SD zU5j;j;_#HJW#UYR#h+ElE_(KyXPI@La=)D$VP1;u*R?><(6~-z$79wgpN6~WoOC>o z4SXcJb6)T|lz5gkkM%865PEIg3IQrFrn@&QuNDUqlTkO}zJAXQuj~qxD?WJ-94|O* z6H0%XXOb6>8Cjv!I{#7RYyYss7*3Ygkeh#59O^lw0=j*@bVxr6$|$F=K)SZ{j{FkC z;@yb2fc3op9Qi%6Fr(s%=T+b(VfN{@bt~tKXa5UleD1c=F=9N8QzYuAugbPh_Md@0 zgMS$rHPBv6ewHd~qkAKeV4X8G6w&7}4;kzY6%|i2#%Pp?2E>Y~lkR%)rzifFsQJHR zq+nH`9f{xjksRg&A}D>%(d|{Y>~4kKM>DUL)CmyCfaHaA>Xzb%|>hS^3P_=m%k zM7$~_F{R`vX#!A(L9VTJW(=p=9a;K|y|mnpn&b6ws`XN7^7cj;x@$g2v(_&CnA_@7 z`|{&JRFjiY6y@K-Vjn>uNcS|J3GX6SfacT63 zB(yt+)h02<6){<#vRs@_4|r{_i#Mjx z4rQOc6=G;@=AH>1cduow5yNd88tfuh+PC!7eJYn8cR1Ck>Oo8P4w|xV9o#wp9S|2FCFWvB6DX8Q>jUlqU1)yZx=ncTZF2_EWglS?iyJd(%oNfjlL|_ zAEJnqDY3ubW4zB^k~FC&dNA&zS5k`mP&beU&iMAt<2v79t>)@nF~UIYkyBS;F6o;v zZy(;nid;sm@!QIZYG^A?3N9W-dFlacUyBN@pEcr%5ljaAnw~WVj-U5-))g(167i+E z;V*kt7RUK)>C=;^jNI7?Sry8Hfd!3n?fj5nq;tL6b0|y_d+6rJ$9Q3cPhk}>OHbvk#tjwxCg*DXvvA|hDSUQ1(Z?0$T; zUr3*xnTb=1m}ZC?Ev?Cq))s!XGGItPSc_@rdG*@=L&VA*b~?>-gM6D#c;*$oG*M>q z*6r2&h-MwP*xA!XV!uB=Oj#{WoP5-0&~a( ibdHq`!^(U44IdH~ zFJGqGBt-;O+*i&rA=OdEaRxuvrXwgt1@bA;QB_n>y%ziWzD2e7;~Pa*i{y#PT2CJp zRg)zx8QN8g8Zn^4hQm-&Q-VmTdR7iLvJB$8u_8zBavTiSPNJJWx|(ggU(UJBWftL% ziE?^WIn}L%^o(h&malcz8hn(0^E31DN_PAV=E4*emq4Zm`Z<=G~#9|HwE-^XQJzjKazsiqI ztk~=V3%Xj-6%<0VZTt#8$ARK^bwbHYuYj^Mn*{r((guVMp4WDIu)->D*L{NPEmO@{O60&#m|8? zSPkOcUcs0UU-#pwlN+Gj84 z*PX$3o{U>t@7$*b>epSvA0iQLlj0XK*O2(^X05Zb zJsOp6|1kLMzJEZ?`EeXyVE=UHq%<1bB1eaea))gJ4IM<1Kd$2N@v(9#e6=M?x{lxW zlyTOoJ26C<;kK@Eq;9{YoH|7Kn}Yd>jrVdognp<1ZS+_O>fSfQj)-hNVdPWwOggL_ZkJrnvTC+*|`)3FU2m=&ynb?IjoLza4Zo-J)kb?qN9OVy>>8g}*X-xp!}O!0qdtkE2XTS%`?KZR z4+jT_Tr%k-s8Z*^p;Mo1CL=MU#1cdzA@vP{9}Sfe+BZb&Es1m(9;XZCrD}qAOiRnl zM2w6`r9ZWaMYxzFBO}eNv}I)A))(jJ$@D00M0<7zWB!TFUPWb0zR zb)H-38wv{9X>2T#Dbf5(qT&H9M=g>`Ozc9r76~yi2nvN<-$){jMj(&(Q*1>dDKpFu zwY`hY&d--7hh5KMGNIq~^m$-&`6MRiEA`d4hm)78>uiByBQ++Y62Gu%ZW5_fUHnYC z65C{(hC&VWQhA(RT#WcMRXCY4G#3cGA1~J3d|n?C&-B{duO)45=}QP#lm-~)Cu%Yd zy$;62`Gs#8I+mzVh%78D1~QgJlG)MnN%lV8U!y(Jxknt!{~hoN6PcgoGo;r4;sSK! zMoZ04t6i8}D4&F6+EjlT#+ArSGKz~~V;jPdc2 zj1%c&s8~VoPZ!lK9&4(s;aSivyjAJ=Zx*qVTj_(`S;FrXXpncXJb#tA-M3k+v|$rl%0_wz`psC8lvKTB@8JOJDGHc1KIGwAXmiywI^U~>1$nISlm zbY@LUP4T|-fcEH}oQt6T8Yf@Wrf^rpLc$$#Z~TJ`e)yCpq{Zdba3)`p8BLgzlT*FT z-Jw7Qb-ewQ>bTCz)DAHxn4Is`Bvt*W6E{%9_F`$Np!SUmy1xV^zA~G2c~l*eL*3}cTEC+f-AjN za|*K{)Ifd|6>K%XwvFER(!+~8fcJ6KRpAXKdIM7-6J~Sk)*at7k%sqh==^J#7n}>P zPm}fP*O+ONBPKc{qm();`E@g%v`^6Z09_0`qVx&KJrh6Cr?SK#QX$9Y8y|CP>M<)U zgW)&|b(RK?W?M(YNzf}VC+HPy2#(!msDRb-?Ql5Dsp&GJ#!$xdIjl?GwPr7j?!JET z+>AE~+iFL)o$RMBnMl_{a{7jFl@?ysAU>t|V~MzC}3 zGKsCn2}47F^{G@K9Y53GHY0rAik-1%#s$xo%-`K9j1Tu5!pie_tM=})WV-mZNvA{z|N z1KUXG8x+#kM^c*kR{gogAR!gj-zWIjzWbcv=_%rKvDbvu)*b)($SNV+B&|28RKDKc zx$mdm;#SWL*&N+Kv5r@j*HQAF-==PJF#pRP01X_RuReL|*tQANn8%}2NHd4rCEL~rAes(<1tLeEg^j;<{?+4F_KoMZo z{W9C>L)h5ZXx26^PGlm^e?&v0x@)}Ux=7m8fxy7BY{oT~q3<3ZKF+%gjofGZo^&iy z_M<=#i_O9McXO6GQ24hpODK(uy`2N!UQR2qe*E~cI1r7u+DgkmkZvg=B66C^?RG%D zOZY1$JXSOU-C}rGoQ{?jzx1~o)B$}Sl*+Vfur`d_o>i~UufJvkWt0-eNRUwZ-0at2 zik-ebCs5tZa)Rw-(T2t+$Bg=$;@aR%MrJAOq|bGR1Jyd zFA}Lnlu9j)hj@ijiff>r8L_dk=Tsq{SJqnHVnii={6NQwl)wNU7|)4{qH0)&}Vqy@Q4c3yp!m+fkYt2s8hW+6u7(_D*-L1of8m=axkwDGgk0#*P zZCUXz3ojp4^>D)iuH1UN7keYHX(nWz`Yln>v}s6Tx8`eez11Q;6Eiinkhx7-NC+hG zJtr4>tPi!;cq35lX$=09Yh&*B-)`4D1&Vo-BK!)sbIF8D@IzP5oDuC48m^sTI{wlw&wC=N;rmzj6#)ZW$e=-c&14AF!!0a6tRX3>T(m%P`g5dn4@5R>HZjAW{42Jr&^9}&iKC0g1B1yNE1fD3Jvfj= z)O?xr3?%X9vZbtj9OfFzBW7rqB@!B2Q30mW$~{Nl@L%f`Z0MN~e%19FTi8vHKwVD% z`IAg$hzkY`i%My|B_Vff?2FFu{=kcS`xO>Akgtq+cEWF0jcyKT3{ue7 zi`}ioM>BU;O}wju>tQ&@T7rMbMU2}zXZQoSlHp%xAlx{(gEym*K`K@w^cnk5v(t$EGD|+?qO~E zFc>Cm<`(MWVPB{QiYH1;K_nD)-Q0dOv3n5XqSFR8q;j5rS4-nUY{rISLIBxZ9Xnt4 zY9V(a?Tc}XmVhTFqd&bF5TrE61@mPtUI~UTRk1jjujo7ya%Z)xaP&3IH+w8SQ6bwc zzLJm3T??iL5p5z@m3W6J>e)Z%7-BAoRJsMYO;eqr$1_~MIE@up@L*naHGbMWdyqnL za9B3y&Mkrb?$ylX)vl`>&t1%~upES3l$j&WA~pCu<`V2RUuw$}E6KKU>=O$jA~MkL z2W)?cP`m015!w$X{Cv>95sl-x2pT&hMZ%36C=Y%W@<(c4iRr(w5oU6Gvwib%rP6J` z7K8UOA|;Qo3h_(x#MDe{an_SxL>m3T6^c1Mp8G>@Z-t`)5RtFK7r2h&qm7TMM=W<5 zO;E=8Rx|$Od;Sz4wtJI%7ONG!GB~V1Eqa5iY)(O3=;(||DWu!_u~SlssHDmS668Jt z&hFqid^o|xzJGW3I3@4#_8}UXphs;G0d2mP$oL8$Cex?G@6fx}z_RmWS+`bRs^@w@ z5c5uX`n@yE;c78AwYbWCm<`R}?q@m&1M(|6!!P`)^Ut+@BatNQVYk(B97u!t2}M!e z2uw&nI-$PT#dxb9q-sAtHP1eOU9J~MJ4jGGT@dLdJ#m9a1z?8~uffy6c-(=jqVH{U zHB0RY=JTL#65)r_+#1}9HTq6<(+htE)=F^Qps8)*C=Sf^#@W$Pad}0BE)gE*8neO?C}8XE_O zGb8joUGHiMuQ70`jcnJ#fkGlg{-|f~C^p-VEX+}&3QbMLqRK5s7Tzvf3~_UyAKz&A zQq=AljsTwHh9`49?Zq7T;jRE}q>C7Jc?gTE%|RM$oq-nQ`Fy{f#G;!tBCA5^ksGeJK+Q0@-lBBXrJ>Eib4Guj1H{T|O4Pa4tT(4W6W%5ko>U zlPv0EoN+0J5pzNwfW9IfJl`pz0wk1@nxIcX2vkx^iu!gA*+f+JeZ4f_AGPJHi;MAL zJvdUGgqD!*9<#M`EjjDnMYVgiTodkSl9|4o`Pg7HoMs>MX zBg9w=Q=UVjDw5dpc4R=u&#zy*_&!Nz9a9{!` z(==QKEW@GLA=`8u4&erxd}JIeOz#69CJ}-*k>tfRS9!=SwCi1MuxtDQj_`0@aa` zDLA^tFld8@St{b~W3Kj7bNJ0svG&Lmdrr7T(J4s0P0SI>`G$w^^TlfV0uhyyyOI^W zh{F5h?RhJl5rG+}DoLRD>X5`q_*)&hHG#%K^w+1BPYj)an(Cl9shDC{<%5OK)JZa3_r%bqq=9)a&Eqk0Z=kP z3IxZQUEuI|gzPH{&0Mj7s*g)dkbD0VuYnssn>Rg_8!;BS2u@_+(U_7b`TLYkWW9xI znZY(IC2c&7=wle=XrW%n@<@wIe(co8tLa>URj(m8c5<#2Wk9k*l^%3EDnKAIpbH0b z+eL*rQ~uy!*3FqJe7-0P!=tSY1raEK?k@+1*Vz@g*DMkgO@p^OWV%{dktCHM5~ht! z9)_U~Q#0npOR7nCJWTzZb95sd)O#pS^As>}NstDVKPfJAM|oDgJ={lqN~LTFjUQfc zFTAppib8s971&R{&&~3my@jB%qv_1isrRW0WCq^Qgfh~EVTUv49)THUr%3&}Ls;$b z@k*Vfpi7!BH%k?u3=E}7D}@FdLQC{@jk?rXuP(7VjA2Kzva%{jz5V6>m3aPC{>E|7 zIQ9|HSS;8@m`6H)lxsSVKe|(>UV!t0tEjHXX4LI$WUWi{q00SMvlEQ$T`0givF~3^ z>J1ha*1}1p8kX=SfJfoxUi+}3;F3#~TFiQVAf};%2X?e=L)Auzs)RK2q=I$M1U|nj zybfIuV({%pnYy9{H1#C}H$78w+UlxTW-5Q>+~&Rhq?dDZ0y~<7V5q^>+p|SBB2I9F z>&YX#&iy}CTP1ve)5G06tF|FsiAUOlmv3|P^AY6H#;?Nk84+SMgSoWHVXjuuT2w|s zqCfF;oE9GSg;vo(63tOZSXTDP%7VI~g^;Sb%0XQttvJ#FGrc6(0n>iKprT0ad7xXr ziU%?P>wgYmizuV>CiIlfO~}84tb?PW#%IkR*z0&!y$ucc2u%=1-CN}99y?e+BCUhT z#Iy9TrwW}rolukkg*ewgi0|M+IeMZW#S4Gy!jJZx7!&_Agof`^*eU&k@$WJedzSUU z6vC;)oDune>-sS7s!HThUFrq5x{p*V`2v$;7oe6??{8??Ero_SnF?+;;4AeCO+Un( zBiWN-v*jRxR1BT+Swo$fO$cpu@K#~pkvZ1ZTBr%TRP^nBcV=wK;1FGOMIk4?Thpjp zt$*D03bU|)ij5<)y(bBihU*{Hn_cL7xt41> zzzLdKQZX-ur5?w8>L>uiQ8u&0G{$!6@Y2`WMRz_?>TFDA%o*H_52OedoSJ6s+tUr% z#&d=M)OZC9OVyQHq&z}WNJz<-;CQeOcHc76v50Y;<4^ptH+0SVNd1L&NH!>=!|%?N zr4@;20C~xIm(R1^cyiw-3}$+tg@B5b88Eq&DBJy=r(a~qM&Hi8oUYXSY$2gs#+7=B zLQBO9dph}&hf_o!cq&g_Ndn6hIjO}UD6+=FeDr-(pqdGFva7zr#NI)7?KeJdQyos7NNF0;Id+R=Vhxp6c zkQTJ(c|@!)iuX!v1|Kk#!l1YF3zjF*#eG8sqccL`pj8i5^E=PSQZ3S3oSH=Do4FTl z{vBW}HC#l-E4`quIbRv%^_5ALSjow$|B*|-xOXr zf6oSo)jYKCi=Q*!2jbh0N~K6giN6rphlF`+`6blB-G{vS{8ZDDf;(_7E3MQfxH)E% zQ=;(><1|?<$-M?&Mx7W_9R5F}w7}twtA!IC?J$DDxINHS} z1wyU!e2jX;5VvnJx!Rw+9GOh^2^Qg{XL$l@L-3lJuMZH>geMP7)$O~~EC@0%gR_#5 zJ?m58KdaKKSZ$-vGVX}eZ`tNu5<9pu?~dIWcX9Uei!h%34ma6*tsch0-^*xUYN&ia z)y_mje=o)+!1~gWlaYv*zz2v6>p&K=on3LA;5)Ng5>ip*DWpv6G;GJNva9aM9>Vt) zt6KH(c~ai;`!~4uQxCSVJkQ48zH__B_|K`|WQ^9As=>OIb`_EHk;%-Qo=OgZx47P~ zlB1B*k#tC52G`{^{R$R*QrLtKGLdN1^)6xFTvyJ5)yN9yrkv(jyLc)Y3*hxat@t*H zoR%SjQHTropkctc+ck-@Vzj)`N{y^Y!mss{hFW8hl<(7Z0yQ=%rRuss0$;ze}o zQ&!svYkHAw>lp{LAI!i7zeHx21~>O^R5C{7>7w}9 z>0*lW4uQ6I2i!|x;SrzJcUQP0wY~a^w-y-r58e>2@wC~huj~~VcDQCdy4yw7^c?38 zFuYn?yDz=$N}sB|P4a0wGw=G=Dbw(p*g~X5VXraYdKp<}L{-X~$m5!R)-`_biM5T= zw=D~S_Q8v2HU&?5_hHaqqTt`EnCvv4Zldvi(=o{^2pN^&@pOex=+uUXccIHS31#u^ zW3l7%*Ha%MQm0?;e!^C#Ij85rVEH>zF&uDd1)XSeidW`F1 zypxeBHrV6E?@(_|YRUX9HaLX@*j!boYpI@uWvex0F3Kf#hBCcL=D2?!ywJT8+}?YR zm2le(kRaZF^HZPgmH(8A>)%Zdchh(#KH}2}4`7GGrr^FE?BDS97Tcb@zA1Dsjap(S zViknO=e}9}>E4-3HT@i1zbO?P)~SGi<+Y7XS|{|F!Og zLPW$srg#BVICN&v5|LeiCRrcKX2#Lj5RN7@OzN~aTLfW^H9H-;!ecV(*VGxPYifo| zt12pTjtNi?bL0a{XGI{?z}&*3Ky@#m-eT7Dn;GE|U?HJe^b)3|rk3RUpDk6B&@(gF zn0D`)WG)L{3~V1BvbX;+kiZ!Nyq++_*phA+YUbRJ=R*PjXd5Z1t1ppS^irA=u4$S` zS@kh;2rKCB+uPeeB}hNG`EH`kngXbFC-}6M|+$O)U6M7$Ud4Tqh@!g>(0GvivR8fYL%S z33CWAKpcnLY`{CB7}?n?ryyCrf2Xezq?puCHBf1A*h5n@iC%AUp&6c^pBKo&DvI~b zrYSG3w_a8n&~H{6v#m(s4kPm;!-AB=+(An8Qoeo$Jjva&GnsVcR+m#T4ACyE!br2V z)5XfqlkIK6mIV2+p`j@PF6SeAQ;n0CdY~&SD|?;+{8&O#GH3qU8xtNL z-jh!lJTlnPQ1mR)_ue}ghutI@Vv-3-8j|At~}oyDx! zOlGWNRMc*|T}L-y$mab08!?f|jiQENKAj8BhCl~MC&r;gkE8*4ZSC#H4{n=2A#_>| zRdXsXyM&qU67aFjp&&XMxox@=J0-QDr$b#<&s z@wCDtlta;Y-1vU)_lwS79HA@fir;Kk8|VUGtyifN9T+w6e31R@W$f=8G zw1*k)66E(nZBgPhcwn_;Y35fRZ8oPaSFm{dA!Z1viS-x0)?r>3SP=q}m*``q8N z#sy{?uaS|_IjV%{6mM#5Ziwa_+ut|N-!&hsHB%6#YPguNMz+0nJ#PBxCM9nr@`Z`g#9OBz!d%ZcB?O&51alGvYXl(_bA>!7{crWs+j%NmSC!V z5+3Nyg@Qxix~=w+x{%PX`kb7cHStgy07J^v%Wk7#skY37=fVek6uR)wL2=SJmHja| z!la;CV}v4??L~T*aUGCkV5qeFR~KT@OcKFJUaO>@b;>n|i|MO85g=Ipjl{y;oV=#b zaTQ}S@{#j2AsZVGyA7Dhl7vw++&r$;Ee8eM9;4aVSZaPd-&uZ}pZpB%)QfDMtgi@3 zV&nE*E|$%gMHcHD?&zM0wu|4bL*1YmXx159vbbOuyLWm7cd=NIckjQzlgsy~Ck!Gx z>@zzy?-Y4dZZO)O!}S&-AQk^5;iiM%i0~D8X?2@oW)mHFeXKfKhh)QE75-BYba=W* zM8S(kBp&lyj}w5JiF7!t}xO}9#Y1wCsO!IWH-yKeB+gv#G<;DW>=Mu@a_8es1j$=Nx5#=PPcgi3)IkgM2$WCIk~kIL%*PbPu<-J2MCeyk6aYr>2&;+sX7&JtDfT z;RBn#A%pxA0flkM@BB<~hO`>c&`9RyggYl_>hSo#`VM!{A#d?{kv(=jpQDVNF>rW1 z@dl|v*^2OwkznSKu(IW%NJzLlb$=095`Wv@v5}#k3qo7%863PBCNA-+tf=~UI=|Z-{WPZ-??BC-2V>zehlV0|CtUqlx(|K|fI6nMX&)Qpe zJX6eknGJ@DBn=h%F$aLu*qYCdX<+X~%{?y$f#}egnQ6q)OHr>p>EMSClI}KgN^F`R z0da{`-4rH4%0ls^&o_Cefp_`1!*BK1Fgz2?-{+ZxrQia(Bmei9u^+YWMqf5W8TrdMmZ?W`)?t{nC@5DbRzQ}dL@jQC zB0arlY>v9z`K$W|7pUsMz^yeM?-_`~;eTn%5f0hu3qzSFpN9BoKrr*m2>EK|+uIDz zpLC3k5{=ut5!d@S*dbP~FPUDaCxg?;{^ic%h11LG7Dh23KsbKWVK(tcF$N#1$pO?f3P-t@kMNd*;TeNErcj6y@)>Dp|*6pi=s zJWsrUJz6q>yneIY>v4UAH69-4`;?1gO;hCops@7!52au-&qUb*Th&Z;G{lI)L|pFS zJapxyHwpPjI7>_&J}I(M@ni5-O+GLZF~lW3oM!tvpsAccLLze|c8j$dFL;ySUpdej zbj!#tttOg0%YT?4SdP3}my}>!pR4U|Y)s|nlS(Juk@fm41X@~J=7vjUj4&hJtg3Kk z6yX}r;!FPH4Fy-;9A-A`N%S+zQO}LkygC<`pI-j24g6}ga|%7B2oM2^{r$pf;;=$4 zIV1euN=lZAEqXeFf)J~lsY-~rxe?Qnc$Y}mL@5H4g`P1X!s&FxH z1d6J0UQ5Uhi_HFTQQ^|b?TP2OmMG=g>87i%tJANjESfo1Qh_A-VQs*Oc|+5{hzSRQ zf(Q}N-51cU&v>oRh&ivy6RO9#gFHgRm}L8Tc?R43l1zh$cP?xHD(YM>Gi8e~D@ab` zfwe8yD8H`t^LM0rK@+^~6 zrE+ILUp=nDFmkmSBQKpxUBh4SMzhQ5#zgQ6cX2~)cCE8^yE?sdl zXr9ce3kAj*eH|vsTWp*$vu1rDGQVC?^bG zxp%;#c%2Pq;q01Y?lfLMWiAKxux?%CaD|I6&K?@Cy#?X&i!JKNWd*Os3OcvW#_bNt zN#@XlgdHw<8V&3K_7~})>yjUo+dx!OhMQXtM~cg7^pxLZ&c+cF6rU?9{px3Y6Q=Wr z4-5Wh-It{7`@9J$9J$QkWbVei^@?_8gErGi73+xr4$^mr*mjYBS2#z_i6x_%K#Y4F zNunaq*^Ib@x`2p}CTfoD*i~1-ycjlLM_ehCKpN!QL{egMgvyy9ouTbbKjj4MdYCi+ z{gZS@(A%k@>=FC|0(WaiQy>NzvVyc`H-2*@BRw&5BCMr^Lx&JS+S?8N?Ds&cL!_K{ zrkk#2&MP6{`J)zcUB5lTSK)DDcZ(y0ISoJ}Y(FebGaH0r7~=0}aFCJaKfyX4i*I81 zb7aoV%`0Akf3pV>+2v#MuLy{^QW*B+%5vf;60ibRg*=c<`Qab9mb!SHMeFWNeIqWjY)5)6%M#6r)?%yK&=YRje^P zQ2Wp6D+A&z+huYhqI~#w?`v|}AGnWgdTJJxQ?GWiNt~Ov1y4a+PIz~qaf#Z-DNcw< zKSo(S4qc^9voR3(76oIX@QF}@-SfyL4%OY)f)NT&r)tfPUhX$vk2F`RnJ&vxn#7aQ z<8pg`7Yr%UU&lhK`Q&yf@TF|(?FTT_P@=$~#C+JC`~lR-v!-vMT|>rqwgzJT0drxj zwM=`Ch;dEVq%fP0R)Jjgb=9w)NaLxjb&Ojh`}aur$$jmxjp>pYQ@%X)H zoES#diguhl_?8ie=6g=}?IJAEuNM~X4w;#aMx>gh+0 z`!3Z^Q$tUzq=hDV!O;-4)SN7UPRZPlo8?=cyiQ0(G>4Bete2m#) zC~0Cg!jE7Ti6IpuxaXS30X58Z6C4US2afY*3CA_=CssbIdz9o+^)YA<8v2X(KZE;X z5)%PM6%J1H?=`Wh<1?aJeLPJufa(2bq9}WNINU@#T1Z$hb1XMhh64hKy^tJn8P2Xp_M=W069_M-aoKo>>09eg3_N zDC2Cq6?iDOJXn9$(Qmqe>#>}Vd+Q#wAT&@jBGTyiO2$NMnNNw4L#U)XCnhb$+L@36 z-3oLm?m+1#$A^Om2m@a0?*P@iG|JuF!m8^$njiv?OjuePbP_+PHdKKc3`$n65Ecb7 zI`Xc}a{CJ>N4}*?%;eBeDLO)|QEq(c6kddanqD@ifGHzpq~ku%UU%dqcCM}sueLj; zARfd!V-*u~t>{0=eJ;pSou}{XHC5`8JKxWj7sA-M#`nzAKTgWZYo0F%pS(jRC4u!bp{L}|G1}l7R4vFeRsN zj63>n*D2Vl(~8{WhSOqkt1fcxBue)cqLRo=}}n373b*?zC?FIO8y4(d8HM z(m3I5Oe1dBJaVB|JBq9r$O{$;^heoIjSR;~?eSp31)nIExmWq(OKF;Qzj#ohEjKrp zW&fMa{{bR0z&pgy&|^f6w6{J;QF%2rj3$GMFgF*!R&3-TLCsCo7}&h|z7b87e}L%G za=}jGbtAhLJ4lZtaDCEZs~RJ+*np9P4oye7Le}uQP%f{rCtm>bw(fOdY)5 zToGLIxPa!#7T1^RG*$n25PPtb?<28R7fnTBV%xszMg*%ZxDza+&LqN8jZ6_{FmUC#s0SPWTVGfY09p4zFEA z+EiCK8n?*47Z3I-K;Pw9st@_QC`p^*{pC={jgayTn(vec>ve**AIMW0zIRZi@LMpT z+q~iO%kzhg;(H+@-5~jJc?acT`1PJ>U{t$Kx&ulu((S?{J?g<&R5|8~89hR#9<*YG zJAFJ`ErY@Prt(y`#g~dr?#RhjIV$ID)yxfk`o7aueDkGt?u+wv(B#U2-Nba7%=XEd zVQ9e5?)yD!R((1unBw$Gk0754)*798b+x1@!{Ld0;b$$HQpvz2n;z^0i=qG0Kgz-A zi#tHT^^30EbL-UU(7|j`56Z)y;G9BkU|*Gn@pgdj42Kg0MLwf%fIbr@sJZ^w?JlkJ z%jbKI3NwRDqed#y{&0=?+PG`lNZwVM2&+FVN%k0RVET363DGjn4`9U)-*)PCN~rb?){B(30sKE*M>xnPiVoW>XkX$(u#A zh2-|o?)DW?F5tH4o%xi0b6Rkvan0WRnDl8J^W~wyH>Nt~lGhE_`)T5b5QnQ(@1zp< zsGyPpm?%`tXTvl&;q8;96E6?+{|sjG10|BIhnDKe&VDFKbHQhUXw>eCmw!H5bfK2U zAnPqvJ=MxA@*ABA!icHlvw6XZfY{Fq8Kq33mkJKb+vTmPN>Na#4*FMf6r=zh(T~IJ zVy$JR-bz?m`E~*z&fGP|;EsTNpTwX?kIm!GD3{3<1O%30=I7=_XiYKab$Q&Uw{&4R zI61FFxUDxkcpF)X{{=}(|NedLDCK=zZM5Uo)X-S}h&7kV;=uwGFc#j0G7T1>7iQny zp;shO(WgHTb2^sMW~J_%XrNcMV|jUbLPln05f>L1e!1mjr`aSvA|76*wwKo{FDL|D zigvuYgpsMKSPToYfeQEaQ>?kSgou!^Ft4f71*MW^!Tt%QZ-a4t7yE?7^L#{L-Yr`%Hv^n3EXg%*@P@?|2#;(YLVJloTiw z6co=4I3vIJmwFNFy1KeQMMdHfaQV7HZ<9+)n8(M*_O7l;P~Ql$5RJ^tLb|#Hu%@Z$ z;hOmY#2NApnBn1oTl4El03H!Bq`jRN%R`!mh#RmvfQ*^vSZ{BD`ziGU*Pb_kocB;K z)|vxCL!mISummYliAhNVgQ?v4pym6>DJaC1%oG{np0hhT_~H{1QtO#h+$nLsetpKH zx7(a>LzEKvDG(Tdgo-M%=xs|xLJ~j^MvQKp&M*Fw2I$DioY{MnP?fsv@qt8!sw$Xz zdU{C$04gs16%YW56{u#M3H?vmP;~4o!HDKkG7gK5F6%i_Ww>)(P*+5t z^R%ev>;7nRyp4$kh$-X$1;|5Y1YRUiX-$i<^FM;-@>D1&rht<|LpatJ_4F!b&L^Xw zr;pZP`9H`V_^kU=w-q?#P(gnFACKFEI#3NEA&~15De-cfKzb{R#9R8f9OMw;aDn5NJAQ6FCYU;MMz2Mo9E+2lGVNj6KCYFMt*_(#7M2avY#xAP`9PZ2?xIdW$m^P$>~;XlS@Df}cK9IGxDv zRa;C((b2E}-Iy-GDmxa^wY|9ky8U)f=Krd&hR*H*eS*`~EI^WymB+zcMkKIEF;7f| z11j752HK{Atf$(3Tc}K@H3CK8QR{rdwg)oYuG69I$@;yQEeyY1Q#aa&rC zj|zDPua~R5;wOnMoiyxq!sxzc#MuCk?OKzrw(T<)usnr>fWE~QX~6qwXagGLY#0su zLYZ~UMt)NSo<-la2J0&1#{q(RO_$R%IeN zXtqec6Al4kA(hvw0q>t?Hy;WPi#|ts3d}w;L|hJqrCiYnrOdC2m`{%^lh2Y>CN;eo-gJZrNx@5!@Zf!1@C{jY^Xu z<0j%1mR432RVhZ^GK$)y-=H~>hsnzw>n-PV2T4dsX5G$~a>m~`e_!h5o2R({4gj>( z7%H2dxI!JkC4pR9G=Pub92g`-f^rNEH8wRpaUd2l;{m!4tBKrbYnd-20J^Fu3V50_ ziiKid|6c;DBFh8ZkNUCsc^3_rWl^w4&*OJ0v z*?tm<53yNq^!~9e8|l~Z%)mFynx}JdH?$g|B|Hub69W(G%|e0mk%do0b5+K}Ye8xw z&LbUEHZ&Y-e7L~UD|7Gb@1JKlk0D)wQ#r0QO3EVBIU2=xY*@1IYsJ)fg3gjktKX;* z{(>Rk!s4=0ucW^`ooyQeSZXIba3zR}1Bc7pj!!Jd@1AV%s+t@yJJz=3B!pPQ!@>RG z;z~+NnKRIXKP?l-$%QoHe|k%>LbvlM7nh zVJN30DeBkf5hhBwI_dvaS^ufj#k6By4?E$7LL%DDGLPK&T;Z#E;*{g>|5ciA-w#}O zE+$DXKUS>YQ4mdKD!s3tI`l}axd;fC7gaC_S+oK_CS0bPOQ>vleL_C*MgPDyt^*1* zPgZA$hAiGv%E``Qp8PQR;1@*XA&i# za0(nOG+5nNLxO5z)cYp1DS;=@kclGC3s0(VjJn38f<72Irgm_L1jH#vaG=MCgB-508BR z{Y!wi8&Sy=gjdAviKglJDn4lp;oouoKpZWlsZLl^gd>ekhn%zXJezy#bI^3}V2|*+ zA2!AHDD;Vn5v^#25j}C-Xz%9^+R|v1|9-k zK;M&&<`Mk-z5|i#va4y&pluswu+b*pUkLkE%ETF4$R=>$X#|&~$H3?W?$ciFVxK3H zODwv096G2W`0K-ZhJc>=4fCl5R!)Tj?1eW0R1o&l>wyS;87M{r5k#E^xySbN6;~P? zV9Zkc976+HQh{j7zkQ6C-~I<#Zy8ocvt|uHNeJ%lF2OChyF+k?;2zv9xVyUscY?dS z2MfM&ci+I*oSAcG=KZd#|Il>zuCA`S>z1`v>20kBfa72arMOvn5cHilM0{gNg4@A6 zK~(y#1gxysP0l@iT=nMi{Us)}(9TZC4kys#p0^`0GK%tf#~KK@k%cLYmy;7outFgK z9ocHZwI+uRijXX11adEsw`VE_&ha0l{mJ0lX#+RkeV05Yh?ggqX(lE?H6_$FSFHxz zIF2eZR(`@@xeT>VH)G>4yF+{OBHzFNG&bDYt#QDnbdX)%$bIzoYqR6>lUe2GTK`if zUc0D>_Rp9EH^|u-_P!3n;MIo+%sc*JStoisX4`-F2HlQcb{StNBiiTo8Wj}H6deXv-Sit?(6DGn=1zQloYc_RT`*j}}%AlRK z{QAlr*P;8R5O0pbId7v+c<>II^eCAkKjz|+ai;!|DG0jx#}MWn|FrRyjE=*~5ReaT z_V_jJZmW=!e+=ZZ51uB~jrzHQc(*nk(F311WGCQQldFg(UptqWM1K}uzFOoN^MFC0 zcT2Ayu9dd@^xycQi{Ylkst!nX10^L#^5M2vs059-Mz%zamhA=7jxYDG7s@aiZYU{j+?V!^coTwQb$B^JX&VTAo#sn&~7&Kb^=*UItRhwDeH z`22Cjm^6xD827htr1%g@nOnX&B>E4eaOF%UOxQF~|1PzCLysFNttmC=?k~{6lJpF* z&iXq~+55*~cGNp6QBvd}O+5z(+d=GOl4sF8SrehmjP~JX%{UFUQ9faUUHq z%`U`$4N-GusdGfmN>;lZz`XqSS&3wHLzaza>)4D5kfMC?K?_O$@+UDI@L`@ z=HZa6zOK#=)DP3{^{8afB{vvOr`xImT8Pclf(P3W;5r=&H}!dW+uaLIHG#$6$@A}T3l&~KPC}$e?q^#Y&)#HK1OboB_otgfje1jr zr`zL@pFjWkYV#NU$B!T8b43V1C=6gcK9Hn*2g1OE<$5YWhC!mb$>+r*?FI1WcCqvw z982qsgOBPuy?y$6H*dSP|Ew;j+MRGRI1oi*20(5BxiN^3By?Gsc2;xZUN7gLGan5Q z#ZOj)&v?! z5dzZ%e@^*mM#ITqsb{)jf=Pk}}YHG?q>S4=vyx>i7{-_yhhpe~W>^E%Y zgWchY#88duxlB~E$I%Y5K3nyF486K9?o~`dOZ;C6pg`R8{*0Cfv4vUxyk91H-g>;y zbBua}Io<+s5q61R2mx@}d9(HJ&}UrOvhwd2)=M>hRU_nby!}?(dEZeAnn@*`oPLkL z!Jb{K>{H|76A;AE9Cyg^y7c;p4BhQo%5yz$x0A+ro-FBoQ77$~Ks(X}FO^$a`O@0w z2nLG$5Z)*ZQxD7GuL9G9Pn$LjTdGay?{tk->~s^9I8+>$Uow{gVI80IKP2U?#i{`e zx>LYdIn71d%kTwXN|06ISB-e1u%?Ew?o0r*XZoAlTe9-r4%oonlNMLLc|t-ymgj|{ zD7-Rltx_w?BH#0)s_P!Zh_AwVObKr+cDvrRRkCk%tgOm8Y5dy-U7MDcT*^hV_O&%N zZW^jNdAFf)T?s+f0-R2E*((e5R;p|rk=EAwkt@F4QYEFDU#@e{cz202}J3r>U|U@n3<2TWIRJxXqzX^$*q<;QZ~W?ot~mJs}$lMK;4*q*DXCJ`v+N+@ z4>#~%)7-u!5SWe%iDO;RXmiK*aezK`{u`m>{ zLd>eAzgm#{n#P8wS8qy6Mk!8xRw=(Rh3s=FFc3DB`624EuM^Bg4qm4WWu#Q;%kPmR z5oYjt+2`^h+!K6TTrHwp$n=P&5Xk_o2H36ophT$_WNaN~K>V($48zF0C@eH902Gs) zeprTUD{O3aNuX%3_o5(u+MX^AgHg-!3J&~3=QTTv&zF%lbL__JtN&&EfPuY+bur|* z{vIe?m8*$!51X*L=;F~YBZc{hE(-fW20McZT3Sf)yZG?Pc;5UtR^P1URyO49k zEv@EGpY-Jf*Iqwe+}%(^5O51N*+@hQE&1-}nVCf4M&WKxKGc4#n9uF0!QsZYSMb_u z^1y(=#WioUfg&Ca+UHP?1B#VnQ_p=a{m|r4pL@&>4NL6(ck67Z0C}cnffuWHj}ccs zOB`!a=o2~_VX`Z?3wVSg@L{Ia_yd!j3)?fF{_zs6=@%`uLdaD>O}7{ zVIV2~KuqCT5>E-^L)rwG0hyfrGuK(C!9v8}_Ir($Ye~j7U92vu7g=`fhVE9eLlE!K z4$jfx9go&OreBx1^crYl> zAltO^+7bXO*~1j};e#7^8!3Fu9ew{n8SKS~C; z@xf_plC|0*W*S@nQiAjhM;6}N1R=C7`!iONYDbT`rY&*`!$)3E&tKnCkE9`~kQ>^Z z=$%$;Nwt-k`D-0VJ*=TAbg)OYKNelStvpS!VauTHWUL~evFnl?~ zh@JUgV>s#AzJ|jWTyV$qosm2w(((he{p@lxKzKpJVFyMu-)mcLitZ(Fg8cr1n+C@Q z51S02%+r?RO&iJx=}8pX>DPP%c9G+hrWNm502(rx`*#jL7O1(g{gkPei`HzPYBQ|`hB zbZVa{WaYJRt%DIH0J$)CE)*FJB%EONHrJkZGljxV?+7h=ZPJ6y57$|rzOfURHb zwnXVcJD+1Xrm|a|a)kVxPE|9A|3s!$&VgH6(ctO889(!AzQ0UyBDTMyn^yi|W*eZs z%z8vy%fn+5`S??;x<~cqdy&D%Ufr!rFZH;^24)+% z&!JNzDtL*p}sCj$K#2HC=i zaUbqcL}q;M`9lE*&2xO1bc)2_@98RnUlHZm)I-rQlkFRq-{g>dulED;KqyoX&zEe5 z&yL7r(a%zMDKa*mkfBy7`_ihvvjI>8+!PSU94h^JEc}=(=)mI@UEIthK;WZfQ$JE& za5nqvJ0hs&xhejI?2MIs<<)@W&||SdG2Y1a<$g{q-USeU`&Du+^_k9Z$K?TE!QS9* zBVEU4Zoup^Uw8-rg5<#|Oy>ol*5-+2r<%8hI-+njv;O!kTLn5RykuG2p4zXLf;e3N zBSjG$)_JZ;x%DN*EivVnM7DpPSF9nT$RjkDz3kyxm@}#o6Sk@ZZ*q*2F&7d=;O}H! zMD7Vv;V|M`{MmsdODe*`>m?8gVyMDM|KRn9_-!^PHuH_hach**yuZ`E|0HNgq5(6H0ClWje>r0*+P`~`e71bzxwP=(Q+4+?5D$d_ zSe$Oj4P5p1MH0F@>i>h(NvR1vE1xhlLchYxcN_&z_O@V!0*V_+c!KQ zuI*_zHF|oR(xT7DsIb%#j^oE)=E9*9-i0{45aafZocj0R@qC z;chW#i&u&cQK-g-{_!ci*;*PQMe6a^oj`YbPtn2WxzpoLyz4n>IY~#1l=j8hm(;@V zzpcJve)>xnvQmF~gFk!hmGlo5xCiAX|) z=}HwDFm~5v{s3TzNFQ&lmgF)cle;Pd-jd}c-Ckwc`UB4Eg&fdr@Ni|K6NH=#9W``~ z2>$vG530mOE08G7RmCyuiIdM%of<#dSi|wUVT@JC$cqkkE|G=ckeZ<>E8 zvaY(dVwB?8>r74|LUK1)$OqD)d4MM{2-d!>)O?_N+DJg(b%^IP-)9Q;ioLnt)WeL> z>!28NrlT|Ga0a6L8(-tqi2dKxAUkjVyn)1SzP1Blk0kN+<|W3jfj{WUZV6lelhLbINKca!t`NQ}X>yC+ix?ia2yQ!u_;LX?hspBQ* z$4jk|%O>V^K;TS)yjWs8eCo}dAy80shmwlsPb?b(bM26i*1rATt088ZL%-3E-S3Sy zqO{stH%?c~qo|i~LaG*+*}RjP_7*0~Q`v$1u`p#xN@qfMXEGc1w+}Xsth^f+0`t_3 z#`~e>ae*P#`@~!@{2a9xxwd-l+Abwme_0t*#Z-|$^8{Sd(}%1T%S3m$zm-h8lNa|m z;9(@nOpO+bp%Qjx2kekPtU};GNC3gT=H4n4YnSRlN1f0A0XO}Rv-&?!)&KEK|Ak)t z&m|(I{bZcv;S6Q)_ROTCm0I^;2HrRZ_+24&T>`y0#rdn{2y`TEJXQ_u^pcx^wzbQ0 zhkKnid4$x|<8r6gceTb}XB=!ic$0gkG+C6@+i1uc*^}Y)@Q?)`9p4-EuNJ7#Ujkxf zpR+?KNe|XSvM^%~jOBDuS!lAWThH_61mat)W%B*@Xz)bFjP`$zV(q zWWQ!TGd_q6K*&LZ314n(m7%gSQVoZa1ie7Uh&+zo%>te=C4o+KxU1--JG1U)VcR=Z zh(!nI)?w;#QcFIX_)`5DPkV5TX}ezJFIm2i0-k0c2nS|DE;-JGc|QmX#|Hj0uom9d zAO?r-YEG@D)h;IO2T}s}=|)(6Bo`#s2o?SaWAEBB#=$y7pa@MNxbxf&PS zvY+K@>S~r-lus?*aS!9t%Mq1KsvF-M=!vS5IG-9?Ep8}Xc#!ft?ByHtB?%_38sR?@ z$MSAFzPR^b#LegA3}hT4;wKiqBNmbVwX<^S<_Eja6b>Zcs4cX8W-jC7i^kz?v~TYHN11<2do{6ZXkXxBmZbFBVr8h)Vrur{G3=LsSKmrDN? zJrw8|xq%y9Bu#4bfZKhqpzF;(IyyXX681(={ljy5zW!XbH9WI(G0!XZH<5~JD|N^W zM*d=+69K!UbzZNz2LwDV~Veg>Ne%L2ubx-{%QF-=X3-6*RtdoB6(tWOARy5vRT z5jM9cPobx%7TmPZm_n+Wy3C_Gn%n7#-9dpux48K^v&lp9;kBB-$C3m53doemNb954 zKn*SphC~Ie&i0Pef+{%ok59}mJ2r$~xy2|pG@u-rsUH3E67#A8Y+sXo)i-N{-R(BJ z2Tlh3oJ|Pk4ZC%$MpJG>yOP5;!dZg5IH$4~xF5VLflK|!C1oWMms*@k7QqKX9WDdw zhReOvdhp~hZ8)79raAIvVdozQJS~aU`wd>+H z_i5oW5_KH<1CU5sp2hzG#m^ep@hv0IB-h(q5h?|CqfhBrMkH*dIYDrd;!wCt$a>IFP6bAA^WfjMV2Zr6$w&s0L z;*h@8;6^sz{;u&bj;$i`q(%Hw(HhnYHCtAEUxNZ1z5e7<`XF zFsvyys;W(bGgWbVIaACLYck# zHQ74ydsBFJq{j%+?k~~_GrxVm;}F<2G_WZ{_+-P@8o(b<)>It9Mf4b@kV&8(63#^= zt|TwmoPmrOT|Py~JhHt1RcPGZQ?jkvXAq|;D6uAJID)TjKqpdcOfo7GIl<1KYw!mQ zrxWoCzYkAi68^rTMmxMh?^S}HlNkoEsG!+Bt$Rs_D#3P;iz7pXK?xy~6G8}~OI&_I zcyULUC=rOshw^Rt`E*ST4GK`C8F@lP z7*4l`RJ==`wdUiN_Y^clkZZNT7vBp{4^D99Y5th1F#JTSq z7Sx`zSh*C`@}1s;<2hd{wt2oxLO6Ek&Bq^==P}|&cc81$^J#-46#VA`p4JK8=w-S& zeODxOZ`VIn*1<_oYj&1W3O7%;VUu$)hSE8$ZeY@nxRx~ElvM|7@j6?2RcO>9 zgIjS!r6e)-O8_Zh`wmNkHxq@Ev^AWGE6%C-!FKzQ+TCF~S=?sKIrZN|yJy;0sXO><7X zmn|?R6ecQk`e=ZHW#0)iRE_zyAp1s)`*D}p)B@V(+us0PG-qH6ZQb=LxAbbH{S}fJ z`zLIq?gwJSSErd@1CpzDJdruROa3^t+&kP;@!bc?W_Dgj=r=3vpUbt_hnnm6FT02! zw?p`zYl>{FBKh5MQ{J>73DD3uUC#Wy3&b~v@Fq2uD_{n5x0(N9tt+*f8;@)wd3`==cfCN8#bk9C{m`908p=Ti@4%?Aea+1;3YQp)*@rdK zDnr)ppU<6L1xIFAyP-MPvHl zzQ*R(8Hw7fxUnt_EoH8Px@XfC6|M$Jy2^I1ZaAr*zV+fz(tfzKzauALELo`0y3at9 z!YX=Szc4r5=}#mM1u7)P8mi6$^00brOE z%~#s>j;KRR=yfM&t zCX)<%dC}^o7lnL8B*A8kfG~l@|q3?_&P7Ni_U&Z(IyNB@tNvsnDGN~ zVeM!k_cY09tVUMM`gP8Bod$LKD^B3fQljxFTIe3luD4>>Y_rY`u+0Xdjw<;%Y<5J_JNeBp-E#{MS4C0koQWK~@<#d}{r>zre z%L|DAstay@Wr|IzNo(H6coN#zT)ptTMfR2D4nlzP8QeKvH28bvlFwaZ{mcY^@V;`rG2*V+POF>d@h+#A4XG=)XL8n^IFG z*ql$!3V_U?TXol1Yn|u0cQxPmfP_dW7^2x_;9ZQE|GUXz3HpfpZ*zyU%=+Wiv`}I# zL(K1f(XZIN5E4F_nQek{(t#GcqtN%4LS1qhwZ1oBwpd>8`;c$68u8m8ePepwR>(y2 zSBN5VE6TKT-2_S|3MOJg`ZM96LLz?F)Y`Hb?;j4K8^rL8Jt0z6_ zuQ~hR?99Qu-`lfA+8t*${CM1@8n`r9$E{5}l+EEF zBjx+5@R}HfY~<_RD3keskfCT&emdFOsexY+7zQ2H!?5!Ea(DyaC){PWSanv;>a&e0 z*6}SVGz^1gyWvThaVspHf4YjxU)KIG^C&s^}$VoJZmb#kP3UWAGFf$;;i~ z4>h9npy&*-kJ2C;e{lY+l0hlx$?b8HEBPz@KdW!7o0po)+3Mju0F{JHPfxFPlG=Dj z`F#Qev1b6@F@Z>_P^{a|_a6VxX+YJfAHX#lnU1F#NPZ;U21*bit7~grfE2?>qVz9I zfX7cHUn(5yW{iTEO#Q7~jb5c%FAIV^#BMy3I-8CLzyVnwj3iJAeFU!A0lbRFM)o40 zluP^p1`e*=z|{1vx%tH`Of4#NTa)AZOefCM72RKqB4XwnK&g83maEe<+4X zUr~o~L0#YbwhMryR)4o3o}eZ^M@2+M&i@lJ^c=XY`;in2G5OGqHy-3xyYvJVZ5Yri$WpO#0 zqF_Y>#Oz$@B%0!g>nIZggFNI|NCaGbcK~R_@fjsL^P>Y$8Kg)q>ibfT$p--cXaT-I zBml_qwAC;(Gb3D2&6FU4mXQCz<#Z4WbW}))geZVOiblWBkYOM;o63G6-Wnz$7D=;` zI#{aRCLgU54MRtwr?0g0_4S=Y!a!>I36H}fS_=k*>MDV18UcM3768O?Q0VRLEz3wt zgZY31$TAEi{y>$Hk>MDH6a}0_!0D}3Vu@U~Rz4Ht5AN?5C2)4W?FV`E;N#=Fu-yNS zj2Mz=<${qJ+melSRbnTWcFK@2fR(flR&7B%2f9=f0H8^70`3}WtiO@D`N32fJvlx^ z*w8+DY;G>`(%-*&43$_JfdOCUL6^)QK>%1w7d88LtR3J4=4c9L^LZA1^?JB4WF!QN ze2j*MhSr)G!GQt9mk-q+>)b9u5O8pCS-}W+og7|32`(=>T3*Ax%N!7NXiJSqUjg*x z?t|9=$@p@h*f~YH1$c~g7Z+Q7)Buk2Gir1^M72j2w{w{wXa-O|yaEt@e|!3k7TY=p zDMFRV2z59$l1y5_6Ep3xlH?aRH#;^2d3t(!gOrqjn9f%Il32A9qEa*ev@x1`e_i;rT zJUhuvGI3Z<56CGf((2w`CX#5?JKbNw?%I#+Ha4f|cU`J!H6?&RSsX+l@ueFXJ{q84 z%pks=#CIY>@E~2Cq zKLU`f5oalqX4+iO{n#x3EXhyod@674djfjw!16SaoGG-xorCa0FW75mB^t{V@Sp4%T(=Oo}35jbT}WL02nR_ z9e}iKMHqYnf34j8N z7l=n8BO`Zv+DQb#Vr=g22ANKzZvp+iNx*sS<`8^&eT_D>kLGI@1oTRH7}*w1=Jvrs z=$}6-B$N(rrh92x@{*FFsTrxMp+kKN*}N#vc8j?M1!Rq%p`aqTu*moUt0o!fes_ZN z=g%L9pso2YKKQ7J{{0021eqwuCe7@%f;0|`C_U{OZb~;2u$;iQ3StW9Kp!hcZXy%{ zwiO*wNJa*3aBxtVxA_wj3yXhvczB7l9n}@XXbK}^U?`IC#KyzUe6r{LSr|KB+b11mkg zTOGd9>MS$9+q(q<1i z2oF!`e()sMBsxX~V$D3_{Rji_Gv*mDDH&OP7@{j33=B--cZe_v3-aTYT(F!X7Z>pJ zM9ua)RRO+Z@52h>zsB(YGmrncMDKCwI-IYcjDkY7=$pj)1~hO7dY#?0 zUBbV6;(b($c3#-(mZUHP!Ry2Ke_2T34@C3yU2)rPRD$gaNc<@=7)V1Hq9 zkJ|ZPq4|GaT?lmP_xr~hu6mWuW3D$K1ri1b(kO#a$O(Vpyr#MWP!wnwn4T)#w%q)D ze?WsE>=qy<1gp>tgrbm%h6n;M7Lf={dQk}hFd1hjQi!j?*nONN`8#~2Oud@n>EqT4 zFpMGqHI)JYpklsIfy1EFEJ!o~JfGqN022WNLPo$+9HNoUW`&8#pi}bDVY9-X$>WOX z=jUf=9s)Qf(EB7w*${MIc;Wo@CmQgi-pzS*uJ-yI7L(CU@Z+^1=wr__%S70!svW>6=+ERq(whJz zUeI6Cf%Od&z~@XaEQkZxa*D6Oy|Ws>%~6VE(?}r!!uD(5(tTAqGm=zLnA+(DBxT`6R8{BE zQDg4EfB$~r0I(u%5cm~OrswA1(mCx7cY%+$W;U70MKqrTVVhwjT=>=bNX3ysHs@ci zuP93Q@bGX-lN_B!O?On6H&}nuR^VFw6ClZ>A|)X~b)uZZ3gnc~QQWroVo5}_0RGF{ zs4oigYoaZn8N@c0NWFc}HJJirkiwDK+1b^fZw{{!&|=AmNQuEbrN9c-2yD&c32vE8 zdcOo4@GK+%)hzaSRU!7byA|7Wn|};?^x#+$AnvCk-7H|Oe8j=EJfjexhtzpq$|CB0sNb!cg2?Oj9$kXNeAvb{j zltn3<+TB$f?qFxf*`qV`o6%j5oRH|lIah_noPWoQ=iw}cG!sAywA<{S1oWsnZik3` z|J2vlJD$xH4An4t%L7JHQT83$odAdw#cW2EifwrT11TR{Q6(_oJvaA%R_yl^?-@G) z$wIibwG|EMO*PET%{9n4e54>J*Px=Lyi-w98Xa%VesP84H=hf!yE|Fd$&ncv91K#*dcsxu^{emb7!356$ zYrw6(MbSce*>b+DXLMA$c6>;CWcl!4Q2aNOth7&u5QL{b?ThNLnEt>0hl0rnmD0O&7ku_A7ehD*wKIxjCDpQo6Zm}>qCnEvX=rGA$Wz0NQYo%9pWpTF-?a&de6tAFg%`lb&sf4khf zFvMPT7Ju6iq%1y#2SYN={-M*HmnlV`%FmCBkBhVEc#iAaPLIar(^l3OILZRqZ+80? zIC*w;;VJ?9hB%$Aaw(*c5;Y|c6RE2&j)>{<3g_^Zr(|blPLPzAm*f_eN`87-Iai`;A;m-v3E1AfaKHk?Ed~yY0X*O7 z{ah+`OLU6EJkGY?8c&0-IispBK_MdYFxcPjOmTR4Q~_HYU+wlzXHXSFiq$IOR=Pcv zHpPR=K&{jgVWY0d z{Oy2cF(;zVZO5xlX{_Sr>nB`G%N;FO$GO3v$8ZT16_wqO^O_CgG8J~l6e26A7LcmB zgwJP-X!4nym+Q@coRp+%?2Kz~pQM;du)~-3_bAS~N@-{dz8X{($D~}^W_W?m*Dda6 zs*9;I*l5^bQVkC-^e(?Zn>KuumP8btR5gmNUA1gRy|MG%IS9An&X%dRBCB#P=h zN@e=t<&;Z`ydtfJ>6|T!Y;Z#g?Yxl(QraP-AHQ72nqw!oiY8vYfl)wtMOkV`v$DDZ zLHz{~SN4;iq!ayjcnUKHegFHBeSIN3X@%~h8gBq&TW9&zEGt`SB{5Ey1od- z@wyBVlHA^<$&RYE;P(AqrtPjVo1+P-`}cYxEtsnGiTsM?N%|j3x@q_@DpL%GR3u7hh3~K=m+0j5Pj#ch5)s9={JFUuVCJ-7W`^$Y_-qLY$z<`T**tV8@l2K3Ii$_-@vvND`GaaA zQ@JafWL%h-M7F^XB8l2c)6XJwTu<=zUFE?EuKL?WW)QE~8lM#O20^rVB6P;R390dZ zKW;0g+taD5_+a|F?gN;+^qrd@#R}2_U|u;-{FVxxoJwr`*xAO#cqgZN9fNR|@;{!? zIc@cel76Al-20m3ClKSFFV?_#-=ka|98tSFD>&dF*ze7(Zh%v-Fqbquo(S5U$eHeX zgy8mvqj{KZONlL*-h(L?^V5mJ;tMHRR(l=i@3nUiz3U zbWj|tY>{Xga&*N(oe_E(drY19vcQnf3uOWWp$6KV%Lw<39@txsyjV&j*ewXn)qlD) zn!*%(j*`qe)H@(TI?>NxoMNcO{y;m*|mB>)?IOr*Q{+8EYz?%CkgVWMK0e!pAYlVjqh6yjXwShwo1Vmq5}Vtk8i+ z-&5*&O=57|sEZRxc_%Vp?-0y&#G=fJ)M6Kk_ZnsQr~Wv?ckMOz36_ld3v_fBIDFbl zeM4{Y2>}4(PA*W!kDQIjmhKQRcevNei)oTDwFpbHI8@Ft(6;TL%VVe5rdF6^XAqMy zf0#ic0v*l{2$!I~ymVE#?OgjVPdwjMsyM5fkPv46aiaDwP`-+aIXAPa`c%DGSMBH( zfc9;Y(-TRLw=*1*+gyL_<7sEz=AvZiw@D_kq;W4)IW8F@>M|N!VP4L|cyv*U_ECX} zB_GV-JLpI+a&^O#vF;(Im=ZSVB-so6VG1|2pLmTXd}tF(puoP$sf96ciV=c?e$hM zR5RGOJN9oi`;DrV|KYAX>T7`_F?2V0!%gitXD*y=!Xc-SQ`&rJ_H-jm{|T8CiGrKp zUuJSE+CV`yC4#C+jRTE!E_q;CMoL0qyQ@m$Z@ZxH+e+ws+G(Upx6H&4p!H+$tttlf zhp@bscn^<4vNS6)>UJ278a+w^c7J~(<=G?QFa|?vP|I$^r)(kh+|sJ4Dj6MqW>bZ) z&vlhz7*s6lIp}0?>&J^UJ{#c9E)WOShiKk_(G~F>RfO!gNAjwXM@LYT7tuMwG5TfT zMr)dlZx_Le@#mxDiEt)n1;Txty_xpqmPw9%cW?X4<~Ls425W@Np`W;+W;kwJdBuh= z<7+XZJQ9#-0ULMxgD3pwXWm_AeRUO+KO$S6bD&f5iz{i$nD$pi>R{r8V`nLt{wSgu zoIQwdO;@(d>>ceQ1pedxc_eduhe7qb4UHoUA8z8nl;&S6eynzgYV&pM0BswCH#W@Y zOseo(o+`wFpL@rtKTW?cHpCrlcunwZTj)45m1%iL@yQ#d703iOw&s=eHa`+fQi?jv zvc~5XSkU#lb#)@{n`vJ~Hu+oVk_b9b&5av~HlAuTAQ10@SB9Rdk|%Swk_m`W!O zsGzzdVaN){I*cbhN+B?> z*QUZS^ESmwqctwq(2!T9#3CB+yGoFj8L2YTCZI!~2-~dJ4MVQ=`#WNxY*@QcA}eYh zo>QqE>-;GVlM8%ck%3{DEUQH;jsJNf_`~#WAXQT5U6-&`#~e)DtxA76)2!>w+qd>I z>e6p=QDEas3H~JK)%>a)c#MX~coJM38p)`6NFce`A-#x1N-rOQ>h~X{!N1@J z{}s}NW4=7yiU6s^fpb8k)?lU4Cg=76*qG%#n%B|MIWSBV^yxgM**m1B=Da;-bhAHR zFynD4FzA~}m8;@$-CPjJkmBY446uc<98FA2ZcbOQpb&?j;#ELKHpV`!DXoC|!bc$W z55#RD48kxJt3yz2kYgS+MD8aLuZQ#7r{e2bZ&a;aD)aMsK#nD8B0cvS{CS6$pG~P$ zg`Cr@HxP!?9++MKt!kNH@MmvSx!bnGhqx{dy4#pe7P$nCy9JLL#41ib7|Cz63O+# z2$b}`gKNx)7Jl1Axv={5TxU#{fNvM=mOBv|I$scb6tV?XMLyA3mR+k64b z%#}Ktiq0*q4nc-5r#9LK6R-(Jb3Wo;=3gcmQjxa9F%;{~6m)c2v3(}xNp;pbUuwYT z!QnL1bF6Q@jrM4~{O-cgLE-5hjk}p&@mMkCH3xkku{A!>P+Sfd|BX+&xdDgdt4v<0 zQdBPhJMeb*_d^&M7)Tn0cUjKU)KHZi_$^-ZHa19OE;7V9Fnd3*Qm8Sf&W*2B{h78)|vmOb|R-e}ZkN`UK z&&kpEY;|4-?d=WDea0PU*X!~j0AhSV+!qqa9RzLlg+y460>PPRgK_uI4@=GVWB^Yr z0N6>0gn>amRBF*rtR1Y9oFV#ex>vvxY%g92iD$CGJ+%M3&*hcYq67oPHh!(e8 z*8sZWTf}Zj14Ra8&8KS-P$7uxM?j^#v~{Z-nPy z0;uQ8s4HNf-`njWSvUS4)}|qd1ou0%guotDgk7c+xH+>k+t-nG^lK5Eyt`0BfKHIJ4F0rB;uqbBG6 zj&Wx8i*{a-MAR8yBhai0h#QJ(Auk5Y#j1|VFF702-p}QgHXH2eRp{TptKMJ=I&q9bBn(vXPwOD!ci1;N>Rku4n^+9kziYqLHb;`m&a_j;E=;>vTaLbIM? za&nUO5R;1kb7NzpI*=uFYUIp3zF%=&&|WW$Lr+VS{&nktuvAwW2fp{rX#~F4UdqFR zTX_f)5n_>c))!eopk)mbiEy=uGwXV)NheYLs|_7cQB9IrxjniY%I8mxj;{KQi6jq% z-yxiUD$Wux6L4C0!+LW8IRF7bp2AJcp7)-b!?yechy6x=m^J3<*RDqtx6iEB)GDv` z`Nn6TsRAH*^akjMs~-Y+N?KhV9iPILoCijga<$WGKstP}xcM!{Z>5n#Qbu}qWxaZ; zKJenAjzVq6H;pY`Ky$<@!?Gi;jrA~@^2*TbT&oK_J!22^D=-qvFD9dMnP(% zbMrD1Hi|5z3W(ea2+6}FkOGiR7-K9=)Q1LTeU6QX{iB)~n;0h)CNxOKvFfy>!W81H zi6-4(I6jsO{QwoHB|N7 z!}04>4bfk~viA-r1C9rc|EEzbz~cJeDC76?7jSI<>#zT``M>`i``@?!``_Z{TfZP1q} z>4Ho1Z_Ci$8Cu)ZmFgO<3mhx#Xx<3pN2foFs|{-x4=Hrh@GqQ<9$}xesBNU-R4cTA zh;7Esr}1;~8m93|QMFApznnVAq#3V@Z%r^P=~MO(X*z)Z+!}{kfc|}^h`vld6#{Ve zHeXj5mm4iKweov{Cqmn|VW(7SscRj&=j5a`ak9(b7~BU%ly!q(ez8riBLzpe8dsg7 z*q1&ypKt2~RT{Z_<2OIT3Moo`v8{;mnW(fM;(?_)gEWvQl92qB#_2;PiJd&CDt94Q z;2;~B(BG<#B6aX>w=a=$&k3v-W4No94RAgG1>n^#&K*5fSBv98! zKUl)I2an6@cwvWob}BMWtM&CyCT-!MPu(Tp1QH^Q<{Ow8;kVzSelU=#xGRe|Pfr|D zOc500Zf7LSc2N^ghc>e)EGP}%Q3-=qNYweG+Mv0`6~2}Owd`$2v3S>9`0b>Xom9er z2X>*zd26Q@2j%jWX}&r%d490__*T`W`c(XF&nhmBdcdYy*9~V2^104t`i~EGuc7zy zo$kr2M|3MjmzZ3}k0no|%zQSJZ(|dNK0{`VUjA8uhld)Tlwg9|WeaEmzBQaI(q;QDxj)uCcjBfm$8^(I6NEdt>GSfQ zMmklZWZ-|4W8*6{B@e$4g{kDTvI4@CFt=JW4u8hXsRlkSPHYaSyD`-z+(p}es-4T@ zF2GzjG^)Wb{UgwwPAEPrP5Cp)r^AWTn@!Geq^SnAN7E=t5;0<#O&r?yNFZjfa|5=5YHn*in9Qb ze@QYnZ*OCA@|w4o!|PEqR>CK(G7z(jlc9%S@Ab#@rq~Mp?SP*bqO}Z^%$RBNjLg3q z=ykk}gYE*bnBA^e)WDs)I3$rnx@vA?_bs~^evNDsijx{}dP24tzs_r3cI^WPiZ+K& z1tZP1QIbu5r^c4H-!G9c*KPT(Enn(xV273jeqHrNi2}lneg`o}UCQAijq7S8aG&wz zg`><^tf3t(9xr03n4#sM=eCqo!i6UkPQ0uKx~lZF(*B|z3=DPLXINX4olqLJO1rBw zd;@Y$aGWe9YsqP6dhgkbm0_0tu+3#^@HO2*4+r}5g>!?oXRqjn8v2eyyS}~= zCFpNP`voosUsHidrA7YFMU_R*^V$NmPXkZ;c}>e#s+T$iNhh6kL=K3NBsTlbJ!WV^{;Nc2rcN&8?vu)l*p*gJg*q>sQ`-IXqCu zw$Fl7RqK)A_+g9{pLv z1f)@Z+6M$1E_ctM?6x`&1?U%%P0lG-Y!3`2^!=IQ?h7M$TlFtLR7y zTY~wJyyzrDN2gv|{7$|kobx~a10snu@&5jz5&pML8zeVRY&)vWsb8(hEwAES&xw8g zd>y+wXF%h;XSMAMyOa`Ono&*IXnz82aI*0Zo;+bxs~-t~rdI~2cF^5xFx!D2sK4>* zmn9uJ5?b$4+um3x5&9yOexAzZR2)-~P6}NJ-J6#clk@H4(u^A6AQ$2d$6g=A^vwK- zjGy!o4^VWrHI0HhBdHKiyi(j(DmKKK@#xmZl)d>n-DKfz8k!$Oy@@_pn-fCW`>5IM z_S@lNf(-9fqu4BhM=7bttZP;OWGHU*g19-C9{ER7nEyOd` z!uN|7?JNuGGM_P-7NncpTjWYFhv|X{Z@9U>6>b%u=FruwOe&s=n9LCKNhiO5YJYAF zHx^F>rKD7Z*}fgx(_c)wu4vS*g4BPtM8uF+^Vc@-^Ay?U%?Z)vu(3qWoA5(UABYW zx(b2x&dI&A0j#JVeW1~h2d~(4+T4ji3|5TR!~aLwTZZMaHC=;*2oAv=65I*yF2UV3 zxVw9TI|L8z5FCO94esvl?h;&PbI$X;^UXJMU6UW3o4%#HckiyMT~%wXm(l65zJbma z`Mh!F>-LscSKOY_QJr&dewK)ZQE*H_K|dU7XSGySzaQ3zZ-bk9)S+EhkSC7xkoXyk zp-cc}iPPD;htKJ{CTSDT0Rbfz@9FIb z=$a?Q8_9?B&ZWzHuLE&GN&RZgI-7q4#s?-|)?UZ|cc}O5m$<{^EW7IjSb+2_Y#k0UjpX*SD+P(h3(ZuPjguFc+eZsdp zdyBtf)5FTpceYfeE){wa68v>RHkOY){qu!!;vvSrp^yYy-ni@F+_irhw*Xr7vo@hf z2><)HtJACB;-C$=t2+2{oX(*!GfGk3fR-fGd2;%ZP+1ii-(JEe7^~5rvFowQ{|yff zxq0y)4!)ajUE1ATQFoH%fmAi6`2vpq91Q)KfVzxmU7cT6WW#Q5n2(XZL4Jg{bZOE_BL5X+Olgi7ufgeJNhVVrH%;&PE^3)Mg zlHx>8W)_?I;>xmpJBHf1j-?e5t9tC1z`7#T(Bvy++k67~1$U1uk zhh<39q@;F>BdXktr0K6@-YoWB%SLYG`gJg*fblBd+!$1M>QCoXE>r zwZi?~CN_BNC?emq06H9H28@iu^Cv;}CXX{0Cx+p=nsTFWywU?gDLks+SBlU)}7 zvVRc8g7PpnyfJCvZ98LkV-p**pd{BO^0LA5r7%}Zu>0yYH@)tly{rlyzwP3N`KBx=3uiTtHn|97#8m6s9335=Xl z&sq`iEE~9oT{|u7TA6CDpGj6O9IeaPl~z_(RsF6ig~KfDKVX&1z@)EKP#znI)Pf;mn|FQYmLLjP{R zOWs|o$4gdXk-s$6i2n3Oe)GIPWjQD=UI`X$xxIp_VLByj;(FWU-telCYydrf{m)Qc z#u@g0oQUFmmMz7M%2K@P`5|fvs<+f?t{HeW7_{H+OMaZ{JYU7m-B}oIP>N4X ztZ^FW>Nh+8J}=~UhcDrDRJb$-hco03g&q+?6;9m9nV$<8ZpcPa0GOb^)Yxm~sOi}| zlO@94c_DT>`zp*Rt+f57*@{+@V6wIi^1pUE>d*A~1*^}E8TChP443NU#1A*MnvEw? zrDnWC%(=-W;A3#Ms91Huu62`8DfXb)1F^=3!+{zB^Z^X^bw;7fe>?i~wE9%M?qngV4jYieWY^tHb_g-G71kzj05eY11A(4l!C$K{AMIvSk zWJO#ySd2$dz5Gdn0>Pa6tme7&?%F$*!d-eu!d~nXBPj}l1l@C~ffYi^D?ec$0*$Ty zkiS>4KE5l%N5Ks)s+UyBILMUd!!b(gJ#j|nQ=&s07t7c$_l?M8$B={T)xaILm6knc z{*il<)!e<)6~V&dL-sFPU3WApG7cS@hsm_#6L@ek-&65pw+W_a!3KJJ|a6Kc7EK2rntcR_DvwY7Sh!sa35tdMYHL&epu9 zY2x;jld{iVB3yMpApoEM-xikt-)p%4e@i@J7)Ao1EEXIl>HAsmONh*S($yjUUQ*Pb zO0cA)45J^!TTvV8_Yx)~w^07JlTVMF?Toi^J`wKo1;Jtor6-RF&NU2rwi{m|h8b8b#_UQD~*UH~?q{0kj#Kh@8dX*%CWy1-W z2rxJ~8n9{CCNV^*>AA4Q;H0p9ZEDnn}3k>yynh^=HhfWh4Td-_jGX z=e=0o8aej2O_|WAH$5bx1bhgEmUcc80LB?)rN4%MmM;)tVWOa<)SDj;3cxT~$)8@g zhq#$2;qr5(&&^W@d;328Bzuz(+W zMtWprd`l3m(V8?i;a_XSt=K)RMHD2M@k+Tev)v5v?0!VXRl8#CX%Mq=2zUNSZflK+ zse1g}HeXGb%FRklv`mlu0{7luU4Dd6 z3P05lf7@f@baxjv-^dE{)Q_yIOLuQbevcv3TaWJxf0d-x?B$nGr&RqvUI_Kci@jV@ zncn6ryD>9xSKa-J%RpaO!GC1Fp{=YYSe3wpR8pI{(9(a(#1pUyP)v7`bQ4YN<+%=S z?4tsTUbM<|+(X2mI3>2y)-BgK{TLXA`Z4q|VEOgFQY@UnE47l;Vy{84u>|g|e51 zgwp#$8jUxk`(Wh5@la&{Zxh3i{wA;;{J=L}WkO-J|*(t?R8x8i6CnbuhY$=S=|M3dgba{x;E(#d9`1#=yz8_ zQ)j4IfD*gcgbV?PD*UsKKL^*xoAtNqZkQNk?Kr=@3cGTG^(@N#VA7}zj?@Y98vaUD zdW+ISF(h7VW|cg=`o28@Swgas`a^j&Z>}BB4yF?{0*n>wap*aggjWm0K?``A(ZCmH zTQvV>_p;$l&9IU$c`oZaXRB*I>{d}xpmbH~D=@%%Vkfgm#amwg9-orFpvJ52Pp0g{ zFZ|$ub)XT3@gBqkrx;PbB^y}mNKHWKA>WiY4W(&K>tr#C^TgOyAEa%z>Y) z#8D&r$I;zxM9S3ABB#W?V|tCC0w?*c*o8#2=2u5sO8NWv=unW|k!y`Xe&Sr~t1YOS zPkFNyUK1c5EG-peBL=B8%iFOqs~@EZ;hUrIr2}5(*?78smB4p&HqIq|;?AKZX`u&s z2v16Q0Lp1z1nup5jF3o}2?_%!?f7ErEs#Pho! ziTXgsu$#8y*nRX8+aXRV&4(pKN%hkRGmvwTBw<6t3~JV*v^tfP>M?zJ4`RAZAlAXuY!Yf5QBs1J3wA%E+JOIpyKE}({eySUbZU0PCw93*4}kM zYhhUcr_SNc_cH#ePVl-I6kXwHP z<*dk`JUFz9kwn2PH5l7{My5JO>e=_DVP(Agpz=Z0fE{0k>T|frn=AFe>k_P*f><2RmTps-9w>_Tt01E4jcL8VQau#V*JfN&JlnE84z_Z zFz&T9m!KAgxdlY1Uwdjda)XZRwR2{y))RXHDZzaxd=IX$o^~~;rQ}%wNg?#(7QLj# zBi43<7-1~l(}mzNmeCq<5v&7?k0ew;k;*kheE5ESj=2VZUx@)#uaUJZ_#51Fz;*Gi z)*g_cgxpYfSD`bZNbrI*sCcU9I_8F>JoO<8we41v7uvxfmaEh7FtylQb4ntV(O!U9 zNjwfcN=uI7w+fmbouKrq_ZO>o)9U2dIf`z<4)tjBH>lsNf=VE(rP0C_BiXCp@`jx` z!53bMoRFW&Cr}tiv3uHGm96#<*Pqfq&mlMG zg@r$J=8_l+rz=sJ|Nccj-tarHP~Dh%ytk=~BJe9ZniuHlg@*Z#?CN}sXZ`pKTOs6- zGxG5o@Az=>l>rymY@HR9xad0qe6CQB`>U*u^44rYzd$ibsm`NP%~kKsidmEOJZjsy zN_;YO>THDp6*(38Z>`1DbTm(|`xqDq9W7NcqFMsp;x#%3Bqw0_67Y7;y}gKjPlp>8 z+_PjlYg^k47uJJymX%fSa|%I#$5|*Ablo-K^7t;USo^cT)8XRVXIyS*J>KQt;}>2% zRVL4Q7fo+xA3NT6J*lvmXFul;vELrhpZ<2Q;orFz2@e7qmULw|7?M|u0zp4NcXG0* ze0t)|rbI{LbH?Tpi+W|cJMM(1xj?jD93S_AYlcoBRKM%^`HZq4` zj}9#E1QoT>6{odP?`PF^H%5J}PvJt_UT1tVtnf-!s%uZ$O8j&p4cDHDIQaJIFM@_F zZ||^B-k%<8g&Z2P(gxpFq(19&T_~2$B5_@VKfX+(V@jycb_07oyQ~-WMCsVC_cwM= zmd5VuV)bvqZGAc*s(l`R_4Lv1w$@dthR*M=;{2D{m&&qtf&o z`=OyBQzd4=k^t+k0)GmW4s>!u~ zzf+c$#>-$;J~U8jdna^F$PaMOkV}Nn4*CoAFo=cI3yX>| zZ)R(ylUIAAV%76pn$aa-Fgg!;H&$#qT`?=!>mIlj?s zy%(ivrB8po(XIa{!73Q`bfm5;=R?mqU|Ii$M6ep<1!ZeBCGlNUIxq@tF9QuPPdrE*OC!CJYvX?9qXsLFnX39W-uHK@7fd-m7A9*@qmx4BB{ zvZmhOe$Sjisv$?IUS(DDyw2`CJM6~^O$hNNxL4;lto_vF6i}yT>q`BWO|hxVfIS5* zQXym}KTglW>?>wlOXdgn5kfJWqJL%BsWB-Xy6_)g0nw& zowJBo{DD*XmDmB-g5R?fyuw1ordTa(*tN6uy4s2xdP_}!n*NIrQ95;PK|X1io9)el zlbOx5oe*(PVpnYZA2}O4Za^rJ&61hfg9v{%h!I#$7QGBoy10JtY*0!Zb?N zU-XHsR=_m(*<*teS|E$J{ZEY&Y-oD3D)o3OA*Pz8@A0% zpGKt{VEc&Iyt*fz98km?nJh!8jtGbKJRCI{sR~#tr8d_{ws|tJ(#yv|!X3`nQ$G)2 zj8j(Dv$P27#iU=xm2DgU^`%E5IQWIK!M}1n(8OSdj%I0s_r{a2@yzxb26O0Mx>%DE zR#!)8g}sLMsreC7m7r;`CT(JN3Tr@ba2ojt4F+N<9#?2{;Hvsg?HcL zk`(MP_tePlykVtigUy3*N-%AJ%2yK9@8YzkJgtNopJb+CH!3Yv1&6?1en3AsVpJ!a zlHOUcbzA&7+bv_}Qb=7|C;fZRUrm_00?gCig}tGxz|eMe=CFBIehG6Tod8#_$+KI7 z5V$($78b!RbJ&dzLfJympP2oX;D*={G*{!)5vD7Y%uKNg8|R~i^w|+6=*FFoFmwm1 zR4~_col#qKkqqccsNG$>9rL{yJ-8#6md&<>c67mvqM>3n3#IUxb5c-H5zTNqShKsL z@hsCuUvL``o^Bt`mnY68BiW=X2S`ztb}lhvU+h0;yFI0HqszaL<4Io8m=-c+?t z&&~N%yQMWy0srS*#NN^}Yb(r`U|_NB)$6CZ(2iKLiszr-#8u1nPENB1UER>{ZZV3^ zf@LLyfR4bYvy^%E=NYzje5BS)wGxgyh%$mI4Yv!JdxkPq+J}1+n==_fQzfEEj@#_N zQBdD+zn7DoUW<7jt0JZ0%m??pugiFovoT3rvK`l!-_GHzFVPTeB3y^VUXx2Mg-{bP zSHDIO%<`GQbM*H7T5TJ_sy$rzt(2w@eqF}97YsVq}n+;EZwsXbQ)t(6zeVE`PTrR?XO z)KJ1gWS|4b#A0xRn1q#peoM-}{?<7|qgQG%LN+~Jcr7~leH2TnX4dTu4Ay}8$^(8> z@Q!zVr8O<&@glOGiq8_tPKttVU=C_FWoPwbL z>4~ncvQm;fw;(t8=cmXaOVXQ-nr3?dR*c%C*|K@$x%gpMsP&PV(`a}Er* z^9ZR)4ERrFbf&!4O|HV#*=8G%_+hP$@^vWf|bEbihHqSP-BWzGihRmElfNTjtSYb zKg#!kJR5p5teRO%`?sK!o6cvI`<52tnxyj=(uCjBv^I;MJd8MKXl6K{lGYUe`Ms^p zZN8MQONO(X<@%4ye0`x4cTW0LyOmnCR_KZJex84jJXL+Xg6MFrnZ{+!n z%lBkJWr0I&rILrV-NgUyKUuE-_LhvgE-rCLcZ-n+Lw?aL3%m&3o1tiZ-|1oc$+Z`S zSN{LAJ>@gZ2Tsm;8Ch9+F=b_z00ln^Xdor891$Mg6dxB?h)MHLOUv7ir6sR@Kx~j` z)Ux+j=6QQw_YNLwR9#V#DM2Bq7p74*Za9O_XLM@nujaB5W2?!4FleF~Q7isNzyNBaj_*;gUj2K5 z(Q7v&c3y?A`pnsHDuHSd;nn^W^)GOtV}MQ9Mv0FfKiZ>ae)_}@1yB3$tV!A}wg-y150~Py);bFD7yyecYr+?t<>EDNo z{#4@~pcQ6jnLiBMM(h~ROAqjZ?XDFTUjeipkSq`-zFJ%34OpWHex-Na=j_}X{^7OY zdqPnF9Ule#UxHy#e6Ty+In4asInnF@ZU@81*GdP@qz8%b;RF1i9e!(mAXg8BWIew>aGBaxGrM?TnkNAmHb0CZ$}`mzZZ`R`Z1 zfkfCKQ2Gh#?ChMq1pS`mTqEoa`Y(%S3Np}oS_f4uK5fX-CkbxZr!88U1E^%dpiCGGH5<372ufW5@!;-5&85bYl zXZz25q;Pvj!oq?M$nCcQU3>X$BE6$X3;aWuG!TeWj3Rt)ZN7&HTc5v&dNN3CxQwLu zAg%NU&b*|OwA(bCCpp{9Je=(}z3R7dcZBvpP4nH>V6?R7F5KbdU$qUFxBG8K9&`C=ECNh<>b2XD-qohnb1mjJuO%KG{` z*@eg7$H&Kizw>kh!RY;PV+48vpH!u!;9Kv%5n{7R&K>q@^fa!DT6|t;YgrlMc0Fy> zOr~}{C6FIU<=E(LwOB?qx3xVLon(gi;QEJ$PPgTO4hiq!diz)j&!zC@2%figkQ*t=i=bV3&-cWqSn=25i0y!D?k;m z0)z#f=->kAO94*_zlcb{#$*1k+S)Qey)a#IGTPqNCDQLr&a0-THmS~f0t3iyNbexd z?Q3=_KYRt_`xyv90g0y%wL%{;K1>31D!o1*3yqjsTtdS9;>j<@A2f;5ggwr}FqTk` zQws}R>5t(iT!rwHmiH)VXqUu<`ze8Zk1?gF&48o(t|Eg66$J(I7JwLu=&!DLRP&O5 z{7|lP%84l@&bMs-l*Ve6jNJOw2{3y=e*jlJhFz-N$jV7gUA&Ukh+U10j9fPx=^GSO zd??29k)54=cx;RzD~Asj8z-n73gD*0R)q}mXH1#%xsy&S+954%Fj(EsR^lZ{Tfg+i z1p%gvK>-KQ$g6K+k{FKj4&qG|qBY>(c`Xk&s&GSz=bgn!D2Mwp=^!BfvxO%3_oYwj z`nvuIz|iMqlC65@%Vs=z3b}McfIAG{2a~Yq<-hmbFWa`)|7>$&*GEnY3k&&0z@K22 zauaZRdV2OwOrXY(Mdsz_j{`+8dF225!65#7NGl=GmD)Eo6%RxrDe38>Ce2yYH8m9h zIgVJ)*eDR=6aT4{ooxtaV5mW_>Er9hu^^8-#=QWAO}G1C$V(pV~QBE%G(O};i85#x)lxNxBT^&g}J3H%Z5X=L=EeqQ9)v{iOEt8J%ht!*} zo0}WXf}br+EDQ`;05%?~$wy2?1i#VT+-wHueH`yD&Bo1Z3@t1q?drht-;4xRHh-g7F@=+kcToRcdH3JOXhq)!Zr4BQ^-2x>`v;YYFC2u#Wc z9v2Nr|Ba1}>2us%a+fI4_pGdBfKFj4d3kx3gn}~r8~dx172U=0a10~}h&M>4Z@l0j zkRT)4UI(<0W;cN8JC+E|$J5cbW#8e^piTz$w*WL%x|<^Ggp({?FDji&I8 zyqC9k3wzNHm)mmDA5F-jAUN+k|BT2rfi=BT`ERp3}1jNB@=p-;>pjjt&uiS1}C6BxtxWWr_6hp zYG@?aTN?os^!lX2(KHqW1pnz*&QmUpo6+~n8h^^&Ms=^{H2)ruU7G9G_rDf8vb(E_ zjfv?z{curc@l?atF|bz3Rio*etbvF`?Fr5pjIfF8z`OrGP+%J0BV%Dv+;yyaX-{_3 ze>j>c!AxzeUZdY$I+>gBm(mJq@ZIO9@xea3%a)r?#zN=Z$X3J3^TXW_htd^sPP z$Q4>9^U1<@1r~*|RiIH`4!|9DyR}zrpn5cAT)(Wjv}QWczZ`pa(=|-Ut3acuwX8hn z)A8ZluWVJt^9Aqu zLh(1_Oo(H*di(Jm0Oum;kLDc#b@HvoJp*TV5$@&7oRlpa<#2pF3XM#aft;`#A9J%3 z5FC%+{;!tie;$4?B>$QrXaZoGj&hrVWO>0pFfL*1+P)W0beBBtg7%Lx?i){_xYoP4n7X*QCe(Qj(gbcC`5R`NRy-ziU2q`jD*_16>EN&Vx5|p#A_50uS0H$L7 zN>4{r`@+uFHWNIS9UWW1bqj!hX!!UM^pO7y7~F3y>zlMXYg=x^NrIk^;P2m&UpRg2 zfU@d(f*#M4x0iW_^P17=dth;a)x7SKZ9Ywi0FgH~WLSJWI_b*KTcu1(BbNz?lKt&%XQ! zq7d-vm@`j;;s zuyJw25|DtwPi8O(bWJYdCEkK_(!4l@oy z-`4p(onK-iCITQ>dlOn+&CC!9l?AvaK;Vy|-R!RXCZVF@Qzf@#0?o$|VL^cL&jG5m zWMFK-%^wYQ{ZJTDM`nxQWZJ#5lkvP?Tn@hhn2t=xbH%f}a@@a|72*w#k1KfUL_uW% zI*Z^_xn@s-FS!aoO~uEcqVnVZ{h4%RpcDi)u76;F z7%0KIKi%$#6!(FP6FGQigT5xf-}(#0oRfKyn8;{19$t5sS%7D0jI#}Rc?BgUH0gBi zIa`UIwzhA8C4?V1y=u1$92-pDr5&hAP0-Bpl7r>--2SP>jIAj6>x_8aeDXdej&wwpZzc5las11sTK(6KS zO0&a)z_h4!`*Oyax%Qts1b)=jG(J9F1*rW#E9&SR6MYwBj<}VQkm&!Kphc$gWC(yv z*WFSBh-H(2gC)_=*SA(8Z`|3z8tWyR;UrCyF+oE{W}s$cV~bwN>N&C9a5KboRFAaqjVmZHkif+K!eaD>#r#44k`Lv?_yY+^?y{L0#hBG%Jp(BS{TcyD-{68x zE6+0UbIZ&7_-#1|`qW>>45E0hc+DY?dxnONP|ROt-u4<+X<_g~hJ}SSd*7@DosRI{ z5Blkj@>4G>(po12Dwn3##<*UKIwePA8X+C0tX`*}fXjkF^ONjEYX z0^()^ucL%2srDki%t$J^6c6_WI^_A~<60?ryvrF`S*Llf7ac?&u$7Uh z$jG*@=vyD!Gv-F)1Afc_f~W;fcbnGcn>$h-pykvYjtxZ^6 zUylI^oK;ytLBZ+l+E3Vb4{?_(( z5fFCU3a4G*^O{;0thijC{m!+;<8$@S9x4pd+(Dz4}lXa;^FB9R|Nr)iO;~sM(=%8GxIK+?0;ES z{QL5M+41jc<3Brcek-e}Xn?6VBqJr2>I$g$dH{PUZBfg{=$>QK!YY|pHwe*bXlRnX z)Lnl(2uOd9#JhzeJUw!hY04o3TvCd_E<*vFXe}TMG|5((U#%4?j$dSVGCv=hC`fNW zw{sRWlaXPYlvpsCDb{PFLIF(b3TnZ<0A{?*kBh ze0-8wtu(^?!|we3{e!dUU;})C(y^Gjy86vJ=cfo!gXGjy?gS*@K6Ki8#7R*80&>Yj zzPsI=3>;isYI(_0Vy5l>3cn1mD&AM6dtA@asDtqW*-li#rz7;9 zm$)6~}|DpmVfd(CXS%8$e6&3z(K?-W_&$T?qW00o>1 zx~>#?{*-wHh=}<%{eJ#5+XJw}^fg+d!XF8$l!=Xns3f*EPF ztX1D)(_!(SpP=AKySs}p;0U;FOLSYG!nNpJME?p|y(}wMX^8;=Ql4H%;91THM#c%4 z<-tdW;3+GtBrYkbHii``u%hP4Oig!;JSn<^TxWA4 z>3NFJVLuXQM4gX2V!0u}97gjU)roRU3ogqNez127kN)yuz zn1iOD_~?ic>g0JZmgDH?$c9Fvy09EvABTCKo7N5GVW~l}N||}T$<11DxD{@A9tz{_ zYebn$n2!p@r17GX_VJ-O9uzLb+z)&7K}gDc&6c;0&+<7wZo8{sveN*@POlu0#e!== zasB!?$oXWM_T3LDvN9+@*65L0#mLBL3TEH>UBv#!f}fa8f;-A;YP*e=b5$__I?cC! zd`u95UqqXb$aswN*C_k(EIthXl)%C^*p0ot1t6BC(nO( zfQozx?sMDtTO>U0o8RNWg?H9D?v7$($IdT?ROhqi#wJ(tp~2LbuHHKmN5qg6F~+ED zMhoAs%6cRWY*hoH@Uuq13OSU-;0LU#&lD9UW!C7ZTuVox!7UCUXE+Hb=@7`nC#>Jwr)F)^Zgf}w(v<3$?BqTCoNqzBWbVOmYDcA2rUijezHZ4Y;A<5ma( zhz244?i`%aKa@gYE$W_s2y4^OcFAR_C<+R^GOKo~3+OzY<5^K6qsD)nUO3?$^*I9z z+$Uu%t-~pz&+RHYxfLfuoG=YoWb*HuS3Y2_CWBg8ey5;!6xYpjDFhT6MDtBR3^=<7(U}PSVxsyeU$FO$D zNUut5a8xC+sfzp@epQ#Sxh~2CBbnKsuFkkH?+ErUi4r+F$~`2f+Fvsm#^2#$%OB{l zt<6%u&dPaRZZ_Oz7Uwk_#2i2L%MI`XBoxk&O{zTg5!k zCX>l@>jWD!+Bs%w5N(C&|9zzZJmx=32j+rwn^wuPsL1Tai2@3GM&C(vbi<15cq+7GKd3fnt5AU)(`Pc(OPo#{X2#7Dt?>W9?Fnn}L2Sp97id(Uv;7p7b5r>Jq~ zXTiP{RwCEkGjCd`8_v;a0>n*g8v(Lz6e=oJc`b8>M*@eGesuE^J0t;pLt)uVmmIsc zvTAZFKN+2&qg)m}VQ+0wIoWH5%`Zpd-3m;#)?11a*38-x%hIsQlqv~OIz73Qb@vl! zqfYRBgNNc}G`XFFv5p^aO~&_5GkNQ&HwTn+6^r*eFDY5NF;hV_ZpHUq*~La7apmZv zI#{kPWq5qk5{)ELQg?U%ei8gV`*2VQio)yK z8rF3~y6R*miuoM2;qQb>|Kf8>)*`ZIJB3jXYt`i`Nx?^5tJynFW=pBjUKM0 zS3gSOl+I-+ZSaueGHGx&V|L}CPeiT#yoo9en87`X;67AZa$;(Tf^*~Oqd0V=ia>PS zt9F{|@IvF6zh~h@Z;iZ4f6ndpU}aQwH@=aO7~+xb*?96pFUHWZXcg$2&t zN`#|BhYzLx6LsL(@<=Ox2b)daghK`~EgVj*mv1NHH4Yqtf`bE2r4z3B&>+Rt#R&Wb z{^d~XPi~fg(2ey@c3L<@PZQ5u8$y&NGlA12&a}X%if=NlrzOz%2tz4Bc)UJA(eFcV zH%}ZlTKSZ$Y%rcfe0lGD&>n{~#HnJ(P7zYnPhoO`1Ilsw&vfg9-#y=Rg=#!#Or0~! z4R1vyC_HcJ%87`&H`5Zh-(_b1EPTJEeQ)d(=2>t==bDrvG52mI_DZ)mJNV$5wRkI@ zVy}bH;COECo%`&lY{3LY4!;aRBx5qucx-kV=IF5l_T?GVx7?|HQ%tU^oo_~_Ur`rs zoD8_oe`6&kkYj#+Hkd=aJy}?XFQv@jUI@ZR!W~=Ql?rW<=Z~B=uC{GL%G*(v+pXLb z9ZEsHnAzJs-C96PQ{t~>M0Iz_<|8$Xs~S;$>rd&|I8OW&S$!l$mABbDCtr^~gtINc z_c<4LKP$`Lb?G-(k|JF(v801Rk(_zwWetAR(B363m!bjof*YOT$^om2&*u}jR$=cH zR)P#&3zNoZ?ld8ahyCj~Rrjz|D^F9U6A?$+3#|J{)`?%lt;nCxP0FouCz~z+#}qrx z@&$T7rHuZGjp53GH0;?A@wO%Mi70YRTn)wT$Rc+Q8>RKAxFmEs!4dzblV46eKfGJ3 zs^l-WFE3h?9>Pr3E0|p}`(8iG?A@yFZcd$aG7Gs6qSL-#Q=O^Wk}y1ww80s3;7$9D zVO|&%*uUnq^JPoC3w_SeT3=ei>6V8U3#T;n$>Xvs*-Db8aQ4^8R^r;%SH}t%n->M5 zRUbxcWaK3Wj!o@u1JUsKNDh)ivu^(!9Zle4fi7NqV=*pP(W zs=GUpD*`F!9c}wZ4P~_k`HRdSbroW25bK9GD_<<7mP|&FO9=v>kwb*z=r2w`xM^tk zZ84)GQMsox8ISi`aqS&SI*8LIx*V_S8R*f-{6b48#$n-E5xBsJnYu@zB&{o=EGukE za$Ng)d9G#?DpfLXrYl94Jv*s?cK^el8<~5!GOg~3$)s#+%%H7oa%jxA%xKX{CrUqK zCh@ysNoJbKgxQk;?_}4quT^v&!Z253q4`!z=Qg1mIX_yQ@_4|e;Qodlwa$ILMkRh2 zlh>mr(Nh0UsvvsJJdJ@!oJK_{35Iy;DTIWaLPG&RtLG^kd>IjzKkacdKak@oaa@LH zmp(?j*GJ{^?C@d;2wHZ|n%pWn6Q11DX_`ca*|AlPgibJPdET86xsn*CF?$9^9qjPL z1BTPCNUan1Z95F2$QAV<#y!V&pS=)o$xg)O#mR;?H_U{BuroHB45RWWWvfrr_H*Z{ zAL)0#t=FV@$?k95l03Q}pEx$&+@;;7lf;XPZ}=`}Z>CZx6!qiK6e!S|d`l>|C=$&G z#o6Ub@ogfj`cM=4_AyND)!K1n9KKgixrTW2vYTpCOO2CcDaQA*NuN2`{-{Wd0<6&W z^-fBJWyY)(4u`A9`!IY{vr>E~#W|?!yf`a87GFf0uGLaH6x0dhA1-54?DEFz^CuJs zqiv0)9ITd&oq|n8)weQd^Ow+>PXo{5s;z1t%QD6`7LZ`z_(;BIcM%t;^|AKaV?b){ zwhuuzjJ)DnaGej82$Q5IHh?k#I+B8be_r>?9guKO-=q1+}A|6>Kz_mI(61l$2nrZ z$HY*JkDxAq5xvss-DmJe)Y1|iWAkngg}Poj&fund=gsqu5C0EHZcY$|F3iQDddCo9 zG?|-b$tA`s+@z{+UbJ)LH1NhrSz3wzNc^lGgcLgQQK{!y(g3}yD|!Wx8J+K%#(;uP zTNj+;_Lf_&GF8_o-oa+#Q)lwJJ zO<67q>$x3$H;d|JomSC;j0~Y=2VFFu#E=>UWeoJH_x8!{8D63f(rLV|w$wh&GQcHd z((4?4hQTIXr_e2%1c2)A&1qfVpL`INNC$Ec8SSXnr|g!iNx1{6V9_R*ref0Z*TjS9 zjD8U}26^c3K@fWUgQ!j|88W@HMZyS%6`@!KbqF?_#EG9bT6X3}3u%h157onyZQ65V z`N=JOo;hO!#d2rvF_pxQa8z`v*cuW=8-GoWiCFwGyqChuQ{r9IVyI2HGKcNfR>}&I z%nZxl9^Nmsw;vmgX~_SiGjUqcu7*D)e)QVmYet1E4^>3oxTnq9sI-{nOp++8eZ@>= zi>yiLtRN34IcUSm7d|N{B~%%)OS3Yvff7_JW}GsuP_ufHNM`b?OQa0R+ZGM z%1Yb3ES~L{rYbdmzitIHw376uzP5SE>Xuzi33yzBpV;?&H_4>~433-qs)j^0nRHjp z2qza9n57t{_Hv5HKW!P9{p&Cmp&td{uTdGEw>-MjlCB&hX8IqRJi3+ROS5vFEV}-u zqykDB2Qo((>G=tUflwX$kKU6q z3c&|X4sHJ}=b1^?8g>c7L8RQfMGstAS#bTWXtN9YzmTT#Hq$Y=F6VDV3Oz?9heOc( zmZwkIj&BDWRx*mu8no1HN7#{R#-m2#<8%=wEP2l~Vz;$t9*9xvg4d4kngrkjxAd~s zc6yP(0iNJ8W?Hi*D9k280%l_c8|{skFADvK@&2u}<|y8}TF_9v(!kRIrKA58UP1cg zKb6@3Gf%>a=a!c|IG9%$j98*IWm~>pio+d#`lf$)?V|^*=gn=-!Srxt@|uVBfkJ3l z-}K;b4WyCL?}arQ60~OZT-PcH1PVqi(1e^q*CV6I;^@Ci??>eHB$6czVv@7T2P37_ zDTGL?|Kg)^LH~}6m2Aex?_0#8CB%oZ*$W<_H=V35U0&Dwjw^1Tm~}JFN%5<_n52}( z`tMe6>wJXP-5I&;{%M|LXM|2I4<&4=9P$x_51opo4uN`dQgmxGKDMOo>Rh_Ad9`D6 z#aA?Q=^Va^{TWv*)y-(5?h_IhLLp9KlGRAz1XR$DuwbRHuC!$whrT6Q_IQg*!g6EJ z8Qm_-7PB*(O*FrT%xLqtisWz4%vJ!JBTV0#k#AD57$qdie_wAS_%K682dIn(`Z%5F zf6{1)uW>`a%EjL>u^xie@2$QxUf>#65LdrBC00ywXQuF96~A&;DJOazR{7`8 zrc>f@@R!z}j>l|TLD5jUKyl?Ms7hbIQ1khTS%2)n(fN^+^S;9!lr#ycsHyj+OEp=# zU+NeBF=rb+6QI&V-c74sodY$|g|{F+#vWut@M zf~=$6J!{9gDA>cd0VK~t_U22M*}oP&IXdn+e#?NURv0hdTcbQVRayPT%6 zrIhk&GAGE4&SQ$#m{2CAq)cQA_)&cL@U_;e@g6Bx?>QVa2Ic=fC|0p1AWERqrV{Mz zkEceMIQww^bbm4d)C&4Q?chxU$cKz!>U!!y69JC#51_~?At{M^lEH50t5T|AMDdbF zyWCE(8K2Shkp_J6%r?v13@ewHmqkAO#Kh+y0kg%$$vJ)Bvdt}Yd0?y3h4FW|Tv-&zFvKw&(@XA7 z9dVgGmSAs=6Mr@KdW=Z2QL!xf$XyTh_B+hN@Vtln)P0LYR^eIQ{%o7pSejL;-Ve-X z8Lxto%pn&+l}3aY{hvIwG%h3ph@0UhTeP+(@s~ybtisYeGfcp3h^%J4SZ_DNOgzWu z4T_PSX1Ki4=H})R5IIQ9fOr4BfFVe{>whBgz`(oN0c|28a4<-;#G>Kvzja0Cc@W?M zHhr>wt6i_J_duCpP=J=%Zsm)SvZbZ5N|p*0?R;nLz+ial9ILSGkn`ksT){50pm~Ly z5p3_1`ML~fn!0Qv3mJzeZl3e;fz5Wr21Dm7{p8DmMDsUEJd(wb5hJI_M8WW0Tgt3W z3RVlGA7K{qIo&-JhyPj-Rl}!WXG7D}9v^2bZ(h!yP;Q)Wy;~`VLn7bcyNQMb>3i)H zTI2%ld6XZ19Y^$)`E<^&n8;zYR2o#SI~#F|k@>*m)vK!zaPEIq_FKin6YgK0=ALx90$LL!# zsT-ZK`zyYD3*b}9&aO|gY;-0y(beT_G0(#~wuIO_LM2x>Wyp_n*xC1Lb^q<&28zPF zb<0^5GZ^D-&-c|nC<{GCw5cK#!=l0nT3Ug{4uEG zbTVrJeXjaIgR}LnbwN1-F;{F*aLT>m!c7ZYF1LDmxSfo*Lc2_NU58q5&uU3Jp;o0N8ZgFbaKr%lyc|#GhPO7@mR2HH(5D3 zi*l1ro}h3x4Og6zL0$s~(MvyukzKcLV%wB|;|A^f_+v^ueoRc$(EBwS1^j!^$t+g!Wup8mtTH) z&p6&%!2+rn>T6LsaNvL#?uWOC@Y5oEsLO>57sT+O@7K0&-8y{vos^Z8RrV|fHSvHg zMM1%5MlSx-`{Dmyv#d3jWA|T|GSU9XnwewQzM zY18H&KYsj^lP6E2*ChaGv;6)2f15dT=4?|_(=yaX%NjiI#bta*Ja%lxZ-4)Iv%0d< z9JSJMncLVDOkMHCl&*dI)_H+;vvwfH1IU;$WB$emg+gKb`|rOmzj*QDD_X7A1YZXL zv?gC)--8n;PJF|`!66B?(F$R2%$S{TjS1hW)o6^*hi!c)GBk9lvaHk&HPilCIXPvH zSoHdbfs>vJZOrs7)^jOux_s)Xrxx*nzgDZ&<|!#Dk0vE0O~}m599ULX=2lu-+Et}e z;rt%}JT%_F5byZQ#>OVy$;s)OpP%0WA0MB?78Vu-sGYV$B9*EKJ^#W#`M_W6v|7pS zYY8E@&Yqo+e(BPqWqG;o<#~Bs6s4v1sI9g`W^bP(vvP@npJqdAVMyT*eK#9{sr}3v_sIbnlg!D9lHdZ+J3!-Uc151Y-Vo{L= z87n2aBBw(A?zG%m;+<>vkycL#Sygse{JlAj5NK6ld#TFhB*0jNt* zPmTt}czlrwxu9wc8LTNpB2v#3jTU%QVhs#_61@|HhL7C3ofVj_W&|vjp zEsS@bH&q(vEG}F8vb_<-!hHMu_h-vS3n2~;j(j^~Jx@e!$IXz{_wtuMSHF8utTKHB zizl0e)wff@7<*lu`QKrO7M}O#uI`cur6&U1L#c;Etx&gxHXmzzN6+Ws`IL>M;^?t! zFTW+U!p?gUB2^#RS7=^PaaZm>J$PQCPO3cmRk)wTPSdB!QN;@}KhL;%+FF<6)?)`I zUauzoNGi5wfG0<|PX&DeeNoO5MsN#}-W(;CC;5j0Lby2mv=RUH&>D8SClHcsTjlD3 z@MOi+Aw!ph|R~LC&_-}Hj?IUm6j2NA&KJkRV7)+#wh|O zqEyaG%({BKEHxGJXlV|MJGZBFrP)^A(dbHZ$zu6iJ0lg$m4ICPhUtR4YkYfZC@LEvRSN!JrfRO-&dLAy+@S7{_+A2O)Nm60BypQp9j zbwo9hF^~m@BEjqUTYx$?&f4RUqGwf ziu)J!t75r&(~(5*sM){c>d;X*@$5}D?x?ZVDY$OoKu0_gmzZAZX6yMwRtakvBO{}* zwN8(X-I|Ppp5n5YKeH%kq=L@Db>#OVQ>x_I`;1~I9-e&W?(Udp!>x3;A zS_+Dyy&{<;qEusk4$rfl;QZ(LfO97=tz}f&N-2ss;h#T$E}t(qSBh`AhaupCD>bTh za$j5MUmnXFri<{v^(I5c`kVU`za-#lt6peM6P(=KLOSK!dz&0xU4wgjh16pBzmWDH zPUl0cuC5jhMMp<}@AdcV^1g$Eg@tu=cJ2>?MwWFo(FVo8bo)M`&CJZW8Y(FvYiMY& zu(I|gQ7etEmyN;&p%4=zBO}LUg=V3_?YKP1DJn_|3;#IoHj_p|Wn*KDPfk{|P9S-R zh=~blY-HbVt9U$FtX02hmLn@iczjvy4KQq`_o!+adu$Sx4vD32nLVpeuO#E(Xi_5+ zSvUTwVoUwd<#CZ?4Ht|JmERQH*Zb#@Qxn2GE?QQQZIlj={zMRNJ|6gKcAoD}#>++< zEN94U*Sm0uh5UL82$0B(sU#Hlu;+oE&E~%+Z);+nagP zo>5?yKaPBw*#>7a5#K41IJN{T&XEkZw(n1eX^GTrxFE-e7m)MI3^LI)Wt<2hN1kIG zLMapkGsvAGo-eggZl4Q(&xRn$8Dv9tdkbmTOwsvT<#h4NT_0m& zQG+P+S@t3l`@PxH?rl7P`>fUN%}Gl)tHbm(eRg(MeRz-RZHJGKAC1c{Sp$-$K%*_f zO}fa|YX*rSJXuJ&TeaxBvkDR3GwPCF=D+GnrFSyp2Eqi@UZV?AM?c*hoM3Y{yfzE@ zK9a1ZN}$?x_+IQzr!n80&1C7~s32x=+3Cc@;B)sdPAb^Ul{u-)$eP8iU$+{_|fB%4bnIj>Jq(o%y6Fc~^Okk08U5)ko2iyC4%H34M z{!<)tyDH16-;jr~AN7Ga$}eun#asr?sGL>>H0_Oxekg>g5DtH=amguKDtRCRpRpT9wNE8}e5nDxAC{j*6o9XPZQT<~7S!(u~8Tfa{9 zs4x>vC*=4v+IXqLX?(z+HsfZi;#iI^f3dMp*NWhC#uiwXAne*4laNTH`Ti9=R*p9* z0H^#o5y8UCof)~Aj;;43g^YOSO~yp~6`QD5?a;3RnJ_f|<2@*~o>dd-in(1_RtyIm znui@A-RcFc5J_e9A=sf96-$>D+69kLDp%fnPZXB?EFcU1Jsy2r`c-9W9YZvb%0GJv z$#8Pyik55dmpRT%p+6BbYJ)vzWMmb5v^7?2I;SRd$;ku4PRMDIEMlymiF(zbN94ccVT)a#PILaJ%YxMdq}? zidwRxbeLF5p(_viu1mV}g`5H`6gP#^A6Xp~<#vXwZHw3cOCxEqnVMX8=WaHi$9@a2;Huxd^1(|q$ zwwc^lybfDd>9wnH1ibr-SV{cAzAaZRb$>Wp@hBSAJeO6)X(;>2QYM_d_qU+vp}wif zm(>bf^jCH!9*@)d_vB=a7BUN`$N zaByVgCH)__WibsPP{PQQo+qYb;9F6d|Ua2DC zQNqWv6=MZy&b=QEgH^AO${}l$ecMzBzqapV6XRm za-K(%wg;hL5XxwuZHCB4o<{a4xhEC53U#(8a!Bl65Q=J_rJ2nuj&iGx!a@GI8mUr5 z$*sk0v!W zHN9AS<{23oDLDc@Tt7Dsx&<#c%v@bvMrhK2p3oeO1wLy?BiHMwM9p2eDUR5$FTDTcP3Nh z;D86QeyGRrRjccm552xD94Zv!B0|bV>Rzu6w0_YU%hgrI!|>&@@>a#iwmj&mo-~x0 ziL|doYDP&hhQW2|HdyvgY!RD)tTbT-&47MrMdzqd?OH!fu!o5V32|14DCzUVh0+7J z{i?K(63w>i=K$h=$OpUr!Q0;k7v?Z_Y2h!=*{oYGKK1G*G6!k6QRv_q{MP&m5|l7K z;v!}xgE=~B!087N=<~_z(~a(RXWVJnjS_5u+sVR-pc^s-eAK3I@W!B81dAz$)|Bs96FHD_>(h~YK+nMSY zd}fby9LtA++gUE;usJU_SEc`j(?6)CRE`QmQ|u%MCCNL@J*Q!<(;tK`yVtQ03MH!` zB`-^-!p43>7tUHr(DKK%vcMXyz#tYqOM$`Jc9NCELfHdH?Xgi~sYt3RX~DsPKcZlN;ZgH)STjPn@9Z4dQhCSH9fN z(KoLEK{qG1X*Y;8D&jV;H+?EAr$>95b;9ImoQ1~b5JfZ9xeQ)HA`_{R5cUdH>?^_A znXO&i<${XxV#HsyFDh~4kWY!Ui9at#MJnZ=9t+7vNnePSzZMXDy?D5Kw7OuoT1pu* zOgT#WO%F}l>WmWZJp3+&5l90~N^=bBuK!_xr=gsa5D8yP5WM?vag?ab10&7@)9~Kv zSu0ok9O+bU7s|U33KJpI2hocYeXK^U$~*Y2C`m6&?fEa{2ESn!boli!rnhBN*6}>oJ1IN5!c~w^u}$7hCg~ ze(5f7{GqFn{Y8qFhEE!QZd>$_TCJ_x73VM8jido)6R);Da{{md+n=L7GD5_C#vfkv z7W}Uuw!w@HX+>KFBSLGT>zPUUJXK`o08k0)(H%jbqT1_KF!EYy5zFz#K&JhC%#9 z92lGWSzJ5g&pAZ7e3!g-;Ind1DArO=c?Dy?&tA@^Jss3FPkWqfoJx0=wqfSHEYW(Chs}AC-->e^7hF3 zu{-zGd!ik`hvv>TezLHrx2UI`C$T|5l=Jw8vt#O4+~BY@OjFb4{=ULj!7gOOjH3yH zm1eP72Pl%)d3u-ooViy<#PPyC72Jimy)+$#co@qADf7v%6*;Aq8 z08=(i>1uyKDq5c$7pvzY@>*z#@v-oM`h$8@1b*c+^3gS|DA{YhRqrkY(N$cP{NrR( zmoth%7LP)j(pJC=m;QB-CeoMkyIpLJrKXZUgl2678c?IoHdP34&e?kQqa*;{f9kYb zY4IWuNIE|@JA!XXw@QeunsVzJ?P6 zM3f($oV-wZP?&P0R5bvI<=zvZP>gE&d3yZp?VkH5hM98Y8LCWC2#z{kp7nWTbb1Mx zgL89pQ@|3PS;=lOX?rnKID|t;n9aY3ta!L5`bm$!9N|BLUtCQ7zEP4t z`AWHhrq*Ni?Nw6kgOii7a~B+Qq>OOtDCZ+qoi>X#Y{cF?ro-_DtFyY>?V}i5*}X+H zV>dluMwqL_YFkgKxyaDRZ0x8%)(KcC$|z)W+lmm%da`4+3|9k&t4CC7jEr=;PziUf zO0UjRQc`jjp)71{1xytaiCg#BQi^1p4upyC0ghqvpN{ zPNxYO8SIF>#M~|}F1#Lr`T3;cWT^Ur{;xC&m7$?fg!e`ukVq}a!9gi5!No-hNqGyd zyx|6U_goav$Si(K~9EFrgM78Xj9AW@lj2452?S?hi82g&wWu6Zf2hGu3^ zWn^S9J2Q0?le|tul7oIL<*4P5hUhk+2>L$$UKW{a&y+0DHKA!E6#qBB3eGAhrmz~R z{jHN~MXOnhqrDOLgsG<6Y#joPOq4u!4eixES8JG?Do~+Wt5~^j#@TDsu8yK@nEo_x zJX+{{xrh9-wUry^i6*?kd`|`Ic&R~~sj?lRgak*xo5RlEezlD?TewO#h3=^(PcefH z^7;9BsmTgGyDftQl%&0`2J3&!&!$W8q(_1RV~O5*TD5Yv++66?>-WM%rI;oCYhSZU zs}G}y#Qi+^v4z)92RzY}x9?Vf!{6$#p)n$U!+vlzn~k(jN zk=$x640g}*t08&x{e%0h*%LMSjthI+umVAgB{Sh@Q7aJ25=p7Ta zl^ir_{RCibb4qIJp@|%Ul_H8Y>I_I_)%SU3hPR+C%Qz7KpfyeWeVIo0LdoMylOeJ+z%C4k5?2HN? zCPVjT*AZF7_zb&pzfH5%s?o)DBy$D4#?HRh5IrUV~Eyldh?Mal{JZ6UY( zZFTWYKcHvFwe6xP)*r}~LMOl}onprf@97pu z`~q<^jxP3EN(FszCW%}3V2HEm@SOubape!K;ld_+It?@c9Dq&4-5`B+R9Ry;XEG@F zPvD~n9bP$1BTrxU= z*0(HzBf%Vm^VM*&ynqh%?3-bTA^TmSNCphMTvdJ#T;dv4J{K(cynT^nQ=83rO7IkywMy&Y*r_>pH$A<- zxE(06F8>LA&n}<64DrQzhU3NA$kzY;%W$71hsZ}qLkr)*0JtYaHm_TO4Va#ugyhpi zCZ}rTv`&-d)dQdcwPNgL{cE(C<>>Of`gx8HNkRl8%`MJ0+UvYG>Z;(~l@vD6*Z28i zqc`ndlpZm~?Q#iaxxu@}zdYLfxm$Vk*Zb#9s6Ap;S(!`>$E&38uNJP#W$LJT}uDtruUSCUR3mxm^afHK3vp zWh6A{{Mj}?I@aS!NadGxiWv>6Meh?@_6@j8DV1~qd- z1DD$W0_n5mh0syEM|ef)aYGT?>WO(tk@2cIDUpiflgiMaEI3sN{YC(K{-2FT6RzQL z1xm|l72ob8bKtvXxJL6h35KO`UU^`p1|anU~zCjF8TRUNP7H>%3cf| zXuoIaLg@O@v5=jRned}z{zXKpEbOw4`|@%v=rH&wk$$E|L^Rb}Z?CjY&y}nB!h@SSV0$bzFe{b1`V#{YS!^Cu zeP{Ii8Ez^-F{}<7E>(LB!?w5*ZSQ1RjT|~<7D?jskG&>peM4@N9d}-x&z3@=v zu=~NMNW(?5&gZdXU$yt*&)OK|v}vKY>>dR=P>@#NiS?5d$J+Ur&`ndsT6P*3%<>6T zLiE2Gb}&{FX4k;E^;1LRmxL%KS=>0cwUhZF*1rw#(GV@c7$hPI?`S;Vb; zy=(Qcr3>Wb?fC1EWD+ZLMghl>&OB*t=1LG{?YOLldORKxR1hAgB~OqceRrnr;xbHa z&`$BogpJz1?86M$&8vT*igsPL?-DTDjIa?z&*|5B< zMh;{`Gf~5+$cDo|S!IJ{u?24c^HA6=?k!Xx8DfoG+=*7f+R&IJ+lk=@(ZU4%FL(LB z=X`Ux24_o?@eSsWgwf_2o>fDsl+NIQ4J+#RZdRRhEx%v(m+y`e)oe?7q2y>A&-79v zf>gx=ylm9o~J!ZySJF@l3L1SN`nrpjB0qx_xoOj^x=#eVvelYv3m&45}_XjtKM-IjDz zWbj3*klY6*`^T^6B}a{IBaN&xC^Gn09Z{7`>Ee_ii};g^Z*BpB6zAIQg2LvdF}D=- zN~0numU4gll5)&$L6;AOv8S?YKdS^%*d=&2K1_C=2(VR*>&43^DmDM=V+Nc7PJ&d& z#KXt88%HNaod(Rm^^x=jer-B67!>;vgP`UI2OG7<_>QM-{ARDPT%RTkOk9m95Qc#W z;4rKF3ic90QvTJHTujbqE`lR3fiu_>cQ)si~aWVThJV28KwslX1Z`xr=r`T23tIE9%J=ZrhdcTk{sAOg^6ji1zX#* zSvjU?iHXec+Z*!OgGE6pmegvlDY4 zwIf=0Y`gsyTh6Q~FOO-u-L);Yi9BpW@r8Lv0WODaGj3wKLJjsvMrLl_Ovkuj^&>Pj zRgH%rOW)C9$lVg|D~hGf&d3aTo!vUY1@VFWu9iHQgTRY$+N!7LL0eyPcL^H_u1vVn_>uJ4)hoY# zM>A0@{lopfPfl7cpT6_X&3V47?tNzQNbXvv|Mf?3I82AX$3_rSF4^@2K0zi+&+RA) zB(0QJ5y_s>FikkwYf=SV0Xjp_EJAeW+l#zg+|Nj#P~= zmP<1qNw1y?RURDVEtUX*odFi0Zc4f$;B%h^24L@myoliE5l6D6*YR|D96;J;GXwNS z?}{wPL@cHpncPTfnX$egXg??73sbnKqd=sZ-06RPO$$J0Kf#;tm&9h zvF&!xW0woNS>0B92>{xX3(<>#b>Yv03o{(P`dx5QGY%> zKK|=CN@{^S(BH2@PEJ1L{PLoWTNG^WJ(kL7ki~N1vJ$(ejY7d_Z*MPWzuxu4-de3& zEQ_fjsxHoGe!V+_I46Na$m^;li&cVEl{rRJ^>bL`VRU(rzTsGBeYT$grqGubCS&rK zyjYFAv5AS?*)kOsm8=4MMvfpQrGy`5@VMMYla*@mdRJcg8fGAGaY(l@&Yr4BRaMpI z=H`!=hl@%H+S)pUI$28$%_H%N*{~$ALAY7~GEM0^{P8+EImrpb$6r_9S`+ zhP4qTVKKx>P^9q-qyv+?rU(fMt?a^*#YXXcbv!9a_mC1}2laxAGJay9so;~Q2En9a z?1u|SfaCisr77q zHjk{{e>f4u0+}F;_hWSBWJ|S7RYy%!L>irq)|4)(^-tDmD+}<}+%~3Ik3(H3dkG1~ zbziKn11kqdQMM`I_gKwO11gGtx@w36bI6~6|Foa45{jhmAt*mUv9!{tq#G>KFQ2R^ zZtm_RfcbMIn9olO9q3!WCnSgl8Su_;ftM6nLqO^MCti}W0p$@Hw1;}VmGJR6oVl#c znf9MlNCzjn-g-QDrJ>Jo9OI&=jR8(;AMn0Bh! zZ}enq$M@HHHxE9sIIuc9ygWUX`}Ti4?!@sAc|yiF`vOseB>T#pC0z|^b(h4XB*r#P zkZqFGLlLEa)%BKKnW{*!xw@y}3KV-7=4cs1Lg>XLoH zdq!B|3UzgLm-i137h8vip0vFmGEb58a`OktG>P5DbTnDcdi&N!LXMon{FD9=U%qrK zmMQOG(g&$Ie%pJz+5Qvd=5v4g1QBowvze1OEaFjXw!-jg1R zh)?9~=-8HE`0YA3Hde7*!T9pLM=B1+a6`poMXS=J6g|bxZezESMB+;2wf)K1|Lsn5 zxl>;w-`VBqdT(Rcd!|4_M;wHa@m->1uRjF-7XAXDQP4>M{oyhnPha5T;(~K2Z>ni- zROy`GSih#8U|zgJ$7+wp>lUpbk#GYk>?@PzzCPt6wSUmV0f$a$0m|TyMk-@KEFdaGikbAsh`Pub#I9MOy=_7 z)5kQ42n?UXm%cvI$DMIGQ>-mKs6NfSj12i_<8X{C!VsUtkNwtaefW#LL&@J{rz@IL z)(X$sp(`@BuMvHSS{YKr zeLzDwIf#0=P3&H^q%V5|db*hb{1maUW`yCX1B$r0z0LZrwimBnwnvX$=xm0rR&fWj zFOju7ILwqu2Sduw-xZOPGT*pevIEGx9|>+Q^m4_z$bMj@P=1Qtl$*s=b;_DQ7*h3W zDHYYS3vqv@si0tqY!>&nC*)ExAsP^A@v(! z$cp&mf??>DxK+wrvR z9zk4Q8MP<&Rs6kWD~q$Zuk$w`F7tb#3%5e820kzp<){E73jnLIvmt@cK%R>H;Mz%Km{+Qh8&_CrY!2UMOJPp9W{*cY<;7ZfKLd7gru@E`>ATa zzV8S#aYSUJJ475`znDgd*IBN_8VvaV7WQU1GeIDl$`q+}a~K~k(2n1KW(pup14`Sm<72}i0ViMED_~oFg(TW7x*zuF$`B+ z{N>~FrfRQz9WAYnqG#5GJSWWx%L}Ne2hjM9RF|;r5$;*nSzc{8|9Mp%lMiY<73p(( zRf_yyGj%RudjhGD{7{H~sfK8je8i923O#-WxH8JiHsr0XEvnlFgpQ;nOT`<6Xsv3XFC*^OelX9PElS1%-JRn?EQrh+cEm;t?(U zj-DwkIL*y<(X$12xTp;`VYX^dK&QQKUqmj`G-a8zlB3w0M(*msI3|yL8}{6Jh=oiF!nn8k~)OeeSPb)$W-fy zKENB(Fr)851(MWIJ>_jnA;Hku4Aw^tVqWjH?YZZ=gbLQZw(!!XM@jlePYVi^UbC7u ze@r;TBc`ejt_D`H=bT!UYga6jt|s39NhUP(khuJwEN(L#meV8zf_k^9ylh*f8GgDc z>4JW|{vU4-WVwsws?=&VdbrezS>GdEqxrn>K5k#|Zt1O2d*J6Uo+t_Q^c+DW#(%U> zz!_<`0%tRY&~BbeEkFPY6$gh#KM9vOliLBw!^5MkqXWz-GM^k&wAcIbJ^-Ym9Itm} zj!U!UO#$7=Ur%aFF8pa2vyyiKG;@BF2u6fD|p)| zXy_(9B8>YDjm$FeMr8lio>8;d+42{Vj`Z9`~U0yj$K3;H;mk>g^fCksrx{=!e}3t$xqyzB*tJ&?jNw4c!L{C;IQ z*Exl>Ri)in70J6)hB4kFx?I+-xhfQ*9uM9w&Gl!aJ>qm#kS`DpEjBkx(O!9rKjYIc zGDAreF)OBsbmy0g+H*VE&-)Da}qS#E<~MkO`O1XHZE zks=t=CP)yVf|N}mj4jJb?<16?N!BXIG_i^G{TQ34(vpj!oiPo??Ciqlef{Ug8Cbz= z5+U3q<|UzZja-^G`Kui#>gU_GmR0aKbWqmW%h5wiHlA|X=sPn=x9rBS<;PW>nm{!#af`@6$)oF|7L9r*fa z#SlyF4j#yJb`b7N595!qxw$pG6<*5q8!&hd@o ztw((yY#g!{e_fzn`iA05UIAOn$!8vJU!^aK;JZU6pZc3+#}0vpS*Ft-R=Bmy@!e~? z>{|l#H|w$@yI}hm3!~Z<&m*rF2L;jUinB|$L$WLa=xwLpun5j?gwPIh`+8>=4R{vB zj1mwlM4ot#aCXPB{cDSzm-?L(&LBn4@#=W50t>sK^r1LZrxU6*4z35ocXoXm%D=Cp%VOy_6wTtnaB#+V z+QhbePpUz0)E7jD2>Q}*X{ja;;e4}~n}zz0mGdrj^nQu7QuJ3ilUY0Q;)xi2V~lWW zSbh(oGvpPrkx$ynQhK+doOYc3QIlpm|76Z}q^y0&A?`rE>6B&9k!cT2>@~J!wM)WU z__nGV#BD_K>TXN@B}H0-hFMeDnlACno`9mg7 z$PJJ;EP2Ed4by{K>CNx{Fpulo=l<`}2m4wb{<{IeHBV@ADmn=IrvJSBzUueFBqJbu zU+xRH_!hJG$YsOzBK0s?NMFP6?B8jIjALtu{T=D+^XztlSbKMT#?bG5^Jo=sZ3jam zJB2g&oDW$f9#CIiigcvjm0t*|v4xOb5c~^xP?SkO1w;FZP*CjRhjKH>IzZ6U`rd`) z>+CYsv#14u9dq=}DdP*koo1X(l@@{3X>VJ^sl)TV)osrn-y~gKg~@$PYLd}HPni4L zJ6cFJscU27u7*uoGh)a`n*<Bh7{;^M+Px-GBvSKWklsG>7p%3ca{WW>T z!E1TS+&Ek%U=GlpO!=O(_fHcZ0{nXc2HDrd@jm|*2O2yH0u=@ANp)L^(X*0(>S@E3 zMuHP+G~8bzUV)ET(&i{l+F1=~G&Bh0{K~RW`7_9)#4*$#ij$`JD~ULWKhLbN&QG`~7_X56|v6DMJgJ zrgD?X`PPkoZgCZC^oT~IJo>?5MWnW81_YPqgeoYgU~_ z+(2)xHOHe7ystyj%T?0kHk5WIu6D2Fj4=q7-KqY8GmGW&as*%5?0%gB-+qcTmJh96bMI$IhZ5C@}6n% z0fpn`$I4AKApE6&kycEanBp|im75f2^&UU&~- zLp(7wSaVapAchBZW4csS{nXN6H&#qhkKP?0huc!)q2f$Y2jL)uqREm_?u9Yi; zH#%H>$GYC{>Rz7t#Q&CpJfWdEs_n@RqG@Q@aPg;J3i7jAi5~xKo))6;hEJ}G5@&2P z@P3LDMnH5z-F)Ybw9;bbc{#N3o%Kc}++eGlfYS5oA##!d9j;o!S!*??x=3Q69)z(Y zW4khfmG1QQ3IRs4Fa3EwrDFnpOooK*M=eJiv|jSz?)iWFXY3c?O5#= z2snonhS`ZirB(*hdFh=AcsgFwgiT4;2dM5HiwdnyR`9k;yQi*h@jncMb65DK}4oqQl| zjXr$!b;+;iBvi7;7p9L0Q)^*cI{@sf-Lj#uZ4B`l}Y zb*faTRk9RP8~jJ#!TPd6_v^&ZMKO;G0?|D8&T1HD{5rSrP7?^j*K z?x`x8terchvzue@f4pO+I)3D~UGpIzj!!piVJ|gZ1Zc6}z?r`-K+>1w^d(Nbu?D>Q zGko}|wZu3*Kj&(3T(M}__u<|e_;fi z0WPI}#*@!}?xp~&#nrA~>sRyj%1nq=E)fWlCxBDI3c;IBcfPk>xLWs}T zGyq`jI*(nL=+yv}Umfm$gV_%p&sv+Oxw)l+0PC>t%7pc8fzZ}+1?r>I6*9nY9^E9C za7f6nS27L~e#>Jl#z*pNo&7QfH}`w2Q>miK&<_We^Ia?3vo}m$#ShecW<$}kLWsar zlqsd`QFQaAngFNQAuH*Kn3TUR$9KP$-qwtw1-%h^TOFc$Z2SkxbIna2dwuFW1}}YU zb;%$^iLQA9*7{HKaIE>Wjle}w=Oql&+?1$auGicI}sj)vC!*2|nb(IfnWRN|YPPxEzbjip-# zUF~9v#>!NK+Qt>h!7o$Hj%?$D5tRXX6%vTwxS!F&m}~MsVvbw0@KBU$$2i7!G!vD= z&a$C4&tp-YuZ9UFlPMGNkVR#6$YS;X3GWnA&W&*AY|RAj@iNO!(||O(kmok)Wg)bu&SYR(Q3Sl>{~^J(o7`vF0%VJCM+-vqj8R zTM+NYj@f^>$!`Dj-c8AYVz-_z_T7<-7C*mv@~l9Azt~&5e}NQ8uL}#`SFPfXPG8{iXkm(A97Muc24JG@?%p3;qL;V(%H0-WAM^ zv+z0?n5A}pxeyR2UU68p2j49Sb~}UpB*C~2`Zg9Fib{#QAs=Te&O>Ic7q%(mw5Kgc zar_`p=P(`?ch?$E!3pm7PAKG27oij@h<{Ew3M9pmdhM-gup$zdOU;dXe|0TwK%3kF z={H|fL(tmj7T{CLa+WxqURs9aQm55#g_GWt@Gg#Xn1U7W*`5NoaMmtcm_BtP(`JsE6&J0d1Z@NH#hKWy#WF9 z7rh@nE{iq#4vz3+?P!~TqMgA$j`t7hNpq59YU>&@ON0sR#>UQmHOAa)%4s>hdH4g6 z3e50*04^D6vD{>Jt4@s-1(^jdUi$YBmM7?Y9((EFp!iIO+sW7e46OyA`I1teM-F-t z=R+K;p&O96U$(Zk6mJfu7U!mEmZlb#n{7;*o0_&ulyc91Ux(nL6c+$ZBS1tbf$N{5 zv~*dE|J$?Cr0@@RjN#GI{zy!EHalC}^B6qN3ISEcJvR4Kts|Ck;64rE0)L7*{24ll zKx79Bc+}u&5>^kUXo$<}M6lqw>y__fS?FoilznnJm@HN_0E5BN zDyph6fYb1vBNLLZ0ws=R%&+BMM#Rg@du0krG}^ThMngxh1X@RKK?U*O8_g#^fZmlL zHBu&^X?3H4AOWx88~AaIBHtK_f{LnSzuo1ag-ux+hs{))S)G+cDvn5?-&y=;aq(W1 zOcE8Rd7{yOLofdv3P`_V0A`+b_9GzBr;d37enHS4yjU|L3@eelySu!yI!Y=tf<_2H zqQq{Q87QGys47*O!>qX5fnIK=C6QzT^KJ6n##f))yH zqMr)oTe5AXdSz&Qd_2FGxw(1h+??7s9v;l}+Su4w(;w^9H#x|vb5~ploScB`9-fG@ zN8!LzV40JX(^A`xp#+U@?9uiwSJDD_hadGkQCeuJ7joV_)ygI!vHMC%jNSd&?DYY|Lr4`;*t_xFxuk&)bJ^U6j@e6f(zNSG9@>W(GYX* zCj2yse|zdlttT-NvTtfi2`_YNY88|t6fl{?3(R!ra_dXv?)rMxBdZZ-VMxpAyw6=- zUDtMEAQrX1KjI}d*XvPe;gWcH0&5eSZ2u+p5Uw=aNXelT84zJ$h@TuY8+4U9&Z8F7 z{rsNpz^AFEhB3iyd?_;@@{NQ{9rK#4&EtZ|dcH!UvOc$>gf0EEGK~00I67VrlRQQe z$2riuoQRbcL6#`lvhoid0Z{(I_n6K^>_o-zxy%jm%yzHX=qj?L^YPpc>(l&XUSgA^ zUIWq4>?E>%s^)*4!8n=t*DXmQH1t~|Nz@FbvZ()#qip%YZ8;^~e{sxRzhK^}@)RQc zAM9g+<02_ie7V|@T0RQT*NOi-zN(JoR;W@e+jN6h2&}Z=Htlw2vu5HZx10S5XKV|w zySVRggDU2h!~N4KW&et{&oy9Xz@y96f$cXtVH zA-KD{1%f*ScL;959fCW-Y23Lx=bV{4Gk4uTU@dy}Dypli_I~B}Ja1yK^#Hkz4X-%j zvHXX(b7Ly zJ`f{<4hjk~1l7(NfQ*+Y@0)iBJ>LfKqT%y>r3cMGc2??(+Pxp@RW^p z3LTFHYPuZ5p5QOVLU%sD;wd#+zPvvkTWPS-)@k=l^U8Vun$2t^TVFZ!<`JyxN$pr5{5EcZmY< zV#$R2CqcdREx7fI9smlNNc-;P3`3|GNb3OY-hHytI@xHaUjlhYuT>XHn|;KS?=zUe zTS_CfpFP7`5F(vMpx$eqF!&Q zIu7KGd`ZLTAVIoi2Yv8{u!xA-EkwI_CG82Eow*_zItfA492^{n^ZGus>(WOOU=xBX zP=l(jt!?d@Rprp&EG4Gbr$z4X?-!=%2nY!H4z`YyE-nKcEG2j9*+CMY$H~mr{s+gk zx1h`bA5&j{>FW&Her6br2}g{VPzKash#obE@>e10_>! z#j*X_vU%5v)hCn$z5Pj`D=aYCkS2!-@b`b~q>8ccL#JLL1MC-cN0XG2lT;rQZ9ga} zDOtCE*(W=eR|qxIv?-L3{)JPUyFCmfuib+@GLA!jbcUV-KiZc-B=K`%LZJxM=!w1y z`8>zgMB|ioGvn@rvKaT*sTJJ*pQ6gS?FSIJ(AoU1={wvSh~bcShn^~nMl9ZH-N$Z- zi>7WBjhYEy!ix~@H>L6a+fM~p!1UVA`yNKUw%Y+<`A|r+sf9r;m!Fp#k-(&LOS^2T zdM(mgvqxN`po7n4+t#Sx;Y~gy>dn8{;gh_yD>PSH8^`SO#gpZ6?dK@R8~+h`{MaAb zje>9p2v((o=?R$*kGMFjP$`HzOtdD_ep9&m4xqE&F(}di=wzFcqN1YsymJs}&b|!B zkq=;bt$*#|Kb2@Vvm{HZ;igy)?Sd5CX&FRp>Zy?pF9y`1=9Gu zNDwSG{Cc<4Fq*zbc)O?neH&5A+S>XGtP#7A1nMbHVI{1S(R@+`DX~GB*4oCk0O2!J zUMZ=DQ*Up2{c3bPC@%`t<9`->el!`WJHlR)kqi-Ow|=z=Oiost0s=%NmG>9PjJn@k zo?l1NYp^5xH~4Mt#;iEl(1`F`_Oz5TSnR);EO^0u?Rt?#Enm9L4UgC?bQzSHmFQLG zGYNCNJO-a=NeWwae@>p5qFO4kXj^Z(_cc}0mzg2^(At_aTHd$s(|F#*+{BQ$=*%zj zSe^HM!fv6WQtSqy#MW{@`L7|YT@z$>u>CrpK!kjx*P6}q|M+VF}yim z2&h6iZDRiUDxK*QC32ek>}Nt)2|x3Ej{L|-M6Zgv#AeX-%Av(aVR&NK;Pg_ryeZq= z9RApiqdmSRvXF=WXSxXG8;6y|i^tYp0Q3V&SItM%I(lUT8%_ADed&E2!pA??l53?> z(d_XF;+h0#=j(&N9Zu$R!zpL5WGloLJ9VaJsW~~2yji2?8ZVE~?zU`PY)I8@+-NJp&WS39!`Rtl0Ep4KbuNt!>;x%cJuhbUShlMix3^%r)>DNy~D#L zZ8^<1n@SwSHLzb;4UP|>$N$tfH7{Z2vNNP|2RjWUraTYTi^lz0;Svxu7ol@;x#0n7 zU@MiKSIXvFaRf>&HEgV63Z7$~tI%5mt5}Y+I55qPPLvU>VFuyipO{S$wLROSj@qLY z9n*SyCJK-EFAi}F2JvE-TS{jhVNq(!{_t9)3Pj|y3$1ok_6csW;zn+&^QFQ5tCs|- zne|9gWm<)GrgJ@9-%eisIt0azzo+e9Z}`gnh1z^^AR39mVVoL%tbW9PSlf$;X})64 zZy4tl=s`bDM*nFd^019oO}lme%#3EM$MbY0;rxu#THzz#2vesQVSHm&rke?xCvR<^ z?k8-3_{&hpo>|XsIUC)f3?R0*)?@oxc{WD=L!;lwAN!qW9vrCjY&6t)-B})00qB$+pj_Zcm3BRSzEbviG`T=-;?gJDJ$g*g7i6am;4J)ZI2cE=wuGPTMCjZkxjdD4L?V za(^_nhw&m3Clp%jrixj5Ei6KBuKb#75nT9RM`1Gs4J;_K>(mnqpgHd6&fL!2dSk9W zw<4G^WW?eVy(vQSk&23E9|?_fZ8hg2l#C93Ir;7wT$au3-f({0wO?I5dCjqbtoK+7uNzQLLq!RHm+pJj)t5WSHkoCYOdFeobtH-QE9|CA7JAW zlhb}ye%dmz&4(TU!W@)ODxd!QpDN7z3!YJ*j^|OL6V&!kp#O2KN&aFoIy6){Uo7Su zb?iaTx|)@cz{l~nhu69fE+(t#@t)-C8g9~FVpU8fOZn3p_npD3Z#84=ie z4s--@-!X`iy=)LQY#dyyLDmxV73&?n0=+NQ${wYVk%LF)pA3GtLyJ7O`nD+h^gh8E zqdjc$EIziP#1zU4uk5qg@3s0l?wN+|T=duIdc4l!i{Mo*+B&)EL3O`FmuZgo|DcZJ z7lI-^hW6`*5k=4k+3bgwaAJmkDs{{S61nt8KR;1tigtupVseQ4-LT`m2+b@f>TmSH z0&8Q3OIx{0y=O?rEw>7zr;gHFU0AM~Pj4Tgf8NICi**yAw3`TPxala>Xv7nl5t&!P z!(S}z&pSFip?)WGA#s*yc->79!B^=>6$Bp|%fB4+7&90oFCCGCFxuK#`(;#U0?39Y zIPCau`*)*~Qy}P1DVlo%$!pk_;1SgI1%~9OEuYSvUj)OVohT9f*RBbR9IKi1w+VLd#v{&q zxm?;*8qks|+nH4&!p{^^xS(Q))hZ=aK&9nh_29(lSCe5LL726>GOV-`2a*BsDZ7EF z7|9S?F?*xUJ)}@I;De@|8*4DFd;BK%y^vdCcuq~E|=1Lfw_iSeBsiFq= zH%+Y%3Xvr=!vy2x@&c!p{e=sVp&R~i??@S2IKn}-lX_>%=pCJ~LXU{p`K>_=; zUpn>uDM@Q8k@VG6=mD~6?^Hqu6BFT6%;rLe{?o?Unejy==ErqDkUH1}f~5gq!<6(b z6#ORV;lU#&CZ?BkiaVaoY_jSF+#h6jl%Qax71TmZY}J?By$C?UWs=s#a*>%YX)j?( zJI0tA;@j$ybdxcX5k&QLztxrLv(au-W|{N>Y`?TC#H=Q;$b{U!B;L2LsO2;B#}a_+ zQt`YUuxtSGLpYEdbOPF$#r^X0jTjzNu%wG2%tS78$B?eEi8oJp>_@rBbXrT8kPUL0&FyOqx^Y%NQQheD0i?xcQ+>3 zpRcirOxbw$u0GB9%5Xa&gA#M^laGt>W;4P9pW|zZ6QNL9UB0{}`HQo;CuB?KgV!;- ze3M@~8)3cf&_#%dVCw?Un%$9(x$gu8J#l+(j{4Sqw#P56EmV7rIn|tSxgIV1IZ(^f zjrnS5X|+d&hJG%VB1PL0KD)k_u(xOaKC}T`IW8Bng#*s+udE1n(Lq5-8fy$_hw<@q z^TmFLM?NY-~Y|Iv2r#>$|&eVPIe^d$+c>{-Um_>FLVG zJ}1jOmSV8I%rAH5W4MtjC!@gU!VN!pTl~aJGgNsOl#@0qJD!!K9(i=HXv-d%Yf91c z|5%;i397Vs#duWN@choo5Ws-Tn0&FjV@-9un{Kkx*ST}XdOTe&+|WYAkJP1x`8fXR zlT7Dqz13$8BNfNf3tTNNG7i#Lzet2ON7|aJiZwCfyuB%hV;1YPV4E97^E``?X`n)o ziH2^t-{WmFejl{Gc>M+|gG-D@sD3=J_#mRX+98`3Hx_)E`pR{a>l@U*0EYg4iOX_u zwpVQt9xM^=StTd%MWm9JQWO3C+`av#dbq-DkDMeX~n4BAQK6Xtp3xHfXC59 z63en<;@z}Nad^>fO|rP=z=lssMd}lu^`H~$B)Zjbb0w(_^yI`uwv#Qt*Zr66{plhX zRd&PAmX>B96_wJ)+LG8U20~^Q-C8r*FXAdQ7Sn~Zz>Ez}A?en$OkS*kd6;cYtc|?E-TWYpHmv}+|V=IRLqm8Z>+C(R^R73(?wbI5g@1hZE)kV=2mi1 zhoaA*E0}M4a{_bmApeKmRv#NziP)B)6x}Wf*gV#F#u+|kq?=|kHNGs?9DwI}uV#6$ z=n`~-aYtPLmVx>IhE&8Lr1~BelH+GP)&^@St)_;Jjxjv1U?l);gKy_7K|ds-WodTj z=F85JO|J0bVy`42u@NZ=b)%r#*r;S>=ov}pqs&V|UDz|UsPN;0^4VCcIh-kNT59m; zXQVH6v%LE7HvF&+bGw!dh?}bKIU63M(pYMh?6%@EsU)Nw-J8Q}a~e2H{~VS%x4)*w z?B071R&31Dp?uF27kR` zu)i>U&B%}3H`Rr-aV3Zxbu3$T-%Ce--yk@~kC=nvQWTv0XD%PU=nve2v%o(hes6(U z9STcL)%h)5XrJb1^>L_`bTwfq8TjXx?EwK?om9I6VTz${+7tJ{WyAZ{g$dK$lOim+ zk5N};o0kFNUpzo$Cs!E%%QwRcNf^2{)Ajj;(EJR=`13;t8s-%)GB$(5<*JP5{8x;V zhm$-M7vl%ObL5dw%QNY?HAH)S{A`$g_}0WU%%S&55+JRg4IbWnoBtE@C-4JfmXBXy zux~J0ggCe3jifs$BreVniKiT^ho}_uTU0;0G+n)DwU9imztXj`w8)v&*Y1MDyrGVg zOqP0`zUsBkY=Z00lo8PWgDBE+zH23}XY%U{so2VmZ;+L?Ya~HbkZlR@!Rr_qo4@jG+zWBh-&VEbb zk{Ze_bkbMd)V&iSe1-4$5OzwzCS51s`Wo1c0%y-V+jo%!oVka{)Z?8$^hy3`E_F5u zLx=M8h)BbjSoj=KfZl}PW$I^l@2i}iY|`y>b~cRX)~{227Cj`cH3p2&oK`M}6)lGqR)@*Q2gwx`D=mk66)pXXD=WJ1$Y`;16NNu=>EO4gH80Z@ z?1m?2p%yD}yP=AHY8Oo~o3xR8uT+mlCDMGfLpTEbHXVuyHkwOm|m zZv9amm{lf>-gbQ{vU1tFoq46{+P^H#fPhO6Tx5Lbl)@(sELM|b#E$-tAIC8}bYh}VPy75 zHHKHwZo^Rx#D_(uP&Hg4?gvWi#I_&SF;GX(z&k4&x{bb;lcufgRuxxPew2nfXEaDn zi-(eRu7$e6Ti|A*HovYCd=oUbP%`|*oRG->HK2?@OW(fwJwW{YY4pccBme36{yMmC9upv8SG2 z2RaB?cFxJbq!0%iHr9T5(iE^!r6*cNH9rm6MGNRYLy+xl6TUj5XaA_;QCMR+bo7io zXmB&SaIE-8V0kpM@;Hs>2mPV~{8qdqZZe{kZwViMTvjQL4Z;ieV zTU4R#E{$J$18R4zyOJ8^m%ZO};$2*KXdNw&QcE-PPfgJh)L!!s8LN)0WVtw8vhmDC zjL3VB`$Na9{n=Igpc90Nj90Y0hr_+M+xp3x^_u&IX6**KoeYNsOym&I%# z;0l#}YxjC5Ju;oVJ>hf>pDs#>k)AbT&)HTd7?ECgIFGyO>|La_)|>6s3vx_Y`2MI3 zQOuL?#go48LTkv0+rE>#I0q>py7Eb$9Kh$`syw;>^N4a(mb%#`R5JEw&vzl8onGj! z^d+dh0iViCPn$h?XpzPHKovnv;@iTPeI8FeDok#waFpkdNnDOp1!5b2e&C&7EaFSt zmiA?B9!8ZDZC#jM7?xWFT->CPao;QY8RyqUiyk3iu~EWVx3 z5?e3UW_~1(7t4wp>eq6M4%^&Gk4_igV_KEW3;&qMpG#KzVexlNu=zSqle-d6o7yN{z5W#+K@fs2j4Kc}Ef_7SeDQJ;!?wn(ELJ(^*n==PAM* z7Cq+Kvi?dD`C&vZudkuttw@Idd2dM509YKRu;Q};_FIK}WBy1wM!;cB@pi62TvD{s zjKP9`wv?g2=q%Fo_Yb})W8(|Li!nn}J^tr~9X}rE15!aAA|H~Qe)H($P5wrzXZ%$K z#H!lHxq;|1rn3he=fKdTFYaB^ZFT$uVvz2EN<@oB?D!d6LWlHVGmd9R8Ec)^)37PvK; z`{r|tV?FN3+)1Y)#W`p6ua52-s~i4-o$m9&!IAC^uS)z`lVif=_*hL0PgKIa$~--{ zlTjaV$TZFUg&lS^Z+fe}_2j^jZ|ee*JTSV{d(B)gEQ+4nr-)P!Q$XjwUB8fd3d5X zqN1OOVouxh0bG%YnwUz%iH;I179afe2jS3_&@&kg)T>t;rU&1Z6Q&K;dP{W%K1qEb zG$I?G%9sCLH8&d+WP6vne`o~Z41{M48Lap(bsDJ(2o)6|{_(-<_IoMXmX3sFmy|=qYTZdD~rv?%C zsz~;`wls_$fjKV9bag+p;SR@y#BU_9t7<2LF1BC;`w9#eQ?3U^II)S`$*AOPPZi*P z3Y8#sOuT+{IVm|yA1`b_Ph={{xXD(mAMfj*FF4kDpJ;OL0{$mLF4CPQa!SDD@TMAV4i;r@hdgDXq+>GoI? zbC5);><3>jdw^$Dvi8T{FiBQNhbi&R?hIOjg&w{^9{dhooy_(V+C3neG-&qyYR zPB!PTzr1cD&p7rGpl0_08#$NK5MTX|n4XB<*`De{Az784s2ODC~oFcUEWyU>y z=IaQ|DqQn%l^r$5LlOM8riZQex4evmYpDA-7xjCO3ZpWT^vG8p(VeKLDEhSp9(ljG zJzkg`tPNEp+nGQIsW%99QMC7+*_l5oK7}t-y)-v^wNI1!hZ&bPAtnKDV<$_z(b53XnX;-u# zl%`lOZZR;E=#%Z5&S^4~R9O^$HwiKdX;CKY7U$bh&smh{Hj|g-zRpY8qR;q}1yh}h ztoP%z`{QuzHiVjWqgkVUBj@EK{0w?wRlT+#6(u9FXHe5`XhPJ4)P9*Y^VBm7+1o&h z&?_xYy+k#k1639SICT_dO%BtqJ}@TCXld0;dA|C>is))2C^;%Bh-X-vAc_d+O_a*; zITO0H;7w5_5)i}MSr#baP^yn7FPFs+wH#V+D2q!=>MG45N4Ukpdy%P2N2UB^Xw{hb z2@+fHV!wOhF+01$rqHrXp&y{uf2kwF;^MPv3t_FUD#=HJw&9Q#CJ8P78Bn|AmfsPX9_RL6E;4_NK&~~>Qgl;Zde8Z}7yJK%| zL2;+&oQ4sKj6&mU#+;Zc`>oM@$jWoJZ?UfeHOqfi7O>RhmWRWP?&YLTcoK(;yQ^W3 z?g^v57TyHE!eE3^DZsK6>-wJ;6eoL)uU!~eTq5ZDa{XEUOqVP;ecQcOc7mcZ$j?`34hgzMZlfz}%rMZl&q;!0r+V4na{c%aQW1d7)ixH0mF;8%m z{#9QkW5t5NIm|-6E%c3-2V`aS$zJa#d>0By?r16t_w#^CB%c#9UprB>oy&1ohc2(- zB_yG#+5!5}ZcSwPRC0Z}`!3b>j3gPL$=3993TZ z=-Zk~S5S3BFJEW9Kmaqw5Ky#+WU#iB6`_ zC&G&pxYVP(nGzvCS}I!wnIH+3g&oLLjxaQ|q^npNaZp}qd399E-rEA5fQCU5{GA#{ zMDkOIZ+hYkg^5Ywub_YgnlRy~Z#MRi=lCYI9o?(7<An=w&h8Q^>D_9*;vLq!!|aUD|IEmnadI4ba3!}2^^))S|8kAi$%o_X1mz!&Ube% zN#7dit>nNUKa_}aI4cSZMM3D>=c&yxHBji3wKO7Qou1wv-{wZf4K*E3k9b4i0;MW)1IQoIp zv_(W!$`G)d+1+-kowE|?^=5hP0%_pR^oiMe!{YJ67zQ!ZrA5K#Z~+&gEZ=Inl-qSy zQYG!awp5P0);(UCZS_uI7{9G|Pfhf@<*5DDwP2GVch_~gh^Q{Xo=!vi)wA3v4C%XV zxD&y4*bZNh+{KzN!#B87R=kDJ(|NuR=E5i}rvrJn9!oTlx0Wo=jaMNePxYLYl;!af z&b(batBQ)I_fFGXBc)*GcYYeezOd-(lNfAVXB&LH{r6+YE2?or{L3U+Vdl1 zQMYCDIVYgW#Xu<1y7V2xd$`eHp8)a%?|_DCG|uY>^d6U^?yuJ)xwqOT5RIl4*+;#0 zI$dHvbwd*!$CONM4;9|Z&(n&ny-eeso?F&JHyV#E9-mUm5AVyqY^tT%d)`09sjKGi zD;?%6*(q_cZqSS%;k-k}K{jlNS!M9%%JRNk1W(kFP^-$L;H3k4M;ko(mfsBr#ADGd z;r8i@$pUH{FV&7raOFBwzr*)o(`C0K>k~sG;YMm};aVAcm3P(c_xb|_2pvXr_p<$~ zP5TYhUC5N&=1uNl^nAOy=H8>xKH_=1dPS(dUJ#ggqS?aUedRo5N}pVxs78RUQ6FTN zvBXzkh~cWv`+oXc=1O0s4ENmCKIM&_az~}(veeecyD#D<Yy}Kfm0bJEF{jK-L(D*MUFfRFOn*dV3yBi(FJ<^2o8Z59#lC(3 z{?-7m%ZQ_P^-8@wLLwqA1(hV%HnCb)7TQt|Hnv(xpzi%4Pb#^oXlcKZD&X-oZdtFx zo9NfCUsRZ~1?Wr?;!!wb05CdKEROrT!~XX+`}aSb4uRtv0W(dch|M`rw)Z$%sCNFF z2dqae1dH4BX7ah%+SGu*vn>(+y-WXVtEQ=P9mx_BA_rUr<%=5vLIl}EPC-EsXlXIF z19*G$ah{%m;q)(43@5(PS`Bzw$()=VWD;~HLOMFSRjHKkFKyM;)oX!p7?w&>39fBi zz`=y|;jpqJ7l6usfRpP;Apwx9Q3CLN4GTg5h(M|8;dZAVv{2C>4;P6TVqH4`-!Ua6 zCDA>BmfR`P3%O+U2$M8ZZf-7ZoPDgTC-aD9C~$9Ym;xZbno*tK9=Jad$;yJD6=#!uk&4Mn|f#6<6buE+P)-e>I!_pjFTrs4=)DRl1 zLb>mje~ym$qbO&B%G;5=yq@M;RscE8CNZ1FW?srtMjnt`x_$c%jfhA$K$El`_&tdM z@>=h3ZeW1g5m1$dYd$Yt=6W;=f8tyd@d1smI|J~-qzD`)IfJ>^sj6{%?qJ9O)9eIj z`Vo|?)aB9865Xn!+ltfcw=b`Od(Iv3YeRP{fG6aoASD$JDM#AO3x$!?)fI@N?j+*- zs*@_@<85xnNXK&MFaLaTK2`8ZP3Yy(NfjD8;Ggi!sgRJTo)DA}mP7l8R2JjTQYr)g zxTl*nA3Eow1qT~2_hwg_28~3P-vp6>vm6+)d?u%Qcaxe;ak#%vsZ??eF;rWN20+{K zMpOyC9P8%hCc9>mvc9M&xt~ag0xV=*LqlVE&mRJOW8@kd8dBa%V?wWv^)96Y#~XnL z(Dbr;F9sWgfr3Xt7!C&qlXLc80VhnKA{{CSDfa9H4WTweV0WnG!}YPl@ghg{xDd%)i873yo*q0z9)h>{^XE@Glfd)7^xJuO z9Gv~jT)^HXpVC2vC(4D!yd(AuKHeM88jeXwNZ5hP1xC{LE-rf)AI>b^bm4fNUtDY{ zqlBYFz$^(*Vr4+BhXs0V^&_#{trCLfJZ738uv@0^UY!rrW_$GJ;^KlF9vr~)@$vNz z3|ypj1hoR@9m*C=T*xjgR3rVQLmbSixHlM>S5>vMG1e1>^ZMpwB_J#e4w!6-ErYvQ zCeR5?#aiFr*Zkae|L_pOqy|n1%V-6#?tll-z8&7;>L7TQdG>6Fcyo%q!9-zv4UDGW zj9rX}0wDqVd{gR~%*aNV+FN<{n$uhUtqWt&l;22B`NkU2)zu|T(QtNVzY+Z6SpMV3 zPFeu9`-!ACmuHsDl|S~!=c=gC&{+LFk*+OS(A_5t2@Vd|Z+|y)xS13p5E6m5Ml9$_ zv&`>yE*9$I&DDnAw-p?i2Ne+l46Nap>FH&>qf@jzc?OraE5Dx|Gwmd7WkUC&-99~4(A7e#gDi^a(YLb$;R$6 zpgendY**XiK%;$fVMx|e&ugO~5v;Yv@%B!Q%uODv{oNSmNwli#8ykw9NF9Y`Wf8r- zz3@0WZGMT`Cd(r08@=M+BP12OIl1_)n^7ICqHpd!wcE}w-<2)Sl&Q-1C%`K?FXm;94K8-r-@NMMpG-z^K5lj#j`-ZoPjUQ{#DcXE9QL(D8jaOxS| z3zs?JjKKlaJ%_dFiJQ(~X`Y{-pIi5>EX4hA?gziENw;Du0pka;H#q;QNeSYMvt)%$ zNty|x28x8j*ct3(J(_HvP>Xo#fQ@iR73udE#F_(m;lzDQ1ZR3B8Cpkk{@ldA02f9& z`d7OrZM|izZN}&?rQM&zR`(-#v6JZetxX+zI{MG{;koblf+1sGZC%qtL-0VJfYriA ztT+V9$kRL2K6{kUZ+v}}w)KrNzJKp?JJ3+6IfDx}ap(~`J@>{Baz+HEAQ(>)CV+xt zBMy@+QA~7aXS#CDLR;-4-LApycYt1r|{a=R-NRom>13x>( zA#ri>oobCienwsRL)`wpjGKd2Q*ZVN zIM2*wJ$FG&=!3C4U01mrbN!n(|L@%S@21{+*cTvgIl>2vqrjnUeM; zPzaL=Jn=AD@fBqBT$*$1Pqeqzx-}(G!{qGmDhXAzKR18u3rtR@z|{M%m82MVvupk~ zTeBY%MQ|?2438XBi(iTx69XL?tm^}ZYSd-gjTNaI>Eq<2+D#wL+_v@MqG`NW>vBo5 zUWfYB>~%b9n7Ls#Xb}o;DjK!fIh<-tcuNS)9rtE#C-vioGL=237-Ck822g9*vR=H0z5C)C zXw-?r1ULdLhwdL@zZYv?gUAfhGW*L__gl}Bu*o34%mp|qrjVW1q&%l$LOI*_@~*n7 zr1gJQKL6kH=ikUpCnCf;_~=~vM6-Jsy+FX^`%TA&lXc?!OAO5`2pEE<+5ECMyqM31 z9wz1~!f+}&XTkcew1I}-l)+Ce5mCJRzY7}wUDZfLfZSfq>qEdE)-f&M*-NGG_MJu( zNE!Z`BZF7;Jt1$Ri3OznBom`|CaaAl>ugu>>D0m?~nci-QANSR;@O;qtpy z;hy|-*pl$P-!C#s=X0r8jzK2k%?9EIZlC8iTvrYdB8;SSp@68u4`8dQ&?bPwFnaIr z^YWBpR1JGJp7oc22GL%%*TdK9w}>dB-ris;pb_UC8o5L$oF5qS765c1VPW34@3_5D zLSm{$iB7;KgyH0Oc35jZj_r^tbOMVWL*}$IgjF3y#D@*+53!(F!Pq0kbI5Bx&s+Pr z!P`AGBwLP)$j0TB;>Y^bBr#H8JT*ztHC5n2SUI~KkR zcy#%C_IB2>q2)htSk9nQssQ6{@uc9bKYuj-2!PnmueFu0uD)KpQX0g!hSI~*pEURT zH=MH2PycpI*Dp$eZP5k@JdL)Xy7pK{?l8la^|f5d2}8ItAhP{H#nML=z~#-T(^NI_6$1|}wRS>rqmF$+ zfi%1|Obj(m>$!0+!=O5Dbxt@e7K9KoqVgOIZ*kzAuQaQmt2f>8puU@{l2*Y$58-JOpn;`0QfmXrsgiI!?8*3#%v{1s5C zNgM$MAFW!Q?=)cFw9?2BYPP z4nWM>Pf}YZUJ?O=gDmJEqu2z{MiL!!kzYkBn+2ANTR}b2J?@y61pzfRj#PHz>-vV^ z8jipu6xyw}Y2Fy$Oy+{zG4Yj(ipmtoPf9z$#dZB!-2Wpk=1C5GK1GR%i3ur#0q++6x0_eCW|{RyBCW}~`2T)kOIOiG#t%Gi~_nD2_0w^9jGmko%w zi*zikQ>FacxB}+mcxG#Pdt+STFpZ3^FK)>^5jKg$`jpX3$^2j<9m;tKQ%Vy^`iu}_ z|NQxb4+Ly77QbtD)_@xBL3Wbd9t>-9NiEpWAoO;C>>#LIa0C>|q(RBbj^13;-OxI+ z8s4L7;Hv7w=$*x3X&r@bTYj?Wu~Srt51HMgUT z?}*XE^3k(=>nVsc6B8-WEl(8vPP@U5MXi=f2dAT}>tm`~D_34;RbCu7AjWv7TShIu z1NIV6yTgf|9%w*>GRD26ss1VMumJ{XN4kO{&ZAL4z!9y|gM^uT%l+C9Efd)` zM_EZ(Wo0rPlvPeerS3R_b_p9$c9;NKU9x6#yuwaPM@nI^(&PcDGcf^p?DxX4E%^1M zrMU%rdAB1H2L=XG{=AGa7}&z4TqA1QZFa_NF{!d|42}*(A18P_IV;CUNRCPUgp#7= z5D)$eQQNci;N9Bj2{Q6p3OZc<{2V;nvbD3^+$qGWuY0V14}o=<$X zjC9gsJbZleTiAxr7mH>N%%#5=s*j93k|{>ArREH!rNgV#F3a;2o4v)VpF14J=|~|3 z4$qcx_i^NsUoXM1!G(e77<>IJiB~5sygNdbMHRu{BqS8nX!Xld#i*&bGKDEf+PC;8~i(^3+*$-d^e7*x^roN-re&jPqdu?u!J|JAC)K-P;M(zv*f}qIn zcnpO&Y_8|xCoWvy$c0JeJWg_Mx*dNrI3i~_pOtjxGq%$MtX*gG2_%DrTO2o=VX|Z+ujZ!QHxwLZZxH@%VHTzC2J$|72OFmLZsY zB`dpuhWB1bPF9AU=4{QpB++(B#j!v>_FJZ}cBY@w(TgK@R#hO?}xnv|La_nxbT@!I@?oX?GR&cD2LRt8bA;E-nh zv6Drl%#*(nW5gAbP$yXK%4P$%-0j0kWAc4jyecfWm{4bHSve_f+jco(>TOW+Q(}e^siT$_9lx1^`hAf%``A# zpvN}~$K`^&m-=V#a~-ajAnSK5O+tJcjK;lfqLMSXJotEUkfw(Riu{x_*liSHab=9r zxe7@&cYNC@qNt;hkxiVK7q2DQjvW&*WiKQ|TdRPTu~+bD|3GUk8DxE0b-|l!r)6cU zRb0iJG{xc6Bc#8+svn)~GNi9?uTTwju`(CJmy6Mtr7z4ae`{*0YTeF`NOTy*lmaoF zY(_{_QCVj-$>z5GX;tZ|k5#Tp9>A>Kg5oP4y)ED&oHAK`zmHCVxJr;3%kga@wEs+>JX9F1Y z6z%!8lo6ZIm7et}&zIYb@}JpJ=O7NYEh`Ut!OPcd_rHx#yyZPt%UJktf=-St+vB{2!&Id6flJW=8=b1w#`S7G$iF-C?b$dr_( z8n|=Vb0eLcbk%D+IFQyQH-4=d;1IzrR9wm|te_O6ezpT;8|iG5T~Zj5c=;M42PhVM zANLPO1l3kMaf@5j>x(Is!CIiqa~*?$=5|Pxn5b%?Fi$MsXf1MaMXp=g z*qZ#8^(tryiF)gvNS}1ATP_K!j~0oksIY^l+^m}3!D@76C4C>2Ca{nn({5L!e`UHA zYlTW5RX0&ySiNj?+n~%rN_>+w0MF%;HL#timz3H^{)3Fccn$?8=F!%bdmB4C+&{VH z6}oaRd`2Vd*Ur0#PnxM>a4alSadKYkBo2}%RD669rtbTxZ?aOY}c&+5y0 znIjB;Hq8}uF^TYJ1~tQT$&1>BUR+tb4>4q->3&6k44wv`4hNERWi23e+I0NfslzV0 z)QSi+w~y{g6bf_|$BIZ=@q417Lg~;$%+BK?Vibj<*~FKcQ?{DbP)diiU$kGo$Glax859BJ=aX zQ+C#*0?eI_3;N3@50F(a71QvNKz54a>;qN%dsbjMo+uGW2UMA_U#12DaShp}v^*$f^4Gc3SL_zDw%badz}I+bnmer3!F}#|l3VZTMfJoy zLaK8YpTrGYj_g`}aXh~Sb%M0-g* z-s!|V(O@zzEg`xj$n8%$OrgoeG>^Sa1WGt!0n ziI$bL5w&h))Nrc288s&MV$Wc?2~MT1PE2*vMrHqj65Z1a?c@tmH8FASqT}8kT=B&; zQv_$(;eXR8PIulzfQNT^c({hyS-rRSt`TnUcseM1&(!qySk(h}l6M@Z2K(`ZHI^aj zsB~^hc{?{cJ~a^49JCWEZ&MpO+xAw+>97Yf_dN1ZSt+lU)AOZ*ghi!^AJi58Taj zjWM1teR?Gdx8=GFLO2dR;`j}%Uw0j{@Uh-=%B`dAZ%MeuX z0IUm-Z9YcDufRNJE*)P-C!c$g^QRPZxunRyjWthp$X|9&Qyjn_~YV1}{3`?XXs>`sW7WhruQqYS!6Th(gST zcxfh4%_p~=rWillv%Z>(nsSO=x?+ea?l50Gtd~iC@%u*)cQECoYbJkrKvK&LyPGmT zS5^Dce@w(^4joU+Y)75je@v8zty$)$lSnKJtFo%0%FrkIWGcw3LMd2!0z6h8a%f^S z#bW)EM|dePxi+)EAN$85nJC|~s@DA653=L{dK?o|5r+4uLwND5y0jOv(=>4SZ{r;k zq?ETf;?Q-kr!+0if;EKol#{|*3aJu@e?bNQ!b=O4lk;xmjCm}koYE=?my(W*UVwcQ zhGG^JNI|7m{E~L>_8&^Ye5H*#bHydy2Gds-o$)b2`}rV8IxnN9^(NZE(WK6 z6br7cIT#osxm|JbEG!l-uha*J1{Dw?um}h}f0LAJpXWRC|A(=!42!E-w%TbzH$?p`(%5Pu#NA+zummS=L^A_28>)dxF&6kJ@P3F>4L&7Yr_t&&w z1!`$`H+<3i1_8k3?Ena=FzkH`R59TB`S~mA>VjfoP?L|z&%b;D%O)?;F$#bb(B^yt z3vfsY0h$h=w3q*2J%cKS5ny{%B>39nA4cU-Y{3w#|o?N?y|sJ^tfNAI5lG;cUv z_EUrF0BrULm>FU&4TyaLI7cFr-ct;^kDtLpSxEiuYK%N+37u|F$K~B3W9(J&VmeVS zcvx9uNr-$rE1t@$$Z97iUF>yZQye4QoCiS1*(gqF3g!z?%E~@Qj?#@2rk&EhEL#jl z-<#84UMrsAHYI8iutn~ltNGbMJ6*AoqPP2-(az$AJ)F~%b-0pDyfKRe6Hx^LVPbzQ zE^V=la}opCfx1nufok^n1mF}RU=2uAKO6$-2Bc8MLM8HOQvl0QKldNc5`%Yp-Fw&I z^T2ODQQ!-T=upufRIh!5<%Qx{00juwb2VvTgM~5xg#NiaT3N=clLGo4qFMp|{=v5E zU#c87nD_ggr5#Ae`6pp-uDUF=x7Pe1c91b z88Yp}n!r#*W)0h$(vm1889u$R=Gm{%+q|P486#z7<)i*VO&vhRGW3q5^k$&Df=I&w zP~hPBqg5}0O^Um+rr3V{7;q(B0wmc;R#n~gqaRnh)x(E>e)>J_p8pd2&h2>Bo)k|b zFc77;vNA5Tc=l^b_;dvEk_B(^YPvlY?ko_-FEbD8$(N6&knHLzzYe9<_J%$M4LlrP z5bsxpvh_oCM%Q$1>iw0c>n$dA%PN}3Cjj`04xTF04g(S{Z^4@MTMSVE8U(NbZw-X` zMyD_n4MlFSy!x_CCIlG1`b!R?R-~nAr?1S<0Gww$@!{A%<;WL72mqe*nXn-$^702p z!opuvB>DZ+Xx(PanH=IZLx9svBC`=(Elc$|0Be!4q22i9@qi@!5e>P?E*YM;j;tYZ zRUrNd%vXbl`#XRmZ~YPZWOu8GTf6)HVrH$y=3tooDm-X_xz6hM({1iq+l6l^LKg>m zw^w1DoO--3t!BuIs8@zkJ0opcg%)%BE4(fhZnu|dir&4JnIBJrT@#2`ELXFsJS{59 zqiAB#q9W*T2dlS?+}w>_L9R-PlaC;O|3w0z6ni(=+RCMJ5_>~=-AKHLQ@LU!EIH+& zQVEb$4jY}!?uG>bT(!=SM1@R~h#@1XeuV(A^`H{z$ZtV+^9rmCgz4%y#U5Q&IyUrx z<#FZPKDw9c^S#R-G47k_iz^JUeSm97WuQd9TpGW5yK0Kv%EP6?5huHmedb1ac}(D5 zfBo zi?PhJ_`?3-nSCTdO--J!akg+rvXx*-pqpC!IQaT2Beb^_0i~8CfthK9mM77_sKTui1d9AOA0}Mi zv9O!~fv=x(Vy>9zY&GBHHwN(C-G_G5(AoGuu(6RhV=~-p?DoqIJ)*7v#57Y^S2ste z7vz7qJvjiDRL<%si&lSr_(E+K8qbnjTYbKVVld|A<;iye_*XFcccJwK!S}bMq@}5< zcQBP)qE`MbnTLm04LymQn_i|2E&^Av@^<_raSlRQ^5` zj+>Kt-fPOhSjl>xhyDCdfX|e|d*pz34g)Pk;@9g>(B6JNnPm&Jv07x06aGT=CVA{} zZ$1$$Gymh`7owGaz5EgmY8vpeui+@Ov=lLfEJ8SfDD-n+JhxH|bt`g5ih{DLUdmgt z&I)c=MY#whYu6c7wjfy}Ww-|Bfv^nN=g<9>1!I}!51FdRf(io|UWj8;kP#uii}=%1I*u?hda zj5_-JzW@CH|Kn|nUExUNwQQ9v;$a$H70hE_l8c!2W5$-Sk%Phr^xjKlz6gXRafvL{ z`}NYPguCtI@XI0^96E^TPl08`eF1?$(8t1&d_h(hd%eEL^P@_dWAj7tOLPQ;9C2}? zu|b3dH3`gC_!T z;c%bDHW&)-RzyKD8*#&O-{TAcE!riI;oQQ zarV!^0`mN62#qZtGe7#ciw7E&Eq>9a0aTjkOE!6depZC9m6dHjB~G{XD|n9TYaSw6 zT3iX67x3-5Mpnw6lWoZ%Ridfz;jtMW2JntWCV^Zxd}955fLr&`OX)S`K~qOs{wUMv z_>ThXNfbaiEmcczovW^{wp$Xy+P@TQ7t};R(~FH ztXsOR0&H6Me6de8^TFQ#WaTVa#?@EqdUEu)_nRhN9X&Ivd|MWPXc(H9{G9aQc}lXN zm~U_Lt?Y!aZRIvGWsfd`&(Gk@+w{{M?)S8=koY*gz3DIyo2&gmo8W3DPj}YzzT;g7 zEziqg9)TOcO*{13>KLnf=kCM&N=OlD>C`pNc06l}X`*aC`l{NuIfhaC;@ni(>GBI zTDj0 zPmjq>6B9FzmRpg%4j2GRf@ZzjLinV=Y#~wLf#mlby!aVz#?;Kw;X;KR0iw-GP*7TA zX(=ozo0pd%8Aa7Y!|I7tAr9fSM$vMNw2YE_^!$l%a$Rf*?;89A?AF(*N=dsOXT%>a zX+=K=Ip8uY$JRU!_#mACzN++Tr&YottWzgu_Ne1$BS#o415T^-M!iUWz8in>Zp&i&kqr5rg^zs-`K!_x+Zmb@r_Z(U;1w8 zATB;SUXCl1rI_7J9?>G`ObM;pBhZjQ9Y2D3l0pt?8`nzxD3BXeR0CG-S z)Sts)mR|$!_ht{(;`hs|nlQj=|Ics0@4~M=~9po2*kaiNK9|A}vn~$vNs*(wXn`f|F9v_ZH>iP71?$lydXw zeifY1)D3Q8J{I(}od^Gor8)r7UaIiql&Ac8M z?0459!)1X~BV5Foj3lwxZ}B8;kv*qN#hS6JMTyJv@^x2Df^=QPdjd|zn2C7tmWJe* z%%-&Pa5*`DG`bMZ->kTFc({c)%-8qGNc!HbQU^OW`=0vygUd-AO~k_j|7&Y2_gcN^ zL&PK8Lt*&V_<7>eezhr@s$IE>0nzh*mZ%qP7BuHlT&)cUj3wwq)lm*o$KT=I%S&=j zxBGZ_d02|0HmKITLd)`K2Hvo)O^fI&9d4j7s*?88WeJFikpfzh1_sVA?;*IU9TMHu zAk5ldJ;H(=3&Q2n<55a-Ql3tHJUrE(zn2IPEk#_3se7+!r>DimT?K}dTaZr%Wk$x` z+RNw@AvVhCce$94-V)QGJ(4G@K8+t(_-lU;ZG*!cU#Az1;NL!{Z_@eWFlNC(Kg2+m zhVIM&4QmRb>1%+Cba8by?y^|uZBpc5@^?0}xLPCg@tME3OJx!cT^;T=FQwUgb??yj z>P}PT=R=Fx^YTBgigO7$#-SJ?wdZl75k7nBW`n(qtcsrTmzfT1yY}Z2?;YVR2c4J- zA`pfak&M`~W0BkwC?+FBX`kBYF-?yD_&lYOsE9`T=9!!w?~VG$w`Bq$$WZn34bPS( zs4MVPPMVxzuDEX-Cuy~j;zpvhQf;3U)>3M0>hz~-#cO86x7vv`+_J@FnI{a!2>TXJ z79VIS21wpVP@ln(;<2G;9-tyjdfFX3oJ4-J5CQ9$>>E6 zK9+z0Wj3rG74%Z3Dh$*tPkWcK@&dMfiEjd)GT#IbXT8LgNKT99GVROxOS%XHU$Nv% zYwq*%c9?{?kDIhvTrIx$Ji>eFw5RCNCV#kC_v&lL4e@XqTH*Sbm`xick6Y1N zA6cxIB;^?G)hh%ZB$pGC=K>H+sP^Rs?tMu2eh|w0un^zwCN44W#Q|WuS!Fv`QyMr? z@ZK#^kWCX`ONo!bqq zW>UK~MIeJ!(hLb*`}K%VrG%4O|J0B9DREB6vwt^qU&8YciOltg;f(L=dhiUxudUxj!?qk$bj;}bjQ(n<^#UC`wm0r{nCv}6bhPcmT0Z#HrPQRg*0sOY zTX3js02{yYo||Z;JhGT!ca0(%>~qEE)^7-feFeKDbS@7yHo8&tIcbHEZ32K43|lJs--VW9)gcP``P4P%CQdM?B=_t@sejkxo66I~y2KxJ0@>ex z{Zx?9mRatUNS{eIGx%hIyW2wW*<)BgBe#r%;$b<)n~N_JnKVXYidn3mo8qJGpGqv8 zo4lP6R>D`AKfV?6Jbfh8E?A(FQNOdT*oxdywe5Bp?+$Hxt#oSrzx9I|3V5s_V!t)iMY(IX1uzLrW6MR9lmM}Pvz z@CMc*CQu*tuzypceyduV|9fF*)huo~sy~VTrUC^0cA@jX9#Hdxwr|n1m!axvDo##o zZk^xM9rQd6b90F!u*th*@j8+JB)&q*Ayu$9=1@^p_E>Q;zfvGFbm*g^#T@ivbHKly zsisg(I~rt3b(UIeJoe&G*=+NJtaY!yOunqjWz(2sj~n*9uHAW_8FfW&5=df19!Jtp z$5axb10Cq<<#9N9lYiGZ$$Z7n!GGS+gtKl^pp0F*;~CUArM=1mZQ0`%qB7S}RHD{c zYTMW~{bu@lUp@s6%2pmY&aQoCewSNv>R2BEmOH0v%f2LMcmF8zkiQzpxA`vD74+qh zj!scVmcOVtEpdRB`<+V3(b%`ZcL2ec9wFA1<#MA%4pp;f0?3$kv-VMuu6nalaogWY$}p74kfagWslbEEMd)@xk0v zX^Q<-_=pRsB*tokvYz&diBICn%la=O97~o=r*#K@>J?bMpm*}Z+WD3B>f|7P(fZwr zxvFzuB9i~Gcb^GGspZ(8i0RkDD8SkhO*v*7$|W&C{1p%5WibKYr_oB5{aaq4$75a{ zK{hlo4xMzmYKe?MuzZDtdg5iOt|>D31Ez7ZDEns#musUHeAdA{21`_)xOj+$qp>+$ zI1Zcl-*IC)me+~*`C2jGZm|+G{?6^jkGGqj@nmRweK3;Js-NfGug)Mn{guNcg+<3S zBDAF2n1nSb8QsO9hNL+iyDm=r1}7)?f$iC!f}j~k>I0_sn_)<(Y!uezIvC!JRcKRq zo$0FeWDj3c{4m4zM7d46!Tm2Xj(5P(bv6OI!G&pS+d9MPNio5pP5FQHkUf`wJIw#| zmj9Pl^Z)y8pM6`{msiMLQ?W#e)dG75R%!Q-jk4mXn52-ky<~xs6Y-`S>tn-78lhUi zAQ_wZ2HUiNl$ahtvT_TJ$S85b<>TO8S~!H$7~s9zLh@=c!VPawQ4`(=N>E2(LEGLS zBbZtgD}RdBTUM^7LY9iMR7DDvmi6;(HvFeikP+Y znHe&;U?o9KwPzITjcCY5iLAz+WYS|)L{eCM#-1NHHx&e9^}dd?M5RV6GXJN~75q=1 z+k}A1=j1tEh%f&FLntAoI4vVq~0IWIC|5?R_^6NG3;Ae^_6@2~ok8)*c8S zhO8V4R6xR!#PZXcv14OnncU|5^iLc>|2ewjesK2r;#?%jEh;UIzAGBpKT81+*5hmA zD!0Z)^auR1#R!_#uNFOSelCV=U@Als(=c%aA{9nGxFoSWHjf#3MICVNf)dK;W?Sm- zhX>j=t(}=B6ubEoV93Z!fcOgTvm~L)6l~Os^v*v!sw$ssN+Et_zQHj$*|G~#rdor@ z(hxV&cjV7hyOM*0<y^POX z1Zg~8-M<0#)kiF|EFW52I?m0I8M3X4cL;1ok89|lH*KHf3AM*nG%qMN7ZDS~r|T9} zmPNu&D(vZz5*eoO5mXyTlS|);O2v4^(w^LwQNP}R0oF|`Zr}aSndZHu^ykVlgypXy z0nkEh$${V={R_w!S#k+Z0Ubz>KW0IWF8=2VvPZ-upy(XL>` z8&yVX_uub2B?af8nf+E!9_<)8-}$KXYv_1_JXBPe*c2>IS5-3~IgX2q{WD z0(E;pt>@te5v?>{kWR~U1XNU3omQ1LY1kYsXX{WSaA5B)Q^!Gy7~6mxri!)}}m~u9w}> zOG2^SX4r2Hjq@s-q5=R`as}SbT6Rx9I}0)FszfvtDKBPT5&DYb#~sJ>&cKbEWCa>_ z(iA}ILMx%l&N5Oxw&tyY&65$Y@(Qn&4}Qtcdl`>|!nOb9!|DpYC;B_du`A!Fqz5bp zcNH^`U>}L_Aq;j|@H@b(7jZ<&K9Uqwy*3ZK_YR=UE{8JIE7KZUvwd=}yGJG6k# zZqChXVDYGSX=IW66QMnUZ=c;f>$Oa6V!@n-TE;>j8Yin#a~Ngk`=n^Zh8cbZm|)$T zQPe^4eji8UVwMlmmD33q&n}WMFJa3#T8T=-3Q^%Stz}bfaDrla)O7UiJd_DXO+DP*#nsKV7ps@Y(?T;?v^!?5Q73poqDzIZL%Ac~-5W3t|I=#TM?Gm~t z_5zM<*Q7+TIsyFW1|h3&E?9oRl9ZU8`ZD6cvCr!X5J*7qh_lXmL6*Y&MzKp05kXH} zlwx4c1^I@XoxK8|_f4T<^hi~0V6yL%v6W>S%gb2Fm6gN63{U;!NU*17mFwIsDXM$$ z9@iJt^_uVP>%M}b{@V|SlB&wDTNp-D<7zpS_VM4?S6frsUAP_J==QR|~vIE~uK;KtAc?CeN`d#&4U| z(C*gY1b@XG6u9m|ltpw-mr@%jZ})sfkJnJ4uI`n$hRhp%0yI3b=+<^KyI{>M&I6}yrtt=A2k2W%0eR46nU-Uk*OZxn+5IBt1HZk10*x^E27`g#gMj6 zapaDNp}$Xu+~MTB&_dv?zEO`%qv1;sQ5mW$$--`vx)d(vQ}tG9zKKckKf=dzWg&bhl9wt$)b zY5g$X)Y`_kBi7N9bII3F&8ve?P3^pUT^XXV&*%@{TfLY-n7 zvn1(RmTJ}dx3QQXSUsN_!1QenX$PhF&%2`+sm(1f)Vcayhi{Hx z8Gg^dkRCT5&^7@PcctqNwcgo8;N|HhevOrYkd(&Tp$1F8{^soEbTI*Fo7i+(1yhX} zP#MT9DS3LZ;Zkw1tNUIm(j(tQ_tQPrPD-}f9RX-E+Nz0=cKK^y?Lwm45H7xJ7B87< zl)oB(ZqU&Y)c)%ZIrV@b{t@8B7BGDQG!0_cU#|~Wm69Uk?W+;-TBurm8J>;sS0U%I zyJcRcmgBMVhqQWt(_CK3&dQ5qH|YA&A|Y?Oy+hhIjXAAaD*9*PdwCgzz;9OjyKwgm zR)}J>tNl5hwdF@hiHsRXU9D9>NE-gO<5uWE_#0kcdn}jpU7?Guam5;Sha7V9 zpHAcA^8$_v^DIltM)UKHFY+dfv&C-^6;u^}!gFw>>NX*RmCu7yOOAC&OTY^}{+$t`U6K=e+y(HZ69d*_8f#SZkHkIbWZ!uOktrQg1H$F{C10?(#O0-RPT+DhAj zt7G?}9_+;#HFCO*hbsPgt0%V!fwT8b#I1MnH3F0Af;%4c{*`CB7WLSTH|vUsye2;8 z{eBSnck9fX9FgTz99lfgaMQsK(HH5%*`k?E%YU>z+1GlCVeYet%StvOL#=p%?&27z z!*rZe%-uO`)BZ;pgK+y64~U=h8fm<>y;SB6EHWX_PTW__Z0Yu|0!jTA#*5O?yXd|L zb8*qXZf|6e7&&V#MxbKdj z^>eO(KVYB0ZD}W#oun9 zB~%=}Zg;KSktAXL(Uge%6@*b?oBcirJrNQURjkNvIV?K3C@LqR(HAQE@_Aweh%33j zMwa?4=uZ6FEGI$sYF+02`=^rZUj_RfE_hFN0eOezV(7QSx`4_0(B1J~={J$!=yHr^ zh12gQ9x|D~4i55$z3~|W#LG-swRdMnk4vGij}D)0ZEud(5$+P>TWM?5t|?!o1Y(@C zTJ+I`M#AU)IP70`X_#oMWTDr3@Vz|OY>lbjqaM{veU<@KhdCo75n=#f1?6 zddWkB)v@R9rEW@~_m#ld*ktzRj`!)*KA)rIefc-X)x)gCN+Q>dAH*6=?_m*Yl8^mo zDy$ZLYlmU@3LSy@c!*32jC zd1K@|lXm&Gxn{@a+DZ_7&**5qrG&iv?CsB+EQ8yyd6OR{KI5Bi0^>yqlwTt=iDeh7 zA##km;;j%I^;r2?QJ`dYQ#HEZ%=x4jfB0yWEVrldLt5?)5Ibi(GO z6Yl0Fqd+hBaq4kk$-`-fXawYFy*?n_`gMRZ#^Zd?=&K&MF@)a5-$$C6pd1Y=)IGm}5v*_vI+Z)^1 z08-3=jh-*&Q5&?(*NVZy!KQIaVI}m*N;01B1FlSk4F{~Km#>}Dsa|M38}D*tTw~bd zYSEf{C-Iq;kMi)e;_NW0c{jMf1!-59b(4objePO@>8=WLG^a~#$3Yu|R>n}dTwY*V z8Jg2x@;nA1+GPfPA63N@3>>6dbkXXDN_w(e;ocq6u7^Cj;l5u1Z*W*g>UR@yIiz;m z6)~*5nr}8{q}i(CYj ze2UNLMRFpC6^vDJ0wit(RIhkND<3BMUg`JLMxY7se#nf=P$oAz;j&NHM7)>EXFQ;r zwKn`Des$#*8y~I3<)IjB^$x?BePX6Bx)%RlHt*?;(ufP;UP5$g|NZYt4QPgW@Znip zJEmOv0u^!2A0H*EI9BJM!i_B^NDKV#qF@4tE+goSGiX!MvYlmiHCD~IY?FChih0+U z2B8U5KB<$;%?1b1PZid4a@f@1Xf)>s+t`xC6B2IcBb4yXTi9iH9_+e#7jvtsZ#1|yO+?2Rpc1-S|j{$Z=@Ubgss zqGb&R94^Zx-reGt(b&?V*g~4V_01O>EF%tY?>0&i49yKCw~~4t_s%8V(&Ls!k|tS~ ze#vir$G+JdE`^4z@X5Ek%jW(b4$p`9Y)T(p?7tUcbLfMsVznUIBd1|VR6V$bBHMQt zHS-HiM#UuypWK}15!kefjEgd+Zg_UQcrjM_qE&IT!NDG?dvlt#ZzG${;j&Nh%)x={ z;m`KD)#==i`_uYJ$VS}hmF>$01RNQS#zr*zbyj);ZvTm-BxV({UwF-bJUPD}cGd0~ z8k&hE_4cCK4x~gfUY06#dst7x;oL$W#%?4aqvuHvSy9y{1>L80Yqq0J*4k_|VH@_2 zSR6XyJk0y(1AMn$6R^omzr#GIO5;xSi?&^h#XNhYR5r#SJ6?wFXn1UwMk``TeapXm zth`J$^9wDcJX=x{??>3vFBI{O67CTsaN{joNyb-JSLmNhLocM|rmkdR+2jH&QH8%K ztDD-(Wvl~7Cs|FT!GtYE+lf!z(PGSToeA(zAJe(;1CNADPe$_dOsj?lu1O{5twq~! zdIuqE%zSeEbRYTej7&qkoZT4X3Zqzr-`mo_%MQJsfcf4tlt(Hs7_$}qki8k;G5nyC zSM`xue@0}^dv~_MFz9N3A*l8!O2jEv`Lbji~ z+A~R}b4f4p>h4B$+Z9@L>8f%1V2etJ0fTTge2Y@>97d|r_E7Lc8|w2NPngG_p!M(wmOm!gd==@=~|215R7X6^z-r7JFDwfu1ty_q@Ayd9^VRsO!)Zt`SS7c z-%lM9vZO35vkIOc?9Pq#T`}fSUGyQdw zdW;uV6k;>sl@-|VGjG7LI1vEngl*sn5x3qu4Ec2Q1ZG#vAVt#P$QS43KPUIk)8FG3 zY~Hx<*sWZy5mMPGEiZ>E5K+o=DCjmaHcsB!++2N~pYyGvg37@sJ!E%%U7TLCw&d7gYo?NP z5u>wC+btB5ZnQ^<=aU76LgQzKKLW=AF}!hpE%!gK;hZT638B=>rCGrL@2ZUeO*oj> z&ZEJG1q1z8II;{H78Vx$^H4UzYCpgBcNm11lutfix|##?)wDz|hdi#BjkDqLu3q}xB<}hXneEv;p>}q5l3>_FAfci5ZzFYFz#cQg*WKT-67XEV zQpNSngUc(o5}TfG-2jxDjDG+AO^OC5<_)&1q65Pc@;Irp39CSpE8Tiq;!j}PqU?lu zjW-~xkuJJzr0HZC*ug)LfJ?##hlB(X;0j6q8gEqyTzwo(C6e!Y|m~5ES-hhI>Q23H8RE-Bv zu-l160-J`@U~g$*1U)A-9G#qE0KxU{ZGKJ;SrC{8w`?Bgy96|GG`hj40r~lq)M%mI zG=3r-V8jr(95)pVi1{6@tgH^2FMfLr0vpz6c9Oocf!WzBOGpB@Baw@`fD;~?kT5;W z8*64|mBwK_fR!5;H))U%ot&Ip2L>qW^Jf@JJ)dhn_tVR(L5{`SuRMsCuRshaP)uf;j{0bDay4(sU&4C-9PZR_K z$-XSG1X~xAz*fZCZf#na&+gSj5`e%u)O@r5eem)Q?6nk!N2zoi&y&SiUtf32mVl@N z8a4m1i=v_;Hjq@13xz;z$WrspM>0hg!4_|H?Wwp#@JYd=mIV}fhqyomMz9%`u+z@LVXjS* zQ!3XsmPNJX<57)mY-5|^S7Z|2ATl2?2cp5L)Gjxx9{g_JaM_vK<7sh#NqAFW13T(v z14#0W_EIu3j=&p)7Rku{Si!i}`wk6o^_L3%@DXpuVPj)c2#=UFU2hjR`)3IF%{~J& zAyzn3Vbu+6|6J>+yTAur-JnO|Dm)wD;k&@1*XEA|oOs7%b5xeu%EtJLHaSOAuLT2LV+xR3uh)fOaT@T&v#`oWzt#9pTfZW z*U0xz0OZ9#LII@nJHSKkKvn%on#82nRsjSI_QYj*KTn4>00pY&6VIt+0dcil4up3E zkX7J1{_nX&Z~=o5Snq-$5vlP^P{c!#Chk^L?SnXd5Y(U@sqYyK?~9|KZSB3iA-j8f ziVii2QBlZAf@f_=>IO?sQVJLR0|FEk6p(42e$FTVSGfLfQTtz~@cEjSAE>Jd0W(rG zTwG}owqj#qM1bd|p@oHXLqh`)ZX@plme8%raJaa*%8EMVVr!rGAy(2JAIROm6N2O4Rk^iIj~gIAkd zTfiVD;(e}?qLR{AN9TZuCmVZz{t&fpcmf|vY9Jt$Crs0q4}yrHu`$KPn)qg00DOHw zbvjIn?;seqBdo*5SG!a;^Yx1B{GDmf7Bv@ZEY#dm<{o7>YI(T1m4M^Y=4x-uSmxT= zS~M`pzPh@KZf$LK6yBw}Is^Bnn32o&LhPLXR25SM1_kvWT@vuQ_t?5^5l|GQ{4oB+0`BtWieZ%;BE)_Zbw3~BfBMG zDfuA-%8%~28~Dh`M9M1hpg2sG7n4r5_=?1%E0^K@^k3tz*uV4}2L=XIT>sQ<9TI!( zzy##?&G5xpLLg<2o2zTj+@aL)yboSQBFf(ZfjRr=`2j-~Lwp(grb*|?qEgQxeF#th zi%m=n?hJ>qeEIj&h}FXlRShsR4_=Xp|}&`m4w^j{N|h@Vyb@pJ6#%PUT;Je!L43K zuEI?QWu z(4YJmM<#5_Kwg|1F2?#Y3t!IM`}zZ;Cl5_I4&1+jj}Y(EL)Ok$kF_C8$KR)a;?Lt8 zw6L(avVnmwIX-4%xSn+n509 zx1P?<03b>EURpY=s=9j3B~_jnc#EN7W2>*eZ%75swO6M@KxQ#oD);N~k9xP0JkK5s zn7>y(BRv?>)Wplo#ukUvcYJY?fLI2KmE*@-+Mck*C=puQ+sy3j4Kg1;QE~k<%f*&v zPaMh(MOCib_eaHQ7(AaUT(37lnw;Du}}V)PBNY!ULsOE*z5tjS24sy%s^&#_Pl`s87<;} zu7-*c)~$Z`dbQ|6#IvlU`${Hy)X$ueV>z?OYY%7K|#R^>Z~i#LE(H3{SH`r zC#PJXt)c+z*MH5-j1(wlZvq_`VB^gXx}linpMVa7$v0C3s%PfA+mqqPto4|~2nppM zb7pk(QP14=O9ULzy}7!CHQ;d{m7Prrm_*@#3@C!hpcQokBvW+OD}nR%RwB4kG*FmE zAfgp<@)#SyrCMI0b~ss=&AC`U|7LTBXLfMj4p1ilAIhs}p= z@Q#2fxAl3tT$d5D5hKq}oU0@WVre`CyIh64#+U%9+vat2HmQgO;uG@ z1%Rg6kS5W88JZf46CTLG)-r2Tf2W?fG)@9;lA4T^%n^}Gcz~T8ilW_r5dGm zwY4o@l3{Y+F);;;(ND;QM?@SnJr?!hOHOuh2N)j71(VyipbB{v z7!c6FYCb{r=-q6k&N(@CJq3!mkj<&mIhXoVn2~VM^Bt`EC&Ogyj{^DD&!CfK4T+3A zMl0s=AXpt=mii__Elptga} z2B3=rAksE5vbgB83dDJv5eaw;+C|Z7`&CEK%s_y?7?T=o!0l^P3aZQVIiEhDz(fkPn#{753N3X!k2+D# z^yIMrrZNS|M(4e2(tOa?-d5PJ^+BARoK7fZlXL!bBbxSsrfZqqdfqf03blFEE1UK& zP*>F5E*}bm+!RkopqC>Qk@^4~UjKM{P4~%l&2$)7rSqpLPn;s2JbURm*6Q=%vp3&x z0?Cz5XfZZ4j1_P@Hhi&|q=W&Ajtg)D=I5&x(*rj1Wi;};lWooBNw=e=m6ekP04n@m z?e-Ip`?#xkDAM@!>C?-QR18o|L!Yrcclx1|_uAvCmV0-tWiSUe+V2Wf6lWb(PcRixtwOfyk%n~2>2K}sWF*U3ytOWPlwP+u@?VL6$ihxzJN5KXIC zs7-+We?ys^P;!-$Sb*-@27oJmf>7!509e4ySG~iJI?SN%l{MGUNLB~UeLMmo|1AOr z-C08!)5at2Rv_%!Z~{C`&zAHCfchIg_+zznKnCrA|1x`e$nkfmGU9)pBm=RqSroP> z|22>OlXm`{eg49D|3SJ`-hUo3H35Q53tGRhvn?RCNaw)%c*% z7KrRe`oQ7l=2iq!eG91UHi4{KT3&C>Em@?rateSjMmd<7L+xE$bRlaqPYSx1{nC@+GbF5ZcJye)qSbI3=Yo;pes!%%>v zhWO_7>#f0JLjJ-kH*_6w*3;uja3c{S$O$(I`~|NfXsWRJ*Z=(a^foO#%ZkTkUrWms zQU0k;;n>j7KH6OP;X8`}$m`BHExy&FN$&d~#7G2gH~Wv94b{(>V`6YKRL%Lj5OBp= z_r{!Ts(&}v9aSXNXpQwZc%!@;FQLoDPr)Otgamq{V@bK_H-d{<0)DxBB#BsmLrE#BCA}2kd z^SLzVyV2$1?t(+@0abt)xSMjoZ~2Z8Mbz0HZqBVhA%$vWVxs0sAipetRy!9n4yL&A zqCj91=o%j$38cerFQm1$9#a2|=Lg~?p6rdqes{4_#H~TSKPcOux#!MrvznsU(84nb@qJ#of%j*@UM z`1oWee6}E^W4`H^-ef;2z=4Q(0O-82n74$ng=e4Z}kpcDxB`8n+afcH@}Qm5SL(Q zn{>R>REBiFcv&lMH9=^-yU5`i;{YMx5g)qp{+2bN;Pd*(4lr!%#N;>Yq_`LZLhYRf zsC1>F?+aDh@kF_;W}CzU?Mq8a-k%qkRpksFA>JtrnmD=(BBq)EdY8ym)0 zSE|liSlytdVm(%^5km%|<)36M#}&PwHaBAG{d!Oji#4d$|rjxwam ztD^XJLm-LMr4~bnHZ5M6Zi_7`1aAp}_QISSc+f)+L!j?79|^6Bz%y5Vh^#tT$Po*} z=)d4iiXvNq;?kw-N%X_^03GYq34tA1351TvnBh9il+W4{ta^|H-m2fm(K1yunfWr zsM;%^jLC75yMXp!lScI6NS#!CmLFB?R9bee5IdVCCdr~n2ln`SDX!^?cy2hJ{qtzj z5Toe$cySAkk{q6;%C^(v-VXjq%ULo7tKAM7rwL&uvAzpx6a*@+iK6*Cpfp?lOgT?x z%iO}kBaeTsr^{uL{{#3QmBOCEEMGLj4Cl7Jyc%C$8Eh^tM;2mV`;)$NmucrcPucDt zL^Z=fEWf8g^U#$DZujPo-hPv@%=EKU5fvz51%cXY9xAFNdjjsEprUynC@y|FU!b_U zyQ?*F`10j=U_=TPC9O6rgIC|TeQ~Zvrwzmk&p7_v8AP&$j-8wo&+h}EpuO#CY-q5u zb8%UOQKl6PK4WXT7v-vvM&J{coMS4MOD%6P3Y8J|P?mCiO0QKf2zL$2#nB4A_SJcs zbjxOw2gGA87j<)buP`+8d9LJG4L7HCAC6jCqIPjfG>6gX;|U`qF_8JJ?ho6MtY|%U z^t6AvoaAjSVKSUj+dwJW7TMXE{aFe{HZ9B)c}BTjwYV1N!rJOF4`Z~R2bOL#hLEo2h zlwinHpjbNoj*KivtK0k+che9osZg#?iF2|l5R|w+~+hMG$g!PQgpFn zWywwL;Fap5@xUKBDOU5zLPtlRESoO~3UO#IV5*7slQ~1Fk*v1wlrWlDnY6sFw%=4 zy(+ya5KuZOZRov*CJNF6q4ypFB26Il;3y-#g(x6x=%EV%LI~ykd%w^9?RmauopsJy zr|j(O+WTiDujxBo%=1^}hV4tPouj18^j=pQ}nP1xf671BjV*39R27uiw&i_C)qUwragdR;fVWCBw6Z;PtPhPSu2=?W>T zp)Ltu3D-LM_wLFh+XJ>7207Kw3VoXou^YZ1tBoT@6#O*j6n zzPk!FW9(u(p8L^PTy41{r&g0Kr8@@~lEdejcakJ5={^+)SyD+z?AGb66Js)(Nj7e1Q^+}{=Q8VuFNUc9F!3v7Sbfy= zB_b-tD~&8gzu>7z_Ker36m}M*ik9g;i|#pX5n?a$2zMul6S zDVm(Azsi$NE$O;y=D){D=x&SR=d}!yT;C*o>%yUllA*}fnvnqf}c%ep^9`c zqNG64EMP;2DkJ_*sOWgjb%J(5zGc-%RcRQ)T2;^m*TPYCc*wu;)xVuIsIUHeJRyKd z9?o*Kp((evmd?zoi|7c9Z>q*C2o9ijCL8;Qx-w=b+x2bQA1+_jp`nFUhM!~3D|*&f z@}&DeeTTC&?HPphXsQ}1x^VUUlWSMvu|WCk&+Uq`<-}uP4H*z68_!Pb z^ijMB`fzXD<8UXF^}tu1^wS%o+|-6IaL8mOY3Zo;RMx(9bW**mV#(HpE*=WI6E9iW z{zIeG&{}QXqYmlcyTJcremq#H3rnUmUp;?!YgiUKBq8O=-*b@+Rq*7S?6`^DIavfZstEo8Osq+^7Y zaR6%JF4R05fB%$ZSa^$W_P))<=wE6?Zpwf%4Wr3b!HpGNQJuvS=V=-_zv60}uqTlb zB3WdKq6?|!i?i+(!eU6d_`_lkK@;l5#=;T30%*E^W0mLlBkHWNwhhm_Q(D(amKSG6 zF2p&@f!IVo=>tQp64UpyN>-VZQ+hTUauULM z5hiTx8UjMSRfrP&Z2_lZO>UMkv|)oaWB<-~M;OHSa%vE8BW0{Oz5P{ZfvDF!65_6$ zWfZsfO?0SEd$v{Np|8x*xL~*6({KYH}2*-b9aE@DDuEGv-dUx z?gs=%OP~Jv3^`ua8%1w?SO~H=I49=4n-aqn>KTzk3q$pkbGiv19u^IJ3MP7msGj7F zsH6;Y7d=)GY(S@E+!_^t-iYL3+41~=?c(Dy%nvcCOFbvp^-uNZq`7&K4h=By%N_C^%()@wyY+W=8KN)~V(V-so8g!4C3AHB?)CX_>Z-u%meqCYNLF1r z=-aQQftL@Wd#y^#!V{vdh$b2YK_tf#Yt&f>Mzk4|{D0cr)2AoA@QXvI-;!q=*3zO$ zQxyTI4pQ{CkC1*z)y^E;>eNvPkE_p8SX6}y3JMRLXU3QW&G$Yl65W_OdeDk@VVLZgwpNSV?cl(l z&hD*-<}MkkB5yq|H~t3i`@>g^&ya^s^O0vqV7%XBQEzIRy(EpT5hL&M)gWv5_B+X9*Ht8~$Ekt?KZ;q>M` zUtSqw{^%$4_d^o3aKEul9yU5?F%I1kx@)`{L}!&$!q_o0k)Jiw$H}8KkNr88*!Ar# zN);Yj5vMmKomV>uqiBwKjZYJoH4DrjFa$6V&M^|JnwI+P zH&+zkJcp+DS>51;Ufh^XJnObN`<7|xojN0vNs~ULVIaSh%s|81iG-OF>i?gXzC3DN z0z33x*p3PBUYqh8 z=)=S$)W7p3P8sF|c~H>N{Cs$m4ou9cP0TI#;)hs`;!7d2Rs4RTXVfc)SV5fsG!<4# z68WK3CSI;ypEjwFebLTqbWfnI^MXQhdpZwv71F&nxC(O5s8&H2%9z1novP$BNha~0 zzE!3OcL4=WPcRY+HU&bOTpW;a=}>}(PuQjEX2UCb(r}J&a*GUGoUE+3f-FWsyD$sg zKqI0$i?(M0kz9azR%bx6NBj9! zKvkp@x~83nZ1J{VZn_l6dH-=6+r8)`Ghif#HJT1pu@k+qNPy)8|Gb97uHSGGZQz9u z8sBDf?OFeD(i(#X6$tbbNB5v{#($JYga009X`}!t!znWG zwoJSwODJ_i+hBc?bkglV`LgDUQ=iSeks;-k^eE`^7ZA{dy8BUgmA>4v5Ch|>24&2Kx^U5E@;{kC@S?8?)J?N zWB+A{gN7`#x&6jS^>?n{p;=nA4W;RQ6qT{PZuy~m^A7@bsj<(i3^@H`A^uV%-q{H! z%HSlPe1WK|l8FZu3hwkeExRhg0%15GVU3(T_0vH8Gy!?a48y1PbB{{<(uTob@yx`X zhaaBL^e0MJoLD5q9{fDqcz<7C;+cuva-Wt(p5@T6mTnxZ=G!qMO}B-fo?lSfWO>1O z(}NKymy^hKJV=zKkV<#>adSMy{C8@axpIqgoo?0G0HwbReX=w3bavSIRc_X#X_csz zSA9*ZD^8TL(}}CU?=SZ*zdFIVIX86g>p*Xi1%4B1r>csb`1&-v`8T+a8mhtws~n1- zRldk-R^$Fkd8PP?zJ86m_7fV1->;hIUd^r0qDQN=>JB}|Em`K5A-e+ zS?*0ny`y2pf^d;|G&2*E0gz_;#>WvCAmfILmbTV6;xz(sTM=|R?46vnXjmkQK`V3& z&|NQw->3ALfrTF{7qG1bY^w?Y5PiJ7io?%O5iKn(dRHEDcatN93JRPqw>{(08+kc~ zd5BR&S8KRb*QH1_=>*qLKs(Rn!bL3~Q<08-`2++SGkvvyW;XWU$B+-xEi_vb4liunqb}`Yz46r^h?G00O4cz;tw|tlE5{ ze}xnU2VWP|d2cMRQ4ZR*s;8%?5P+ds$)CkDbRHaSPp1LEV$ZIvt?dVrlH@>BdVJq2 zI6tPjx%rHZo}RnlrGY_;#zNM+LCXf)=+H~jdeIlVD^q&1Qe_5wcmT+u_V)8ODFR$v zD)E7Lt!{A?%WNLrr0O<3_&cYir&)57+=knlBjW3{>-yX$h}&h2)h|-*CTr~%O1OoY zBvO0;z9i>)BDP-tX3r=0u4>=g&u-6J?uZN>=;%&t)v<_a?>@TQ%%%`^sHewweC&R3 zu`^jJp7A-ny;CZBHiniV*wi4t6)g&LFV_-nbt zU?xMQ*&;;w{Lp9v5&`m?O3$YnMsg(+Fyvi%?Dy}Pv_ZiAkpKvat5*)daR8Z975Od- z3nqbMW|`jGII5((harm$7b*XW@KdYnJct*{x@TSTsHw3rjbveJnod@fCu9HQ<^7_1 zWh(KVR9aDyJ|*RYqKq%SLx>cWlIxEt$$ZB@<*e-N4wwiEvPAq7`3uFZ$gtS0p=M8I zbMn{p-^mXpkwiEf(vA>;L~_S4?)2KO6kLsol3{*q-VT!p+f$M|{6cJU!l#gJ)&4Vw zM6z1R7=+^Ttucw=9FiaTlEXP7RE(rNDjY-;OWqAzZA6p0`+dr4tpr;yq7{8tR4k@G zwsontEmRMh-42-jtZqM3tLT72r4j48$1t83CS@0l!XOKB3c!$R7Vn3jOBxylpfyWx zWWvu*xI-TO^QE6Hz~K)zCZ>}yCB+`~@2%c;%<#3a&!0boa0rz@fN$x$VG43?9vJNx z-n|?d7|=OBouUMx30871K_(tQJDg3Hi%^3n|A?=x6)AiSMyu`>q_a4DI>I@&{#yU4 z^`trc9LCIFr5)RzP?vnn2_ue64k-Eg_v=`qqE}+So^B5?_`#+*=yq7wd@=a2G&DQ3 zDJoyy!l#Iuv64`oR#kF~Na48VQv`-{9;gk$^{Lg8j9PY~iGE@3@mh5Z9RV5TkO0?3 zycTF5=`J1&38s}hi8VJM#t~`VqR76%EWtC3f)oh8KEyPhod3}apD6t+#^8m^=0r;} z1&wW!o10rGAb#&~QPdB3d1H2GtIi0&LR=lPvsDK`)}Q(e$@j&J%poHQ7M~)ZB^p{< zS|YCINjRt8lq8c#+P&?6jk34j7pb>>rgn@5(Kmg76u=wyW?J+sRDxQg3LeJ94U#cI znC3XZ2lHdLD|7q}Io#j${?)pmes=vH%6f^~Q3ta^|b`UuIjq@8XpB`rnGJbV?_$0d;r4fTgoO96VxT zhH!mgK3hGbT~$seOaZBPt~DakEl72_c9EiLlaIGcBCdl>7vRDE~oE$bI9RKt5Sd9coN z+NU#Jnj@rGYN~QO>hQ8LvTvab9XzzN!Cju&%)CGJDm-|?yMZnZ!mLeuPky}Gbuuld zrl#{^`RY|?;^jF97*Z;~uVeN%@t?(#oCS)*GWLlIqawP$`Y6%P`}=-dKRHjIvsJhA zD75OA^sT$9=^o0}Dv`GvJug8zD;RCu_re<+0g_1^liH2kS?IQ@IDo|g=_&(^iijqE z>B=8i0-3Ag=M#In1aQ?jCvG-z`@WD;#z4el@X#e@-vK_YFvvn;c3bQJag%N$l(d>9 zdHiE+d|bOg#(OE{)Q#h*eBk_o!-1D3LCDD1=scP? z``5DDd%r|W*yKyV%+Y`u zC>PG|f|D`e%V^_X50%bUciPxvZyV9flX8FIOGQP+^6% z?_+cUGL5S%3al#Mvhwlq@dN%BdH{^a2)Q6VmjC_N%MCbGqx%NbE@ifb!46oqXTQMo z9ATBQ+UJ{#6;5aFpRvzeFdUt)ri72H+1gy>s)#rbOW9QrQ7k?@I%;AGq|qZF7=&g3 z0)OMV1z8Mm`ppT{=w-9(q(=@A95j;@l+4Y|&A>2tgJN?(XjH7Tn$4-3cu2?h@SHJvan{y9Rd;Zf|n$|G!tSs@bY# zc6VmFr_VW`oNxs>2?RK7xDOvbAV^7yDt-6>f&byd$G@=9!0V?Qv?AcZX9r15=MNtc z2mbwiOr}A^`S4-zO-fWq#bf0(8%6_70%!PrZMq^bEReMh91&>LZ-)}ym8v1YRws(; z&EaO8A5K;`fZ=^XCQe5E<40hA;CDjU85M4cgY(t&orwafz3)3|1e5$7E#uAZo39t+ zr{g^3G0HJv3gY-@SOwQ@tj_GNbT^L8w5>OzJ2rL~D*MKzfr_m{-0rn>^N8o`_jGP6 zW>w#0T%*#$Oa_KXzg`5Ys2JEQb*Kz`;^Ou52JtZ$F-ZzYD3cbOB-)gXtnucCxttQja?+%SArf$|j z{JHiP-IfUL(zJUZ`;~ycXL!^_leC|}F%TpL^PEE{A zxWkmGaQfZ5!w~Dy^}5jO%?rcd2Sx5=NfEQZcHdc$Hi*fI@Z2z|t`WD}I&8}7 z=kf}xy+^+46FuB^7R~bzLQjyQ9AW|(EMpJq+v3Ta+2iTH*!9c5hrBlH{MC;cyeAZ4 z8kdlyB@>zJZqi0TqD`7#q()x8M^+wt7nOG-Dg=#j;U;3EgzcBT@yS2OKSEp2aNGQK z%#72ezeX13eASeCt#guu=&{QsJ2@S12|XB} z{hsf_m<4=aa)&ou<(FuW_+iYT1Z?o-U3iNN*WImkVstPBvAsK#-@eP_HSbc%tHDkalo$WBrQyHu{sWKk8-6=nKxiDm^!!BTWU?-5puGA+_~F<)}`#Pn*|gJ`~+{7t8WEY$Y{m3wWv~t9h@oIQ#VN zPOM+;NS=DF!XA=~)w(iGx{T^J2YM&T+Cl?x?&y-4?6#K~G{$i?Zq3cjt={+aE-o&A z4iCdx>^F(2so~1X%I1d&WAXW(G(7vUz=R;!!m;@Y5fdW(zAh@XK1?`6kiNctF_ElF zx==)HVj}8Bm$$?wH4_ulIAKms&bY`DN#a;Gk9(R>T4>UD%?7iry|L6*&zoZ45lKcD z77?i^5o)$wRWr~v#V!y=P(pUak`+l>BCKz+q#h?!9TaIzI1Kyy*9Cmd?O|hMvznEK zTLPRyW>L4t@72@E$tf;6`uFWMcQqK?pM!!Uil5v!D7HX|M8My;W9GJY;$h&4cL6MH zM4CC?XrP=1X9jOdI z(pTNO2Dr?;LudGyNB6sAe7}YfePNMS1R0|R*XeQ+ui+eMs%sgK2=59iE3?!+U^h|jXG^apjb2WW&ZYc^&&2w?7PIDE&1XGTz&|9 zIrN&UirXbeST3K^Q|Pum5<9IXI~QjiFWm4Nykn!Cwp7VU6eDEw@3!jtL}a>aBlpfj z778UKa}ODw3*V0YU>W+}d;8UguT3OSppbL*wF`oEck(t-VU#9WKzcpjB zit3ZC+qOzN2#^wKdr@g5x;{{fWF6@X{$j0WvQ?eH+c@R*bv^<%RS`Ll z8J1Q@+|yFhQp7Y!%t!DrbK5_b&bBow!G+hU(pah7Sdtr$3CS>4_A@+lhds&Z3k58n zcG^@JNWCln&|VDDuHvPCY}PC9D;;M9CB=m8sv{(>Jnyd)H%U= zy<;sLL}+^>XAn{z@Tz#aoM&qYEleaw+z2Ejb5@HvA(NMSj7U^OHD5SJ7H9%oa^mSk za~E8Tppid|dElf*aI+!Qy*xPE;I8J&QgD?G8$N`*LVjc8)49|M>^)<53id^}C_5SZ z4I0YMy4v`i%;QdE#lQW_I+vhmU>I9)(7917sX_Q4Fid@m`b|6gta~&mdRKvqHgESW(4UJH7w; zZe#-4QT$TKb9W9q(^W)pz<;kAA*2c~4jVb(Z<>XcBdNB$5-nJgn;sR3N}jq8a}Kq$ z>skf3t_9xvj2TERXrXe$a(%XcVIQ#zYYM2Uc~kreA)QIQ2S}l3WU=T%m*Bsq(gezn zo?#wcY>KpWBmDM>hu4zRqCUQRf{1_DVdxS95=YSGQfHg4C$@0=DP)E#l|Bo8yt^S9NLI2a~xxOJxoSw5F{x1_Ui}8Y=6C_c{ zf`fhnWlDm>;f%Z_#(?3>57$<&3x)@%u=mAvOEewc*wjY|DT}C^oBcmcvc9$lSS*&3 z(TTI&V9hZM)=KDbV#QJ+w=8cZgObU>%>yRryv89yNnwM^$2SzcF630Qh4*9*lwjT{ zp-6n@JSNh$XX8*8uG6cXPJE@T%U;tx<=Z?I`*@gKxKu?d?0UB|t*v^~G3mL|fw3`b zX)mvKB2703hb7gel7R9ICR9ftcac$2mb!zX5%^af&VexFO)7-Cwzj6i?Rwl;M>?D| z2T7GAv{0kZpi?i3o0`M|9gWh9RlrLirbyI-UUDH|4zE|ODD9#|$|?@Tv%(%#6%}>| z{Dxxt&2B3)-cN%k&+<`9BiYZSq^!`7!b|NpeI{hAbfnuWS*i78t&Qb;y+fT1NDm*GLb|*8qoSffSXkjvYi278 z3k$WiwWV`EVUyKfg_@(C@5&;ZehZh zLE+RaBPB;OMPIgecCJpBS+EPGNKsVn!6U~KrZ`|e=44wC27N(VoS=Pu-S6@$p_LZ< z*w$9g3?`C%>d`)HOG_d;x~eCv-Ci(^3w|6!l7}f)K_9%5s<3HoOB6Bo!0+E@q9t z{{6!Ly}#S{S+X^1ea}-Ch2Hq_das-ppP@t)Kf&gTO_aLGyF3Dieg_Yt_H}@bG!!S_ ztzt^J-xO`3tLa3!W@azNxud08vw^&0=}M$9m=66>N>;H>#6rAM4JA7w(pN#SY!ZxF zKX)a9hMw%?^CQwUPLJ;7kC|OiSiO<)41O;YQbcldk*dH$kRE+I{odN3(I-yAxua>+ z=@$FZVZ!<$!Y&dM9;7B~lOTrE6NB5b?Ish_A;MSF8D><+HPtnf`nJ8r+J?hu7NmU= z8Xkmxp0^O?a{<2@%pi`E!QY%b_wAs?aZ*R<#n>s~_P)1SPgjo0sd@Us^ioQk~LzV4&D!HsSI>(FWC+)>W z9AWt(zv6z&Ga@MtNto@9#B(}sLm{L)Uj7l1YAaTv389`R9KcN2_DjA5B@CNyF;ioC zvNEMgXdrqL#wrr*AwP+n%SSa8Nd@Ec5=ni3ct~2{GmLWlKs{%}> z;UygZw^ZxHG$HK*a#?G3aM!J%RwUI(SiyUR?G)$&Mc>eA(%1vr>7!2$cGdbgvf0-6 zF^}NR@C3sC!h64hBbNB&tf=Rmp&u#AJU*9yzxx#oNy5Pku4a4x(5%2XDhwVEg0ci{ zEAfO4aKSQtK63FwPmVg-Q1qNZJ|G-fXp|;Kr-DN{_>pcb1eFcI1hg<#!7Q*~{vu9MW%-iu;Nm@^0%(#rih;MStJGHZf;rk)f#{9@%*Zw)bn`Uy=SG#W zEEca@&jWv0?Qd_NZuKQxm=GN#osT3MM;337-G@{u)g8Z*{E+Gp)|K*r7-*DFShbY} zNNoH_Lu`$Q{P#M3YD7a8)1@r=0zp5gejw6*v+X^&nr?X2sNCR!ccwV)-~6ghNO?;2 z*EKpWiMSe1kNXyrb*|~i9?urC@=5t+V_|xxgvh}fC&QUt5&W?QVfg^z9*pip_g_f$ zfxF2{=yD5Ecd_&RgHN5uXQhoE82xVuHRo%+nG!j$E{^eb<~yhG&qN}~H`inj$H!AF z$VgU(d%HnFVX&l~zM1B^xvrqE_Kwhhzqz2`KST(OpLG(xQLo+%v&^`l91y~5X?bMY zZ{sHTA_o$q6h2qN=6s4U4(N*f66znunf8-y(buKh=Xp3@jBG+kqs81M@0oalX!$GA z@vHR_KTTlT+WC1s$Ms_ofUnVdtE*jp$(PE0FX_tyb4!W^;Z#%ZPGhJj#z`ES6#WJV zg@)cUa&VNa_bgQF(okDU9wZ2BRmu?Kk8SVot5w%g#NzRgWAk}63jf`&K|v&Tgttqm zP84+}kI64D&u9RUozsM>990-<0%a_V`GiV5Cv-Y&+XR)8sDvUV%ogs>-P7%fSg=^r zge%%SkYu}Y7!3qfZ;&cA>HJdJ-uD+ z3=f$+p49Z@4Dp3`?7HHzu{E(yEFU`R=;$mo*>C!N4u^MpdAMpJ5s#|fzw%hV?zGg? z(@Smhy>Do4mc!@usLiRarq`9%>r?ixOdy#vkf{=yc+Qn7?m5BR z^}K%3p4^j31H!Ag0`f#bKJf($3>75lw!0WH8r+v4J#)nTpG&K&>W5c>U~oEE#dM?; z#n5nD9u|+=9ds{>TPdW1gcU%Y!q!ca| zl4r3{iRHTonlGcTLD?r16PyDRR^Zo<%`bB$tq7Ui;GzpTIWarOm8)5mNruhD^$wb>%QWQ-Q6TU77kf%GVkie9|k@z#g7&5|?mCI(bBgp6Q1~fObXJu#C zdEHuZ+x!NgWL{n#5gu2J&#dQ@3a-Ka^F`0_-PtN|*D!A9YgD>!qh}(*S>QM#)NqMy z+@RxqTt%1cY5Mta@=UO?4~ zR(YRrPjWcs(=dn>u@5b%H?9Osx%!j4P#b*e(De8ox`uE6s}HC%=N^6hQr7T9H6?Ts zx*qF&4U$HwOf);(Y|YM_%9A1kB|+D0aY`2za6N*_S+a*+U2mhTx!7g*$|FPO3^p1& zlUHqdaH^ujE>~C84w>;3&vxC0NVBuE2&`;usAIo{pv?Ga_CABI<||HTtqIUHsD|le zn4(OTu#$HOak?!71|@O~ekCSVB-7t`QjZ`;X0E-VJiz00_Q$VxnkhOOdB^YOh6X?pE9;r;aGav@e13tx z4Cb00iBY16Da%_*o~sHf5!{AE;1OGlB)IuU0porK&u3p>F^gMVs!olx+k@z zQ7h615t6GLF%6|P)-w<+dU8ZX`=btW>gCJ~HUnMdR1-vGd%SoP$ihyOs|FKY5%KS) zj*8@DZ0DvV6M+;u`r4>Eg(9#B5hEkRjE?3x&-8E3%_Z3pU}J0T*(zjd z&7p9?mUYw|ZyJYrNjk)TR{cgeArv?8K-l$sQve@B)RsD^1{$W4K-(@JBiX*m`lgG% zt@R80>TxTt=WE;fi!-Em7o)}oSaC4Be`Tgn7zzKn_yu~HiD|ZC$~rupG8g|9TE|jK zy}+nPOM~i9K}&iESDgIU7Oq#8^W5}wna_a%qec$6H|u{!UhPDkrH%|O=dMU5 zYati}Bk&4LQU4Z!W~Y2KG* z!a9wGQbbs4e9RMH-=AJ0Fj8I(lnRh_a_swS5i=e8Y%zx1miu*ARRFdn`mLGm9WG@E zk&&(O_bfyevE$M;Pv`#22VENLLh(+qRROnv;baSy2cOGU;+m7oJPYO%7$|}@q#Gd- zif3D`HjLc4{1ON3s1#dgMUfUQ_aDv?kM)@krWAIFNMs~aM}L#W7+O}6 z*y1k@$nv@X=>Pt~(?;efnj%Ih(jdcXiMJQOC1>!Dtq%2^s%P>(yp_*4%St(iO--~RXBfpdQudtOKQz?Alnwlz~cH+bnA^o(&v9k!xVteeZcr>3Nb-Q+}0uL<)a zM$235HCeXtczoc-=ldA@{_O|Hnx%U0hfjsb4bMx{wYc24nxh0T@L|3$VIAhYg(0E- zl}Juj>g|iaa^HP$!TdeO4-%x)Qh}Ampb?s2hjkulB0VzoF8&zo>`kVPp{J?;Jw#}k zrnB4{i$$e-_hKg<@SZp{26b&k6qNnSX?N9?2QC~#D*0xLH8V*xs!a)*(l7q!x8-AF z21A{*McEBk`tQ+(iE)K5$c_Y=kBKj0X3Yv)2vT|s2|l4YYPO^$T?L+zzAeK)6&4fr z8Oq^Yy?w(osU>9u*8aw+@Z9j%F=ptN1C45MXs+I zm#|S)DB|eh0|)&1I~T2g+R!+B*_Cn3%u3X#2LD)F3+Zlt2wXGmf<}l(!~AfdY`)cD zs5?j*T4^PDjaxVBxvHUtJ{-5pXQEFsS z3=_-+^Z$0&f47<9r)=ZbGz<-=znVF&c$ss79q*yk?puXt;wOhSenKCg+uxdjpj4=7l9KM3UvjO%qo|EbW;{0%}wzijYJi4^IT*Gq!o9J$R7`e@baq!bwg% zfYq4$Vqn^Pwmc~Cl8x<1r+-AUGjO;d;P9|(8@FJvoXw-z$@7tOnBnV7(OAMAo_392 zl9{1hTm+sciJD~n0Y#&jw~wDj1EU)ylc7+xqG82pWG$0 z7>{&P$QNw?5L}17*`LH8O)WAF{LvFIn9mh4G~Phz-Qu5`o(UzS`z%w8D<&D#+OSY> zA8WjRKE2fWrw8JhR$exPRVb=Q;CN+OXm|>iZ~yo3`I{#g8i&K;`@N7*+VfA;*cjYm zUlm-5*xvm+x!`l>Uu|C=tS<$R_`&DvuZ_++4qy6a>f|{68DRNvX&qK+WcPchG4D-T zUTzrCw9VXtL$C>`EVs2dwlT>=R>Hzj7fFHQ=SO%jQHYyu5VtsY+R|!um~RRJ{$#b$ zL+Z`t&jV&H_H&5b?;W1iMIE!09?$E2yF@rYipv8U;T?x!ImHpWRwO0;D7sR-$fKv~ z<^|{GID}&FHqq)PuZ<6z@f2p~M2iJKs4~O3cgvRRovq9%mtxqAFlQL!_6 zq|9i)j=i-(KthGXVI!G+GMYY{w)6JkNJ`2jceULexUEW_UCrIk{Fl*%%8HV>U`C6h zVLe0hbCrqjY$b1xMI-Nzp}hY+v|=(j>{oX#Pp|T;>E&v$1V&ogkAi1sTYNq?7S9w*Nu25$_d4voj53Mstt5ZSZS5i2#7ImNy5fM6iZts^UEh~&b#&BH z+mm2yecjj4@Pxgr!3jtR>nPB9HrR8Px$M?!gT8DDQ)GoD%@6J)VoG`s5xP^f3Q?ln+nd|?ixm2c1k-P?P z8Su`-&7GhGZ+q_n+&v0{kus)m-eqD;e0;oOs&cHwKCYhtf zUsLgPGA_ovc;(ne?t?xCbBUXonc+<^8KIr&QJN^GaE?UdaH#n`?xlJz=y$l$HOuGn zJMkbYg2TeXnjr#yHYgT!7RcDGG*Wr?27Y?#^1e?QtAj?w<&4TiKg4m^9YJ0UN2M5| z-1b$FJotkvB8m%!pK%9NHz6yla=F*1TYCg7X3_I_!{6iMBa0m9n&_HcUak`n=rp_B zGt9Y@liM*uso~%j%h?cm=a?;8?QzqItIu*-oQ{4Ems?hAM(hWmGy#9VVBFNwk!sxz zpAbYm?m%bw_iJwPH`nUwY8eq>;RUD1%uhNS=BUmw@{CTqBSOiprx)GN)uv(uv&+k# zcl!HPu+)CUSlb@pRgr=}CV1`~={n3$MTZn@}EK0ZFd1c_V{RFbl?q^@M>Ub0G# z!%5&?J(^!3U0r+$iHXR#xZ~&C&WP!eDyoCCB?O_MS;AL-<^lb;+uPgtl#~!akRzs` z2;Ik%%!~(=v?*RFtmToVrL^<@nVE!Yl2xy_7lkDJd(* zCnZ6Nh=_=aiA{IHJyzm_2xD|ee?{w%f?yAM$;qL4@ngBslo82Di8%Z)9N|AZIyz3x z&K5*C-rM!!+axpsT=Hp?5}xPHJ^~AbbIkT^p%m)F^E1mqX>}ZL*y%~JOe%e2nPBTU zY{WQMIn`(8UR|l7q)t7_4G{^6Q1&NaF5=8&M@hE;G(FCR3BQjEj39uqhU3F8V>H$` zt$@YAz(DunRq8YRrHDYdsi0AW>5Le$yOWucf^jx3YOz?2=lhM<i%S#$lnls~n#%@VI&P%-)qIf)IrZFQ>?jFRMPGoT{)ti3l zxEbe)2vPBfk6_@>mDkR$C@Y($jysU(DOg(i@A7J=poB_Z0Ra7EnGIY%?ttbz6KRj@iZTy8iZc9ThW zMw9l8b@~Yu*#`f465wO-`Kasb>#0xKiu$q&GDI>yVPL#xQT=bJpx8EnOh90N1JE1z zs*in}UEUOURlC%TjdxOk$*SHv#(jT#zSxIB!XH;mp#XPm zrLo&;#lK&yceJdZt+tSnh@Dp-FIME|6YJC&ebPUl0H92GJ;a` z^Cl26CVh&RB*pqJDONp^XA={@`T6PY>P=KHl%~8s`2Fm@to~f*aj3eZ_!o` zdbRdy`7Y`?v&j<^Jy4> zcJjD>(mA@3$j(yqUxV_HebrB&EE%mN_|tRdzC^DVQJCrn+vA|elx2JacLb;2B_G<=>4`=H;<_!BTt;N9FLoO!|_woDq@+?AsW8FzGhhY6q@fz&W__uVcHuH z()B0K)c^9a^R|y3z3~=qf#iJH6m7KUMQq;JcRWZ9>~}8_7WtM+f8$XOf@@%ET^H|+ zx%%EL{!Ig$=TGa&c&FGvtu^Bm{p-|??u33HU~IXX_>B&5vBN-ZJ!NvlPR(!lP|E%p_aRP>*J#X6MM~ z(ecQgx*YCN^CwkA5KUGf$V3%f`*u3U+cS18O*Fy{y)~6R>VgltBFF|{W8%pOm1ovL z(sS&L?R5oo9&L<}hx-L$c1P@Msf{T5wX^+_!O`_e4^jl4q&OQa056j1$Htg6LXyCp zN|->b`OkaCF{i6Fo7R^PK`sZK*B!F487FS>*jU*`SMO zymZ~Fx(e&PR-;i3I`r7TFhq$&n!^>oPl9FJ-s*BV6<~L;wFMNXSVUFhqY67X9Ck_E z(3&mglla`kO>J#lXZI^pP?dT2Wlf}+`ug~{Kl5nzI*VBLnitYYxQ~YmRjY8O4lyrKFfg-a zr3y;}RHPtNqD1CegWfgd&$YWh$o20w zxU0%Y%gEr*VK$Y{H0n{qEx|=*YVh5i&S8R^_Vb-6u0HJ^sWt7*mhNFdLVE2QaXrYz zSz0eGR>gydF2EfW(UyVqQSF}5_i=KvO6JzL#d8h&v4(}BB$l3&p=&yk%9^>Tr26Jw zOGs1Uu^pe05-@>hle~gyh)htPQ{xw8(^;C74EH*^JT6AQNy`3K3X42m zD#TcO6;K(&S($g^_Tc5$6Kk8$7=$IREqq0h$J`Xt;Hm}zlvre_OdM1vu_GGJg6mLZ?MaqxNI%am zt`}==bS8f$Q`-U4X%}0DT}4@S?4gIh&si>*u`#j*Leu2=)y6fwyV)Ag^nvEVoy( zXl{vZd4A1ySTo-z;?r>|)~qKyy|ZPp9nD|Go-aF<5x+eK7(xYh!-f+51ct(@nS;R4h+W(kA|pO1yN>#gXz`swoj?hvsnV8F17y$kRhmu3h;`93*HI zE_M}M7s{iVOoxLosqElIohXAInd@Xz@x61*pT}Yco)e?psYgcWS${871k5ieO3@1o z8(E>b3%Jef9oSdTJObvS!xzWPGTtMpX>p~_@G#WXjptiU?$ljw*aVH5gfl+fp&Opr11-OOJMF*|b|yzSId8CyfHep|Pa>A^bPcO< z<1dX%W#y&OI`+Wx!w<8_lv?d(+`uUX4~Dc7+-*ba>e$c##~GtRi38Pux^C!&th@e! z^92=N;mywmiZYorH5JpW)1NIRrN@d39vFAW0M74#YG3m3q!xlB*LEu+b^37Q#hVwF zGiWXf%A&#_ejGayG_uZvb7+ChEb3p(5FL<&<--@?bHgG+kOobQa z^)+v?7MV3_Aix{S&^`|9E7ENSy0bjBD6da{BIDF3JRbJqcGhiEV>O8cWngs*HMvVe zA6>2mE#^{C_2dMyG>w4mZ-mk~Ku>0xOkjc088VhV$j)LM*y%h#IeIF|JD4uHRiaO= zi$c9#$U5`Q>)#WXoDdP_D*yuCn6Mdp2g5b#-Lwd68tEmt{oloV#0?w^$q|5oAJtk5mOd;4~>ch4OX-r5D`&ExIcepKB2_K#m@ixc$i<8RRLk;`>&fO3=RK7rL~|G4ovr<%(#G^ygIf zs+uBLNU?&<+Vq~^WCfxZ9gRg z!W`PHP%XJL(3#U0piC9y893swf;Uvd$ay6_Z*juYdA#7M6#!$kcGG=)>ARl-bS_hQ>e@MVCDf2iuTN+e!{u#>l}|mkU`5s#iCM2Mhn-RKb{or6$>&;-BIel(j8o8Zmc#BD z_8Spb&|Rx(9}$7%Tun;Ff>T>m8>5R2gd^xID&lcB+0>vJSn0dMRHipig@0}7TG z+9)QJr>E(>&qRU7J$@uP^qMMcgFC5TwvC2J=sASQAwJVdJ{;{1+pRJ5p_Dm*Bqz0( zH(Dy>_g;_tg9>cobV7rSt7lD}{5M?Wyr!h%px%&6vg2DI=s2d3wuWZ)(+tN(c9vO= zcvtq=vtjKDLLx6l2V(nPw(=;@5h0E|X;z=r*r$+wPbU>PsAx<8dyA4lECR;*An%7O zMrC%Wa6BDKof|$-DgD2Vr>eo5;)%593-#6fMm#yRdk@lqrwZ(ibyC2V9 zunZ2g(Vv9K%QZgiMD`8A5)3m=zcB*yg}?oG4f20b|KiWWtQhxJd$+ckQg&;4BT)Ds zM^-n;ZLJgwEjb@?@#>2kN^kCKytcrc+YtmH)71P~TX{QVeDw%m)owMW-=DC4AKZU9Z3nN{=>(W$LZ9~O z9H#e>Xy4CC7tZm6f8XfV-j28|tuzj=51ZFoTpQ}Nb>I*oPfibeG9&6~1h8%D5A1`L zYybGe)b8Hb)Hyw2tvT>~|H+~Ekl*i-)%wQ5{^Ed_c_;rffl7kW-?;|DlD_ryXD!42 z_F-}pC}O}k-sa_sz~;>xj(h2T*f!Sqp?xd~;-E~{$NQ0*emoN#?|o-v{ncEy#}6`; zA_`d4;kqt!cOUN~IJ@_!FD_Q|fws9djy}gGFAkFkJ+8;!u{i9E4i>wvdRWY_7Jq(x za5`d!TJMmN_{iGOGMru2WBe;Pa*4wQwm7RNZ2h%ce38IUbT0C%!u-?+{cq@#^g5Jr z`sC&qb88W2Y->gmshE3BO5Whv%k~pd$v}$U3&NBd|?O z4Ydd7lrT?sn+jxg*I{)F-5=SP?E5-gKascdI!<9fDR@1;$!Le5Y=}M)F+K8)pRgA9 z@a2XNI}vTq{>(?e%h8Pr+I8pjb0v|DqCI-&b(&pDYY~0*qH{Ps<}NL>{F4fP2LgJP zV8&ngkM+*XMSVgVe^=FAs*B4%7GS%6;gdJb%kibr(Q5p_^zow#=Qtj&gWsDD>F~gx zT($~B3sbRKWFbP>hK8f>^1S@|FQ+=)qKj=dZ|F@nHU^6=1b~%@#_yc{O?Gf+@AiZ> z+W$O_7Li1J`{yIF=LCsAwxL{%3MVWU)oAPO7`Yd}s0$p=Wb5RBFkOlVATl(LY$ohw zfAzV3@f!|@N#}3M<&hsKNV(O#bj*qql3~E`LJTg_91NE?wBdcK9l22<-?ur|+O;3O z2CO)qeiRPdLdEiD2ah!Bb-wTaIyLMj4}~Z5YFPm(gO>Fy-My3*!CL zL!X!HJ!1C7`R08=6+^hMr?WQ&_aquX?Jdo-O?oYxwybv?zMS9LewvXS$=zStl?u*b zKn{CZm6>RmIpOts^9VslM338BeP$t{B*cfgQ_tp(O$Te!8MVk>9Rlqm9Sm?Gp4Oo} z6SL;E&&0^FSNd$v>FGjOhv%#r>t8<=RA*`nsZ4rA2nU++bce6A}{AH#6hp2zW-> z)#gtCN!_}>uCC7R{q42R^Tv!;vtCr<+c&yoPcGD0CsYJxDUD{Ebhs-KIZ?m&q_9fu z7Wxu^(jJCE!2TOetZxpG?~%!Jq$pIok0r&$3++CS*ZP1<2lFr2bQ+&`vkP8Z2^AGp zARyqgARBHgcIU_E=8KvD9KEK_w74oI+CDrkrvq(+#bbU|)obtOrvIN9JRZ@fr>BK2sUqFpCCUn0qt_LfoxT3q zY(BzpB#uaAGFQMKa1|S-aV0`8ZKawCU}IwgHu(6w$pLV{Qboy zLvk2sB8M-N-~Y`gID8uL+IE@x@C#H_J_7{qx70o-<&=~ZcYr@tx6Eb1VYP60J)E9t zA)om53u4r9Je#M5J{2$8-KDIVSck;?!X{p_@K?BYxR~)qr>86DbeLhz zpu?*k|$t2*@gIAt|dqy78)`*-Jn z^QWneqw#2WG_e5f=m{DLpZ95|NTviD9`mOtI6Tyd@X_mO-Uj(&bXK)^<$wp+0B(s?-hT`%(0#+9QAZ{bqyfx zN>9hi_PRY*Evj~&&KG0l7uM3sm4|4qDq+OUD5vQ|rxz!(geMIkOBGhL6v z5iqf{`za>#Y%~2Uyn&xrO$4}Rn%mpK!9gM+as>u}M-h?J(9oa+Ata3h=S0 za^X~ZU5EQ>4_Oc$9o>u~!rR*$oTD9}>4*yoe&~<_YWRqd=4LniJV_auf*z>@jy#31 z!a~xya@ELc4ko5vfWR&?5^4W&a(Fn!4Wm>e{3elMTT)WeKRvBTEt&8)ft8(|9TpLB zf<#NKi0EJ#xF-ccK(I4J`UEhae31(dZ?JXCcOtP8c z)mc*RpPMZ#A|enljU81xqf&v2r3oS{}a~@}T zz3-yd3CZ!{O?wv>FuJ?DgBQ~O17ULAAm#(@1S4n(_k2|1ZA4p|7?ipR`mU6ASP?e#o*yQYNuv ztQqnk*C^xvCB**Ws}T4EpxELW`3wcoXfYkgPACJYP&-po`0a)EGH;0X|CZTGQZc$S zD=X{pfweFI(-KWB%l02Un-9z99$D{jkA3sI-VJB1DwMGO?-%}4PKsy}WzQs~@9vto zC8m2Y{(@9e9R2^0T}T3x`2_CMd?C=Ix76-RQ>A`5U-5ON$y!1Ly}h;d=gJCpfkdph ztStQ9`FdnBjrxqOI*<_7ku0${0ZsA+F#dTwToS2OY6JiQtAA}RYlxieO2F)QhL~}( z-DY<-Ru1skVm(~+ydR3<+g)D@_&%X=*l!f(3k8z*c;ClBlP>^L){&H;F)=X;Hk*}b zF!*vWRexr(Nt6?VK`-iCCc9!UVW7x9R6Q*X@4wk4`wn&WxE;x0A;L&ZNlNJi2%%*T zaal0E^YiF{&{Z_OXusYr1}03@fkOrn^OAzD13!HMVi5C3^tW4$%;8V9ydl2 zmMa4l*Jhh#V%?2qTb%5~HJEf#4{z^TDF~`SAYD~Ytwlm5>=4Eo#TCXc19vb1Kk*-A zoaUjzrBg7yf6-tk&E2zUSPo%4fpYAXB=_X|H1JUrV;y8>CkHIhf4V*Vfj4?&^z_@bT&V4V))%>8yhL<>{nmW^EWS zSN`0&;!n>RfHD*jR>S)z5WAO`mmdL>Jg=m21w<1T+HePx<9Ug8L+7Fn&6i423yHVT z>%**k+pMsR==`y>wfhbq@S((QUS9cRR~?3rPvWaHwqA~3>COW-ceCbH{EcJ7>^x}4 z_II-Xu07jMkjGL8wf^ZMysN7RYtxSGooA-0xw&<ubMjjU}N&KenHn5|SCh79buRdZ!L!`OV z4qrEzVT^M_&Fo3WLWA}$$2up~gaQ~P6*nwSvD4EJw@DBS95$=Tm{kRyImcAf_o(rK zBE*$HmAuJ~rwAkFg;e`4^er>ebVVW>dK#S^_pxmL_$)DT;O?LCOKG!}jiIWyGxXt3yb zp?!9LN7CRZ=F$ry%P&$zsN_0>5%OYx;>zf2OJ_Ro^a!=yP}E?XLDcKLI-G07SjfH- zF|xwwwo!%Q%gCI1ZSC^WC;Xi@ky2Y$AT!Aj$U~u3y`U(PPxvLf&3E(0Tc3&@XSea= z0pC{{f1G1YV){pf2VOS#iw7K0Vj{V=_b|l?f5KBRM`hINpTFQX%y~;5UdY&=7iZt1 zF4~duE(rQp20l~h^hkKAF#`lmNR^m9@0YH?;a-Zilg;2C792|p&kz*r{@)2n5D{-f zo!rimCe!B1jrzoi+k?s#$2(%n-HxLKm|L z3VU3uD&tYGA#yUXSI*ZEV8t%8*wN4K@kCDxLQChX`S2&wLfpLXi5`CXiR$%)$Vtfm z0hho;@wf#JCrOP+OAEhVp(@ts`v>I;gvJ$wPH+7&99Vlr0!Z?{n+~9-B|3P%bh;Lk z7p)iOo@Dzt8NxE-h4U+$&Dr5&Q4rco=jr9Dn#U_=X1Ii(to8mY9BTS=+#7E***?CH zbSj5@Z3)sd)x85Z7aMaQz?B?&5#w{MMGKr`i&NB}f0u#9haTLz-jQUjtbma*#>?2B zDS+js!6ZAVrz=?zv5zn8_3sE)QXU)F=9I{isLlmk5&m6nO&!W*{ zBN1|9Y5b3&r4C`O0wv;`4sM=`gb2u0^v#=6|2YlN2*VZcScA3|7Zyw_$_YDBGO>OB z`~^gA<}~}Pxim&#_IminOjlbATF-U%{!j#5$?_C6XgHWNZ&K)w1j&UjR8dXawoiaI&Vbn`Rkg+{#8x;lbv=1j~S;yvc?1=VsF{eSp+3!pgGt!wxs zSO^4n88o=N6I_G4yN2K}cyPDi9^5SuT!K3UcXwxS=Wouv=e_TJzpB5AnkuGex}TnY z`q_K0z1Hf!>}pF+g0`Vnk{amrr(Qem=*otrS=`$Itj8&W>ved~6`g{&X#Mb?{fKk^ zJZa(a=42`&v_yJQV6q64O)@w!pf-eUovgh9V7CbINi$+v5|EywkEonG&&daTSx5ZN zGP=})W&H=i#w^&l!XH4VYfZp~?WeMm0jnX}@cp&O9whf2uSdbB`?Eh_)F|{E& z57^#`#;p!r`$w1z{j6lCU47F`Tkv7%RVz%HD*-=Nm1QM*kS8=c0 z&yWV4-~KP3W1g>*`4pQ7oR#@{BgxGje3o!{kQW}3*gjB)#S~W^OGWv83J8?VlHL?B zGs(Odl>6M{AG)cT@ftKS3;tOusT#l*z4yfBiBL73@FB<*A2xT^hfzKfS7mZ9K(_!0 zH3dWgy#+?_m{4ihgSOTFE(P)@v`KyE$%Mj^>|97Bxy~p5l4D3(wXd0S#&jk6lMKGA zc3t8%kE$8V)D+}*UE_H;oG;~Y{Jv$0-xqrH5Ebws363W9n(4;@uXa)rMtOPVkyL7h z_0afEGx9`<#81l49LkD!bCW9MeufTcx5C*u_fR)e9W7PZ^Aleh0n@a|WZkar;kNDbQ-uhmG85kH|i9F5lvV38|+1Z9D_*r7i zB%MO9{CQDPXbSnv2q5&2I|D`fxAt~HxlF#$q9Q690)XzKVlp)~Rb@TPaCYZerr)l2 z#8y&L1Qh$et3QEaL3Rt%PvK;P*|;}?;?;V=tiI@++kQhd`%o&1*r!6&MN=54YhoYT zfEta`N5()5t4A2fOZ+=`_`rO6qvzW|ApXXL6DF3y?c(`6ASLRyS`tXgYOm5;pEdiKPXC3YJCHpZHPvYPQofCXneIx|zRI|7$A)zZR( zJYm;fh48g&?iilJJm(DwsQkjIcI_6>;m14NQJf%Y{A?5w!(>abcNbeHcza9LYlS`dWB zzgCssz{oYd{3Rq#KyZM(ePZeZZsQqTzQBi>aQcenCY2bVxqx!X;_j&!|Unn1lUC4KU@!+G{CpG9FE*ruW5-G zk?V)tNybgBjl#G#6#^`~#kg9}%=e!i_Z6WtUb}XLvwksgWI2|w^`#Qgae^b2*iaUu zxlQnJ9g<@#W2X&E!A_p_Pjf!nM*-+fgrCIgzM;?ZpRE!38T+pTHa?j{)daa4fUAUE zqko1|>eMDv)Jj@!s0iQk%D5R9m`|1AGY2L<%ZIP^s7XYX!btUB0r`ZJ1xqZ5(kB&Q zg#gD|fDhK>Z)tV-IM$SY=~T48Pr}N8brXd2N_6;YjRTu)T)hq{ZjPwD*$F zY*N0y;GcGSJ==U?VP2h^ATazv2_Fq8AcBr0XJayaiD-UwK@{#y?8eEQkRo-Fc|2$4 zyLtU59-iCIHYE37Wl)$W3Zen$g~g*7m`fproiE_7J3JM>cbeS$KwF*hzRhlNx_BJg z);KFv9}VJNly9Ce>)Y@&y**J|2Z~Ue@o#wO^aq-MFcT{3EL^@t%Z)O=SFj^rP;V~b zb>+a%1nyThF?iPn-})^|W)llY$l>6G`X<75XvifUSg4m?_FRfLuqjc=0mVemjne1x zKWvzKyY|CZAKEs;kY6Kw`)q_&)OKH%2-V|W%YF)X&kE51e@m2<&?2mOh?L~+;DLMX z-1n^6@wX=*uCYMA)qkc{#H8KVp#bWVio8VY;R7YXmmvF|hRMsDIR+2A+Y^=4w3wI_ z-ABMi!jK~e{c*g%76H%}r2nY@z4;>!Wpp=D^k1VPe97 z+Y?$inrLJsG`YiQ&kp){F`S3rotT}EfL;5SaDQwUlhtHF|I^f$aWq@Gj2}7Z-s=SP z1(N-8^pBZg4I5#HXCzK3TTU1`ol_6ae6P9V^4^Z*4rqY)p<8Us?7MLTE18^5J`7YNsEb1w|@jh;eEbfqCzS>#eSZtW##_7)K zZ+qd2$zlS-&|I#=rxZ*q7MU8f=efg&iKWR*6#>1vy9W?_)C1h!7>dK{NFa$kc)^hj z5BfcD=DuGJ%CoFDCjuWFfVmvCvMoEuGJ`G#SnUXzYmK`7&)CR)&XTn7zsN7QE>XY?Uqhk$w2q4 zY0v)WX|CYHFr`&9jH{^8ZHX^X{Int@IBLRAHb;-*&I#FM9Pryy;)9#z)b%4qc% z1zMbf)%H7?+=ss3GaIxzH!I(YZlmb~JlL{6lrGquaou8g3NsphT4ZOM`t`eA-bYAu z3E{uEF+(XN+wbo34*tUtn7BF!3bK3j;tkl}uLb#gdR706^I{2AJCo)e7?psjSElU` zCL-EKL6+KNo;WKFO=)v##iOM8PS76`g=Mk$Cq}L4yL@@xND#n@DOd2i(EGIL%d{2T zRKkI#oNKXJ38MGzCj)_egY6&g)M)UwhWh=#wL=(~-#J^c6}+5Iy2F zi0eS4p_KGzoVX3I9VhcyN~1z zSX^B&zME^q3}t+Z7vUqf;gF2Vu@NELcb_PZVnZr5&l6ij*2Fvf^Gq#jwE&ddr9~zS zwHdO4(KewHLiWSWTcS=ag2!AEcs^Io8oso8rTgxzT|0Je)lkK_5S`I6Sa+>omU02I z=*=%9n1rXZQ9sG389@pP1W=ph_IFx70ZAD%r?pwj$ zoMP!G;f$8dAHgqrJh5u|;|%o)B79gxUQt=%b0pOC2-*xVYu3R{PW%I(zu?V&pRr{t zEsR!=9k}G&rzI=K*JP@KkGPz&-_oPHpyL+SNqEU}eZ>iM%hq=r6~&tT{%um|^Z1qHm{>ul~p@AsJ4NMt(&=PDwKGnNHxG zuD&IszVy5R;dwZBF!V99gIr%Ls!=Yf0>R@{*MRr?q(Nh(!(hI-=>%ygv=l$wfRv;I zdLB9f$-zz}-=aV&d#>u?;(pDY|3>di62X_2y4Z}X6eL^AyZ%_wMz4mnn)nMK8NQP6o)(fj8;hA;UhpFrj}LzrL^0?*t&mYL6UxAH`lFEYoY29i zFZImeJQ0kbU}Qw-a{BGJNwHl4)@96#jY*bWD-#{<0QiU1fw~HZC*pOO zW*68wYR%X0_}!rmcSnB%K9R{+$HC@;<=?jZ6^jh5gX@zRNv>?T066WlAg;Synlu#U z?4e+cj36pxENgvU8Up4aPrZ)|yeLfsH$3>P5ggL%w%t;_4L%9j2yTl!TYLGJ@g`BP zKH&W!CK~qMuk}U`{c{d;FWMwswWx6f|1}Q#eac)U;PK#5S<7Ai;eR#V2_v_mFTIdA932L zc`L?0UTNv|K$G0igV2stLOa9h!qR)s8oeL&fK1TJ50_P^LkH`yL5Mfhmv6IsPiUo4 zk80ddR8o?gY6-vZ|b-ki}k4C6f`{Rc&owKqOW{0 zQ*K{;+Go+~m84-i-v$L5&d{}A-{m(P~Ec zoXl3kd7q|)>cb9Wz-)wNSXCHAw;{yb1S5>{*ggiQjpXQ$Z`k|}NpLg@=Yu0Bd4VbG z;RBAbU=jRF|06_`BYmXOd#czBdbb2Nd9Z}K=ApS7jUJiRg^vnL9qb8PGZgETl<>y$ zl2gEJXg!TJxroz*;Y=IxYrPucwbNOz6U7SkZPTRL7l9XcC-%~is!X8=3{tW_%165N zGA(7l#5bM+4T))W#Izi+$k@XYU4h}T;8htF#Q=Q6WDeUmaY2!5%xkQ*OAWX`(+PC$ zj0~z9l>FbKws>jxU?97Bz?q+%?AkiI2XD9Qjr9FUxNv-vo!ne_mX_sEUBx;Z7+V3m zY-rp6Y#rB=9{t!$Il6cf#Bxz^h-kKXHgF9q3fV2ZV`wFeY-h#)z%p z1A-Q6;h@>#d*??i`TFwjPrgG#_9G5?PYbGPv+{M*u9(DBVS&9&_tT~H&J9ptaUV_( zjB6kEc-VlPZnPy=9guR!?FY>myQ~kNKArVE`c!+!F*@PY2S2UCg}W{VrNnXweAy1k zZqMkQW``O#+CoZy*kpCeY9NC1d3x7c2Fzy&4*-Rqv2N_~ zFB@sD(ZSyI@rNqI7pDmPmiKW!r$PF?px%j*E@rpA)#SD#kzunJBCZ-l*!uzttwK1p zulW8wf*Bp%FV4M>_7Y4Us`|1-)r9SjciaM}+_=b46`xeaFr%gq*3a&ylerx@vC4>s zcbb{ZKMQ(J?0fLJ-G}I+e=aJuTw7?(?dhCL<`t6fd$*r*w@h$gvA@~n(zSllh%D&U z`bOFNRPTt37G1Ycwri6%NwLOQLg&Q;J=N!m{p~Vi^@HvQReZMJJ=;S}k86fsZflV# zbQ*&QyMjB5o$l(qb#$KLrr6lBb4tSaQe+8s8xWGt z#?(a=+U50^mYQH}B%-NZ(rxKLkye^(h11yU_^HGJxy9iLDBt%25QpcTK16YdlP-x> zGBNKmj+}XOPh~nEIc`a#IOMZD);(caEvR)!lxLg`vG!G&sPK}23T*>JmPAuigO&=I{`R>1q zzQ*oUtZ^r!AfJqh$MetV!|og$)(h}JvE%mfZ{h1dH`&-(TWav}%Qs}W&bkvZx!rLV z{C$ER-s7`+c_$Xqr<-*_I!u`5XynyQ@nmOV4_E#8uoW)M7Zwz|BZb-7F))zuyQiAF zVpWjg_3#m49!i!KGOh9g9Vx3=qdRZ4*0o!?&Zco+w!IPg5qtWC`xhNG6Po z4EB${`?N-ZP%lymc{(ek&H%Z52XCC<_&use zUULqoh={Pj*t~q9)VT6FN=h=4H|z_)`g$;jdRi4H?AxlrRp1nqBCK0ogJkxE#}@?B zgdNOzffr6!JU2$1?8tCo#iMe>p2r$Z34NRb;`v4vPr#Oipe!8l<|7qE z`tIqcP%ymbZkZS~AGcat-ujec3_hMer0PrP8XG68)Jy0np!{TIk$I;~aN^0OOCj%j z)802!xZuD^47;1?6~x@0)m2cuJZ^Og0q^#3&mXORex!3z6OWXi7Eb@luB%~tH#~5lf6!E}7w64-=p0icJ_muv zH$2tSwTV_cwa%UOI{iy)LUS=Psw0p$p(}>9>q`Jpn?|IROmo=5@9*vHJ%D$B@c|LP z-U*d%^Y1Q4LD;H;!QliV1nl*VKNwo6OvZ#HI|OUw?VHvH&r?F?m(_~JFs4lJ z@sB~c7k%7f$%f(b;dfUOcZ6{4FJC1>`!wfo-NbB}cRM@QNq@(h_cvPKQ+J+QL78{f zSoKXe2Ww7~s8x@wD33i5x9+-9x0eqY8+%V*bZRjRf?WbhWetkdLk*uzj3~^vuOH?7 zA2XNGF0vAxXdu86SBSmi+J|Ge?w5Q)6G8BDaTmC@?d%hFH<38flWuMx5NdT_=hMx1 zB=_vqR$%VRoP^NV6zxvEu{d`+X>NEvsmMU^F>wC8hZqq)k6=4gd0?LXD4L=WmJyqd-GIT+ycw9O=>nG4i=uSV{5gToI9FnU_|A zeibslmkL3f7QF6=x^aFR5LIM#cS41MA|nIPO7R_W6N9vP4T=5)d$tvV5DGaE9b>>M z7=SaDoA=sp-wdjcKw!+7qSLCSss~ygRsbPU|3uL2__&k> zKxWg&yi1RZiz7^;*Tyojwe?vqt!x9F>AQ0u19J_#f~)}YPjGZ}w6rN|%woOm3lWT3_>5!@~Cn-UWn4J`@${%R(J!V7T~W8SY%xSB&vyb?;Mpa0AV7O zS{A0(8)P_x>+>_NTB4zM{Pj2>kJ;9;u8b${{H?A(#Mp zhh%WF=lK9-AGPW#()smAC@84M%Srh^Gc(@w>r_<4vYrbo0R7czvf%Tq!r*ss{QGB< z09C>Bw#RcBz0_7koyNvSJb){sBt2ap-PZQ(v*L2GGlD8EE>2BOKn^-p`4mzgTu@LT zN)cyST=IOQZrfm&2T<;qZq}u#r8gj>&;iTcje`yXhK7dafHlA(hAt5r+QheZ@@pQQ zMh8>rac8Asl~TY>;$mf+`zOsNiJ)Nn7=jw16qh6)P5L)z7?_Uv`MVIbUvNd4{2nff z0BzRr%a<~ZF@2fcLuna+z{`0;g3J$6cjt<8r8zvUC4ru#Zqw;)~i?C zGi90=x39*quOq4Z#^-)1SqWIXOJ79=hlNS6j0wJ!IRb`!>_?vB0Jkf$9{sVf0SUy1 zWB>B(g%8SVYI09xNhh*R9~~L_xK0dFkb8s6@dc+ut^9uQEF~qS2@el1Wf06TOdVmS z8ljKPpo6pW%UZqGYWl#rMDW!nf}!-}wu-H~yni-6z`uL590deo(8B?k%EcJF#s&r` z9Wb$~yl*RY8aKEsC-T(2TXuJMlbV3ur9Z#`tvA`X)5aYOZ$uVgFfInw1Kh(o*(`xp ztmS2L&^8SLAPnZC^l`itGch%V)FI)f-J%$%VXiOrM&he)0?w1w-lR63K zE5J4z2k1i!gU^9gH8mIeKYsiG$;ru8BJvt`LMLE*$x6h4sf){C2!zhKj1l4=cF40OzZmQ#>Qi_X;dk|d{^a;cEy2(g{8`50IkYu^d6u+ zk1Aa|T22;>9JN2+%P=SA1C7qa($Z3%W`+Z?#nRifBAE6-65w8%T5v*Szr2b~T>6DkXm^IbLaf_=|T|K=9>}bu>$m$R1b^N|Xy^ zna5{l3W`v`AvE|1;&5&U{b z{`^Qx{KI&6G^5Zld(96bkbVKkm{&MCIA#(|DHstD!jr>Rs7mtl6SM$JXL?VX20fYt zE5O9U=Mo_1%HJF>-oR_;*8m*xHNa~`Ya&B_1Jdhsyx@HP0A2w|$kAq_>BX8UV~U?Y zNAgBL4PG)Jg~I)7>HTN@HA6#3CuG!X;fhuwC3`k|{`?*vFN&Sk?N23h3+L9Nyh@{50_=bs)P2|y z*fly@p_H|`*%!Sp90!Dte}5U+LnxdgqKu3TU?k~}>=?@HdO{5NgrEfiRgzv*LP7$V z#<P6VmK_I1^@S`n#tG2H>tbWdntjY1jNbF2L?pdQ3!s(md21m3mgG=(5hh87TG*HIY<=7j-1cm5ugQtvoeKcx6X!jsw8fK zCOeefSyR*``v1TH(^ z477~U$?78%OBFghGR*jXOg94H<4;UZx~=|jVwU6!34^vJwpnd!wR^|I!_yM%N&;GX zlboDc<!Hq~W^Fn#hn$j@N;i)JN!Lox@9bv8me!gdbg<$ z6u@BQbvY4T{uhold1Din6b*)3BOKeuEyf5jQPFpW8|&*ND>pwVDS=txfp}^VA}G9l z*4O;VADP1#WNB?3F46ipfQXHRp>1f zbchDb!|We>;f9Y7SSNgd3phe3k}I91rDePUu=5AWj(VZHv>b=9Hk@8TyUl)GxR=D& zN%eo~@4pLjU@b;^Bt(4f&b0^@e4UytXwPqxe0_!T1teBh-@Tq-wcQ`PIAE^+ldzz4 zBdo7BDKHuX??Dz~?0{(=@K&H?FXnSgu_!{Q2_-AV{Jg zs+VcJNs$c#GOJJ|Um#@*1v015DDPVdJ5PM1m(E06vIOaBfQvc>FvKrmI$waSiDPFp zBOLG~`T+zqF0XqwFE)t{Ar)AFty=|#7wH_CB*>hA8l;-feG44g|VKE1s<8L8-MD~X>^Z?Z# z0q~r`M)#o%tjv9r4qPs2*vf+b^^7MReEdz|RE##>c091qhb^hv0gp22PUl6|8>z0V z!+J{1-?X0 zC76K+wk-Dc_RbWT__*=`*|3DO^VJe(WZ&4Bt*4dM!J6M;9sm;nX(9;}l)t3(em%mA z%J1IZox193dxd;dWO?~9R6s4IEs><|wk9G1@U-jxGyx{ON$w96pHt5i*XibS@;#RU zPZCsg^e$|Ch4<~+va+&oB_i=ulQ7XVF_rj$b?P3t2R^#Fxs^C^Cm;w&F9Djap5&S% z@dw6yoow~_JL1`Z^O%?zh0R%gpOG&sEqCW2e)ot_vefAJ zH$B+;kA=s8mr?NR?IcV?%?UilgoKN$0o{@0iY5STS18n}X#ej0d$du*g<8u$Q&V(T zF6~d(_<+L_)tdwYwS=-}>)DDfC|JZ>jr|_u_0B+QrvVz!QBx@D39r-M*@PWnoe~(7 zK^{*8WVX>88yh;q!^55lYJ8+*Wca&4Wih^8lC0C@1g~D9(*fLEZvGb4FM#8c?Q?eo zTFKj=fKzc6aE7H+<>1GwS$$4vA}tt8)#gtH725j@@p9>uY!h8WBs+W>Y@TmFEFU@W zx=8)3z*$P2*Wu#j4R`j8IlQ~@@hvcfEvZAIO?sk$(In+Bk#6i>?p}qv$Hh%J5kRP| z7HbGJE$#x;YYTvn7@w*%qh4w^CNUT_vo4Hx_6PlIvd zyrpQ}p%8=sqU)o@H)JBpY*tFxyK>DnUaaF2aq)}ZrCefN{Q^kxm9td5sAGe|j{2w4 z9$C|1Jfyxo$%a|_bH+2)QxN=yv@zgD-INilKqUoKSTHf+YK^8raa(5 z+o_0hxbsFbJjDNDT9Sgo)_j%5N=bv=Euv^K%2e^Ys?~Z-E=@wtRhLJDQsHxHhO~i! zYkpZBa5vy44DzTRLRO|&^HarT>83SSlG-%Izv5lWMd`O&U{47fhw3Yqi(HX*Yol#3qJms7ep><$n+7q zsHB+WU;}0f^g{MEng~wHvjzCd=P~57%kK8TnO_T!$RLJ$%-7C@N4o$y=%eA+yuj_g z$DZ@y4CEihnXCSWrxY9(hgMPH$i`=<8IrZeL;U!fn?L30=t}o~G&M4qow`$Xx|A9F zR$P^9m`V4n?)qm}6!`6X>5_3-we@eX5NS3!2p&9Aw zgc2al%rU&LtHPX=Piw{KYu+&-_QqFw$tXyP&16SfO{Y$LX=L-uuzjW-9I;07OVgEK z@^Od=g?ybd9QvGo-^F``5pnfJQ)~9O%S|llm)3*U@junbyy~{;jrH;H4Y2q1&roh| zEJuy!WF~G(4XTH};!$3xS$Lfl9hC~Iis*(WEY#OJPm0~jY_haTw%xVsN5l}pmtmja zJ_|{Q2?*0=H?ItS>1ju_f}rVcVew;r!Py`*5I#ircVsr531NMDMv*WAxJtZP${w*JU2 zh$JC=Mq6}fJGrf&t4P&^B9XJPLRKzYb$XVmUTU8v68;nx6e@+(4fH87`Vy0pC;>QU zu@2!Y^cSCpPQ_`g^}Z-fEy|HWzaZZ?KhZbD22Pl65sHdRyNcv=bwG1O$H*YmloVU* zt(_nMP)cUAiWu@2koYBk{~lu5YE#&WSv%h-@x^?ip&F%7E4Ob8TeA7O^QorIsBu2k z`SsvZkej|`YV>eIPC?ig_EIT6X;N;ov;?gl{cV@3DgV_;m1+W<6j*I#UD1!2-d>vD zX#+!>3P=$t=>(u=h7;`6NhD58Zhg|r(jRTb8;A!8pEQO*LFVHZEcwe=`ZS_2B9b6AsRnfb*fT*jWL&_VAzJ#9JBPKBcN6K zZ53vThZ;%?i-}?CyUY7> zEa_m9(`0}Cb&8cTCy?Qa&VJ7fI(3>!j13(T=rQIjY-o*~1wy83$NMbJNE^`CrwQ~v z$Hpb-{zQ?~Os0O>;zd4jqIu6fLC5B_2Q~Ji^$z#bZ0gf9^z7q{5PjOUq;#}_kv4KY zlxx>$**L;xv6T*-tNo{t(We;WoYeEBrv%U3L6gQZt=j~R9l63<&uPO=UUVe;a#mKw z)|XxIPsayVN+nE}r+YHHO;`=*lZc2aCLGQ$A!{}-zX7E!cCWEcrGW7D5n2wq%ig!5 z0;;7|1Qu6NX$AQ5MTO3>P#F)bDmAo3P_52@unViYeOIMY?C`$Q?@V0M1A#xinP}vo z?@o6Gcdx{FAnD3}g0>_ECtlP*1#jm=nSY<+e$E1Gf~vCFjjIU5;@93NxQ}1Ex`uCu z6Es~^>D*^_6yqI{bE+*Q`DLGW+l&Y+IR>vR4Lje}VnGKc7SR=Ggc2 zT<~1%&m8peH6cc)k^-VM>A=GqEt}=h5+-DlILZIhzztnIW1^q24Jav~`06cK(#>S} zaFcU<;&pc0vRY#mL1g7}6tE!p91ybE7n7CB8b z8S5A;8)r{lW=qr_VtBQuZl_9Uk!BthyL~25SDLi<&$HOoRvWIvP^DBeEgEApZ(@~X)* zQDEB%I0zkBJ;Gbxhv2g`Z zAD)J#v&>A{|2Thd696a<24$kFe(~6|O9yRfeh}Rw6~PUa6mxA|wQE zrdX!K{Jc0S;r`jWp4*sF*6f-S#fh4pH&#=^zmhGu_&-#p!x!ZE4LKi>see9xLPb{e zlJX>`C^o~~5q6^O`!yUV%+FdNE0(LE{V6#mna$~=!t6i=hGk+>;b1yu`!mfpnon|I zezH>yOLmefH(sTwEE^g?9Xp^oz2sVP^DowN`JNmy5f_*Jks{~P#Nsd{v`F-Sr#$}@ z6ZxjsNApIRadG~DjGvU4c&+?6EqaW_dWH_L1W00d#hAuJqM~{Mw_xf-K=~1EI+WP@ z%j@QF7Fnq{p5g85_5t^6@2&uNbU>;N4_F|)BH9}DUkSydL6HC$mJQ$|XE!&&rKPk> z%gf`nmdb!x1b{t5Sy@?~U0;g>*q!~;y)$4hxhtORfFJdEL(V-ya00n&KXPs7eOh9)W zP+Uw+js_3ZB>q7C(b3uY*4x`#_)B_v`uit_kk-~#3$|@Xy{mzdk$h40w+GXuH_;Pe zaLRT4wY6;4O|qw%-*x%`C2)m?-cOUzWXJV20)BUuVK2{fiD6zq(Lz$a4nXgrcP(xg z(vP}KkBse)!q`FsdsD@ei20b&fC6Uf`M7>{PXrLeuz+j)Qd6~3ygzFeY-E?0XM8a> zc6`{MEd0FZfEsYl?g`gM*^pYT8Q5?Np+5;LOG?eo0g+Vt>(K zVU~XhOHq0Yo#6S$$RMFHKh?*O?>M{`rrL0eO-a-rzolu{%U)?Tn~~&0LuRb$pw#f7?zA>RiQ7I`kKio?80M`RC-o7TA z28s~IFf)7E;_sdUGFil<9~A{X=aPKFMz&qFw@g1BEC^8j`p0N!s=lngnbB<$8tZst zrKJ_q-9viP`yt?DH9S2YLpt|n9L!c~={KgmXm~o!R3?C`u_wqXLN9x&jlW_zFt?5> ztzPhsZ&{AVm{UG>}3{RU8iB@SY>RX1JF_=#)x?zfviPK5cV>b58!`*k;dXcH>m}YBx zz;48rR(O+dUFjFARUgUb1Q?#?wLr%58@T&`YL*BSg%BLu0J=WA@2hdSF7VAmQFN=*{ z%*Dkw2G`#7yw?UWtF?M}mA_J6><1&6;Zr|8 zfnVyXR35PIz8z;_etkFJjIX#m1`x_HK43G5cP{gu0g{aX`+FChvSt@!NSSC@7GuQW zj7YhnG0NF2&%e*c{rZ|Tk`3`gY+7RPX!GO6pf)Qgi05E~S;oj+uDJ8!ZEAf?85ihV z%$!p-12sRc8z}p>AP(v)^cMDltAE@X6PqTT{#7J;?y)Y#i& zi{dfpc>>y(55MD*AHlcPrn`e@rf`6@q?C9Q`Aq`E#8l?4)nCUF#2@A^|7Uz_Ru9Hf z6O#Yl)_5aGi-XW^YlhB{oa-@G7Q|Yldnj*k^DI`)Ky{D`mhFPT3(`hNe9CJ!!f&ha z?V@C2bwYt@BzP&rP6=(erDNpl!CY-0Z|xvg{B3QG*W$1my1#Dpw7F+}bOTeJo{BpZ zwM$cy#yL>=3$OV{l&(BMD?8ly!1LJkVH80zbjIQHx3%Q7n6124mdv9iM6+SH%zgeU4-df9ChT zb+D$<^WnSI^90&VF;$&somcFOs;Wxni}IjXxYvO6T$1#9>z;LKSEuB|U1Umf;40Gn z&(!4FcnHcV{s3-lj##$uQ(u`vE8V%6B3LL54p-RtH2&7-nLqFRNN(7}{>4rXOE%kI#NNF(^6_<3qZ8hD9mm!xMTdKI~ z5AA6+h^xEgyRTk?S~xLEJr@;P#Vb3b&s+!5&*dfSKKkt6Y(>M0w#_B;a@cdqOB;*! zEBRCOjo(K|18VLd7nk2I(I}!6CLJqE$WV)O>$U0_rKqN@4$Fm`I zJ6}Nqk2|+@QPM^KR6@zU8=o*dPL8!QJ{felRgeZ0gR9!ZYb9s+O{YspR z$&H*zKrryrXw=#;Y9SjfE%!Wp95wE(-j?aa2x-xReUS6siUbO_IqqoGXsuf^{AZ0m z%RMF&N{Wq+7VdljJxeo+OHH2rMcz+nM1>aA#caL)HM>^H$?rQ?$GCdlU*?=8DcoSa z^LUZ^p1d`@xT*UkEsMhgv+Yw^3`0|t;|L=XHmH}Xb9mwE?AP^E&J$7Vm5Qtb(n<(Q z9Kkcp*aVq(CE-}pq);BiDM`y;JIX@BM*L#FdKk}WG+A5FeM=~D=^3C^>_xM#d7(h> zLK(EMa`ax(M}m`J0@Z+dm;L71g`4neA2NgHa!1p&M&BL1<~V!m8mD%1h1=aobe%GounOf!kJjFZ zC70@ZL9`yc$DjQYidbS2NXUDkb$KBL2f%YS#uQMw;SJS_Rljy)yS zGl``K1e3%SNKr(o8}7Faq@h_rf$Lf0?tEdGS>Y1FFz+0kYbtZpE}-corxu?XSpWb{h$kzDF)0~{;WX@Gr$3TfW=ZKr5&Rb_ zurk6SYG`sci=%ec$9~I6ebr~wIm(slfh6xt16&797xJhdUv!|PJo&zOTm`wMaWp)2 zX^cbE6c0vH;OJQ$Z_Bl!((}l1c$z~h)xed-@UDF04x478x?Is`xe}r&hRfw}U)(Rd zuTVu|KRUX5V8$@8EsA zmL+i!)eH(Chu>W5j6i%D<|Jmpl=vz}KJ+)Q!& z6gWy6rVRtVT_KGOr?kLmuzWOcHoR$*a_@JcL~TnB?(f4|jAqKXH!Ac+I9SOjBJslI zJ<(5>hh7G^G^6tgG+nM~yJ8>;Xj@*rMJ0(0E&lnSwo^^?QaNah`!6oiSqny^9`H}j zt7JXyGGsQFHkRRPqh?{C&obyi#PJN3e1~3=s$%6T>*Xa}x$1HA0A2lSw!E33^)D4e z8W(-HXIy>E))I^3^AA>wE{d0CTB%IX*=25GV&zUS2&Zwm9e!eGsREeK)|oymi%zP~ zU}=Dtzl6iBQ>`~!hiB!@iN>+)LF3L!{~3n`B;C2W$2Puw8&V;cQ&SPZ7K+oHZ}|cJ z@wBRPkNX!fgnHg6J*hW}!f1X_1D_vXi;SBLA4^=z;>aYz*QO*Kq5}$~3|~=j^C4PV zGZ8$rpPKLet84yQ4+}Vz$Rbhw@n!H0ta5VftxWBwhB+5;`a_pFAFr@I_Fu%*DdRb= z$^z01`W!PgrgypRd&aq86_FaNE6x~SVNXz6iw4gf#Po?;B$VB3b5%bdX2UJ64t1gg z{ER(1rfrwa`?2- z57d{uq}gYb`@XSB2v67V1;{D5Q6V?gkfpW%`FzXATmx(I4tWc=%IuS;dyM-Lq67?4 zr$fDOf4n@p$tlMV85pjfZu1TQDZ>6K;r?Bt{Zn-Qv-#ikp5Oof=6{!i|CFpnqP-&W z^7z!$xZrrK|F5yHjLYg-X2fNB)7EoZ#I^K=FXiyU&d+I#OpIDSYA4FoyoikYDV?=O z8{YcauPF`7&YqQ$k%}Sr&rB5Th6Lfy_cIKm+?(b8kg?T=y(3;48x@#r*1KH3Jinrptz42&b1}pcz%E~ zm!uw#=OUp#7De?)gdmFj_S!wYmyJ+hxBF|2B2)%Qv+3 zjg23R3-6+Q>Kuql?$j_rDNWY*=7>AuiO%WiCUtGOJBnh_CTm{s156c>TfeXd=3%P4 zoPjkLh(4)kq?a)J9$mC#-C~rfMwFp22O&nLc>t~9gL(QrrHZS}_G?c>@3AI3g~G^K z$02o^_&~o;qYoW419PbtZa{q)#&gVPRms}XWU4DZ*dvfQyJ@uj<+UX89SJQpHXHe@ zzf^=j2lIQmo@tRygO0)kk|1V8G&tNGgWgp$Q@_MVI1X28LHwcTaJ58#`R+JG{6};t z+ii7O`@P$uxWv#C&u2*?%rofm*0e;lnoVpO&Ljx6QQjWtAi^I%jmYsce@b%X`u8>AMMOlyvezG4RhR`lOi=(C zddz=?cj(p@l7KE zZg}`N!;Hlwr(q^$zoop5o=*~-H-n)ZFmrOwG&i|hWs#&%sPIuMS6E~QgSeX zw`o4Re2Jp}d@%94xO^2A4dk#L8x5z3gk#p5t-!rkD*iaT*3FP3i$O;-*i&wZdVVEp z%|pv}Pa8_o^?;6kxcDO_nINe<$m1TZz zIE`cc2P1#Wa`-eR@IPmqZCf+S)?=NkD%UIXWj4fuj@|Uf!#dpFILf_qux*2wp-t7MX4Z%^s#@)sGDj51ysES z?1TLi;&<_%VNR6(3=Vu(NEkT%fvC!v8+b8q#bUP~R8`a-PdO>%e#H9G-TALk9)tdGoPiwXpXa~yWxWiYPw)XbfznVsI4#MwFsFM`I#Nd7 z=BLyW4tj%86#tFsC}Q0&d}b^!U5Xw*OxhQ4W69`QMC=eRQq|((hHsQKv{99EQc?z9 z{QFc*D=sQ7?x6;~F=X5%P?HOFYl9td;z+&CM^1gBt&>QE+FH_~q=QuUd#xaoGoQ=^ zNBQWkN5GEWL{nTNl^mL5YZy+LpiTFF{zSMZMN^NHwM82z>h{dNb6{jCz`l~=v+(@I z9_FB(g7}&&I&zHjb(5h~0TC zQ#3_bm}-b#A3%sPbP~C|_lSR&|0Vppz3B*KhiM$=kzh1#WTe^=m6jN@%qN#={`qt+ zfR6EdKAz+G54UHA-~Pd!DPb7Zt1O|JKMv~#hx)Ybdqg;6^a?vRp|Q8**GszEm(AW2 zi@!k<0h64BlNaWPtZ~g?74GZ|)EuuMYJB)>7XvHks?v7j;t#?UhK=WOlSzmj`;Qhz z@^hanT)$*%dNYOp#HCfEc?OpD-Di$Tsp_^ECAxSO4% z-m#3MUCa6Nm4UQapOpHq+g86DS|UuAVz6JVmz^PKj06An1QOIf^rz(O>iuk27lp41 zE#M|lFyj|#pZECrF3YojPToe+Hz6+&BJ*`F6SX7r3yg3_J;-lu3N|yp`vmIb;%Q50 za3}~qCpx}fGB%Jt@z%)*3`eXtb21|gt&Hp)3gI9KiiHF>*!wh7*sQcl{QfFDCPKCd z2emhad7GRZ2Yco22LB-4pnUBGZNYJUet)$qSV(rY)lXAJ^i-MO`Htdp7n2cl{kFtX z!U9KD8QY-8a0mV5P+Y|4_T+;;*LZ1*Uq~SuIsioaJ*XUn)oGCX|IATu#7>yNAznn_ zw9?Nr(j!F>|LF}(QT(?3|Qtr??=z%S(huR@&bZpG8 zQd_sWPJgzDvX+)x6e#QVcG+tanPGfP_#=cg=BOS)rg?ko$z$}Ng#;zPfHbz%pUl>) z&J2?TfOn`o?Yj)^!<$4INc*3xK-gHa=#}p-|2QO_wD!}hr`P6Vj+WURPmRD#JC10Z z*;c`G$w!{`j<4Sap@h?Keh4Gl&Uzh z*_XEA#H6sA=ld@~t$b3k?LlC7OP6qy_C`14VMTHsw!nE?@8DGw3YF6JYGu2#5*G17 z?tZEKfPtl80S?-^OZ-!i-&O`QhtrK^&sRA#gT*Tt>&sgQl|;@Gt7MYs&E>o)S&h0z znAEE{M8iAso?hwhTxxZzjYE>s0nd|e>&sa-mH3$qi-D>yii%#^$L9NdwKzNRAjx;c zOhbqvB*{`Z_fqXG7X<(DAMQ~4k2Y#aujIJo2 z1mo7=1GwYX797?PfT^OQVW`mXnkrd(qs$@sh15n~Kd`XDKGj)%_wYB&9SZm&4d9z2 z2J7NAm)mgWLP8zTua-yiFk$O$w{D)6LcDFKiiVjP1=L*eU8PexCYmRO$OoFMG9GyY z64lw-$N#|5Y1RoQBnI8Vpe$bwCT~BU4dpBraF&gYS(~pxLk^ZGs&HK{d5SC_@eD#k zb4Hq8Dol(YuXiCOXU1C?^@l{f?x+}qEv9m+9J|dI`iVYRh_a_06dD|I-(+cC-GjSZ~ci~FF=Y|Y3lBW{y7 z{U+mYn%7>uw7MDMN3+>8$Q}Ab8SM9?hv0GTKeAkD|X6 z&(Gju|F|7%QlNuB>Ox+xU5Wa3$E#K!c@>tK^lZ{SYx>ZuN~m<%Z|xblr_1!aprt^z zkc5rkJ|5Ta{qX2`YugFMuiP}B5SXkWbDGZw4EEbf!kw?5VUlyw@YsHvD&?j;caCYW zW2H0yR5ib(S=37ZPIu5`%3alR+Zbte-S!qO%i}5l=W)jJdTB{$#x1XV@B~#_b0JXs z@m>RMC|k2z|MvJm<#=lO{{A!&qI7f*#gC{O6n7ntT?J97EC`TIeG1)}6D3>UAuE*z zEj^ct3o2?x@k`S9wCmU?V$CN8yV>#Uc0l;)Wl=9rqqI4>a=s_8ym6RC(e z)xwV1@3NdfxZwg!5TX<>Z!n)V{1lschjyxKfq(W{$0wXRM}9W<%iQaSJcvUWp^pF_ z8wtt!9|UzC8WYa7^62~${p&BneEmexY9fl5Z1#JCUYS01F-p0EVC#x`C2Xd%E^95H zjl6eiW#5oNDVod^^9Pag54=<#Y#bU)obJvzM3Z>iRLfG^pL;g(P%Il>~ zq4Ex!g#`0Av}mv4U>k$zX#HAZFe^@9uu&bBu6lfO$chu|;?s_OFe6}Rv3a4&^BNAo zvG2;+Y~K_@WiB{EqAb%Gz>!|9(lZp1n0r{*^rn!|Mj`HplDwi{W-f2~T51DR$|x!t z0WqS+)~1(_6EkC(sGJF+G{g+uxL@5}!bRHKMtAPl49&XTzNbg=>$UrZ zVZA3?wK~;j_S&$Nj^>fa#EB|&FpD9m?0okp!v3NX@%wk79>M;$e~Q#OwjUdEr=~w5 zH27VtpHJI!n{VJouIZ*6VlOY@1VE&YDc=;^++V<%rd1&?ITx$XM68)FwP z;ai!ddnnJ~OGD*nPJ+OT+d9SYSPCI$gWkOj>}c#QoG~i45;n({w6pw-(PEsosa6D68$o>n z8Va7b_NAt?3Kha1Dr((d>bmN^eEBOYSC#w@tB{&z@T~a>ix;6S*=Ccgsr?ag-R^GmG$ZvzM84J@3ICsWENw-Vcs{~=c z{J$3PSYfjhZcO#gxi=$Z+_AJY2i*laf=0Me>tQm~mH^aFVST4(jAw7-lqRsVQYTB5E}W?m0{ zgmvq*!#TFW>UMw~@uM{HgAunN%C3e^b#7Bqn?^C`pz+^Ud{b}nT56jo+KbnM* z*08>5u(n(qtw#m7sAjbeFzk)~0Pl{e&aP|iC)gY*ryo=pDPi09?O)?j&|9K|@!AJ^ z&o_v$;BEIuof-es4t{=>swHeZ81QAZ;b(FPg2z2w7J9L{G%{VG21yon>0yRe=OnH9 zOoP>HF7m8tu175qr~UeEwua~*{D;e6JdEu_xP>CO-m0iuVN)~dseB?|4|_kyU! zzkm^=UB$?JC7XWo>)qc*ng1biDj^A2d$$0tD7ANBKygFg=X`(W%nu|e3V%nD_&W;O z*p#j1%4f6f?e5;%9W6eHAt8kzN??MKWQ`I1gh^#hN77%%wX_24AmHiMb_e>`8@$fv zI7^^=3NuQs_Xohiw*g4IOkiN39Cg?=E$CWeZm-P&?PDIYCe7UKKy_%-<qpR&B)q|bZ)x%o{w;FTQA?SzaVyN4 zYD$ArjIY<RK(fh(5&!Q@b#Q+>UT!UX zM*UumW=fXFEw6(){o*rGvpD-0-x84fp+A_IimEp_;M5HRBl4d*IpO!F7t?LQ-Exb& zts#E+79YV=V;dP81I#NuDIHxA74yd!pb+B>>I+~YYKPN={AOJBpuZyLn-3W1olPQ% z%cfL1Y!B;Wr8BjupGX7jcoe_Q{&eXYH*ZW*68_>TE*d(z+(dsr%|>>ryGeR+F_DOJ z!1IJ6y=3x}>DBodN1Sc5CJ?6T-wW%ZItzefSD-174yb|XyynA2etr?5*EMm&qoUpj z3k$0-FrKrrvtMOV%f$hytfi39&?5TCKME4{A<@y8Pf_LlVLsh|;J+-o>`@(^PDt}^F_T!I-PctSww7X_U`_^>-Aa~ zKVk1(Ib^Ar%yMAOAf$Qgge@56-%s$GfkfJX8G*e2?!$$osIoG9%+*axtiGP!?jd;R zvjL(x5eQ#v0j2_l-SONr>98XJum1x&Tc^Us-_-%m@zM;@5RlhV_F18qQdd*s3k?jk zS*Mo=0^H4*?Tpr|9bL}O&LeiOpPTq_QAM4dxd0B2HV&4*s;sO|GWXF$rS(zg91!*y zU*Fug^{WeB9xYk+!dErO@INT{@WVUdf$9BP{*YB7I3A3fu@9Oqk#iOECuQpd>CG>u z@d*fc!>XMtEEWb@Er6}XmjO#w%M}0F3nh9nTZU-FP)N1yE|~*ztRrk?Wd*uv6{81}x#=xt z$~NRMF)?v9LzLTzD70#|?*AJ9nXN25I{eko5^pKbH{z&os3w)h5iB%+S842-nie+66{^kc-Q~_**ymPS z{8Cc*(4bdoB_QzX1<5N|(;mVyzkL^`KW10=L~%Ii!~&jQZ`}A(w;}-p{t&0_U_58@ zSrYS5d<8iTjTup_^OKdWt!cx>r20{e9N2WCb7*e&vCa1zE~APM=^{Z%2K{j(rUVZ4 z1mH+2o~^Ub59`#kMnXZMe>PhfV!=4FE$?0b6cQ2v6gvOyq`Kt{FtYt>IM!2b{?g8L z(WmC_A>)-4;|L1~zW%LV&?3u5Mn>WFU4jTGqcqNv7FB) zEe6aSED=#^RqEq;wj>!Tse|>W%hbK1`om9@dt*{hybPo|jH| zZbehZsj0}capKlveA;yAa=-ae56-&&5kw?p;V{-#_%l0bT(xE`ArXjw;b4?TqJHPu zH{7%>Ei5LMZTjP#knhgLEizqYD;X1$O}7vV?;AQmerC1Y#A-TuUp-^SX0kF|l$)26 z13T^@U9;kgrv#`o+}_7dZ)Cm>s5?GB{z~bFyQEiIGci6c4)b-b@|Y+#CWcK`P}1Do zyh3AY%+2-S%y@#YJZp4xbno5s`HEk+mEwYq`|)`ygF#FCz=|9WAy}i6tT*O{2E%O| z52NhcXW1Ma5ZUIX=rN`Q5Jr9|NgzrM_p4RBmZzO zSUM@aW8!q`N@ixjx^wrQE+9>ejw43iTux67czkK}po`2{9>J$L0 z6;xEj%*)T$Emc|G*zl3f5N$Q7Tm@&5k)`F9=Po%5%bUf;#h(8D^)}+?k2L{07rzCI zZeUG@-fF3<2eq{cLY$rRh*y7&?V#e~2DG$%tf{L@&&YTQ?97J`AHG~X3rL8Fh=4_F z>4_klC@Cvrii(QTnXj?7DMrII`09##7#QcS?lJ`cDa~P&dAIZIq3Ik7#tcx5evoNDPRYXdnuXS=;4vM ziubM@yPN=na2ucJ9}?0DjI#A|3lu96Qa#;VCqOztB zSk@{CD%cmY+8k>Cyn{XWc?B;fDXe^Pagj%l#>q=o=U_r!h$kp0dZmm0qHbzTQC>bW zA*I4oyieG2%)-oUA1wxdEOMFjceLPcL=1-Ug;lt&T%AL&Lz=Tc*x>$jKljBmEA`vF z;dV^a}kf^Wyvd@tyu` z=v6oXhn$|CmaEx%uT>yFZ{U${UsP3d12w`(rf7R|v5f=5_Xxk%B!ya4eCa{vqon+F z5kr;D`_+)Pki6_=tUN)igrI<(T}7R*(58SI`_IV831bw>2S#%zdbzL)hi4L?%HKVA zKZ8s*SOz=87ezPfq5)Asp1kCOy8hoM7!-0JAg0TaQ0d#+(r?q|NTSTUyUw#?t>OsNF}p z($38_Ewrrzfa?{Dvqqo%liDJ*|A?FVXJ9M*eT#P^7r7`Sk(<_MLk{`PqnlXXmDnA; z34Z=Ef4Us{p8pdcZ1b(urosUK~^U_&jLi;ys`&~giOi6Z~#U4S1>R_#Z&orEx;YfOYHx9!$>dL5|IGY)~=|v zs;Vj#Dj1n?j@LSq4r8isKagsK57jkvco8X3zBvIFnY^)&lbK z7&bOGmvuwn^YeZuCWLy6^xtLaN0{;m!n4I zg$DpFy>Kh?`fIM?d;9x40Hx5x6JRr<`XWAzTDI1-o0nf=GC@^Ih8+?TLKQV{-Aw=# z1Le6NV`8v?KatVYq-F0;{zEv>3mEYU6A@F>JQqmV7(vr;qC=8y0@0cgFPl;-6TDfDA>g@Z^Vvk;<*0KI`l73 z&lmQAtH6tD^F_k@A}jj?1h4t>v;dhVY;Vun1vHCO@7F2vCf;##t5;fx=lj2c>K<%r zY$O0j64i$uTcCv622K;jJ?{@xRDvcZR2FqRS%dOiz-fE-h=%9qg8^CEmrARi-00`M zMNIPh{aVxAVf&nA^FsE&?xN^dtd?_bcL_j`$zl2dA=kWB;%u7V9H6mkWhXn8FFzE> zw<_W*6>GUoo&i5qIg`2;St!u!RTTS@Yx!B}tAwI3pS9W0rb&T+S=0YxQ~#O*J3f$+ zxB+|UJy@EI8kU@TkVUX_bi8`|*K0|4j|dMx_Iv~W@;_RZe>*k*-tMGtqX2>1_27?} zFfn~d^K^b-wBUGV!zO$pq9^27wr6vOWD8t8Ep#p{8kO(hbagKTv^5LYyZOcBMq|fY zKgs_!)_+F)x6AbZT>ftt!j3{0ET(`!nT`&X-5Pi-B^c);G zhlhs`d~UhSEG!Dn^lnPxV&^IzDQ_jXb_pF37`wDaDMmxeQx^H-ia5{{j#U-vW=;+ zaVvP6U=EglQ2XVeR18TJT*iO;`2+|X%P%hHEVXwxHz#|Rt#RW94A%G`Pr?o|Gc%Xg zvc&9m3Y4hXEar0pTXk9rs}}>Or>Fb)G!qAW!}uR@W?Nq>zZiKB4A9e~?GW!2Di&6i z=Ou6bpU4&4r`tVedKI|6ElDV z)|Ld^#^Z=||E4APOYHGaqAv1Y&7aUjVii zOT{Um_nSt*lB0x7TGs$lT$irW(t{!VPd7tb%n(;eAULe;=p^KaQBcHJQghROX!d;} zpqY+PJju*pyMTOKN^v+b5&FW#nyspRARE(J8NqIFQh;&Df%}X6oadC5ixh8YNJ#5y zCp(aRUh^#OqwnbiY>Xp|S&cHuNL}AWYnT`+jUZ}}_1bhGPlef$cx3w+UHp_j9hi!V#k2Uq)v-F{P26JE4E!s%#Vv7OmU1hCTMnpLVHH?TV`HMH8vlqCy}v# z8&;DZ%&=UXY20K6!&Bt3#lHCsn39GB-8=y5=EIw54}rcJ}y*bpbShavLUUJN~Mk-(a$4AL4{$( z*G80AB5v->-{Z2w6R3iz=~iP~zQA9qK~fVEL*TXfLBG<4Wb$Zp^o*HuTe`t@g`JwMe_ci0Pizo2sD3tEHU*sMBprSKJT z*BHH$X|^_P>G__eIufXSGPIpV7>ex)Y8VwD@TIybb1lk$LsiwNsYPH{Scy0|0 zf{6~raY8QsbVA&04^@X=L+V#fo>-xFI+3n90vcf*DEg!<8fqM_Zej=SKmG8BWzaiF zA?*)Cz_03~VzVPGiod4bA5;klfl1}t|&RZQ_=zo!0@V#p0o5?mtV0Eh}P!CgB{%Aq#8cYXS?!x&R z!)9E}O@L~Vg6n(Kd9AN$g9cBnUYTJfGtWkWk0&R=6)R+U(Nl(S!Td`?U6c^ou%c3Z z;(FnLLyL32npxQ}qw1_dS-p6#VxzjT`z)jo^IE6-)Pj4?g%PB+e@Zum>}I_PJ}2~Y z!Z;FAnwgsAxxs-ST6_|&j=Q{o3UGURuDmGI+wD@EEcBk?aWy`w9?NZE-!9No+ zrtMeHV^0gFQ**KWe`6dOokeGu(_=(%xO4t2Up&%4Zk!DG= zRH9c;y?gMndaTY7eT;ooR{za1nf;faS7BGOCl?MiFn&6{sgEcLr#2Cf_vLO0RkOYo zJEqz>A2gn1l4c(<=kFh^C(7x6U4D66_IRnxIykLOBi3_OJhkhD6rvh`oXqpO^y$QO z-Dsty6yG^tEGAj(>u)tty2Zs37IxF4yZwWLj3&bRAsYVVeCqSV!{e~jAKz8WBOW%F zYK6WXZ{t}y8rmmh7G+xU_WVIsQxkuzqlEEM%sz@yTN?exMGoz-mJa^TM*64%CApyc zBz;WNl)_Lcf4Nk9&WT$qGD$JSN8Xd6cZonXbBU!m+oafWTy{pMjlxB;#B~M7`?}6l zyXRIb+bwVLw=dCTR`b#4?>Xj&A7}q?eTKi14eNg8WWpU20XcZu`1R}5j+e=j04vd9 z94A2E2g%5|`dlq6x1B0gU!}kyC2-fLKA(n}f+f-9mc>0s8(&XoYwheo26({hQNi;B zmv{0+lU4CRjAb#mahD~e=fg~vr>#Nk_KVExt_@qA2M!LV|3 zn=r=WEF8rqt01VT2*-D}^TB#oHePbMYx31(kL$3s+j=*@&_qR14n6NGGv}$V%1o&> zL-2Wm<*U9Sh|)I_Xz6E6gwChA&aoxUI@Ez(7Js!KTfN)zEou+^sgS-gxX2K;>*TQ7C zl2Fo=dS3}|-@rCiTIADSM8$U;PtOT`C;pD*5sGM}gIR2we5@BQB4V_IZ1GD>wNv{$CiUX zrdrm;(-$+Z+{iFjl1Z2n?WHxD7||-z!jF+!PCDe(b6e6cMeiFOl%(ZQ9V88Lhpx&L z3*5!qFP$IGsQ%30sLoBb*y$CR$?Y2Qs4q2RzR ze~Yv~8B$z@zgD_2Y|9aTHKbdeTp1IShvhROX(`k>NWd|Lt=4j7kV|%x@Q};#6x$nb z@3whn$=`j;IaQKUH&Hxge^a(QS26LV)aTS~tFX4q{GzKwHd&_n4OX5!5&Fkl1sS56 z8<-ZyT?K{rN3s`^x!g9wm1UnF*HXVYo-?Sy!(aP!FOSs6J|&0DZF#SCej5u{oy`e7 zRi7)&W7RwCh}ac>3ZcyoySI^H&6h`O)ihE1* z2e;oo3uJkf>FuNGw0GhYOvGZhiO7#r@u(2N0eA2>5t4F{w+<+5~#0Dtnu_Syx2ax!3M2R1CG6&Q`f1Y7@9&(m6YNUrX=1YN=_M zRjrIr#a{Nb`!_zZ$5pQ|PuvoVUBtu~KtgbXN{DDDL(i$L*283yEDpFFJ|_ppop%sL z-1JHs(Q&|~!eKBT{(zCa9%413rEL1`1ee4uQ%R_BIGd>k3v7M$>=X9{vby=!1H*wY z#?FU@3R#z-W~FSk_2)^&z3bc92E1pb*-!IZH=+;#QTBg2^X%SF8M>w&4A(~neVKB^y)qJLqypTG zl1C>APp(hLGelVC6bo)~(}{{9#X}kxBx^jCm)9avcdlbkSC34J_d4XQ{o?FfQ zLv`EEi??N0;c{|k1IY;FC1_~Y4eDgQ?K?#>PSniIdX(sd3JQr4PI>Zp)ySm--RzTNQhYL%Z&cJey( zEcoT>oOEKn@u*9)OM@muI zm2eg>*y@DE`WvEd7S|ePs-GG?eX!B$!Jc2)t*(_vEbz+bO_5toaNrUbL)6bve>1bU z71BKf4v7f~{4?*WzN}}qC4uW{W?(qJ0j+s*^8p^w*F&GoH6gJ^&X+h}E9~6=19X_c zkcF4nAFK-K0a++-U*y;r^crO%d}7-*?_QyZ;}BXu>vv(|em^grQ53TMR@4{L4w*RK z5Cp~jB=uHQw%$M_krE{v)$2M_==(yFKaxR;>(Gd&_R_F*m&;TAMrYAzj%r1#l1TdU zhoe_<-9GC0*6TJ8SKN8g3Y%|8dYc9>O_ zSanA*>W>_9xvFjWO(@1nPdY%Njuf8eG#W+@F_3~7g(c$}uI-4&X1JE;GflixQ;Gl_ZEm>IWt%N$9Fus2?{OucKZ4MSH zrEsideNes$RD|GjCihjnEM-O=BlObi#t$Gw4sx*p)wEtxUf zwRdhL1Z+_)QIzt_hliohnK^<+{RFOL(1;Ry+|ocv6@xnv)< z?bz2qy==P4jr;WM?C#vvk!b)B7;8T~tw+k(ko~>Aqn|~6ni5FRFN>OPO@i^*kpX$| z9==7T8t70Ee&$8yjX^yDtrGdDC#QY%j-eC+>!saUY?}|19{lo+?--^QBjdeQXF7^P*!&I4FvhBTzMv-@j>PP zue7wgtrs604XD(E%;NFIh2m72>q#ee9!C!)IvlMH*M{JbV_~d+6T!hpQmMQBS&%hp z^L&l)2$Iryjq|Slw|?H9hAB>>n(8OV?I`&OteKet4(CI>S4nTXzcQ`N7^Zf%`5>J1 zkcH)pF@wDJ?s@RqEkdr48n^pZ{ZeaRpX5X$C^~kb0e3INFr;xOydGLY%2`hrySXa! zAzKVmE_0CNb|bvXj0Kg_&uY}qf+C7^iZfw#A!Yt*UUS23j=S~D~__L7^5qU1bwsZjn@2xAd2T;Vm_0_OMN#EunLJPU+>8+N78n64O+Z~*WG-HP1 zSE|RhoBcP` - read-only buffer +- `redhawk::buffer` - adds write operations to + `redhawk::shared_buffer` + +Buffer classes have reference semantics, which means that assignment +shares the underlying buffer instead of making a deep copy. Multiple +buffer classes can point to the same underlying memory; the memory is +freed only once there are no more references. For this reason, buffers +are memory leak-proof (unless you create them as pointers view the `new` +operator). + +The intent is that new data starts out as a `redhawk::buffer`, which +then gracefully degrades to a `redhawk::shared_buffer` once it's +passed to the port. This allows the originator to modify the data as +needed, but prevents any downstream receivers from modifying it, which +is necessary to avoid copies. Both classes are part of the core +libraries (not BulkIO), in ``, and have complete +Doxygen documentation. + +Unlike `std::vector`, the size is fixed at creation time. + +BulkIO Output Ports +------------------- + +Using the output stream API is strongly recommended, but all of the +numeric port classes have an overload of `pushPacket()` that takes a +shared buffer for the data argument. + +To create a new writeable buffer, use the single-argument construtor +with the desired size (in number of elements) to allocate space: +``` +redhawk::buffer buffer(1024); + for (size_t ii = 0; ii < buffer.size(); ++ii) { + buffer[ii] = (float) ii; + } +stream.write(buffer, bulkio::time::utils::now()); +``` + +The buffer is shared with all local connections (which now have a +`redhawk::shared_buffer` that points to the same data), and transferred +over CORBA for remote connections (same IPC cost as before). Once a +`redhawk::buffer` has been shared with other contexts, in this case via +the `write()` method, **you must not modify it**. + +If your algorithm requires history (besides overlap, which is supported +from the input stream), it's cheap to keep a read-only "copy" of your +output buffer: + +``` +redhawk::shared_buffer history = buffer; +``` + +BulkIO Input Ports +------------------ + +To use this feature, you must use BulkIO input streams. The DataBlock +classes have been updated to use a `redhawk::shared_buffer` internally, +and provide access to the internal buffer in both scalar and complex +forms: + +``` +bulkio::InFloatStream stream = dataFloat_in->getCurrentStream(); + if (!stream) { + return NOOP; + } + + bulkio::FloatDataBlock block = stream.read(); + if (!block) { + return NOOP; + } + + if (block.complex()) { + redhawk::shared_buffer > buffer = block.cxbuffer(); + std::complex sum = std::accumulate(buffer.begin(), buffer.end(), std::complex(0.0, 0.0)); + } else { + redhawk::shared_buffer buffer = block.buffer(); + float sum = std::accumulate(buffer.begin(), buffer.end(), 0.0); + } + + return NORMAL; +``` + +You can pass along the input buffer to an output stream, and the same +sharing rules apply as above (though you don't have write access). + +Advanced Usage +-------------- + +Beyond being a better array, buffers include some additional features +for low-level and signal processing use. + +#### Externally Acquired Memory + +You can wrap existing memory in a `redhawk::shared_buffer` or +`redhawk::buffer` (depending on whether you plan to modify it via the +buffer's API): +``` +float* data = new float[1024]; +redhawk::shared_buffer buffer(data, 1024); +``` + +The buffer takes ownership of the memory, calling `delete[]` when the +last reference goes away. + +#### Custom Deleter + +You can customize the delete behavior by passing your own deleter as the +third argument: + +``` +float* data = (float*) malloc(sizeof(float) * 1024)); +redhawk::shared_buffer buffer(data, 1024, &std::free); +``` + +The deleter can be any callable object or function pointer that takes a +single argument, a pointer to the memory being deleted. The `std::free` +example is somewhat contrived, but it's easy to imagine a scenario like +SourceNic, where you may want to push portions of a larger slab of +memory to downstream components, and then be notified when the chunk +becomes available for DMA. + +#### Slicing + +Buffer classes provide a `slice()` method, which allows you to get a +subset of the data without making a copy. The returned buffer still +shares the underlying memory, but only provides access within the bounds +provided. + +``` +// NB: The arguments are the start and end indices. +redhawk::shared_buffer part = buffer.slice(8, 24); +// part.size() == 16 +``` + +#### Recast + +The internal data is strongly typed, but you can reinterpret a buffer as +another type with the static method `recast()`, similar to C++'s +`reinterpret_cast`. The size of the elements are taken into account in +the returned buffer, with remainder always truncated. + +``` +redhawk::buffer > source(20); // 80 bytes +redhawk::shared_buffer shorty = redhawk::shared_buffer::recast(source); | +// shorty.size() == 40 +``` From 7ffbf29d92e9ce372bb3c4fb0848b10878e695b4 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Thu, 9 Mar 2017 15:58:29 -0500 Subject: [PATCH 0740/1644] Refs CF-884. Added a delay to give GPP time to update the usage state --- GPP/tests/test_GPP.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/GPP/tests/test_GPP.py b/GPP/tests/test_GPP.py index a53961d3e..eebd4a4a7 100755 --- a/GPP/tests/test_GPP.py +++ b/GPP/tests/test_GPP.py @@ -1445,6 +1445,8 @@ def testSystemReservation(self): time.sleep(wait_amount) self.assertEquals(self.close(upper_capacity, self.dom.devMgrs[0].devs[0].utilization[0]['maximum']), True) + time.sleep(1) + base_util = self.dom.devMgrs[0].devs[0].utilization[0] subscribed = base_util['subscribed'] system_load_base = base_util['system_load'] From e99661eb14802734726b8d813c211f2b3cc98ea6 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Thu, 9 Mar 2017 15:59:07 -0500 Subject: [PATCH 0741/1644] Refs CF-884. Verify that the nic is up before adding it to the list of nics --- GPP/cpp/NicFacade.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/GPP/cpp/NicFacade.cpp b/GPP/cpp/NicFacade.cpp index e8951a0aa..ec81374b0 100644 --- a/GPP/cpp/NicFacade.cpp +++ b/GPP/cpp/NicFacade.cpp @@ -28,6 +28,7 @@ #include #include +#include #if BOOST_FILESYSTEM_VERSION < 3 #define BOOST_PATH_STRING(x) (x) @@ -97,6 +98,12 @@ NicFacade::poll_nic_interfaces() const tmp << BOOST_PATH_STRING(iter->path()); boost::filesystem::path test_file( tmp.str() + "/statistics/rx_bytes" ); + std::string operstate = tmp.str()+"/operstate"; + std::ifstream fp(operstate.c_str()); + std::string _state; + std::getline(fp, _state); + if (_state==std::string("down")) continue; + if(boost::filesystem::is_regular_file(test_file)) { interfaces.push_back( BOOST_PATH_STRING(iter->path().filename()) ); From e904cabe8a0362790de0dab3419c60ecac7a12d0 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Fri, 10 Mar 2017 15:51:09 -0500 Subject: [PATCH 0742/1644] Refs CF-1720. Fixed cpp type matching testing --- redhawk/src/testing/cpp/AnyUtilsTest.cpp | 4 +-- redhawk/src/testing/cpp/PropertyMapTest.cpp | 8 +++--- redhawk/src/testing/cpp/ValueSequenceTest.cpp | 6 ++-- redhawk/src/testing/cpp/ValueTest.cpp | 28 +++++++++---------- 4 files changed, 23 insertions(+), 23 deletions(-) diff --git a/redhawk/src/testing/cpp/AnyUtilsTest.cpp b/redhawk/src/testing/cpp/AnyUtilsTest.cpp index 6546aa414..ee9d5cf5d 100644 --- a/redhawk/src/testing/cpp/AnyUtilsTest.cpp +++ b/redhawk/src/testing/cpp/AnyUtilsTest.cpp @@ -257,7 +257,7 @@ void AnyUtilsTest::testIsNull() CPPUNIT_ASSERT(ossie::any::isNull(any)); // Insert a number, should no longer be null - any <<= 1; + any <<= (float)1; CPPUNIT_ASSERT(!ossie::any::isNull(any)); // Likewise, a more complex type should not be null @@ -283,7 +283,7 @@ void AnyUtilsTest::testToBoolean() CPPUNIT_ASSERT_EQUAL(false, result); // Integer, converted by C++ rules (zero == false) - any <<= 0; + any <<= (short)0; CPPUNIT_ASSERT(!ossie::any::toBoolean(any)); CPPUNIT_ASSERT(ossie::any::toNumber(any, result)); CPPUNIT_ASSERT_EQUAL(false, result); diff --git a/redhawk/src/testing/cpp/PropertyMapTest.cpp b/redhawk/src/testing/cpp/PropertyMapTest.cpp index 269ca0ba1..e400cc952 100644 --- a/redhawk/src/testing/cpp/PropertyMapTest.cpp +++ b/redhawk/src/testing/cpp/PropertyMapTest.cpp @@ -30,7 +30,7 @@ namespace { redhawk::PropertyMap generate_test_data() { redhawk::PropertyMap propmap; - propmap["first"] = 123; + propmap["first"] = (short)123; propmap["second"] = "abc"; propmap["third"] = 5.25; return propmap; @@ -152,7 +152,7 @@ void PropertyMapTest::testPushBack() CPPUNIT_ASSERT_EQUAL(std::string("one"), propmap[0].getValue().toString()); // Push a PropertyType; it should be the second property - propmap.push_back(redhawk::PropertyType("test", 0)); + propmap.push_back(redhawk::PropertyType("test", (short)0)); CPPUNIT_ASSERT_EQUAL((size_t) 2, propmap.size()); CPPUNIT_ASSERT_EQUAL(std::string("test"), propmap[1].getId()); CPPUNIT_ASSERT_EQUAL((CORBA::Long) 0, propmap[1].getValue().toLong()); @@ -190,7 +190,7 @@ void PropertyMapTest::testMutableIndexing() CPPUNIT_ASSERT_EQUAL((CORBA::Long) 7, propmap[7].getValue().toLong()); // Overwrite a value by index - propmap[3] = redhawk::PropertyType("overwrite", -128); + propmap[3] = redhawk::PropertyType("overwrite", (CORBA::Long)-128); CPPUNIT_ASSERT_EQUAL(std::string("overwrite"), std::string(properties[3].id)); CORBA::Long lval = 0; CPPUNIT_ASSERT(properties[3].value >>= lval); @@ -237,7 +237,7 @@ void PropertyMapTest::testMutableMapping() // Set a value for an existing key, and check that it overwrote the old // value CPPUNIT_ASSERT_EQUAL(std::string("second"), propmap[1].getId()); - propmap["second"] = 5000; + propmap["second"] = (short)5000; CPPUNIT_ASSERT_EQUAL((size_t) 4, propmap.size()); CPPUNIT_ASSERT_EQUAL((CORBA::Long) 5000, propmap[1].getValue().toLong()); diff --git a/redhawk/src/testing/cpp/ValueSequenceTest.cpp b/redhawk/src/testing/cpp/ValueSequenceTest.cpp index da0b3fe7a..c1321f108 100644 --- a/redhawk/src/testing/cpp/ValueSequenceTest.cpp +++ b/redhawk/src/testing/cpp/ValueSequenceTest.cpp @@ -97,7 +97,7 @@ void ValueSequenceTest::testPushBack() redhawk::ValueSequence values; CPPUNIT_ASSERT(values.empty()); - values.push_back(0); + values.push_back((short)0); CPPUNIT_ASSERT_EQUAL((size_t) 1, values.size()); CPPUNIT_ASSERT_EQUAL((CORBA::Long) 0, values[0].toLong()); @@ -183,7 +183,7 @@ void ValueSequenceTest::testMutableIteration() // Modify one value via an iterator for (redhawk::ValueSequence::iterator iter = values.begin(); iter != values.end(); ++iter) { if (iter->toDouble() == 5.0) { - *iter = -1000; + *iter = (short)-1000; } } @@ -196,7 +196,7 @@ void ValueSequenceTest::testFromConstValue() // Create a ValueSequence with known values redhawk::ValueSequence original; original.push_back("name"); - original.push_back(1000); + original.push_back((short)1000); // Create a const Value with a copy of the original sequence const redhawk::Value rvalue(original); diff --git a/redhawk/src/testing/cpp/ValueTest.cpp b/redhawk/src/testing/cpp/ValueTest.cpp index 517b96789..ae1ee2b1d 100644 --- a/redhawk/src/testing/cpp/ValueTest.cpp +++ b/redhawk/src/testing/cpp/ValueTest.cpp @@ -162,28 +162,28 @@ void ValueTest::testNumericConversion() // (where zero is false and non-zero is true) CPPUNIT_ASSERT_EQUAL(true, redhawk::Value("True").toBoolean()); CPPUNIT_ASSERT_EQUAL(false, redhawk::Value("false").toBoolean()); - CPPUNIT_ASSERT_EQUAL(true, redhawk::Value(-1).toBoolean()); - CPPUNIT_ASSERT_EQUAL(false, redhawk::Value(0).toBoolean()); + CPPUNIT_ASSERT_EQUAL(true, redhawk::Value((short)-1).toBoolean()); + CPPUNIT_ASSERT_EQUAL(false, redhawk::Value((short)0).toBoolean()); // Octet conversion from string, int and double; range test CPPUNIT_ASSERT_EQUAL((CORBA::Octet) 222, redhawk::Value("222").toOctet()); - CPPUNIT_ASSERT_EQUAL((CORBA::Octet) 1, redhawk::Value(1).toOctet()); + CPPUNIT_ASSERT_EQUAL((CORBA::Octet) 1, redhawk::Value((short)1).toOctet()); CPPUNIT_ASSERT_EQUAL((CORBA::Octet) 125, redhawk::Value(125.5).toOctet()); - CPPUNIT_ASSERT_THROW(redhawk::Value(-1).toOctet(), std::range_error); - CPPUNIT_ASSERT_THROW(redhawk::Value(256).toOctet(), std::range_error); + CPPUNIT_ASSERT_THROW(redhawk::Value((short)-1).toOctet(), std::range_error); + CPPUNIT_ASSERT_THROW(redhawk::Value((short)256).toOctet(), std::range_error); // Short conversion from string, int and double; range test CPPUNIT_ASSERT_EQUAL((CORBA::Short) -25000, redhawk::Value("-25000").toShort()); - CPPUNIT_ASSERT_EQUAL((CORBA::Short) 1, redhawk::Value(1).toShort()); + CPPUNIT_ASSERT_EQUAL((CORBA::Short) 1, redhawk::Value((float)1).toShort()); CPPUNIT_ASSERT_EQUAL((CORBA::Short) 16000, redhawk::Value(16000.1).toShort()); - CPPUNIT_ASSERT_THROW(redhawk::Value(65536).toShort(), std::range_error); + CPPUNIT_ASSERT_THROW(redhawk::Value((float)65536).toShort(), std::range_error); // UShort conversion from string, int and double; range test CPPUNIT_ASSERT_EQUAL((CORBA::UShort) 60000, redhawk::Value("60000").toUShort()); - CPPUNIT_ASSERT_EQUAL((CORBA::UShort) 1, redhawk::Value(1).toUShort()); + CPPUNIT_ASSERT_EQUAL((CORBA::UShort) 1, redhawk::Value((float)1).toUShort()); CPPUNIT_ASSERT_EQUAL((CORBA::UShort) 50000, redhawk::Value(50000.999).toUShort()); - CPPUNIT_ASSERT_THROW(redhawk::Value(-1).toUShort(), std::range_error); - CPPUNIT_ASSERT_THROW(redhawk::Value(65536).toUShort(), std::range_error); + CPPUNIT_ASSERT_THROW(redhawk::Value((float)-1).toUShort(), std::range_error); + CPPUNIT_ASSERT_THROW(redhawk::Value((float)65536).toUShort(), std::range_error); // Long conversion from string, short and double; range test CPPUNIT_ASSERT_EQUAL((CORBA::Long) -262144, redhawk::Value("-262144").toLong()); @@ -194,14 +194,14 @@ void ValueTest::testNumericConversion() // ULong conversion from string, int and double; range test CPPUNIT_ASSERT_EQUAL((CORBA::ULong) 4294967295, redhawk::Value("4294967295").toULong()); - CPPUNIT_ASSERT_EQUAL((CORBA::ULong) 1, redhawk::Value(1).toULong()); + CPPUNIT_ASSERT_EQUAL((CORBA::ULong) 1, redhawk::Value((short)1).toULong()); CPPUNIT_ASSERT_EQUAL((CORBA::ULong) 3000000000, redhawk::Value(3e9).toULong()); - CPPUNIT_ASSERT_THROW(redhawk::Value(-1).toULong(), std::range_error); + CPPUNIT_ASSERT_THROW(redhawk::Value((short)-1).toULong(), std::range_error); CPPUNIT_ASSERT_THROW(redhawk::Value(4294967296L).toULong(), std::range_error); // LongLong conversion from string, int and double; range test CPPUNIT_ASSERT_EQUAL((CORBA::LongLong) 1099511627776L, redhawk::Value("1099511627776").toLongLong()); - CPPUNIT_ASSERT_EQUAL((CORBA::LongLong) 1, redhawk::Value(1).toLongLong()); + CPPUNIT_ASSERT_EQUAL((CORBA::LongLong) 1, redhawk::Value((short)1).toLongLong()); CPPUNIT_ASSERT_EQUAL((CORBA::LongLong) 10000000000, redhawk::Value(1e10).toLongLong()); CPPUNIT_ASSERT_THROW(redhawk::Value(1e19).toLongLong(), std::range_error); CPPUNIT_ASSERT_THROW(redhawk::Value(-1e19).toLongLong(), std::range_error); @@ -210,7 +210,7 @@ void ValueTest::testNumericConversion() CPPUNIT_ASSERT_EQUAL((CORBA::ULongLong) 9223372036854775808UL, redhawk::Value("9223372036854775808").toULongLong()); CPPUNIT_ASSERT_EQUAL((CORBA::ULongLong) 1, redhawk::Value(true).toULongLong()); CPPUNIT_ASSERT_EQUAL((CORBA::ULongLong) 500000000000, redhawk::Value(5e11).toULongLong()); - CPPUNIT_ASSERT_THROW(redhawk::Value(-1).toULongLong(), std::range_error); + CPPUNIT_ASSERT_THROW(redhawk::Value((short)-1).toULongLong(), std::range_error); CPPUNIT_ASSERT_THROW(redhawk::Value(1e20).toULongLong(), std::range_error); } From e1092661448ac0cb034cb7043a449f380e5d1a16 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Fri, 10 Mar 2017 16:22:34 -0500 Subject: [PATCH 0743/1644] Refs CF-1721. Fixed bulkio unit tests for 32-bit --- bulkioInterfaces/libsrc/testing/tests/cpp/OutStreamTest.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bulkioInterfaces/libsrc/testing/tests/cpp/OutStreamTest.cpp b/bulkioInterfaces/libsrc/testing/tests/cpp/OutStreamTest.cpp index 3f43addc0..f16661591 100644 --- a/bulkioInterfaces/libsrc/testing/tests/cpp/OutStreamTest.cpp +++ b/bulkioInterfaces/libsrc/testing/tests/cpp/OutStreamTest.cpp @@ -116,7 +116,7 @@ void OutStreamTest::testSriFields() sri.mode = 1; sri.blocking = 1; ossie::corba::push_back(sri.keywords, redhawk::PropertyType("string", "value")); - ossie::corba::push_back(sri.keywords, redhawk::PropertyType("number", 100)); + ossie::corba::push_back(sri.keywords, redhawk::PropertyType("number", (CORBA::Long)100)); // Create a stream from the SRI; assign to a const variable to ensure that // all accessors are const-safe @@ -197,7 +197,7 @@ void OutStreamTest::testKeywords() CPPUNIT_ASSERT(stub->sriCounter == 1); // Set/get keywords - stream.setKeyword("integer", 250); + stream.setKeyword("integer", (CORBA::Long)250); stream.setKeyword("string", "value"); stream.setKeyword("double", 101.1e6); stream.setKeyword("boolean", false); From 003fd5e5683d4d124d777e88b2556edbaa819f65 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Mon, 13 Mar 2017 12:32:48 -0400 Subject: [PATCH 0744/1644] Refs CF-1722. Host collocation works with multiple shared library components --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 19 +++++++++++++++++++ .../testing/tests/test_04_ComponentHost.py | 19 +++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 3399d5ec4..b4db95f9c 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -583,6 +583,25 @@ void createHelper::_placeHostCollocation(redhawk::ApplicationDeployment& appDepl } throw redhawk::PlacementFailure(collocation, "failed to satisfy device dependencies"); } + + for (DeploymentList::iterator deployment = deployments.begin(); deployment != deployments.end(); deployment++) { + if ((*deployment)->getImplementation()->getCodeType() == SPD::Code::SHARED_LIBRARY) { + LOG_DEBUG(ApplicationFactory_impl, "Component " << (*deployment)->getInstantiation()->getID() + << "' implementation " << (*deployment)->getImplementation()->getID() + << " is a shared library"); + redhawk::ContainerDeployment* container = appDeployment.createContainer(_profileCache, (*deployment)->getAssignedDevice()); + if (!container->getAssignedDevice()) { + const redhawk::PropertyMap& devReqs = (*deployment)->getDeviceRequires(); + if ( devReqs.size() ) container->setDeviceRequires(devReqs); + // Use whether the device is assigned as a sentinel to check + // whether the container was already created, and if not, + // allocate it to the device + allocateComponent(appDeployment, container, (*deployment)->getAssignedDevice()->identifier); + } + (*deployment)->setContainer(container); + } + } + LOG_TRACE(ApplicationFactory_impl, "-- Completed placement for Collocation ID:" << collocation.getID() << " Components Placed: " << deployments.size()); } diff --git a/redhawk/src/testing/tests/test_04_ComponentHost.py b/redhawk/src/testing/tests/test_04_ComponentHost.py index ee7d504e0..0866bd7eb 100644 --- a/redhawk/src/testing/tests/test_04_ComponentHost.py +++ b/redhawk/src/testing/tests/test_04_ComponentHost.py @@ -46,3 +46,22 @@ def test_BasicShared(self): self.assertEqual(len(props2), 1) self.assertEqual(props2[0].id, 'pid') self.assertEqual(from_any(props1[0].value), from_any(props2[0].value)) + + def test_CollocBasicShared(self): + self.assertNotEqual(self._domainManager, None) + + app = self._domainManager.createApplication('/waveforms/BasicSharedCollocWave/BasicSharedCollocWave.sad.xml', + 'BasicSharedCollocWave', [], []) + + comps = app._get_registeredComponents() + self.assertEqual(len(comps), 2) + + request = [CF.DataType('pid', to_any(None))] + props1 = comps[0].componentObject.query(request) + props2 = comps[1].componentObject.query(request) + + self.assertEqual(len(props1), 1) + self.assertEqual(props1[0].id, 'pid') + self.assertEqual(len(props2), 1) + self.assertEqual(props2[0].id, 'pid') + self.assertEqual(from_any(props1[0].value), from_any(props2[0].value)) From 488d5da158bbd3ca944ca3db27ce004657102f21 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Mon, 13 Mar 2017 12:35:11 -0400 Subject: [PATCH 0745/1644] Refs CF-1722. Test files --- .../BasicSharedCollocWave.sad.xml | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 redhawk/src/testing/sdr/dom/waveforms/BasicSharedCollocWave/BasicSharedCollocWave.sad.xml diff --git a/redhawk/src/testing/sdr/dom/waveforms/BasicSharedCollocWave/BasicSharedCollocWave.sad.xml b/redhawk/src/testing/sdr/dom/waveforms/BasicSharedCollocWave/BasicSharedCollocWave.sad.xml new file mode 100644 index 000000000..03154e070 --- /dev/null +++ b/redhawk/src/testing/sdr/dom/waveforms/BasicSharedCollocWave/BasicSharedCollocWave.sad.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + BasicShared_1 + + + + + + + + + BasicShared_2 + + + + + + + + + + + From 621199468d5b783fe3a73fe746296da8114bfdee Mon Sep 17 00:00:00 2001 From: Max Robert Date: Mon, 13 Mar 2017 14:07:34 -0400 Subject: [PATCH 0746/1644] Refs CF-1723. Deprecation warning for Python package deprecated functions prints in CentOS 7 --- redhawk/src/base/framework/python/ossie/utils/model/__init__.py | 2 ++ redhawk/src/base/framework/python/ossie/utils/prop_helpers.py | 2 ++ redhawk/src/base/framework/python/ossie/utils/sandbox/local.py | 2 ++ redhawk/src/base/framework/python/ossie/utils/sandbox/model.py | 2 ++ redhawk/src/base/framework/python/ossie/utils/sb/domainless.py | 2 ++ redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py | 1 - redhawk/src/base/framework/python/ossie/utils/weakmethod.py | 1 + redhawk/src/base/framework/python/ossie/xmidas.py | 1 + 8 files changed, 12 insertions(+), 1 deletion(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/model/__init__.py b/redhawk/src/base/framework/python/ossie/utils/model/__init__.py index 466e636d4..a95ae7e21 100644 --- a/redhawk/src/base/framework/python/ossie/utils/model/__init__.py +++ b/redhawk/src/base/framework/python/ossie/utils/model/__init__.py @@ -44,6 +44,8 @@ import warnings as _warnings from connect import * +_warnings.filterwarnings('once',category=DeprecationWarning) + _DEBUG = False _trackLaunchedApps = False diff --git a/redhawk/src/base/framework/python/ossie/utils/prop_helpers.py b/redhawk/src/base/framework/python/ossie/utils/prop_helpers.py index 81b11a3fd..d6b06a175 100644 --- a/redhawk/src/base/framework/python/ossie/utils/prop_helpers.py +++ b/redhawk/src/base/framework/python/ossie/utils/prop_helpers.py @@ -41,6 +41,8 @@ from ossie.parsers.prf import configurationKind as _configurationKind SCA_TYPES = globals()['_SCA_TYPES'] +_warnings.filterwarnings('once',category=DeprecationWarning) + # Map the type of the complex number (e.g., complexFloat) to the # type of the real and imaginary members (e.g., float). __COMPLEX_SIMPLE_TYPE_MAP = { diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py index c1c870186..5d85916b5 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py @@ -41,6 +41,8 @@ from debugger import GDB, PDB, Valgrind import terminal +warnings.filterwarnings('once',category=DeprecationWarning) + # Prepare the ORB orb = CORBA.ORB_init() poa = orb.resolve_initial_references("RootPOA") diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/model.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/model.py index a7c9a0cba..213457c9c 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/model.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/model.py @@ -26,6 +26,8 @@ from ossie.utils.sandbox.events import EventChannel +warnings.filterwarnings('once',category=DeprecationWarning) + class SandboxMixin(object): def __init__(self, sandbox): self._sandbox = sandbox diff --git a/redhawk/src/base/framework/python/ossie/utils/sb/domainless.py b/redhawk/src/base/framework/python/ossie/utils/sb/domainless.py index 43d001af2..e07480ba9 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sb/domainless.py +++ b/redhawk/src/base/framework/python/ossie/utils/sb/domainless.py @@ -119,6 +119,8 @@ from ossie.utils.sandbox import LocalSandbox, IDESandbox import ossie.utils.sandbox +warnings.filterwarnings('once',category=DeprecationWarning) + # Limit exported symbols __all__ = ('show', 'loadSADFile', 'IDELocation', 'connectedIDE', 'getIDE_REF', 'start', 'getSDRROOT', 'setSDRROOT', 'Component', 'generateSADXML', diff --git a/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py b/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py index 567b60117..35cad93d7 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py +++ b/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py @@ -49,7 +49,6 @@ import copy as _copy import omniORB as _omniORB import CosEventComm__POA -import warnings as _warnings from ossie.utils.model import PortSupplier, OutputBase from ossie.utils.model.connect import ConnectionManager diff --git a/redhawk/src/base/framework/python/ossie/utils/weakmethod.py b/redhawk/src/base/framework/python/ossie/utils/weakmethod.py index 423a93258..7269b501f 100644 --- a/redhawk/src/base/framework/python/ossie/utils/weakmethod.py +++ b/redhawk/src/base/framework/python/ossie/utils/weakmethod.py @@ -19,6 +19,7 @@ # import warnings +warnings.filterwarnings('once',category=DeprecationWarning) warnings.warn('%s has been replaced by ossie.utils.weakobj module' % __name__, DeprecationWarning) from weakobj import WeakBoundMethod diff --git a/redhawk/src/base/framework/python/ossie/xmidas.py b/redhawk/src/base/framework/python/ossie/xmidas.py index 9f1390a49..778a8a878 100644 --- a/redhawk/src/base/framework/python/ossie/xmidas.py +++ b/redhawk/src/base/framework/python/ossie/xmidas.py @@ -23,6 +23,7 @@ # X-MIDAS interoperabiliy layer import warnings +warnings.filterwarnings('once',category=DeprecationWarning) warnings.warn("ossie.xmidas is deprecated, use xmsca.resource instead", DeprecationWarning) from XMinter import * From 9fef86a33bf07287edaf2fbf7b26bd22ca777542 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Mon, 13 Mar 2017 12:35:11 -0400 Subject: [PATCH 0747/1644] Refs CF-1722. Test files --- .../BasicSharedCollocWave.sad.xml | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 redhawk/src/testing/sdr/dom/waveforms/BasicSharedCollocWave/BasicSharedCollocWave.sad.xml diff --git a/redhawk/src/testing/sdr/dom/waveforms/BasicSharedCollocWave/BasicSharedCollocWave.sad.xml b/redhawk/src/testing/sdr/dom/waveforms/BasicSharedCollocWave/BasicSharedCollocWave.sad.xml new file mode 100644 index 000000000..03154e070 --- /dev/null +++ b/redhawk/src/testing/sdr/dom/waveforms/BasicSharedCollocWave/BasicSharedCollocWave.sad.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + BasicShared_1 + + + + + + + + + BasicShared_2 + + + + + + + + + + + From cec95440d2ab0a59c2f08ac640dd78d0818ce906 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 13 Mar 2017 14:21:31 -0400 Subject: [PATCH 0748/1644] CF-1422 Link the shared address space beta docs from the top-level README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 0d7132531..cced87ee2 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,8 @@ ## Description REDHAWK is a software-defined radio (SDR) framework designed to support the development, deployment, and management of real-time software radio applications. To support the design and development of software applications, REDHAWK provides tools that allow development and testing of software modules called "Components" and composition of Components into "Waveform Applications" that can be seamlessly deployed on a single computer or multiple network-enabled computers. +REDHAWK 2.1.0 added support for new C++ Components to be created as shared libraries, which allow multiple Components to be deployed into the same process and enable faster, lower-cost I/O. For documentation on this beta feature, refer to docs/shared-address. + ## Subdirectories * redhawk - Contains the REDHAWK Core Framework base libraries and system software. From 7008672365e70ef50211e0901af50bd28a37509b Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 6 Mar 2017 10:31:53 -0500 Subject: [PATCH 0749/1644] CF-1710 Preload libraries from $OSSIEHOME/lib to ensure that common libraries are already loaded, to avoid component libraries accidentally providing common symbols --- .../control/sdr/ComponentHost/ComponentHost.cpp | 15 ++++++++++++++- .../src/control/sdr/ComponentHost/ComponentHost.h | 4 ++++ .../control/sdr/ComponentHost/ModuleLoader.cpp | 5 +++++ .../src/control/sdr/ComponentHost/ModuleLoader.h | 1 + 4 files changed, 24 insertions(+), 1 deletion(-) diff --git a/redhawk/src/control/sdr/ComponentHost/ComponentHost.cpp b/redhawk/src/control/sdr/ComponentHost/ComponentHost.cpp index fe9fa7f35..3bd9e87ff 100644 --- a/redhawk/src/control/sdr/ComponentHost/ComponentHost.cpp +++ b/redhawk/src/control/sdr/ComponentHost/ComponentHost.cpp @@ -21,7 +21,6 @@ #include #include "ComponentHost.h" -#include "ModuleLoader.h" using namespace redhawk; namespace fs = boost::filesystem; @@ -37,6 +36,7 @@ PREPARE_LOGGING(ComponentHost); ComponentHost::ComponentHost(const char* identifier, const char* label) : Component(identifier, label), + defaultBundle("default"), counter(0) { executorService.start(); @@ -45,10 +45,23 @@ ComponentHost::ComponentHost(const char* identifier, const char* label) : ComponentHost::~ComponentHost() { executorService.stop(); + defaultBundle.clear(); } void ComponentHost::constructor() { + // Preload libraries from $OSSIEHOME/lib to ensure that they are always + // available. This prevents common libraries like BulkIO from being loaded + // implicitly by components, which can lead to the component library being + // unable to be unloaded. + const char* ossiehome = getenv("OSSIEHOME"); + if (ossiehome) { + std::string libpath = std::string(ossiehome) + "/lib"; + if (fs::exists(libpath) && fs::is_directory(libpath)) { + LOG_DEBUG(ComponentHost, "Loading default libraries from " << libpath); + defaultBundle.loadDirectory(libpath, ModuleLoader::LAZY, ModuleLoader::GLOBAL); + } + } } CORBA::Boolean ComponentHost::allocateCapacity(const CF::Properties& capacities) diff --git a/redhawk/src/control/sdr/ComponentHost/ComponentHost.h b/redhawk/src/control/sdr/ComponentHost/ComponentHost.h index ed2a08c14..7400bb6b2 100644 --- a/redhawk/src/control/sdr/ComponentHost/ComponentHost.h +++ b/redhawk/src/control/sdr/ComponentHost/ComponentHost.h @@ -24,6 +24,8 @@ #include #include +#include "ModuleLoader.h" + namespace redhawk { class ComponentEntry; @@ -62,6 +64,7 @@ namespace redhawk { std::string getRealPath(const std::string& path); + ModuleBundle defaultBundle; int counter; boost::mutex loadMutex; @@ -70,6 +73,7 @@ namespace redhawk { // Threaded service for performing cleanup checks redhawk::ExecutorService executorService; + }; } diff --git a/redhawk/src/control/sdr/ComponentHost/ModuleLoader.cpp b/redhawk/src/control/sdr/ComponentHost/ModuleLoader.cpp index 17967a4e9..6ac8718f2 100644 --- a/redhawk/src/control/sdr/ComponentHost/ModuleLoader.cpp +++ b/redhawk/src/control/sdr/ComponentHost/ModuleLoader.cpp @@ -191,5 +191,10 @@ void ModuleBundle::unload() { // Unload modules in reverse order of loading std::for_each(_modules.rbegin(), _modules.rend(), std::mem_fun(&Module::unload)); + clear(); +} + +void ModuleBundle::clear() +{ _modules.clear(); } diff --git a/redhawk/src/control/sdr/ComponentHost/ModuleLoader.h b/redhawk/src/control/sdr/ComponentHost/ModuleLoader.h index 2d8565220..583b9fd5a 100644 --- a/redhawk/src/control/sdr/ComponentHost/ModuleLoader.h +++ b/redhawk/src/control/sdr/ComponentHost/ModuleLoader.h @@ -98,6 +98,7 @@ namespace redhawk { void loadDirectory(const std::string& path, ModuleLoader::LoadBinding binding, ModuleLoader::LoadVisibility visibility); void unload(); + void clear(); private: const std::string _name; From a1bc857f28c637ad880935b757cc93b62ec167ab Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 17 Mar 2017 14:11:13 -0400 Subject: [PATCH 0750/1644] CF-1710 Track modification time of loaded shared libraries to report when an updated version cannot be loaded; reduce duplicate loads from directories --- .../sdr/ComponentHost/ModuleLoader.cpp | 110 ++++++++++++++---- .../control/sdr/ComponentHost/ModuleLoader.h | 16 ++- 2 files changed, 102 insertions(+), 24 deletions(-) diff --git a/redhawk/src/control/sdr/ComponentHost/ModuleLoader.cpp b/redhawk/src/control/sdr/ComponentHost/ModuleLoader.cpp index 6ac8718f2..eed59e631 100644 --- a/redhawk/src/control/sdr/ComponentHost/ModuleLoader.cpp +++ b/redhawk/src/control/sdr/ComponentHost/ModuleLoader.cpp @@ -21,8 +21,12 @@ #include #include #include +#include #include +#include +#include +#include #include @@ -31,6 +35,15 @@ using namespace redhawk; namespace fs = boost::filesystem; +namespace { + static std::string real_path(const std::string& filename) + { + char buf[PATH_MAX]; + ::realpath(filename.c_str(), &buf[0]); + return std::string(buf); + } +} + bool Module::IsLoadable(const std::string& filename) { std::ifstream file(filename.c_str()); @@ -50,8 +63,10 @@ bool Module::IsLoadable(const std::string& filename) Module::Module(const std::string& path, void* handle) : _path(path), + _name(fs::path(path).filename()), _handle(handle), - _refcount(1) + _refcount(1), + _modtime(_getModTime()) { } @@ -60,32 +75,41 @@ const std::string& Module::path() const return _path; } -void Module::load() +const std::string& Module::name() const +{ + return _name; +} + +bool Module::modified() +{ + return (_getModTime() != _modtime); +} + +void Module::incref() { LOG_TRACE(ModuleLoader, "Incrementing reference count for " << _path); ++_refcount; } -void Module::unload() +bool Module::decref() { LOG_TRACE(ModuleLoader, "Decrementing reference count for " << _path); _refcount--; - if (_refcount == 0) { - ModuleLoader::Instance().unloaded(this); - delete this; - } + return (_refcount > 0); } -void Module::close() +bool Module::close() { if (dlclose(_handle)) { LOG_ERROR(ModuleLoader, "Error closing dynamic library " << _path << ": " << dlerror()); + return false; } + + // Try to reopen the library without loading it (RTLD_NOLOAD); if it is + // successful, the library could not be unloaded, usually due to unique + // symbols in the library (or a dependency) _handle = dlopen(_path.c_str(), RTLD_LAZY | RTLD_NOLOAD); - if (_handle) { - LOG_WARN(ModuleLoader, "Dynamic library " << _path << " could not be unloaded, some symbols may still be in use"); - } - _handle = 0; + return (_handle == 0); } void* Module::symbol(const std::string& name) @@ -101,6 +125,13 @@ void* Module::symbol(const std::string& name) return symbol; } +time_t Module::_getModTime() +{ + struct stat file_status; + stat(_path.c_str(), &file_status); + return file_status.st_mtime; +} + PREPARE_LOGGING(ModuleLoader); ModuleLoader::ModuleLoader() @@ -118,8 +149,16 @@ Module* ModuleLoader::Load(const std::string& path, LoadBinding binding, LoadVis return Instance().load(path, binding, visibility); } -Module* ModuleLoader::load(const std::string& path, LoadBinding binding, LoadVisibility visibility) +void ModuleLoader::Unload(Module* module) { + Instance().unload(module); +} + +Module* ModuleLoader::load(const std::string& filename, LoadBinding binding, LoadVisibility visibility) +{ + // Use the real path (symlinks followed, relative paths removed) to avoid + // loading the same module under different aliases + const std::string path = real_path(filename); Module* module = findModule(path); if (!module) { LOG_DEBUG(ModuleLoader, "Loading module " << path); @@ -131,16 +170,33 @@ Module* ModuleLoader::load(const std::string& path, LoadBinding binding, LoadVis module = new Module(path, handle); _modules[path] = module; } else { - module->load(); + if (module->modified()) { + LOG_WARN(ModuleLoader, "Dynamic library " << module->name() << " has been modified since it was loaded" + << " (" << path << ")"); + } + module->incref(); } return module; } -void ModuleLoader::unloaded(Module* module) +void ModuleLoader::unload(Module* module) { + if (module->decref()) { + return; + } + LOG_DEBUG(ModuleLoader, "Unloading module " << module->path()); - _modules.erase(module->path()); - module->close(); + if (module->close()) { + // Close succeeded, clean up + _modules.erase(module->path()); + delete module; + } else { + // Close failed, reset refcount to 1; this library must hang + // around for the life of the process + LOG_WARN(ModuleLoader, "Dynamic library " << module->name() << " could not be unloaded," + << " some symbols may still be in use (" << module->path() << ")"); + module->incref(); + } } Module* ModuleLoader::findModule(const std::string& path) @@ -177,9 +233,23 @@ Module* ModuleBundle::load(const std::string& path, ModuleLoader::LoadBinding bi void ModuleBundle::loadDirectory(const std::string& path, ModuleLoader::LoadBinding binding, ModuleLoader::LoadVisibility visibility) { + // Shared libraries often have multiple symbolic links to the same library + // (e.g., libxxx.so->libxxx.so.0) that can lead to a lot of excess loads. + // By remembering the real path of everything, we can load only unique + // libraries. + std::set known_files; + for (fs::directory_iterator entry = fs::directory_iterator(path); entry != fs::directory_iterator(); ++entry) { - if (!fs::is_directory(entry->path())) { - const std::string filename = entry->path().string(); + if (!fs::is_directory(entry->symlink_status())) { + // Get the filename and run it through realpath to follow symlinks, + // relative paths (e.g., "../") and extra slashes + std::string filename = real_path(entry->path().string()); + + // Skip files that we've already seen + if (!known_files.insert(filename).second) { + continue; + } + if (Module::IsLoadable(filename)) { load(filename, binding, visibility); } @@ -190,7 +260,7 @@ void ModuleBundle::loadDirectory(const std::string& path, ModuleLoader::LoadBind void ModuleBundle::unload() { // Unload modules in reverse order of loading - std::for_each(_modules.rbegin(), _modules.rend(), std::mem_fun(&Module::unload)); + std::for_each(_modules.rbegin(), _modules.rend(), &ModuleLoader::Unload); clear(); } diff --git a/redhawk/src/control/sdr/ComponentHost/ModuleLoader.h b/redhawk/src/control/sdr/ComponentHost/ModuleLoader.h index 583b9fd5a..1e30d3ef2 100644 --- a/redhawk/src/control/sdr/ComponentHost/ModuleLoader.h +++ b/redhawk/src/control/sdr/ComponentHost/ModuleLoader.h @@ -33,24 +33,31 @@ namespace redhawk { class Module { public: + const std::string& name() const; const std::string& path() const; void* symbol(const std::string& name); - void unload(); + + bool modified(); static bool IsLoadable(const std::string& path); private: Module(const std::string& path, void* handle); - void load(); + void incref(); + bool decref(); - void close(); + bool close(); + + time_t _getModTime(); friend class ModuleLoader; const std::string _path; + const std::string _name; void* _handle; int _refcount; + time_t _modtime; }; class ModuleLoader { @@ -69,6 +76,7 @@ namespace redhawk { }; static Module* Load(const std::string& path, LoadBinding binding, LoadVisibility visibility); + static void Unload(Module* module); private: ModuleLoader(); @@ -76,7 +84,7 @@ namespace redhawk { static ModuleLoader& Instance(); Module* load(const std::string& path, LoadBinding binding, LoadVisibility visibility); - void unloaded(Module* module); + void unload(Module* module); Module* findModule(const std::string& path); From afc78321ba8811c1031d21787cf73e69da619b0a Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 17 Mar 2017 16:15:46 -0400 Subject: [PATCH 0751/1644] Fix compilation issue with Boost.Filesystem V3 --- redhawk/src/control/sdr/ComponentHost/ModuleLoader.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/redhawk/src/control/sdr/ComponentHost/ModuleLoader.cpp b/redhawk/src/control/sdr/ComponentHost/ModuleLoader.cpp index eed59e631..479db6643 100644 --- a/redhawk/src/control/sdr/ComponentHost/ModuleLoader.cpp +++ b/redhawk/src/control/sdr/ComponentHost/ModuleLoader.cpp @@ -30,6 +30,12 @@ #include +#if BOOST_FILESYSTEM_VERSION < 3 +#define BOOST_PATH_STRING(x) (x) +#else +#define BOOST_PATH_STRING(x) (x).string() +#endif + #include "ModuleLoader.h" using namespace redhawk; @@ -63,7 +69,7 @@ bool Module::IsLoadable(const std::string& filename) Module::Module(const std::string& path, void* handle) : _path(path), - _name(fs::path(path).filename()), + _name(BOOST_PATH_STRING(fs::path(path).filename())), _handle(handle), _refcount(1), _modtime(_getModTime()) From 5b75362383fe9027b8d676b1ed29311200517af8 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 20 Mar 2017 11:41:24 -0400 Subject: [PATCH 0752/1644] Ignore .pyc files in BurstIO --- burstioInterfaces/.gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/burstioInterfaces/.gitignore b/burstioInterfaces/.gitignore index fad13ac1e..639a8c9d4 100644 --- a/burstioInterfaces/.gitignore +++ b/burstioInterfaces/.gitignore @@ -4,6 +4,7 @@ *.lo *.java *.jar +*.pyc .deps/ .idlj/ .idljni/ From a7d8955c6815ed30d65741a6e7fbea85f1853715 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Mon, 20 Mar 2017 14:38:30 -0400 Subject: [PATCH 0753/1644] Refs CF-1733. Fix test to work when Java is disabled --- redhawk/src/testing/tests/test_08_SADProperties.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/redhawk/src/testing/tests/test_08_SADProperties.py b/redhawk/src/testing/tests/test_08_SADProperties.py index 263f8d74b..4d23634e8 100644 --- a/redhawk/src/testing/tests/test_08_SADProperties.py +++ b/redhawk/src/testing/tests/test_08_SADProperties.py @@ -94,7 +94,7 @@ def test_ExternalProps(self): # Configure all props = [pythonProp, cppProp] - number_props = 6 + number_props = 9 to_find = 2 if java_support: props.append(javaProp) From 2c8a1b2eab6da0508a640cbc019968d82180dc90 Mon Sep 17 00:00:00 2001 From: Ryan Bauman Date: Wed, 22 Mar 2017 11:04:19 -0400 Subject: [PATCH 0754/1644] CF-1737 - Remove unused GTK import --- .../fei_base/frontend_tuner_unit_test_base.py | 697 +++++++++--------- 1 file changed, 348 insertions(+), 349 deletions(-) diff --git a/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/tests/fei_base/frontend_tuner_unit_test_base.py b/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/tests/fei_base/frontend_tuner_unit_test_base.py index 026d2170d..826230be6 100644 --- a/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/tests/fei_base/frontend_tuner_unit_test_base.py +++ b/codegenTesting/sdr/dev/devices/RX_Digitizer_Sim/tests/fei_base/frontend_tuner_unit_test_base.py @@ -38,7 +38,6 @@ from redhawk.frontendInterfaces import FRONTEND, FRONTEND__POA, TunerControl_idl from bulkio.bulkioInterfaces import BULKIO, BULKIO__POA from ossie.utils.bulkio import bulkio_data_helpers -from gtk._gtk import RESPONSE_ACCEPT DEBUG_LEVEL = 0 def set_debug_level(lvl=0): @@ -74,14 +73,14 @@ class FrontendTunerTests(unittest.TestCase): Customize deviceStartup function if your device has special start up requirements Customize deviceShutdown function if your device has special shut down requirements ''' - + dut = None dut_ref = None device_discovery = {'TX':0, 'RX':0, 'CHANNELIZER':0, 'DDC':0, 'RX_DIGITIZER':0, 'RX_DIGITIZER_CHANNELIZER':0, 'UNKNOWN':0} testReport = [] testReportStats = {} - + # mapping of required/optional frontend tuner status elements and the allowable data types FE_tuner_status_fields_req = {'FRONTEND::tuner_status::tuner_type':[str], 'FRONTEND::tuner_status::allocation_id_csv':[str], @@ -108,13 +107,13 @@ class FrontendTunerTests(unittest.TestCase): 'FRONTEND::tuner_status::output_port':[int,long], 'FRONTEND::tuner_status::decimation':[int,long], 'FRONTEND::tuner_status::tuner_number':[int,long]} - + # get lists of all methods/functions defined in digital tuner idl digital_tuner_idl = filter(lambda x: x[0]!='_', dir(TunerControl_idl._0_FRONTEND._objref_DigitalTuner)) # In future, could also do this: #import frontend #digital_tuner_idl = filter(lambda x: x[0]!='_', dir(frontend.InDigitalTunerPort)) - + # map data types to DataSink port names port_map = {'dataShort':'shortIn', 'dataFloat':'floatIn', @@ -128,21 +127,21 @@ class FrontendTunerTests(unittest.TestCase): 'dataXML':'xmlIn', 'dataChar':'charIn', 'dataFile':'fileIn'} - + @classmethod def devicePreLaunch(self): pass @classmethod def devicePostLaunch(self): pass - + @classmethod def devicePreRelease(self): pass @classmethod def devicePostRelease(self): pass - + @classmethod def getToBasicState(self, execparams={}, configure={}, initialize=True): ''' Function used to launch device before each test case @@ -160,14 +159,14 @@ def getToBasicState(self, execparams={}, configure={}, initialize=True): #Add custom execparams here for param,val in DEVICE_INFO['execparams'].items(): execparams[param] = val - + #Add custom configure here for param,val in DEVICE_INFO['configure'].items(): configure[param] = val - + ### device-specific pre-launch commands self.devicePreLaunch() - + print 'Launching device --',DEVICE_INFO['SPD'] print '\texecparams:',str(execparams) print '\tconfigure:',str(configure) @@ -179,9 +178,9 @@ def getToBasicState(self, execparams={}, configure={}, initialize=True): except: # deprecated, use in 1.8.x versions self.dut = sb.Component(DEVICE_INFO['SPD'],execparams=execparams,configure=configure,initialize=initialize,impl=IMPL_ID) - + self.dut_ref = self.dut.ref._narrow(CF.Device) - + ### device-specific post-launch commands self.devicePostLaunch() @@ -190,25 +189,25 @@ def getToShutdownState(self): ''' Function used to release device after each test case Add special shut-down commands for your device to deviceShutdown() function ''' - + ### device-specific pre-release commands self.devicePreRelease() - + if self.dut_ref: self.dut_ref = None if self.dut: self.dut.releaseObject() self.dut = None - + ### device-specific post-release commands self.devicePostRelease() - + @classmethod def setUpClass(self): - + self.spd_file = DEVICE_INFO['SPD'] self.spd = SPDParser.parse(self.spd_file) - + try: self.prf_file = self.spd.get_propertyfile().get_localfile().get_name() if (self.prf_file[0] != '/'): @@ -217,7 +216,7 @@ def setUpClass(self): except: self.prf_file = None self.prf = None - + self.scd_file = self.spd.get_descriptor().get_localfile().get_name() if (self.scd_file[0] != '/'): self.scd_file = os.path.join(os.path.dirname(self.spd_file), self.scd_file) @@ -226,10 +225,10 @@ def setUpClass(self): # create a map between prop ids and names #if self.prf: # self._props = prop_helpers.getPropNameDict(self.prf) - + self.testReport = ['\nDiscovering Tuner Types'] self.getToBasicState() - + #Count # of each tuner type props = self.dut.query([]) props = properties.props_to_dict(props) @@ -238,33 +237,33 @@ def setUpClass(self): self.device_discovery[tuner['FRONTEND::tuner_status::tuner_type']] += 1 else: self.device_discovery['UNKNOWN'] += 1 - + for k,v in self.device_discovery.items(): if v > 0: self.testReport.append(' Found %s %s'%(v,k)) - + self.getToShutdownState() self.testReport.append('Completed discovery') - + def setUp(self): - + signal.signal(signal.SIGINT, self.tearDown) signal.signal(signal.SIGTERM, self.tearDown) signal.signal(signal.SIGQUIT, self.tearDown) - self.getToBasicState() - + self.getToBasicState() + def tearDown(self): self.getToShutdownState() #self.testReport.append('\n%s - STOP'%test_name) #ossie.utils.testing.ScaComponentTestCase.tearDown(self) - + @classmethod def tearDownClass(self): self.testReport.append('\nFRONTEND Test - Completed') for line in self.testReport: print >> sys.stderr, line - + print >> sys.stderr, '\nReport Statistics:' MAX_LHS_WIDTH=40 MIN_SEPARATION=5 @@ -281,29 +280,29 @@ def tearDownClass(self): print >> sys.stderr, ' ',key[:MAX_LHS_WIDTH], '.'*(MIN_SEPARATION+MAX_LHS_WIDTH-len(key[:MAX_LHS_WIDTH])), total_silent_checks key='Total checks made' print >> sys.stderr, ' ',key[:MAX_LHS_WIDTH], '.'*(MIN_SEPARATION+MAX_LHS_WIDTH-len(key[:MAX_LHS_WIDTH])), self.testReportStats[key] - - #self.printTestReport() - + + #self.printTestReport() + def skipTest(self, msg=None, silent=False): if msg == None: msg = 'Skipping test %s'%(self.id().split('.')[-1]) if not silent: self.testReport.append(msg) raise nose.SkipTest - + def attachChanInput(self): pass - + def detachChanInput(self): pass - + def testFRONTEND_6(self): ''' TX 0 - Not Implemented ''' self.testReport.append('\nFRONTEND Test 6 - TX - Not implemented!') #self.testReport.append('\nFRONTEND Test 6 - TX') #self.testReport.append('\nFRONTEND Test 6 - Completed') - + def testFRONTEND_1_1(self): ''' ALL 1.1 Verify device_kind property ''' @@ -312,14 +311,14 @@ def testFRONTEND_1_1(self): #pp(props) self.check(props.has_key('DCE:cdc5ee18-7ceb-4ae6-bf4c-31f983179b4d'), True, 'Has device_kind property') self.check(props['DCE:cdc5ee18-7ceb-4ae6-bf4c-31f983179b4d'], 'FRONTEND::TUNER', 'device_kind = FRONTEND::TUNER') - + def testFRONTEND_1_2(self): ''' ALL 1.2 Verify that there is a device_model property ''' props = self.dut.query([]) props = properties.props_to_dict(props) self.check(props.has_key('DCE:0f99b2e4-9903-4631-9846-ff349d18ecfb'), True, 'Has device_model property') - + def testFRONTEND_1_3(self): ''' ALL 1.3 Verify that there is a FRONTEND Status property ''' @@ -331,22 +330,22 @@ def testFRONTEND_1_3(self): if (len(props['FRONTEND::tuner_status']) == 0): print '\nERROR - tuner_status is empty. Check that the unit test is configured to reach the target device hardware.\n' self.check(False,True,'\nERROR - tuner_status is empty. Check that the unit test is configured to reach the target device hardware.') - + success = True for field in self.FE_tuner_status_fields_req: if not self.check(props['FRONTEND::tuner_status'][-1].has_key(field), True, 'tuner_status has %s required field'%field): success = False if not success: self.check(False,True,'\nERROR - tuner_status does not have all required fields.') - - + + def testFRONTEND_1_4(self): ''' ALL 1.4 Verify there is a tuner port ''' #Attempt to get both ports and compare if None, then xor (^) the boolean result reason = 'both' try: - + DigitalTuner = self.dut.getPort('DigitalTuner_in') print "&&&&&&&&", DigitalTuner except: @@ -362,10 +361,10 @@ def testFRONTEND_1_4(self): reason = 'digital' if (DigitalTuner==None) and (AnalogTuner==None): reason = 'none' - self.check( (DigitalTuner== None)^(AnalogTuner== None), True, 'Has an analog or digital tuner input port (%s)'%reason) - - - + self.check( (DigitalTuner== None)^(AnalogTuner== None), True, 'Has an analog or digital tuner input port (%s)'%reason) + + + def testFRONTEND_3_1_1(self): ''' RX_DIG 1.1 Allocate a single tuner ''' @@ -376,12 +375,12 @@ def testFRONTEND_3_1_1(self): print 'RX_DIG 1.1 FAILURE - Can allocate single RX_DIGITIZER' pp(t1) pp(t1Alloc) - + # Deallocate the tuner self.dut_ref.deallocateCapacity(t1Alloc) self.check(True, True, 'Deallocated RX_DIGITIZER without error') - - def testFRONTEND_3_1_2(self): + + def testFRONTEND_3_1_2(self): ''' RX_DIG 1.2 Allocate to max tuners ''' ts = [] @@ -394,17 +393,17 @@ def testFRONTEND_3_1_2(self): pp(ts) pp(tAlloc) self.check(True, True, 'Allocated to max RX_DIGITIZERs') - - # deallocate everything + + # deallocate everything for t in ts: tAlloc = self._generateAlloc(t) self.dut_ref.deallocateCapacity(tAlloc) self.check(True, True, 'Deallocated all RX_DIGITIZER tuners') - - def testFRONTEND_3_1_3(self): + + def testFRONTEND_3_1_3(self): ''' RX_DIG 1.3 Verify over-allocation failure ''' - + # Allocate to max tuners ts = [] for t in range(0,self.device_discovery['RX_DIGITIZER']): @@ -416,7 +415,7 @@ def testFRONTEND_3_1_3(self): pp(ts) pp(tAlloc) self.check(True, True, 'Allocated to max RX_DIGITIZERs') - + # Verify over-allocation failure over_t = self._generateRD() over_tAlloc = self._generateAlloc(over_t) @@ -431,13 +430,13 @@ def testFRONTEND_3_1_3(self): except CF.Device.InvalidCapacity, e: # Deallocating shouldn't be required if the allocation failed so we would expect this deallocation to be invalid pass - - # deallocate everything + + # deallocate everything for t in ts: tAlloc = self._generateAlloc(t) self.dut_ref.deallocateCapacity(tAlloc) self.check(True, True, 'Deallocated all RX_DIGITIZER tuners') - + def testFRONTEND_3_2_01(self): ''' RX_DIG 2.1 Verify InvalidCapacityException on repeat Alloc ID ''' @@ -459,7 +458,7 @@ def testFRONTEND_3_2_01(self): else: self.check(False, True, 'Allocate second %s with same alloc id check (returns %s, should produce InvalidCapacity exception)'%(ttype,retval)) self.dut_ref.deallocateCapacity(tAlloc) # this will deallocate the original successful allocation - + def testFRONTEND_3_2_02(self): ''' RX_DIG 2.2 Verify InvalidCapacityException on malformed request (missing alloc ID) ''' @@ -477,12 +476,12 @@ def testFRONTEND_3_2_02(self): else: self.check(False, True, 'Allocate %s with malformed request (alloc_id="") check (returns %s, should produce InvalidCapacity exception)'%(ttype,retval)) try: - self.dut_ref.deallocateCapacity(tAlloc) + self.dut_ref.deallocateCapacity(tAlloc) except CF.Device.InvalidCapacity, e: # Deallocating shouldn't be required if the allocation failed so we would expect this deallocation to be invalid pass - - + + def testFRONTEND_3_2_03(self): ''' RX_DIG 2.3 Verify InvalidCapacityException on malformed request (missing alloc ID) ''' @@ -500,11 +499,11 @@ def testFRONTEND_3_2_03(self): else: self.check(False, True, 'Allocate %s with malformed request (alloc_id=None) check (returns %s, should produce InvalidCapacity exception)'%(ttype,retval)) try: - self.dut_ref.deallocateCapacity(tAlloc) + self.dut_ref.deallocateCapacity(tAlloc) except CF.Device.InvalidCapacity, e: # Deallocating shouldn't be required if the allocation failed so we would expect this deallocation to be invalid pass - + def testFRONTEND_3_2_04(self): ''' RX_DIG 2.4 Verify failure on alloc with invalid group id (generate new uuid) ''' @@ -519,11 +518,11 @@ def testFRONTEND_3_2_04(self): else: self.check(False, retval, 'Allocate %s with invalid GROUP_ID check'%(ttype)) try: - self.dut_ref.deallocateCapacity(tAlloc) + self.dut_ref.deallocateCapacity(tAlloc) except CF.Device.InvalidCapacity, e: # Deallocating shouldn't be required if the allocation failed so we would expect this deallocation to be invalid pass - + def testFRONTEND_3_2_05(self): ''' RX_DIG 2.5 Verify failure on alloc with invalid rf flow id (generate new uuid) ''' @@ -538,12 +537,12 @@ def testFRONTEND_3_2_05(self): else: self.check(False, retval, 'Allocate %s with invalid RF_FLOW_ID check'%(ttype)) try: - self.dut_ref.deallocateCapacity(tAlloc) + self.dut_ref.deallocateCapacity(tAlloc) except CF.Device.InvalidCapacity, e: # Deallocating shouldn't be required if the allocation failed so we would expect this deallocation to be invalid pass - + def testFRONTEND_3_2_06(self): ''' RX_DIG 2.6 Allocate Listener via listener struct ''' @@ -556,7 +555,7 @@ def testFRONTEND_3_2_06(self): print 'RX_DIG 2.6 FAILURE - Allocate controller %s'%(ttype) pp(tuner) pp(tAlloc) - + tListener = self._generateListener(tuner) tListenerAlloc = self._generateListenerAlloc(tListener) if not self.check(self.dut_ref.allocateCapacity(tListenerAlloc), True, 'Allocate listener %s using listener allocation struct'%(ttype)) and DEBUG_LEVEL >= 4: @@ -566,9 +565,9 @@ def testFRONTEND_3_2_06(self): pp(tAlloc) pp(tListener) pp(tListenerAlloc) - + print "DEBUG -- done with allocations, now time to deallocate" - + # Deallocate listener using listener allocation struct try: self.dut_ref.deallocateCapacity(tListenerAlloc) @@ -576,10 +575,10 @@ def testFRONTEND_3_2_06(self): self.check(False, True, 'Deallocated listener %s using listener allocation struct without error'%(ttype)) else: self.check(True, True, 'Deallocated listener %s using listener allocation struct without error'%(ttype)) - + print "DEBUG -- done with deallocation of listener, now time to deallocate the controller" self.dut_ref.deallocateCapacity(tAlloc) - + def testFRONTEND_3_2_07(self): ''' RX_DIG 2.7 Allocate Listener via tuner allocation struct ''' @@ -610,7 +609,7 @@ def testFRONTEND_3_2_07(self): pp(tAlloc) pp(tListener) pp(tListenerAlloc) - + # Deallocate listener using tuner allocation struct try: self.dut_ref.deallocateCapacity(tListenerAlloc) @@ -619,7 +618,7 @@ def testFRONTEND_3_2_07(self): else: self.check(True, True, 'Deallocated listener %s using tuner allocation struct without error'%(ttype)) self.dut_ref.deallocateCapacity(tAlloc) - + def testFRONTEND_3_2_08(self): ''' RX_DIG 2.8 Verify failure on listener alloc w/o matching existing alloc id ''' @@ -642,13 +641,13 @@ def testFRONTEND_3_2_08(self): pp(tListener) pp(tListenerAlloc) try: - self.dut_ref.deallocateCapacity(tListenerAlloc) + self.dut_ref.deallocateCapacity(tListenerAlloc) except CF.Device.InvalidCapacity, e: # Deallocating shouldn't be required if the allocation failed so we would expect this deallocation to be invalid pass - + self.dut_ref.deallocateCapacity(tAlloc) - + def testFRONTEND_3_2_09(self): ''' RX_DIG 2.9 Verify failure on listener alloc w/o suitable existing channel (bad freq) ''' @@ -666,12 +665,12 @@ def testFRONTEND_3_2_09(self): tListenerAlloc = self._generateAlloc(tListener) self.check(self.dut_ref.allocateCapacity(tListenerAlloc), False, 'Allocate listener %s using tuner allocation struct without suitable controller %s check'%(ttype,ttype)) try: - self.dut_ref.deallocateCapacity(tListenerAlloc) + self.dut_ref.deallocateCapacity(tListenerAlloc) except CF.Device.InvalidCapacity, e: # Deallocating shouldn't be required if the allocation failed so we would expect this deallocation to be invalid pass self.dut_ref.deallocateCapacity(tAlloc) - + def testFRONTEND_3_2_10(self): ''' RX_DIG 2.10 Verify listener allocations are deallocated following deallocation of controlling allocation ''' @@ -691,50 +690,50 @@ def testFRONTEND_3_2_10(self): has_listener = self._tunerStatusHasAllocId(tListener['LISTENER_ID']) self.check(has_listener, False, 'Listener %s deallocated as result of controller %s deallocation'%(ttype,ttype)) try: - self.dut_ref.deallocateCapacity(tListenerAlloc) + self.dut_ref.deallocateCapacity(tListenerAlloc) except CF.Device.InvalidCapacity, e: # Deallocating shouldn't be required if the allocation failed so we would expect this deallocation to be invalid pass - + def testFRONTEND_3_2_11(self): ''' RX_DIG 2.11 allocate below minimum center frequency ''' tuner = self._generateRD() ttype='RX_DIGITIZER' low=DEVICE_INFO['RX_DIGITIZER']['CF_MIN'] - + tuner['CF'] = float(int(low / 2.0)) tAlloc = self._generateAlloc(tuner) self.check(self.dut_ref.allocateCapacity(tAlloc), False, 'Allocate %s below lowest frequency in range(%s < %s)'%(ttype,tuner['CF'],low)) try: - self.dut_ref.deallocateCapacity(tAlloc) + self.dut_ref.deallocateCapacity(tAlloc) except CF.Device.InvalidCapacity, e: # Deallocating shouldn't be required if the allocation failed so we would expect this deallocation to be invalid pass - + def testFRONTEND_3_2_12(self): ''' RX_DIG 2.12 allocate above maximum center frequency ''' tuner = self._generateRD() ttype='RX_DIGITIZER' high=DEVICE_INFO['RX_DIGITIZER']['CF_MAX'] - + tuner['CF'] = float(high * 2.0) tAlloc = self._generateAlloc(tuner) self.check(self.dut_ref.allocateCapacity(tAlloc), False, 'Allocate %s above highest frequency in range(%s > %s)'%(ttype,tuner['CF'],high)) try: - self.dut_ref.deallocateCapacity(tAlloc) + self.dut_ref.deallocateCapacity(tAlloc) except CF.Device.InvalidCapacity, e: # Deallocating shouldn't be required if the allocation failed so we would expect this deallocation to be invalid pass - + def testFRONTEND_3_2_13a(self): ''' RX_DIG 2.13a allocate at minimum center frequency ''' tuner = self._generateRD() ttype='RX_DIGITIZER' low=DEVICE_INFO['RX_DIGITIZER']['CF_MIN'] - + tuner['CF'] = float(low) tAlloc = self._generateAlloc(tuner) if not self.check(self.dut_ref.allocateCapacity(tAlloc), True, 'Allocate %s at lowest center frequency in range (%s)'%(ttype,low)) and DEBUG_LEVEL >= 4: @@ -743,11 +742,11 @@ def testFRONTEND_3_2_13a(self): pp(tuner) pp(tAlloc) try: - self.dut_ref.deallocateCapacity(tAlloc) + self.dut_ref.deallocateCapacity(tAlloc) except CF.Device.InvalidCapacity, e: # Deallocating shouldn't be required if the allocation failed so we would expect this deallocation to be invalid pass - + def testFRONTEND_3_2_13b(self): ''' RX_DIG 2.13b allocate just below minimum center frequency (partial coverage, should fail) ''' @@ -757,7 +756,7 @@ def testFRONTEND_3_2_13b(self): bw=DEVICE_INFO['RX_DIGITIZER']['BW_MIN'] sr=DEVICE_INFO['RX_DIGITIZER']['SR_MIN'] bw_sr = max(bw,sr) - print low,bw,sr + print low,bw,sr tuner['CF'] = float(low-bw_sr/2.0) tuner['BW'] = float(bw) tuner['SR'] = float(sr) @@ -768,18 +767,18 @@ def testFRONTEND_3_2_13b(self): pp(tuner) pp(tAlloc) try: - self.dut_ref.deallocateCapacity(tAlloc) + self.dut_ref.deallocateCapacity(tAlloc) except CF.Device.InvalidCapacity, e: # Deallocating shouldn't be required if the allocation failed so we would expect this deallocation to be invalid pass - + def testFRONTEND_3_2_14a(self): ''' RX_DIG 2.14a allocate at maximum center frequency ''' tuner = self._generateRD() ttype='RX_DIGITIZER' high=DEVICE_INFO['RX_DIGITIZER']['CF_MAX'] - + tuner['CF'] = float(high) tAlloc = self._generateAlloc(tuner) if not self.check(self.dut_ref.allocateCapacity(tAlloc), True, 'Allocate %s at highest center frequency in range(%s)'%(ttype,high)) and DEBUG_LEVEL >= 4: @@ -788,7 +787,7 @@ def testFRONTEND_3_2_14a(self): pp(tuner) pp(tAlloc) self.dut_ref.deallocateCapacity(tAlloc) - + def testFRONTEND_3_2_14b(self): ''' RX_DIG 2.14b allocate just above maximum center frequency (partial coverage, should fail) ''' @@ -798,7 +797,7 @@ def testFRONTEND_3_2_14b(self): bw=DEVICE_INFO['RX_DIGITIZER']['BW_MIN'] sr=DEVICE_INFO['RX_DIGITIZER']['SR_MIN'] bw_sr = max(bw,sr) - + tuner['CF'] = float(high+bw_sr/2.0) tuner['BW'] = float(bw) tuner['SR'] = float(sr) @@ -809,56 +808,56 @@ def testFRONTEND_3_2_14b(self): pp(tuner) pp(tAlloc) try: - self.dut_ref.deallocateCapacity(tAlloc) + self.dut_ref.deallocateCapacity(tAlloc) except CF.Device.InvalidCapacity, e: # Deallocating shouldn't be required if the allocation failed so we would expect this deallocation to be invalid pass - + def testFRONTEND_3_2_15(self): ''' RX_DIG 2.15 allocate with bandwidth = 0 (succeed) ''' ttype='RX_DIGITIZER' tuner = self._generateRD() - + tuner['BW'] = float(0.0) tAlloc = self._generateAlloc(tuner) self.check(self.dut_ref.allocateCapacity(tAlloc), True, 'Allocate %s without specifying bandwidth (BW=0)'%(ttype)) self.dut_ref.deallocateCapacity(tAlloc) - + def testFRONTEND_3_2_16(self): ''' RX_DIG 2.16 allocate with sample rate = 0 (succeed) ''' ttype='RX_DIGITIZER' tuner = self._generateRD() - + tuner['SR'] = float(0.0) tAlloc = self._generateAlloc(tuner) self.check(self.dut_ref.allocateCapacity(tAlloc), True, 'Allocate %s without specifying sample rate (SR=0)'%(ttype)) self.dut_ref.deallocateCapacity(tAlloc) - + def testFRONTEND_3_2_17(self): ''' RX_DIG 2.17 allocate below minimum bandwidth capable (succeed) ''' ttype='RX_DIGITIZER' tuner = self._generateRD() low=DEVICE_INFO['RX_DIGITIZER']['BW_MIN'] - + tuner['BW'] = float(int(low / 1.333333333)) tuner['SR'] = float(0) tAlloc = self._generateAlloc(tuner) self.check(self.dut_ref.allocateCapacity(tAlloc), True, 'Allocate %s below lowest bandwidth in range(%s < %s)'%(ttype,tuner['BW'],low)) self.dut_ref.deallocateCapacity(tAlloc) - + def testFRONTEND_3_2_18(self): ''' RX_DIG 2.18 allocate above maximum bandwidth capable (fail) ''' ttype='RX_DIGITIZER' tuner = self._generateRD() high=DEVICE_INFO['RX_DIGITIZER']['BW_MAX'] - + if self.check(high, 0, 'Upper bandwidth range set to 0, cannot test above highest bandwidth', silentFailure=True, successMsg='info'): return - + tuner['BW'] = float(high * 2.0) tuner['SR'] = float(0) tAlloc = self._generateAlloc(tuner) @@ -874,21 +873,21 @@ def testFRONTEND_3_2_18(self): print 'END DEBUG - failed max bw alloc test' ''' try: - self.dut_ref.deallocateCapacity(tAlloc) + self.dut_ref.deallocateCapacity(tAlloc) except CF.Device.InvalidCapacity, e: # Deallocating shouldn't be required if the allocation failed so we would expect this deallocation to be invalid pass - + def testFRONTEND_3_2_19(self): ''' RX_DIG 2.19 allocate outside of bandwidth tolerance (fail) ''' ttype='RX_DIGITIZER' tuner = self._generateRD() low=DEVICE_INFO['RX_DIGITIZER']['BW_MIN'] - + if self.check(low, 0, 'Lower bandwidth range set to 0, cannot test tolerance below lowest bandwidth', silentFailure=True, successMsg='info'): return - + tuner['BW'] = float(int(low / 2.0)) tuner['BW_TOLERANCE'] = float(10.0) tuner['SR'] = float(0) @@ -905,48 +904,48 @@ def testFRONTEND_3_2_19(self): print 'END DEBUG - failed outside bw tolerance test' ''' try: - self.dut_ref.deallocateCapacity(tAlloc) + self.dut_ref.deallocateCapacity(tAlloc) except CF.Device.InvalidCapacity, e: # Deallocating shouldn't be required if the allocation failed so we would expect this deallocation to be invalid pass - + def testFRONTEND_3_2_20(self): ''' RX_DIG 2.20 allocate below minimum sample rate capable (succeed) ''' ttype='RX_DIGITIZER' tuner = self._generateRD() low=DEVICE_INFO['RX_DIGITIZER']['SR_MIN'] - + tuner['SR'] = float(int(low / 1.333333333)) tuner['BW'] = float(0) tAlloc = self._generateAlloc(tuner) self.check(self.dut_ref.allocateCapacity(tAlloc), True, 'Allocate %s below lowest sample rate in range(%s < %s)'%(ttype,tuner['SR'],low)) self.dut_ref.deallocateCapacity(tAlloc) - + def testFRONTEND_3_2_21(self): ''' RX_DIG 2.21 allocate above maximum sample rate capable (fail) ''' ttype='RX_DIGITIZER' tuner = self._generateRD() high=DEVICE_INFO['RX_DIGITIZER']['SR_MAX'] - + tuner['SR'] = float(high * 2.0) tuner['BW'] = float(0) tAlloc = self._generateAlloc(tuner) self.check(self.dut_ref.allocateCapacity(tAlloc), False, 'Allocate %s above highest sample rate in range(%s > %s)'%(ttype,tuner['SR'],high)) try: - self.dut_ref.deallocateCapacity(tAlloc) + self.dut_ref.deallocateCapacity(tAlloc) except CF.Device.InvalidCapacity, e: # Deallocating shouldn't be required if the allocation failed so we would expect this deallocation to be invalid pass - + def testFRONTEND_3_2_22(self): ''' RX_DIG 2.22 allocate outside of sample rate tolerance (fail) ''' ttype='RX_DIGITIZER' tuner = self._generateRD() low=DEVICE_INFO['RX_DIGITIZER']['SR_MIN'] - + tuner['SR'] = float(int(low / 2.0)) tuner['SR_TOLERANCE'] = float(10.0) tuner['BW'] = float(0) @@ -963,22 +962,22 @@ def testFRONTEND_3_2_22(self): print 'END DEBUG - failed outside sr tolerance test' ''' try: - self.dut_ref.deallocateCapacity(tAlloc) + self.dut_ref.deallocateCapacity(tAlloc) except CF.Device.InvalidCapacity, e: # Deallocating shouldn't be required if the allocation failed so we would expect this deallocation to be invalid pass - + def testFRONTEND_3_3_01(self): ''' RX_DIG 3.1 Verify connection to Tuner port ''' port_name = 'DigitalTuner_in' tuner_control = self.dut.getPort('DigitalTuner_in') tuner_control._narrow(FRONTEND.FrontendTuner) - + # Verify connection to Tuner port self.check(tuner_control != None, True, 'Can get %s port'%(port_name)) self.check(CORBA.is_nil(tuner_control), False, 'Port reference is not nil') - + def testFRONTEND_3_3_02(self): ''' RX_DIG 3.2 Verify digital tuner port functions exist ''' @@ -986,13 +985,13 @@ def testFRONTEND_3_3_02(self): tuner_control = self.dut.getPort('DigitalTuner_in') tuner_control._narrow(FRONTEND.FrontendTuner) function_list = self.digital_tuner_idl - + for attr in function_list: try: self.check(callable(getattr(tuner_control,attr)), True, '%s port has function %s'%(port_name,attr)) except AttributeError, e: self.check(False, True, '%s port has function %s'%(port_name,attr)) - + def testFRONTEND_3_3_03(self): ''' RX_DIG 3.3 Verify digital tuner port getTunerType function ''' @@ -1000,17 +999,17 @@ def testFRONTEND_3_3_03(self): tuner_control = self.dut.getPort('DigitalTuner_in') tuner_control._narrow(FRONTEND.FrontendTuner) controller = self._generateRD() - + # make allocations controller_id = controller['ALLOC_ID'] controller_alloc = self._generateAlloc(controller) self.check(self.dut_ref.allocateCapacity(controller_alloc),True,'ERROR -- could not allocate controller',throwOnFailure=True,silentSuccess=True) - + try: status_val = self._getTunerStatusProp(controller_id, 'FRONTEND::tuner_status::tuner_type') except KeyError: status_val = None - + try: resp = tuner_control.getTunerType(controller_id) except FRONTEND.NotSupportedException: @@ -1023,9 +1022,9 @@ def testFRONTEND_3_3_03(self): self.check(resp, 'RX_DIGITIZER', '%s.getTunerType return value is correct for RX_DIGITIZER'%(port_name)) if status_val!=None: self.check(resp, status_val, '%s.getTunerType matches frontend tuner status prop'%(port_name)) - + self.dut_ref.deallocateCapacity(controller_alloc) - + def testFRONTEND_3_3_04(self): ''' RX_DIG 3.4 Verify digital tuner port getTunerDeviceControl function w/ controller ''' @@ -1033,12 +1032,12 @@ def testFRONTEND_3_3_04(self): tuner_control = self.dut.getPort('DigitalTuner_in') tuner_control._narrow(FRONTEND.FrontendTuner) controller = self._generateRD() - + # make allocations controller_id = controller['ALLOC_ID'] controller_alloc = self._generateAlloc(controller) self.check(self.dut_ref.allocateCapacity(controller_alloc),True,'%s.getTunerDeviceControl(controller_id) ERROR -- could not allocate controller'%(port_name),throwOnFailure=True,silentSuccess=True) - + try: resp = tuner_control.getTunerDeviceControl(controller_id) except FRONTEND.NotSupportedException: @@ -1049,20 +1048,20 @@ def testFRONTEND_3_3_04(self): self.check(type(resp), bool, '%s.getTunerDeviceControl(controller_id) has correct return type'%(port_name)) self.check(resp in [True,False], True, '%s.getTunerDeviceControl(controller_id) return value is within expected results'%(port_name)) self.check(resp, True, '%s.getTunerDeviceControl(controller_id) return True for controller alloc_id'%(port_name)) - + self.dut_ref.deallocateCapacity(controller_alloc) - + def testFRONTEND_3_3_05(self): ''' RX_DIG 3.5 Verify digital tuner port getTunerDeviceControl function w/ listener ''' port_name = 'DigitalTuner_in' tuner_control = self.dut.getPort('DigitalTuner_in') tuner_control._narrow(FRONTEND.FrontendTuner) - + controller = self._generateRD() pp(controller) listener = self._generateListener(controller) - + # make allocations controller_id = controller['ALLOC_ID'] controller_alloc = self._generateAlloc(controller) @@ -1070,7 +1069,7 @@ def testFRONTEND_3_3_05(self): listener_id = listener['LISTENER_ID'] listener_alloc = self._generateListenerAlloc(listener) self.check(self.dut_ref.allocateCapacity(listener_alloc),True,'%s.getTunerDeviceControl(listener_id) ERROR -- could not allocate listener'%(port_name),throwOnFailure=True,silentSuccess=True) - + try: resp = tuner_control.getTunerDeviceControl(listener_id) except FRONTEND.NotSupportedException: @@ -1081,10 +1080,10 @@ def testFRONTEND_3_3_05(self): self.check(type(resp), bool, '%s.getTunerDeviceControl(listener_id) has correct return type'%(port_name)) self.check(resp in [True,False], True, '%s.getTunerDeviceControl(listener_id) return value is within expected results'%(port_name)) self.check(resp, False, '%s.getTunerDeviceControl(listener_id) returns False for listener alloc_id'%(port_name)) - + self.dut_ref.deallocateCapacity(listener_alloc) self.dut_ref.deallocateCapacity(controller_alloc) - + def testFRONTEND_3_3_06(self): ''' RX_DIG 3.6 Verify digital tuner port getTunerGroupId function ''' @@ -1092,17 +1091,17 @@ def testFRONTEND_3_3_06(self): tuner_control = self.dut.getPort('DigitalTuner_in') tuner_control._narrow(FRONTEND.FrontendTuner) controller = self._generateRD() - + # make allocations controller_id = controller['ALLOC_ID'] controller_alloc = self._generateAlloc(controller) self.check(self.dut_ref.allocateCapacity(controller_alloc),True,'ERROR -- could not allocate controller',throwOnFailure=True,silentSuccess=True) - + try: status_val = self._getTunerStatusProp(controller_id, 'FRONTEND::tuner_status::group_id') except KeyError: status_val = None - + try: resp = tuner_control.getTunerGroupId(controller_id) except FRONTEND.NotSupportedException: @@ -1117,9 +1116,9 @@ def testFRONTEND_3_3_06(self): print resp print status_val self.check(resp, status_val, '%s.getTunerGroupId matches frontend tuner status prop'%(port_name)) - + self.dut_ref.deallocateCapacity(controller_alloc) - + def testFRONTEND_3_3_07(self): ''' RX_DIG 3.7 Verify digital tuner port getTunerRfFlowId function ''' @@ -1127,17 +1126,17 @@ def testFRONTEND_3_3_07(self): tuner_control = self.dut.getPort('DigitalTuner_in') tuner_control._narrow(FRONTEND.FrontendTuner) controller = self._generateRD() - + # make allocations controller_id = controller['ALLOC_ID'] controller_alloc = self._generateAlloc(controller) self.check(self.dut_ref.allocateCapacity(controller_alloc),True,'ERROR -- could not allocate controller',throwOnFailure=True,silentSuccess=True) - + try: status_val = self._getTunerStatusProp(controller_id, 'FRONTEND::tuner_status::rf_flow_id') except KeyError: status_val = None - + try: resp = tuner_control.getTunerRfFlowId(controller_id) except FRONTEND.NotSupportedException: @@ -1152,9 +1151,9 @@ def testFRONTEND_3_3_07(self): print resp print status_val self.check(resp, status_val, '%s.getTunerRfFlowId matches frontend tuner status prop'%(port_name)) - + self.dut_ref.deallocateCapacity(controller_alloc) - + def testFRONTEND_3_3_08(self): ''' RX_DIG 3.8 Verify digital tuner port getTunerCenterFrequency function ''' @@ -1162,17 +1161,17 @@ def testFRONTEND_3_3_08(self): tuner_control = self.dut.getPort('DigitalTuner_in') tuner_control._narrow(FRONTEND.FrontendTuner) controller = self._generateRD() - + # make allocations controller_id = controller['ALLOC_ID'] controller_alloc = self._generateAlloc(controller) self.check(self.dut_ref.allocateCapacity(controller_alloc),True,'ERROR -- could not allocate controller',throwOnFailure=True,silentSuccess=True) - + try: status_val = self._getTunerStatusProp(controller_id, 'FRONTEND::tuner_status::center_frequency') except KeyError: status_val = None - + try: resp = tuner_control.getTunerCenterFrequency(controller_id) except FRONTEND.NotSupportedException: @@ -1187,9 +1186,9 @@ def testFRONTEND_3_3_08(self): print resp print status_val self.checkAlmostEqual(resp, status_val, '%s.getTunerCenterFrequency matches frontend tuner status prop'%(port_name),places=0) - + self.dut_ref.deallocateCapacity(controller_alloc) - + def testFRONTEND_3_3_09(self): ''' RX_DIG 3.9 Verify digital tuner port getTunerBandwidth function ''' @@ -1197,17 +1196,17 @@ def testFRONTEND_3_3_09(self): tuner_control = self.dut.getPort('DigitalTuner_in') tuner_control._narrow(FRONTEND.FrontendTuner) controller = self._generateRD() - + # make allocations controller_id = controller['ALLOC_ID'] controller_alloc = self._generateAlloc(controller) self.check(self.dut_ref.allocateCapacity(controller_alloc),True,'ERROR -- could not allocate controller',throwOnFailure=True,silentSuccess=True) - + try: status_val = self._getTunerStatusProp(controller_id, 'FRONTEND::tuner_status::bandwidth') except KeyError: status_val = None - + # getTunerBandwidth # double: >= 0? try: @@ -1221,9 +1220,9 @@ def testFRONTEND_3_3_09(self): self.check(resp >= 0.0, True, '%s.getTunerBandwidth return value is within expected results'%(port_name)) if status_val!=None: self.checkAlmostEqual(resp, status_val, '%s.getTunerBandwidth matches frontend tuner status prop'%(port_name),places=0) - + self.dut_ref.deallocateCapacity(controller_alloc) - + def testFRONTEND_3_3_10(self): ''' RX_DIG 3.10 Verify digital tuner port getTunerOutputSampleRate function ''' @@ -1231,17 +1230,17 @@ def testFRONTEND_3_3_10(self): tuner_control = self.dut.getPort('DigitalTuner_in') tuner_control._narrow(FRONTEND.FrontendTuner) controller = self._generateRD() - + # make allocations controller_id = controller['ALLOC_ID'] controller_alloc = self._generateAlloc(controller) self.check(self.dut_ref.allocateCapacity(controller_alloc),True,'ERROR -- could not allocate controller',throwOnFailure=True,silentSuccess=True) - + try: status_val = self._getTunerStatusProp(controller_id, 'FRONTEND::tuner_status::sample_rate') except KeyError: status_val = None - + try: resp = tuner_control.getTunerOutputSampleRate(controller_id) except FRONTEND.NotSupportedException: @@ -1253,9 +1252,9 @@ def testFRONTEND_3_3_10(self): self.check(resp >= 0.0, True, '%s.getTunerOutputSampleRate return value is within expected results'%(port_name)) if status_val!=None: self.checkAlmostEqual(resp, status_val, '%s.getTunerOutputSampleRate matches frontend tuner status prop'%(port_name),places=0) - + self.dut_ref.deallocateCapacity(controller_alloc) - + def testFRONTEND_3_3_11(self): ''' RX_DIG 3.11 Verify digital tuner port getTunerAgcEnable function ''' @@ -1263,17 +1262,17 @@ def testFRONTEND_3_3_11(self): tuner_control = self.dut.getPort('DigitalTuner_in') tuner_control._narrow(FRONTEND.FrontendTuner) controller = self._generateRD() - + # make allocations controller_id = controller['ALLOC_ID'] controller_alloc = self._generateAlloc(controller) self.check(self.dut_ref.allocateCapacity(controller_alloc),True,'ERROR -- could not allocate controller',throwOnFailure=True,silentSuccess=True) - + try: status_val = self._getTunerStatusProp(controller_id, 'FRONTEND::tuner_status::agc') except KeyError: status_val = None - + try: resp = tuner_control.getTunerAgcEnable(controller_id) except FRONTEND.NotSupportedException: @@ -1285,9 +1284,9 @@ def testFRONTEND_3_3_11(self): self.check(resp in [True,False], True, '%s.getTunerAgcEnable return value is within expected results'%(port_name)) if status_val!=None: self.check(resp, status_val, '%s.getTunerAgcEnable matches frontend tuner status prop'%(port_name)) - + self.dut_ref.deallocateCapacity(controller_alloc) - + def testFRONTEND_3_3_12(self): ''' RX_DIG 3.12 Verify digital tuner port getTunerGain function ''' @@ -1295,17 +1294,17 @@ def testFRONTEND_3_3_12(self): tuner_control = self.dut.getPort('DigitalTuner_in') tuner_control._narrow(FRONTEND.FrontendTuner) controller = self._generateRD() - + # make allocations controller_id = controller['ALLOC_ID'] controller_alloc = self._generateAlloc(controller) self.check(self.dut_ref.allocateCapacity(controller_alloc),True,'ERROR -- could not allocate controller',throwOnFailure=True,silentSuccess=True) - + try: status_val = self._getTunerStatusProp(controller_id, 'FRONTEND::tuner_status::gain') except KeyError: status_val = None - + try: resp = tuner_control.getTunerGain(controller_id) except FRONTEND.NotSupportedException: @@ -1317,9 +1316,9 @@ def testFRONTEND_3_3_12(self): self.check(type(resp), float, '%s.getTunerGain return value is within expected results'%(port_name)) if status_val!=None: self.checkAlmostEqual(resp, status_val, '%s.getTunerGain matches frontend tuner status prop'%(port_name),places=2) - + self.dut_ref.deallocateCapacity(controller_alloc) - + def testFRONTEND_3_3_13(self): ''' RX_DIG 3.13 Verify digital tuner port getTunerReferenceSource function ''' @@ -1327,17 +1326,17 @@ def testFRONTEND_3_3_13(self): tuner_control = self.dut.getPort('DigitalTuner_in') tuner_control._narrow(FRONTEND.FrontendTuner) controller = self._generateRD() - + # make allocations controller_id = controller['ALLOC_ID'] controller_alloc = self._generateAlloc(controller) self.check(self.dut_ref.allocateCapacity(controller_alloc),True,'ERROR -- could not allocate controller',throwOnFailure=True,silentSuccess=True) - + try: status_val = self._getTunerStatusProp(controller_id, 'FRONTEND::tuner_status::reference_source') except KeyError: status_val = None - + try: resp = tuner_control.getTunerReferenceSource(controller_id) except FRONTEND.NotSupportedException: @@ -1349,9 +1348,9 @@ def testFRONTEND_3_3_13(self): self.check(resp in [0,1], True, '%s.getTunerReferenceSource return value within expected results'%(port_name)) if status_val!=None: self.check(resp, status_val, '%s.getTunerReferenceSource matches frontend tuner status prop'%(port_name)) - + self.dut_ref.deallocateCapacity(controller_alloc) - + def testFRONTEND_3_3_14(self): ''' RX_DIG 3.14 Verify digital tuner port getTunerEnable function ''' @@ -1359,17 +1358,17 @@ def testFRONTEND_3_3_14(self): tuner_control = self.dut.getPort('DigitalTuner_in') tuner_control._narrow(FRONTEND.FrontendTuner) controller = self._generateRD() - + # make allocations controller_id = controller['ALLOC_ID'] controller_alloc = self._generateAlloc(controller) self.check(self.dut_ref.allocateCapacity(controller_alloc),True,'ERROR -- could not allocate controller',throwOnFailure=True,silentSuccess=True) - + try: status_val = self._getTunerStatusProp(controller_id, 'FRONTEND::tuner_status::enabled') except KeyError: status_val = None - + try: resp = tuner_control.getTunerEnable(controller_id) except FRONTEND.NotSupportedException: @@ -1381,9 +1380,9 @@ def testFRONTEND_3_3_14(self): self.check(resp in [True,False], True, '%s.getTunerEnable return value is within expected results'%(port_name)) if status_val!=None: self.check(resp, status_val, '%s.getTunerEnable matches frontend tuner status prop'%(port_name)) - + self.dut_ref.deallocateCapacity(controller_alloc) - + def testFRONTEND_3_3_15(self): ''' RX_DIG 3.15 Verify digital tuner port getTunerStatus function ''' @@ -1391,18 +1390,18 @@ def testFRONTEND_3_3_15(self): tuner_control = self.dut.getPort('DigitalTuner_in') tuner_control._narrow(FRONTEND.FrontendTuner) controller = self._generateRD() - + # make allocations controller_id = controller['ALLOC_ID'] controller_alloc = self._generateAlloc(controller) self.check(self.dut_ref.allocateCapacity(controller_alloc),True,'ERROR -- could not allocate controller',throwOnFailure=True,silentSuccess=True) - + try: status_val = self._getTunerStatusProp(controller_id) except KeyError: status_val = None props_type = type(properties.props_from_dict({})) - + try: resp = tuner_control.getTunerStatus(controller_id) except FRONTEND.NotSupportedException: @@ -1420,18 +1419,18 @@ def testFRONTEND_3_3_15(self): print resp print status_val self.check(resp, status_val, '%s.getTunerStatus matches frontend tuner status prop'%(port_name)) - + self.dut_ref.deallocateCapacity(controller_alloc) - + # Verify setter functions # for each of the following, do bounds checking in addition to simple setter checking # setTunerCenterFrequency # setTunerBandwidth # setTunerOutputSampleRate # setTunerGain - + # Verify in-bounds retune - + def testFRONTEND_3_3_16(self): ''' RX_DIG 3.16 Verify digital tuner port setTunerCenterFrequency function in-bounds retune ''' @@ -1440,12 +1439,12 @@ def testFRONTEND_3_3_16(self): tuner_control = self.dut.getPort('DigitalTuner_in') tuner_control._narrow(FRONTEND.FrontendTuner) controller = self._generateRD() - + # make allocations controller_id = controller['ALLOC_ID'] controller_alloc = self._generateAlloc(controller) self.check(self.dut_ref.allocateCapacity(controller_alloc),True,'ERROR -- could not allocate controller',throwOnFailure=True,silentSuccess=True) - + #check Center Freq: tune to min, max, then orig try: cf = tuner_control.getTunerCenterFrequency(controller_id) @@ -1485,9 +1484,9 @@ def testFRONTEND_3_3_16(self): self.checkAlmostEqual(tuner_info['CF_MAX'],tuner_control.getTunerCenterFrequency(controller_id),'In-bounds re-tune of frequency - tuned to maximum CF (%s)'%(tuner_info['CF_MAX']),places=0) tuner_control.setTunerCenterFrequency(controller_id, cf) self.checkAlmostEqual(cf,tuner_control.getTunerCenterFrequency(controller_id),'In-bounds re-tune of frequency - tuned back to original CF (%s)'%(cf),places=0) - + self.dut_ref.deallocateCapacity(controller_alloc) - + def testFRONTEND_3_3_17(self): ''' RX_DIG 3.17 Verify digital tuner port setTunerBandwidth function in-bounds retune ''' @@ -1496,12 +1495,12 @@ def testFRONTEND_3_3_17(self): tuner_control = self.dut.getPort('DigitalTuner_in') tuner_control._narrow(FRONTEND.FrontendTuner) controller = self._generateRD() - + # make allocations controller_id = controller['ALLOC_ID'] controller_alloc = self._generateAlloc(controller) self.check(self.dut_ref.allocateCapacity(controller_alloc),True,'ERROR -- could not allocate controller',throwOnFailure=True,silentSuccess=True) - + #Check Bandwidth: tune to min, max, then orig try: bw = tuner_control.getTunerBandwidth(controller_id) @@ -1541,24 +1540,24 @@ def testFRONTEND_3_3_17(self): self.checkAlmostEqual(tuner_info['BW_MAX'],tuner_control.getTunerBandwidth(controller_id),'In-bounds re-tune of bandwidth - set to maximum BW (%s)'%tuner_info['BW_MAX'],places=0) tuner_control.setTunerBandwidth(controller_id, bw) self.checkAlmostEqual(bw,tuner_control.getTunerBandwidth(controller_id),'In-bounds re-tune of bandwidth - set to original BW (%s)'%bw,places=0) - + self.dut_ref.deallocateCapacity(controller_alloc) - + def testFRONTEND_3_3_18(self): ''' RX_DIG 3.18 Verify digital tuner port setTunerOutputSampleRate function in-bounds retune ''' - + tuner_info=DEVICE_INFO['RX_DIGITIZER'] port_name = 'DigitalTuner_in' tuner_control = self.dut.getPort('DigitalTuner_in') tuner_control._narrow(FRONTEND.FrontendTuner) controller = self._generateRD() - + # make allocations controller_id = controller['ALLOC_ID'] controller_alloc = self._generateAlloc(controller) self.check(self.dut_ref.allocateCapacity(controller_alloc),True,'ERROR -- could not allocate controller',throwOnFailure=True,silentSuccess=True) - + #Check SR: tune to min, max, then orig try: sr = tuner_control.getTunerOutputSampleRate(controller_id) @@ -1594,28 +1593,28 @@ def testFRONTEND_3_3_18(self): raise else: self.checkAlmostEqual(tuner_info['SR_MIN'],tuner_control.getTunerOutputSampleRate(controller_id),'In-bounds re-tune of sample rate - set to minimum SR (%s)'%tuner_info['SR_MIN'],places=0) - tuner_control.setTunerOutputSampleRate(controller_id, tuner_info['SR_MAX']) + tuner_control.setTunerOutputSampleRate(controller_id, tuner_info['SR_MAX']) self.checkAlmostEqual(tuner_info['SR_MAX'],tuner_control.getTunerOutputSampleRate(controller_id),'In-bounds re-tune of sample rate - set to maximum SR (%s)'%tuner_info['SR_MAX'],places=0) - tuner_control.setTunerOutputSampleRate(controller_id, sr) + tuner_control.setTunerOutputSampleRate(controller_id, sr) self.checkAlmostEqual(sr,tuner_control.getTunerOutputSampleRate(controller_id),'In-bounds re-tune of sample rate - set to original SR (%s)'%sr,places=0) - + self.dut_ref.deallocateCapacity(controller_alloc) - + def testFRONTEND_3_3_19(self): ''' RX_DIG 3.19 Verify digital tuner port setTunerGain function in-bounds retune ''' - + tuner_info=DEVICE_INFO['RX_DIGITIZER'] port_name = 'DigitalTuner_in' tuner_control = self.dut.getPort('DigitalTuner_in') tuner_control._narrow(FRONTEND.FrontendTuner) controller = self._generateRD() - + # make allocations controller_id = controller['ALLOC_ID'] controller_alloc = self._generateAlloc(controller) self.check(self.dut_ref.allocateCapacity(controller_alloc),True,'ERROR -- could not allocate controller',throwOnFailure=True,silentSuccess=True) - + # check gain: set to min, max, then orig try: gain = tuner_control.getTunerGain(controller_id) @@ -1655,24 +1654,24 @@ def testFRONTEND_3_3_19(self): self.checkAlmostEqual(tuner_info['GAIN_MAX'],tuner_control.getTunerGain(controller_id),'In-bounds setting of gain - set to maximum gain (%s)'%tuner_info['GAIN_MAX'],places=2) tuner_control.setTunerGain(controller_id, gain) self.checkAlmostEqual(gain,tuner_control.getTunerGain(controller_id),'In-bounds setting of gain - set to original gain (%s)'%gain,places=2) - + self.dut_ref.deallocateCapacity(controller_alloc) - + def testFRONTEND_3_3_20(self): ''' RX_DIG 3.20 Verify digital tuner port setTunerCenterFrequency function out of bounds retune ''' - + tuner_info=DEVICE_INFO['RX_DIGITIZER'] port_name = 'DigitalTuner_in' tuner_control = self.dut.getPort('DigitalTuner_in') tuner_control._narrow(FRONTEND.FrontendTuner) controller = self._generateRD() - + # make allocations controller_id = controller['ALLOC_ID'] controller_alloc = self._generateAlloc(controller) self.check(self.dut_ref.allocateCapacity(controller_alloc),True,'ERROR -- could not allocate controller',throwOnFailure=True,silentSuccess=True) - + #Verify outside-bounds retune #check Center Freq: try: @@ -1701,25 +1700,25 @@ def testFRONTEND_3_3_20(self): tuner_control.setTunerCenterFrequency(controller_id, cf) except: pass - + self.dut_ref.deallocateCapacity(controller_alloc) - + def testFRONTEND_3_3_21(self): ''' RX_DIG 3.21 Verify digital tuner port setTunerBandwidth function out of bounds retune ''' - + tuner_info=DEVICE_INFO['RX_DIGITIZER'] port_name = 'DigitalTuner_in' tuner_control = self.dut.getPort('DigitalTuner_in') tuner_control._narrow(FRONTEND.FrontendTuner) controller = self._generateRD() - + # make allocations controller_id = controller['ALLOC_ID'] controller_alloc = self._generateAlloc(controller) self.check(self.dut_ref.allocateCapacity(controller_alloc),True,'ERROR -- could not allocate controller',throwOnFailure=True,silentSuccess=True) - - #Check Bandwidth + + #Check Bandwidth try: bw = tuner_control.getTunerBandwidth(controller_id) except FRONTEND.NotSupportedException: @@ -1760,24 +1759,24 @@ def testFRONTEND_3_3_21(self): tuner_control.setTunerBandwidth(controller_id, bw) except: pass - + self.dut_ref.deallocateCapacity(controller_alloc) - + def testFRONTEND_3_3_22(self): ''' RX_DIG 3.22 Verify digital tuner port setTunerOutputSampleRate function out of bounds retune ''' - + tuner_info=DEVICE_INFO['RX_DIGITIZER'] port_name = 'DigitalTuner_in' tuner_control = self.dut.getPort('DigitalTuner_in') tuner_control._narrow(FRONTEND.FrontendTuner) controller = self._generateRD() - + # make allocations controller_id = controller['ALLOC_ID'] controller_alloc = self._generateAlloc(controller) self.check(self.dut_ref.allocateCapacity(controller_alloc),True,'ERROR -- could not allocate controller',throwOnFailure=True,silentSuccess=True) - + #Check SR try: sr = tuner_control.getTunerOutputSampleRate(controller_id) @@ -1812,24 +1811,24 @@ def testFRONTEND_3_3_22(self): tuner_control.setTunerOutputSampleRate(controller_id, sr) except: pass - + self.dut_ref.deallocateCapacity(controller_alloc) - + def testFRONTEND_3_3_23(self): ''' RX_DIG 3.23 Verify digital tuner port setTunerGain function out of bounds retune ''' - + tuner_info=DEVICE_INFO['RX_DIGITIZER'] port_name = 'DigitalTuner_in' tuner_control = self.dut.getPort('DigitalTuner_in') tuner_control._narrow(FRONTEND.FrontendTuner) controller = self._generateRD() - + # make allocations controller_id = controller['ALLOC_ID'] controller_alloc = self._generateAlloc(controller) self.check(self.dut_ref.allocateCapacity(controller_alloc),True,'ERROR -- could not allocate controller',throwOnFailure=True,silentSuccess=True) - + #Check gain try: gain = tuner_control.getTunerGain(controller_id) @@ -1854,33 +1853,33 @@ def testFRONTEND_3_3_23(self): self.check(False, True,'Out-of-bounds setting of gain produces BadParameterException') new_gain = tuner_control.getTunerGain(controller_id) if not self.checkAlmostEqual(gain, new_gain,'Out-of-bounds setting of gain - gain unchanged',places=2): - + # DEBUG print 'DEBUG - out of bounds retune of gain incorrectly caused change in gain' print 'DEBUG - orig gain: %s new gain: %s tuned gain: %s'%(gain,new_gain,tuner_info['GAIN_MAX'] + abs(tuner_info['GAIN_MAX']-tuner_info['GAIN_MIN']) + 1) # end DEBUG - + try: tuner_control.setTunerGain(controller_id, gain) except: pass - + self.dut_ref.deallocateCapacity(controller_alloc) - + def testFRONTEND_3_3_24(self): ''' RX_DIG 3.24 Verify digital tuner port setTunerAgcEnable function ''' - + port_name = 'DigitalTuner_in' tuner_control = self.dut.getPort('DigitalTuner_in') tuner_control._narrow(FRONTEND.FrontendTuner) controller = self._generateRD() - + # make allocations controller_id = controller['ALLOC_ID'] controller_alloc = self._generateAlloc(controller) self.check(self.dut_ref.allocateCapacity(controller_alloc),True,'ERROR -- could not allocate controller',throwOnFailure=True,silentSuccess=True) - + # test changing values for the rest # setTunerAgcEnable try: @@ -1902,23 +1901,23 @@ def testFRONTEND_3_3_24(self): self.check(not orig,tuner_control.getTunerAgcEnable(controller_id),'setting agc enable -- set to new value') tuner_control.setTunerAgcEnable(controller_id, orig) self.check(orig,tuner_control.getTunerAgcEnable(controller_id),'setting agc enable -- set back to original value') - + self.dut_ref.deallocateCapacity(controller_alloc) - + def testFRONTEND_3_3_25(self): ''' RX_DIG 3.25 Verify digital tuner port setTunerReferenceSource function ''' - + port_name = 'DigitalTuner_in' tuner_control = self.dut.getPort('DigitalTuner_in') tuner_control._narrow(FRONTEND.FrontendTuner) controller = self._generateRD() - + # make allocations controller_id = controller['ALLOC_ID'] controller_alloc = self._generateAlloc(controller) self.check(self.dut_ref.allocateCapacity(controller_alloc),True,'ERROR -- could not allocate controller',throwOnFailure=True,silentSuccess=True) - + # setTunerReferenceSource try: orig = tuner_control.getTunerReferenceSource(controller_id) @@ -1939,23 +1938,23 @@ def testFRONTEND_3_3_25(self): self.check(int(not orig),tuner_control.getTunerReferenceSource(controller_id),'setting tuner reference source -- set to new value') tuner_control.setTunerReferenceSource(controller_id, orig) self.check(orig,tuner_control.getTunerReferenceSource(controller_id),'setting tuner reference source -- set back to original value') - + self.dut_ref.deallocateCapacity(controller_alloc) - + def testFRONTEND_3_3_26(self): ''' RX_DIG 3.26 Verify digital tuner port setTunerEnable function ''' - + port_name = 'DigitalTuner_in' tuner_control = self.dut.getPort('DigitalTuner_in') tuner_control._narrow(FRONTEND.FrontendTuner) controller = self._generateRD() - + # make allocations controller_id = controller['ALLOC_ID'] controller_alloc = self._generateAlloc(controller) self.check(self.dut_ref.allocateCapacity(controller_alloc),True,'ERROR -- could not allocate controller',throwOnFailure=True,silentSuccess=True) - + # setTunerEnable try: orig = tuner_control.getTunerEnable(controller_id) @@ -1976,24 +1975,24 @@ def testFRONTEND_3_3_26(self): self.check(not orig,tuner_control.getTunerEnable(controller_id),'setting tuner enable -- set to new value') tuner_control.setTunerEnable(controller_id, orig) self.check(orig,tuner_control.getTunerEnable(controller_id),'setting tuner enable -- set back to original value') - + self.dut_ref.deallocateCapacity(controller_alloc) - + def testFRONTEND_3_3_27(self): ''' RX_DIG 3.27 Verify digital tuner port getter functions w/ bad alloc id ''' - + port_name = 'DigitalTuner_in' tuner_control = self.dut.getPort('DigitalTuner_in') tuner_control._narrow(FRONTEND.FrontendTuner) controller = self._generateRD() function_list = self.digital_tuner_idl - + # make allocations controller_id = controller['ALLOC_ID'] controller_alloc = self._generateAlloc(controller) self.check(self.dut_ref.allocateCapacity(controller_alloc),True,'ERROR -- could not allocate controller',throwOnFailure=True,silentSuccess=True) - + # verify invalid alloc_id -> FrontendException bad_id = str(uuid.uuid4()) for attr in filter(lambda x: x.startswith('get'),function_list): @@ -2008,24 +2007,24 @@ def testFRONTEND_3_3_27(self): self.check(False,True,'%s.%s called with bad alloc_id (produces %s exception, should produce FrontendException)'%(port_name,attr,e.__class__.__name__)) else: self.check(False,True,'%s.%s called with bad alloc_id (does not produce exception, should produce FrontendException)'%(port_name,attr)) - + self.dut_ref.deallocateCapacity(controller_alloc) - + def testFRONTEND_3_3_28(self): ''' RX_DIG 3.28 Verify digital tuner port setTunerCenterFrequency function w/ bad alloc id ''' - + tuner_info=DEVICE_INFO['RX_DIGITIZER'] port_name = 'DigitalTuner_in' tuner_control = self.dut.getPort('DigitalTuner_in') tuner_control._narrow(FRONTEND.FrontendTuner) controller = self._generateRD() - + # make allocations controller_id = controller['ALLOC_ID'] controller_alloc = self._generateAlloc(controller) self.check(self.dut_ref.allocateCapacity(controller_alloc),True,'ERROR -- could not allocate controller',throwOnFailure=True,silentSuccess=True) - + # setTunerCenterFrequency bad_id = str(uuid.uuid4()) try: @@ -2038,24 +2037,24 @@ def testFRONTEND_3_3_28(self): self.check(False,True,'%s.setTunerCenterFrequency called with bad alloc_id (produces %s exception, should produce FrontendException)'%(port_name,e.__class__.__name__)) else: self.check(False,True,'%s.setTunerCenterFrequency called with bad alloc_id produces FrontendException (no exception)'%(port_name)) - + self.dut_ref.deallocateCapacity(controller_alloc) - + def testFRONTEND_3_3_29(self): ''' RX_DIG 3.29 Verify digital tuner port setTunerBandwidth function w/ bad alloc id ''' - + tuner_info=DEVICE_INFO['RX_DIGITIZER'] port_name = 'DigitalTuner_in' tuner_control = self.dut.getPort('DigitalTuner_in') tuner_control._narrow(FRONTEND.FrontendTuner) controller = self._generateRD() - + # make allocations controller_id = controller['ALLOC_ID'] controller_alloc = self._generateAlloc(controller) self.check(self.dut_ref.allocateCapacity(controller_alloc),True,'ERROR -- could not allocate controller',throwOnFailure=True,silentSuccess=True) - + # setTunerBandwidth bad_id = str(uuid.uuid4()) try: @@ -2068,24 +2067,24 @@ def testFRONTEND_3_3_29(self): self.check(False,True,'%s.setTunerBandwidth called with bad alloc_id (produces %s exception, should produce FrontendException)'%(port_name,e.__class__.__name__)) else: self.check(False,True,'%s.setTunerBandwidth called with bad alloc_id produces FrontendException (no exception)'%(port_name)) - + self.dut_ref.deallocateCapacity(controller_alloc) - + def testFRONTEND_3_3_30(self): ''' RX_DIG 3.30 Verify digital tuner port setTunerOutputSampleRate function w/ bad alloc id ''' - + tuner_info=DEVICE_INFO['RX_DIGITIZER'] port_name = 'DigitalTuner_in' tuner_control = self.dut.getPort('DigitalTuner_in') tuner_control._narrow(FRONTEND.FrontendTuner) controller = self._generateRD() - + # make allocations controller_id = controller['ALLOC_ID'] controller_alloc = self._generateAlloc(controller) self.check(self.dut_ref.allocateCapacity(controller_alloc),True,'ERROR -- could not allocate controller',throwOnFailure=True,silentSuccess=True) - + # setTunerOutputSampleRate bad_id = str(uuid.uuid4()) try: @@ -2098,24 +2097,24 @@ def testFRONTEND_3_3_30(self): self.check(False,True,'%s.setTunerOutputSampleRate called with bad alloc_id (produces %s exception, should produce FrontendException)'%(port_name,e.__class__.__name__)) else: self.check(False,True,'%s.setTunerOutputSampleRate called with bad alloc_id produces FrontendException (no exception)'%(port_name)) - + self.dut_ref.deallocateCapacity(controller_alloc) - + def testFRONTEND_3_3_31(self): ''' RX_DIG 3.31 Verify digital tuner port setTunerGain function w/ bad alloc id ''' - + tuner_info=DEVICE_INFO['RX_DIGITIZER'] port_name = 'DigitalTuner_in' tuner_control = self.dut.getPort('DigitalTuner_in') tuner_control._narrow(FRONTEND.FrontendTuner) controller = self._generateRD() - + # make allocations controller_id = controller['ALLOC_ID'] controller_alloc = self._generateAlloc(controller) self.check(self.dut_ref.allocateCapacity(controller_alloc),True,'ERROR -- could not allocate controller',throwOnFailure=True,silentSuccess=True) - + # setTunerGain bad_id = str(uuid.uuid4()) try: @@ -2128,23 +2127,23 @@ def testFRONTEND_3_3_31(self): self.check(False,True,'%s.setTunerGain called with bad alloc_id (produces %s exception, should produce FrontendException)'%(port_name,e.__class__.__name__)) else: self.check(False,True,'%s.setTunerGain called with bad alloc_id produces FrontendException (no exception)'%(port_name)) - + self.dut_ref.deallocateCapacity(controller_alloc) - + def testFRONTEND_3_3_32(self): ''' RX_DIG 3.32 Verify digital tuner port setTunerAgcEnable function w/ bad alloc id ''' - + port_name = 'DigitalTuner_in' tuner_control = self.dut.getPort('DigitalTuner_in') tuner_control._narrow(FRONTEND.FrontendTuner) controller = self._generateRD() - + # make allocations controller_id = controller['ALLOC_ID'] controller_alloc = self._generateAlloc(controller) self.check(self.dut_ref.allocateCapacity(controller_alloc),True,'ERROR -- could not allocate controller',throwOnFailure=True,silentSuccess=True) - + # setTunerAgcEnable bad_id = str(uuid.uuid4()) try: @@ -2157,23 +2156,23 @@ def testFRONTEND_3_3_32(self): self.check(False,True,'%s.setTunerAgcEnable called with bad alloc_id (produces %s exception, should produce FrontendException)'%(port_name,e.__class__.__name__)) else: self.check(False,True,'%s.setTunerAgcEnable called with bad alloc_id produces FrontendException (no exception)'%(port_name)) - + self.dut_ref.deallocateCapacity(controller_alloc) - + def testFRONTEND_3_3_33(self): ''' RX_DIG 3.33 Verify digital tuner port setTunerReferenceSource function w/ bad alloc id ''' - + port_name = 'DigitalTuner_in' tuner_control = self.dut.getPort('DigitalTuner_in') tuner_control._narrow(FRONTEND.FrontendTuner) controller = self._generateRD() - + # make allocations controller_id = controller['ALLOC_ID'] controller_alloc = self._generateAlloc(controller) self.check(self.dut_ref.allocateCapacity(controller_alloc),True,'ERROR -- could not allocate controller',throwOnFailure=True,silentSuccess=True) - + # setTunerReferenceSource bad_id = str(uuid.uuid4()) try: @@ -2186,23 +2185,23 @@ def testFRONTEND_3_3_33(self): self.check(False,True,'%s.setTunerReferenceSource called with bad alloc_id (produces %s exception, should produce FrontendException)'%(port_name,e.__class__.__name__)) else: self.check(False,True,'%s.setTunerReferenceSource called with bad alloc_id produces FrontendException (no exception)'%(port_name)) - + self.dut_ref.deallocateCapacity(controller_alloc) - + def testFRONTEND_3_3_34(self): ''' RX_DIG 3.34 Verify digital tuner port setTunerEnable function w/ bad alloc id ''' - + port_name = 'DigitalTuner_in' tuner_control = self.dut.getPort('DigitalTuner_in') tuner_control._narrow(FRONTEND.FrontendTuner) controller = self._generateRD() - + # make allocations controller_id = controller['ALLOC_ID'] controller_alloc = self._generateAlloc(controller) self.check(self.dut_ref.allocateCapacity(controller_alloc),True,'ERROR -- could not allocate controller',throwOnFailure=True,silentSuccess=True) - + # setTunerEnable bad_id = str(uuid.uuid4()) try: @@ -2215,14 +2214,14 @@ def testFRONTEND_3_3_34(self): self.check(False,True,'%s.setTunerEnable called with bad alloc_id (produces %s exception, should produce FrontendException)'%(port_name,e.__class__.__name__)) else: self.check(False,True,'%s.setTunerEnable called with bad alloc_id produces FrontendException (no exception)'%(port_name)) - + self.dut_ref.deallocateCapacity(controller_alloc) - + # TODO - noseify def testFRONTEND_3_4_DataFlow(self): ''' RX_DIG 4 DataFlow ''' - + ttype='RX_DIGITIZER' controller = self._generateRD() #controller['CF'] = float(DEVICE_INFO[ttype]['CF_MIN'] + max(DEVICE_INFO[ttype]['BW_MIN'],DEVICE_INFO[ttype]['SR_MIN'])) @@ -2230,14 +2229,14 @@ def testFRONTEND_3_4_DataFlow(self): controller['SR'] = float(DEVICE_INFO[ttype]['SR_MIN']) listener1 = self._generateListener(controller) listener2 = self._generateListener(controller) - + tuner_control = self.dut.getPort('DigitalTuner_in') for port in self.dut.ports: if port._direction == 'Uses': comp_port_name = port.name comp_port_type = port._using.name self._testBULKIO(tuner_control,comp_port_name,comp_port_type,ttype,controller,listener1,listener2) - + def _testBULKIO(self,tuner_control,comp_port_name,comp_port_type,ttype,controller,listener1=None,listener2=None): if comp_port_type == 'dataSDDS': print 'WARNING - dataSDDS output port testing not supported' @@ -2253,9 +2252,9 @@ def _testBULKIO(self,tuner_control,comp_port_name,comp_port_type,ttype,controlle dataSink2_port_obj = dataSink2.getPort(self.port_map[comp_port_type]) dataSink3_port_obj = dataSink3.getPort(self.port_map[comp_port_type]) dataSink4_port_obj = dataSink4.getPort(self.port_map[comp_port_type]) - + #sb.start() - + # alloc a tuner controller['ALLOC_ID'] = "control:"+str(uuid.uuid4()) # unique for each loop tAlloc = self._generateAlloc(controller) @@ -2263,7 +2262,7 @@ def _testBULKIO(self,tuner_control,comp_port_name,comp_port_type,ttype,controlle pp(tAlloc) comp_port_obj.connectPort(dataSink1_port_obj, controller['ALLOC_ID']) self.dut_ref.allocateCapacity(tAlloc) - + # verify basic data flow print >> sys.stderr,'attempting to get data from tuner' for attempt in xrange(10): @@ -2273,7 +2272,7 @@ def _testBULKIO(self,tuner_control,comp_port_name,comp_port_type,ttype,controlle if len(data1)>0: break self.check(len(data1)>0,True,'%s: Received data from tuner allocation'%(comp_port_name)) - + # verify SRI #try: # status = properties.props_to_dict(tuner_control.getTunerStatus(controller['ALLOC_ID'])) @@ -2295,15 +2294,15 @@ def _testBULKIO(self,tuner_control,comp_port_name,comp_port_type,ttype,controlle chan_status = None else: chan_status = chan_status[0] - + sri1 = dataSink1.sri() print 'sri1',sri1 self.checkAlmostEqual(status['FRONTEND::tuner_status::sample_rate'], 1.0/sri1.xdelta, '%s: SRI xdelta has correct value'%(comp_port_name),places=0) - + #complex is an optional property but if it is present check that it matches sri. if 'FRONTEND::tuner_status::complex' in status: self.check(status['FRONTEND::tuner_status::complex'],sri1.mode,'%s: SRI mode has correct value'%(comp_port_name)) - + # verify SRI keywords keywords = properties.props_to_dict(sri1.keywords) if 'COL_RF' in keywords: @@ -2317,32 +2316,32 @@ def _testBULKIO(self,tuner_control,comp_port_name,comp_port_type,ttype,controlle self.checkAlmostEqual(status['FRONTEND::tuner_status::center_frequency'],keywords['COL_RF'],'%s: SRI keyword COL_RF has correct value'%(comp_port_name),places=0) else: self.check(False,True,'%s: SRI has COL_RF keyword'%(comp_port_name)) - + if 'CHAN_RF' in keywords: self.check(True,True,'%s: SRI has CHAN_RF keyword'%(comp_port_name)) self.checkAlmostEqual(status['FRONTEND::tuner_status::center_frequency'],keywords['CHAN_RF'],'%s: SRI keyword CHAN_RF has correct value'%(comp_port_name),places=0) else: self.check(False,True,'%s: SRI has CHAN_RF keyword'%(comp_port_name)) - + if 'FRONTEND::BANDWIDTH' in keywords: self.check(True,True,'%s: SRI has FRONTEND::BANDWIDTH keyword'%(comp_port_name)) if not self.checkAlmostEqual(status['FRONTEND::tuner_status::bandwidth'],keywords['FRONTEND::BANDWIDTH'],'%s: SRI keyword FRONTEND::BANDWIDTH has correct value'%(comp_port_name),places=0): self.checkAlmostEqual(status['FRONTEND::tuner_status::sample_rate'],keywords['FRONTEND::BANDWIDTH'],'%s: SRI keyword FRONTEND::BANDWIDTH has sample rate value'%(comp_port_name),places=0, silentFailure=True, successMsg='WARN') else: self.check(False,True,'%s: SRI has FRONTEND::BANDWIDTH keyword'%(comp_port_name)) - + if 'FRONTEND::RF_FLOW_ID' in keywords: self.check(True,True,'%s: SRI has FRONTEND::RF_FLOW_ID keyword'%(comp_port_name)) self.check(status['FRONTEND::tuner_status::rf_flow_id'],keywords['FRONTEND::RF_FLOW_ID'],'%s: SRI keyword FRONTEND::RF_FLOW_ID has correct value'%(comp_port_name)) else: self.check(False,True,'%s: SRI has FRONTEND::RF_FLOW_ID keyword'%(comp_port_name)) - + if 'FRONTEND::DEVICE_ID' in keywords: self.check(True,True,'%s: SRI has FRONTEND::DEVICE_ID keyword'%(comp_port_name)) #self.check(1,keywords['FRONTEND::DEVICE_ID'],'SRI keyword FRONTEND::DEVICE_ID has correct value') else: self.check(False,True,'%s: SRI has FRONTEND::DEVICE_ID keyword'%(comp_port_name)) - + # verify multi-out port bad_conn_id = "bad:"+str(uuid.uuid4()) comp_port_obj.connectPort(dataSink2_port_obj, bad_conn_id) @@ -2358,12 +2357,12 @@ def _testBULKIO(self,tuner_control,comp_port_name,comp_port_type,ttype,controlle sri2 = dataSink2.sri() print 'sri2',sri2 self.check(sri1.streamID==sri2.streamID,False,'%s: Did not receive correct SRI from tuner allocation with wrong alloc_id (multiport test)'%(comp_port_name)) - + if self.device_discovery[ttype] < 2: self.check(True,True,'%s: Cannot fully test multiport because only single %s tuner capability'%(comp_port_name,ttype),successMsg='info') else: pass # TODO - additional multiport tests here - + if listener1: # verify listener listener1 = self._generateListener(controller) # unique for each loop @@ -2371,7 +2370,7 @@ def _testBULKIO(self,tuner_control,comp_port_name,comp_port_type,ttype,controlle listenerAlloc1 = self._generateListenerAlloc(listener1) comp_port_obj.connectPort(dataSink3_port_obj, listener1['LISTENER_ID']) self.dut_ref.allocateCapacity(listenerAlloc1) - + for attempt in xrange(5): time.sleep(1.0) data3 = dataSink3.getData() @@ -2384,16 +2383,16 @@ def _testBULKIO(self,tuner_control,comp_port_name,comp_port_type,ttype,controlle sri3 = dataSink3.sri() print 'sri3',sri3 self.check(sri1.streamID==sri3.streamID,True,'%s: Received correct SRI from listener allocation'%(comp_port_name)) - + # verify EOS if listener2: listener2 = self._generateListener(controller) # unique for each loop listener2['LISTENER_ID'] = "listener2:"+listener2['LISTENER_ID'] listenerAlloc2 = self._generateListenerAlloc(listener2) comp_port_obj.connectPort(dataSink4_port_obj, listener2['LISTENER_ID']) - self.dut_ref.allocateCapacity(listenerAlloc2) + self.dut_ref.allocateCapacity(listenerAlloc2) time.sleep(1.0) - #for port_dict in port_list: + #for port_dict in port_list: #data4 = dataSink4.getData() self.dut_ref.deallocateCapacity(listenerAlloc1) self.check(dataSink3.eos(),True,'%s: Listener received EOS after deallocation of listener'%(comp_port_name)) @@ -2405,35 +2404,35 @@ def _testBULKIO(self,tuner_control,comp_port_name,comp_port_type,ttype,controlle # cleanup listener2 comp_port_obj.disconnectPort(listener2['LISTENER_ID']) try: - self.dut_ref.deallocateCapacity(listenerAlloc2) + self.dut_ref.deallocateCapacity(listenerAlloc2) except CF.Device.InvalidCapacity, e: # Deallocating shouldn't be required if the allocation failed so we would expect this deallocation to be invalid - pass + pass # cleanup listener1 comp_port_obj.disconnectPort(listener1['LISTENER_ID']) # cleanup controller comp_port_obj.disconnectPort(controller['ALLOC_ID']) comp_port_obj.disconnectPort(bad_conn_id) - + # TODO - noseify def testFRONTEND_3_5_TunerStatusProperties(self): ''' RX_DIG 5 TunerStatusProperties ''' #self.testReport.append('\nTest 3.5 - Tuner Status Properties') #self.getToBasicState() - + tuner_control = self.dut.getPort('DigitalTuner_in') tuner_control._narrow(FRONTEND.FrontendTuner) - + controller = self._generateRD() listener1 = self._generateListener(controller) listener2 = self._generateListener(controller) - + # make allocations controller_id = controller['ALLOC_ID'] controller_alloc = self._generateAlloc(controller) self.check(self.dut_ref.allocateCapacity(controller_alloc),True,'ERROR -- could not allocate controller',throwOnFailure=True,silentSuccess=True) - + listener1_id = listener1['LISTENER_ID'] listener1_alloc = self._generateListenerAlloc(listener1) retval = self.dut_ref.allocateCapacity(listener1_alloc) @@ -2447,7 +2446,7 @@ def testFRONTEND_3_5_TunerStatusProperties(self): if not retval: self.testReport.append('Could not allocate listener2 -- limited test') listener2 = None - + # Verify correct tuner status structure (fields, types) # check presence of tuner status property # check that it contains the required fields of correct data type @@ -2477,7 +2476,7 @@ def testFRONTEND_3_5_TunerStatusProperties(self): all_names = self.FE_tuner_status_fields_req.keys()+self.FE_tuner_status_fields_opt.keys() for name in filter(lambda x: x not in all_names,status.keys()): self.check(False, True, 'tuner_status has UNKNOWN field %s'%name, failureMsg='WARN') - + # Verify alloc_id_csv is populated after controller allocation try: status_val = self._getTunerStatusProp(controller_id,'FRONTEND::tuner_status::allocation_id_csv') @@ -2488,7 +2487,7 @@ def testFRONTEND_3_5_TunerStatusProperties(self): self.check(True, False, 'controller allocation id added to tuner status after allocation of controller (could not get tuner status prop)') else: self.check(controller_id, status_val.split(',')[0], 'controller allocation id added to tuner status after allocation of controller (must be first in CSV list)') - + # Verify tuner is enabled following allocation try: status_val = self._getTunerStatusProp(controller_id,'FRONTEND::tuner_status::enabled') @@ -2499,9 +2498,9 @@ def testFRONTEND_3_5_TunerStatusProperties(self): self.check(True, False, 'Tuner is enabled in tuner status after tuner allocation (could not get tuner status prop)') else: self.check(True, status_val, 'Tuner is enabled in tuner status after tuner allocation') - + if listener1: - # Verify listener allocation id is added after allocation of listener + # Verify listener allocation id is added after allocation of listener try: status_val = self._getTunerStatusProp(controller_id,'FRONTEND::tuner_status::allocation_id_csv') except KeyError: @@ -2511,7 +2510,7 @@ def testFRONTEND_3_5_TunerStatusProperties(self): self.check(True, False, 'listener allocation id added to tuner status after allocation of listener (could not get tuner status prop)') else: self.check(listener1_id in status_val.split(',')[1:], True, 'listener allocation id added to tuner status after allocation of listener (must not be first in CSV list)') - + if tuner_control: # Verify frequency prop try: @@ -2526,7 +2525,7 @@ def testFRONTEND_3_5_TunerStatusProperties(self): else: self.checkAlmostEqual(status_val, val, 'correct value for FRONTEND::tuner_status::center_frequency property',places=0) #setTunerCenterFrequency - + # Verify bandwidth prop try: val = tuner_control.getTunerBandwidth(controller_id) @@ -2540,7 +2539,7 @@ def testFRONTEND_3_5_TunerStatusProperties(self): else: self.checkAlmostEqual(status_val, val, 'correct value for FRONTEND::tuner_status::bandwidth property',places=0) #setTunerBandwidth - + # Verify sample rate prop try: val = tuner_control.getTunerOutputSampleRate(controller_id) @@ -2554,7 +2553,7 @@ def testFRONTEND_3_5_TunerStatusProperties(self): else: self.checkAlmostEqual(status_val, val, 'correct value for FRONTEND::tuner_status::sample_rate property',places=0) #setTunerOutputSampleRate - + # Verify group id prop try: val = tuner_control.getTunerGroupId(controller_id) @@ -2567,7 +2566,7 @@ def testFRONTEND_3_5_TunerStatusProperties(self): pass else: self.check(status_val, val, 'correct value for FRONTEND::tuner_status::group_id property') - + # Verify rf flow id prop try: val = tuner_control.getTunerRfFlowId(controller_id) @@ -2580,7 +2579,7 @@ def testFRONTEND_3_5_TunerStatusProperties(self): pass else: self.check(status_val, val, 'correct value for FRONTEND::tuner_status::rf_flow_id property') - + if listener1: # Verify listener allocation id is removed after deallocation of listener self.dut_ref.deallocateCapacity(listener1_alloc) @@ -2590,7 +2589,7 @@ def testFRONTEND_3_5_TunerStatusProperties(self): pass else: self.check(listener1_id in status_val, False, 'listener allocation id removed from tuner status after deallocation of listener') - + # Verify controller allocation id is removed after deallocation of controller self.dut_ref.deallocateCapacity(controller_alloc) try: @@ -2599,7 +2598,7 @@ def testFRONTEND_3_5_TunerStatusProperties(self): pass else: self.check(None, status, 'controller allocation id removed from tuner status after deallocation of controller') - + if listener2: # Verify listener allocation id is removed after deallocation of controller #self.dut_ref.deallocateCapacity(controllerAlloc) @@ -2638,7 +2637,7 @@ def check(self, A, B, message, throwOnFailure=False, silentFailure=False, silent self.getToShutdownState() self.assertFalse(failureMsg+'::'+message) return False # failure! - + def checkAlmostEqual(self, A, B, message, throwOnFailure=False, silentFailure=False, silentSuccess=False, indent_width=0, failureMsg='FAILURE', successMsg='ok', places=7): # successMsg suggestions: PASS, YES, ok, u'\u2714' (check mark) # failureMsg suggestions: FAIL, NO, u'\u2718' (x mark) @@ -2689,7 +2688,7 @@ def _buildRow(self, lhs, rhs, indent_width=0, filler='.', len_total=80, rhs_widt else: line2 = self._buildRow(lhs[idx:], rhs, indent_width, filler, len_total, rhs_width, depth=depth+1) return line1 + '\n' + line2 - + def _tunerStatusHasAllocId(self,alloc_id): props = self.dut.query([]) props = properties.props_to_dict(props) @@ -2697,7 +2696,7 @@ def _tunerStatusHasAllocId(self,alloc_id): if alloc_id in tuner['FRONTEND::tuner_status::allocation_id_csv'].split(','): return True return False - + def _findTunerStatusProps(match={},notmatch={}): ''' query latest props, find tuner status associated with key/value pairs in "match" dict where the key/value pairs of "notmatch" dict don't match @@ -2724,7 +2723,7 @@ def _findTunerStatusProps(match={},notmatch={}): tuners = [x for x in tuners if x not in bad] #tuners = filter(lambda x: x not in bad, tuners) return tuners - + def _getTunerStatusProp(self,alloc_id,name=None): ''' query latest props, find tuner status associated with alloc_id if name arg is specified, return the tuner status property of that name @@ -2739,7 +2738,7 @@ def _getTunerStatusProp(self,alloc_id,name=None): break else: return None - + if name!=None: try: return tuner[name] @@ -2747,7 +2746,7 @@ def _getTunerStatusProp(self,alloc_id,name=None): return None else: return tuner - + def _generateRD(self): #Pick a random set for CF,BW,SR and return value = {} @@ -2758,20 +2757,20 @@ def _generateRD(self): value['RF_FLOW_ID'] = '' value['GROUP_ID'] = '' value['CONTROL'] = True - + if (DEVICE_INFO['RX_DIGITIZER']['CF_MIN'] != DEVICE_INFO['RX_DIGITIZER']['CF_MAX']): #value['CF'] = float(random.randrange(DEVICE_INFO['RX_DIGITIZER']['CF_MIN'], DEVICE_INFO['RX_DIGITIZER']['CF_MAX'], 1.0e3)) value['CF'] = float(int(random.uniform(DEVICE_INFO['RX_DIGITIZER']['CF_MIN'], DEVICE_INFO['RX_DIGITIZER']['CF_MAX']))) else: value['CF'] = float(DEVICE_INFO['RX_DIGITIZER']['CF_MIN']) - + if (DEVICE_INFO['RX_DIGITIZER']['SR_MIN'] != DEVICE_INFO['RX_DIGITIZER']['SR_MAX']): #value['SR'] = float(random.randrange(DEVICE_INFO['RX_DIGITIZER']['SR_MIN'], DEVICE_INFO['RX_DIGITIZER']['SR_MAX'], 1.0e3)) value['SR'] = float(random.uniform(DEVICE_INFO['RX_DIGITIZER']['SR_MIN'], DEVICE_INFO['RX_DIGITIZER']['SR_MAX'])) else: value['SR'] = float(DEVICE_INFO['RX_DIGITIZER']['SR_MIN']) - - + + if (DEVICE_INFO['RX_DIGITIZER']['BW_MIN'] != DEVICE_INFO['RX_DIGITIZER']['BW_MAX']): #value['BW'] = float(random.randrange(DEVICE_INFO['RX_DIGITIZER']['BW_MIN'], DEVICE_INFO['RX_DIGITIZER']['BW_MAX'], 1.0e3)) #value['BW'] = float(random.uniform(DEVICE_INFO['RX_DIGITIZER']['BW_MIN'], DEVICE_INFO['RX_DIGITIZER']['BW_MAX'])) @@ -2794,7 +2793,7 @@ def _generateRD(self): def _generateListener(self, c): value = {} - value['LISTENER_ID'] = str(uuid.uuid4()) + value['LISTENER_ID'] = str(uuid.uuid4()) value['ALLOC_ID'] = c['ALLOC_ID'] return value @@ -2820,12 +2819,12 @@ def _generateAlloc(self, value): 'FRONTEND::tuner_allocation::rf_flow_id': value['RF_FLOW_ID'], }} return properties.props_from_dict(allocationPropDict) - - + + ######################################################### ## CODE FROM unit_test_helpers with @classmethod added ## ######################################################### - + def isMatch(prop, modes, kinds, actions): if prop.get_mode() == None: m = "readwrite" @@ -2865,7 +2864,7 @@ def isMatch(prop, modes, kinds, actions): return matchMode and matchKind and matchAction - + def getPropertySet(spd_file, kinds=("configure",), \ modes=("readwrite", "writeonly", "readonly"), \ action="external", \ @@ -2884,7 +2883,7 @@ def getPropertySet(spd_file, kinds=("configure",), \ # Simples for prop in prf.get_simple(): - if isMatch(prop, modes, kinds, (action,)): + if isMatch(prop, modes, kinds, (action,)): if prop.get_value() is not None: dt = properties.to_tc_value(prop.get_value(), prop.get_type()) elif not includeNil: @@ -2896,7 +2895,7 @@ def getPropertySet(spd_file, kinds=("configure",), \ # Simple Sequences for prop in prf.get_simplesequence(): - if isMatch(prop, modes, kinds, (action,)): + if isMatch(prop, modes, kinds, (action,)): if prop.get_values() is not None: seq = [] for v in prop.get_values().get_value(): @@ -2911,7 +2910,7 @@ def getPropertySet(spd_file, kinds=("configure",), \ # Structures for prop in prf.get_struct(): - if isMatch(prop, modes, kinds, (action,)): + if isMatch(prop, modes, kinds, (action,)): if prop.get_simple() is not None: fields = [] hasValue = False From 9ce94590c416bb57ff3f5aaadccab9b14bd8d29d Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 16 Mar 2017 16:03:11 -0400 Subject: [PATCH 0755/1644] CF-1710 Replace use of boost::function with new redhawk::callback class that provides similar functionality, but does not create unique symbols in libraries that prevent unloading --- .../cpp/include/bulkio/bulkio_in_port.h | 4 +- .../src/base/include/ossie/MessageInterface.h | 2 +- .../src/base/include/ossie/MessageSupplier.h | 2 +- .../base/include/ossie/PropertyInterface.h | 29 +- .../src/base/include/ossie/PropertySet_impl.h | 2 +- redhawk/src/base/include/ossie/callback.h | 963 ++++++++++++++++-- 6 files changed, 891 insertions(+), 111 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/include/bulkio/bulkio_in_port.h b/bulkioInterfaces/libsrc/cpp/include/bulkio/bulkio_in_port.h index aa254fb8e..44ca00b00 100644 --- a/bulkioInterfaces/libsrc/cpp/include/bulkio/bulkio_in_port.h +++ b/bulkioInterfaces/libsrc/cpp/include/bulkio/bulkio_in_port.h @@ -245,7 +245,7 @@ namespace bulkio { */ template inline void setNewStreamListener(Target target, Func func) { - ossie::bind(newStreamCallback, target, func); + newStreamCallback.assign(target, func); } /* @@ -313,7 +313,7 @@ namespace bulkio { // // Callback for notifications when new SRI streamID's are received // - boost::function newStreamCallback; + redhawk::callback newStreamCallback; // // List of SRI objects managed by StreamID diff --git a/redhawk/src/base/include/ossie/MessageInterface.h b/redhawk/src/base/include/ossie/MessageInterface.h index 8d1e0f8ad..f98b2e6ae 100644 --- a/redhawk/src/base/include/ossie/MessageInterface.h +++ b/redhawk/src/base/include/ossie/MessageInterface.h @@ -224,7 +224,7 @@ class MessageConsumerPort : public Port_Provides_base_impl class MessageCallbackImpl : public MessageCallback { public: - typedef boost::function CallbackFunc; + typedef redhawk::callback CallbackFunc; MessageCallbackImpl (const std::string& format, CallbackFunc func) : MessageCallback(format), diff --git a/redhawk/src/base/include/ossie/MessageSupplier.h b/redhawk/src/base/include/ossie/MessageSupplier.h index 711cbd0bf..6c984373a 100644 --- a/redhawk/src/base/include/ossie/MessageSupplier.h +++ b/redhawk/src/base/include/ossie/MessageSupplier.h @@ -89,7 +89,7 @@ class MessageSupplierPort : public redhawk::UsesPort any <<= *(reinterpret_cast(data)); } - typedef boost::function SerializerFunc; + typedef void (*SerializerFunc)(CORBA::Any&,const void*); void _beginMessageQueue(size_t count); void _queueMessage(const std::string& msgId, const char* format, const void* msgData, SerializerFunc serializer); diff --git a/redhawk/src/base/include/ossie/PropertyInterface.h b/redhawk/src/base/include/ossie/PropertyInterface.h index a6de6e58b..2512c21a1 100644 --- a/redhawk/src/base/include/ossie/PropertyInterface.h +++ b/redhawk/src/base/include/ossie/PropertyInterface.h @@ -282,10 +282,7 @@ class PropertyWrapper : public PropertyInterface template void setQuery (Target target, Func func) { - if (!isQueryable()) { - throw std::logic_error("property '" + id + "' is not queryable"); - } - ossie::bind(query_, target, func); + setQuery(QueryFunc(target, func)); } template @@ -300,10 +297,7 @@ class PropertyWrapper : public PropertyInterface template void setConfigure (Target target, Func func) { - if (!isConfigurable()) { - throw std::logic_error("property '" + id + "' is not configurable"); - } - ossie::bind(configure_, target, func); + setConfigure(ConfigureFunc(target, func)); } template @@ -312,7 +306,6 @@ class PropertyWrapper : public PropertyInterface pointerListeners_.add(func); } - template void addChangeListener (Target target, R (Base::*func)(A1*, A2*)) { @@ -355,10 +348,7 @@ class PropertyWrapper : public PropertyInterface template void setAllocator (Target target, Func func) { - if (!isAllocatable()) { - throw std::logic_error("property '" + id + "' is not allocatable"); - } - ossie::bind(allocator_, target, func); + setAllocator(AllocateFunc(target, func)); } template @@ -373,10 +363,7 @@ class PropertyWrapper : public PropertyInterface template void setDeallocator (Target target, Func func) { - if (!isAllocatable()) { - throw std::logic_error("property '" + id + "' is not allocatable"); - } - ossie::bind(deallocator_, target, func); + setDeallocator(DeallocateFunc(target, func)); } const std::string getNativeType () const @@ -450,10 +437,10 @@ class PropertyWrapper : public PropertyInterface private: // Delegate function types - typedef boost::function QueryFunc; - typedef boost::function ConfigureFunc; - typedef boost::function AllocateFunc; - typedef boost::function DeallocateFunc; + typedef redhawk::callback QueryFunc; + typedef redhawk::callback ConfigureFunc; + typedef redhawk::callback AllocateFunc; + typedef redhawk::callback DeallocateFunc; QueryFunc query_; ConfigureFunc configure_; diff --git a/redhawk/src/base/include/ossie/PropertySet_impl.h b/redhawk/src/base/include/ossie/PropertySet_impl.h index 545fe90bf..35afc2b8b 100644 --- a/redhawk/src/base/include/ossie/PropertySet_impl.h +++ b/redhawk/src/base/include/ossie/PropertySet_impl.h @@ -373,7 +373,7 @@ class PropertySet_impl return wrapper; } - typedef boost::function PropertyCallback; + typedef redhawk::callback PropertyCallback; void setPropertyCallback (const std::string& id, PropertyCallback callback); typedef std::map PropertyCallbackMap; diff --git a/redhawk/src/base/include/ossie/callback.h b/redhawk/src/base/include/ossie/callback.h index fb5620001..b3cbbfbec 100644 --- a/redhawk/src/base/include/ossie/callback.h +++ b/redhawk/src/base/include/ossie/callback.h @@ -25,6 +25,858 @@ #include #include +#include "internal/equals.h" + +namespace redhawk { + namespace detail { + // Bring ossie::internal::has_equals into this namespace (in effect) so + // we can specialize it for boost::bind + template + struct has_equals : public ossie::internal::has_equals { }; + + // Special case: boost::bind returns objects whose operator== returns + // another bind object, as opposed to a boolean, which breaks the + // default has_equals template. However, it does have one, and can be + // compared for equality using function_equal. + template + struct has_equals > { + static bool const value = true; + }; + + // Helper class to manage an object via void pointers, to avoid + // generating a lot of virtual functions and object type information + // when using callbacks. The object is stored in a buffer directly + // following the void_manager; its type is erased, but the key + // functions of copy/delete and equality comparison are maintained as + // function pointers that are able to cast back to the original object + // type. + struct void_manager { + ~void_manager() + { + _M_deleter(get_object()); + } + + // Returns a pointer to the managed object + inline void* get_object() + { + return &_M_buf[0]; + } + + // Returns a const pointer to the managed object + inline const void* get_object() const + { + return &_M_buf[0]; + } + + // Copies this void_manager and its contained object + void_manager* clone() const + { + // Allocate enough space for the manager plus the object, then + // initialize the manager with placement new + void* buf = _M_allocate(_M_size); + void_manager* manager = new (buf) void_manager(*this); + + // Dispatch to the object copy constructor (via _M_clone) + _M_clone(manager->get_object(), get_object()); + return manager; + } + + // Compares this void_manager's contained object with another's. + bool operator==(const void_manager& other) const + { + // If the object doesn't support equality comparison, consider + // the objects unequal. If the two managers have different + // equality function pointers, the types must differ, so also + // consider the objects unequal; this may be more limiting than + // the compiler might allow (e.g., due to implict conversions + // or overloads), but is the safest approach without more type + // information. + if (!_M_equal || (_M_equal != other._M_equal)) { + return false; + } + return _M_equal(get_object(), other.get_object()); + } + + // Create a new void_manager with a copy of the object + template + static void_manager* create(const T& object) + { + // Allocate enough space for the void_manager and the object, + // then initialize with placement new + void* buf = _M_allocate(sizeof(T)); + void_manager* manager = new (buf) void_manager(&deleter, &clone, get_equals(), sizeof(T)); + + // Clone the input object into the new void_manager + manager->_M_clone(manager->get_object(), &object); + return manager; + } + + private: + // Function types for object management; these adapt the object + // type, which is only known at creation time, to void pointers + typedef void (*deleter_func)(void*); + typedef void (*clone_func)(void* dest, const void* src); + typedef bool (*equal_func)(const void*, const void*); + + // Create a new void manager; can only be used from create() + void_manager(deleter_func deleter, clone_func clone, equal_func equal, size_t size) : + _M_deleter(deleter), + _M_clone(clone), + _M_equal(equal), + _M_size(size) + { + } + + // Allocates enough memory for a void_manager with an object buffer + // of the given size + static void* _M_allocate(size_t size) + { + size_t bytes = sizeof(void_manager) + size - sizeof(_M_buf); + return ::operator new(bytes); + } + + // Deleter function template, instantiated by create (as a function + // pointer) + template + static void deleter(void* data) + { + // Call the stored object's destructor directly instead of + // delete, because the memory is part of the void_manager + // instance + static_cast(data)->~T(); + } + + // Copy function template, instantiated by create (as a function + // pointer) + template + static void clone(void* dest, const void* src) + { + // Call the placement new copy constructor into the destination + // object buffer; the memory itself is managed by the + // void_manager instance + new (dest) T(*static_cast(src)); + } + + // Equals function template, instantiated by create (as a function + // pointer), but only if the template type supports testing for + // equality + template + static bool equals(const void* lhs, const void* rhs) + { + return equals(*static_cast(lhs), *static_cast(rhs)); + } + + // Implementation of equality function for types that support it + // normally + template + static inline bool equals(const T& lhs, const T& rhs) + { + return lhs == rhs; + } + + // Overload of equality function for boost::bind objects, which are + // not possible to compare with operator== + template + static inline bool equals(const boost::_bi::bind_t& lhs, const boost::_bi::bind_t& rhs) + { + return function_equal(lhs, rhs); + } + + // Template function to get the function pointer for equals, for + // types that cannot be compared for equality. Unlike the other + // function pointers, equals is looked up in this way to avoid + // instantiating the function template unless it's needed, because + // when used as a function pointer it creates a linker symbol. + template + static inline equal_func get_equals(typename boost::disable_if >::type* unused=0) + { + return 0; + } + + // Template function to get the function pointer for equals, for + // types that can be compared for equality + template + static inline equal_func get_equals(typename boost::enable_if >::type* unused=0) + { + return &equals; + } + + // Object management function pointers; see type definitions above + deleter_func _M_deleter; + clone_func _M_clone; + equal_func _M_equal; + + // The size of the managed object + size_t _M_size; + + // Buffer for storing the managed object; its true size is known at + // allocation time (and stored in _M_size), but it must be at least + // 1. The object storage starts at _M_buf[0] and goes to the end of + // the allocated memory. + char _M_buf[1]; + }; + + // Forward declaration of an "unusable" argument type. For simplicity + // of implementation, callback provides zero, one and two argument + // versions of operator(); without variadic templates, we would have to + // create specializations for each argument count. The overloads with + // too many arguments take an "unusable" struct, which will never match + // the argument type, giving an error message. + struct unusable; + + // Traits class to bind a function signature Sig to an invoker function + // type. Callback invokers take a void pointer as the first argument, + // which is a type-erased pointer to a callable object (e.g., function + // pointer, member_function, etc.), followed by the normal arguments. + // This is how the callback class dispatches function calls. + // + // This class must be specialized for each number of arguments (in this + // case zero, one and two). The result type is also included in the + // typedef rather than using Boost's function traits classes because + // it's simple enough to include on our own. + template + struct callback_traits; + + // Specialization for zero-argument invoker function type + template + struct callback_traits { + typedef R result_type; + typedef unusable first_argument_type; + typedef unusable second_argument_type; + typedef R (*invoker_func)(void*); + }; + + // Specialization for two-argument invoker function type + template + struct callback_traits { + typedef R result_type; + typedef A1 first_argument_type; + typedef unusable second_argument_type; + typedef R (*invoker_func)(void*, A1); + }; + + // Specialization for two-argument invoker function type + template + struct callback_traits { + typedef R result_type; + typedef A1 first_argument_type; + typedef A2 second_argument_type; + typedef R (*invoker_func)(void*, A1, A2); + }; + + // Templatized class that adapts the callable type Func to the function + // signature Sig. This must be specialized for each number of arguments + // supported (in this case zero, one and two) with a static function + // call() that is used as a function pointer; it must be assignable to + // a callback_traits::invoker_func. The call() function receives + // the callable as a void* (which can then be static cast back to the + // callable type) and any arguments declared in Sig. + // + // For each argument count, this should be further specialized for the + // void return versions to adapt non-void callables to void return + // signatures. The compiler allows statements like "return f();" if + // both functions return void, but if f() returns a value it becomes a + // compilation error. + template + struct function_invoker; + + // Specialization for zero-argument invocation function + template + struct function_invoker { + static R call(void* data) + { + Func* func = static_cast(data); + return (*func)(); + } + }; + + // Specialization for zero-argument void return invocation function + template + struct function_invoker { + static void call(void* data) + { + Func* func = static_cast(data); + (*func)(); + } + }; + + // Specialization for one-argument invocation function + template + struct function_invoker { + static R call(void* data, A1 a1) + { + Func* func = static_cast(data); + return (*func)(a1); + } + }; + + // Specialization for one-argument void return invocation function + template + struct function_invoker { + static void call(void* data, A1 a1) + { + Func* func = static_cast(data); + (*func)(a1); + } + }; + + // Specialization for two-argument invocation function + template + struct function_invoker { + static R call(void* data, A1 a1, A2 a2) + { + Func* func = static_cast(data); + return (*func)(a1, a2); + } + }; + + // Specialization for two-argument void return invocation function + template + struct function_invoker { + static void call(void* data, A1 a1, A2 a2) + { + Func* func = static_cast(data); + (*func)(a1, a2); + } + }; + + // Template class to bind together a member function with an object + // instance. The instance may be stored by pointer, value or shared + // pointer; the function must be a member function pointer. + template + struct member_function { + member_function(Target target, Func func) : + target(target), + func(func) + { + } + + Target target; + Func func; + }; + + // If the target object type supports it, define operator== for the + // related member_function type(s). It is assumed that the function + // objects are always comparable. + template + inline typename boost::enable_if,bool>::type + operator==(const member_function& lhs, const member_function& rhs) + { + return (lhs.target == rhs.target) && (lhs.func == rhs.func); + } + + // The get_pointer() function converts the target of a member function + // into a pointer so that any type can be used with operator->* to call + // a member function pointer. This overlaps quite a bit with the Boost + // function of the same name, but supports by-value objects in member + // functions via its default implementation. + template + inline T* get_pointer(T& value) + { + return &value; + } + + // Overload of get_pointer() for types that are already pointers + template + inline T* get_pointer(T* value) + { + return value; + } + + // Overload of get_pointer() for boost::shared_ptr + template + inline T* get_pointer(boost::shared_ptr& value) + { + return value.get(); + } + + // Templatized class that adapts a class instance/member function pair + // to the function signature Sig. See function_invoker for explanation + // about specialization requirements. + template + struct member_invoker; + + // Specialization for zero-argument invocation function + template + struct member_invoker { + static R call(void* data) + { + MemberFunc* func = static_cast(data); + return (get_pointer(func->target)->*(func->func)) (); + } + }; + + // Specialization for zero-argument void return invocation function + template + struct member_invoker { + static void call(void* data) + { + MemberFunc* func = static_cast(data); + (get_pointer(func->target)->*(func->func)) (); + } + }; + + // Specialization for one-argument invocation function + template + struct member_invoker { + static R call(void* data, A1 a1) + { + MemberFunc* func = static_cast(data); + return (get_pointer(func->target)->*(func->func)) (a1); + } + }; + + // Specialization for one-argument void return invocation function + template + struct member_invoker { + static void call(void* data, A1 a1) + { + MemberFunc* func = static_cast(data); + (get_pointer(func->target)->*(func->func)) (a1); + } + }; + + // Specialization for two-argument invocation function + template + struct member_invoker { + static R call(void* data, A1 a1, A2 a2) + { + MemberFunc* func = static_cast(data); + return (get_pointer(func->target)->*(func->func)) (a1, a2); + } + }; + + // Specialization for one-argument void return invocation function + template + struct member_invoker { + static void call(void* data, A1 a1, A2 a2) + { + MemberFunc* func = static_cast(data); + (get_pointer(func->target)->*(func->func)) (a1, a2); + } + }; + } + + /** + * @brief Generic callback class. + * + * %callback provides overlapping functionality with Boost Function/Bind + * and C++11's header (also available as part of TR1 on older + * compilers); however, for the way callbacks are used in REDHAWK, each has + * deficiencies that necessitated the creation of %callback: + * - boost::function creates unique symbols per type that prevent the + * dynamic loader from unloading libraries + * - C++11's std::function does not support operator==, which is used in + * the notification class to unregister a callback + */ + template + struct callback + { + private: + typedef typename detail::callback_traits traits; + typedef typename traits::invoker_func invoker_func; + typedef typename traits::result_type result_type; + typedef typename traits::first_argument_type first_argument_type; + typedef typename traits::second_argument_type second_argument_type; + + // Use a member pointer as the type for boolean-like conversion (so + // that you can do "if (x)"), because it cannot be converted to any + // other type + typedef invoker_func (callback::*unspecified_bool_type); + + public: + /** + * @brief Construct an empty %callback. + */ + callback() : + _M_invoker(0), + _M_type(TYPE_NONE) + { + } + + /** + * @brief Construct a %callback with a function pointer. + * @param func Function pointer. + * + * The signature of @a func must be compatible with the declared return + * type and arguments. + */ + template + callback(Func* func) : + _M_invoker(&detail::function_invoker::call), + _M_type(TYPE_FUNCTION) + { + // Function pointers are simple enough to store in _M_impl, but the + // type doesn't match the function pointer placeholder; rather than + // work around aliasing warnings, use placement new to initialize. + typedef Func* impl_type; + new (&_M_impl) impl_type(func); + } + + /** + * @brief Construct a %callback with a functor by reference. + * @param func Reference to a functor object. + * + * The signature of @a func must be compatible with the declared return + * type and arguments. + */ + template + callback(boost::reference_wrapper func) : + _M_invoker(&detail::function_invoker::call), + _M_type(TYPE_FUNCTOR_REF) + { + _M_impl.functor = func.get_pointer(); + } + + /** + * @brief Construct a %callback with a class instance and member + * function pointer. + * @param target Pointer to the class instance. + * @param func Member function pointer. + * + * The signature of @a func must be compatible with the declared return + * type and arguments. + */ + template + callback(Target* target, Func func) : + _M_type(TYPE_MEMBER) + { + // Like function pointers, member functions with a pointer to an + // object can be stored in _M_impl, but the types don't match. + // Because the member_function template class is intentionally + // laid out to match the member function placeholder, placement + // new can be used to initialize. + typedef detail::member_function impl_type; + new (&_M_impl) impl_type(target, func); + _M_invoker = &detail::member_invoker::call; + } + + /** + * @brief Construct a %callback with a functor. + * @param func A functor object. + * + * @a func must be copy-constructible and support an operator() that is + * compatible with the declared return type and arguments. + */ + template + callback(const Functor& func) : + _M_invoker(&detail::function_invoker::call), + _M_type(TYPE_MANAGED) + { + // Create a new managed object, which also copies the functor + // object argument + _M_impl.managed = detail::void_manager::create(func); + } + + /** + * @brief Construct a %callback with a class instance and member + * function pointer. + * @param target Class instance (or shared pointer to a class + * instance). + * @param func Member function pointer. + * + * The signature of @a func must be compatible with the declared return + * type and arguments. + */ + template + callback(Target target, Func func) : + _M_type(TYPE_MANAGED) + { + // Create a new managed object, with a member_function as the + // contents. This is most likely to be used with shared pointers, + // but can work for other types as well + typedef detail::member_function impl_type; + _M_impl.managed = detail::void_manager::create(impl_type(target, func)); + _M_invoker = &detail::member_invoker::call; + } + + /** + * Copy constructor. + */ + callback(const callback& other) : + _M_invoker(other._M_invoker), + _M_type(other._M_type) + { + switch (other._M_type) { + case TYPE_MANAGED: + // Copy the other callback's implementation (which includes + // the manager) + _M_impl.managed = other._M_impl.managed->clone(); + break; + case TYPE_FUNCTION: + // Copy the function pointer (the type doesn't matter) + _M_impl.func = other._M_impl.func; + break; + case TYPE_FUNCTOR_REF: + // Copy the functor pointer (the type doesn't matter) + _M_impl.functor = other._M_impl.functor; + break; + case TYPE_MEMBER: + // Copy the member function object and pointer (the types don't + // matter--the sizes are the same regardless of the object type + // or function signature) + _M_impl.member = other._M_impl.member; + break; + default: + break; + } + } + + /** + * @brief Destructor. + * + * Any allocated objects are destroyed. + */ + ~callback() + { + // Delete any managed object + clear(); + } + + /** + * Copy assignment. + */ + callback& operator=(const callback& other) + { + if (&other != this) { + // Use the copy constructor, swap and the destructor to handle + // everything (as opposed to re-implementing basically the same + // thing) + callback temp(other); + this->swap(temp); + } + return *this; + } + + /** + * @brief Replace the current target with a class instance and member + * function pointer. + * @param target Class instance (by pointer, shared pointer or value). + * @param func Member function pointer. + * + * The signature of @a func must be compatible with the declared return + * type and arguments. + */ + template + void assign(Target target, Func func) + { + callback temp(target, func); + this->swap(temp); + } + + /** + * @brief Checks whether this %callback is equivalent to another. + * @param other Another %callback. + * @return true if this %callback is equivalent to @a other, false + * otherwise. + * + * Two callbacks are considered equal if their targets can reasonably + * be assumed to be equivalent. The targets must be of the same type to + * be compared: + * - function pointers must be exactly equal + * - member functions must point to the same object and member function + * - functors must support operator== and evalute as equal + */ + bool operator==(const callback& other) const + { + // If the invoker functions are different, the types must be + // different + if (_M_invoker != other._M_invoker) { + return false; + } + switch (_M_type) { + case TYPE_MANAGED: + // Defer to the managed object's equality operator + return (*(_M_impl.managed) == *(other._M_impl.managed)); + case TYPE_FUNCTION: + // Compare standalone function pointers directly (the types + // don't matter) + return (_M_impl.func == other._M_impl.func); + case TYPE_FUNCTOR_REF: + // Compare standalone function pointers directly (the types + // don't matter) + return (_M_impl.functor == other._M_impl.functor); + case TYPE_MEMBER: + // Compare the object and member function pointers directly + // (the types don't matter) + return (_M_impl.member.target == other._M_impl.member.target) && + (_M_impl.member.func == other._M_impl.member.func); + default: + // Empty callbacks are "equal" + return true; + } + } + + /** + * Returns true if this %callback is empty. + */ + bool operator! () const + { + return empty(); + } + + /** + * Evaluates to true in a boolean context if this %callback is non- + * empty, false otherwise. + */ + operator unspecified_bool_type () const + { + return empty()?0:&callback::_M_invoker; + } + + /** + * @brief Returns true if this %callback does not have a target. + */ + bool empty() const + { + return _M_type == TYPE_NONE; + } + + /** + * @brief Resets this %callback to an empty state. + */ + void clear() + { + if (_M_type == TYPE_MANAGED) { + delete _M_impl.managed; + } + _M_invoker = 0; + _M_type = TYPE_NONE; + } + + /** + * @brief Swap contents with another %callback. + * @param other %callback to swap with. + */ + void swap(callback& other) + { + // Copy the raw bytes, since we do not know (nor do we need to, + // really) the other's implementation + impl temp_impl; + memcpy(&temp_impl, &other._M_impl, sizeof(impl)); + memcpy(&other._M_impl, &_M_impl, sizeof(impl)); + memcpy(&_M_impl, &temp_impl, sizeof(impl)); + + std::swap(_M_invoker, other._M_invoker); + std::swap(_M_type, other._M_type); + } + + /** + * @brief Invokes the target function. + * @return The result of the target function (or nothing, if the + * return type of this %callback is void). + * @throws std::runtime_error if this %callback is empty + */ + inline result_type operator() () + { + if (empty()) { + throw std::runtime_error("empty callback"); + } + return _M_invoker(_M_data()); + } + + /** + * @brief Invokes the target function with a single argument. + * @param a1 The first argument. + * @return The result of the target function (or nothing, if the + * return type of this %callback is void). + * @throws std::runtime_error if this %callback is empty + */ + inline result_type operator() (first_argument_type a1) + { + if (empty()) { + throw std::runtime_error("empty callback"); + } + return _M_invoker(_M_data(), a1); + } + + /** + * @brief Invokes the target function with a two arguments. + * @param a1 The first argument. + * @param a2 The second argument. + * @return The result of the target function (or nothing, if the + * return type of this %callback is void). + * @throws std::runtime_error if this %callback is empty + */ + inline result_type operator() (first_argument_type a1, second_argument_type a2) + { + if (empty()) { + throw std::runtime_error("empty callback"); + } + return _M_invoker(_M_data(), a1, a2); + } + + private: + // Poison comparison to callbacks with different signatures + template + bool operator==(const callback&) const; + + /// @cond IMPL + + // Returns a pointer to the callable object, for invocation + void* _M_data() + { + if (_M_type == TYPE_MANAGED) { + // The invoker takes the void_manager's contained object + return _M_impl.managed->get_object(); + } else if (_M_type == TYPE_FUNCTOR_REF) { + return _M_impl.functor; + } else { + // Use the impl object as an alias for the function pointer or + // object/member pair + return &_M_impl; + } + } + + // Discriminated union type to hold the specific implementation of the + // callback. Function pointers, by-reference functors, and object + // pointer/member function pointer pairs can be stored in-place; all + // other types are allocated on the heap. + typedef union { + // Placeholder for a function pointer; all function pointers should + // have the same size, so the specific type is only relevant for + // dispatch, which does not go through this object + void (*func)(); + + // Pointer to a functor object; functors passed by reference (via + // boost::ref) are converted to a pointer and stored here + void* functor; + + // Placeholder for an object and member function pointer; as with + // function pointers, the types are only relevant for dispatch, + // which uses a different interpretation of this object + struct { + callback* target; + void (callback::*func)(); + } member; + + // For all other types, which cannot be stored in place, a heap- + // allocated void_manager holds the callable object + detail::void_manager* managed; + } impl; + + // Discriminant for implementation types + enum impl_type { + TYPE_NONE, + TYPE_FUNCTION, + TYPE_FUNCTOR_REF, + TYPE_MEMBER, + TYPE_MANAGED + }; + + impl _M_impl; + invoker_func _M_invoker; + impl_type _M_type; + /// @endcond + }; + + template + bool operator!=(const callback& lhs, const T& rhs) + { + return !(lhs == rhs); + } +} + namespace ossie { // The functions and classes in this header are designed to provide easy @@ -166,7 +1018,7 @@ namespace ossie { class notification_base { public: - typedef boost::function func_type; + typedef redhawk::callback func_type; /* * Register the callable 'func' to be called when this notification is @@ -189,6 +1041,31 @@ namespace ossie { this->_M_listeners.end()); } + /* + * Register the member function 'func' to be called on the instance + * 'target' when this notification is triggered. + * + * Listeners do not need to match the signature exactly, but the + * notification's argument types must be convertible to the listener's + * argument types. + */ + template + void add(Target target, Func func) + { + this->add(func_type(target, func)); + } + + /* + * Remove the member function 'func' on the instance 'target' from + * further notifications. The pair must have been registered together + * in a prior call to add(). + */ + template + void remove(Target target, Func func) + { + this->remove(func_type(target, func)); + } + bool empty() const { return _M_listeners.empty(); @@ -218,34 +1095,7 @@ namespace ossie { call_each(this->_M_listeners.begin(), this->_M_listeners.end()); } - /* - * Register the member function 'func' to be called on the instance - * 'target' when this notification is triggered. - * - * Listeners do not need to match the signature exactly, but the - * notification's argument types must be convertible to the listener's - * argument types. - */ - template - void add(Target target, Func func) - { - super::add(boost::bind(func, target)); - } - - /* - * Remove the member function 'func' on the instance 'target' from - * further notifications. The pair must have been registered together - * in a prior call to add(). - */ - template - void remove(Target target, Func func) - { - super::remove(boost::bind(func, target)); - } - private: - typedef notification_base super; - template static inline void call_each(Iterator begin, const Iterator end) { for (; begin != end; ++begin) { @@ -269,35 +1119,7 @@ namespace ossie { call_each(this->_M_listeners.begin(), this->_M_listeners.end(), arg1); } - /* - * Register the member function 'func' to be called on the instance - * 'target' when this notification is triggered. - * - * Listeners do not need to match the signature exactly, but the - * notification's argument types must be convertible to the listener's - * argument types. - */ - template - void add(Target target, Func func) - { - super::add(boost::bind(&invoker_type::template invoke, target, func, _1)); - } - - /* - * Remove the member function 'func' on the instance 'target' from - * further notifications. The pair must have been registered together - * in a prior call to add(). - */ - template - void remove(Target target, Func func) - { - super::remove(boost::bind(&invoker_type::template invoke, target, func, _1)); - } - private: - typedef notification_base super; - typedef ::ossie::detail::invoker invoker_type; - template static inline void call_each(Iterator begin, const Iterator end, A1 arg1) { for (; begin != end; ++begin) { @@ -321,36 +1143,7 @@ namespace ossie { call_each(this->_M_listeners.begin(), this->_M_listeners.end(), arg1, arg2); } - - /* - * Register the member function 'func' to be called on the instance - * 'target' when this notification is triggered. - * - * Listeners do not need to match the signature exactly, but the - * notification's argument types must be convertible to the listener's - * argument types. - */ - template - void add(Target target, Func func) - { - super::add(boost::bind(&invoker_type::template invoke, target, func, _1, _2)); - } - - /* - * Remove the member function 'func' on the instance 'target' from - * further notifications. The pair must have been registered together - * in a prior call to add(). - */ - template - void remove(Target target, Func func) - { - super::remove(boost::bind(&invoker_type::template invoke, target, func, _1, _2)); - } - private: - typedef notification_base super; - typedef ::ossie::detail::invoker invoker_type; - template static inline void call_each(Iterator begin, const Iterator end, A1 arg1, A2 arg2) { for (; begin != end; ++begin) { From ffc1cd44d643d3db7982bcd172ecdaeca9572a00 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 22 Mar 2017 13:01:13 -0400 Subject: [PATCH 0756/1644] CF-1710 C++ unit tests for redhawk::callback class to ensure base functionality is correct --- redhawk/src/testing/cpp/CallbackTest.cpp | 525 +++++++++++++++++++++++ redhawk/src/testing/cpp/CallbackTest.h | 70 +++ redhawk/src/testing/cpp/Makefile.am | 1 + 3 files changed, 596 insertions(+) create mode 100644 redhawk/src/testing/cpp/CallbackTest.cpp create mode 100644 redhawk/src/testing/cpp/CallbackTest.h diff --git a/redhawk/src/testing/cpp/CallbackTest.cpp b/redhawk/src/testing/cpp/CallbackTest.cpp new file mode 100644 index 000000000..ba85c0677 --- /dev/null +++ b/redhawk/src/testing/cpp/CallbackTest.cpp @@ -0,0 +1,525 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK core. + * + * REDHAWK core is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +#include "CallbackTest.h" + +#include +#include + +#include + +#include + +CPPUNIT_TEST_SUITE_REGISTRATION(CallbackTest); + +namespace { + // Simple global function and counter to test zero-argument functions + static int global_counter = 0; + static int increment() + { + return ++global_counter; + } + + // Convert a C string to uppercase in-place, returning the number of + // characters that were modified + static int upcase(char* str) + { + int count = 0; + for (char* pos = str; *pos != '\0'; ++pos) { + char ch = *pos; + if (!isupper(ch)) { + ++count; + *pos = toupper(ch); + } + } + return count; + } + + // Simple functor that returns a constant value + template + struct Constant { + Constant(T value) : + _value(value) + { + } + + T operator() () const + { + return _value; + } + + void set(T value) + { + _value = value; + } + + bool operator==(const Constant& other) const + { + return (_value == other._value); + } + + private: + T _value; + }; + + // Functor that multiplies argument by a pre-defined scale value + template + class Scale { + public: + Scale(T scale) : + _scale(scale) + { + } + + T operator() (T arg) + { + return arg * _scale; + } + private: + T _scale; + }; + + // Functor that returns the average of two integers + struct Average { + float operator() (int arg1, int arg2) + { + return (arg1 + arg2) / 2.0; + } + }; + + // Object that provides some const and non-const member functions to test + // various modes of member function callbacks + class Object { + public: + Object(const std::string& name) : + _name(name), + _total(0) + { + } + + std::string name() const + { + return _name; + } + + int total() const + { + return _total; + } + + int reset() + { + int result = _total; + _total = 0; + return result; + } + + int add(int count) + { + _total += count; + return _total; + } + + int subtract(int count) + { + _total -= count; + return _total; + } + + int clamp(int min, int max) + { + _total = std::max(min, std::min(max, _total)); + return _total; + } + + private: + const std::string _name; + int _total; + }; + + // Class to help test by-reference arguments and returns + template + class ArgumentTester { + public: + ArgumentTester(R result) : + _result(result), + _arg1(0), + _arg2(0) + { + } + + R& call(A1& arg1, A2& arg2) + { + _arg1 = &arg1; + _arg2 = &arg2; + return _result; + } + + R* result() + { + return &_result; + } + + A1* arg1() + { + return _arg1; + } + + A2* arg2() + { + return _arg2; + } + + private: + R _result; + A1* _arg1; + A2* _arg2; + }; + + // Functor that takes two arguments by reference and modified them: + // - an integer, whose sign gets inverted + // - a string, that gets reversed + struct Mutator { + void operator() (int& number, std::string& message) + { + number *= -1; + std::string out; + std::copy(message.rbegin(), message.rend(), std::back_inserter(out)); + message = out; + } + }; +} + +void CallbackTest::setUp() +{ +} + +void CallbackTest::tearDown() +{ +} + +void CallbackTest::testEmpty() +{ + // Default constructor creates an empty callback + redhawk::callback func; + CPPUNIT_ASSERT(func.empty()); + + // Assign a value; should not be empty + func = &getpid; + CPPUNIT_ASSERT(!func.empty()); + + // Clear should reset to empty + func.clear(); + CPPUNIT_ASSERT(func.empty()); +} + +void CallbackTest::testEmptyCall() +{ + // Calling an empty callback should always throw a runtime error + + redhawk::callback func0; + CPPUNIT_ASSERT(func0.empty()); + CPPUNIT_ASSERT_THROW(func0(), std::runtime_error); + + redhawk::callback func1; + CPPUNIT_ASSERT(func1.empty()); + CPPUNIT_ASSERT_THROW(func1("abc"), std::runtime_error); + + redhawk::callback func2; + CPPUNIT_ASSERT(func2.empty()); + CPPUNIT_ASSERT_THROW(func2(0.0, 0), std::runtime_error); +} + +void CallbackTest::testBooleanOperators() +{ + // Empty callback, should evaluate to boolean false + redhawk::callback func; + CPPUNIT_ASSERT(func.empty()); + CPPUNIT_ASSERT(!func); + if (func) { + // Boolean-like conversion has to be tested in the context of an if + // statement to ensure we are testing what we expect (CPPUNIT_ASSERT + // expands to something like "if (!cond) {...}", which we're already + // testing above) + CPPUNIT_FAIL("Boolean-like conversion returned true on empty callback"); + } + + // Empty callback, should evaluate to boolean true + func = &getpid; + CPPUNIT_ASSERT(!func.empty()); + CPPUNIT_ASSERT_EQUAL(false, !func); + if (func) { + // Expected behavior + } else { + CPPUNIT_FAIL("Boolean-like conversion returned false on valid callback"); + } +} + +void CallbackTest::testFunction() +{ + // Zero-argument function: getpid() + redhawk::callback func0(&getpid); + pid_t self = func0(); + CPPUNIT_ASSERT_EQUAL(getpid(), self); + + // One-argument function: complex conjugate + typedef std::complex complex_float; + redhawk::callback func1 = &std::conj; + complex_float conj_result = func1(complex_float(1.0, 1.0)); + CPPUNIT_ASSERT_EQUAL(complex_float(1.0, -1.0), conj_result); + + // Two-argument function: power (with integer exponent) + redhawk::callback func2 = &std::pow; + double pow_result = func2(7.0, 3); + CPPUNIT_ASSERT_EQUAL(343.0, pow_result); +} + +void CallbackTest::testFunctionEquals() +{ + // Function pointer callbacks should only be equal if the function pointers + // are exactly the same + redhawk::callback func0 = &getuid; + CPPUNIT_ASSERT(func0 != &getpid); + CPPUNIT_ASSERT(func0 == &getuid); +} + +void CallbackTest::testFunctor() +{ + // Zero argument functor: return a pre-defined value + redhawk::callback func0 = Constant("test"); + std::string message = func0(); + CPPUNIT_ASSERT_EQUAL(std::string("test"), message); + + // One-argument functor: scale argument by a numeric factor + redhawk::callback func1 = Scale(1); + int result = func1(2); + CPPUNIT_ASSERT_EQUAL_MESSAGE("One argument functor returned incorrect result", 2, result); + + // Two-argument functor: average of two numbers + redhawk::callback func2 = Average(); + float avg = func2(7, 10); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Two argument functor returned incorrect result", 8.5f, avg); +} + +void CallbackTest::testFunctorRef() +{ + // Associate a functor by reference; changes to the functor should be + // reflected in subsequent calls + Constant constant(-5); + redhawk::callback func = boost::ref(constant); + CPPUNIT_ASSERT(func == boost::ref(constant)); + short value = func(); + CPPUNIT_ASSERT_EQUAL((short) -5, value); + constant.set(10); + value = func(); + CPPUNIT_ASSERT_EQUAL((short) 10, value); +} + +void CallbackTest::testFunctorEquals() +{ + // Constant has an operator== defined, that compares the constant value + redhawk::callback func0_a = Constant("same"); + redhawk::callback func0_b = Constant("same"); + CPPUNIT_ASSERT(func0_a == func0_b); + CPPUNIT_ASSERT(func0_a != Constant("other")); + + // Scale has no operator== defined, so compare always fails + redhawk::callback func1_a = Scale(2.0); + redhawk::callback func1_b = Scale(2.0); + CPPUNIT_ASSERT(func1_a != func1_b); + + // Average has no operator==, but references compare based on whether the + // references are to the same object + Average avg; + redhawk::callback func2_a = boost::ref(avg); + redhawk::callback func2_b = boost::ref(avg); + CPPUNIT_ASSERT(func2_a == func2_b); + Average avg2; + CPPUNIT_ASSERT(func2_a != boost::ref(avg2)); +} + +void CallbackTest::testMemberFunction() +{ + boost::shared_ptr obj = boost::make_shared("test"); + + // Zero-argument callback; use a const pointer alias, and a const-qualified + // member function + const Object* obj_ptr = obj.get(); + redhawk::callback func0(obj_ptr, &Object::name); + CPPUNIT_ASSERT_EQUAL(obj->name(), func0()); + + // One-argument member function; check that the object is modified as + // expected + redhawk::callback func1(obj, &Object::add); + int result = func1(10); + CPPUNIT_ASSERT_EQUAL(10, result); + func1(20); + CPPUNIT_ASSERT_EQUAL(30, obj->total()); + + // Use assign to rebind the callback (using a non-const pointer instead of + // the shared pointer) + func1.assign(obj.get(), &Object::subtract); + func1(15); + CPPUNIT_ASSERT_EQUAL(15, obj->total()); + + // Use an object by value (implicitly making a copy); the function should + // work as expected, without affecting the original object (yes, this is a + // contrived example) + redhawk::callback func2(*obj, &Object::clamp); + result = func2(0, 10); + CPPUNIT_ASSERT_EQUAL(10, result); + CPPUNIT_ASSERT_EQUAL(15, obj->total()); +} + +void CallbackTest::testMemberFunctionEquals() +{ + // Member functions should only be equal if both the target object and + // function are the same + Object obj1("first"); + redhawk::callback func1(&obj1, &Object::add); + redhawk::callback func2(&obj1, &Object::add); + CPPUNIT_ASSERT(func1 == func2); + + // Same object, different function should be unequal + func2.assign(&obj1, &Object::subtract); + CPPUNIT_ASSERT_MESSAGE("Different member functions should not be equal", func1 != func2); + + // Same function, different object should be unequal + Object obj2("second"); + func2.assign(&obj2, &Object::add); + CPPUNIT_ASSERT_MESSAGE("Different target objects should not be equal", func1 != func2); +} + +void CallbackTest::testMixedEquals() +{ + redhawk::callback function = &std::abs; + + Object obj("member"); + redhawk::callback member(&obj, &Object::add); + + Scale scale(1); + redhawk::callback functor = scale; + redhawk::callback functor_ref = boost::ref(scale); + + // Test all possible combinations + CPPUNIT_ASSERT(function != member); + CPPUNIT_ASSERT(function != functor); + CPPUNIT_ASSERT(function != functor_ref); + CPPUNIT_ASSERT(member != functor); + CPPUNIT_ASSERT(member != functor_ref); + CPPUNIT_ASSERT(functor != functor_ref); +} + +void CallbackTest::testReferenceArguments() +{ + // Use a functor that modifies the passed-in arguments to check that the + // original arguments are modifed (as opposed to some argument value on the + // stack) + redhawk::callback functor = Mutator(); + int value = 1; + std::string name = "test text"; + functor(value, name); + CPPUNIT_ASSERT_EQUAL(-1, value); + CPPUNIT_ASSERT_EQUAL(std::string("txet tset"), name); + + // Use a member function with const arguments (by reference) to makes sure + // that they are passed unmodified (i.e., no copies) + typedef std::string R; + typedef const int A1; + typedef const Object A2; + typedef ArgumentTester TesterType; + + TesterType tester("references"); + redhawk::callback member(&tester, &TesterType::call); + + int number = 0; + Object obj("argument"); + R& result = member(number, obj); + CPPUNIT_ASSERT(&number == tester.arg1()); + CPPUNIT_ASSERT(&obj == tester.arg2()); + CPPUNIT_ASSERT(&result == tester.result()); +} + +void CallbackTest::testArgumentConversion() +{ + // One-argument member function: abuse constant value functor and its set + // function to implicitly construct a C++ string from a C string + Constant message("Test"); + redhawk::callback func1(&message, &Constant::set); + func1("Updated"); + CPPUNIT_ASSERT_EQUAL(std::string("Updated"), message()); + + // Two-argument functor: implicit conversion of arguments from double to + // int (truncation to -1, 6), plus implict conversion of result from float + // to int (2.5 truncates to 2) + redhawk::callback func2 = Average(); + int avg = func2(-1.25, 6.375); + CPPUNIT_ASSERT_EQUAL(2, avg); +} + +void CallbackTest::testVoidReturn() +{ + // Test to ensure that functions which return a value can be assigned to + // callbacks that return void. From a C++ implementation standpoint, there + // are template specializations to ensure that callback invoker functions + // returning void are syntactically correct--a void function can return the + // result of calling another void function, but if that function has a + // return value it is a syntax error. + + // Zero-argument function: ignore the result of increment(), defined above, + // but check that it takes effect + global_counter = 0; + redhawk::callback func0 = &increment; + func0(); + CPPUNIT_ASSERT_EQUAL(1, global_counter); + + // Zero-argument member function: ignore the result of Object::reset() but + // check it it takes effect + Object obj("void"); + obj.add(5); + func0.assign(&obj, &Object::reset); + func0(); + CPPUNIT_ASSERT_EQUAL(0, obj.total()); + + // One-argument function: ignore the result of upcase(), defined above + redhawk::callback func1 = &upcase; + char buf[64]; + sprintf(buf, "message"); + func1(buf); + CPPUNIT_ASSERT(strcmp(buf, "MESSAGE") == 0); + + // One-argument member function + redhawk::callback func1_member(&obj, &Object::add); + func1_member(1.25); + CPPUNIT_ASSERT_EQUAL(1, obj.total()); + + // Two-argument function: ignore the result of strcpy (which is just a char + // * to the destination, anyway), but check that it worked + redhawk::callback func2 = &strcpy; + const char* expected = "expected value"; + func2(buf, expected); + CPPUNIT_ASSERT(strcmp(buf, expected) == 0); + + // Two-argument member function + obj.add(100); + redhawk::callback func2_member(&obj, &Object::clamp); + func2_member(0, 50); + CPPUNIT_ASSERT_EQUAL(50, obj.total()); +} diff --git a/redhawk/src/testing/cpp/CallbackTest.h b/redhawk/src/testing/cpp/CallbackTest.h new file mode 100644 index 000000000..15dad7151 --- /dev/null +++ b/redhawk/src/testing/cpp/CallbackTest.h @@ -0,0 +1,70 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK core. + * + * REDHAWK core is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +#ifndef CALLBACKTEST_H +#define CALLBACKTEST_H + +#include + +class CallbackTest : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE(CallbackTest); + CPPUNIT_TEST(testEmpty); + CPPUNIT_TEST(testEmptyCall); + CPPUNIT_TEST(testBooleanOperators); + CPPUNIT_TEST(testFunction); + CPPUNIT_TEST(testFunctionEquals); + CPPUNIT_TEST(testFunctor); + CPPUNIT_TEST(testFunctorRef); + CPPUNIT_TEST(testFunctorEquals); + CPPUNIT_TEST(testMemberFunction); + CPPUNIT_TEST(testMemberFunctionEquals); + CPPUNIT_TEST(testMixedEquals); + CPPUNIT_TEST(testReferenceArguments); + CPPUNIT_TEST(testArgumentConversion); + CPPUNIT_TEST(testVoidReturn); + CPPUNIT_TEST_SUITE_END(); + +public: + void setUp(); + void tearDown(); + + void testEmpty(); + void testEmptyCall(); + void testBooleanOperators(); + + void testFunction(); + void testFunctionEquals(); + + void testFunctor(); + void testFunctorRef(); + void testFunctorEquals(); + + void testMemberFunction(); + void testMemberFunctionEquals(); + + void testMixedEquals(); + + void testReferenceArguments(); + void testArgumentConversion(); + void testVoidReturn(); +}; + +#endif // CALLBACKTEST_H diff --git a/redhawk/src/testing/cpp/Makefile.am b/redhawk/src/testing/cpp/Makefile.am index d7f36a450..ec2029c84 100644 --- a/redhawk/src/testing/cpp/Makefile.am +++ b/redhawk/src/testing/cpp/Makefile.am @@ -13,5 +13,6 @@ test_libossiecf_SOURCES += PropertyMapTest.cpp PropertyMapTest.h test_libossiecf_SOURCES += MessagingTest.cpp MessagingTest.h test_libossiecf_SOURCES += ExecutorServiceTest.cpp ExecutorServiceTest.h test_libossiecf_SOURCES += BufferManagerTest.cpp BufferManagerTest.h +test_libossiecf_SOURCES += CallbackTest.cpp CallbackTest.h test_libossiecf_CXXFLAGS = $(CPPUNIT_CFLAGS) -I $(top_srcdir)/base/include test_libossiecf_LDFLAGS = $(CPPUNIT_LIBS) $(top_builddir)/base/framework/libossiecf.la $(top_builddir)/base/framework/idl/libossieidl.la From fbf1807665f5a7e302c79d5f478ea3dcf1eb22f9 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 22 Mar 2017 13:02:38 -0400 Subject: [PATCH 0757/1644] Fix issues found by running the BulkIO C++ unit tests with Valgrind --- .../libsrc/cpp/bulkio_attachable_port.cpp | 2 +- .../tests/cpp/Bulkio_InPort_Fixture.cpp | 47 ++++++++++++------- .../tests/cpp/Bulkio_MultiOut_Port.cpp | 4 ++ .../tests/cpp/Bulkio_OutPort_Fixture.cpp | 26 ++++++++++ redhawk/src/base/framework/UsesPort.cpp | 7 +++ redhawk/src/base/include/ossie/UsesPort.h | 1 + 6 files changed, 69 insertions(+), 18 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_attachable_port.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_attachable_port.cpp index 147328df8..dc277a300 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_attachable_port.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_attachable_port.cpp @@ -862,7 +862,7 @@ namespace bulkio { boost::mutex::scoped_lock lock(attachmentsUpdateLock); try { LOG_TRACE( logger, "Creating ATTACHMENT FOR CONNECTION: " << connectionId); - char* attachId = inPort->attach(_streamDefinition, _name.c_str()); + CORBA::String_var attachId = inPort->attach(_streamDefinition, _name.c_str()); LOG_TRACE( logger, "Created ATTACHMENT, CONNECTION " << connectionId << " ATTACH ID" << attachId); StreamAttachment attachment(connectionId, std::string(attachId), inPort, port); attachment.setLogger(logger); diff --git a/bulkioInterfaces/libsrc/testing/tests/cpp/Bulkio_InPort_Fixture.cpp b/bulkioInterfaces/libsrc/testing/tests/cpp/Bulkio_InPort_Fixture.cpp index 9318597bf..72da69eb1 100644 --- a/bulkioInterfaces/libsrc/testing/tests/cpp/Bulkio_InPort_Fixture.cpp +++ b/bulkioInterfaces/libsrc/testing/tests/cpp/Bulkio_InPort_Fixture.cpp @@ -186,7 +186,7 @@ void Bulkio_InPort_Fixture::test_port_api( bulkio::InFilePort *port ) { bulkio::InFilePort::dataTransfer *pkt = port->getPacket(bulkio::Const::NON_BLOCKING ); CPPUNIT_ASSERT( pkt == NULL ); - BULKIO::StreamSRI sri; + BULKIO::StreamSRI sri = bulkio::sri::create("test_port_api"); port->pushSRI( sri ); streams = port->activeSRIs(); @@ -194,7 +194,7 @@ void Bulkio_InPort_Fixture::test_port_api( bulkio::InFilePort *port ) { CPPUNIT_ASSERT( streams->length() == 1 ); delete streams; - bulkio::InFilePort::PortSequenceType v = new bulkio::InFilePort::TransportType[1]; + const char* v = "file:///tmp/test_port_api.dat"; BULKIO::PrecisionUTCTime TS; port->pushPacket( v, TS, false, "test_port_api" ); @@ -241,7 +241,7 @@ void Bulkio_InPort_Fixture::test_port_api( bulkio::InXMLPort *port ) { bulkio::InXMLPort::dataTransfer *pkt = port->getPacket(bulkio::Const::NON_BLOCKING ); CPPUNIT_ASSERT( pkt == NULL ); - BULKIO::StreamSRI sri; + BULKIO::StreamSRI sri = bulkio::sri::create("test_port_api"); port->pushSRI( sri ); streams = port->activeSRIs(); @@ -249,7 +249,7 @@ void Bulkio_InPort_Fixture::test_port_api( bulkio::InXMLPort *port ) { CPPUNIT_ASSERT( streams->length() == 1 ); delete streams; - bulkio::InXMLPort::PortSequenceType v = new bulkio::InXMLPort::TransportType[1]; + const char* v = ""; BULKIO::PrecisionUTCTime TS; port->pushPacket( v, false, "test_port_api" ); @@ -442,7 +442,7 @@ void Bulkio_InPort_Fixture::test_port_api( bulkio::InSDDSPort *port ) { sdef.multicastAddress = "1.1.1.1"; sdef.vlan = 1234; sdef.port = 5678; - char *aid = port->attach( sdef, "test_sdds_port_api" ); + CORBA::String_var aid = port->attach( sdef, "test_sdds_port_api" ); CPPUNIT_ASSERT( aid != NULL ); BULKIO::SDDSStreamSequence *sss = port->attachedStreams(); @@ -455,7 +455,7 @@ void Bulkio_InPort_Fixture::test_port_api( bulkio::InSDDSPort *port ) { CPPUNIT_ASSERT( strcmp( paddr.c_str(), "1.1.1.1") == 0 ); delete sss; - char *uid = port->getUser(aid); + CORBA::String_var uid = port->getUser(aid); CPPUNIT_ASSERT( uid != NULL ); //std::cout << "user id " << uid << std::endl; CPPUNIT_ASSERT( strcmp( uid, "test_sdds_port_api" ) == 0 ); @@ -483,6 +483,7 @@ Bulkio_InPort_Fixture::test_create_int8() CPPUNIT_ASSERT( port != NULL ); CPPUNIT_ASSERT_NO_THROW( port ); + delete port; } @@ -497,7 +498,7 @@ Bulkio_InPort_Fixture::test_int8() test_stream_sri_changed( port ); CPPUNIT_ASSERT_NO_THROW( port ); - + delete port; } void @@ -507,6 +508,7 @@ Bulkio_InPort_Fixture::test_create_int16() CPPUNIT_ASSERT( port != NULL ); CPPUNIT_ASSERT_NO_THROW( port ); + delete port; } @@ -521,7 +523,7 @@ Bulkio_InPort_Fixture::test_int16() test_stream_sri_changed( port ); CPPUNIT_ASSERT_NO_THROW( port ); - + delete port; } void @@ -529,6 +531,7 @@ Bulkio_InPort_Fixture::test_create_int32() { bulkio::InInt32Port *port = new bulkio::InInt32Port("test_ctor_int32"); CPPUNIT_ASSERT( port != NULL ); + delete port; } void @@ -542,7 +545,7 @@ Bulkio_InPort_Fixture::test_int32() test_stream_sri_changed( port ); CPPUNIT_ASSERT_NO_THROW( port ); - + delete port; } @@ -551,6 +554,7 @@ Bulkio_InPort_Fixture::test_create_int64() { bulkio::InInt64Port *port = new bulkio::InInt64Port("test_ctor_int64"); CPPUNIT_ASSERT( port != NULL ); + delete port; } @@ -565,7 +569,7 @@ Bulkio_InPort_Fixture::test_int64() test_stream_sri_changed( port ); CPPUNIT_ASSERT_NO_THROW( port ); - + delete port; } @@ -574,6 +578,7 @@ Bulkio_InPort_Fixture::test_create_uint8() { bulkio::InUInt8Port *port = new bulkio::InUInt8Port("test_ctor_uint8"); CPPUNIT_ASSERT( port != NULL ); + delete port; } void @@ -587,7 +592,7 @@ Bulkio_InPort_Fixture::test_uint8() test_stream_sri_changed( port ); CPPUNIT_ASSERT_NO_THROW( port ); - + delete port; } void @@ -595,6 +600,7 @@ Bulkio_InPort_Fixture::test_create_uint16() { bulkio::InUInt16Port *port = new bulkio::InUInt16Port("test_ctor_uint16"); CPPUNIT_ASSERT( port != NULL ); + delete port; } void @@ -609,7 +615,7 @@ Bulkio_InPort_Fixture::test_uint16() CPPUNIT_ASSERT_NO_THROW( port ); - + delete port; } @@ -618,6 +624,7 @@ Bulkio_InPort_Fixture::test_create_uint32() { bulkio::InUInt32Port *port = new bulkio::InUInt32Port("test_ctor_uint32"); CPPUNIT_ASSERT( port != NULL ); + delete port; } void @@ -631,7 +638,7 @@ Bulkio_InPort_Fixture::test_uint32() test_stream_sri_changed( port ); CPPUNIT_ASSERT_NO_THROW( port ); - + delete port; } @@ -640,6 +647,7 @@ Bulkio_InPort_Fixture::test_create_uint64() { bulkio::InUInt64Port *port = new bulkio::InUInt64Port("test_ctor_uint64"); CPPUNIT_ASSERT( port != NULL ); + delete port; } void @@ -653,7 +661,7 @@ Bulkio_InPort_Fixture::test_uint64() test_stream_sri_changed( port ); CPPUNIT_ASSERT_NO_THROW( port ); - + delete port; } @@ -663,6 +671,7 @@ Bulkio_InPort_Fixture::test_create_float() { bulkio::InFloatPort *port = new bulkio::InFloatPort("test_ctor_float"); CPPUNIT_ASSERT( port != NULL ); + delete port; } @@ -671,6 +680,7 @@ Bulkio_InPort_Fixture::test_create_double() { bulkio::InDoublePort *port = new bulkio::InDoublePort("test_ctor_float"); CPPUNIT_ASSERT( port != NULL ); + delete port; } @@ -680,6 +690,7 @@ Bulkio_InPort_Fixture::test_create_file() { bulkio::InFilePort *port = new bulkio::InFilePort("test_ctor_file", logger ); CPPUNIT_ASSERT( port != NULL ); + delete port; } @@ -692,7 +703,7 @@ Bulkio_InPort_Fixture::test_file() test_port_api( port ); CPPUNIT_ASSERT_NO_THROW( port ); - + delete port; } @@ -701,6 +712,7 @@ Bulkio_InPort_Fixture::test_create_xml() { bulkio::InXMLPort *port = new bulkio::InXMLPort("test_ctor_xml", logger ); CPPUNIT_ASSERT( port != NULL ); + delete port; } @@ -714,7 +726,7 @@ Bulkio_InPort_Fixture::test_xml() test_port_api( port ); CPPUNIT_ASSERT_NO_THROW( port ); - + delete port; } @@ -723,6 +735,7 @@ Bulkio_InPort_Fixture::test_create_sdds() { bulkio::InSDDSPort *port = new bulkio::InSDDSPort("test_ctor_sdds", logger ); CPPUNIT_ASSERT( port != NULL ); + delete port; } @@ -736,5 +749,5 @@ Bulkio_InPort_Fixture::test_sdds() test_port_api( port ); CPPUNIT_ASSERT_NO_THROW( port ); - + delete port; } diff --git a/bulkioInterfaces/libsrc/testing/tests/cpp/Bulkio_MultiOut_Port.cpp b/bulkioInterfaces/libsrc/testing/tests/cpp/Bulkio_MultiOut_Port.cpp index 674eb7114..6dc040639 100644 --- a/bulkioInterfaces/libsrc/testing/tests/cpp/Bulkio_MultiOut_Port.cpp +++ b/bulkioInterfaces/libsrc/testing/tests/cpp/Bulkio_MultiOut_Port.cpp @@ -355,6 +355,7 @@ void Bulkio_MultiOut_Data_Port< OUT_PORT, IN_PORT >::test_multiout_sri_eos_filt CPPUNIT_ASSERT_MESSAGE( "getPacket - PKT was empty", pkt != NULL ); CPPUNIT_ASSERT_MESSAGE( "getPacket - StreamID Mismatch", strcmp( pkt->SRI.streamID, filter_stream_id.c_str() ) == 0 ); CPPUNIT_ASSERT_MESSAGE( "getPacket - EOS Mismatch:" , pkt->EOS == 1) ; + delete pkt; filter_stream_id = "stream-2-1"; this->port->pushPacket( v, TS, true, filter_stream_id ); @@ -362,6 +363,7 @@ void Bulkio_MultiOut_Data_Port< OUT_PORT, IN_PORT >::test_multiout_sri_eos_filt CPPUNIT_ASSERT_MESSAGE( "getPacket - PKT was empty", pkt != NULL ); CPPUNIT_ASSERT_MESSAGE( "getPacket - StreamID Mismatch", strcmp( pkt->SRI.streamID, filter_stream_id.c_str() ) == 0 ); CPPUNIT_ASSERT_MESSAGE( "getPacket - EOS Mismatch:" , pkt->EOS == 1) ; + delete pkt; filter_stream_id = "stream-3-1"; this->port->pushPacket( v, TS, true, filter_stream_id ); @@ -369,6 +371,7 @@ void Bulkio_MultiOut_Data_Port< OUT_PORT, IN_PORT >::test_multiout_sri_eos_filt CPPUNIT_ASSERT_MESSAGE( "getPacket - PKT was empty", pkt != NULL ); CPPUNIT_ASSERT_MESSAGE( "getPacket - StreamID Mismatch", strcmp( pkt->SRI.streamID, filter_stream_id.c_str() ) == 0 ); CPPUNIT_ASSERT_MESSAGE( "getPacket - EOS Mismatch:" , pkt->EOS == 1) ; + delete pkt; filter_stream_id = "stream-4-1"; this->port->pushPacket( v, TS, true, filter_stream_id ); @@ -376,6 +379,7 @@ void Bulkio_MultiOut_Data_Port< OUT_PORT, IN_PORT >::test_multiout_sri_eos_filt CPPUNIT_ASSERT_MESSAGE( "getPacket - PKT was empty", pkt != NULL ); CPPUNIT_ASSERT_MESSAGE( "getPacket - StreamID Mismatch", strcmp( pkt->SRI.streamID, filter_stream_id.c_str() ) == 0 ); CPPUNIT_ASSERT_MESSAGE( "getPacket - EOS Mismatch:" , pkt->EOS == 1) ; + delete pkt; streams = this->ip1->activeSRIs(); CPPUNIT_ASSERT_MESSAGE( "Multiout SRI Filtered - Port 1 Stream Failed", streams != NULL ); diff --git a/bulkioInterfaces/libsrc/testing/tests/cpp/Bulkio_OutPort_Fixture.cpp b/bulkioInterfaces/libsrc/testing/tests/cpp/Bulkio_OutPort_Fixture.cpp index 4c8001367..9e52facbc 100644 --- a/bulkioInterfaces/libsrc/testing/tests/cpp/Bulkio_OutPort_Fixture.cpp +++ b/bulkioInterfaces/libsrc/testing/tests/cpp/Bulkio_OutPort_Fixture.cpp @@ -396,6 +396,7 @@ Bulkio_OutPort_Fixture::test_create_int8() { bulkio::OutCharPort *port = new bulkio::OutCharPort("test_int8", logger ); CPPUNIT_ASSERT( port != NULL ); + delete port; } void @@ -409,6 +410,7 @@ Bulkio_OutPort_Fixture::test_int8() test_port_statistics(port); CPPUNIT_ASSERT_NO_THROW( port ); + delete port; } @@ -417,6 +419,7 @@ Bulkio_OutPort_Fixture::test_create_int16() { bulkio::OutInt16Port *port = new bulkio::OutInt16Port("test_ctor_int16", logger ); CPPUNIT_ASSERT( port != NULL ); + delete port; } @@ -431,6 +434,7 @@ Bulkio_OutPort_Fixture::test_int16() test_port_statistics(port); CPPUNIT_ASSERT_NO_THROW( port ); + delete port; } @@ -439,6 +443,7 @@ Bulkio_OutPort_Fixture::test_create_int32() { bulkio::OutInt32Port *port = new bulkio::OutInt32Port("test_ctor_int32", logger ); CPPUNIT_ASSERT( port != NULL ); + delete port; } void @@ -452,6 +457,7 @@ Bulkio_OutPort_Fixture::test_int32() test_port_statistics(port); CPPUNIT_ASSERT_NO_THROW( port ); + delete port; } @@ -461,6 +467,7 @@ Bulkio_OutPort_Fixture::test_create_int64() { bulkio::OutInt64Port *port = new bulkio::OutInt64Port("test_ctor_int64", logger ); CPPUNIT_ASSERT( port != NULL ); + delete port; } void @@ -474,6 +481,7 @@ Bulkio_OutPort_Fixture::test_int64() test_port_statistics(port); CPPUNIT_ASSERT_NO_THROW( port ); + delete port; } @@ -483,6 +491,7 @@ Bulkio_OutPort_Fixture::test_create_uint8() { bulkio::OutOctetPort *port = new bulkio::OutOctetPort("test_ctor_uint8", logger ); CPPUNIT_ASSERT( port != NULL ); + delete port; } void @@ -490,6 +499,7 @@ Bulkio_OutPort_Fixture::test_create_uint16() { bulkio::OutUInt16Port *port = new bulkio::OutUInt16Port("test_ctor_uint16", logger ); CPPUNIT_ASSERT( port != NULL ); + delete port; } void @@ -503,6 +513,7 @@ Bulkio_OutPort_Fixture::test_uint16() test_port_statistics(port); CPPUNIT_ASSERT_NO_THROW( port ); + delete port; } @@ -511,6 +522,7 @@ Bulkio_OutPort_Fixture::test_create_uint32() { bulkio::OutUInt32Port *port = new bulkio::OutUInt32Port("test_ctor_uint32", logger ); CPPUNIT_ASSERT( port != NULL ); + delete port; } void @@ -524,6 +536,7 @@ Bulkio_OutPort_Fixture::test_uint32() test_port_statistics(port); CPPUNIT_ASSERT_NO_THROW( port ); + delete port; } @@ -532,6 +545,7 @@ Bulkio_OutPort_Fixture::test_create_uint64() { bulkio::OutUInt64Port *port = new bulkio::OutUInt64Port("test_ctor_uint64", logger ); CPPUNIT_ASSERT( port != NULL ); + delete port; } void @@ -545,6 +559,7 @@ Bulkio_OutPort_Fixture::test_uint64() test_port_statistics(port); CPPUNIT_ASSERT_NO_THROW( port ); + delete port; } @@ -553,6 +568,7 @@ Bulkio_OutPort_Fixture::test_create_float() { bulkio::OutFloatPort *port = new bulkio::OutFloatPort("test_ctor_float", logger ); CPPUNIT_ASSERT( port != NULL ); + delete port; } void @@ -566,6 +582,7 @@ Bulkio_OutPort_Fixture::test_float() test_port_statistics(port); CPPUNIT_ASSERT_NO_THROW( port ); + delete port; } @@ -574,6 +591,7 @@ Bulkio_OutPort_Fixture::test_create_double() { bulkio::OutDoublePort *port = new bulkio::OutDoublePort("test_ctor_double", logger ); CPPUNIT_ASSERT( port != NULL ); + delete port; } void @@ -587,6 +605,7 @@ Bulkio_OutPort_Fixture::test_double() test_port_statistics(port); CPPUNIT_ASSERT_NO_THROW( port ); + delete port; } @@ -595,6 +614,7 @@ Bulkio_OutPort_Fixture::test_create_file() { bulkio::OutFilePort *port = new bulkio::OutFilePort("test_ctor_file", logger ); CPPUNIT_ASSERT( port != NULL ); + delete port; } void @@ -606,6 +626,7 @@ Bulkio_OutPort_Fixture::test_file() test_port_api< bulkio::OutFilePort, bulkio::InFilePort >( port ); CPPUNIT_ASSERT_NO_THROW( port ); + delete port; } @@ -614,6 +635,7 @@ Bulkio_OutPort_Fixture::test_create_xml() { bulkio::OutXMLPort *port = new bulkio::OutXMLPort("test_ctor_xml", logger ); CPPUNIT_ASSERT( port != NULL ); + delete port; } @@ -628,6 +650,7 @@ Bulkio_OutPort_Fixture::test_xml() test_port_api< bulkio::OutXMLPort, bulkio::InXMLPort >( port ); CPPUNIT_ASSERT_NO_THROW( port ); + delete port; } @@ -636,6 +659,7 @@ Bulkio_OutPort_Fixture::test_create_sdds() { bulkio::OutSDDSPort *port = new bulkio::OutSDDSPort("test_ctor_sdds", logger); CPPUNIT_ASSERT( port != NULL ); + delete port; } @@ -650,6 +674,7 @@ Bulkio_OutPort_Fixture::test_sdds() test_port_api< bulkio::OutSDDSPort, bulkio::InSDDSPort > ( port ); CPPUNIT_ASSERT_NO_THROW( port ); + delete port; } @@ -662,4 +687,5 @@ Bulkio_OutPort_Fixture::test_sdds_sri() test_port_sri< bulkio::OutSDDSPort, bulkio::InSDDSPort > ( port ); CPPUNIT_ASSERT_NO_THROW( port ); + delete port; } diff --git a/redhawk/src/base/framework/UsesPort.cpp b/redhawk/src/base/framework/UsesPort.cpp index fd489a9fd..bf3f3ac85 100644 --- a/redhawk/src/base/framework/UsesPort.cpp +++ b/redhawk/src/base/framework/UsesPort.cpp @@ -62,6 +62,13 @@ namespace redhawk { { } + UsesPort::~UsesPort() + { + for (TransportList::iterator port = _transports.begin(); port != _transports.end(); ++port) { + delete *port; + } + } + void UsesPort::connectPort(CORBA::Object_ptr connection, const char* connectionId) { RH_TRACE_ENTER(logger); diff --git a/redhawk/src/base/include/ossie/UsesPort.h b/redhawk/src/base/include/ossie/UsesPort.h index 2c0339edd..c1e0635c6 100644 --- a/redhawk/src/base/include/ossie/UsesPort.h +++ b/redhawk/src/base/include/ossie/UsesPort.h @@ -81,6 +81,7 @@ namespace redhawk { { public: UsesPort(const std::string& name); + virtual ~UsesPort(); // Register the member function 'func' to be called on class instance // 'target' when a new connection is made. The function receives one From 8a131dce5c22794c5cd848ad3f02a80e62161f7b Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 23 Mar 2017 14:55:21 -0400 Subject: [PATCH 0758/1644] Replacement test for CF-1729 that specifically targets load() and does not modify existing test soft packages (to reduce cascading failures) --- .../testing/tests/test_01_DomainManager.py | 17 -------------- .../tests/test_05_LoadableDeviceTest.py | 23 +++++++++++++++++++ 2 files changed, 23 insertions(+), 17 deletions(-) diff --git a/redhawk/src/testing/tests/test_01_DomainManager.py b/redhawk/src/testing/tests/test_01_DomainManager.py index d30afea77..b94c80884 100644 --- a/redhawk/src/testing/tests/test_01_DomainManager.py +++ b/redhawk/src/testing/tests/test_01_DomainManager.py @@ -621,23 +621,6 @@ def test_createApplicationFailures_comp_bad_dep_ref(self): ## reset file shutil.copy(comp_spd+".ORIG", comp_spd) - def test_createApplicationFailures_deps_readissue_dir(self): - wf_name=self.wf_name - sadfile=self.sadfile - - dep_dir=scatest.getSdrPath()+"/dom/deps/cpp_dep2/cpp/lib" - os.chmod(dep_dir,0000) - comp_spd=scatest.getSdrPath()+"/dom/components/cpp_with_deps/cpp_with_deps.spd.xml" - shutil.copy(comp_spd+".TEST.readissue", comp_spd) - self.assertRaises( CF.ApplicationFactory.CreateApplicationError, self._domMgr.createApplication, sadfile, "", [], []) - try: - self._domMgr.createApplication(sadfile, "", [], []) - except Exception, e: - self.assertEqual(e.msg,'Failed to load file') - ## reset file - os.chmod(dep_dir,0775) - shutil.copy(comp_spd+".ORIG", comp_spd) - def test_createApplicationFailures_dep_missing(self): wf_name=self.wf_name sadfile=self.sadfile diff --git a/redhawk/src/testing/tests/test_05_LoadableDeviceTest.py b/redhawk/src/testing/tests/test_05_LoadableDeviceTest.py index 443c7dee8..704c956bf 100644 --- a/redhawk/src/testing/tests/test_05_LoadableDeviceTest.py +++ b/redhawk/src/testing/tests/test_05_LoadableDeviceTest.py @@ -697,3 +697,26 @@ def test_cpp_LoadOctaveDir(self): def test_py_LoadOctaveDir(self): self._test_LoadOctaveDir('test_ExecutableDevicePy_node') + + def _test_NoAccessDir(self, nodeName): + devBooter, devMgr = self.launchDeviceManager("/nodes/%s/DeviceManager.dcd.xml" % nodeName) + device = devMgr._get_registeredDevices()[0] + + dirname = '/noaccess' + testdir = os.path.join(scatest.getSdrPath(), 'dom' + dirname) + if not os.path.exists(testdir): + os.mkdir(testdir, 0000) + else: + os.chmod(testdir, 0000) + + fileMgr = self._domMgr._get_fileMgr() + try: + self.assertRaises(CF.LoadableDevice.LoadFail, device.load, fileMgr, dirname, CF.LoadableDevice.SHARED_LIBRARY) + finally: + os.rmdir(testdir) + + def test_cpp_NoAccessDir(self): + self._test_NoAccessDir('test_ExecutableDevice_node') + + def test_py_NoAccessDir(self): + self._test_NoAccessDir('test_ExecutableDevicePy_node') From debba0e73fa992666b879dcbbb3f54f26134a9de Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 24 Mar 2017 15:49:52 -0400 Subject: [PATCH 0759/1644] Make BulkIO, BurstIO and FRONTEND libraries closed (i.e., fully linked) so that they can be always be dynamically loaded by ComponentHost --- bulkioInterfaces/libsrc/Makefile.am | 2 ++ burstioInterfaces/src/cpp/Makefile.am | 4 ++-- frontendInterfaces/libsrc/Makefile.am | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/bulkioInterfaces/libsrc/Makefile.am b/bulkioInterfaces/libsrc/Makefile.am index 8aa399d98..dc053f756 100644 --- a/bulkioInterfaces/libsrc/Makefile.am +++ b/bulkioInterfaces/libsrc/Makefile.am @@ -84,6 +84,8 @@ library_include_HEADERS = cpp/include/bulkio/bulkio.h \ libbulkio_@BULKIO_API_VERSION@_la_CXXFLAGS = -Wall -I $(srcdir)/cpp -I $(srcdir)/cpp/include/bulkio -DLOGGING $(BULKIOINTERFACES_CFLAGS) $(BOOST_CPPFLAGS) $(OMNIORB_CFLAGS) $(OSSIE_CFLAGS) +libbulkio_@BULKIO_API_VERSION@_la_LIBADD = $(top_builddir)/libbulkioInterfaces.la + ############################################################################### # Python diff --git a/burstioInterfaces/src/cpp/Makefile.am b/burstioInterfaces/src/cpp/Makefile.am index 0df3c2ff0..0ce007752 100644 --- a/burstioInterfaces/src/cpp/Makefile.am +++ b/burstioInterfaces/src/cpp/Makefile.am @@ -56,6 +56,7 @@ nobase_nodist_include_HEADERS = redhawk/BURSTIO/burstioDataTypes.h \ redhawk/BURSTIO/burstio_burstUshort.h libburstioInterfaces_la_CPPFLAGS = -I . $(OSSIE_CFLAGS) +libburstioInterfaces_la_LDFLAGS = -lbulkioInterfaces BUILT_SOURCES = $(nobase_nodist_include_HEADERS) $(nodist_libburstioInterfaces_la_SOURCES) CLEANFILES = $(BUILT_SOURCES) @@ -100,8 +101,7 @@ libburstio_la_SOURCES += lib/OutPortImpl.h libburstio_la_SOURCES += lib/utils.cpp libburstio_la_CPPFLAGS = -I $(srcdir)/include -I redhawk $(OSSIE_CFLAGS) $(BOOST_CPPFLAGS) -libburstio_la_LIBADD = $(BOOST_LDFLAGS) -libburstio_la_LDFLAGS = -lburstioInterfaces +libburstio_la_LIBADD = $(BOOST_LDFLAGS) $(builddir)/libburstioInterfaces.la $(BULKIO_LIBS) libincludedir = $(includedir)/redhawk/burstio libinclude_HEADERS = include/burstio/burstio.h diff --git a/frontendInterfaces/libsrc/Makefile.am b/frontendInterfaces/libsrc/Makefile.am index 37f8d3ec0..349c1d3e7 100644 --- a/frontendInterfaces/libsrc/Makefile.am +++ b/frontendInterfaces/libsrc/Makefile.am @@ -33,7 +33,7 @@ ACLOCAL_AMFLAGS = ${ACLOCAL_FLAGS} lib_LTLIBRARIES = libfrontend-@FRONTEND_API_VERSION@.la libfrontend_@FRONTEND_API_VERSION@_la_LDFLAGS = -version-info $(FRONTEND_SO_VERSION) -libfrontend_@FRONTEND_API_VERSION@_la_LIBADD = $(BULKIO_LIBS) $(OSSIE_LIBS) +libfrontend_@FRONTEND_API_VERSION@_la_LIBADD = $(BULKIO_LIBS) $(OSSIE_LIBS) $(top_builddir)/libfrontendInterfaces.la libfrontend_@FRONTEND_API_VERSION@_la_SOURCES = \ cpp/fe_rfsource_port_impl.cpp \ From 143b221d09989f289a8e54a23b22332d76f53c08 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 27 Mar 2017 10:49:17 -0400 Subject: [PATCH 0760/1644] On tests that depend on files not being accessible to the current user, check the access after chmod() to ensure the base OS assumption is correct --- redhawk/src/testing/tests/test_01_DeviceManager.py | 6 ++++-- redhawk/src/testing/tests/test_05_FileSystem.py | 6 ++++-- redhawk/src/testing/tests/test_05_LoadableDeviceTest.py | 3 ++- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/redhawk/src/testing/tests/test_01_DeviceManager.py b/redhawk/src/testing/tests/test_01_DeviceManager.py index 08c011e8d..12e20a1e0 100644 --- a/redhawk/src/testing/tests/test_01_DeviceManager.py +++ b/redhawk/src/testing/tests/test_01_DeviceManager.py @@ -76,8 +76,10 @@ def tearDown(self): (status,output) = commands.getstatusoutput('rm -rf devmgr_runtest.props') def test_NoWriteCache(self): - (status,output) = commands.getstatusoutput('mkdir -p '+os.getcwd()+'/sdr/cache/.BasicTestDevice_node') - (status,output) = commands.getstatusoutput('chmod 000 '+os.getcwd()+'/sdr/cache/.BasicTestDevice_node') + cachedir = os.getcwd()+'/sdr/cache/.BasicTestDevice_node' + (status,output) = commands.getstatusoutput('mkdir -p '+cachedir) + (status,output) = commands.getstatusoutput('chmod 000 '+cachedir) + self.assertFalse(os.access(cachedir, os.R_OK|os.W_OK|os.X_OK), 'Current user can still access directory') devmgr_nb, devMgr = self.launchDeviceManager("/nodes/test_BasicTestDevice_node/DeviceManager.dcd.xml") self.assertEquals(255, devmgr_nb.returncode) self.assertEquals(devMgr, None) diff --git a/redhawk/src/testing/tests/test_05_FileSystem.py b/redhawk/src/testing/tests/test_05_FileSystem.py index 9d13cdc90..736064061 100644 --- a/redhawk/src/testing/tests/test_05_FileSystem.py +++ b/redhawk/src/testing/tests/test_05_FileSystem.py @@ -630,6 +630,9 @@ def test_readException(self): # Issue #533 self.assertRaises(CF.DomainManager.ApplicationInstallationError, self._domMgr.installApplication, '/waveforms') def test_ExistsException(self): + self.assertNotEqual(self._domMgr, None) + fileMgr = self._domMgr._get_fileMgr() + # Makes sure that FileSystem::exists() throws correct exception and # doesn't kill domain for files in directories it cannot access dirname = '/noaccess' @@ -639,9 +642,8 @@ def test_ExistsException(self): else: os.chmod(testdir, 0644) - self.assertNotEqual(self._domMgr, None) - fileMgr = self._domMgr._get_fileMgr() try: + self.assertFalse(os.access(testdir, os.R_OK|os.X_OK), 'Current user can still access directory') self.assertRaises(CF.InvalidFileName, fileMgr.exists, os.path.join(dirname, 'testfile')) finally: os.rmdir(testdir) diff --git a/redhawk/src/testing/tests/test_05_LoadableDeviceTest.py b/redhawk/src/testing/tests/test_05_LoadableDeviceTest.py index 704c956bf..312b5f329 100644 --- a/redhawk/src/testing/tests/test_05_LoadableDeviceTest.py +++ b/redhawk/src/testing/tests/test_05_LoadableDeviceTest.py @@ -701,6 +701,7 @@ def test_py_LoadOctaveDir(self): def _test_NoAccessDir(self, nodeName): devBooter, devMgr = self.launchDeviceManager("/nodes/%s/DeviceManager.dcd.xml" % nodeName) device = devMgr._get_registeredDevices()[0] + fileMgr = self._domMgr._get_fileMgr() dirname = '/noaccess' testdir = os.path.join(scatest.getSdrPath(), 'dom' + dirname) @@ -709,8 +710,8 @@ def _test_NoAccessDir(self, nodeName): else: os.chmod(testdir, 0000) - fileMgr = self._domMgr._get_fileMgr() try: + self.assertFalse(os.access(testdir, os.R_OK|os.X_OK), 'Current user can still access directory') self.assertRaises(CF.LoadableDevice.LoadFail, device.load, fileMgr, dirname, CF.LoadableDevice.SHARED_LIBRARY) finally: os.rmdir(testdir) From 92f706b76530fe11be649a400f062071c862d491 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 27 Mar 2017 13:13:17 -0400 Subject: [PATCH 0761/1644] CF-1710 Use a string sequence property in ComponentHost to control the set of preloaded libraries. This limits the set of libraries that we try to load, but in a dynamic way (default list is in ComponentHost's PRF, but could be overridden by the Domain/Sandbox). The preloading is also more fault-tolerant, so that a bad library won't prevent ComponentHost from working. Because the mechanism is different than the normal ModuleBundle mode of operation, the "default" bundle was eliminated, as there is no concern about trying to unload the preloaded libraries. --- .../sdr/ComponentHost/ComponentHost.cpp | 41 +++++++++++++------ .../control/sdr/ComponentHost/ComponentHost.h | 5 ++- .../sdr/ComponentHost/ComponentHost.prf.xml | 13 +++++- .../sdr/ComponentHost/ModuleLoader.cpp | 25 ++++++++--- .../control/sdr/ComponentHost/ModuleLoader.h | 5 ++- 5 files changed, 68 insertions(+), 21 deletions(-) diff --git a/redhawk/src/control/sdr/ComponentHost/ComponentHost.cpp b/redhawk/src/control/sdr/ComponentHost/ComponentHost.cpp index 3bd9e87ff..95cbeb689 100644 --- a/redhawk/src/control/sdr/ComponentHost/ComponentHost.cpp +++ b/redhawk/src/control/sdr/ComponentHost/ComponentHost.cpp @@ -36,30 +36,44 @@ PREPARE_LOGGING(ComponentHost); ComponentHost::ComponentHost(const char* identifier, const char* label) : Component(identifier, label), - defaultBundle("default"), counter(0) { - executorService.start(); + loadProperties(); } ComponentHost::~ComponentHost() { executorService.stop(); - defaultBundle.clear(); +} + +void ComponentHost::loadProperties() +{ + addProperty(preload, + preload, + "preload", + "", + "readwrite", + "", + "external", + "property"); } void ComponentHost::constructor() { - // Preload libraries from $OSSIEHOME/lib to ensure that they are always - // available. This prevents common libraries like BulkIO from being loaded - // implicitly by components, which can lead to the component library being - // unable to be unloaded. - const char* ossiehome = getenv("OSSIEHOME"); - if (ossiehome) { - std::string libpath = std::string(ossiehome) + "/lib"; - if (fs::exists(libpath) && fs::is_directory(libpath)) { - LOG_DEBUG(ComponentHost, "Loading default libraries from " << libpath); - defaultBundle.loadDirectory(libpath, ModuleLoader::LAZY, ModuleLoader::GLOBAL); + executorService.start(); + + // Preload libraries as given in initial configuration (in most cases, this + // will be the PRF value, because ComponentHost is implicitly launched by + // the Domain or the Sandbox). This allows us to prevent common libraries + // like BulkIO from being loaded implicitly by components, which can lead + // to the component library being unable to be unloaded. + LOG_DEBUG(ComponentHost, "Preloading " << preload.size() << " libraries"); + for (std::vector::iterator libname = preload.begin(); libname != preload.end(); ++libname) { + try { + ModuleLoader::Preload(*libname, ModuleLoader::LAZY, ModuleLoader::GLOBAL); + } catch (const std::exception& exc) { + // NB: The library name should be at the front of the error message + LOG_WARN(ComponentHost, "Unable to preload library " << exc.what()); } } } @@ -237,3 +251,4 @@ void ComponentHost::cleanupComponent(ComponentEntry* component) boost::system_time when = boost::get_system_time() + boost::posix_time::microseconds(125); executorService.schedule(when, &ComponentHost::cleanupComponent, this, component); } + diff --git a/redhawk/src/control/sdr/ComponentHost/ComponentHost.h b/redhawk/src/control/sdr/ComponentHost/ComponentHost.h index 7400bb6b2..f1e399b7f 100644 --- a/redhawk/src/control/sdr/ComponentHost/ComponentHost.h +++ b/redhawk/src/control/sdr/ComponentHost/ComponentHost.h @@ -59,12 +59,13 @@ namespace redhawk { virtual CF::ExecutableDevice::ProcessID_Type executeLinked(const char* name, const CF::Properties& options, const CF::Properties& parameters, const CF::StringSequence& deps); private: + void loadProperties(); + void componentReleased(Resource_impl* object); void cleanupComponent(ComponentEntry* entry); std::string getRealPath(const std::string& path); - ModuleBundle defaultBundle; int counter; boost::mutex loadMutex; @@ -74,6 +75,8 @@ namespace redhawk { // Threaded service for performing cleanup checks redhawk::ExecutorService executorService; + /// Property: preload + std::vector preload; }; } diff --git a/redhawk/src/control/sdr/ComponentHost/ComponentHost.prf.xml b/redhawk/src/control/sdr/ComponentHost/ComponentHost.prf.xml index 0bce0fe97..6890aa7ee 100644 --- a/redhawk/src/control/sdr/ComponentHost/ComponentHost.prf.xml +++ b/redhawk/src/control/sdr/ComponentHost/ComponentHost.prf.xml @@ -19,4 +19,15 @@ You should have received a copy of the GNU Lesser General Public License along with this program. If not, see http://www.gnu.org/licenses/. --> - + + + List of shared libraries to be preloaded by ComponentHost at startup time, to be made available for all components launched inside of this ComponentHost instance. + + libbulkio-2.1.so + libburstio.so + libfrontend-2.4.so + + + + + diff --git a/redhawk/src/control/sdr/ComponentHost/ModuleLoader.cpp b/redhawk/src/control/sdr/ComponentHost/ModuleLoader.cpp index 479db6643..a5eb35b90 100644 --- a/redhawk/src/control/sdr/ComponentHost/ModuleLoader.cpp +++ b/redhawk/src/control/sdr/ComponentHost/ModuleLoader.cpp @@ -150,6 +150,11 @@ ModuleLoader& ModuleLoader::Instance() return loader; } +void ModuleLoader::Preload(const std::string& path, LoadBinding binding, LoadVisibility visibility) +{ + Instance().preload(path, binding, visibility); +} + Module* ModuleLoader::Load(const std::string& path, LoadBinding binding, LoadVisibility visibility) { return Instance().load(path, binding, visibility); @@ -160,6 +165,21 @@ void ModuleLoader::Unload(Module* module) Instance().unload(module); } +void ModuleLoader::preload(const std::string& filename, LoadBinding binding, LoadVisibility visibility) +{ + // Preloading does not go through the normal module resolution that loading + // does, because the use case is different: + // * filename will usually be just a module name (e.g., "libbulkio-2.1.so") + // that is located via LD_LIBRARY_PATH + // * preloaded libraries are not unloaded, so no need to reference count + LOG_DEBUG(ModuleLoader, "Preloading module " << filename); + int flags = binding | visibility; + void* handle = dlopen(filename.c_str(), flags); + if (!handle) { + throw std::runtime_error(dlerror()); + } +} + Module* ModuleLoader::load(const std::string& filename, LoadBinding binding, LoadVisibility visibility) { // Use the real path (symlinks followed, relative paths removed) to avoid @@ -267,10 +287,5 @@ void ModuleBundle::unload() { // Unload modules in reverse order of loading std::for_each(_modules.rbegin(), _modules.rend(), &ModuleLoader::Unload); - clear(); -} - -void ModuleBundle::clear() -{ _modules.clear(); } diff --git a/redhawk/src/control/sdr/ComponentHost/ModuleLoader.h b/redhawk/src/control/sdr/ComponentHost/ModuleLoader.h index 1e30d3ef2..07af4f993 100644 --- a/redhawk/src/control/sdr/ComponentHost/ModuleLoader.h +++ b/redhawk/src/control/sdr/ComponentHost/ModuleLoader.h @@ -75,6 +75,8 @@ namespace redhawk { LOCAL = RTLD_LOCAL }; + static void Preload(const std::string& path, LoadBinding binding, LoadVisibility visibility); + static Module* Load(const std::string& path, LoadBinding binding, LoadVisibility visibility); static void Unload(Module* module); @@ -83,6 +85,8 @@ namespace redhawk { static ModuleLoader& Instance(); + void preload(const std::string& path, LoadBinding binding, LoadVisibility visibility); + Module* load(const std::string& path, LoadBinding binding, LoadVisibility visibility); void unload(Module* module); @@ -106,7 +110,6 @@ namespace redhawk { void loadDirectory(const std::string& path, ModuleLoader::LoadBinding binding, ModuleLoader::LoadVisibility visibility); void unload(); - void clear(); private: const std::string _name; From acb97560c5edc213544da4de70b0e2326940a41b Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 27 Mar 2017 14:34:52 -0400 Subject: [PATCH 0762/1644] CF-1710 Turn warning into an exception when a library is already loaded and has been modified --- .../sdr/ComponentHost/ComponentHost.cpp | 20 ++++++++++++------- .../sdr/ComponentHost/ModuleLoader.cpp | 3 +-- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/redhawk/src/control/sdr/ComponentHost/ComponentHost.cpp b/redhawk/src/control/sdr/ComponentHost/ComponentHost.cpp index 95cbeb689..0a9ea417a 100644 --- a/redhawk/src/control/sdr/ComponentHost/ComponentHost.cpp +++ b/redhawk/src/control/sdr/ComponentHost/ComponentHost.cpp @@ -176,24 +176,30 @@ CF::ExecutableDevice::ProcessID_Type ComponentHost::executeLinked(const char* na bundle->load(libpath, ModuleLoader::LAZY, ModuleLoader::LOCAL); } } catch (const std::exception& exc) { - throw CF::InvalidFileName(CF::CF_EINVAL, exc.what()); + LOG_ERROR(ComponentHost, "Unable to load dependency: " << exc.what()); + throw CF::ExecutableDevice::ExecuteFail(CF::CF_EINVAL, exc.what()); } } - typedef Resource_impl* (*ConstructorPtr)(const std::string&, const std::string&); - ConstructorPtr make_component; + LOG_DEBUG(ComponentHost, "Loading component module: " << path); + Module* module; try { // Resolve all required symbols now so that we can catch the error and // turn it into an exception, rather than having the process exit at // point-of-use - Module* module = bundle->load(path, ModuleLoader::NOW, ModuleLoader::LOCAL); + module = bundle->load(path, ModuleLoader::NOW, ModuleLoader::LOCAL); + } catch (const std::exception& exc) { + LOG_ERROR(ComponentHost, "Unable to load module: " << exc.what()) + throw CF::ExecutableDevice::ExecuteFail(CF::CF_EINVAL, exc.what()); + } + + typedef Resource_impl* (*ConstructorPtr)(const std::string&, const std::string&); + ConstructorPtr make_component; + try { LOG_DEBUG(ComponentHost, "Resolving module entry point"); make_component = reinterpret_cast(module->symbol("make_component")); } catch (const std::exception& exc) { LOG_ERROR(ComponentHost, "Unable to load module entry point: " << exc.what()) - make_component = 0; - } - if (!make_component) { throw CF::ExecutableDevice::InvalidFunction(); } diff --git a/redhawk/src/control/sdr/ComponentHost/ModuleLoader.cpp b/redhawk/src/control/sdr/ComponentHost/ModuleLoader.cpp index a5eb35b90..60fa9ae94 100644 --- a/redhawk/src/control/sdr/ComponentHost/ModuleLoader.cpp +++ b/redhawk/src/control/sdr/ComponentHost/ModuleLoader.cpp @@ -197,8 +197,7 @@ Module* ModuleLoader::load(const std::string& filename, LoadBinding binding, Loa _modules[path] = module; } else { if (module->modified()) { - LOG_WARN(ModuleLoader, "Dynamic library " << module->name() << " has been modified since it was loaded" - << " (" << path << ")"); + throw std::runtime_error(path + ": library is already loaded but has been modified"); } module->incref(); } From aa352f4268e244676360d14d546a22ad200fa5be Mon Sep 17 00:00:00 2001 From: Max Robert Date: Tue, 28 Mar 2017 16:10:01 -0400 Subject: [PATCH 0763/1644] Refs CF-1739. Test for the interactive feature deprecation is more forgiving for additional test in output --- redhawk/src/testing/tests/test_13_TestSB.py | 24 ++++++++------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/redhawk/src/testing/tests/test_13_TestSB.py b/redhawk/src/testing/tests/test_13_TestSB.py index 71f8ca249..fc6ad1f28 100644 --- a/redhawk/src/testing/tests/test_13_TestSB.py +++ b/redhawk/src/testing/tests/test_13_TestSB.py @@ -84,17 +84,15 @@ def tearDown(self): def test_NoInteractiveJavaService(self): status, output=commands.getstatusoutput('sdr/dev/services/BasicService_java/java/startJava.sh -i') - self.assertEquals(output,self.message) + self.assertNotEquals(output.find(self.message),-1) def test_NoInteractiveJavaDevice(self): - print os.getcwd() status, output=commands.getstatusoutput('sdr/dev/devices/BasicTestDevice_java/java/startJava.sh -i') - self.assertEquals(output,self.message) + self.assertNotEquals(output.find(self.message),-1) def test_NoInteractiveJavaComponent(self): - print os.getcwd() status, output=commands.getstatusoutput('sdr/dom/components/ECM_JAVA/java/startJava.sh -i') - self.assertEquals(output,self.message) + self.assertNotEquals(output.find(self.message),-1) class InteractiveTestPython(scatest.CorbaTestCase): def setUp(self): @@ -105,17 +103,15 @@ def tearDown(self): def test_NoInteractivePythonService(self): status, output=commands.getstatusoutput('sdr/dev/services/S1/python/S1.py -i') - self.assertEquals(output,self.message) + self.assertNotEquals(output.find(self.message),-1) def test_NoInteractivePythonDevice(self): - print os.getcwd() status, output=commands.getstatusoutput('sdr/dev/devices/BasicTestDevice/BasicTestDevice.py -i') - self.assertEquals(output,"DEBUG:root:Starting Device\n"+self.message) + self.assertNotEquals(output.find(self.message),-1) def test_NoInteractivePythonComponent(self): - print os.getcwd() status, output=commands.getstatusoutput('sdr/dom/components/ECM_PY/python/ECM_PY.py -i') - self.assertEquals(output,self.message) + self.assertNotEquals(output.find(self.message),-1) class InteractiveTestCpp(scatest.CorbaTestCase): def setUp(self): @@ -126,17 +122,15 @@ def tearDown(self): def test_NoInteractiveCppService(self): status, output=commands.getstatusoutput('sdr/dev/services/BasicService_cpp/cpp/BasicService_cpp -i') - self.assertEquals(output,self.message) + self.assertNotEquals(output.find(self.message),-1) def test_NoInteractiveCppDevice(self): - print os.getcwd() status, output=commands.getstatusoutput('sdr/dev/devices/cpp_dev/cpp/cpp_dev -i') - self.assertEquals(output,self.message) + self.assertNotEquals(output.find(self.message),-1) def test_NoInteractiveCppComponent(self): - print os.getcwd() status, output=commands.getstatusoutput('sdr/dom/components/ECM_CPP/cpp/ECM_CPP -i') - self.assertEquals(output,self.message) + self.assertNotEquals(output.find(self.message),-1) class SBEventChannelTest(scatest.CorbaTestCase): def setUp(self): From 574d3c5d4c0ddabc102d5ea3d8bc84027606154e Mon Sep 17 00:00:00 2001 From: Ryan Bauman Date: Thu, 30 Mar 2017 14:03:30 -0400 Subject: [PATCH 0764/1644] RELENG-595 - update framework version to 2.1.1 --- .gitlab-ci.yml | 5 ++--- GPP/GPP.spd.xml | 2 +- GPP/GPP.spec | 4 ++-- GPP/build.sh | 6 +++--- GPP/cpp/configure.ac | 2 +- bulkioInterfaces/build.sh | 6 +++--- bulkioInterfaces/bulkioInterfaces.spec | 4 ++-- bulkioInterfaces/configure.ac | 4 ++-- bulkioInterfaces/libsrc/setup.py | 2 +- burstioInterfaces/burstioInterfaces.spec | 4 ++-- burstioInterfaces/configure.ac | 6 +++--- frontendInterfaces/build.sh | 6 +++--- frontendInterfaces/configure.ac | 4 ++-- frontendInterfaces/frontendInterfaces.spec | 12 ++++++------ frontendInterfaces/libsrc/setup.py | 2 +- redhawk-codegen/redhawk-codegen.spec | 4 ++-- redhawk-codegen/redhawk/codegen/versions.py | 2 +- redhawk/src/base/framework/python/ossie/version.py | 2 +- redhawk/src/configure.ac | 2 +- redhawk/src/releng/redhawk.spec | 4 ++-- redhawk/src/testing/setup.py | 2 +- 21 files changed, 42 insertions(+), 43 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 7b66c7c34..e43900688 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,7 +1,6 @@ variables: - DOCKER_REGISTRY_URL: '' - REDHAWK_VERSION: '2.1.0' - FRONTEND_VERSION: '2.4.0' + REDHAWK_VERSION: '2.1.1' + FRONTEND_VERSION: '2.4.1' stages: - build diff --git a/GPP/GPP.spd.xml b/GPP/GPP.spd.xml index 12d3007ee..a85806866 100644 --- a/GPP/GPP.spd.xml +++ b/GPP/GPP.spd.xml @@ -19,7 +19,7 @@ details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see http://www.gnu.org/licenses/. --> - + Redhawk GPP null diff --git a/GPP/GPP.spec b/GPP/GPP.spec index 84d88cf77..a070b246e 100644 --- a/GPP/GPP.spec +++ b/GPP/GPP.spec @@ -31,8 +31,8 @@ Prefix: %{_prefix} %define _infodir %{_prefix}/info Name: GPP -Version: 2.1.0 -Release: 3%{?dist} +Version: 2.1.1 +Release: 1%{?dist} Summary: REDHAWK GPP Group: Applications/Engineering diff --git a/GPP/build.sh b/GPP/build.sh index 2c86df2d8..02d81ed5d 100755 --- a/GPP/build.sh +++ b/GPP/build.sh @@ -24,9 +24,9 @@ if [ "$1" = "rpm" ]; then if [ -e GPP.spec ]; then mydir=`dirname $0` tmpdir=`mktemp -d` - cp -r ${mydir} ${tmpdir}/GPP-2.1.0 - tar czf ${tmpdir}/GPP-2.1.0.tar.gz --exclude=".svn" -C ${tmpdir} GPP-2.1.0 - rpmbuild -ta ${tmpdir}/GPP-2.1.0.tar.gz + cp -r ${mydir} ${tmpdir}/GPP-2.1.1 + tar czf ${tmpdir}/GPP-2.1.1.tar.gz --exclude=".svn" -C ${tmpdir} GPP-2.1.1 + rpmbuild -ta ${tmpdir}/GPP-2.1.1.tar.gz rm -rf $tmpdir else echo "Missing RPM spec file in" `pwd` diff --git a/GPP/cpp/configure.ac b/GPP/cpp/configure.ac index 578c9be46..5a47d725b 100644 --- a/GPP/cpp/configure.ac +++ b/GPP/cpp/configure.ac @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see http://www.gnu.org/licenses/. */ -AC_INIT(GPP, 2.1.0) +AC_INIT(GPP, 2.1.1) AM_INIT_AUTOMAKE([foreign nostdinc subdir-objects]) AC_CONFIG_MACRO_DIR([m4]) diff --git a/bulkioInterfaces/build.sh b/bulkioInterfaces/build.sh index 262c304a2..28273ddf1 100755 --- a/bulkioInterfaces/build.sh +++ b/bulkioInterfaces/build.sh @@ -25,9 +25,9 @@ elif [ "$1" = "rpm" ]; then # A very simplistic RPM build scenario mydir=`dirname $0` tmpdir=`mktemp -d` - cp -r ${mydir} ${tmpdir}/bulkioInterfaces-2.1.0 - tar czf ${tmpdir}/bulkioInterfaces-2.1.0.tar.gz --exclude=".git" -C ${tmpdir} bulkioInterfaces-2.1.0 - rpmbuild -ta ${tmpdir}/bulkioInterfaces-2.1.0.tar.gz + cp -r ${mydir} ${tmpdir}/bulkioInterfaces-2.1.1 + tar czf ${tmpdir}/bulkioInterfaces-2.1.1.tar.gz --exclude=".git" -C ${tmpdir} bulkioInterfaces-2.1.1 + rpmbuild -ta ${tmpdir}/bulkioInterfaces-2.1.1.tar.gz rm -rf $tmpdir else # Checks if build is newer than makefile (based on modification time) diff --git a/bulkioInterfaces/bulkioInterfaces.spec b/bulkioInterfaces/bulkioInterfaces.spec index 578102a3a..0ecbc4d11 100644 --- a/bulkioInterfaces/bulkioInterfaces.spec +++ b/bulkioInterfaces/bulkioInterfaces.spec @@ -28,8 +28,8 @@ Prefix: %{_prefix} %bcond_without java Name: bulkioInterfaces -Version: 2.1.0 -Release: 3%{?dist} +Version: 2.1.1 +Release: 1%{?dist} Summary: The bulkio library for REDHAWK Group: Applications/Engineering diff --git a/bulkioInterfaces/configure.ac b/bulkioInterfaces/configure.ac index 08f01d45c..0a60fbf69 100644 --- a/bulkioInterfaces/configure.ac +++ b/bulkioInterfaces/configure.ac @@ -18,7 +18,7 @@ # along with this program. If not, see http://www.gnu.org/licenses/. # -AC_INIT(bulkioInterfaces, 2.1.0) +AC_INIT(bulkioInterfaces, 2.1.1) AC_CONFIG_MACRO_DIR([m4]) AC_SUBST([LIBBULKIOINTERFACES_VERSION_INFO], [3:0:1]) @@ -44,7 +44,7 @@ fi PKG_CHECK_MODULES([OMNIORB], [omniORB4 >= 4.1.0]) RH_PKG_IDLDIR([OMNIORB], [omniORB4]) -PKG_CHECK_MODULES([OSSIE], [ossie >= 2.1.0]) +PKG_CHECK_MODULES([OSSIE], [ossie >= 2.1.1]) RH_PKG_IDLDIR([OSSIE], [ossie]) PKG_CHECK_MODULES([OMNICOS], [omniCOS4 >= 4.0.0]) RH_PKG_IDLDIR([OMNICOS], [omniCOS4]) diff --git a/bulkioInterfaces/libsrc/setup.py b/bulkioInterfaces/libsrc/setup.py index e25f0a2a8..1c62ebb42 100644 --- a/bulkioInterfaces/libsrc/setup.py +++ b/bulkioInterfaces/libsrc/setup.py @@ -29,7 +29,7 @@ # replaces it (i.e. a developer does a command-line build), use 1.X.X version='__VERSION__' if version.find('__') == 0: - version = '2.1.0' + version = '2.1.1' setup( name='bulkio', diff --git a/burstioInterfaces/burstioInterfaces.spec b/burstioInterfaces/burstioInterfaces.spec index a91fcfa8d..22f471dbf 100644 --- a/burstioInterfaces/burstioInterfaces.spec +++ b/burstioInterfaces/burstioInterfaces.spec @@ -28,8 +28,8 @@ Prefix: %{_prefix} %bcond_without java Name: burstioInterfaces -Version: 2.1.0 -Release: 3%{?dist} +Version: 2.1.1 +Release: 1%{?dist} Summary: BURSTIO interfaces for REDHAWK Group: Applications/Engineering diff --git a/burstioInterfaces/configure.ac b/burstioInterfaces/configure.ac index 7b859a3c7..68442dbe4 100644 --- a/burstioInterfaces/configure.ac +++ b/burstioInterfaces/configure.ac @@ -18,7 +18,7 @@ # along with this program. If not, see http://www.gnu.org/licenses/. # -AC_INIT(burstio, 2.1.0) +AC_INIT(burstioInterfaces, 2.1.1) AC_CONFIG_SRCDIR([src/cpp/Makefile.am]) AC_CONFIG_MACRO_DIR([m4]) @@ -42,10 +42,10 @@ fi AC_LANG_PUSH([C++]) PKG_CHECK_MODULES([OMNIORB], [omniORB4 >= 4.1.0]) -PKG_CHECK_MODULES(OSSIE, ossie >= 2.1.0,,exit) +PKG_CHECK_MODULES(OSSIE, ossie >= 2.1.1,,exit) RH_PKG_IDLDIR([OSSIE], [ossie]) -PKG_CHECK_MODULES([BULKIO], [bulkio >= 2.0]) +PKG_CHECK_MODULES([BULKIO], [bulkio >= 2.1]) RH_PKG_IDLDIR([BULKIO], [bulkioInterfaces]) AX_BOOST_BASE([1.41]) diff --git a/frontendInterfaces/build.sh b/frontendInterfaces/build.sh index f557d1f9a..9df463656 100755 --- a/frontendInterfaces/build.sh +++ b/frontendInterfaces/build.sh @@ -25,9 +25,9 @@ elif [ "$1" = "rpm" ]; then # A very simplistic RPM build scenario mydir=`dirname $0` tmpdir=`mktemp -d` - cp -r ${mydir} ${tmpdir}/frontendInterfaces-2.4.0 - tar czf ${tmpdir}/frontendInterfaces-2.4.0.tar.gz --exclude=".svn" -C ${tmpdir} frontendInterfaces-2.4.0 - rpmbuild -ta ${tmpdir}/frontendInterfaces-2.4.0.tar.gz + cp -r ${mydir} ${tmpdir}/frontendInterfaces-2.4.1 + tar czf ${tmpdir}/frontendInterfaces-2.4.1.tar.gz --exclude=".svn" -C ${tmpdir} frontendInterfaces-2.4.1 + rpmbuild -ta ${tmpdir}/frontendInterfaces-2.4.1.tar.gz rm -rf $tmpdir else # Checks if build is newer than makefile (based on modification time) diff --git a/frontendInterfaces/configure.ac b/frontendInterfaces/configure.ac index 1e92e47bb..5ab228d35 100644 --- a/frontendInterfaces/configure.ac +++ b/frontendInterfaces/configure.ac @@ -18,7 +18,7 @@ # along with this program. If not, see http://www.gnu.org/licenses/. # -AC_INIT(frontendInterfaces, 2.4.0) +AC_INIT(frontendInterfaces, 2.4.1) AM_INIT_AUTOMAKE(nostdinc) AC_PROG_CC @@ -41,7 +41,7 @@ if test "$IDL" = no; then fi AC_LANG_PUSH([C++]) PKG_CHECK_MODULES([OMNIORB], [omniORB4 >= 4.1.0]) -PKG_CHECK_MODULES([OSSIE], [ossie >= 2.1.0]) +PKG_CHECK_MODULES([OSSIE], [ossie >= 2.1.1]) RH_PKG_IDLDIR([OSSIE], [ossie]) # If you depend on other IDL modules, such as CF or BULKIO add them here diff --git a/frontendInterfaces/frontendInterfaces.spec b/frontendInterfaces/frontendInterfaces.spec index 3b09344c1..e5f2c0457 100644 --- a/frontendInterfaces/frontendInterfaces.spec +++ b/frontendInterfaces/frontendInterfaces.spec @@ -34,8 +34,8 @@ Prefix: %{_prefix} Summary: The frontend library for REDHAWK Name: frontendInterfaces -Version: 2.4.0 -Release: 3%{?dist} +Version: 2.4.1 +Release: 1%{?dist} License: LGPLv3+ Group: REDHAWK/Interfaces Source: %{name}-%{version}.tar.gz @@ -43,10 +43,10 @@ Vendor: REDHAWK BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot -Requires: redhawk >= 2.1.0 -Requires: bulkioInterfaces >= 2.1.0 -BuildRequires: redhawk-devel >= 2.1.0 -BuildRequires: bulkioInterfaces >= 2.1.0 +Requires: redhawk >= 2.1.1 +Requires: bulkioInterfaces >= 2.1.1 +BuildRequires: redhawk-devel >= 2.1.1 +BuildRequires: bulkioInterfaces >= 2.1.1 %description Libraries and interface definitions for frontend. diff --git a/frontendInterfaces/libsrc/setup.py b/frontendInterfaces/libsrc/setup.py index d032a902c..b04d72c22 100644 --- a/frontendInterfaces/libsrc/setup.py +++ b/frontendInterfaces/libsrc/setup.py @@ -29,7 +29,7 @@ # replaces it (i.e. a developer does a command-line build), use 1.X.X version='__VERSION__' if version.find('__') == 0: - version = '2.4.0' + version = '2.4.1' setup( name='frontend', diff --git a/redhawk-codegen/redhawk-codegen.spec b/redhawk-codegen/redhawk-codegen.spec index 30af01add..60f0d71f5 100644 --- a/redhawk-codegen/redhawk-codegen.spec +++ b/redhawk-codegen/redhawk-codegen.spec @@ -23,8 +23,8 @@ Prefix: %{_prefix} Name: redhawk-codegen -Version: 2.1.0 -Release: 3%{?dist} +Version: 2.1.1 +Release: 1%{?dist} Summary: Redhawk Code Generators Group: Applications/Engineering diff --git a/redhawk-codegen/redhawk/codegen/versions.py b/redhawk-codegen/redhawk/codegen/versions.py index cd989455c..961a28d50 100644 --- a/redhawk-codegen/redhawk/codegen/versions.py +++ b/redhawk-codegen/redhawk/codegen/versions.py @@ -17,7 +17,7 @@ # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see http://www.gnu.org/licenses/. # -codegen = '2.1.0' +codegen = '2.1.1' redhawk = '2.1' jinja2 = '2.6' boost = '1.41' diff --git a/redhawk/src/base/framework/python/ossie/version.py b/redhawk/src/base/framework/python/ossie/version.py index 93b931f11..2f49373df 100644 --- a/redhawk/src/base/framework/python/ossie/version.py +++ b/redhawk/src/base/framework/python/ossie/version.py @@ -18,4 +18,4 @@ # along with this program. If not, see http://www.gnu.org/licenses/. # -__version__='2.1.0' +__version__='2.1.1' diff --git a/redhawk/src/configure.ac b/redhawk/src/configure.ac index 17036c44e..deb937aab 100644 --- a/redhawk/src/configure.ac +++ b/redhawk/src/configure.ac @@ -19,7 +19,7 @@ # dnl Update this version number immedately after a release -AC_INIT([ossie],[2.1.0]) +AC_INIT([ossie],[2.1.1]) #AM_INIT_AUTOMAKE(nostdinc) # allows filenames over 99 characters long during dist AM_INIT_AUTOMAKE([1.9 tar-pax subdir-objects]) diff --git a/redhawk/src/releng/redhawk.spec b/redhawk/src/releng/redhawk.spec index 30e4d8c0c..17bf1f6d3 100644 --- a/redhawk/src/releng/redhawk.spec +++ b/redhawk/src/releng/redhawk.spec @@ -26,8 +26,8 @@ Prefix: %{_sdrroot} Prefix: %{_sysconfdir} Name: redhawk -Version: 2.1.0 -Release: 3%{?dist} +Version: 2.1.1 +Release: 1%{?dist} Summary: REDHAWK is a Software Defined Radio framework Group: Applications/Engineering diff --git a/redhawk/src/testing/setup.py b/redhawk/src/testing/setup.py index b0ca90547..b5ec387ba 100644 --- a/redhawk/src/testing/setup.py +++ b/redhawk/src/testing/setup.py @@ -47,7 +47,7 @@ '_unitTestHelpers.runtestHelpers', '_unitTestHelpers.buildconfig'] -version='2.1.0' +version='2.1.1' setup( name='unitTestHelper', From 5a8035c655991982e8440f2a4f76bfe15d379f58 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Thu, 30 Mar 2017 15:52:08 -0400 Subject: [PATCH 0765/1644] Refs CF-1682. Added event channel manager persistence --- .../sdr/dommgr/DomainManager_EventSupport.cpp | 6 + .../control/sdr/dommgr/DomainManager_impl.cpp | 118 ++++++++++++++++ .../control/sdr/dommgr/DomainManager_impl.h | 9 ++ .../sdr/dommgr/EventChannelManager.cpp | 44 ++++-- .../control/sdr/dommgr/EventChannelManager.h | 94 +++++++------ .../src/control/sdr/dommgr/PersistenceStore.h | 22 ++- .../tests/test_09_DomainPersistence.py | 131 +++++++++--------- 7 files changed, 300 insertions(+), 124 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/DomainManager_EventSupport.cpp b/redhawk/src/control/sdr/dommgr/DomainManager_EventSupport.cpp index ab9d3c77b..4e1ee1c53 100644 --- a/redhawk/src/control/sdr/dommgr/DomainManager_EventSupport.cpp +++ b/redhawk/src/control/sdr/dommgr/DomainManager_EventSupport.cpp @@ -209,9 +209,15 @@ void DomainManager_impl::establishDomainManagementChannels( const std::string &d if ( _eventChannelMgr ){ if ( !dburi.empty() ) { + LOG_INFO(DomainManager_impl, "Restoring event channel manager state"); + restorePubProxies(dburi); + restoreSubProxies(dburi); + restoreEventChannelRegistrations(dburi); + LOG_DEBUG(DomainManager_impl, "Completed Restoring Event Channel Manager state"); LOG_INFO(DomainManager_impl, "Restoring event channels file:" << dburi); restoreEventChannels(dburi); } + LOG_TRACE(DomainManager_impl, "Establishing Domain Event Channels"); diff --git a/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp b/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp index 3ab6341dc..626fc1a42 100644 --- a/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp @@ -2107,6 +2107,124 @@ void DomainManager_impl::_local_registerService (CORBA::Object_ptr registeringSe //exists which causes an unsuccessful registration. } +void DomainManager_impl::storePubProxies() +{ + EventProxies _proxies; + EventChannelManager::PubProxyMap _retVal = _eventChannelMgr->getPubProxies(); + for (EventChannelManager::PubProxyMap::iterator it = _retVal.begin(); it != _retVal.end(); it++) { + _proxies[it->first] = _orbCtx.orb->object_to_string(it->second); + } + try { + db.store("EVTCHMGR_PUBPROXIES", _proxies); + } catch (const ossie::PersistenceException& ex) { + LOG_ERROR(DomainManager_impl, "Error persisting change to event channel manager publisher proxies"); + } +} + +void DomainManager_impl::storeSubProxies() +{ + EventProxies _proxies; + EventChannelManager::SubProxyMap _retVal = _eventChannelMgr->getSubProxies(); + for (EventChannelManager::SubProxyMap::iterator it = _retVal.begin(); it != _retVal.end(); it++) { + _proxies[it->first] = _orbCtx.orb->object_to_string(it->second); + } + try { + db.store("EVTCHMGR_SUBPROXIES", _proxies); + } catch (const ossie::PersistenceException& ex) { + LOG_ERROR(DomainManager_impl, "Error persisting change to event channel manager subscriber proxies"); + } +} + +void DomainManager_impl::storeEventChannelRegistrations() +{ + ChannelRegistrationNodes _nodes; + EventChannelManager::ChannelRegistrationTable _retVal = _eventChannelMgr->getChannelRegistrations(); + for (EventChannelManager::ChannelRegistrationTable::iterator it = _retVal.begin(); it != _retVal.end(); it++) { + ChannelRegistrationNode _tmp; + _tmp.channel_name = it->second.channel_name; + _tmp.fqn = it->second.fqn; + _tmp.channel = _orbCtx.orb->object_to_string(it->second.channel); + _tmp.autoRelease = it->second.autoRelease; + _tmp.release = it->second.release; + _tmp.registrants = it->second.registrants; + _nodes[it->first] = _tmp; + } + try { + db.store("EVTCHMGR_CHANNELREGISTRATIONS", _nodes); + } catch (const ossie::PersistenceException& ex) { + LOG_ERROR(DomainManager_impl, "Error persisting change to event channel manager event channel registrations"); + } +} + +void DomainManager_impl::restorePubProxies(const std::string& _db_uri) +{ + try { + db.open(_db_uri); + } catch (const ossie::PersistenceException& e) { + LOG_ERROR(DomainManager_impl, "Error loading persistent state: " << e.what()); + return; + } + EventProxies _proxies; + try { + db.fetch("EVTCHMGR_PUBPROXIES", _proxies, true); + } catch (const ossie::PersistenceException& ex) { + LOG_ERROR(DomainManager_impl, "Error persisting change to event channel manager publisher proxies"); + } + EventChannelManager::PubProxyMap _newVal; + for (EventProxies::iterator it = _proxies.begin(); it != _proxies.end(); it++) { + _newVal[it->first] = ossie::corba::_narrowSafe(_orbCtx.orb->string_to_object(it->second.c_str())); + } + _eventChannelMgr->setPubProxies(_newVal); +} + +void DomainManager_impl::restoreSubProxies(const std::string& _db_uri) +{ + try { + db.open(_db_uri); + } catch (const ossie::PersistenceException& e) { + LOG_ERROR(DomainManager_impl, "Error loading persistent state: " << e.what()); + return; + } + EventProxies _proxies; + try { + db.fetch("EVTCHMGR_SUBPROXIES", _proxies, true); + } catch (const ossie::PersistenceException& ex) { + LOG_ERROR(DomainManager_impl, "Error persisting change to event channel manager subscriber proxies"); + } + EventChannelManager::SubProxyMap _newVal; + for (EventProxies::iterator it = _proxies.begin(); it != _proxies.end(); it++) { + _newVal[it->first] = ossie::corba::_narrowSafe(_orbCtx.orb->string_to_object(it->second.c_str())); + } + _eventChannelMgr->setSubProxies(_newVal); +} + +void DomainManager_impl::restoreEventChannelRegistrations(const std::string& _db_uri) +{ + try { + db.open(_db_uri); + } catch (const ossie::PersistenceException& e) { + LOG_ERROR(DomainManager_impl, "Error loading persistent state: " << e.what()); + return; + } + ChannelRegistrationNodes _nodes; + try { + db.fetch("EVTCHMGR_CHANNELREGISTRATIONS", _nodes, true); + } catch (const ossie::PersistenceException& ex) { + LOG_ERROR(DomainManager_impl, "Error persisting change to event channel manager event channel registrations"); + } + EventChannelManager::ChannelRegistrationTable _newVal;// = _eventChannelMgr->getChannelRegistrations(); + for (ChannelRegistrationNodes::iterator it = _nodes.begin(); it != _nodes.end(); it++) { + EventChannelManager::ChannelRegistration _tmp; + _tmp.channel_name = it->second.channel_name; + _tmp.fqn = it->second.fqn; + _tmp.channel = ossie::corba::_narrowSafe(_orbCtx.orb->string_to_object(it->second.channel.c_str())); + _tmp.autoRelease = it->second.autoRelease; + _tmp.release = it->second.release; + _tmp.registrants = it->second.registrants; + _newVal[it->first] = _tmp; + } + _eventChannelMgr->setChannelRegistrations(_newVal); +} void DomainManager_impl::unregisterService(CORBA::Object_ptr unregisteringService, const char* name) throw (CF::DomainManager::UnregisterError, CF::InvalidObjectReference, CORBA::SystemException) diff --git a/redhawk/src/control/sdr/dommgr/DomainManager_impl.h b/redhawk/src/control/sdr/dommgr/DomainManager_impl.h index 66bf1056a..1f6455bde 100644 --- a/redhawk/src/control/sdr/dommgr/DomainManager_impl.h +++ b/redhawk/src/control/sdr/dommgr/DomainManager_impl.h @@ -294,6 +294,12 @@ class DomainManager_impl: public virtual POA_CF::DomainManager, public PropertyS void disconnectDomainManagementChannels(); void idmTerminationMessages( const redhawk::events::ComponentTerminationEvent &msg ); void destroyEventChannels (void); + void storePubProxies(); + void storeSubProxies(); + void storeEventChannelRegistrations(); + void restorePubProxies(const std::string& _db_uri); + void restoreSubProxies(const std::string& _db_uri); + void restoreEventChannelRegistrations(const std::string& _db_uri); bool applicationDependsOnDevice (Application_impl* application, const std::string& deviceId); @@ -370,6 +376,9 @@ class DomainManager_impl: public virtual POA_CF::DomainManager, public PropertyS bool _useLogConfigUriResolver; bool _strict_spd_validation; + // orb context + ossie::corba::OrbContext _orbCtx; + void _exit(int __status) { ossie::logging::Terminate(); //no more logging.... exit(__status); diff --git a/redhawk/src/control/sdr/dommgr/EventChannelManager.cpp b/redhawk/src/control/sdr/dommgr/EventChannelManager.cpp index d9152954a..860c1327f 100644 --- a/redhawk/src/control/sdr/dommgr/EventChannelManager.cpp +++ b/redhawk/src/control/sdr/dommgr/EventChannelManager.cpp @@ -634,9 +634,9 @@ void EventChannelManager::restore( ossie::events::EventChannel_ptr savedChannel, throw (CF::EventChannelManager::OperationFailed()); } - ECM_DEBUG("restore", + /*ECM_DEBUG("restore", "ADD Channel Registration, Event Channel: "<< channel_name << " fqn:" << fqn ); - ChannelRegistrationPtr reg __attribute__((unused)) = _addChannelRegistration( channel_name, fqn, event_channel, false ); + ChannelRegistrationPtr reg __attribute__((unused)) = _addChannelRegistration( channel_name, fqn, event_channel, false );*/ // // return pointer the channel... we maintain a separate copy @@ -645,17 +645,26 @@ void EventChannelManager::restore( ossie::events::EventChannel_ptr savedChannel, } +ossie::events::EventChannelReg_ptr EventChannelManager::registerResource( const ossie::events::EventRegistration &request) + throw ( CF::EventChannelManager::InvalidChannelName, + CF::EventChannelManager::RegistrationAlreadyExists, + CF::EventChannelManager::OperationFailed, + CF::EventChannelManager::OperationNotAllowed, + CF::EventChannelManager::ServiceUnavailable ) +{ + SCOPED_LOCK(_mgrlock); + return _registerResource( request ); +} - ossie::events::EventChannelReg_ptr EventChannelManager::registerResource( const ossie::events::EventRegistration &request) +ossie::events::EventChannelReg_ptr EventChannelManager::_registerResource( const ossie::events::EventRegistration &request) throw ( CF::EventChannelManager::InvalidChannelName, - CF::EventChannelManager::RegistrationAlreadyExists, - CF::EventChannelManager::OperationFailed, - CF::EventChannelManager::OperationNotAllowed, - CF::EventChannelManager::ServiceUnavailable ) + CF::EventChannelManager::RegistrationAlreadyExists, + CF::EventChannelManager::OperationFailed, + CF::EventChannelManager::OperationNotAllowed, + CF::EventChannelManager::ServiceUnavailable ) { ECM_DEBUG("registerResource", "REQUEST REGISTRATION , REG-ID:" << request.reg_id << " CHANNEL:" << request.channel_name ); - SCOPED_LOCK(_mgrlock); // get the event channel factory... throws ServiceUnavailable _getEventChannelFactory(); @@ -709,8 +718,8 @@ void EventChannelManager::restore( ossie::events::EventChannel_ptr savedChannel, reg->channel = ossie::events::EventChannel::_duplicate(creg->channel); std::string ior = ossie::corba::objectToString( reg->channel ); - ECM_DEBUG("register", "NEW REGISTRATION FOR:" << ior ); creg->registrants.insert( RegRecord( regid, ior ) ); + this->_domainManager->storeEventChannelRegistrations(); ECM_DEBUG("registerResource", "NEW REGISTRATION REG-ID:" << regid << " CHANNEL:" << channel_name ); @@ -726,11 +735,13 @@ void EventChannelManager::restore( ossie::events::EventChannel_ptr savedChannel, CF::EventChannelManager::OperationFailed, CF::EventChannelManager::OperationNotAllowed, CF::EventChannelManager::ServiceUnavailable ) { + SCOPED_LOCK(_mgrlock); int retries = 10; int retry_wait = 10; int tries = retries; CosEventChannelAdmin::ConsumerAdmin_var consumer_admin; - ossie::events::EventChannel_var channel = get(req.channel_name); + std::string _channel_name(req.channel_name); + ossie::events::EventChannel_var channel = _get(_channel_name); do { try { @@ -791,7 +802,7 @@ void EventChannelManager::restore( ossie::events::EventChannel_ptr savedChannel, } while ( tries ); ossie::events::EventChannelReg_ptr ret_reg; try { - ret_reg = registerResource(req); + ret_reg = _registerResource(req); } catch ( ... ) { try { _proxy->disconnect_push_supplier(); @@ -801,6 +812,7 @@ void EventChannelManager::restore( ossie::events::EventChannel_ptr savedChannel, } std::string _reg_id(ret_reg->reg.reg_id); _subProxies[_reg_id] = ossie::events::EventSubscriber::_duplicate(_proxy); + this->_domainManager->storeSubProxies(); return ret_reg; } @@ -810,14 +822,15 @@ void EventChannelManager::restore( ossie::events::EventChannel_ptr savedChannel, CF::EventChannelManager::OperationFailed, CF::EventChannelManager::OperationNotAllowed, CF::EventChannelManager::ServiceUnavailable ) { - + SCOPED_LOCK(_mgrlock); int retries = 10; int retry_wait = 10; int tries = retries; CosEventChannelAdmin::SupplierAdmin_var supplier_admin; ossie::events::PublisherReg_ptr reg = new ossie::events::PublisherReg(); - ossie::events::EventChannel_var channel = get(req.channel_name); + std::string _channel_name(req.channel_name); + ossie::events::EventChannel_var channel = _get(_channel_name); do { try { @@ -851,7 +864,7 @@ void EventChannelManager::restore( ossie::events::EventChannel_ptr savedChannel, ossie::events::EventChannelReg_var ret_reg; try { - ret_reg = registerResource(req); + ret_reg = _registerResource(req); } catch ( ... ) { throw; } @@ -1496,7 +1509,6 @@ EventChannelManager::ChannelRegistrationPtr EventChannelManager::_addChannelRegi ossie::events::EventChannel_ptr channel, bool autoRelease ) { - ECM_TRACE("_addChannelRegistration", "Created ChannelRegistrationRecord, Event Channel/FQN : "<< cname << "/" << fqn ); ECM_TRACE("_addChannelRegistration", "Created ChannelRegistrationRecord, Event Channel : "<< channel << "/" << autoRelease ); @@ -1520,6 +1532,7 @@ EventChannelManager::ChannelRegistrationPtr EventChannelManager::_addChannelRegi ECM_TRACE("addChannelRegistration", " ChannelRecord: channel:" << _channels[cname].channel); ECM_TRACE("_addChannelRegistration", "Registration Table Size: "<< _channels.size() ); } + this->_domainManager->storeEventChannelRegistrations(); return ret; } @@ -1552,6 +1565,7 @@ EventChannelManager::ChannelRegistrationPtr EventChannelManager::_addChannelRegi _channels.erase(itr); } ECM_DEBUG("_deleteChannelRegistration", "Completed delete registration...EventChannel: "<< cname ); + this->_domainManager->storeEventChannelRegistrations(); return; } diff --git a/redhawk/src/control/sdr/dommgr/EventChannelManager.h b/redhawk/src/control/sdr/dommgr/EventChannelManager.h index 7e188b112..9277ce5a7 100644 --- a/redhawk/src/control/sdr/dommgr/EventChannelManager.h +++ b/redhawk/src/control/sdr/dommgr/EventChannelManager.h @@ -167,6 +167,13 @@ class EventChannelManager: public virtual EventChannelManagerBase { */ + ossie::events::EventChannelReg_ptr _registerResource( const ossie::events::EventRegistration &req) + throw ( CF::EventChannelManager::InvalidChannelName, + CF::EventChannelManager::RegistrationAlreadyExists, + CF::EventChannelManager::OperationFailed, + CF::EventChannelManager::OperationNotAllowed, + CF::EventChannelManager::ServiceUnavailable ); + ossie::events::EventChannelReg_ptr registerResource( const ossie::events::EventRegistration &req) throw ( CF::EventChannelManager::InvalidChannelName, CF::EventChannelManager::RegistrationAlreadyExists, @@ -214,14 +221,7 @@ class EventChannelManager: public virtual EventChannelManagerBase { bool isChannel( const std::string &channel_name ); void setPollingPeriod( const int64_t period ); - private: - - typedef std::pair< std::string, std::string > RegRecord; typedef std::map< std::string, std::string > RegIdList; - - std::map _subProxies; - std::map _pubProxies; - struct ChannelRegistration { std::string channel_name; std::string fqn; @@ -234,11 +234,53 @@ class EventChannelManager: public virtual EventChannelManagerBase { return registrants.size(); } }; + typedef std::map< std::string, ChannelRegistration > ChannelRegistrationTable; + + typedef std::map SubProxyMap; + typedef std::map PubProxyMap; + + SubProxyMap getSubProxies() { return _subProxies;}; + PubProxyMap getPubProxies() { return _pubProxies;}; + ChannelRegistrationTable getChannelRegistrations() { return _channels;}; + void setSubProxies(SubProxyMap &_inval) { _subProxies = _inval;}; + void setPubProxies(PubProxyMap &_inval) { _pubProxies = _inval;}; + void setChannelRegistrations(ChannelRegistrationTable &_inval) { _channels = _inval; }; + private: + // type definitions + typedef std::pair< std::string, std::string > RegRecord; typedef ChannelRegistration* ChannelRegistrationPtr; - typedef std::map< std::string, ChannelRegistration > ChannelRegistrationTable; + // event channel manager state + SubProxyMap _subProxies; + PubProxyMap _pubProxies; + // + // Channel Registration database + // + ChannelRegistrationTable _channels; + + // configuration and default state information +#ifndef CPPUNIT_TEST + // Handle to the Resource that owns us + DomainManager_impl* _domainManager; +#endif + // naming context directory to bind event channgels to... + std::string _domain_context; + // orb context + ossie::corba::OrbContext _orbCtx; + // Handle to factory interface to create EventChannels + ossie::events::EventChannelFactory_var _event_channel_factory; + // if enabled, events will show up in the NamingService + bool _use_naming_service; + // use fully qualified domain names when creating channels. + bool _use_fqn; + // allow event service to resolve channels + bool _allow_es_resolve; + // default polling period to assign to a channel + int64_t _default_poll_period; + // synchronize access to member variables + redhawk::Mutex _mgrlock; void _initialize(); @@ -354,42 +396,6 @@ class EventChannelManager: public virtual EventChannelManagerBase { */ void _deleteChannelRegistration( const std::string &cname ); - - -#ifndef CPPUNIT_TEST - // Handle to the Resource that owns us - DomainManager_impl* _domainManager; -#endif - - // naming context directory to bind event channgels to... - std::string _domain_context; - - // orb context - ossie::corba::OrbContext _orbCtx; - - // Handle to factory interface to create EventChannels - ossie::events::EventChannelFactory_var _event_channel_factory; - - // - // Channel Registration database - // - ChannelRegistrationTable _channels; - - // if enabled, events will show up in the NamingService - bool _use_naming_service; - - // use fully qualified domain names when creating channels. - bool _use_fqn; - - // allow event service to resolve channels - bool _allow_es_resolve; - - // default polling period to assign to a channel - int64_t _default_poll_period; - - // synchronize access to member variables - redhawk::Mutex _mgrlock; - }; #endif diff --git a/redhawk/src/control/sdr/dommgr/PersistenceStore.h b/redhawk/src/control/sdr/dommgr/PersistenceStore.h index 05e9707f4..a462131df 100644 --- a/redhawk/src/control/sdr/dommgr/PersistenceStore.h +++ b/redhawk/src/control/sdr/dommgr/PersistenceStore.h @@ -108,6 +108,16 @@ namespace ossie { typedef std::map AllocationTable; typedef std::map RemoteAllocationTable; + typedef std::map EventProxies; + struct ChannelRegistrationNode { + std::string channel_name; + std::string fqn; + std::string channel; + bool autoRelease; + bool release; + std::map< std::string, std::string > registrants; + }; + typedef std::map ChannelRegistrationNodes; struct ComponentNode { std::string identifier; @@ -258,7 +268,7 @@ namespace boost { } ar & (*ptr); } - + template void serialize(Archive& ar, ossie::EventChannelNode& node, const unsigned int version) { ar & (node.channel); @@ -267,6 +277,16 @@ namespace boost { ar & (node.name); } + template + void serialize(Archive& ar, ossie::ChannelRegistrationNode& node, const unsigned int version) { + ar & (node.channel_name); + ar & (node.fqn); + ar & (node.channel); + ar & (node.autoRelease); + ar & (node.release); + ar & (node.registrants); + } + template void serialize(Archive& ar, ossie::ComponentNode& node, const unsigned int version) { ar & node.identifier; diff --git a/redhawk/src/testing/tests/test_09_DomainPersistence.py b/redhawk/src/testing/tests/test_09_DomainPersistence.py index 9f52c477a..370712229 100644 --- a/redhawk/src/testing/tests/test_09_DomainPersistence.py +++ b/redhawk/src/testing/tests/test_09_DomainPersistence.py @@ -32,6 +32,7 @@ from ossie import properties from ossie.cf import StandardEvent from ossie.utils import uuid +from ossie.events import Publisher class Supplier_i(CosEventComm__POA.PushSupplier): @@ -291,6 +292,18 @@ def test_EventAppPortConnectionSIGKILL(self): app = appFact.create(appFact._get_name(), [], []) app.start() + eventChannelMgr = domMgr._get_eventChannelMgr() + + _consumer = Consumer_i(self) + evt_reg = CF.EventChannelManager.EventRegistration(channel_name = 'anotherChannel', reg_id = 'my_reg_id') + reg = eventChannelMgr.registerConsumer(_consumer._this(), evt_reg) + pub = Publisher(domMgr, 'anotherChannel') + + _channels = eventChannelMgr.listChannels(100)[0] + _channel_registrations = {} + for _channel in _channels: + _channel_registrations[_channel.channel_name] = _channel.reg_count + # Kill the domainMgr os.kill(self._nb_domMgr.pid, signal.SIGKILL) if not self.waitTermination(self._nb_domMgr, 5.0): @@ -302,37 +315,26 @@ def test_EventAppPortConnectionSIGKILL(self): newappFact = domMgr._get_applicationFactories()[0] app2 = newappFact.create(appFact._get_name(), [], []) app2.start() - channelName = URI.stringToName("%s/%s" % (domainName, 'anotherChannel')) - try: - appChannel = self._root.resolve(channelName)._narrow(CosEventChannelAdmin.EventChannel) - except: - self.assertEqual(False, True) - else: - self.assertEqual(True, True) - - # resolve the producer for the event - supplier_admin = appChannel.for_suppliers() - _proxy_consumer = supplier_admin.obtain_push_consumer() - _supplier = Supplier_i() - _proxy_consumer.connect_push_supplier(_supplier._this()) - - # resolve the consumer for the event - consumer_admin = appChannel.for_consumers() - _proxy_supplier = consumer_admin.obtain_push_supplier() - _consumer = Consumer_i(self) - _proxy_supplier.connect_push_consumer(_consumer._this()) + appChannel = eventChannelMgr.get('anotherChannel') # a flag is raised only when two responses come back (one for each running app) - _proxy_consumer.push(any.to_any("message")) + pub.push(any.to_any("message")) self.localEvent.wait(5.0) self.assertEqual(self.eventFlag, True) + _channels = eventChannelMgr.listChannels(100)[0] + self.assertEquals(len(_channel_registrations), len(_channels)) + for _channel in _channels: + self.assertTrue(_channel_registrations.has_key(_channel.channel_name)) + self.assertEquals(_channel_registrations[_channel.channel_name], _channel.reg_count) + _channel_registrations[_channel.channel_name] = _channel.reg_count + self.eventFlag = False # this step tests whether the number of subscribers to the channel is restored app2.releaseObject() self.localEvent.clear() - _proxy_consumer.push(any.to_any("message")) + pub.push(any.to_any("message")) self.localEvent.wait(5.0) self.assertEqual(self.eventFlag, True) app.releaseObject() @@ -350,6 +352,18 @@ def test_EventAppPortConnectionSIGTERM(self): app = appFact.create(appFact._get_name(), [], []) app.start() + eventChannelMgr = domMgr._get_eventChannelMgr() + + _consumer = Consumer_i(self) + evt_reg = CF.EventChannelManager.EventRegistration(channel_name = 'anotherChannel', reg_id = 'my_reg_id') + reg = eventChannelMgr.registerConsumer(_consumer._this(), evt_reg) + pub = Publisher(domMgr, 'anotherChannel') + + _channels = eventChannelMgr.listChannels(100)[0] + _channel_registrations = {} + for _channel in _channels: + _channel_registrations[_channel.channel_name] = _channel.reg_count + # Kill the domainMgr os.kill(self._nb_domMgr.pid, signal.SIGTERM) if not self.waitTermination(self._nb_domMgr, 5.0): @@ -361,37 +375,25 @@ def test_EventAppPortConnectionSIGTERM(self): newappFact = domMgr._get_applicationFactories()[0] app2 = newappFact.create(appFact._get_name(), [], []) app2.start() - channelName = URI.stringToName("%s/%s" % (domainName, 'anotherChannel')) - try: - appChannel = self._root.resolve(channelName)._narrow(CosEventChannelAdmin.EventChannel) - except: - self.assertEqual(False, True) - else: - self.assertEqual(True, True) - - # resolve the producer for the event - supplier_admin = appChannel.for_suppliers() - _proxy_consumer = supplier_admin.obtain_push_consumer() - _supplier = Supplier_i() - _proxy_consumer.connect_push_supplier(_supplier._this()) - - # resolve the consumer for the event - consumer_admin = appChannel.for_consumers() - _proxy_supplier = consumer_admin.obtain_push_supplier() - _consumer = Consumer_i(self) - _proxy_supplier.connect_push_consumer(_consumer._this()) # a flag is raised only when two responses come back (one for each running app) - _proxy_consumer.push(any.to_any("message")) + pub.push(any.to_any("message")) self.localEvent.wait(5.0) self.assertEqual(self.eventFlag, True) + _channels = eventChannelMgr.listChannels(100)[0] + self.assertEquals(len(_channel_registrations), len(_channels)) + for _channel in _channels: + self.assertTrue(_channel_registrations.has_key(_channel.channel_name)) + self.assertEquals(_channel_registrations[_channel.channel_name], _channel.reg_count) + _channel_registrations[_channel.channel_name] = _channel.reg_count + self.eventFlag = False # this step tests whether the number of subscribers to the channel is restored app2.releaseObject() self.localEvent.clear() - _proxy_consumer.push(any.to_any("message")) + pub.push(any.to_any("message")) self.localEvent.wait(5.0) self.assertEqual(self.eventFlag, True) app.releaseObject() @@ -426,7 +428,7 @@ def test_EventAppPortConnectionSIGTERMNoPersist(self): devMgrs = domMgr._get_deviceManagers() self.assertEqual(len(devMgrs), 0) - def test_EventAppPortConnectionSIGQUIT(self): + def test_EventAppPortConnectionSIGQUITFoo(self): self.localEvent = threading.Event() self.eventFlag = False @@ -439,6 +441,18 @@ def test_EventAppPortConnectionSIGQUIT(self): app = appFact.create(appFact._get_name(), [], []) app.start() + eventChannelMgr = domMgr._get_eventChannelMgr() + + _consumer = Consumer_i(self) + evt_reg = CF.EventChannelManager.EventRegistration(channel_name = 'anotherChannel', reg_id = 'my_reg_id') + reg = eventChannelMgr.registerConsumer(_consumer._this(), evt_reg) + pub = Publisher(domMgr, 'anotherChannel') + + _channels = eventChannelMgr.listChannels(100)[0] + _channel_registrations = {} + for _channel in _channels: + _channel_registrations[_channel.channel_name] = _channel.reg_count + # Kill the domainMgr os.kill(self._nb_domMgr.pid, signal.SIGQUIT) if not self.waitTermination(self._nb_domMgr, 5.0): @@ -450,37 +464,26 @@ def test_EventAppPortConnectionSIGQUIT(self): newappFact = domMgr._get_applicationFactories()[0] app2 = newappFact.create(appFact._get_name(), [], []) app2.start() - channelName = URI.stringToName("%s/%s" % (domainName, 'anotherChannel')) - try: - appChannel = self._root.resolve(channelName)._narrow(CosEventChannelAdmin.EventChannel) - except: - self.assertEqual(False, True) - else: - self.assertEqual(True, True) - - # resolve the producer for the event - supplier_admin = appChannel.for_suppliers() - _proxy_consumer = supplier_admin.obtain_push_consumer() - _supplier = Supplier_i() - _proxy_consumer.connect_push_supplier(_supplier._this()) - - # resolve the consumer for the event - consumer_admin = appChannel.for_consumers() - _proxy_supplier = consumer_admin.obtain_push_supplier() - _consumer = Consumer_i(self) - _proxy_supplier.connect_push_consumer(_consumer._this()) # a flag is raised only when two responses come back (one for each running app) - _proxy_consumer.push(any.to_any("message")) + pub.push(any.to_any("message")) self.localEvent.wait(5.0) self.assertEqual(self.eventFlag, True) + _channels = eventChannelMgr.listChannels(100)[0] + + self.assertEquals(len(_channel_registrations), len(_channels)) + for _channel in _channels: + self.assertTrue(_channel_registrations.has_key(_channel.channel_name)) + self.assertEquals(_channel_registrations[_channel.channel_name], _channel.reg_count) + _channel_registrations[_channel.channel_name] = _channel.reg_count + self.eventFlag = False # this step tests whether the number of subscribers to the channel is restored app2.releaseObject() self.localEvent.clear() - _proxy_consumer.push(any.to_any("message")) + pub.push(any.to_any("message")) self.localEvent.wait(5.0) self.assertEqual(self.eventFlag, True) app.releaseObject() From 9bdaf24f3d99e3f09d029071b1ac39267d2c2bdb Mon Sep 17 00:00:00 2001 From: Max Robert Date: Thu, 30 Mar 2017 15:54:40 -0400 Subject: [PATCH 0766/1644] Refs CF-1682. Fixed typo --- redhawk/src/testing/tests/test_09_DomainPersistence.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/redhawk/src/testing/tests/test_09_DomainPersistence.py b/redhawk/src/testing/tests/test_09_DomainPersistence.py index 370712229..7b4113ef8 100644 --- a/redhawk/src/testing/tests/test_09_DomainPersistence.py +++ b/redhawk/src/testing/tests/test_09_DomainPersistence.py @@ -428,7 +428,7 @@ def test_EventAppPortConnectionSIGTERMNoPersist(self): devMgrs = domMgr._get_deviceManagers() self.assertEqual(len(devMgrs), 0) - def test_EventAppPortConnectionSIGQUITFoo(self): + def test_EventAppPortConnectionSIGQUIT(self): self.localEvent = threading.Event() self.eventFlag = False From ce8af513890c4d75b6d21b432a2743ce6add3665 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Thu, 30 Mar 2017 17:20:07 -0400 Subject: [PATCH 0767/1644] Refs CF-1681. Added tests to verify that the connection manager state is persisted --- .../tests/test_09_DomainPersistence.py | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/redhawk/src/testing/tests/test_09_DomainPersistence.py b/redhawk/src/testing/tests/test_09_DomainPersistence.py index 7b4113ef8..a40855b65 100644 --- a/redhawk/src/testing/tests/test_09_DomainPersistence.py +++ b/redhawk/src/testing/tests/test_09_DomainPersistence.py @@ -293,6 +293,8 @@ def test_EventAppPortConnectionSIGKILL(self): app.start() eventChannelMgr = domMgr._get_eventChannelMgr() + connMgr = domMgr._get_connectionMgr() + initial_connections = connMgr.listConnections(100)[0] _consumer = Consumer_i(self) evt_reg = CF.EventChannelManager.EventRegistration(channel_name = 'anotherChannel', reg_id = 'my_reg_id') @@ -312,6 +314,17 @@ def test_EventAppPortConnectionSIGKILL(self): # Restart the Domain Manager (which should restore the old channel) self._nb_domMgr, domMgr = self.launchDomainManager(endpoint="giop:tcp::5679", dbURI=self._dbfile) + current_connections = connMgr.listConnections(100)[0] + current_connection_ids = [] + for _cc in current_connections: + current_connection_ids.append(_cc.connectionRecordId) + initial_connection_ids = [] + for _cc in initial_connections: + initial_connection_ids.append(_cc.connectionRecordId) + self.assertEquals(len(current_connection_ids), len(initial_connection_ids)) + for _cc in initial_connection_ids: + self.assertTrue(_cc in current_connection_ids) + newappFact = domMgr._get_applicationFactories()[0] app2 = newappFact.create(appFact._get_name(), [], []) app2.start() @@ -353,6 +366,8 @@ def test_EventAppPortConnectionSIGTERM(self): app.start() eventChannelMgr = domMgr._get_eventChannelMgr() + connMgr = domMgr._get_connectionMgr() + initial_connections = connMgr.listConnections(100)[0] _consumer = Consumer_i(self) evt_reg = CF.EventChannelManager.EventRegistration(channel_name = 'anotherChannel', reg_id = 'my_reg_id') @@ -372,6 +387,17 @@ def test_EventAppPortConnectionSIGTERM(self): # Restart the Domain Manager (which should restore the old channel) self._nb_domMgr, domMgr = self.launchDomainManager(endpoint="giop:tcp::5679", dbURI=self._dbfile) + current_connections = connMgr.listConnections(100)[0] + current_connection_ids = [] + for _cc in current_connections: + current_connection_ids.append(_cc.connectionRecordId) + initial_connection_ids = [] + for _cc in initial_connections: + initial_connection_ids.append(_cc.connectionRecordId) + self.assertEquals(len(current_connection_ids), len(initial_connection_ids)) + for _cc in initial_connection_ids: + self.assertTrue(_cc in current_connection_ids) + newappFact = domMgr._get_applicationFactories()[0] app2 = newappFact.create(appFact._get_name(), [], []) app2.start() @@ -442,6 +468,8 @@ def test_EventAppPortConnectionSIGQUIT(self): app.start() eventChannelMgr = domMgr._get_eventChannelMgr() + connMgr = domMgr._get_connectionMgr() + initial_connections = connMgr.listConnections(100)[0] _consumer = Consumer_i(self) evt_reg = CF.EventChannelManager.EventRegistration(channel_name = 'anotherChannel', reg_id = 'my_reg_id') @@ -461,6 +489,17 @@ def test_EventAppPortConnectionSIGQUIT(self): # Restart the Domain Manager (which should restore the old channel) self._nb_domMgr, domMgr = self.launchDomainManager(endpoint="giop:tcp::5679", dbURI=self._dbfile) + current_connections = connMgr.listConnections(100)[0] + current_connection_ids = [] + for _cc in current_connections: + current_connection_ids.append(_cc.connectionRecordId) + initial_connection_ids = [] + for _cc in initial_connections: + initial_connection_ids.append(_cc.connectionRecordId) + self.assertEquals(len(current_connection_ids), len(initial_connection_ids)) + for _cc in initial_connection_ids: + self.assertTrue(_cc in current_connection_ids) + newappFact = domMgr._get_applicationFactories()[0] app2 = newappFact.create(appFact._get_name(), [], []) app2.start() From d251f34dec2153e638d1dc6bb26e6f991f12fc11 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 12 Apr 2017 14:40:37 -0400 Subject: [PATCH 0768/1644] CF-855 Use the 'octave-config' utility to locate an Octave installation at both code generation and build time The old Autoconf macro and variable names remain; however, newly generated Octave components use the new macro and variable names. --- .../cpp/component/base/templates/Makefile.am | 14 +--- .../cpp/component/mFunction/generator.py | 2 +- .../component/mFunction/templates/Makefile.am | 31 +++++++++ .../mFunction/templates/configure.ac | 6 +- .../codegen/jinja/cpp/component/octave.py | 30 +++++--- redhawk/src/acinclude/Makefile.am | 3 +- redhawk/src/acinclude/octave.m4 | 69 +++++++++++++++++++ 7 files changed, 129 insertions(+), 26 deletions(-) create mode 100644 redhawk-codegen/redhawk/codegen/jinja/cpp/component/mFunction/templates/Makefile.am create mode 100644 redhawk/src/acinclude/octave.m4 diff --git a/redhawk-codegen/redhawk/codegen/jinja/cpp/component/base/templates/Makefile.am b/redhawk-codegen/redhawk/codegen/jinja/cpp/component/base/templates/Makefile.am index c94efc759..d9becd431 100644 --- a/redhawk-codegen/redhawk/codegen/jinja/cpp/component/base/templates/Makefile.am +++ b/redhawk-codegen/redhawk/codegen/jinja/cpp/component/base/templates/Makefile.am @@ -26,6 +26,9 @@ #{% block license %} #{# Allow child templates to include license #} #{% endblock %} +ACLOCAL_AMFLAGS = -I m4 -I${OSSIEHOME}/share/aclocal/ossie +AUTOMAKE_OPTIONS = subdir-objects + #{% block binInfo %} ossieName = {{component.name}} #{% if component.impl.module %} @@ -41,14 +44,7 @@ bin_PROGRAMS = {{target}} xmldir = {{installdir}} dist_xml_DATA = {{component.profile.values()|relpath(outputdir)|join(' ')}} #{% endblock %} -ACLOCAL_AMFLAGS = -I m4 -I${OSSIEHOME}/share/aclocal/ossie -AUTOMAKE_OPTIONS = subdir-objects - -#{% if component.mFunction != None %} -mdir = {{impldir}} -dist_m_DATA = *.m -#{% endif %} #{% if component.impl.module %} #{% set solib = component.impl.entrypoint|relpath(outputdir) %} .PHONY: convenience-link clean-convenience-link @@ -100,8 +96,4 @@ include $(srcdir)/Makefile.am.ide #{% else %} {{amtarget}}_LDFLAGS = -Wall $(redhawk_LDFLAGS_auto) #{% endif %} -#{% if component.mFunction %} -{{target}}_CXXFLAGS += $(M_FUNCTION_INTERPRETER_INCLUDE) -{{target}}_LDFLAGS += $(BOOST_FILESYSTEM_LIB) $(M_FUNCTION_INTERPRETER_LOAD) -#{% endif %} #{% endblock %} diff --git a/redhawk-codegen/redhawk/codegen/jinja/cpp/component/mFunction/generator.py b/redhawk-codegen/redhawk/codegen/jinja/cpp/component/mFunction/generator.py index a2a3b0091..6ff8d2218 100644 --- a/redhawk-codegen/redhawk/codegen/jinja/cpp/component/mFunction/generator.py +++ b/redhawk-codegen/redhawk/codegen/jinja/cpp/component/mFunction/generator.py @@ -59,7 +59,7 @@ class OctaveComponentGenerator(PullComponentGenerator): def templates(self, component): templates = [ CppTemplate('mFunction/main.cpp'), - AutomakeTemplate('base/Makefile.am'), + AutomakeTemplate('Makefile.am'), AutomakeTemplate('base/Makefile.am.ide', userfile=True), AutoconfTemplate('configure.ac'), diff --git a/redhawk-codegen/redhawk/codegen/jinja/cpp/component/mFunction/templates/Makefile.am b/redhawk-codegen/redhawk/codegen/jinja/cpp/component/mFunction/templates/Makefile.am new file mode 100644 index 000000000..f59fe6ca9 --- /dev/null +++ b/redhawk-codegen/redhawk/codegen/jinja/cpp/component/mFunction/templates/Makefile.am @@ -0,0 +1,31 @@ +#{# +# This file is protected by Copyright. Please refer to the COPYRIGHT file +# distributed with this source distribution. +# +# This file is part of REDHAWK core. +# +# REDHAWK core is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation, either version 3 of the License, or (at your option) any +# later version. +# +# REDHAWK core is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +# details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/. +#} +#{% extends "base/Makefile.am" %} + +#{% block extensions %} +mdir = {{impldir}} +dist_m_DATA = *.m +#{% endblock %} + +#{% block compileFlags %} +{{ super() -}} +{{amtarget}}_CXXFLAGS += $(OCTAVE_CPPFLAGS) +{{amtarget}}_LDFLAGS += $(BOOST_FILESYSTEM_LIB) $(OCTAVE_LIBS) +#{% endblock %} diff --git a/redhawk-codegen/redhawk/codegen/jinja/cpp/component/mFunction/templates/configure.ac b/redhawk-codegen/redhawk/codegen/jinja/cpp/component/mFunction/templates/configure.ac index ac0604fd5..9ce5cc77f 100644 --- a/redhawk-codegen/redhawk/codegen/jinja/cpp/component/mFunction/templates/configure.ac +++ b/redhawk-codegen/redhawk/codegen/jinja/cpp/component/mFunction/templates/configure.ac @@ -19,14 +19,10 @@ #} #{% extends "base/configure.ac" %} -#{% block acChecks %} -AC_HEADER_M_FUNCTION() -AC_LIB_M_FUNCTION() -{{ super() -}} -#{% endblock %} #{% block coreDeps %} {{ super() -}} AX_BOOST_FILESYSTEM +RH_OCTAVE([{{versions.octave}}]) #{% endblock %} #{% block softpkgDeps %} #{% endblock %} diff --git a/redhawk-codegen/redhawk/codegen/jinja/cpp/component/octave.py b/redhawk-codegen/redhawk/codegen/jinja/cpp/component/octave.py index 764cf783b..6c04d69f4 100644 --- a/redhawk-codegen/redhawk/codegen/jinja/cpp/component/octave.py +++ b/redhawk-codegen/redhawk/codegen/jinja/cpp/component/octave.py @@ -19,20 +19,34 @@ # import commands +import os from redhawk.codegen.jinja.cpp.component.mFunction.generator import OctaveComponentGenerator, loader +from redhawk.codegen import versions def factory(**opts): return OctaveComponentGenerator(**opts) -def check(): +def _version_tuple(ver): + return tuple(int(n) for n in ver.split('.')) + +def _check_octave(): # Attempt to determine if octave-devel v3.4 or greater is installed. - findCommand = 'find /usr -regextype posix-extended -regex ".*include\/octave\-[3]+\.[4-9]+\.[0-9]+$" -print -quit 2>/dev/null' - (status,output) = commands.getstatusoutput(findCommand) - if output == "": - # suitable octave header files were not found - print "Could not find suitable Octave installation. Octave-devel v3.4 or greater is required." + (status, output) = commands.getstatusoutput('octave-config -v') + if status: return False - else: - # suitable octave header files were found + + # Check the version against the minimum + version = _version_tuple(output) + if version < _version_tuple(versions.octave): + return False + + incdir = commands.getoutput('octave-config -p OCTINCLUDEDIR') + return os.path.exists(incdir) + +def check(): + if _check_octave(): return True + else: + print "Could not find suitable Octave installation. Octave-devel v%s or greater is required." % versions.octave + return False diff --git a/redhawk/src/acinclude/Makefile.am b/redhawk/src/acinclude/Makefile.am index ded2755c6..cbcffefe1 100644 --- a/redhawk/src/acinclude/Makefile.am +++ b/redhawk/src/acinclude/Makefile.am @@ -55,4 +55,5 @@ dist_ac_DATA = \ pkg.m4 \ AC_M_FUNCTION_INTEGRATION.m4 \ rhpkg.m4 \ - redhawk.m4 + redhawk.m4 \ + octave.m4 diff --git a/redhawk/src/acinclude/octave.m4 b/redhawk/src/acinclude/octave.m4 new file mode 100644 index 000000000..7495fb2e0 --- /dev/null +++ b/redhawk/src/acinclude/octave.m4 @@ -0,0 +1,69 @@ +dnl +dnl This file is protected by Copyright. Please refer to the COPYRIGHT file +dnl distributed with this source distribution. +dnl +dnl This file is part of REDHAWK core. +dnl +dnl REDHAWK core is free software: you can redistribute it and/or modify it under +dnl the terms of the GNU Lesser General Public License as published by the Free +dnl Software Foundation, either version 3 of the License, or (at your option) any +dnl later version. +dnl +dnl REDHAWK core is distributed in the hope that it will be useful, but WITHOUT +dnl ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +dnl FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +dnl details. +dnl +dnl You should have received a copy of the GNU Lesser General Public License +dnl along with this program. If not, see http://www.gnu.org/licenses/. +dnl + +# RH_PROG_OCTAVE_CONFIG +# --------------------- +AC_DEFUN([RH_PROG_OCTAVE_CONFIG], +[ + AC_ARG_VAR([OCTAVE_CONFIG], [path to octave-config utility]) + AS_IF([test "x$ac_cv_env_OCTAVE_CONFIG_set" != "xset"], [ + AC_PATH_TOOL([OCTAVE_CONFIG], [octave-config]) + ]) +]) + +# RH_OCTAVE([MINIMUM-VERSION]) +# +# Checks for Octave installation, with an optional minimum version +# ----------------------------------------------------------------------------- +AC_DEFUN([RH_OCTAVE], +[ + dnl Require octave-config to be able to get the include and library + dnl directories + AC_REQUIRE([RH_PROG_OCTAVE_CONFIG]) + AS_IF([test "x$OCTAVE_CONFIG" == "x"], [ + AC_ERROR([octave-config was not found]) + ]) + + dnl If a minimum version was given, get the Octave version from octave-config + dnl and compare; otherwise, just assume it should work + AS_IF([test x$1 != x], [ + AC_MSG_CHECKING([for Octave >= $1]) + rh_octave_version=`$OCTAVE_CONFIG -v` + AS_VERSION_COMPARE([$rh_octave_version], [$1], [ + AC_ERROR([Octave version $rh_octave_version found, $1 required]) + ], [], []) + ], [ + AC_MSG_CHECKING([for Octave]) + ]) + + dnl Get the include directory from octave-config, then format it into usable + dnl include paths + rh_octave_incdir=`$OCTAVE_CONFIG -p OCTINCLUDEDIR` + OCTAVE_CPPFLAGS="-I${rh_octave_incdir}/.. -I${rh_octave_incdir}" + AC_SUBST([OCTAVE_CPPFLAGS]) + + dnl Get the library directory from octave-config for use as a linker path, + dnl then add the "octave" an "octinterp" libraries to linker flags + rh_octave_libdir=`$OCTAVE_CONFIG -p OCTLIBDIR` + OCTAVE_LIBS="-L${rh_octave_libdir} -loctave -loctinterp" + AC_SUBST([OCTAVE_LIBS]) + + AC_MSG_RESULT([yes]) +]) From 653608936bf90dfa2a7c171b5782660d600c2f61 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 12 Apr 2017 15:36:09 -0400 Subject: [PATCH 0769/1644] Fix current directory mismatch with test Octave components; remove test files in Octave codegen testing that did not differ from the default generated file at the time they were added --- codegenTesting/helpers/scatest.py | 45 ++++++----- .../tests/test_octaveTestSink.py | 81 ------------------- .../tests/test_octaveTestSource.py | 81 ------------------- 3 files changed, 23 insertions(+), 184 deletions(-) delete mode 100644 codegenTesting/sdr/dom/components/octaveTestSink/tests/test_octaveTestSink.py delete mode 100644 codegenTesting/sdr/dom/components/octaveTestSource/tests/test_octaveTestSource.py diff --git a/codegenTesting/helpers/scatest.py b/codegenTesting/helpers/scatest.py index f8ceac83c..89a6b0981 100755 --- a/codegenTesting/helpers/scatest.py +++ b/codegenTesting/helpers/scatest.py @@ -20,7 +20,8 @@ # from _unitTestHelpers.scatest import * import commands -from subprocess import Popen +import glob +import os from xml.dom.minidom import parse import common @@ -182,26 +183,26 @@ def runUnitTests(self): impl_id = impl['id'] impl_name = impl['name'] spd_file = os.path.join(self.build_dir, self.base_name+'.spd.xml') - if self.octave_test_dir: - # setup octave components to run from their test directory - start_dir = os.getcwd(); - spd_file = "../"+self.base_name+'.spd.xml' - os.chdir(self.test_dir) - - _files = os.listdir(self.build_dir+'/tests') - for _file in _files: - if len(_file) > 8: - if _file[-3:] == '.py' and _file[:5] == 'test_': - retval = ossie.utils.testing.ScaComponentTestProgram(spd_file, - module=_file[:-3], - impl=impl_id) - - if self.octave_test_dir: - os.chdir(start_dir) - - for result in retval.results: - if result.errors or result.failures: - if not lang in failures: - failures.append(lang) + + for test_file in glob.glob(self.build_dir+'/tests/test_*.py'): + _file = os.path.basename(test_file) + + if self.octave_test_dir: + # setup octave components to run from their test directory + start_dir = os.getcwd(); + spd_file = "../"+self.base_name+'.spd.xml' + os.chdir(self.test_dir) + + retval = ossie.utils.testing.ScaComponentTestProgram(spd_file, + module=_file[:-3], + impl=impl_id) + + if self.octave_test_dir: + os.chdir(start_dir) + + for result in retval.results: + if result.errors or result.failures: + if not lang in failures: + failures.append(lang) self.assertEqual(len(failures), 0, msg='failed for ' + ', '.join(failures)) diff --git a/codegenTesting/sdr/dom/components/octaveTestSink/tests/test_octaveTestSink.py b/codegenTesting/sdr/dom/components/octaveTestSink/tests/test_octaveTestSink.py deleted file mode 100644 index 3d45df3cf..000000000 --- a/codegenTesting/sdr/dom/components/octaveTestSink/tests/test_octaveTestSink.py +++ /dev/null @@ -1,81 +0,0 @@ -#!/usr/bin/env python -# -# This file is protected by Copyright. Please refer to the COPYRIGHT file -# distributed with this source distribution. -# -# This file is part of REDHAWK codegenTesting. -# -# REDHAWK codegenTesting is free software: you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation, either version 3 of the License, or (at your option) any -# later version. -# -# REDHAWK codegenTesting is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more -# details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with this program. If not, see http://www.gnu.org/licenses/. -# -import unittest -import ossie.utils.testing -import os -from omniORB import any - -from ossie.utils import sb - -class ResourceTests(ossie.utils.testing.ScaComponentTestCase): - """Test for all resource implementations in octaveTestSink""" - - def testScaBasicBehavior(self): - ####################################################################### - # Launch the resource with the default execparams - execparams = self.getPropertySet(kinds=("execparam",), modes=("readwrite", "writeonly"), includeNil=False) - execparams = dict([(x.id, any.from_any(x.value)) for x in execparams]) - self.launch(execparams) - - ####################################################################### - # Verify the basic state of the resource - self.assertNotEqual(self.comp, None) - self.assertEqual(self.comp.ref._non_existent(), False) - - self.assertEqual(self.comp.ref._is_a("IDL:CF/Resource:1.0"), True) - - ####################################################################### - # Validate that query returns all expected parameters - # Query of '[]' should return the following set of properties - expectedProps = [] - expectedProps.extend(self.getPropertySet(kinds=("configure", "execparam"), modes=("readwrite", "readonly"), includeNil=True)) - expectedProps.extend(self.getPropertySet(kinds=("allocate",), action="external", includeNil=True)) - props = self.comp.query([]) - props = dict((x.id, any.from_any(x.value)) for x in props) - # Query may return more than expected, but not less - for expectedProp in expectedProps: - self.assertEquals(props.has_key(expectedProp.id), True) - - ####################################################################### - # Verify that all expected ports are available - for port in self.scd.get_componentfeatures().get_ports().get_uses(): - port_obj = self.comp.getPort(str(port.get_usesname())) - self.assertNotEqual(port_obj, None) - self.assertEqual(port_obj._non_existent(), False) - self.assertEqual(port_obj._is_a("IDL:CF/Port:1.0"), True) - - for port in self.scd.get_componentfeatures().get_ports().get_provides(): - port_obj = self.comp.getPort(str(port.get_providesname())) - self.assertNotEqual(port_obj, None) - self.assertEqual(port_obj._non_existent(), False) - self.assertEqual(port_obj._is_a(port.get_repid()), True) - - ####################################################################### - # Make sure start and stop can be called without throwing exceptions - self.comp.start() - self.comp.stop() - - ####################################################################### - # Simulate regular resource shutdown - self.comp.releaseObject() - -if __name__ == "__main__": - ossie.utils.testing.main("../octaveTestSink.spd.xml") # By default tests all implementations diff --git a/codegenTesting/sdr/dom/components/octaveTestSource/tests/test_octaveTestSource.py b/codegenTesting/sdr/dom/components/octaveTestSource/tests/test_octaveTestSource.py deleted file mode 100644 index 7ccd0ce5d..000000000 --- a/codegenTesting/sdr/dom/components/octaveTestSource/tests/test_octaveTestSource.py +++ /dev/null @@ -1,81 +0,0 @@ -#!/usr/bin/env python -# -# This file is protected by Copyright. Please refer to the COPYRIGHT file -# distributed with this source distribution. -# -# This file is part of REDHAWK codegenTesting. -# -# REDHAWK codegenTesting is free software: you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation, either version 3 of the License, or (at your option) any -# later version. -# -# REDHAWK codegenTesting is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more -# details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with this program. If not, see http://www.gnu.org/licenses/. -# -import unittest -import ossie.utils.testing -import os -from omniORB import any - -from ossie.utils import sb - -class ResourceTests(ossie.utils.testing.ScaComponentTestCase): - """Test for all resource implementations in octaveTestSource""" - - def testScaBasicBehavior(self): - ####################################################################### - # Launch the resource with the default execparams - execparams = self.getPropertySet(kinds=("execparam",), modes=("readwrite", "writeonly"), includeNil=False) - execparams = dict([(x.id, any.from_any(x.value)) for x in execparams]) - self.launch(execparams) - - ####################################################################### - # Verify the basic state of the resource - self.assertNotEqual(self.comp, None) - self.assertEqual(self.comp.ref._non_existent(), False) - - self.assertEqual(self.comp.ref._is_a("IDL:CF/Resource:1.0"), True) - - ####################################################################### - # Validate that query returns all expected parameters - # Query of '[]' should return the following set of properties - expectedProps = [] - expectedProps.extend(self.getPropertySet(kinds=("configure", "execparam"), modes=("readwrite", "readonly"), includeNil=True)) - expectedProps.extend(self.getPropertySet(kinds=("allocate",), action="external", includeNil=True)) - props = self.comp.query([]) - props = dict((x.id, any.from_any(x.value)) for x in props) - # Query may return more than expected, but not less - for expectedProp in expectedProps: - self.assertEquals(props.has_key(expectedProp.id), True) - - ####################################################################### - # Verify that all expected ports are available - for port in self.scd.get_componentfeatures().get_ports().get_uses(): - port_obj = self.comp.getPort(str(port.get_usesname())) - self.assertNotEqual(port_obj, None) - self.assertEqual(port_obj._non_existent(), False) - self.assertEqual(port_obj._is_a("IDL:CF/Port:1.0"), True) - - for port in self.scd.get_componentfeatures().get_ports().get_provides(): - port_obj = self.comp.getPort(str(port.get_providesname())) - self.assertNotEqual(port_obj, None) - self.assertEqual(port_obj._non_existent(), False) - self.assertEqual(port_obj._is_a(port.get_repid()), True) - - ####################################################################### - # Make sure start and stop can be called without throwing exceptions - self.comp.start() - self.comp.stop() - - ####################################################################### - # Simulate regular resource shutdown - self.comp.releaseObject() - -if __name__ == "__main__": - ossie.utils.testing.main("../octaveTestSource.spd.xml") # By default tests all implementations From ae6ee755099c7c5cf6a100b81d23d7ef18a79b4a Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 12 Apr 2017 16:35:16 -0400 Subject: [PATCH 0770/1644] Remove dictionary entry from basic component mapper that is only used in Octave generator --- redhawk-codegen/redhawk/codegen/jinja/mapping.py | 1 - 1 file changed, 1 deletion(-) diff --git a/redhawk-codegen/redhawk/codegen/jinja/mapping.py b/redhawk-codegen/redhawk/codegen/jinja/mapping.py index d1d6a153e..77d1c843b 100644 --- a/redhawk-codegen/redhawk/codegen/jinja/mapping.py +++ b/redhawk-codegen/redhawk/codegen/jinja/mapping.py @@ -271,7 +271,6 @@ class ComponentMapper(SoftpkgMapper): def mapComponent(self, softpkg): component = self.mapSoftpkg(softpkg) component['license'] = None - component['mFunction'] = None if softpkg.descriptor(): if softpkg.descriptor().supports('IDL:CF/AggregateDevice:1.0'): component['aggregate'] = True From b001e1dd259bfd6995c44833f8bf49ef74698abd Mon Sep 17 00:00:00 2001 From: Max Robert Date: Mon, 17 Apr 2017 15:20:18 -0400 Subject: [PATCH 0771/1644] Refs CF-1644. RH::DEPLOYMENT_ROOT in GPP is the cache directory, not the working directory --- GPP/tests/test_GPP.py | 16 ++++++++++++++++ .../src/base/framework/LoadableDevice_impl.cpp | 10 +++++++++- .../src/base/include/ossie/LoadableDevice_impl.h | 2 +- 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/GPP/tests/test_GPP.py b/GPP/tests/test_GPP.py index eebd4a4a7..07be50ab8 100755 --- a/GPP/tests/test_GPP.py +++ b/GPP/tests/test_GPP.py @@ -1552,6 +1552,22 @@ def tearDown(self): shutil.rmtree(self.base_dir) + def test_CheckDEPLOYMENTROOT(self): + self.assertNotEqual(self._domMgr, None) + nodebooter, devMgr = self.launchDeviceManager("/nodes/test_VarCache_node/DeviceManager.dcd.xml", domainManager=self.dom.ref) + self.assertNotEqual(devMgr, None) + app = self._rhDom.createApplication('/waveforms/check_cwd_w/check_cwd_w.sad.xml') + self.assertNotEqual(app, None) + self.assertEquals(app.comps[0].cwd, self.cwd_dir) + pid = str(app._get_componentProcessIds()[0].processId) + fp=open('/proc/'+pid+'/cmdline','r') + cmdline = fp.read() + fp.close() + _args = cmdline.split('\x00') + idx = _args.index('RH::DEPLOYMENT_ROOT') + deployment_root=_args[idx+1] + self.assertEquals(deployment_root, self._rhDom.devices[0].cacheDirectory) + def test_PyCompConfigCacheCWD(self): self.assertNotEqual(self._domMgr, None) nodebooter, devMgr = self.launchDeviceManager("/nodes/test_VarCache_node/DeviceManager.dcd.xml", domainManager=self.dom.ref) diff --git a/redhawk/src/base/framework/LoadableDevice_impl.cpp b/redhawk/src/base/framework/LoadableDevice_impl.cpp index 0b7ea8988..5f4bf2aa9 100644 --- a/redhawk/src/base/framework/LoadableDevice_impl.cpp +++ b/redhawk/src/base/framework/LoadableDevice_impl.cpp @@ -908,7 +908,15 @@ bool LoadableDevice_impl::isFileLoaded (const char* fileName) } -const std::string& LoadableDevice_impl::getCacheDirectory() const +const std::string& LoadableDevice_impl::getCacheDirectory() { + if (this->getPropertyFromId("cacheDirectory")) { + std::string cache_dir = ((StringProperty*)this->getPropertyFromId("cacheDirectory"))->getValue(); + if (!cache_dir.empty()) { + if (cacheDirectory != cache_dir) { + cacheDirectory = cache_dir; + } + } + } return cacheDirectory; } diff --git a/redhawk/src/base/include/ossie/LoadableDevice_impl.h b/redhawk/src/base/include/ossie/LoadableDevice_impl.h index 299cd567f..7affd1251 100644 --- a/redhawk/src/base/include/ossie/LoadableDevice_impl.h +++ b/redhawk/src/base/include/ossie/LoadableDevice_impl.h @@ -226,7 +226,7 @@ class LoadableDevice_impl: std::string prependCacheIfAvailable(const std::string &localPath); // Returns the base directory in use for the file cache - const std::string& getCacheDirectory() const; + const std::string& getCacheDirectory(); private: LoadableDevice_impl(); // No default constructor From db8477668a88940577ac4fc2cbe69da4d11d58da Mon Sep 17 00:00:00 2001 From: Max Robert Date: Mon, 17 Apr 2017 15:27:24 -0400 Subject: [PATCH 0772/1644] Refs CF-1724. Code generator does not use a reserved Python word as the argument of a generated function --- .../jinja/python/component/frontend/templates/resource.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/redhawk-codegen/redhawk/codegen/jinja/python/component/frontend/templates/resource.py b/redhawk-codegen/redhawk/codegen/jinja/python/component/frontend/templates/resource.py index 8677396d3..d687de8e2 100644 --- a/redhawk-codegen/redhawk/codegen/jinja/python/component/frontend/templates/resource.py +++ b/redhawk-codegen/redhawk/codegen/jinja/python/component/frontend/templates/resource.py @@ -228,7 +228,7 @@ def set_nav_packet(self,port_name, nav_info): def get_rf_flow_id(self,port_name): return "" - def set_rf_flow_id(self,port_name, id): + def set_rf_flow_id(self,port_name, _id): pass def get_rfinfo_pkt(self,port_name): From 2dd3b1f5aed5213a216e0f455f96c726c7603e88 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Tue, 18 Apr 2017 15:07:27 -0400 Subject: [PATCH 0773/1644] Refs CF-1687. Raise the BadParameterException with the correct arguments --- .../jinja/python/component/frontend/templates/resource.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/redhawk-codegen/redhawk/codegen/jinja/python/component/frontend/templates/resource.py b/redhawk-codegen/redhawk/codegen/jinja/python/component/frontend/templates/resource.py index d687de8e2..3bd75a5eb 100644 --- a/redhawk-codegen/redhawk/codegen/jinja/python/component/frontend/templates/resource.py +++ b/redhawk-codegen/redhawk/codegen/jinja/python/component/frontend/templates/resource.py @@ -112,7 +112,7 @@ def setTunerCenterFrequency(self,allocation_id, freq): if idx < 0: raise FRONTEND.FrontendException("Invalid allocation id") if allocation_id != self.getControlAllocationId(idx): raise FRONTEND.FrontendException(("ID "+str(allocation_id)+" does not have authorization to modify the tuner")) - if freq<0: raise FRONTEND.BadParameterException() + if freq<0: raise FRONTEND.BadParameterException("Center frequency cannot be less than 0") # set hardware to new value. Raise an exception if it's not possible self.frontend_tuner_status[idx].center_frequency = freq @@ -126,7 +126,7 @@ def setTunerBandwidth(self,allocation_id, bw): if idx < 0: raise FRONTEND.FrontendException("Invalid allocation id") if allocation_id != self.getControlAllocationId(idx): raise FRONTEND.FrontendException(("ID "+str(allocation_id)+" does not have authorization to modify the tuner")) - if bw<0: raise FRONTEND.BadParameterException() + if bw<0: raise FRONTEND.BadParameterException("Bandwidth cannot be less than 0") # set hardware to new value. Raise an exception if it's not possible self.frontend_tuner_status[idx].bandwidth = bw @@ -174,7 +174,7 @@ def setTunerOutputSampleRate(self,allocation_id, sr): if idx < 0: raise FRONTEND.FrontendException("Invalid allocation id") if allocation_id != self.getControlAllocationId(idx): raise FRONTEND.FrontendException(("ID "+str(allocation_id)+" does not have authorization to modify the tuner")) - if sr<0: raise FRONTEND.BadParameterException() + if sr<0: raise FRONTEND.BadParameterException("Sample rate cannot be less than 0") # set hardware to new value. Raise an exception if it's not possible self.frontend_tuner_status[idx].sample_rate = sr From 47e847217279d930cc9013c104fcb607e66d8069 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Tue, 18 Apr 2017 15:19:22 -0400 Subject: [PATCH 0774/1644] Refs CF-1687. Make the BadParameterException message in C++ and Java the same as in Python --- .../jinja/cpp/component/frontend/templates/resource.cpp | 6 +++--- .../jinja/java/component/frontend/templates/resource.java | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/redhawk-codegen/redhawk/codegen/jinja/cpp/component/frontend/templates/resource.cpp b/redhawk-codegen/redhawk/codegen/jinja/cpp/component/frontend/templates/resource.cpp index 3be1aedde..3dd3418a3 100644 --- a/redhawk-codegen/redhawk/codegen/jinja/cpp/component/frontend/templates/resource.cpp +++ b/redhawk-codegen/redhawk/codegen/jinja/cpp/component/frontend/templates/resource.cpp @@ -108,7 +108,7 @@ void ${className}::setTunerCenterFrequency(const std::string& allocation_id, dou if (idx < 0) throw FRONTEND::FrontendException("Invalid allocation id"); if(allocation_id != getControlAllocationId(idx)) throw FRONTEND::FrontendException(("ID "+allocation_id+" does not have authorization to modify the tuner").c_str()); - if (freq<0) throw FRONTEND::BadParameterException(); + if (freq<0) throw FRONTEND::BadParameterException("Center frequency cannot be less than 0"); // set hardware to new value. Raise an exception if it's not possible this->frontend_tuner_status[idx].center_frequency = freq; } @@ -124,7 +124,7 @@ void ${className}::setTunerBandwidth(const std::string& allocation_id, double bw if (idx < 0) throw FRONTEND::FrontendException("Invalid allocation id"); if(allocation_id != getControlAllocationId(idx)) throw FRONTEND::FrontendException(("ID "+allocation_id+" does not have authorization to modify the tuner").c_str()); - if (bw<0) throw FRONTEND::BadParameterException(); + if (bw<0) throw FRONTEND::BadParameterException("Bandwidth cannot be less than 0"); // set hardware to new value. Raise an exception if it's not possible this->frontend_tuner_status[idx].bandwidth = bw; } @@ -187,7 +187,7 @@ void ${className}::setTunerOutputSampleRate(const std::string& allocation_id, do if (idx < 0) throw FRONTEND::FrontendException("Invalid allocation id"); if(allocation_id != getControlAllocationId(idx)) throw FRONTEND::FrontendException(("ID "+allocation_id+" does not have authorization to modify the tuner").c_str()); - if (sr<0) throw FRONTEND::BadParameterException(); + if (sr<0) throw FRONTEND::BadParameterException("Sample rate cannot be less than 0"); // set hardware to new value. Raise an exception if it's not possible this->frontend_tuner_status[idx].sample_rate = sr; } diff --git a/redhawk-codegen/redhawk/codegen/jinja/java/component/frontend/templates/resource.java b/redhawk-codegen/redhawk/codegen/jinja/java/component/frontend/templates/resource.java index b662e17a2..b12dace06 100644 --- a/redhawk-codegen/redhawk/codegen/jinja/java/component/frontend/templates/resource.java +++ b/redhawk-codegen/redhawk/codegen/jinja/java/component/frontend/templates/resource.java @@ -133,7 +133,7 @@ public void setTunerCenterFrequency(final String allocation_id, double freq) thr if (idx < 0) throw new FRONTEND.FrontendException("Invalid allocation id"); if(allocation_id != getControlAllocationId(idx)) throw new FRONTEND.FrontendException(("ID "+allocation_id+" does not have authorization to modify the tuner")); - if (freq<0) throw new FRONTEND.BadParameterException(); + if (freq<0) throw new FRONTEND.BadParameterException("Center frequency cannot be less than 0"); // set hardware to new value. Raise an exception if it's not possible this.frontend_tuner_status.getValue().get(idx).center_frequency.setValue(freq); } @@ -151,7 +151,7 @@ public void setTunerBandwidth(final String allocation_id, double bw) throws FRON if (idx < 0) throw new FRONTEND.FrontendException("Invalid allocation id"); if(allocation_id != getControlAllocationId(idx)) throw new FRONTEND.FrontendException(("ID "+allocation_id+" does not have authorization to modify the tuner")); - if (bw<0) throw new FRONTEND.BadParameterException(); + if (bw<0) throw new FRONTEND.BadParameterException("Bandwidth cannot be less than 0"); // set hardware to new value. Raise an exception if it's not possible this.frontend_tuner_status.getValue().get(idx).bandwidth.setValue(bw); } @@ -218,7 +218,7 @@ public void setTunerOutputSampleRate(final String allocation_id, double sr) thro if (idx < 0) throw new FRONTEND.FrontendException("Invalid allocation id"); if(allocation_id != getControlAllocationId(idx)) throw new FRONTEND.FrontendException(("ID "+allocation_id+" does not have authorization to modify the tuner")); - if (sr<0) throw new FRONTEND.BadParameterException(); + if (sr<0) throw new FRONTEND.BadParameterException("Sample rate cannot be less than 0"); // set hardware to new value. Raise an exception if it's not possible this.frontend_tuner_status.getValue().get(idx).sample_rate.setValue(sr); } From 7a00fe0e39ae3ad31dcaea3517c68e547d2f8e5d Mon Sep 17 00:00:00 2001 From: Max Robert Date: Thu, 20 Apr 2017 13:39:14 -0400 Subject: [PATCH 0775/1644] Refs CF-1695. Created addChannels function to provide more control over the tuner configuration --- .../libsrc/cpp/fe_tuner_device.cpp | 31 ++++++++ .../libsrc/cpp/fe_tuner_device.h | 4 +- .../src/frontend/FrontendTunerDevice.java | 74 ++++++++++++++++++- .../libsrc/python/tuner_device.py | 5 ++ .../frontend/templates/resource_base.cpp | 23 ------ .../frontend/templates/resource_base.h | 5 -- .../cpp/component/pull/templates/resource.cpp | 8 +- .../frontend/templates/resource_base.java | 24 ------ .../component/pull/templates/resource.java | 24 +++--- .../pull/templates/resource_base.java | 4 + .../component/pull/templates/resource.py | 8 +- 11 files changed, 137 insertions(+), 73 deletions(-) diff --git a/frontendInterfaces/libsrc/cpp/fe_tuner_device.cpp b/frontendInterfaces/libsrc/cpp/fe_tuner_device.cpp index a93b3be4e..303f270b9 100644 --- a/frontendInterfaces/libsrc/cpp/fe_tuner_device.cpp +++ b/frontendInterfaces/libsrc/cpp/fe_tuner_device.cpp @@ -595,6 +595,37 @@ namespace frontend { return true; } + /* This sets the number of entries in the frontend_tuner_status struct sequence property + * as well as the tuner_allocation_ids vector. Call this function during initialization + */ + template < typename TunerStatusStructType > + void FrontendTunerDevice::setNumChannels(size_t num) + { + this->setNumChannels(num, "RX_DIGITIZER"); + } + + /* This sets the number of entries in the frontend_tuner_status struct sequence property + * as well as the tuner_allocation_ids vector. Call this function during initialization + */ + template < typename TunerStatusStructType > + void FrontendTunerDevice::setNumChannels(size_t num, std::string tuner_type) + { + frontend_tuner_status.clear(); + tuner_allocation_ids.clear(); + addChannels(num, tuner_type); + } + + template < typename TunerStatusStructType > + void FrontendTunerDevice::addChannels(size_t num, std::string tuner_type) { + tuner_allocation_ids.resize(tuner_allocation_ids.size()+num); + for (unsigned int i=0; i void FrontendTunerDevice::deallocateCapacity(const CF::Properties & capacities) throw (CORBA::SystemException, CF::Device::InvalidCapacity, CF::Device::InvalidState) { diff --git a/frontendInterfaces/libsrc/cpp/fe_tuner_device.h b/frontendInterfaces/libsrc/cpp/fe_tuner_device.h index 227af5cd1..b4e2d5f8b 100644 --- a/frontendInterfaces/libsrc/cpp/fe_tuner_device.h +++ b/frontendInterfaces/libsrc/cpp/fe_tuner_device.h @@ -213,7 +213,9 @@ namespace frontend { virtual void assignListener(const std::string& listen_alloc_id, const std::string& alloc_id); virtual void removeListener(const std::string& listen_alloc_id); virtual void removeAllocationIdRouting(const size_t tuner_id) = 0; - virtual void setNumChannels(size_t num) = 0; + virtual void setNumChannels(size_t num); + virtual void setNumChannels(size_t num, std::string tuner_type); + virtual void addChannels(size_t num, std::string tuner_type); // Configure tuner - gets called during allocation virtual bool enableTuner(size_t tuner_id, bool enable); diff --git a/frontendInterfaces/libsrc/java/src/frontend/FrontendTunerDevice.java b/frontendInterfaces/libsrc/java/src/frontend/FrontendTunerDevice.java index d4fa16419..7041b6f4f 100644 --- a/frontendInterfaces/libsrc/java/src/frontend/FrontendTunerDevice.java +++ b/frontendInterfaces/libsrc/java/src/frontend/FrontendTunerDevice.java @@ -269,11 +269,23 @@ public boolean validateRequestVsDevice(final frontend.FETypes.frontend_tuner_all return true; } + private Class frontend_tuner_status_class_type; + public FrontendTunerDevice() { super(); construct(); } - + + public FrontendTunerDevice(Class _genericType) { + super(); + this.frontend_tuner_status_class_type = _genericType; + construct(); + } + + public void setFrontendTunerStatusClassType(Class _genericType) { + this.frontend_tuner_status_class_type = _genericType; + } + private void construct() { loadProperties(); allocation_id_to_tuner_id = new HashMap(); @@ -345,6 +357,64 @@ protected List getListenerAllocationIds(int tuner_id){ return tuner_allocation_ids.get(tuner_id).listener_allocation_ids; } + /* This sets the number of entries in the frontend_tuner_status struct sequence property + * as well as the tuner_allocation_ids vector. Call this function during initialization + */ + public void setNumChannels(int num) + { + this.setNumChannels(num, "RX_DIGITIZER"); + } + + /* This sets the number of entries in the frontend_tuner_status struct sequence property + * as well as the tuner_allocation_ids vector. Call this function during initialization + */ + public void setNumChannels(int num, String tuner_type) + { + if (frontend_tuner_status_class_type == null) { + logger.error("To use setNumChannels from the base classes, this device must be re-generated"); + return; + } + frontend_tuner_status.setValue(new ArrayList()); + tuner_allocation_ids = new ArrayList(); + this.addChannels(num, tuner_type); + } + + /* This sets the number of entries in the frontend_tuner_status struct sequence property + * as well as the tuner_allocation_ids vector. Call this function during initialization + */ + public void addChannels(int num, String tuner_type) + { + if (frontend_tuner_status_class_type == null) { + logger.error("To use addChannels from the base classes, this device must be re-generated"); + return; + } + if (frontend_tuner_status == null) { + frontend_tuner_status.setValue(new ArrayList()); + } + if (tuner_allocation_ids == null) { + tuner_allocation_ids = new ArrayList(); + } + for (int idx=0;idx frontend_tuner_status_class_type; - protected StructSequenceProperty frontend_tuner_status = new StructSequenceProperty ( "FRONTEND::tuner_status", //id diff --git a/frontendInterfaces/libsrc/python/tuner_device.py b/frontendInterfaces/libsrc/python/tuner_device.py index 3ac13c40c..c147dd9c5 100644 --- a/frontendInterfaces/libsrc/python/tuner_device.py +++ b/frontendInterfaces/libsrc/python/tuner_device.py @@ -587,6 +587,11 @@ def updateUsageState(self): # as well as the tuner_allocation_ids vector. Call this function during initialization def setNumChannels(self,num,tuner_type='RX_DIGITIZER'): self.frontend_tuner_status = [] + self.addChannels(num, tuner_type) + + # This sets the number of entries in the frontend_tuner_status struct sequence property + # as well as the tuner_allocation_ids vector. Call this function during initialization + def addChannels(self,num,tuner_type='RX_DIGITIZER'): for ii in range(num): tuner_status = self.frontend_tuner_status_struct_struct() tuner_status.tuner_type = tuner_type diff --git a/redhawk-codegen/redhawk/codegen/jinja/cpp/component/frontend/templates/resource_base.cpp b/redhawk-codegen/redhawk/codegen/jinja/cpp/component/frontend/templates/resource_base.cpp index 8c4ae556a..6243cc553 100644 --- a/redhawk-codegen/redhawk/codegen/jinja/cpp/component/frontend/templates/resource_base.cpp +++ b/redhawk-codegen/redhawk/codegen/jinja/cpp/component/frontend/templates/resource_base.cpp @@ -20,29 +20,6 @@ //% extends "pull/resource_base.cpp" /*{% block extensions %}*/ /*{% if 'FrontendTuner' in component.implements %}*/ -/* This sets the number of entries in the frontend_tuner_status struct sequence property - * as well as the tuner_allocation_ids vector. Call this function during initialization - */ -void ${className}::setNumChannels(size_t num) -{ - this->setNumChannels(num, "RX_DIGITIZER"); -} -/* This sets the number of entries in the frontend_tuner_status struct sequence property - * as well as the tuner_allocation_ids vector. Call this function during initialization - */ - -void ${className}::setNumChannels(size_t num, std::string tuner_type) -{ - frontend_tuner_status.clear(); - frontend_tuner_status.resize(num); - tuner_allocation_ids.clear(); - tuner_allocation_ids.resize(num); - for (std::vector::iterator iter=frontend_tuner_status.begin(); iter!=frontend_tuner_status.end(); iter++) { - iter->enabled = false; - iter->tuner_type = tuner_type; - } -} - void ${className}::frontendTunerStatusChanged(const std::vector* oldValue, const std::vector* newValue) { this->tuner_allocation_ids.resize(this->frontend_tuner_status.size()); diff --git a/redhawk-codegen/redhawk/codegen/jinja/cpp/component/frontend/templates/resource_base.h b/redhawk-codegen/redhawk/codegen/jinja/cpp/component/frontend/templates/resource_base.h index c9bcd8ee0..8e5187e9f 100644 --- a/redhawk-codegen/redhawk/codegen/jinja/cpp/component/frontend/templates/resource_base.h +++ b/redhawk-codegen/redhawk/codegen/jinja/cpp/component/frontend/templates/resource_base.h @@ -48,9 +48,4 @@ /*{% endblock %}*/ /*{% block extendedProtected%}*/ - -/*{% if 'FrontendTuner' in component.implements %}*/ - virtual void setNumChannels(size_t num); - virtual void setNumChannels(size_t num, std::string tuner_type); -/*{% endif %}*/ /*{% endblock %}*/ diff --git a/redhawk-codegen/redhawk/codegen/jinja/cpp/component/pull/templates/resource.cpp b/redhawk-codegen/redhawk/codegen/jinja/cpp/component/pull/templates/resource.cpp index a464ea30c..b9bc62c6e 100644 --- a/redhawk-codegen/redhawk/codegen/jinja/cpp/component/pull/templates/resource.cpp +++ b/redhawk-codegen/redhawk/codegen/jinja/cpp/component/pull/templates/resource.cpp @@ -87,16 +87,18 @@ void ${className}::constructor() The options for devices are: TX, RX, RX_DIGITIZER, CHANNELIZER, DDC, RC_DIGITIZER_CHANNELIZER For example, if this device has 5 physical - tuners, each an RX_DIGITIZER, then the code in the construct function should look like this: + tuners, 3 RX_DIGITIZER and 2 CHANNELIZER, then the code in the construct function + should look like this: - this->setNumChannels(5, "RX_DIGITIZER"); + this->addChannels(3, "RX_DIGITIZER"); + this->addChannels(2, "CHANNELIZER"); The incoming request for tuning contains a string describing the requested tuner type. The string for the request must match the string in the tuner status. /*{% endif %}*/ ***********************************************************************************/ /*{% if 'FrontendTuner' in component.implements %}*/ - this->setNumChannels(1, "RX_DIGITIZER"); + this->addChannels(1, "RX_DIGITIZER"); /*{% endif %}*/ } diff --git a/redhawk-codegen/redhawk/codegen/jinja/java/component/frontend/templates/resource_base.java b/redhawk-codegen/redhawk/codegen/jinja/java/component/frontend/templates/resource_base.java index 1d9139ac2..0541bb331 100644 --- a/redhawk-codegen/redhawk/codegen/jinja/java/component/frontend/templates/resource_base.java +++ b/redhawk-codegen/redhawk/codegen/jinja/java/component/frontend/templates/resource_base.java @@ -80,30 +80,6 @@ public abstract class ${classname} extends ${superClass} /*{% block extensions %}*/ /*{% if 'FrontendTuner' in component.implements %}*/ - /* This sets the number of entries in the frontend_tuner_status struct sequence property - * as well as the tuner_allocation_ids vector. Call this function during initialization - */ - public void setNumChannels(int num) - { - this.setNumChannels(num, "RX_DIGITIZER"); - } - - /* This sets the number of entries in the frontend_tuner_status struct sequence property - * as well as the tuner_allocation_ids vector. Call this function during initialization - */ - public void setNumChannels(int num, String tuner_type) - { - frontend_tuner_status.setValue(new ArrayList()); - tuner_allocation_ids = new ArrayList.tunerAllocationIdsStruct>(); - for (int idx=0;idx listeners = new HashMap(); public void frontendTunerStatusChanged(final List oldValue, final List newValue) diff --git a/redhawk-codegen/redhawk/codegen/jinja/java/component/pull/templates/resource.java b/redhawk-codegen/redhawk/codegen/jinja/java/component/pull/templates/resource.java index 88ba53cf3..9cfd2a8c0 100644 --- a/redhawk-codegen/redhawk/codegen/jinja/java/component/pull/templates/resource.java +++ b/redhawk-codegen/redhawk/codegen/jinja/java/component/pull/templates/resource.java @@ -191,22 +191,24 @@ public class ${classname} extends ${baseclass} { public void constructor() { /*{% if 'FrontendTuner' in component.implements %}*/ - /************************************************************************** + /************************************************************************** - For a tuner device, the structure frontend_tuner_status needs to match the number - of tuners that this device controls and what kind of device it is. - The options for devices are: TX, RX, RX_DIGITIZER, CHANNELIZER, DDC, RC_DIGITIZER_CHANNELIZER + For a tuner device, the structure frontend_tuner_status needs to match the number + of tuners that this device controls and what kind of device it is. + The options for devices are: TX, RX, RX_DIGITIZER, CHANNELIZER, DDC, RC_DIGITIZER_CHANNELIZER - For example, if this device has 5 physical - tuners, each an RX_DIGITIZER, then the code in the construct function should look like this: + For example, if this device has 5 physical + tuners, 3 RX_DIGITIZER and 2 CHANNELIZER, then the code in the construct function + should look like this: - this.setNumChannels(5, "RX_DIGITIZER"); + this.addChannels(3, "RX_DIGITIZER"); + this.addChannels(2, "CHANNELIZER"); - The incoming request for tuning contains a string describing the requested tuner - type. The string for the request must match the string in the tuner status. + The incoming request for tuning contains a string describing the requested tuner + type. The string for the request must match the string in the tuner status. - **************************************************************************/ - this.setNumChannels(1, "RX_DIGITIZER"); + **************************************************************************/ + this.addChannels(1, "RX_DIGITIZER"); /*{% endif %}*/ } diff --git a/redhawk-codegen/redhawk/codegen/jinja/java/component/pull/templates/resource_base.java b/redhawk-codegen/redhawk/codegen/jinja/java/component/pull/templates/resource_base.java index be372c806..2613ef028 100644 --- a/redhawk-codegen/redhawk/codegen/jinja/java/component/pull/templates/resource_base.java +++ b/redhawk-codegen/redhawk/codegen/jinja/java/component/pull/templates/resource_base.java @@ -150,7 +150,11 @@ public abstract class ${classname} extends ${superClass} { */ public ${classname}() { +/*{% if 'FrontendTuner' in component.implements %}*/ + super(frontend_tuner_status_struct_struct.class); +/*{% else %}*/ super(); +/*{% endif %}*/ setLogger( logger, ${classname}.class.getName() ); diff --git a/redhawk-codegen/redhawk/codegen/jinja/python/component/pull/templates/resource.py b/redhawk-codegen/redhawk/codegen/jinja/python/component/pull/templates/resource.py index b76c2c37b..9e6c4ac8b 100644 --- a/redhawk-codegen/redhawk/codegen/jinja/python/component/pull/templates/resource.py +++ b/redhawk-codegen/redhawk/codegen/jinja/python/component/pull/templates/resource.py @@ -58,9 +58,11 @@ def constructor(self): The options for devices are: TX, RX, RX_DIGITIZER, CHANNELIZER, DDC, RC_DIGITIZER_CHANNELIZER For example, if this device has 5 physical - tuners, each an RX_DIGITIZER, then the code in the construct function should look like this: + tuners, 3 RX_DIGITIZER and 2 CHANNELIZER, then the code in the construct function + should look like this: - self.setNumChannels(5, "RX_DIGITIZER"); + self.addChannels(3, "RX_DIGITIZER"); + self.addChannels(2, "CHANNELIZER"); The incoming request for tuning contains a string describing the requested tuner type. The string for the request must match the string in the tuner status. @@ -68,7 +70,7 @@ def constructor(self): """ # TODO add customization here. #{% if 'FrontendTuner' in component.implements %} - self.setNumChannels(1, "RX_DIGITIZER"); + self.addChannels(1, "RX_DIGITIZER"); #{% endif %} #{% block updateUsageState %} From 10233030a76e5a35d699b0f388289c5b22ad8eb5 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Fri, 21 Apr 2017 15:39:09 -0400 Subject: [PATCH 0776/1644] Refs CF-1697. Removed the assumption that the service name is the same as the service instance id in the DCD --- .../control/sdr/devmgr/DeviceManager_impl.cpp | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/redhawk/src/control/sdr/devmgr/DeviceManager_impl.cpp b/redhawk/src/control/sdr/devmgr/DeviceManager_impl.cpp index 1a517153e..25ec838c2 100644 --- a/redhawk/src/control/sdr/devmgr/DeviceManager_impl.cpp +++ b/redhawk/src/control/sdr/devmgr/DeviceManager_impl.cpp @@ -3312,16 +3312,17 @@ ossie::SpdSupport::ResourceInfo DeviceManager_impl::buildServiceSpd( const std:: CF::Properties componentProperties; std::ostringstream eout; std::string cname; + std::string cid; std::string spdFile; // get service's spd from DeviceManager's DCD file const std::vector& components = DCDParser.getComponentPlacements(); LOG_TRACE(DeviceManager_impl, "Getting ComponentPlacements, size is " << components.size()); for ( std::vector< ossie::DevicePlacement >::const_iterator comp = components.begin(); comp != components.end(); comp++) { - for (unsigned int i = 0; i < comp->instantiations.size(); i++) { - cname = comp->instantiations[i].getID(); - if ( cname == svc_name ) { + cid = comp->instantiations[i].getID(); + cname = comp->instantiations[i].getUsageName(); + if (( cname == svc_name ) or (cid == svc_name)) { LOG_TRACE(DeviceManager_impl, "Getting file name for refid " << comp->getFileRefId()); const char* svc_spdFile = DCDParser.getFileNameFromRefId(comp->getFileRefId().c_str()); if (svc_spdFile == 0) { @@ -3330,11 +3331,14 @@ ossie::SpdSupport::ResourceInfo DeviceManager_impl::buildServiceSpd( const std:: throw(CF::InvalidObjectReference(eout.str().c_str())); } spdFile=svc_spdFile; + break; } } + if (not spdFile.empty()) + break; } - ossie::SpdSupport::ResourceInfo spdinfo(spdFile); + ossie::SpdSupport::ResourceInfo spdinfo(spdFile); try { spdinfo.load(_fileSys); } @@ -3349,22 +3353,18 @@ ossie::SpdSupport::ResourceInfo DeviceManager_impl::buildServiceSpd( const std:: LOG_INFO(DeviceManager_impl, "Service: " << svc_name << " SPD loaded: " << spd_name << "' - '" << spd_id ); try { - const ComponentInstantiation& instantiation = DCDParser.getComponentInstantiationById(svc_name); - if (!instantiation.getUsageName().empty()) - std::string tmp_name = instantiation.getUsageName(); // this is here to get rid of a warning + const ComponentInstantiation& instantiation = DCDParser.getComponentInstantiationById(cid); + const ossie::ComponentPropertyList& overrideProps = instantiation.getProperties(); + // Check for any overrides from DCD componentproperites + for (unsigned int j = 0; j < overrideProps.size (); j++) { + LOG_DEBUG(DeviceManager_impl, "Service:" << svc_name << " Override Properties - ID: " << overrideProps[j].getID()); + spdinfo.overrideProperty( overrideProps[j] ); + } } catch (...) { - eout << "ComponentInstantiation is invalid for Service:" << svc_name; + eout << "ComponentInstantiation is invalid for Service:" << svc_name << " with id " << cid; LOG_WARN(DeviceManager_impl, eout.str()); throw(CF::InvalidObjectReference(eout.str().c_str())); } - // override device properties in DCD file - const ComponentInstantiation& instantiation = DCDParser.getComponentInstantiationById(svc_name); - const ossie::ComponentPropertyList& overrideProps = instantiation.getProperties(); - // Check for any overrides from DCD componentproperites - for (unsigned int j = 0; j < overrideProps.size (); j++) { - LOG_DEBUG(DeviceManager_impl, "Service:" << svc_name << " Override Properties - ID: " << overrideProps[j].getID()); - spdinfo.overrideProperty( overrideProps[j] ); - } return spdinfo; } From c42ae2bf93db471510b0cd0bfcb3041222129dc1 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Fri, 21 Apr 2017 16:05:04 -0400 Subject: [PATCH 0777/1644] Refs CF-1703. cacheDirectory and workingDirectory display the current cache and working directories, even if not set in the DCD --- GPP/cpp/GPP.cpp | 19 +++++++++++++++++++ GPP/cpp/GPP.h | 1 + GPP/tests/test_GPP.py | 11 +++++++++++ 3 files changed, 31 insertions(+) diff --git a/GPP/cpp/GPP.cpp b/GPP/cpp/GPP.cpp index 59d2c1c0b..08ba361d4 100644 --- a/GPP/cpp/GPP.cpp +++ b/GPP/cpp/GPP.cpp @@ -501,6 +501,25 @@ void GPP_i::_init() { } +void GPP_i::constructor() +{ + if (this->workingDirectory.empty() or this->cacheDirectory.empty()) { + char* tmp; + std::string path; + tmp = getcwd(NULL, 200); + if (tmp != NULL) { + path = std::string(tmp); + free(tmp); + } + if (this->workingDirectory.empty()) { + this->workingDirectory = path; + } + if (this->cacheDirectory.empty()) { + this->cacheDirectory = path; + } + } +} + void GPP_i::postConstruction (std::string &profile, std::string ®istrar_ior, diff --git a/GPP/cpp/GPP.h b/GPP/cpp/GPP.h index 1f11efb9b..34991cfb3 100644 --- a/GPP/cpp/GPP.h +++ b/GPP/cpp/GPP.h @@ -174,6 +174,7 @@ class GPP_i : public GPP_base int64_t get_process_time(); }; + void constructor(); protected: diff --git a/GPP/tests/test_GPP.py b/GPP/tests/test_GPP.py index 07be50ab8..fb509488c 100755 --- a/GPP/tests/test_GPP.py +++ b/GPP/tests/test_GPP.py @@ -610,6 +610,17 @@ def for_suppliers(self): self.assert_(81 == any.from_any(event.properties[0].value)) + def test_workingCacheDirView(self): + # set mcast exec param values for the test + eparms = { "DCE:4e416acc-3144-47eb-9e38-97f1d24f7700": 'eth0', + 'DCE:5a41c2d3-5b68-4530-b0c4-ae98c26c77ec': 100, + 'DCE:442d5014-2284-4f46-86ae-ce17e0749da0': 100 } + self.runGPP(eparms) + cwd = os.getcwd() + self.assertEquals(cwd,self.comp.cacheDirectory) + self.assertEquals(cwd,self.comp.workingDirectory) + + def test_mcastNicThreshold(self): # set mcast exec param values for the test From befb96f8fac5666ef473f284ac368534882fe760 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Wed, 26 Apr 2017 11:12:51 -0400 Subject: [PATCH 0778/1644] Refs CF-1740. Number properties that are initialized incorrectly throw an error in both the Application Factory and the Device Manager --- redhawk/src/base/framework/prop_helpers.cpp | 51 ++++- redhawk/src/base/include/ossie/prop_helpers.h | 16 ++ .../dev_props_bad_numbers.prf.xml | 24 +++ .../dev_props_bad_numbers.scd.xml | 49 +++++ .../dev_props_bad_numbers.spd.xml | 25 +++ .../python/dev_props_bad_numbers.py | 183 ++++++++++++++++++ .../python/dev_props_bad_numbers_base.py | 95 +++++++++ .../DeviceManager.dcd.xml | 26 +++ .../props_bad_numbers.prf.xml | 14 ++ .../props_bad_numbers.scd.xml | 45 +++++ .../props_bad_numbers.spd.xml | 25 +++ .../python/props_bad_numbers.py | 156 +++++++++++++++ .../python/props_bad_numbers_base.py | 78 ++++++++ .../props_bad_numbers_w.sad.xml | 26 +++ .../testing/tests/test_01_DeviceManager.py | 5 + .../tests/test_04_ApplicationFactory.py | 14 ++ 16 files changed, 823 insertions(+), 9 deletions(-) create mode 100644 redhawk/src/testing/sdr/dev/devices/dev_props_bad_numbers/dev_props_bad_numbers.prf.xml create mode 100644 redhawk/src/testing/sdr/dev/devices/dev_props_bad_numbers/dev_props_bad_numbers.scd.xml create mode 100644 redhawk/src/testing/sdr/dev/devices/dev_props_bad_numbers/dev_props_bad_numbers.spd.xml create mode 100755 redhawk/src/testing/sdr/dev/devices/dev_props_bad_numbers/python/dev_props_bad_numbers.py create mode 100644 redhawk/src/testing/sdr/dev/devices/dev_props_bad_numbers/python/dev_props_bad_numbers_base.py create mode 100644 redhawk/src/testing/sdr/dev/nodes/dev_props_bad_numbers_node/DeviceManager.dcd.xml create mode 100644 redhawk/src/testing/sdr/dom/components/props_bad_numbers/props_bad_numbers.prf.xml create mode 100644 redhawk/src/testing/sdr/dom/components/props_bad_numbers/props_bad_numbers.scd.xml create mode 100644 redhawk/src/testing/sdr/dom/components/props_bad_numbers/props_bad_numbers.spd.xml create mode 100755 redhawk/src/testing/sdr/dom/components/props_bad_numbers/python/props_bad_numbers.py create mode 100644 redhawk/src/testing/sdr/dom/components/props_bad_numbers/python/props_bad_numbers_base.py create mode 100644 redhawk/src/testing/sdr/dom/waveforms/props_bad_numbers_w/props_bad_numbers_w.sad.xml diff --git a/redhawk/src/base/framework/prop_helpers.cpp b/redhawk/src/base/framework/prop_helpers.cpp index 465c7efe6..e8416a0ba 100644 --- a/redhawk/src/base/framework/prop_helpers.cpp +++ b/redhawk/src/base/framework/prop_helpers.cpp @@ -482,38 +482,71 @@ namespace redhawk { */ CORBA::Any ossie::stringToSimpleAny(std::string value, CORBA::TCKind kind) { CORBA::Any result; + char *endptr = NULL; + std::string _type; + bool fixed_point = false; if (kind == CORBA::tk_boolean){ + _type = "boolean"; if ((value == "true") || (value == "True") || (value == "TRUE") || (value == "1")) { result <<= CORBA::Any::from_boolean(CORBA::Boolean(true)); } else { result <<= CORBA::Any::from_boolean(CORBA::Boolean(false)); } } else if (kind == CORBA::tk_char){ + _type = "char"; result <<= CORBA::Any::from_char(CORBA::Char(value[0])); } else if (kind == CORBA::tk_double){ - result <<= CORBA::Double(strtod(value.c_str(), NULL)); + _type = "double"; + result <<= CORBA::Double(strtod(value.c_str(), &endptr)); } else if (kind == CORBA::tk_octet){ - result <<= CORBA::Any::from_octet(CORBA::Octet(strtol(value.c_str(), NULL, 0))); + fixed_point = true; + _type = "octet"; + result <<= CORBA::Any::from_octet(CORBA::Octet(strtol(value.c_str(), &endptr, 0))); } else if (kind == CORBA::tk_ushort){ - result <<= CORBA::UShort(strtol(value.c_str(), NULL, 0)); + fixed_point = true; + _type = "ushort"; + result <<= CORBA::UShort(strtol(value.c_str(), &endptr, 0)); } else if (kind == CORBA::tk_short){ - result <<= CORBA::Short(strtol(value.c_str(), NULL, 0)); + fixed_point = true; + _type = "short"; + result <<= CORBA::Short(strtol(value.c_str(), &endptr, 0)); } else if (kind == CORBA::tk_float){ - result <<= CORBA::Float(strtof(value.c_str(), NULL)); + _type = "float"; + result <<= CORBA::Float(strtof(value.c_str(), &endptr)); } else if (kind == CORBA::tk_ulong){ - result <<= CORBA::ULong(strtol(value.c_str(), NULL, 0)); + fixed_point = true; + _type = "ulong"; + result <<= CORBA::ULong(strtol(value.c_str(), &endptr, 0)); } else if (kind == CORBA::tk_long){ - result <<= CORBA::Long(strtol(value.c_str(), NULL, 0)); + fixed_point = true; + _type = "long"; + result <<= CORBA::Long(strtol(value.c_str(), &endptr, 0)); } else if (kind == CORBA::tk_longlong){ - result <<= CORBA::LongLong(strtoll(value.c_str(), NULL, 0)); + fixed_point = true; + _type = "longlong"; + result <<= CORBA::LongLong(strtoll(value.c_str(), &endptr, 0)); } else if (kind == CORBA::tk_ulonglong){ - result <<= CORBA::ULongLong(strtoll(value.c_str(), NULL, 0)); + fixed_point = true; + _type = "ulonglong"; + result <<= CORBA::ULongLong(strtoll(value.c_str(), &endptr, 0)); } else if (kind == CORBA::tk_string){ + _type = "string"; result <<= value.c_str(); } else { + _type = "any"; result = CORBA::Any(); } // end of outer switch statement + if (endptr != NULL) { + if ((value != "(null)") and ((endptr == value.c_str()) or (*endptr != '\0'))) { + if (fixed_point) { + strtod(value.c_str(), &endptr); + if (*endptr == '\0') + return result; + } + throw ossie::badConversion(value, _type); + } + } return result; } diff --git a/redhawk/src/base/include/ossie/prop_helpers.h b/redhawk/src/base/include/ossie/prop_helpers.h index b39538553..acc228d17 100644 --- a/redhawk/src/base/include/ossie/prop_helpers.h +++ b/redhawk/src/base/include/ossie/prop_helpers.h @@ -30,6 +30,8 @@ #endif #include "CF/cf.h" +#include +#include namespace redhawk { namespace time { @@ -80,6 +82,20 @@ namespace ossie } } + class badConversion : public std::runtime_error { + public: + badConversion(std::string value, std::string type) : std::runtime_error("Unable to perform conversion"), _value(value), _type(type) {}; + ~badConversion() throw() {}; + virtual const char* what() const throw() + { + std::ostringstream _msg; + _msg << std::runtime_error::what() << ": '"<<_value<<"' to type '"<<_type << "'"; + return _msg.str().c_str(); + }; + private: + std::string _value, _type; + }; + template double perform_math(double operand, T propval, std::string& math) { diff --git a/redhawk/src/testing/sdr/dev/devices/dev_props_bad_numbers/dev_props_bad_numbers.prf.xml b/redhawk/src/testing/sdr/dev/devices/dev_props_bad_numbers/dev_props_bad_numbers.prf.xml new file mode 100644 index 000000000..34aea44cc --- /dev/null +++ b/redhawk/src/testing/sdr/dev/devices/dev_props_bad_numbers/dev_props_bad_numbers.prf.xml @@ -0,0 +1,24 @@ + + + + + This specifies the device kind + + + + + This specifies the specific device + + + + + 5 + + + + + 4 + + + + diff --git a/redhawk/src/testing/sdr/dev/devices/dev_props_bad_numbers/dev_props_bad_numbers.scd.xml b/redhawk/src/testing/sdr/dev/devices/dev_props_bad_numbers/dev_props_bad_numbers.scd.xml new file mode 100644 index 000000000..125128ef1 --- /dev/null +++ b/redhawk/src/testing/sdr/dev/devices/dev_props_bad_numbers/dev_props_bad_numbers.scd.xml @@ -0,0 +1,49 @@ + + + + 2.2 + + device + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/redhawk/src/testing/sdr/dev/devices/dev_props_bad_numbers/dev_props_bad_numbers.spd.xml b/redhawk/src/testing/sdr/dev/devices/dev_props_bad_numbers/dev_props_bad_numbers.spd.xml new file mode 100644 index 000000000..0477452d2 --- /dev/null +++ b/redhawk/src/testing/sdr/dev/devices/dev_props_bad_numbers/dev_props_bad_numbers.spd.xml @@ -0,0 +1,25 @@ + + + + + + null + + + + + + + + + The implementation contains descriptive information about the template for a software resource. + + + python/dev_props_bad_numbers.py + + + + + + + diff --git a/redhawk/src/testing/sdr/dev/devices/dev_props_bad_numbers/python/dev_props_bad_numbers.py b/redhawk/src/testing/sdr/dev/devices/dev_props_bad_numbers/python/dev_props_bad_numbers.py new file mode 100755 index 000000000..601197198 --- /dev/null +++ b/redhawk/src/testing/sdr/dev/devices/dev_props_bad_numbers/python/dev_props_bad_numbers.py @@ -0,0 +1,183 @@ +#!/usr/bin/env python +# +# +# AUTO-GENERATED +# +# Source: dev_props_bad_numbers.spd.xml +from ossie.device import start_device +import logging + +from dev_props_bad_numbers_base import * + +class dev_props_bad_numbers_i(dev_props_bad_numbers_base): + """""" + def constructor(self): + """ + This is called by the framework immediately after your device registers with the system. + + In general, you should add customization here and not in the __init__ constructor. If you have + a custom port implementation you can override the specific implementation here with a statement + similar to the following: + self.some_port = MyPortImplementation() + + """ + # TODO add customization here. + + def updateUsageState(self): + """ + This is called automatically after allocateCapacity or deallocateCapacity are called. + Your implementation should determine the current state of the device: + self._usageState = CF.Device.IDLE # not in use + self._usageState = CF.Device.ACTIVE # in use, with capacity remaining for allocation + self._usageState = CF.Device.BUSY # in use, with no capacity remaining for allocation + """ + return NOOP + + def process(self): + """ + Basic functionality: + + The process method should process a single "chunk" of data and then return. This method + will be called from the processing thread again, and again, and again until it returns + FINISH or stop() is called on the device. If no work is performed, then return NOOP. + + StreamSRI: + To create a StreamSRI object, use the following code (this generates a normalized SRI that does not flush the queue when full): + sri = bulkio.sri.create("my_stream_id") + + PrecisionUTCTime: + To create a PrecisionUTCTime object, use the following code: + tstamp = bulkio.timestamp.now() + + Ports: + + Each port instance is accessed through members of the following form: self.port_ + + Data is obtained in the process function through the getPacket call (BULKIO only) on a + provides port member instance. The optional argument is a timeout value, in seconds. + A zero value is non-blocking, while a negative value is blocking. Constants have been + defined for these values, bulkio.const.BLOCKING and bulkio.const.NON_BLOCKING. If no + timeout is given, it defaults to non-blocking. + + The return value is a named tuple with the following fields: + - dataBuffer + - T + - EOS + - streamID + - SRI + - sriChanged + - inputQueueFlushed + If no data is available due to a timeout, all fields are None. + + To send data, call the appropriate function in the port directly. In the case of BULKIO, + convenience functions have been added in the port classes that aid in output. + + Interactions with non-BULKIO ports are left up to the device developer's discretion. + + Messages: + + To receive a message, you need (1) an input port of type MessageEvent, (2) a message prototype described + as a structure property of kind message, (3) a callback to service the message, and (4) to register the callback + with the input port. + + Assuming a property of type message is declared called "my_msg", an input port called "msg_input" is declared of + type MessageEvent, create the following code: + + def msg_callback(self, msg_id, msg_value): + print msg_id, msg_value + + Register the message callback onto the input port with the following form: + self.port_input.registerMessage("my_msg", dev_props_bad_numbers_i.MyMsg, self.msg_callback) + + To send a message, you need to (1) create a message structure, and (2) send the message over the port. + + Assuming a property of type message is declared called "my_msg", an output port called "msg_output" is declared of + type MessageEvent, create the following code: + + msg_out = dev_props_bad_numbers_i.MyMsg() + this.port_msg_output.sendMessage(msg_out) + + Accessing the Application and Domain Manager: + + Both the Application hosting this Component and the Domain Manager hosting + the Application are available to the Component. + + To access the Domain Manager: + dommgr = self.getDomainManager().getRef(); + To access the Application: + app = self.getApplication().getRef(); + Properties: + + Properties are accessed directly as member variables. If the property name is baudRate, + then accessing it (for reading or writing) is achieved in the following way: self.baudRate. + + To implement a change callback notification for a property, create a callback function with the following form: + + def mycallback(self, id, old_value, new_value): + pass + + where id is the property id, old_value is the previous value, and new_value is the updated value. + + The callback is then registered on the component as: + self.addPropertyChangeListener('baudRate', self.mycallback) + + Allocation: + + Allocation callbacks are available to customize a Device's response to an allocation request. + Callback allocation/deallocation functions are registered using the setAllocationImpl function, + usually in the initialize() function + For example, allocation property "my_alloc" can be registered with allocation function + my_alloc_fn and deallocation function my_dealloc_fn as follows: + + self.setAllocationImpl("my_alloc", self.my_alloc_fn, self.my_dealloc_fn) + + def my_alloc_fn(self, value): + # perform logic + return True # successful allocation + + def my_dealloc_fn(self, value): + # perform logic + pass + + Example: + + # This example assumes that the device has two ports: + # - A provides (input) port of type bulkio.InShortPort called dataShort_in + # - A uses (output) port of type bulkio.OutFloatPort called dataFloat_out + # The mapping between the port and the class if found in the device + # base class. + # This example also makes use of the following Properties: + # - A float value called amplitude + # - A boolean called increaseAmplitude + + packet = self.port_dataShort_in.getPacket() + + if packet.dataBuffer is None: + return NOOP + + outData = range(len(packet.dataBuffer)) + for i in range(len(packet.dataBuffer)): + if self.increaseAmplitude: + outData[i] = float(packet.dataBuffer[i]) * self.amplitude + else: + outData[i] = float(packet.dataBuffer[i]) + + # NOTE: You must make at least one valid pushSRI call + if packet.sriChanged: + self.port_dataFloat_out.pushSRI(packet.SRI); + + self.port_dataFloat_out.pushPacket(outData, packet.T, packet.EOS, packet.streamID) + return NORMAL + + """ + + # TODO fill in your code here + self._log.debug("process() example log message") + return NOOP + + +if __name__ == '__main__': + logging.getLogger().setLevel(logging.INFO) + logging.debug("Starting Device") + start_device(dev_props_bad_numbers_i) + diff --git a/redhawk/src/testing/sdr/dev/devices/dev_props_bad_numbers/python/dev_props_bad_numbers_base.py b/redhawk/src/testing/sdr/dev/devices/dev_props_bad_numbers/python/dev_props_bad_numbers_base.py new file mode 100644 index 000000000..79c7b5018 --- /dev/null +++ b/redhawk/src/testing/sdr/dev/devices/dev_props_bad_numbers/python/dev_props_bad_numbers_base.py @@ -0,0 +1,95 @@ +#!/usr/bin/env python +# +# AUTO-GENERATED CODE. DO NOT MODIFY! +# +# Source: dev_props_bad_numbers.spd.xml +from ossie.cf import CF +from ossie.cf import CF__POA +from ossie.utils import uuid + +from ossie.device import Device +from ossie.threadedcomponent import * +from ossie.properties import simple_property + +import Queue, copy, time, threading + +class dev_props_bad_numbers_base(CF__POA.Device, Device, ThreadedComponent): + # These values can be altered in the __init__ of your derived class + + PAUSE = 0.0125 # The amount of time to sleep if process return NOOP + TIMEOUT = 5.0 # The amount of time to wait for the process thread to die when stop() is called + DEFAULT_QUEUE_SIZE = 100 # The number of BulkIO packets that can be in the queue before pushPacket will block + + def __init__(self, devmgr, uuid, label, softwareProfile, compositeDevice, execparams): + Device.__init__(self, devmgr, uuid, label, softwareProfile, compositeDevice, execparams) + ThreadedComponent.__init__(self) + + # self.auto_start is deprecated and is only kept for API compatibility + # with 1.7.X and 1.8.0 devices. This variable may be removed + # in future releases + self.auto_start = False + # Instantiate the default implementations for all ports on this device + + def start(self): + Device.start(self) + ThreadedComponent.startThread(self, pause=self.PAUSE) + + def stop(self): + Device.stop(self) + if not ThreadedComponent.stopThread(self, self.TIMEOUT): + raise CF.Resource.StopError(CF.CF_NOTSET, "Processing thread did not die") + + def releaseObject(self): + try: + self.stop() + except Exception: + self._log.exception("Error stopping") + Device.releaseObject(self) + + ###################################################################### + # PORTS + # + # DO NOT ADD NEW PORTS HERE. You can add ports in your derived class, in the SCD xml file, + # or via the IDE. + + ###################################################################### + # PROPERTIES + # + # DO NOT ADD NEW PROPERTIES HERE. You can add properties in your derived class, in the PRF xml file + # or by using the IDE. + device_kind = simple_property(id_="DCE:cdc5ee18-7ceb-4ae6-bf4c-31f983179b4d", + name="device_kind", + type_="string", + mode="readonly", + action="eq", + kinds=("allocation",), + description="""This specifies the device kind""") + + + device_model = simple_property(id_="DCE:0f99b2e4-9903-4631-9846-ff349d18ecfb", + name="device_model", + type_="string", + mode="readonly", + action="eq", + kinds=("allocation",), + description=""" This specifies the specific device""") + + + some_float = simple_property(id_="some_float", + type_="float", + defvalue=5.0, + mode="readwrite", + action="external", + kinds=("property",)) + + + some_short = simple_property(id_="some_short", + type_="short", + defvalue=4, + mode="readwrite", + action="external", + kinds=("property",)) + + + + diff --git a/redhawk/src/testing/sdr/dev/nodes/dev_props_bad_numbers_node/DeviceManager.dcd.xml b/redhawk/src/testing/sdr/dev/nodes/dev_props_bad_numbers_node/DeviceManager.dcd.xml new file mode 100644 index 000000000..3caf4e5b6 --- /dev/null +++ b/redhawk/src/testing/sdr/dev/nodes/dev_props_bad_numbers_node/DeviceManager.dcd.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + dev_props_bad_numbers_1 + + + + + + + + + + diff --git a/redhawk/src/testing/sdr/dom/components/props_bad_numbers/props_bad_numbers.prf.xml b/redhawk/src/testing/sdr/dom/components/props_bad_numbers/props_bad_numbers.prf.xml new file mode 100644 index 000000000..a3e29d771 --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/props_bad_numbers/props_bad_numbers.prf.xml @@ -0,0 +1,14 @@ + + + + + 3 + + + + + 5 + + + + diff --git a/redhawk/src/testing/sdr/dom/components/props_bad_numbers/props_bad_numbers.scd.xml b/redhawk/src/testing/sdr/dom/components/props_bad_numbers/props_bad_numbers.scd.xml new file mode 100644 index 000000000..df94ceaf5 --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/props_bad_numbers/props_bad_numbers.scd.xml @@ -0,0 +1,45 @@ + + + + 2.2 + + resource + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/redhawk/src/testing/sdr/dom/components/props_bad_numbers/props_bad_numbers.spd.xml b/redhawk/src/testing/sdr/dom/components/props_bad_numbers/props_bad_numbers.spd.xml new file mode 100644 index 000000000..42ef6d6ab --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/props_bad_numbers/props_bad_numbers.spd.xml @@ -0,0 +1,25 @@ + + + + + + null + + + + + + + + + The implementation contains descriptive information about the template for a software resource. + + + python/props_bad_numbers.py + + + + + + + diff --git a/redhawk/src/testing/sdr/dom/components/props_bad_numbers/python/props_bad_numbers.py b/redhawk/src/testing/sdr/dom/components/props_bad_numbers/python/props_bad_numbers.py new file mode 100755 index 000000000..55cf1a895 --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/props_bad_numbers/python/props_bad_numbers.py @@ -0,0 +1,156 @@ +#!/usr/bin/env python +# +# +# AUTO-GENERATED +# +# Source: props_bad_numbers.spd.xml +from ossie.resource import start_component +import logging + +from props_bad_numbers_base import * + +class props_bad_numbers_i(props_bad_numbers_base): + """""" + def constructor(self): + """ + This is called by the framework immediately after your component registers with the system. + + In general, you should add customization here and not in the __init__ constructor. If you have + a custom port implementation you can override the specific implementation here with a statement + similar to the following: + self.some_port = MyPortImplementation() + + """ + # TODO add customization here. + + def process(self): + """ + Basic functionality: + + The process method should process a single "chunk" of data and then return. This method + will be called from the processing thread again, and again, and again until it returns + FINISH or stop() is called on the component. If no work is performed, then return NOOP. + + StreamSRI: + To create a StreamSRI object, use the following code (this generates a normalized SRI that does not flush the queue when full): + sri = bulkio.sri.create("my_stream_id") + + PrecisionUTCTime: + To create a PrecisionUTCTime object, use the following code: + tstamp = bulkio.timestamp.now() + + Ports: + + Each port instance is accessed through members of the following form: self.port_ + + Data is obtained in the process function through the getPacket call (BULKIO only) on a + provides port member instance. The optional argument is a timeout value, in seconds. + A zero value is non-blocking, while a negative value is blocking. Constants have been + defined for these values, bulkio.const.BLOCKING and bulkio.const.NON_BLOCKING. If no + timeout is given, it defaults to non-blocking. + + The return value is a named tuple with the following fields: + - dataBuffer + - T + - EOS + - streamID + - SRI + - sriChanged + - inputQueueFlushed + If no data is available due to a timeout, all fields are None. + + To send data, call the appropriate function in the port directly. In the case of BULKIO, + convenience functions have been added in the port classes that aid in output. + + Interactions with non-BULKIO ports are left up to the component developer's discretion. + + Messages: + + To receive a message, you need (1) an input port of type MessageEvent, (2) a message prototype described + as a structure property of kind message, (3) a callback to service the message, and (4) to register the callback + with the input port. + + Assuming a property of type message is declared called "my_msg", an input port called "msg_input" is declared of + type MessageEvent, create the following code: + + def msg_callback(self, msg_id, msg_value): + print msg_id, msg_value + + Register the message callback onto the input port with the following form: + self.port_input.registerMessage("my_msg", props_bad_numbers_i.MyMsg, self.msg_callback) + + To send a message, you need to (1) create a message structure, and (2) send the message over the port. + + Assuming a property of type message is declared called "my_msg", an output port called "msg_output" is declared of + type MessageEvent, create the following code: + + msg_out = props_bad_numbers_i.MyMsg() + this.port_msg_output.sendMessage(msg_out) + + Accessing the Device Manager and Domain Manager: + + Both the Device Manager hosting this Device and the Domain Manager hosting + the Device Manager are available to the Device. + + To access the Domain Manager: + dommgr = self.getDomainManager().getRef(); + To access the Device Manager: + devmgr = self.getDeviceManager().getRef(); + Properties: + + Properties are accessed directly as member variables. If the property name is baudRate, + then accessing it (for reading or writing) is achieved in the following way: self.baudRate. + + To implement a change callback notification for a property, create a callback function with the following form: + + def mycallback(self, id, old_value, new_value): + pass + + where id is the property id, old_value is the previous value, and new_value is the updated value. + + The callback is then registered on the component as: + self.addPropertyChangeListener('baudRate', self.mycallback) + + + Example: + + # This example assumes that the component has two ports: + # - A provides (input) port of type bulkio.InShortPort called dataShort_in + # - A uses (output) port of type bulkio.OutFloatPort called dataFloat_out + # The mapping between the port and the class if found in the component + # base class. + # This example also makes use of the following Properties: + # - A float value called amplitude + # - A boolean called increaseAmplitude + + packet = self.port_dataShort_in.getPacket() + + if packet.dataBuffer is None: + return NOOP + + outData = range(len(packet.dataBuffer)) + for i in range(len(packet.dataBuffer)): + if self.increaseAmplitude: + outData[i] = float(packet.dataBuffer[i]) * self.amplitude + else: + outData[i] = float(packet.dataBuffer[i]) + + # NOTE: You must make at least one valid pushSRI call + if packet.sriChanged: + self.port_dataFloat_out.pushSRI(packet.SRI); + + self.port_dataFloat_out.pushPacket(outData, packet.T, packet.EOS, packet.streamID) + return NORMAL + + """ + + # TODO fill in your code here + self._log.debug("process() example log message") + return NOOP + + +if __name__ == '__main__': + logging.getLogger().setLevel(logging.INFO) + logging.debug("Starting Component") + start_component(props_bad_numbers_i) + diff --git a/redhawk/src/testing/sdr/dom/components/props_bad_numbers/python/props_bad_numbers_base.py b/redhawk/src/testing/sdr/dom/components/props_bad_numbers/python/props_bad_numbers_base.py new file mode 100644 index 000000000..0b8293050 --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/props_bad_numbers/python/props_bad_numbers_base.py @@ -0,0 +1,78 @@ +#!/usr/bin/env python +# +# AUTO-GENERATED CODE. DO NOT MODIFY! +# +# Source: props_bad_numbers.spd.xml +from ossie.cf import CF +from ossie.cf import CF__POA +from ossie.utils import uuid + +from ossie.component import Component +from ossie.threadedcomponent import * +from ossie.properties import simple_property + +import Queue, copy, time, threading + +class props_bad_numbers_base(CF__POA.Resource, Component, ThreadedComponent): + # These values can be altered in the __init__ of your derived class + + PAUSE = 0.0125 # The amount of time to sleep if process return NOOP + TIMEOUT = 5.0 # The amount of time to wait for the process thread to die when stop() is called + DEFAULT_QUEUE_SIZE = 100 # The number of BulkIO packets that can be in the queue before pushPacket will block + + def __init__(self, identifier, execparams): + loggerName = (execparams['NAME_BINDING'].replace('/', '.')).rsplit("_", 1)[0] + Component.__init__(self, identifier, execparams, loggerName=loggerName) + ThreadedComponent.__init__(self) + + # self.auto_start is deprecated and is only kept for API compatibility + # with 1.7.X and 1.8.0 components. This variable may be removed + # in future releases + self.auto_start = False + # Instantiate the default implementations for all ports on this component + + def start(self): + Component.start(self) + ThreadedComponent.startThread(self, pause=self.PAUSE) + + def stop(self): + Component.stop(self) + if not ThreadedComponent.stopThread(self, self.TIMEOUT): + raise CF.Resource.StopError(CF.CF_NOTSET, "Processing thread did not die") + + def releaseObject(self): + try: + self.stop() + except Exception: + self._log.exception("Error stopping") + Component.releaseObject(self) + + ###################################################################### + # PORTS + # + # DO NOT ADD NEW PORTS HERE. You can add ports in your derived class, in the SCD xml file, + # or via the IDE. + + ###################################################################### + # PROPERTIES + # + # DO NOT ADD NEW PROPERTIES HERE. You can add properties in your derived class, in the PRF xml file + # or by using the IDE. + some_short = simple_property(id_="some_short", + type_="short", + defvalue=3, + mode="readwrite", + action="external", + kinds=("property",)) + + + some_float = simple_property(id_="some_float", + type_="float", + defvalue=5.0, + mode="readwrite", + action="external", + kinds=("property",)) + + + + diff --git a/redhawk/src/testing/sdr/dom/waveforms/props_bad_numbers_w/props_bad_numbers_w.sad.xml b/redhawk/src/testing/sdr/dom/waveforms/props_bad_numbers_w/props_bad_numbers_w.sad.xml new file mode 100644 index 000000000..cbe734022 --- /dev/null +++ b/redhawk/src/testing/sdr/dom/waveforms/props_bad_numbers_w/props_bad_numbers_w.sad.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + props_bad_numbers_1 + + + + + + + + + + + + + diff --git a/redhawk/src/testing/tests/test_01_DeviceManager.py b/redhawk/src/testing/tests/test_01_DeviceManager.py index 12e20a1e0..5ccc72fbb 100644 --- a/redhawk/src/testing/tests/test_01_DeviceManager.py +++ b/redhawk/src/testing/tests/test_01_DeviceManager.py @@ -236,6 +236,11 @@ def test_IgnoreDeviceDuplicate(self): self.assertEqual(len(self._domMgr._get_deviceManagers()), 1) self.assertEqual(len(devMgr._get_registeredDevices()), 1) + def test_DeviceBadOverload(self): + # This device manager fails to launch because of a bad overloaded value + devmgr_nb, devMgr = self.launchDeviceManager("/nodes/dev_props_bad_numbers_node/DeviceManager.dcd.xml") + self.assertEquals(devMgr, None) + def test_DeviceInitializeFail(self): # These two nodes use the same identifier, but have different names to distinguish them devmgr_nb, devMgr = self.launchDeviceManager("/nodes/bad_init_device_node/DeviceManager.dcd.xml") diff --git a/redhawk/src/testing/tests/test_04_ApplicationFactory.py b/redhawk/src/testing/tests/test_04_ApplicationFactory.py index 6fa6c0853..48e8e0470 100644 --- a/redhawk/src/testing/tests/test_04_ApplicationFactory.py +++ b/redhawk/src/testing/tests/test_04_ApplicationFactory.py @@ -344,6 +344,20 @@ def test_NamespacedWaveformPython(self): def test_NamespacedWaveformJava(self): self._test_NamespacedWaveform('javawave') + def test_BadOverload(self): + nodebooter, domMgr = self.launchDomainManager() + self.assertNotEqual(domMgr, None) + nodebooter, devMgr = self.launchDeviceManager("/nodes/test_GPP_node/DeviceManager.dcd.xml") + self.assertNotEqual(devMgr, None) + + self.assertRaises(CF.ApplicationFactory.CreateApplicationError, domMgr.createApplication, "/waveforms/props_bad_numbers_w/props_bad_numbers_w.sad.xml", "props_app", [], [], ) + try: + app = domMgr.createApplication("/waveforms/props_bad_numbers_w/props_bad_numbers_w.sad.xml", "props_app", [], []) + except Exception, e: + pass + self.assertNotEqual(e.msg.find('Unable to perform conversion'), -1) + self.assertEqual(len(domMgr._get_applications()), 0) + def test_PartialStructConfiguration(self): nodebooter, domMgr = self.launchDomainManager() self.assertNotEqual(domMgr, None) From 9d548509b0c85a90d2b05f759278b360ae6e0d68 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Thu, 27 Apr 2017 16:33:15 -0400 Subject: [PATCH 0779/1644] Refs CF-1699. The string 'now' is valid when initializing a utctime property --- .../src/org/ossie/redhawk/time/utils.java | 5 +- redhawk/src/base/framework/prop_helpers.cpp | 3 + .../python/ossie/utils/rhtime/helpers.py | 2 + .../python/ossie/utils/type_helpers.py | 9 +- redhawk/src/configure.ac | 2 + redhawk/src/testing/Makefile.am | 2 + .../dom/components/newtime/newtime.prf.xml | 8 + .../dom/components/newtime/newtime.scd.xml | 45 ++++ .../dom/components/newtime/newtime.spd.xml | 25 ++ .../dom/components/newtime/python/newtime.py | 156 +++++++++++ .../components/newtime/python/newtime_base.py | 69 +++++ .../components/time_cp_now/cpp/Makefile.am | 60 +++++ .../dom/components/time_cp_now/cpp/main.cpp | 11 + .../time_cp_now/cpp/time_cp_now.cpp | 248 +++++++++++++++++ .../components/time_cp_now/cpp/time_cp_now.h | 18 ++ .../time_cp_now/cpp/time_cp_now_base.cpp | 69 +++++ .../time_cp_now/cpp/time_cp_now_base.h | 30 +++ .../time_cp_now/time_cp_now.prf.xml | 9 + .../time_cp_now/time_cp_now.scd.xml | 45 ++++ .../time_cp_now/time_cp_now.spd.xml | 27 ++ .../components/time_ja_now/java/Makefile.am | 41 +++ .../src/time_ja_now/java/time_ja_now.java | 252 ++++++++++++++++++ .../time_ja_now/java/time_ja_now_base.java | 102 +++++++ .../components/time_ja_now/java/startJava.sh | 38 +++ .../time_ja_now/time_ja_now.prf.xml | 9 + .../time_ja_now/time_ja_now.scd.xml | 45 ++++ .../time_ja_now/time_ja_now.spd.xml | 26 ++ .../time_py_now/python/time_py_now.py | 156 +++++++++++ .../time_py_now/python/time_py_now_base.py | 70 +++++ .../time_py_now/time_py_now.prf.xml | 9 + .../time_py_now/time_py_now.scd.xml | 45 ++++ .../time_py_now/time_py_now.spd.xml | 25 ++ .../dom/waveforms/newtime_w/newtime_w.sad.xml | 26 ++ .../time_cp_now_w/time_cp_now_w.sad.xml | 23 ++ .../time_ja_now_w/time_ja_now_w.sad.xml | 23 ++ .../time_py_now_w/time_py_now_w.sad.xml | 23 ++ .../src/testing/tests/test_11_AllPropTypes.py | 73 ++++- 37 files changed, 1823 insertions(+), 6 deletions(-) create mode 100644 redhawk/src/testing/sdr/dom/components/newtime/newtime.prf.xml create mode 100644 redhawk/src/testing/sdr/dom/components/newtime/newtime.scd.xml create mode 100644 redhawk/src/testing/sdr/dom/components/newtime/newtime.spd.xml create mode 100755 redhawk/src/testing/sdr/dom/components/newtime/python/newtime.py create mode 100644 redhawk/src/testing/sdr/dom/components/newtime/python/newtime_base.py create mode 100644 redhawk/src/testing/sdr/dom/components/time_cp_now/cpp/Makefile.am create mode 100644 redhawk/src/testing/sdr/dom/components/time_cp_now/cpp/main.cpp create mode 100644 redhawk/src/testing/sdr/dom/components/time_cp_now/cpp/time_cp_now.cpp create mode 100644 redhawk/src/testing/sdr/dom/components/time_cp_now/cpp/time_cp_now.h create mode 100644 redhawk/src/testing/sdr/dom/components/time_cp_now/cpp/time_cp_now_base.cpp create mode 100644 redhawk/src/testing/sdr/dom/components/time_cp_now/cpp/time_cp_now_base.h create mode 100644 redhawk/src/testing/sdr/dom/components/time_cp_now/time_cp_now.prf.xml create mode 100644 redhawk/src/testing/sdr/dom/components/time_cp_now/time_cp_now.scd.xml create mode 100644 redhawk/src/testing/sdr/dom/components/time_cp_now/time_cp_now.spd.xml create mode 100644 redhawk/src/testing/sdr/dom/components/time_ja_now/java/Makefile.am create mode 100644 redhawk/src/testing/sdr/dom/components/time_ja_now/java/src/time_ja_now/java/time_ja_now.java create mode 100644 redhawk/src/testing/sdr/dom/components/time_ja_now/java/src/time_ja_now/java/time_ja_now_base.java create mode 100755 redhawk/src/testing/sdr/dom/components/time_ja_now/java/startJava.sh create mode 100644 redhawk/src/testing/sdr/dom/components/time_ja_now/time_ja_now.prf.xml create mode 100644 redhawk/src/testing/sdr/dom/components/time_ja_now/time_ja_now.scd.xml create mode 100644 redhawk/src/testing/sdr/dom/components/time_ja_now/time_ja_now.spd.xml create mode 100755 redhawk/src/testing/sdr/dom/components/time_py_now/python/time_py_now.py create mode 100644 redhawk/src/testing/sdr/dom/components/time_py_now/python/time_py_now_base.py create mode 100644 redhawk/src/testing/sdr/dom/components/time_py_now/time_py_now.prf.xml create mode 100644 redhawk/src/testing/sdr/dom/components/time_py_now/time_py_now.scd.xml create mode 100644 redhawk/src/testing/sdr/dom/components/time_py_now/time_py_now.spd.xml create mode 100644 redhawk/src/testing/sdr/dom/waveforms/newtime_w/newtime_w.sad.xml create mode 100644 redhawk/src/testing/sdr/dom/waveforms/time_cp_now_w/time_cp_now_w.sad.xml create mode 100644 redhawk/src/testing/sdr/dom/waveforms/time_ja_now_w/time_ja_now_w.sad.xml create mode 100644 redhawk/src/testing/sdr/dom/waveforms/time_py_now_w/time_py_now_w.sad.xml diff --git a/redhawk/src/base/framework/java/ossie/src/org/ossie/redhawk/time/utils.java b/redhawk/src/base/framework/java/ossie/src/org/ossie/redhawk/time/utils.java index 043bdf64a..3242befac 100644 --- a/redhawk/src/base/framework/java/ossie/src/org/ossie/redhawk/time/utils.java +++ b/redhawk/src/base/framework/java/ossie/src/org/ossie/redhawk/time/utils.java @@ -151,10 +151,13 @@ public static String toString(UTCTime time) { /** * Converts a human-readable string following of the format: - * YYYY:MM:DD::HH:MM:SS.SSSSSS + * YYYY:MM:DD::HH:MM:SS.SSSSSS or 'now' * to UTCTime */ public static UTCTime convert(String time) { + if (time.equals("now")) { + return now(); + } String[] token = time.split(":"); if (token.length != 7) return new CF.UTCTime(); diff --git a/redhawk/src/base/framework/prop_helpers.cpp b/redhawk/src/base/framework/prop_helpers.cpp index e8416a0ba..4d4fb169b 100644 --- a/redhawk/src/base/framework/prop_helpers.cpp +++ b/redhawk/src/base/framework/prop_helpers.cpp @@ -390,6 +390,9 @@ namespace redhawk { } CF::UTCTime convert( const std::string formatted ) { + if (formatted == "now") { + return now(); + } unsigned int year; unsigned int month; unsigned int day; diff --git a/redhawk/src/base/framework/python/ossie/utils/rhtime/helpers.py b/redhawk/src/base/framework/python/ossie/utils/rhtime/helpers.py index 321442ad0..0a73cf0fb 100644 --- a/redhawk/src/base/framework/python/ossie/utils/rhtime/helpers.py +++ b/redhawk/src/base/framework/python/ossie/utils/rhtime/helpers.py @@ -134,6 +134,8 @@ def toString(tstamp): gmt.tm_min, gmt.tm_sec, fractional) def convert(timeString): + if timeString == 'now': + return now() _sets = timeString.split(':') if len(_sets) != 7: return CF.UTCTime(0,0,0) diff --git a/redhawk/src/base/framework/python/ossie/utils/type_helpers.py b/redhawk/src/base/framework/python/ossie/utils/type_helpers.py index 6cc9185f0..93539ae63 100644 --- a/redhawk/src/base/framework/python/ossie/utils/type_helpers.py +++ b/redhawk/src/base/framework/python/ossie/utils/type_helpers.py @@ -17,6 +17,7 @@ # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see http://www.gnu.org/licenses/. # +from ossie.utils import rhtime class OutOfRangeException(Exception): pass @@ -100,6 +101,10 @@ def checkValidValue(value, dataType): if dataType == 'char' and len(value) != 1: raise TypeError, 'expected a character, but string of length %d found' % len(value) return value + elif dataType == 'utctime': + if type(value) == str: + return rhtime.convert(value) + return value elif isinstance(value, basestring): raise TypeError, "Cannot convert string to type '%s'" % dataType elif dataType in ('double', 'float'): @@ -112,10 +117,6 @@ def checkValidValue(value, dataType): return value elif dataType == 'boolean': return bool(value) - elif dataType == 'utctime': - if type(value) == str: - return rhtime.convert(value) - return value #this is used for structs #datatype is a list of (ID, propType) pairs, value is a dict mapping an ID to a value for validation elif isinstance(dataType, list): diff --git a/redhawk/src/configure.ac b/redhawk/src/configure.ac index deb937aab..c2a4d31d5 100644 --- a/redhawk/src/configure.ac +++ b/redhawk/src/configure.ac @@ -361,6 +361,7 @@ AC_CONFIG_FILES(Makefile \ testing/sdr/dom/components/java_comp/java/Makefile \ testing/sdr/dom/components/msg_through_java/java/Makefile \ testing/sdr/dom/components/timeprop_java/java/Makefile \ + testing/sdr/dom/components/time_ja_now/java/Makefile \ testing/sdr/dom/components/HardLimit/HardLimit_java_impl1/Makefile \ testing/sdr/dom/components/SimpleComponent/SimpleComponent_cpp_impl1/Makefile \ testing/sdr/dom/components/BasicAC/basicac_java_impl1/Makefile \ @@ -392,6 +393,7 @@ AC_CONFIG_FILES(Makefile \ testing/sdr/dom/components/msg_through_cpp/cpp/Makefile \ testing/sdr/dom/components/commandline_prop/cpp/Makefile \ testing/sdr/dom/components/timeprop_cpp/cpp/Makefile \ + testing/sdr/dom/components/time_cp_now/cpp/Makefile \ testing/sdr/dom/components/nocommandline_prop/cpp/Makefile \ testing/sdr/dom/components/Property_JAVA/java/Makefile \ testing/sdr/dom/components/foo/bar/comp/cpp/Makefile \ diff --git a/redhawk/src/testing/Makefile.am b/redhawk/src/testing/Makefile.am index 139726552..9491ef1e9 100644 --- a/redhawk/src/testing/Makefile.am +++ b/redhawk/src/testing/Makefile.am @@ -74,6 +74,7 @@ SUBDIRS = sdr/dev/devices/ExecutableDevice \ sdr/dom/components/TestCppOptionalProps/cpp \ sdr/dom/components/cpp_with_deps/cpp \ sdr/dom/components/timeprop_cpp/cpp \ + sdr/dom/components/time_cp_now/cpp \ sdr/dom/components/msg_through_cpp/cpp if HAVE_JAVASUPPORT @@ -88,6 +89,7 @@ SUBDIRS += sdr/dev/devices/BasicTestDevice_java/java \ sdr/dom/components/java_comp/java \ sdr/dom/components/msg_through_java/java \ sdr/dom/components/timeprop_java/java \ + sdr/dom/components/time_ja_now/java \ sdr/dom/components/HardLimit/HardLimit_java_impl1 \ sdr/dom/components/PropertyChangeEventsJava/PropertyChangeEventsJava_java_impl1 \ sdr/dom/components/TestJavaProps \ diff --git a/redhawk/src/testing/sdr/dom/components/newtime/newtime.prf.xml b/redhawk/src/testing/sdr/dom/components/newtime/newtime.prf.xml new file mode 100644 index 000000000..4fec9ee15 --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/newtime/newtime.prf.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/redhawk/src/testing/sdr/dom/components/newtime/newtime.scd.xml b/redhawk/src/testing/sdr/dom/components/newtime/newtime.scd.xml new file mode 100644 index 000000000..df94ceaf5 --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/newtime/newtime.scd.xml @@ -0,0 +1,45 @@ + + + + 2.2 + + resource + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/redhawk/src/testing/sdr/dom/components/newtime/newtime.spd.xml b/redhawk/src/testing/sdr/dom/components/newtime/newtime.spd.xml new file mode 100644 index 000000000..4fed1388f --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/newtime/newtime.spd.xml @@ -0,0 +1,25 @@ + + + + + + null + + + + + + + + + The implementation contains descriptive information about the template for a software resource. + + + python/newtime.py + + + + + + + diff --git a/redhawk/src/testing/sdr/dom/components/newtime/python/newtime.py b/redhawk/src/testing/sdr/dom/components/newtime/python/newtime.py new file mode 100755 index 000000000..d7f891ed8 --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/newtime/python/newtime.py @@ -0,0 +1,156 @@ +#!/usr/bin/env python +# +# +# AUTO-GENERATED +# +# Source: newtime.spd.xml +from ossie.resource import start_component +import logging + +from newtime_base import * + +class newtime_i(newtime_base): + """""" + def constructor(self): + """ + This is called by the framework immediately after your component registers with the system. + + In general, you should add customization here and not in the __init__ constructor. If you have + a custom port implementation you can override the specific implementation here with a statement + similar to the following: + self.some_port = MyPortImplementation() + + """ + # TODO add customization here. + + def process(self): + """ + Basic functionality: + + The process method should process a single "chunk" of data and then return. This method + will be called from the processing thread again, and again, and again until it returns + FINISH or stop() is called on the component. If no work is performed, then return NOOP. + + StreamSRI: + To create a StreamSRI object, use the following code (this generates a normalized SRI that does not flush the queue when full): + sri = bulkio.sri.create("my_stream_id") + + PrecisionUTCTime: + To create a PrecisionUTCTime object, use the following code: + tstamp = bulkio.timestamp.now() + + Ports: + + Each port instance is accessed through members of the following form: self.port_ + + Data is obtained in the process function through the getPacket call (BULKIO only) on a + provides port member instance. The optional argument is a timeout value, in seconds. + A zero value is non-blocking, while a negative value is blocking. Constants have been + defined for these values, bulkio.const.BLOCKING and bulkio.const.NON_BLOCKING. If no + timeout is given, it defaults to non-blocking. + + The return value is a named tuple with the following fields: + - dataBuffer + - T + - EOS + - streamID + - SRI + - sriChanged + - inputQueueFlushed + If no data is available due to a timeout, all fields are None. + + To send data, call the appropriate function in the port directly. In the case of BULKIO, + convenience functions have been added in the port classes that aid in output. + + Interactions with non-BULKIO ports are left up to the component developer's discretion. + + Messages: + + To receive a message, you need (1) an input port of type MessageEvent, (2) a message prototype described + as a structure property of kind message, (3) a callback to service the message, and (4) to register the callback + with the input port. + + Assuming a property of type message is declared called "my_msg", an input port called "msg_input" is declared of + type MessageEvent, create the following code: + + def msg_callback(self, msg_id, msg_value): + print msg_id, msg_value + + Register the message callback onto the input port with the following form: + self.port_input.registerMessage("my_msg", newtime_i.MyMsg, self.msg_callback) + + To send a message, you need to (1) create a message structure, and (2) send the message over the port. + + Assuming a property of type message is declared called "my_msg", an output port called "msg_output" is declared of + type MessageEvent, create the following code: + + msg_out = newtime_i.MyMsg() + this.port_msg_output.sendMessage(msg_out) + + Accessing the Device Manager and Domain Manager: + + Both the Device Manager hosting this Device and the Domain Manager hosting + the Device Manager are available to the Device. + + To access the Domain Manager: + dommgr = self.getDomainManager().getRef(); + To access the Device Manager: + devmgr = self.getDeviceManager().getRef(); + Properties: + + Properties are accessed directly as member variables. If the property name is baudRate, + then accessing it (for reading or writing) is achieved in the following way: self.baudRate. + + To implement a change callback notification for a property, create a callback function with the following form: + + def mycallback(self, id, old_value, new_value): + pass + + where id is the property id, old_value is the previous value, and new_value is the updated value. + + The callback is then registered on the component as: + self.addPropertyChangeListener('baudRate', self.mycallback) + + + Example: + + # This example assumes that the component has two ports: + # - A provides (input) port of type bulkio.InShortPort called dataShort_in + # - A uses (output) port of type bulkio.OutFloatPort called dataFloat_out + # The mapping between the port and the class if found in the component + # base class. + # This example also makes use of the following Properties: + # - A float value called amplitude + # - A boolean called increaseAmplitude + + packet = self.port_dataShort_in.getPacket() + + if packet.dataBuffer is None: + return NOOP + + outData = range(len(packet.dataBuffer)) + for i in range(len(packet.dataBuffer)): + if self.increaseAmplitude: + outData[i] = float(packet.dataBuffer[i]) * self.amplitude + else: + outData[i] = float(packet.dataBuffer[i]) + + # NOTE: You must make at least one valid pushSRI call + if packet.sriChanged: + self.port_dataFloat_out.pushSRI(packet.SRI); + + self.port_dataFloat_out.pushPacket(outData, packet.T, packet.EOS, packet.streamID) + return NORMAL + + """ + + # TODO fill in your code here + self._log.debug("process() example log message") + return NOOP + + +if __name__ == '__main__': + logging.getLogger().setLevel(logging.INFO) + logging.debug("Starting Component") + start_component(newtime_i) + diff --git a/redhawk/src/testing/sdr/dom/components/newtime/python/newtime_base.py b/redhawk/src/testing/sdr/dom/components/newtime/python/newtime_base.py new file mode 100644 index 000000000..e125073e9 --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/newtime/python/newtime_base.py @@ -0,0 +1,69 @@ +#!/usr/bin/env python +# +# AUTO-GENERATED CODE. DO NOT MODIFY! +# +# Source: newtime.spd.xml +from ossie.cf import CF +from ossie.cf import CF__POA +from ossie.utils import uuid + +from ossie.component import Component +from ossie.threadedcomponent import * +from ossie.properties import simple_property + +import Queue, copy, time, threading + +class newtime_base(CF__POA.Resource, Component, ThreadedComponent): + # These values can be altered in the __init__ of your derived class + + PAUSE = 0.0125 # The amount of time to sleep if process return NOOP + TIMEOUT = 5.0 # The amount of time to wait for the process thread to die when stop() is called + DEFAULT_QUEUE_SIZE = 100 # The number of BulkIO packets that can be in the queue before pushPacket will block + + def __init__(self, identifier, execparams): + loggerName = (execparams['NAME_BINDING'].replace('/', '.')).rsplit("_", 1)[0] + Component.__init__(self, identifier, execparams, loggerName=loggerName) + ThreadedComponent.__init__(self) + + # self.auto_start is deprecated and is only kept for API compatibility + # with 1.7.X and 1.8.0 components. This variable may be removed + # in future releases + self.auto_start = False + # Instantiate the default implementations for all ports on this component + + def start(self): + Component.start(self) + ThreadedComponent.startThread(self, pause=self.PAUSE) + + def stop(self): + Component.stop(self) + if not ThreadedComponent.stopThread(self, self.TIMEOUT): + raise CF.Resource.StopError(CF.CF_NOTSET, "Processing thread did not die") + + def releaseObject(self): + try: + self.stop() + except Exception: + self._log.exception("Error stopping") + Component.releaseObject(self) + + ###################################################################### + # PORTS + # + # DO NOT ADD NEW PORTS HERE. You can add ports in your derived class, in the SCD xml file, + # or via the IDE. + + ###################################################################### + # PROPERTIES + # + # DO NOT ADD NEW PROPERTIES HERE. You can add properties in your derived class, in the PRF xml file + # or by using the IDE. + rightnow = simple_property(id_="rightnow", + type_="utctime", + mode="readwrite", + action="external", + kinds=("property",)) + + + + diff --git a/redhawk/src/testing/sdr/dom/components/time_cp_now/cpp/Makefile.am b/redhawk/src/testing/sdr/dom/components/time_cp_now/cpp/Makefile.am new file mode 100644 index 000000000..5a161c5b1 --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/time_cp_now/cpp/Makefile.am @@ -0,0 +1,60 @@ +# +# This file is protected by Copyright. Please refer to the COPYRIGHT file +# distributed with this source distribution. +# +# This file is part of REDHAWK core. +# +# REDHAWK core is free software: you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# REDHAWK core is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License +# for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/. +# + +ossieName = time_cp_now +libdir = $(prefix)/dom/components/time_cp_now/cpp +lib_LTLIBRARIES = time_cp_now.la + +.PHONY: convenience-link clean-convenience-link + +install: + +all-local : convenience-link +clean-local : clean-convenience-link + +convenience-link : time_cp_now.la + @ln -fs .libs/time_cp_now.so + +clean-convenience-link: + @rm -f time_cp_now.so + +distclean-local: + rm -rf m4 + rm -f config.* + rm -rf autom4te.cache + rm -f acinclude.m4 + rm -f aclocal.m4 + rm -f configure + rm -f depcomp + rm -f install-sh + rm -f ltmain.sh + rm -f Makefile.in + rm -f missing + rm -rf .deps + + +# Sources, libraries and library directories are auto-included from a file +# generated by the REDHAWK IDE. You can remove/modify the following lines if +# you wish to manually control these options. +time_cp_now_la_SOURCES = main.cpp time_cp_now.cpp time_cp_now_base.cpp +time_cp_now_la_LIBADD = $(SOFTPKG_LIBS) $(PROJECTDEPS_LIBS) $(BOOST_LDFLAGS) $(BOOST_THREAD_LIB) $(BOOST_REGEX_LIB) $(BOOST_SYSTEM_LIB) $(INTERFACEDEPS_LIBS) $(redhawk_LDADD_auto) +time_cp_now_la_CXXFLAGS = -Wall $(SOFTPKG_CFLAGS) $(PROJECTDEPS_CFLAGS) $(BOOST_CPPFLAGS) $(INTERFACEDEPS_CFLAGS) $(redhawk_INCLUDES_auto) +time_cp_now_la_LDFLAGS = -shared -module -export-dynamic -export-symbols-regex 'make_component' -avoid-version $(redhawk_LDFLAGS_auto) + diff --git a/redhawk/src/testing/sdr/dom/components/time_cp_now/cpp/main.cpp b/redhawk/src/testing/sdr/dom/components/time_cp_now/cpp/main.cpp new file mode 100644 index 000000000..1a186306d --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/time_cp_now/cpp/main.cpp @@ -0,0 +1,11 @@ +#include +#include "ossie/ossieSupport.h" + +#include "time_cp_now.h" +extern "C" { + Resource_impl* make_component(const std::string& uuid, const std::string& identifier) + { + return new time_cp_now_i(uuid.c_str(), identifier.c_str()); + } +} + diff --git a/redhawk/src/testing/sdr/dom/components/time_cp_now/cpp/time_cp_now.cpp b/redhawk/src/testing/sdr/dom/components/time_cp_now/cpp/time_cp_now.cpp new file mode 100644 index 000000000..7a3c5379b --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/time_cp_now/cpp/time_cp_now.cpp @@ -0,0 +1,248 @@ +/************************************************************************** + + This is the component code. This file contains the child class where + custom functionality can be added to the component. Custom + functionality to the base class can be extended here. Access to + the ports can also be done from this class + +**************************************************************************/ + +#include "time_cp_now.h" + +PREPARE_LOGGING(time_cp_now_i) + +time_cp_now_i::time_cp_now_i(const char *uuid, const char *label) : + time_cp_now_base(uuid, label) +{ + // Avoid placing constructor code here. Instead, use the "constructor" function. +} + +time_cp_now_i::~time_cp_now_i() +{ +} + +void time_cp_now_i::constructor() +{ + /*********************************************************************************** + This is the RH constructor. All properties are properly initialized before this function is called + ***********************************************************************************/ +} + +/*********************************************************************************************** + + Basic functionality: + + The service function is called by the serviceThread object (of type ProcessThread). + This call happens immediately after the previous call if the return value for + the previous call was NORMAL. + If the return value for the previous call was NOOP, then the serviceThread waits + an amount of time defined in the serviceThread's constructor. + + SRI: + To create a StreamSRI object, use the following code: + std::string stream_id = "testStream"; + BULKIO::StreamSRI sri = bulkio::sri::create(stream_id); + + Time: + To create a PrecisionUTCTime object, use the following code: + BULKIO::PrecisionUTCTime tstamp = bulkio::time::utils::now(); + + + Ports: + + Data is passed to the serviceFunction through by reading from input streams + (BulkIO only). The input stream class is a port-specific class, so each port + implementing the BulkIO interface will have its own type-specific input stream. + UDP multicast (dataSDDS and dataVITA49) ports do not support streams. + + The input stream from which to read can be requested with the getCurrentStream() + method. The optional argument to getCurrentStream() is a floating point number that + specifies the time to wait in seconds. A zero value is non-blocking. A negative value + is blocking. Constants have been defined for these values, bulkio::Const::BLOCKING and + bulkio::Const::NON_BLOCKING. + + More advanced uses of input streams are possible; refer to the REDHAWK documentation + for more details. + + Input streams return data blocks that automatically manage the memory for the data + and include the SRI that was in effect at the time the data was received. It is not + necessary to delete the block; it will be cleaned up when it goes out of scope. + + To send data using a BulkIO interface, create an output stream and write the + data to it. When done with the output stream, the close() method sends and end-of- + stream flag and cleans up. + + NOTE: If you have a BULKIO dataSDDS or dataVITA49 port, you must manually call + "port->updateStats()" to update the port statistics when appropriate. + + Example: + // This example assumes that the component has two ports: + // An input (provides) port of type bulkio::InShortPort called dataShort_in + // An output (uses) port of type bulkio::OutFloatPort called dataFloat_out + // The mapping between the port and the class is found + // in the component base class header file + + bulkio::InShortStream inputStream = dataShort_in->getCurrentStream(); + if (!inputStream) { // No streams are available + return NOOP; + } + + // Get the output stream, creating it if it doesn't exist yet + bulkio::OutFloatStream outputStream = dataFloat_out->getStream(inputStream.streamID()); + if (!outputStream) { + outputStream = dataFloat_out->createStream(inputStream.sri()); + } + + bulkio::ShortDataBlock block = inputStream.read(); + if (!block) { // No data available + // Propagate end-of-stream + if (inputStream.eos()) { + outputStream.close(); + } + return NOOP; + } + + if (block.sriChanged()) { + // Update output SRI + outputStream.sri(block.sri()); + } + + // Get read-only access to the input data + redhawk::shared_buffer inputData = block.buffer(); + + // Acquire a new buffer to hold the output data + redhawk::buffer outputData(inputData.size()); + + // Transform input data into output data + for (size_t index = 0; index < inputData.size(); ++index) { + outputData[index] = (float) inputData[index]; + } + + // Write to the output stream; outputData must not be modified after + // this method call + outputStream.write(outputData, block.getStartTime()); + + return NORMAL; + + If working with complex data (i.e., the "mode" on the SRI is set to + true), the data block's complex() method will return true. Data blocks + provide a cxbuffer() method that returns a complex interpretation of the + buffer without making a copy: + + if (block.complex()) { + redhawk::shared_buffer > inData = block.cxbuffer(); + redhawk::buffer > outData(inData.size()); + for (size_t index = 0; index < inData.size(); ++index) { + outData[index] = inData[index]; + } + outputStream.write(outData, block.getStartTime()); + } + + Interactions with non-BULKIO ports are left up to the component developer's discretion + + Messages: + + To receive a message, you need (1) an input port of type MessageEvent, (2) a message prototype described + as a structure property of kind message, (3) a callback to service the message, and (4) to register the callback + with the input port. + + Assuming a property of type message is declared called "my_msg", an input port called "msg_input" is declared of + type MessageEvent, create the following code: + + void time_cp_now_i::my_message_callback(const std::string& id, const my_msg_struct &msg){ + } + + Register the message callback onto the input port with the following form: + this->msg_input->registerMessage("my_msg", this, &time_cp_now_i::my_message_callback); + + To send a message, you need to (1) create a message structure, (2) a message prototype described + as a structure property of kind message, and (3) send the message over the port. + + Assuming a property of type message is declared called "my_msg", an output port called "msg_output" is declared of + type MessageEvent, create the following code: + + ::my_msg_struct msg_out; + this->msg_output->sendMessage(msg_out); + + Accessing the Application and Domain Manager: + + Both the Application hosting this Component and the Domain Manager hosting + the Application are available to the Component. + + To access the Domain Manager: + CF::DomainManager_ptr dommgr = this->getDomainManager()->getRef(); + To access the Application: + CF::Application_ptr app = this->getApplication()->getRef(); + + Properties: + + Properties are accessed directly as member variables. For example, if the + property name is "baudRate", it may be accessed within member functions as + "baudRate". Unnamed properties are given the property id as its name. + Property types are mapped to the nearest C++ type, (e.g. "string" becomes + "std::string"). All generated properties are declared in the base class + (time_cp_now_base). + + Simple sequence properties are mapped to "std::vector" of the simple type. + Struct properties, if used, are mapped to C++ structs defined in the + generated file "struct_props.h". Field names are taken from the name in + the properties file; if no name is given, a generated name of the form + "field_n" is used, where "n" is the ordinal number of the field. + + Example: + // This example makes use of the following Properties: + // - A float value called scaleValue + // - A boolean called scaleInput + + if (scaleInput) { + dataOut[i] = dataIn[i] * scaleValue; + } else { + dataOut[i] = dataIn[i]; + } + + Callback methods can be associated with a property so that the methods are + called each time the property value changes. This is done by calling + addPropertyListener(, this, &time_cp_now_i::) + in the constructor. + + The callback method receives two arguments, the old and new values, and + should return nothing (void). The arguments can be passed by value, + receiving a copy (preferred for primitive types), or by const reference + (preferred for strings, structs and vectors). + + Example: + // This example makes use of the following Properties: + // - A float value called scaleValue + // - A struct property called status + + //Add to time_cp_now.cpp + time_cp_now_i::time_cp_now_i(const char *uuid, const char *label) : + time_cp_now_base(uuid, label) + { + addPropertyListener(scaleValue, this, &time_cp_now_i::scaleChanged); + addPropertyListener(status, this, &time_cp_now_i::statusChanged); + } + + void time_cp_now_i::scaleChanged(float oldValue, float newValue) + { + LOG_DEBUG(time_cp_now_i, "scaleValue changed from" << oldValue << " to " << newValue); + } + + void time_cp_now_i::statusChanged(const status_struct& oldValue, const status_struct& newValue) + { + LOG_DEBUG(time_cp_now_i, "status changed"); + } + + //Add to time_cp_now.h + void scaleChanged(float oldValue, float newValue); + void statusChanged(const status_struct& oldValue, const status_struct& newValue); + + +************************************************************************************************/ +int time_cp_now_i::serviceFunction() +{ + LOG_DEBUG(time_cp_now_i, "serviceFunction() example log message"); + + return NOOP; +} + diff --git a/redhawk/src/testing/sdr/dom/components/time_cp_now/cpp/time_cp_now.h b/redhawk/src/testing/sdr/dom/components/time_cp_now/cpp/time_cp_now.h new file mode 100644 index 000000000..e15ad700b --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/time_cp_now/cpp/time_cp_now.h @@ -0,0 +1,18 @@ +#ifndef TIME_CP_NOW_I_IMPL_H +#define TIME_CP_NOW_I_IMPL_H + +#include "time_cp_now_base.h" + +class time_cp_now_i : public time_cp_now_base +{ + ENABLE_LOGGING + public: + time_cp_now_i(const char *uuid, const char *label); + ~time_cp_now_i(); + + void constructor(); + + int serviceFunction(); +}; + +#endif // TIME_CP_NOW_I_IMPL_H diff --git a/redhawk/src/testing/sdr/dom/components/time_cp_now/cpp/time_cp_now_base.cpp b/redhawk/src/testing/sdr/dom/components/time_cp_now/cpp/time_cp_now_base.cpp new file mode 100644 index 000000000..e2c9ccb12 --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/time_cp_now/cpp/time_cp_now_base.cpp @@ -0,0 +1,69 @@ +#include "time_cp_now_base.h" + +/******************************************************************************************* + + AUTO-GENERATED CODE. DO NOT MODIFY + + The following class functions are for the base class for the component class. To + customize any of these functions, do not modify them here. Instead, overload them + on the child class + +******************************************************************************************/ + +time_cp_now_base::time_cp_now_base(const char *uuid, const char *label) : + Component(uuid, label), + ThreadedComponent() +{ + setThreadName(label); + + loadProperties(); +} + +time_cp_now_base::~time_cp_now_base() +{ +} + +/******************************************************************************************* + Framework-level functions + These functions are generally called by the framework to perform housekeeping. +*******************************************************************************************/ +void time_cp_now_base::start() throw (CORBA::SystemException, CF::Resource::StartError) +{ + Component::start(); + ThreadedComponent::startThread(); +} + +void time_cp_now_base::stop() throw (CORBA::SystemException, CF::Resource::StopError) +{ + Component::stop(); + if (!ThreadedComponent::stopThread()) { + throw CF::Resource::StopError(CF::CF_NOTSET, "Processing thread did not die"); + } +} + +void time_cp_now_base::releaseObject() throw (CORBA::SystemException, CF::LifeCycle::ReleaseError) +{ + // This function clears the component running condition so main shuts down everything + try { + stop(); + } catch (CF::Resource::StopError& ex) { + // TODO - this should probably be logged instead of ignored + } + + Component::releaseObject(); +} + +void time_cp_now_base::loadProperties() +{ + addProperty(rightnow, + "now", + "rightnow", + "", + "readwrite", + "", + "external", + "property"); + +} + + diff --git a/redhawk/src/testing/sdr/dom/components/time_cp_now/cpp/time_cp_now_base.h b/redhawk/src/testing/sdr/dom/components/time_cp_now/cpp/time_cp_now_base.h new file mode 100644 index 000000000..02e23c32d --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/time_cp_now/cpp/time_cp_now_base.h @@ -0,0 +1,30 @@ +#ifndef TIME_CP_NOW_BASE_IMPL_BASE_H +#define TIME_CP_NOW_BASE_IMPL_BASE_H + +#include +#include +#include + + +class time_cp_now_base : public Component, protected ThreadedComponent +{ + public: + time_cp_now_base(const char *uuid, const char *label); + ~time_cp_now_base(); + + void start() throw (CF::Resource::StartError, CORBA::SystemException); + + void stop() throw (CF::Resource::StopError, CORBA::SystemException); + + void releaseObject() throw (CF::LifeCycle::ReleaseError, CORBA::SystemException); + + void loadProperties(); + + protected: + // Member variables exposed as properties + /// Property: rightnow + CF::UTCTime rightnow; + + private: +}; +#endif // TIME_CP_NOW_BASE_IMPL_BASE_H diff --git a/redhawk/src/testing/sdr/dom/components/time_cp_now/time_cp_now.prf.xml b/redhawk/src/testing/sdr/dom/components/time_cp_now/time_cp_now.prf.xml new file mode 100644 index 000000000..add87cab4 --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/time_cp_now/time_cp_now.prf.xml @@ -0,0 +1,9 @@ + + + + + now + + + + diff --git a/redhawk/src/testing/sdr/dom/components/time_cp_now/time_cp_now.scd.xml b/redhawk/src/testing/sdr/dom/components/time_cp_now/time_cp_now.scd.xml new file mode 100644 index 000000000..df94ceaf5 --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/time_cp_now/time_cp_now.scd.xml @@ -0,0 +1,45 @@ + + + + 2.2 + + resource + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/redhawk/src/testing/sdr/dom/components/time_cp_now/time_cp_now.spd.xml b/redhawk/src/testing/sdr/dom/components/time_cp_now/time_cp_now.spd.xml new file mode 100644 index 000000000..a87476b2a --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/time_cp_now/time_cp_now.spd.xml @@ -0,0 +1,27 @@ + + + + + + null + + + + + + + + + The implementation contains descriptive information about the template for a software resource. + + + cpp/time_cp_now.so + + + + + + + + + diff --git a/redhawk/src/testing/sdr/dom/components/time_ja_now/java/Makefile.am b/redhawk/src/testing/sdr/dom/components/time_ja_now/java/Makefile.am new file mode 100644 index 000000000..18d6baf71 --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/time_ja_now/java/Makefile.am @@ -0,0 +1,41 @@ +## This file is protected by Copyright. Please refer to the COPYRIGHT file +# distributed with this source distribution. +# # +# # This file is part of REDHAWK core. +# # +# # REDHAWK core is free software: you can redistribute it and/or modify it under +# # the terms of the GNU Lesser General Public License as published by the Free +# # Software Foundation, either version 3 of the License, or (at your option) any +# # later version. +# # +# # REDHAWK core is distributed in the hope that it will be useful, but WITHOUT +# # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# # FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +# # details. +# # +# # You should have received a copy of the GNU Lesser General Public License +# # along with this program. If not, see http://www.gnu.org/licenses/. +# # +# +if HAVE_JAVASUPPORT + +time_ja_now.jar: + mkdir -p bin + find ./src -name "*.java" > fileList.txt + $(JAVAC) -cp $(OSSIE_CLASSPATH) -d bin @fileList.txt + $(JAR) cf ./time_ja_now.jar -C bin . + rm fileList.txt + +clean-local: + rm -rf bin + +time_ja_now_jar_SOURCES := $(shell find ./src -name "*.java") + +ossieName = time_ja_now +noinst_PROGRAMS = time_ja_now.jar + +else + +all-local: + @echo "Java support disabled - time_ja_now will not be compiled" +endif diff --git a/redhawk/src/testing/sdr/dom/components/time_ja_now/java/src/time_ja_now/java/time_ja_now.java b/redhawk/src/testing/sdr/dom/components/time_ja_now/java/src/time_ja_now/java/time_ja_now.java new file mode 100644 index 000000000..745c95cd0 --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/time_ja_now/java/src/time_ja_now/java/time_ja_now.java @@ -0,0 +1,252 @@ +package time_ja_now.java; + +import java.util.Properties; + +/** + * This is the component code. This file contains the derived class where custom + * functionality can be added to the component. You may add methods and code to + * this class to handle property changes, respond to incoming data, and perform + * general component housekeeping + * + * Source: time_ja_now.spd.xml + */ +public class time_ja_now extends time_ja_now_base { + /** + * This is the component constructor. In this method, you may add + * additional functionality to properties such as listening for changes + * or handling allocation, register message handlers and set up internal + * state for your component. + * + * A component may listen for external changes to properties (i.e., by a + * call to configure) using the PropertyListener interface. Listeners are + * registered by calling addChangeListener() on the property instance + * with an object that implements the PropertyListener interface for that + * data type (e.g., "PropertyListener" for a float property). More + * than one listener can be connected to a property. + * + * Example: + * // This example makes use of the following properties: + * // - A float value called scaleValue + * // The file must import "org.ossie.properties.PropertyListener" + * // Add the following import to the top of the file: + * import org.ossie.properties.PropertyListener; + * + * //Add the following to the class constructor: + * this.scaleValue.addChangeListener(new PropertyListener() { + * public void valueChanged(Float oldValue, Float newValue) { + * scaleValueChanged(oldValue, newValue); + * } + * }); + * + * //Add the following method to the class: + * private void scaleValueChanged(Float oldValue, Float newValue) + * { + * logger.debug("Changed scaleValue " + oldValue + " to " + newValue); + * } + * + * The recommended practice is for the implementation of valueChanged() to + * contain only glue code to dispatch the call to a private method on the + * component class. + * Accessing the Application and Domain Manager: + * + * Both the Application hosting this Component and the Domain Manager hosting + * the Application are available to the Component. + * + * To access the Domain Manager: + * CF.DomainManager dommgr = this.getDomainManager().getRef(); + * To access the Application: + * CF.Application app = this.getApplication().getRef(); + * + * Messages: + * + * To send or receive messages, you must have at least one message + * prototype described as a struct property of kind "message." + * + * Receiving: + * + * To receive a message, you must have an input port of type MessageEvent + * (marked as "bi-dir" in the Ports editor). For each message type the + * component supports, you must register a message handler callback with + * the message input port. Message handlers implement the MessageListener + * interface. + * + * A callback is registered by calling registerMessage() on the message + * input port with the message ID, the message struct's Class object and + * an object that implements the MessageListener interface for that + * message struct (e.g., "MessageListener" for a + * message named "my_message"). + * + * Example: + * // Assume the component has a message type called "my_message" and + * // an input MessageEvent port called "message_in". + * // Add the following to the top of the file: + * import org.ossie.events.MessageListener; + * + * // Register the callback in the class constructor: + * this.message_in.registerMessage("my_message", my_message_struct.class, new MessageListener() { + * public void messageReceived(String messageId, my_message_struct messageData) { + * my_message_received(messageData); + * } + * }); + * + * // Implement the message handler method: + * private void my_message_received(my_message_struct messageData) { + * // Respond to the message + * } + * + * The recommended practice is for the implementation of messageReceived() + * to contain only glue code to dispatch the call to a private method on + * the component class. + * + * Sending: + * + * To send a message, you must have an output port of type MessageEvent. + * Create an instance of the message struct type and call sendMessage() + * to send a single message. + * + * Example: + * // Assume the component has a message type called "my_message" and + * // an output MessageEvent port called "message_out". + * my_message_struct message = new my_message_struct(); + * this.message_out.sendMessage(message); + * + * You may also send a batch of messages at once with the sendMessages() + * method. + */ + + public time_ja_now() + { + super(); + } + + public void constructor() + { + } + + + /** + * + * Main processing function + * + * General functionality: + * + * The serviceFunction() is called repeatedly by the component's processing + * thread, which runs independently of the main thread. Each invocation + * should perform a single unit of work, such as reading and processing one + * data packet. + * + * The return status of serviceFunction() determines how soon the next + * invocation occurs: + * - NORMAL: the next call happens immediately + * - NOOP: the next call happens after a pre-defined delay (100 ms) + * - FINISH: no more calls occur + * + * StreamSRI: + * To create a StreamSRI object, use the following code: + * String stream_id = "testStream"; + * BULKIO.StreamSRI sri = new BULKIO.StreamSRI(); + * sri.mode = 0; + * sri.xdelta = 0.0; + * sri.ydelta = 1.0; + * sri.subsize = 0; + * sri.xunits = 1; // TIME_S + * sri.streamID = (stream_id != null) ? stream_id : ""; + * + * PrecisionUTCTime: + * To create a PrecisionUTCTime object, use the following code: + * BULKIO.PrecisionUTCTime tstamp = bulkio.time.utils.now(); + * + * Ports: + * + * Each port instance is accessed through members of the following form: + * + * this.port_ + * + * Input BULKIO data is obtained by calling getPacket on the provides + * port. The getPacket method takes one argument: the time to wait for + * data to arrive, in milliseconds. A timeout of 0 causes getPacket to + * return immediately, while a negative timeout indicates an indefinite + * wait. If no data is queued and no packet arrives during the waiting + * period, getPacket returns null. + * + * Output BULKIO data is sent by calling pushPacket on the uses port. In + * the case of numeric data, the pushPacket method takes a primitive + * array (e.g., "float[]"), a timestamp, an end-of-stream flag and a + * stream ID. You must make at least one call to pushSRI to associate a + * StreamSRI with the stream ID before calling pushPacket, or receivers + * may drop the data. + * + * When all processing on a stream is complete, a call should be made to + * pushPacket with the end-of-stream flag set to "true". + * + * Interactions with non-BULKIO ports are left up to the discretion of + * the component developer. + * + * Properties: + * + * Properties are accessed through members of the same name; characters + * that are invalid for a Java identifier are replaced with "_". The + * current value of the property is read with getValue and written with + * setValue: + * + * float val = this.float_prop.getValue(); + * ... + * this.float_prop.setValue(1.5f); + * + * Primitive data types are stored using the corresponding Java object + * wrapper class. For example, a property of type "float" is stored as a + * Float. Java will automatically box and unbox primitive types where + * appropriate. + * + * Numeric properties support assignment via setValue from any numeric + * type. The standard Java type coercion rules apply (e.g., truncation + * of floating point values when converting to integer types). + * + * Example: + * + * This example assumes that the component has two ports: + * - A bulkio.InShortPort provides (input) port called dataShort_in + * - A bulkio.OutFloatPort uses (output) port called dataFloat_out + * The mapping between the port and the class is found in the component + * base class file. + * This example also makes use of the following Properties: + * - A float value called amplitude with a default value of 2.0 + * - A boolean called increaseAmplitude with a default value of true + * + * bulkio.InShortPort.Packet data = this.port_dataShort_in.getPacket(125); + * + * if (data != null) { + * float[] outData = new float[data.getData().length]; + * for (int i = 0; i < data.getData().length; i++) { + * if (this.increaseAmplitude.getValue()) { + * outData[i] = (float)data.getData()[i] * this.amplitude.getValue(); + * } else { + * outData[i] = (float)data.getData()[i]; + * } + * } + * + * // NOTE: You must make at least one valid pushSRI call + * if (data.sriChanged()) { + * this.port_dataFloat_out.pushSRI(data.getSRI()); + * } + * this.port_dataFloat_out.pushPacket(outData, data.getTime(), data.getEndOfStream(), data.getStreamID()); + * } + * + */ + protected int serviceFunction() { + logger.debug("serviceFunction() example log message"); + + return NOOP; + } + + /** + * Set additional options for ORB startup. For example: + * + * orbProps.put("com.sun.CORBA.giop.ORBFragmentSize", Integer.toString(fragSize)); + * + * @param orbProps + */ + public static void configureOrb(final Properties orbProps) { + } + +} diff --git a/redhawk/src/testing/sdr/dom/components/time_ja_now/java/src/time_ja_now/java/time_ja_now_base.java b/redhawk/src/testing/sdr/dom/components/time_ja_now/java/src/time_ja_now/java/time_ja_now_base.java new file mode 100644 index 000000000..6ac8e8eba --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/time_ja_now/java/src/time_ja_now/java/time_ja_now_base.java @@ -0,0 +1,102 @@ +package time_ja_now.java; + + +import java.util.Properties; + +import org.apache.log4j.Logger; + +import org.omg.CosNaming.NamingContextPackage.CannotProceed; +import org.omg.CosNaming.NamingContextPackage.InvalidName; +import org.omg.CosNaming.NamingContextPackage.NotFound; +import org.omg.PortableServer.POAPackage.ServantNotActive; +import org.omg.PortableServer.POAPackage.WrongPolicy; + +import CF.InvalidObjectReference; + +import org.ossie.component.*; +import org.ossie.properties.*; + + +/** + * This is the component code. This file contains all the access points + * you need to use to be able to access all input and output ports, + * respond to incoming data, and perform general component housekeeping + * + * Source: time_ja_now.spd.xml + * + * @generated + */ + +public abstract class time_ja_now_base extends Component { + /** + * @generated + */ + public final static Logger logger = Logger.getLogger(time_ja_now_base.class.getName()); + + /** + * The property rightnow + * If the meaning of this property isn't clear, a description should be added. + * + * @generated + */ + public final UTCTimeProperty rightnow = + new UTCTimeProperty( + "rightnow", //id + null, //name + "now", //default value + Mode.READWRITE, //mode + Action.EXTERNAL, //action + new Kind[] {Kind.PROPERTY} + ); + + /** + * @generated + */ + public time_ja_now_base() + { + super(); + + setLogger( logger, time_ja_now_base.class.getName() ); + + + // Properties + addProperty(rightnow); + + } + + + + /** + * The main function of your component. If no args are provided, then the + * CORBA object is not bound to an SCA Domain or NamingService and can + * be run as a standard Java application. + * + * @param args + * @generated + */ + public static void main(String[] args) + { + final Properties orbProps = new Properties(); + time_ja_now.configureOrb(orbProps); + + try { + Component.start_component(time_ja_now.class, args, orbProps); + } catch (InvalidObjectReference e) { + e.printStackTrace(); + } catch (NotFound e) { + e.printStackTrace(); + } catch (CannotProceed e) { + e.printStackTrace(); + } catch (InvalidName e) { + e.printStackTrace(); + } catch (ServantNotActive e) { + e.printStackTrace(); + } catch (WrongPolicy e) { + e.printStackTrace(); + } catch (InstantiationException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + } +} diff --git a/redhawk/src/testing/sdr/dom/components/time_ja_now/java/startJava.sh b/redhawk/src/testing/sdr/dom/components/time_ja_now/java/startJava.sh new file mode 100755 index 000000000..bac09c081 --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/time_ja_now/java/startJava.sh @@ -0,0 +1,38 @@ +#!/bin/sh +# +# This file is protected by Copyright. Please refer to the COPYRIGHT file +# distributed with this source distribution. +# +# This file is part of REDHAWK core. +# +# REDHAWK core is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation, either version 3 of the License, or (at your option) any +# later version. +# +# REDHAWK core is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +# details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/. +# + +#Sun ORB start line +# Important, the $@ must be quoted "$@" for arguments to be passed correctly +myDir=`dirname $0` +JAVA_LIBDIR=${myDir}/../../../../../base/framework/java +JAVA_CLASSPATH=${JAVA_LIBDIR}/apache-commons-lang-2.4.jar:${JAVA_LIBDIR}/log4j-1.2.15.jar:${JAVA_LIBDIR}/CFInterfaces.jar:${JAVA_LIBDIR}/ossie.jar:${myDir}/time_ja_now.jar:${myDir}:${myDir}/bin:${CLASSPATH} + +# Path for Java +if test -x $JAVA_HOME/bin/java; then + JAVA=$JAVA_HOME/bin/java +else + JAVA=java +fi + +# NOTE: the $@ must be quoted "$@" for arguments to be passed correctly + +#Sun ORB start line +exec $JAVA -cp ${JAVA_CLASSPATH} time_ja_now.java.time_ja_now "$@" diff --git a/redhawk/src/testing/sdr/dom/components/time_ja_now/time_ja_now.prf.xml b/redhawk/src/testing/sdr/dom/components/time_ja_now/time_ja_now.prf.xml new file mode 100644 index 000000000..add87cab4 --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/time_ja_now/time_ja_now.prf.xml @@ -0,0 +1,9 @@ + + + + + now + + + + diff --git a/redhawk/src/testing/sdr/dom/components/time_ja_now/time_ja_now.scd.xml b/redhawk/src/testing/sdr/dom/components/time_ja_now/time_ja_now.scd.xml new file mode 100644 index 000000000..df94ceaf5 --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/time_ja_now/time_ja_now.scd.xml @@ -0,0 +1,45 @@ + + + + 2.2 + + resource + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/redhawk/src/testing/sdr/dom/components/time_ja_now/time_ja_now.spd.xml b/redhawk/src/testing/sdr/dom/components/time_ja_now/time_ja_now.spd.xml new file mode 100644 index 000000000..e41a2c85e --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/time_ja_now/time_ja_now.spd.xml @@ -0,0 +1,26 @@ + + + + + + null + + + + + + + + + The implementation contains descriptive information about the template for a software resource. + + + java/startJava.sh + + + + + + + + diff --git a/redhawk/src/testing/sdr/dom/components/time_py_now/python/time_py_now.py b/redhawk/src/testing/sdr/dom/components/time_py_now/python/time_py_now.py new file mode 100755 index 000000000..a155d9602 --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/time_py_now/python/time_py_now.py @@ -0,0 +1,156 @@ +#!/usr/bin/env python +# +# +# AUTO-GENERATED +# +# Source: time_py_now.spd.xml +from ossie.resource import start_component +import logging + +from time_py_now_base import * + +class time_py_now_i(time_py_now_base): + """""" + def constructor(self): + """ + This is called by the framework immediately after your component registers with the system. + + In general, you should add customization here and not in the __init__ constructor. If you have + a custom port implementation you can override the specific implementation here with a statement + similar to the following: + self.some_port = MyPortImplementation() + + """ + # TODO add customization here. + + def process(self): + """ + Basic functionality: + + The process method should process a single "chunk" of data and then return. This method + will be called from the processing thread again, and again, and again until it returns + FINISH or stop() is called on the component. If no work is performed, then return NOOP. + + StreamSRI: + To create a StreamSRI object, use the following code (this generates a normalized SRI that does not flush the queue when full): + sri = bulkio.sri.create("my_stream_id") + + PrecisionUTCTime: + To create a PrecisionUTCTime object, use the following code: + tstamp = bulkio.timestamp.now() + + Ports: + + Each port instance is accessed through members of the following form: self.port_ + + Data is obtained in the process function through the getPacket call (BULKIO only) on a + provides port member instance. The optional argument is a timeout value, in seconds. + A zero value is non-blocking, while a negative value is blocking. Constants have been + defined for these values, bulkio.const.BLOCKING and bulkio.const.NON_BLOCKING. If no + timeout is given, it defaults to non-blocking. + + The return value is a named tuple with the following fields: + - dataBuffer + - T + - EOS + - streamID + - SRI + - sriChanged + - inputQueueFlushed + If no data is available due to a timeout, all fields are None. + + To send data, call the appropriate function in the port directly. In the case of BULKIO, + convenience functions have been added in the port classes that aid in output. + + Interactions with non-BULKIO ports are left up to the component developer's discretion. + + Messages: + + To receive a message, you need (1) an input port of type MessageEvent, (2) a message prototype described + as a structure property of kind message, (3) a callback to service the message, and (4) to register the callback + with the input port. + + Assuming a property of type message is declared called "my_msg", an input port called "msg_input" is declared of + type MessageEvent, create the following code: + + def msg_callback(self, msg_id, msg_value): + print msg_id, msg_value + + Register the message callback onto the input port with the following form: + self.port_input.registerMessage("my_msg", time_py_now_i.MyMsg, self.msg_callback) + + To send a message, you need to (1) create a message structure, and (2) send the message over the port. + + Assuming a property of type message is declared called "my_msg", an output port called "msg_output" is declared of + type MessageEvent, create the following code: + + msg_out = time_py_now_i.MyMsg() + this.port_msg_output.sendMessage(msg_out) + + Accessing the Device Manager and Domain Manager: + + Both the Device Manager hosting this Device and the Domain Manager hosting + the Device Manager are available to the Device. + + To access the Domain Manager: + dommgr = self.getDomainManager().getRef(); + To access the Device Manager: + devmgr = self.getDeviceManager().getRef(); + Properties: + + Properties are accessed directly as member variables. If the property name is baudRate, + then accessing it (for reading or writing) is achieved in the following way: self.baudRate. + + To implement a change callback notification for a property, create a callback function with the following form: + + def mycallback(self, id, old_value, new_value): + pass + + where id is the property id, old_value is the previous value, and new_value is the updated value. + + The callback is then registered on the component as: + self.addPropertyChangeListener('baudRate', self.mycallback) + + + Example: + + # This example assumes that the component has two ports: + # - A provides (input) port of type bulkio.InShortPort called dataShort_in + # - A uses (output) port of type bulkio.OutFloatPort called dataFloat_out + # The mapping between the port and the class if found in the component + # base class. + # This example also makes use of the following Properties: + # - A float value called amplitude + # - A boolean called increaseAmplitude + + packet = self.port_dataShort_in.getPacket() + + if packet.dataBuffer is None: + return NOOP + + outData = range(len(packet.dataBuffer)) + for i in range(len(packet.dataBuffer)): + if self.increaseAmplitude: + outData[i] = float(packet.dataBuffer[i]) * self.amplitude + else: + outData[i] = float(packet.dataBuffer[i]) + + # NOTE: You must make at least one valid pushSRI call + if packet.sriChanged: + self.port_dataFloat_out.pushSRI(packet.SRI); + + self.port_dataFloat_out.pushPacket(outData, packet.T, packet.EOS, packet.streamID) + return NORMAL + + """ + + # TODO fill in your code here + self._log.debug("process() example log message") + return NOOP + + +if __name__ == '__main__': + logging.getLogger().setLevel(logging.INFO) + logging.debug("Starting Component") + start_component(time_py_now_i) + diff --git a/redhawk/src/testing/sdr/dom/components/time_py_now/python/time_py_now_base.py b/redhawk/src/testing/sdr/dom/components/time_py_now/python/time_py_now_base.py new file mode 100644 index 000000000..e68082af5 --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/time_py_now/python/time_py_now_base.py @@ -0,0 +1,70 @@ +#!/usr/bin/env python +# +# AUTO-GENERATED CODE. DO NOT MODIFY! +# +# Source: time_py_now.spd.xml +from ossie.cf import CF +from ossie.cf import CF__POA +from ossie.utils import uuid + +from ossie.component import Component +from ossie.threadedcomponent import * +from ossie.properties import simple_property + +import Queue, copy, time, threading + +class time_py_now_base(CF__POA.Resource, Component, ThreadedComponent): + # These values can be altered in the __init__ of your derived class + + PAUSE = 0.0125 # The amount of time to sleep if process return NOOP + TIMEOUT = 5.0 # The amount of time to wait for the process thread to die when stop() is called + DEFAULT_QUEUE_SIZE = 100 # The number of BulkIO packets that can be in the queue before pushPacket will block + + def __init__(self, identifier, execparams): + loggerName = (execparams['NAME_BINDING'].replace('/', '.')).rsplit("_", 1)[0] + Component.__init__(self, identifier, execparams, loggerName=loggerName) + ThreadedComponent.__init__(self) + + # self.auto_start is deprecated and is only kept for API compatibility + # with 1.7.X and 1.8.0 components. This variable may be removed + # in future releases + self.auto_start = False + # Instantiate the default implementations for all ports on this component + + def start(self): + Component.start(self) + ThreadedComponent.startThread(self, pause=self.PAUSE) + + def stop(self): + Component.stop(self) + if not ThreadedComponent.stopThread(self, self.TIMEOUT): + raise CF.Resource.StopError(CF.CF_NOTSET, "Processing thread did not die") + + def releaseObject(self): + try: + self.stop() + except Exception: + self._log.exception("Error stopping") + Component.releaseObject(self) + + ###################################################################### + # PORTS + # + # DO NOT ADD NEW PORTS HERE. You can add ports in your derived class, in the SCD xml file, + # or via the IDE. + + ###################################################################### + # PROPERTIES + # + # DO NOT ADD NEW PROPERTIES HERE. You can add properties in your derived class, in the PRF xml file + # or by using the IDE. + rightnow = simple_property(id_="rightnow", + type_="utctime", + defvalue="now", + mode="readwrite", + action="external", + kinds=("property",)) + + + + diff --git a/redhawk/src/testing/sdr/dom/components/time_py_now/time_py_now.prf.xml b/redhawk/src/testing/sdr/dom/components/time_py_now/time_py_now.prf.xml new file mode 100644 index 000000000..add87cab4 --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/time_py_now/time_py_now.prf.xml @@ -0,0 +1,9 @@ + + + + + now + + + + diff --git a/redhawk/src/testing/sdr/dom/components/time_py_now/time_py_now.scd.xml b/redhawk/src/testing/sdr/dom/components/time_py_now/time_py_now.scd.xml new file mode 100644 index 000000000..df94ceaf5 --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/time_py_now/time_py_now.scd.xml @@ -0,0 +1,45 @@ + + + + 2.2 + + resource + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/redhawk/src/testing/sdr/dom/components/time_py_now/time_py_now.spd.xml b/redhawk/src/testing/sdr/dom/components/time_py_now/time_py_now.spd.xml new file mode 100644 index 000000000..b6acd707d --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/time_py_now/time_py_now.spd.xml @@ -0,0 +1,25 @@ + + + + + + null + + + + + + + + + The implementation contains descriptive information about the template for a software resource. + + + python/time_py_now.py + + + + + + + diff --git a/redhawk/src/testing/sdr/dom/waveforms/newtime_w/newtime_w.sad.xml b/redhawk/src/testing/sdr/dom/waveforms/newtime_w/newtime_w.sad.xml new file mode 100644 index 000000000..55ed55dc9 --- /dev/null +++ b/redhawk/src/testing/sdr/dom/waveforms/newtime_w/newtime_w.sad.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + newtime_1 + + + + + + + + + + + + + diff --git a/redhawk/src/testing/sdr/dom/waveforms/time_cp_now_w/time_cp_now_w.sad.xml b/redhawk/src/testing/sdr/dom/waveforms/time_cp_now_w/time_cp_now_w.sad.xml new file mode 100644 index 000000000..ec67247e1 --- /dev/null +++ b/redhawk/src/testing/sdr/dom/waveforms/time_cp_now_w/time_cp_now_w.sad.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + time_cp_now_1 + + + + + + + + + + diff --git a/redhawk/src/testing/sdr/dom/waveforms/time_ja_now_w/time_ja_now_w.sad.xml b/redhawk/src/testing/sdr/dom/waveforms/time_ja_now_w/time_ja_now_w.sad.xml new file mode 100644 index 000000000..e1992c8a3 --- /dev/null +++ b/redhawk/src/testing/sdr/dom/waveforms/time_ja_now_w/time_ja_now_w.sad.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + time_ja_now_1 + + + + + + + + + + diff --git a/redhawk/src/testing/sdr/dom/waveforms/time_py_now_w/time_py_now_w.sad.xml b/redhawk/src/testing/sdr/dom/waveforms/time_py_now_w/time_py_now_w.sad.xml new file mode 100644 index 000000000..38757263c --- /dev/null +++ b/redhawk/src/testing/sdr/dom/waveforms/time_py_now_w/time_py_now_w.sad.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + time_py_now_1 + + + + + + + + + + diff --git a/redhawk/src/testing/tests/test_11_AllPropTypes.py b/redhawk/src/testing/tests/test_11_AllPropTypes.py index b4175a349..fc59380f9 100644 --- a/redhawk/src/testing/tests/test_11_AllPropTypes.py +++ b/redhawk/src/testing/tests/test_11_AllPropTypes.py @@ -23,7 +23,7 @@ from _unitTestHelpers import scatest from ossie.cf import CF, CF__POA from omniORB import CORBA -from ossie.utils import sb +from ossie.utils import sb, rhtime, redhawk import struct, time, os globalsdrRoot = os.environ['SDRROOT'] @@ -97,6 +97,77 @@ def test_getTimePython(self): def test_getTimeJava(self): self.basetest_getTime('timeprop_java') +class UTCTimeTestWaveform(scatest.CorbaTestCase): + def setUp(self): + domBooter, self._domMgr = self.launchDomainManager() + devBooter, self._devMgr = self.launchDeviceManager("/nodes/test_BasicTestDevice_node/DeviceManager.dcd.xml") + self._rhDom = redhawk.attach(scatest.getTestDomainName()) + self.assertEquals(len(self._rhDom._get_applications()), 0) + + def tearDown(self): + if self._app: + self._app.stop() + self._app.releaseObject() + + # Do all application shutdown before calling the base class tearDown, + # or failures will probably occur. + scatest.CorbaTestCase.tearDown(self) + + def basetest_Now(self, app_name): + self._app = self._rhDom.createApplication("/waveforms/"+app_name+"/"+app_name+".sad.xml") + self.assertNotEqual(self._app, None) + cur_time = rhtime.now() + app_time = self._app.comps[0].rightnow.queryValue() + _cur_time = cur_time.twsec + cur_time.tfsec + _app_time = app_time.twsec + app_time.tfsec + self.assertTrue(abs(_cur_time-_app_time)<1, True) + + def test_nowOverload(self): + self.basetest_Now('newtime_w') + + def test_nowCpp(self): + self.basetest_Now('time_cp_now_w') + + def test_nowPython(self): + self.basetest_Now('time_py_now_w') + + @scatest.requireJava + def test_nowJava(self): + self.basetest_Now('time_ja_now_w') + +class UTCTimeTestSandbox(scatest.CorbaTestCase): + def setUp(self): + sb.setDEBUG(False) + # Flagrant violation of sandbox API: if the sandbox singleton exists, + # clean up previous state and dispose of it. + if sb.domainless._sandbox: + sb.domainless._sandbox.shutdown() + sb.domainless._sandbox = None + + def tearDown(self): + sb.release() + sb.setDEBUG(False) + os.environ['SDRROOT'] = globalsdrRoot + + def basetest_Now(self, comp_name): + comp = sb.launch(comp_name) + self.assertNotEqual(comp, None) + cur_time = rhtime.now() + comp_time = comp.rightnow.queryValue() + _cur_time = cur_time.twsec + cur_time.tfsec + _comp_time = comp_time.twsec + comp_time.tfsec + self.assertTrue(abs(_cur_time-_comp_time)<1, True) + + def test_nowSbCpp(self): + self.basetest_Now('time_cp_now') + + def test_nowSbPython(self): + self.basetest_Now('time_py_now') + + @scatest.requireJava + def test_nowSbJava(self): + self.basetest_Now('time_ja_now') + class TestAllTypes(scatest.CorbaTestCase): def setUp(self): domBooter, self._domMgr = self.launchDomainManager() From 07ec0527e309f84486266c18e2b84c2c63084884 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Thu, 27 Apr 2017 16:49:57 -0400 Subject: [PATCH 0780/1644] Refs CF-1688. Added queryTimestamp to the rhtime package to make it easier to get a query timestamp --- .../src/base/framework/python/ossie/utils/rhtime/helpers.py | 4 ++++ redhawk/src/testing/tests/test_11_AllPropTypes.py | 5 ++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/rhtime/helpers.py b/redhawk/src/base/framework/python/ossie/utils/rhtime/helpers.py index 0a73cf0fb..07e2965f7 100644 --- a/redhawk/src/base/framework/python/ossie/utils/rhtime/helpers.py +++ b/redhawk/src/base/framework/python/ossie/utils/rhtime/helpers.py @@ -22,6 +22,7 @@ import math from ossie.cf import CF +from omniORB import any as _any def now(): """ @@ -38,6 +39,9 @@ def notSet(): """ return CF.UTCTime(1, 0.0, 0.0) +def queryTimestamp(): + return CF.DataType(id='QUERY_TIMESTAMP',value=_any.to_any(None)) + def cpuTimeStamp(): return now() diff --git a/redhawk/src/testing/tests/test_11_AllPropTypes.py b/redhawk/src/testing/tests/test_11_AllPropTypes.py index fc59380f9..18bdfecce 100644 --- a/redhawk/src/testing/tests/test_11_AllPropTypes.py +++ b/redhawk/src/testing/tests/test_11_AllPropTypes.py @@ -51,7 +51,6 @@ def tearDown(self): os.environ['SDRROOT'] = globalsdrRoot def basetest_getTime(self, comp_name): - _timeprop = CF.DataType(id='QUERY_TIMESTAMP',value=any.to_any(None)) comp = sb.launch(comp_name) _prop=CF.DataType(id='prop',value=any.to_any(None)) _retval = comp.query([_prop]) @@ -62,7 +61,7 @@ def basetest_getTime(self, comp_name): self.assertEqual(_retval[0].value._v, 'value') self.assertEqual(len(_retval), 1) - _retval = comp.query([_prop, _timeprop]) + _retval = comp.query([_prop, rhtime.queryTimestamp()]) self.assertEqual(_retval[0].value._v, 'value') self.assertEqual(len(_retval), 2) @@ -77,7 +76,7 @@ def basetest_getTime(self, comp_name): self.assertEqual(_retval[0].value._v, 'hello') self.assertEqual(myl.rcv_event.properties[0].value._v, 'hello') - _retval = comp.query([_timeprop]) + _retval = comp.query([rhtime.queryTimestamp()]) self.assertEqual(len(_retval), 1) self.assertEqual(_retval[0].value._v.tcstatus, 1) _time1 = myl.rcv_event.timestamp.twsec + myl.rcv_event.timestamp.tfsec From 6e5d0bb1bcf80f29d6cab1f4de2cef2581e1c46a Mon Sep 17 00:00:00 2001 From: Max Robert Date: Fri, 28 Apr 2017 15:56:03 -0400 Subject: [PATCH 0781/1644] Refs CF-228. Component identifiers created from loadSADFile match those created by the domain --- .../base/framework/python/ossie/utils/sb/domainless.py | 9 +++++---- redhawk/src/testing/tests/test_13_TestSB.py | 4 ++++ 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/sb/domainless.py b/redhawk/src/base/framework/python/ossie/utils/sb/domainless.py index e07480ba9..bd4a2d77b 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sb/domainless.py +++ b/redhawk/src/base/framework/python/ossie/utils/sb/domainless.py @@ -620,6 +620,7 @@ def loadSADFile(filename, props={}): sad = parsers.sad.parseString(sadFileString) log.debug("waveform ID '%s'", sad.get_id()) log.debug("waveform name '%s'", sad.get_name()) + waveform_modifier = ':'+sad.get_name() validRequestedComponents = {} # Loop over each entry to determine SPD filenames and which components are kickable for component in sad.componentfiles.get_componentfile(): @@ -637,7 +638,7 @@ def loadSADFile(filename, props={}): # Need to determine which component is the assembly controller assemblyControllerRefid = None if sad.assemblycontroller: - assemblyControllerRefid = sad.assemblycontroller.get_componentinstantiationref().get_refid() + assemblyControllerRefid = sad.assemblycontroller.get_componentinstantiationref().get_refid() + waveform_modifier log.debug("ASSEMBLY CONTROLLER component instantiation ref '%s'", assemblyControllerRefid) if not assemblyControllerRefid: log.warn('SAD file did not specify an assembly controller') @@ -647,7 +648,7 @@ def loadSADFile(filename, props={}): # externprops=[] if sad.get_externalproperties(): - externprops=[ { 'comprefid' : x.comprefid, 'propid' : x.propid, 'externalpropid' : x.externalpropid } for x in sad.get_externalproperties().get_property() ] + externprops=[ { 'comprefid' : x.comprefid + waveform_modifier, 'propid' : x.propid, 'externalpropid' : x.externalpropid } for x in sad.get_externalproperties().get_property() ] log.debug( "External Props: %s", externprops ) # Loop over each entry to determine actual instance name for component @@ -687,7 +688,7 @@ def loadSADFile(filename, props={}): refid = component.componentfileref.refid if validRequestedComponents.has_key(refid): instanceName = component.get_componentinstantiation()[0].get_usagename() - instanceID = component.get_componentinstantiation()[0].id_ + instanceID = component.get_componentinstantiation()[0].id_ + waveform_modifier log.debug("launching component '%s'", instanceName) properties=component.get_componentinstantiation()[0].get_componentproperties() #simples @@ -831,7 +832,7 @@ def loadSADFile(filename, props={}): assemblyController = False sandboxComponent = None if validRequestedComponents.has_key(refid): - instanceID = component.get_componentinstantiation()[0].id_ + instanceID = component.get_componentinstantiation()[0].id_ + waveform_modifier componentProps = None if len(launchedComponents) > 0: for comp in launchedComponents: diff --git a/redhawk/src/testing/tests/test_13_TestSB.py b/redhawk/src/testing/tests/test_13_TestSB.py index 4e4491fa3..69bcc5e61 100644 --- a/redhawk/src/testing/tests/test_13_TestSB.py +++ b/redhawk/src/testing/tests/test_13_TestSB.py @@ -622,6 +622,10 @@ def test_loadSADFile(self): comp_ac = sb.getComponent('ticket_462_ac_1') self.assertNotEquals(comp_ac, None) comp = sb.getComponent('ticket_462_1') + comp_id = comp._get_identifier() + self.assertEquals(len(comp_id.split(':')), 2) + self.assertEquals(comp_id.split(':')[0], 'ticket_462_1') + self.assertEquals(comp_id.split(':')[1], 'ticket_462_w') self.assertNotEquals(comp, None) self.assertEquals(comp_ac.my_simple, "foo") self.assertEquals(comp_ac.my_seq, ["initial value"]) From 705414db14aada2a8b1967fdde87da6be2852386 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Mon, 1 May 2017 11:11:27 -0400 Subject: [PATCH 0782/1644] Refs CF-171. Sandbox MessageSink provides access to contents of the received messages as well as a callback function --- .../framework/python/ossie/events/__init__.py | 15 ++++++++++--- .../python/ossie/utils/sb/io_helpers.py | 15 +++++++++++-- redhawk/src/testing/tests/test_13_TestSB.py | 21 +++++++++++++++++-- 3 files changed, 44 insertions(+), 7 deletions(-) diff --git a/redhawk/src/base/framework/python/ossie/events/__init__.py b/redhawk/src/base/framework/python/ossie/events/__init__.py index f9a26a154..0e0dc0ede 100644 --- a/redhawk/src/base/framework/python/ossie/events/__init__.py +++ b/redhawk/src/base/framework/python/ossie/events/__init__.py @@ -30,7 +30,7 @@ from ossie.cf import CF, CF__POA from ossie.cf import ExtendedCF, ExtendedCF__POA from ossie.cf import ExtendedEvent, ExtendedEvent__POA -from ossie.properties import struct_from_any, struct_to_any, props_to_any +from ossie.properties import struct_from_any, struct_to_any, props_to_any, prop_to_dict from ossie.properties import simple_property, simpleseq_property, struct_property, structseq_property import traceback @@ -322,7 +322,7 @@ def __init__(self, parent, instance_id): self.parent = parent self.instance_id = instance_id self.existence_lock = threading.Lock() - + def push(self, data): self.parent.actionQueue.put(('message',data)) @@ -351,7 +351,7 @@ def obtain_push_consumer(self): self.parent.consumer_lock.release() return objref - def __init__(self, thread_sleep=0.1, parent=None): + def __init__(self, thread_sleep=0.1, parent=None, storeMessages = False): self.consumer_lock = threading.Lock() threading.Thread.__init__(self) self._terminateMe=False @@ -366,6 +366,8 @@ def __init__(self, thread_sleep=0.1, parent=None): self.consumers = {} self.supplier_admin = self.SupplierAdmin_i(self) self._parent_comp = parent + self._storeMessages = storeMessages + self._storedMessages = [] self.startPort() @@ -445,6 +447,11 @@ def run(self): # Stop tracking this thread _consumers.remove(self) + def getMessages(self): + retval = copy.deepcopy(self._storedMessages) + self._storedMessages = [] + return retval + def _run(self): while not self._terminateMe: while not self.actionQueue.empty(): @@ -473,6 +480,8 @@ def _run(self): except Exception, e: print "Callback for message "+str(id)+" failed with exception: "+str(e) for allMsg in self._allMsg: + if self._storeMessages: + self._storedMessages.append(prop_to_dict(value)) callback = allMsg[1] try: callback(id, value) diff --git a/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py b/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py index 22d302684..7a57face1 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py +++ b/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py @@ -143,7 +143,14 @@ def reset(self): pass class MessageSink(helperBase, PortSupplier): - def __init__(self, messageId = None, messageFormat = None, messageCallback = None): + ''' + Received structured messages + if storeMessages is True, then messages can be retrieved through the getMessages function + The internal message queue is emptied when messages are retrieved, so if storeMessages is True, + make sure to regularly retrieve the available messages to empty out the internal list + + ''' + def __init__(self, messageId = None, messageFormat = None, messageCallback = None, storeMessages = False): helperBase.__init__(self) PortSupplier.__init__(self) self._flowOn = False @@ -151,6 +158,7 @@ def __init__(self, messageId = None, messageFormat = None, messageCallback = Non self._messageId = messageId self._messageFormat = messageFormat self._messageCallback = messageCallback + self._storeMessages = storeMessages self._providesPortDict = {} self._providesPortDict['msgIn'] = { 'Port Interface': 'IDL:ExtendedEvent/MessageEvent:1.0', @@ -165,12 +173,15 @@ def __del__(self): def messageCallback(self, msgId, msgData): print msgId, msgData + def getMessages(self): + return self._messagePort.getMessages() + def getPort(self, portName): try: if self._messageCallback == None: self._messageCallback = self.messageCallback if self._messagePort == None: - self._messagePort = _events.MessageConsumerPort(thread_sleep=0.1) + self._messagePort = _events.MessageConsumerPort(thread_sleep=0.1, storeMessages = self._storeMessages) self._messagePort.registerMessage(self._messageId, self._messageFormat, self._messageCallback) return self._messagePort._this() diff --git a/redhawk/src/testing/tests/test_13_TestSB.py b/redhawk/src/testing/tests/test_13_TestSB.py index 69bcc5e61..5b20e80de 100644 --- a/redhawk/src/testing/tests/test_13_TestSB.py +++ b/redhawk/src/testing/tests/test_13_TestSB.py @@ -2359,11 +2359,10 @@ def wait_for_msg(cond, timeout=2.0): msrc = sb.MessageSource() cond = threading.Condition() mcb = MCB(cond) - msink = sb.MessageSink( messageCallback=mcb.msgCallback ) + msink = sb.MessageSink(messageCallback=mcb.msgCallback, storeMessages = True) msrc.connect(msink) # Simple messages come across properties list which translates into the following # {'sb_struct': {'sb': 'testing 1'}} - msrc.sendMessage("testing 1") wait_for_msg(cond) @@ -2373,6 +2372,10 @@ def wait_for_msg(cond, timeout=2.0): wait_for_msg(cond) msg = mcb.msg['sb_struct']['sb'] self.assertEquals( msg, "testing 2") + rcv_msg = msink.getMessages() + self.assertEquals(len(rcv_msg), 1) + self.assertEquals(rcv_msg[0], mcb.msg) + self.assertEquals(len(msink.getMessages()), 0) sb.stop() # terminate this sink object @@ -2398,6 +2401,20 @@ def wait_for_msg(cond, timeout=2.0): wait_for_msg(cond) msg = mcb.msg['sb_struct']['sb'] self.assertEquals( msg, "testing 5") + self.assertEquals(len(msink.getMessages()), 0) + sb.stop() + + # terminate this sink object + msink.releaseObject() + + # create new sink and connect to source + msink = sb.MessageSink(messageCallback=None, storeMessages = True) + msrc.connect(msink) + sb.start() + msrc.sendMessage("testing 4") + msrc.sendMessage("testing 5") + time.sleep(2) + self.assertEquals(len(msink.getMessages()), 2) sb.stop() # reset receiver and cycle sandbox state From 7b461d111a1736035906bbadce978af27e2e1ad8 Mon Sep 17 00:00:00 2001 From: 8530 <8530@vm-131.vsi-corp.com> Date: Mon, 1 May 2017 13:11:34 -0400 Subject: [PATCH 0783/1644] initial sdds data capture and packet parser using ctypes and structs to parser incoming packet definitions --- .../python/ossie/utils/sdds/__init__.py | 22 + .../python/ossie/utils/sdds/sdds_pkt.py | 1091 +++++++++++++++++ .../python/ossie/utils/sdds/sdds_time.py | 157 +++ redhawk/src/testing/tests/test_13_SDDS.py | 374 ++++++ 4 files changed, 1644 insertions(+) create mode 100644 redhawk/src/base/framework/python/ossie/utils/sdds/__init__.py create mode 100644 redhawk/src/base/framework/python/ossie/utils/sdds/sdds_pkt.py create mode 100644 redhawk/src/base/framework/python/ossie/utils/sdds/sdds_time.py create mode 100644 redhawk/src/testing/tests/test_13_SDDS.py diff --git a/redhawk/src/base/framework/python/ossie/utils/sdds/__init__.py b/redhawk/src/base/framework/python/ossie/utils/sdds/__init__.py new file mode 100644 index 000000000..58f1c6d33 --- /dev/null +++ b/redhawk/src/base/framework/python/ossie/utils/sdds/__init__.py @@ -0,0 +1,22 @@ +# +# This file is protected by Copyright. Please refer to the COPYRIGHT file +# distributed with this source distribution. +# +# This file is part of REDHAWK core. +# +# REDHAWK core is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation, either version 3 of the License, or (at your option) any +# later version. +# +# REDHAWK core is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +# details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/. +# + +from sdds_time import * +from sdds_pkt import * diff --git a/redhawk/src/base/framework/python/ossie/utils/sdds/sdds_pkt.py b/redhawk/src/base/framework/python/ossie/utils/sdds/sdds_pkt.py new file mode 100644 index 000000000..353090de5 --- /dev/null +++ b/redhawk/src/base/framework/python/ossie/utils/sdds/sdds_pkt.py @@ -0,0 +1,1091 @@ +# +# This file is protected by Copyright. Please refer to the COPYRIGHT file +# distributed with this source distribution. +# +# This file is part of REDHAWK rh.SourceSDDS. +# +# REDHAWK rh.SourceSDDS is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation, either version 3 of the License, or (at your option) any +# later version. +# +# REDHAWK rh.SourceSDDS is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +# details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/. +# +import ctypes +import time +import datetime + + +def BitsToNumber(sbits, reverse=False ): + tbits=sbits[:] + if reverse: + tbits.reverse() + f = [x << n for n, x in enumerate(tbits)] + return reduce(lambda x, y: x + y, f) + + +class format_identifier(ctypes.Structure): + _pack_ = 1 + _fields_ = [ ('dm',ctypes.c_uint8,3), + ('ss',ctypes.c_uint8,1), + ('of',ctypes.c_uint8,1), + ('pp',ctypes.c_uint8,1), + ('sos',ctypes.c_uint8,1), + ('sf',ctypes.c_uint8,1), + ('bps',ctypes.c_uint8,5), + ('vw',ctypes.c_uint8,1), + ('snp',ctypes.c_uint8,1), + ('cx',ctypes.c_uint8,1) ] + + def __new__(cls,buf=None): + if buf: + return cls.from_buffer_copy(buf) + else: + return super(format_identifier,cls).__new__(cls) + + def __init__(self,data=None): + self.sf = 1 + self.sos = 1 + self.pp = 0 + self.of = 0 + self.ss = 0 + self.bps = 8 + self.vw = 0 + self.snp = 0 + self.cx = 0 + self.dm=1 + + def __str__(self): + return ' '.join( [ x[0]+':'+str(getattr(self,x[0])) for x in self._fields_ ]) + + + def set_dmode(self, dm, reverse=False ): + if type(dm) == list: + self.dm = BitsToNumber(dm) + else: + self.dm = dm + + def set_bps(self, bps, reverse=False ): + _bps=bps + if type(bps) == list: + _bps = BitsToNumber(bps, reverse) + + if _bps == 32 : _bps = 31 + self.bps= _bps + + def get_bps(self): + _bps=self.bps + if _bps == 31 : _bps = 32 + return _bps + + def asBuffer(self): + return buffer(self)[:] + + def asString(self): + return ctypes.string_at(ctypes.addressof(self),ctypes.sizeof(self)) + +class frame_sequence(ctypes.BigEndianStructure): + MAX_SEQ_NUMBER=65536 + _pack_ = 1 + _fields_ = [ ('seq',ctypes.c_ushort,16) ] + + def __new__(cls,buf=None): + if buf: + return cls.from_buffer_copy(buf) + else: + return super(frame_sequence,cls).__new__(cls) + + def __init__(self,data=None): + self.seq = 0 + + def inc(self): + self.seq = (self.seq + 1 ) % frame_sequence.MAX_SEQ_NUMBER + + def __str__(self): + return ''.join( [ str(getattr(self,x[0])) for x in self._fields_ ]) + + def get(self): + return self.seq + + def set(self, v ): + self.seq = v + + def asBuffer(self): + return buffer(self)[:] + + def asString(self): + return ctypes.string_at(ctypes.addressof(self),ctypes.sizeof(self)) + +class msptr_data (ctypes.Structure): + _pack_ = 1 + _fields_ = [ ('msptr',ctypes.c_ushort,16), + ('msdelta',ctypes.c_ushort,16) ] + + def __new__(cls,buf=None): + if buf: + return cls.from_buffer_copy(buf) + else: + return super(msptr_data,cls).__new__(cls) + + def __init__(self,data=None): + self.msptr=0 + self.msdelta=0 + + def __str__(self): + return '/'.join( [ x[0] for x in self._fields_ ]) + ': '+ '/'.join( [ str(getattr(self,x[0])) for x in self._fields_ ]) + + def set_msptr( self, val ): + val = val&0x07FF + self.msptr = val + + def get_msptr( self ): + return self.msptr + + def asBuffer(self): + return buffer(self)[:] + + def asString(self): + return ctypes.string_at(ctypes.addressof(self),ctypes.sizeof(self)) + +class ttag_info_struct(ctypes.Structure): + _pack_ = 1 + _fields_ = [ ('pad2',ctypes.c_uint8,8), + ('msv',ctypes.c_uint8,1), + ('ttv',ctypes.c_uint8,1), + ('sscv',ctypes.c_uint8,1), + ('pi',ctypes.c_uint8,1), + ('peo',ctypes.c_uint8,1), + ('pad1',ctypes.c_uint8,3), + ('pad3',ctypes.c_uint16,16) ] + + def __new__(cls,buf=None): + if buf: + return cls.from_buffer_copy(buf) + else: + return super(ttag_info_struct,cls).__new__(cls) + + def __init__(self,data=None): + self.ttv=0 + self.sscv=0 + self.pi=0 + self.msv=0 + self.peo=0 + self.pad1=0 + self.pad2=0 + self.pad3=0 + + def __str__(self): + return ' '.join( [ x[0]+':'+str(getattr(self,x[0])) for x in self._fields_ if x[0] in ['msv','ttv','sscv','pi','peo']]) + + def get_sscv(self): + return self.sscv + + def set_sscv(self, valid=True): + if valid: + self.sscv = 1 + else: + self.sscv = 0 + + def get_ttv(self): + return self.ttv + + def set_ttv(self, valid=True): + if valid: + self.ttv = 1 + else: + self.ttv = 0 + + def get_msv(self): + return self.msv + + def set_msv(self, valid=True): + if valid: + self.msv = 1 + else: + self.msv = 0 + + def get_pi(self): + return self.pi + + def set_pi(self, onoff=True): + if onoff: + self.pi = 1 + else: + self.pi = 0 + + def get_peo(self): + return self.peo + + def set_peo(self, odd=False): + if odd: + self.peo = 1 + else: + self.peo = 0 + + def asBuffer(self): + return buffer(self)[:] + + def asString(self): + return ctypes.string_at(ctypes.addressof(self),ctypes.sizeof(self)) + +class ttag_info_union(ctypes.Union): + _pack_ = 1 + _fields_ = [ ('msptr', msptr_data), + ('info', ttag_info_struct )] + + def __new__(cls,buf=None): + if buf: + return cls.from_buffer_copy(buf) + else: + return super(ttag_info_union,cls).__new__(cls) + + def __init__(self,data=None): + pass + + def __str__(self): + return 'info: '+str(self.info)+ ' ' + str(self.msptr) + + def asBuffer(self): + return buffer(self)[:] + + def asString(self): + return ctypes.string_at(ctypes.addressof(self),ctypes.sizeof(self)) + +class ttag_values(ctypes.BigEndianStructure): + _pack_ = 1 + _fields_ = [ ('ttag',ctypes.c_uint64), + ('ttage',ctypes.c_uint32) + ] + def __new__(cls,buf=None): + if buf: + return cls.from_buffer_copy(buf) + else: + return super(ttag_values,cls).__new__(cls) + + def __init__(self,data=None): + self.ttag=0 + self.ttage=0 + + def __str__(self): + return str(self.get_SDDSTime()) + + def set(self, ps250, pf250): + self.ttag = ps250 + self.ttage = pf250 + + def set_SDDSTime(self, sdds_time): + self.ttag = sdds_time.picoTicks() + self.ttage = sdds_time.picoTicksFractional() + + def get_SDDSTime(self): + from ossie.utils.sdds import Time + t=Time() + t.set( self.ttag, self.ttage ) + return t + + + def asBuffer(self): + return buffer(self)[:] + + def asString(self): + return ctypes.string_at(ctypes.addressof(self),ctypes.sizeof(self)) + + +class ttag_info(ctypes.Structure): + _pack_ = 1 + _fields_ = [ ('info', ttag_info_union ), + ('tstamp', ttag_values ) ] + + def __new__(cls,buf=None): + if buf: + return cls.from_buffer_copy(buf) + else: + return super(ttag_info,cls).__new__(cls) + + def __init__(self,data=None): + pass + + def __str__(self): + return str(self.info)+' tstamp: '+str(self.tstamp) + + def get_msptr( self ): + return self.info.msptr.get_msptr() + + def set_msptr( self, val ): + self.info.msptr.set_msptr(val) + + def get_msdelta( self ): + return self.info.msptr.get_msdelta() + + def set_msdelta( self, val ): + self.info.msptr.set_msdelta(val) + + def clear_msptr(self): + self.info.msptr.msptr = 0 + self.info.msptr.msdelta = 0 + + def set_msv(self, valid=True): + self.info.info.set_msv(valid) + + def get_msv(self): + return self.info.info.get_msv() + + def get_ttv(self): + return self.info.info.get_ttv() + + def set_ttv(self, valid=True): + self.info.info.set_ttv(valid) + + def get_sscv(self): + return self.info.info.get_sscv() + + def set_sscv(self, valid=True): + self.info.info.set_sscv(valid) + + + def asBuffer(self): + return buffer(self)[:] + + def asString(self): + return ctypes.string_at(ctypes.addressof(self),ctypes.sizeof(self)) + +class ssc_info_struct(ctypes.BigEndianStructure): + _pack_ = 1 + _fields_ = [ ('dfdt',ctypes.c_int32), + ('freq',ctypes.c_uint64) + ] + def __new__(cls,buf=None): + if buf: + return cls.from_buffer_copy(buf) + else: + return super(ssc_info_struct,cls).__new__(cls) + + def __init__(self,data=None): + pass + + def __str__(self): + return 'freq: '+ str(self.get_freq())+' dfdt: '+ str(self.get_dfdt()) + + def get_freq(self): + # frequency units in resolution 125mhz/2^63 + rfreq = ( self.freq * 1.3552527156068805e-11 ) + return rfreq + + def set_freq(self, freq): + # frequency units resolution 2^63/125mhz + sfreq= freq* 73786976294.838211 + self.freq = long(sfreq) + + def get_dfdt(self): + sdfdt = self.dfdt * 9.3132257461547852e-10 + return sdfdt + + def set_dfdt(self, val ): + sdfdt = val * 1073741824.0 + self.dfdt = ctypes.c_int32(int(sdfdt)) + + def asBuffer(self): + return buffer(self)[:] + + def asString(self): + return ctypes.string_at(ctypes.addressof(self),ctypes.sizeof(self)) + + +class ssd_data(ctypes.BigEndianStructure): + DATA_LEN=2 + _pack_ = 1 + _fields_ = [ ('data', ctypes.c_uint16* DATA_LEN ) ] + + def __new__(cls,buf=None): + if buf: + return cls.from_buffer_copy(buf) + else: + return super(ssd_data,cls).__new__(cls) + + def __init__(self,data=None): + pass + + def __str__(self): + return ','.join( [ str(hex(ord(x))) for x in self.asBuffer() ] ) + + def asBuffer(self): + return buffer(self)[:] + + def asString(self): + return ctypes.string_at(ctypes.addressof(self),ctypes.sizeof(self)) + +class aad_data(ctypes.BigEndianStructure): + DATA_LEN=20 + _pack_ = 1 + _fields_ = [ ('data', ctypes.c_uint8*DATA_LEN) ] + + def __new__(cls,buf=None): + if buf: + return cls.from_buffer_copy(buf) + else: + return super(aad_data,cls).__new__(cls) + + def __init__(self,data=None): + pass + + def __str__(self): + return ','.join( [ str(hex(ord(x))) for x in self.asBuffer() ] ) + + def asBuffer(self): + return buffer(self)[:] + + def asString(self): + return ctypes.string_at(ctypes.addressof(self),ctypes.sizeof(self)) + + +class sdds_header(ctypes.Structure): + PARITY_SEQ_NUMBER=32 + MAX_SEQ_NUMBER=65536 + _pack_ = 1 + _fields_ = [ ('formatid', format_identifier), + ('fsn', frame_sequence), + ('ttag', ttag_info ), + ('ssc', ssc_info_struct ), + ('ssd', ssd_data ), + ('aad', aad_data ), + ] + + def __new__(cls,buf=None): + if buf: + return cls.from_buffer_copy(buf) + else: + return super(sdds_header,cls).__new__(cls) + + def __init__(self,data=None, skip_parity=True): + + self._skip_parity=skip_parity + pass + + def __str__(self): + return 'format_id: '+str(self.formatid)+'\n'+ \ + ' fsn: '+str(self.fsn) +'\n' + \ + ' ttag: '+str(self.ttag)+'\n' + \ + ' ssc: '+str(self.ssc)+'\n' + \ + ' ssd: '+str(self.ssd)+'\n' + \ + ' aad: '+str(self.aad) + + + def inc(self): + self.fsn.inc() + if self._skip_parity: + if self.fsn.seq % sdds_header.PARITY_SEQ_NUMBER == 31: + self.fsn.inc() + + if self.fsn == 0: + self.formatid.sos=0 + + ## + ## Format Identifier + ## + def get_complex(self): + return self.formatid.cx + + def set_complex(self, isComplex=False ): + self.formatid.cx=0 + if isComplex: + self.formatid.cx=1 + + def set_dmode(self,dm): + self.formatid.set_dmode(dm) + + def get_dmode(self): + return self.formatid.dm + + def set_spectralsense(self, ison=False ): + self.formatid.ss= 0 + if isone: + self.formatid.ss= 1 + + def get_spectralsense(self): + return self.formatid.ss + + def get_vw(self): + return self.formatid.vw + + def set_vw(self, isVeryWide=False ): + if isVeryWide: + self.formatid.vw = 1 + else: + self.formatid.vw = 0 + + def get_bps(self): + return self.formatid.get_bps() + + def set_bps(self, bps ): + self.formatid.set_bps(bps) + + ## + ## frame sequence + ## + def get_fsn(self): + return self.fsn.get() + + def set_fsn(self, v ): + self.fsn.set(v) + + ## + ## ttag - time tag + ## + def get_msptr( self ): + return self.ttag.info.msptr.get_msptr() + + def set_msptr( self, val ): + self.ttag.info.msptr.set_msptr(val) + + def get_msdelta( self ): + return self.ttag.info.msptr.get_msdelta() + + def set_msdelta( self, val ): + self.ttag.info.msptr.set_msdelta(val) + + def clear_msptr(self): + self.ttag.info.msptr.msptr = 0 + self.ttag.info.msptr.msdelta = 0 + + def set_msv(self, valid=True): + self.ttag.info.info.set_msv(valid) + + def get_msv(self): + return self.ttag.info.info.get_msv() + + def get_ttv(self): + return self.ttag.info.info.get_ttv() + + def set_ttv(self, valid=True): + self.ttag.info.info.set_ttv(valid) + + def get_sscv(self): + return self.ttag.info.info.get_sscv() + + def set_sscv(self, valid=True): + self.ttag.info.info.set_sscv(valid) + + def set_time(self, ps250, pf250 ): + self.ttag.tstamp.ttag = ps250 + self.ttag.tstamp.ttage = pf250 + + def set_SDDSTime(self, sdds_time, ): + self.ttag.tstamp.ttag = sdds_time.picoTicks() + self.ttag.tstamp.ttage = sdds_time.picoTicksFractional() + + def get_SDDSTime(self): + from ossie.utils.sdds import Time + t=Time() + t.set( self.ttag.tstamp.ttag, + self.ttag.tstamp.ttage ) + return t + + + ## + ## ssc - synchronous sample clock + ## + def get_freq(self): + return self.ssc.get_freq() + + def set_freq(self, freq): + self.ssc.set_freq(freq) + + def get_rate(self): + rate = self.get_freq() + if self.get_vw() == 1: + rate *= 16.0 + + if self.get_complex() == 1: + rate *= 0.5 + return rate + + def set_rate(self, rate): + vw=0 + if rate>= 125e6: + vw = 1 + val = val * 0.0625 + self.set_vw(vw) + self.set_freq(freq) + + def get_dfdt(self): + return self.ssc.get_dfdt() + + def set_dfdt(self, freq): + self.ssc.set_dfdt(freq) + + + def asBuffer(self): + return buffer(self)[:] + + def asString(self): + return ctypes.string_at(ctypes.addressof(self),ctypes.sizeof(self)) + + +#################################################################################### +# +# SDDS Payload Containers +# +#################################################################################### + +class sdds_sb_payload(ctypes.BigEndianStructure): + NUM_SAMPLES=1024 + PAYLOAD_SIZE=1024 + _pack_ = 1 + _fields_ = [ ('data', ctypes.c_uint8 *PAYLOAD_SIZE ) ] + + def __new__(cls,buf=None): + if buf: + return cls.from_buffer_copy(buf) + else: + return super(sdds_sb_payload,cls).__new__(cls) + + def __init__(self,data=None): + pass + + def get_data(self): + return self.data[:] + + def set_data(self, samples ): + if type(samples) == list: + for i,x in enumerate(samples): + if i < sdds_sb_payload.NUM_SAMPLES: + self.data[i] = x + else: + fit = min(len(samples), ctypes.sizeof(self)) + ctypes.memmove(ctypes.addressof(self), samples, fit) + + def asBuffer(self): + return buffer(self)[:] + + def asString(self): + return ctypes.string_at(ctypes.addressof(self),ctypes.sizeof(self)) + + +class sdds_cb_payload(ctypes.BigEndianStructure): + NUM_SAMPLES=512 + PAYLOAD_SIZE=1024 + _pack_ = 1 + _fields_ = [ ('data', ctypes.c_uint8 *PAYLOAD_SIZE ) ] + + def __new__(cls,buf=None): + if buf: + return cls.from_buffer_copy(buf) + else: + return super(sdds_cb_payload,cls).__new__(cls) + + def __init__(self,data=None): + pass + + def get_data(self): + return self.data[:] + + def set_data(self, samples ): + if type(samples) == list: + for i,x in enumerate(samples): + if i < sdds_cb_payload.NUM_SAMPLES: + self.data[i] = x + else: + fit = min(len(samples), ctypes.sizeof(self)) + ctypes.memmove(ctypes.addressof(self), samples, fit) + + def asBuffer(self): + return buffer(self)[:] + + def asString(self): + return ctypes.string_at(ctypes.addressof(self),ctypes.sizeof(self)) + + +class sdds_si_payload(ctypes.BigEndianStructure): + NUM_SAMPLES=512 + PAYLOAD_SIZE=512 + _pack_ = 1 + _fields_ = [ ('data', ctypes.c_uint16 * PAYLOAD_SIZE) ] + + def __new__(cls,buf=None): + if buf: + return cls.from_buffer_copy(buf) + else: + return super(sdds_si_payload,cls).__new__(cls) + + def __init__(self,data=None): + pass + + def get_data(self): + return self.data[:] + + def set_data(self, samples ): + if type(samples) == list: + for i,x in enumerate(samples): + if i < sdds_si_payload.NUM_SAMPLES: + self.data[i] = x + else: + fit = min(len(samples), ctypes.sizeof(self)) + ctypes.memmove(ctypes.addressof(self), samples, fit) + + def asBuffer(self): + return buffer(self)[:] + + def asString(self): + return ctypes.string_at(ctypes.addressof(self),ctypes.sizeof(self)) + +class sdds_ci_payload(ctypes.BigEndianStructure): + NUM_SAMPLES=256 + PAYLOAD_SIZE=512 + _pack_ = 1 + _fields_ = [ ('data', ctypes.c_uint16 * PAYLOAD_SIZE) ] + + def __new__(cls,buf=None): + if buf: + return cls.from_buffer_copy(buf) + else: + return super(sdds_ci_payload,cls).__new__(cls) + + def __init__(self,data=None): + pass + + def get_data(self): + return self.data[:] + + def set_data(self, samples ): + if type(samples) == list: + for i,x in enumerate(samples): + if i < sdds_ci_payload.NUM_SAMPLES: + self.data[i] = x + else: + fit = min(len(samples), ctypes.sizeof(self)) + ctypes.memmove(ctypes.addressof(self), samples, fit) + + def asBuffer(self): + return buffer(self)[:] + + def asString(self): + return ctypes.string_at(ctypes.addressof(self),ctypes.sizeof(self)) + +class sdds_sn_sample(ctypes.BigEndianStructure): + _pack_ = 1 + _fields_ = [ ('sn2', ctypes.c_uint8,4 ), + ('sn1', ctypes.c_uint8,4 ) + ] + + def __new__(cls,buf=None): + if buf: + return cls.from_buffer_copy(buf) + else: + return super(sdds_sn_sample,cls).__new__(cls) + + def __init__(self,data=None): + pass + + def get_data(self): + return [ self.sn1, self.sn2 ] + + def asBuffer(self): + return buffer(self)[:] + + def asString(self): + return ctypes.string_at(ctypes.addressof(self),ctypes.sizeof(self)) + +class sdds_sn_payload(ctypes.Structure): + NUM_SAMPLES=2048 + PAYLOAD_SIZE=1024 + _pack_ = 1 + _fields_ = [ ('data', sdds_sn_sample*PAYLOAD_SIZE) ] + + def __new__(cls,buf=None): + if buf: + return cls.from_buffer_copy(buf) + else: + return super(sdds_sn_payload,cls).__new__(cls) + + def __init__(self,data=None): + pass + + def get_data(self): + _ret=[] + for x in self.data[:]: + _ret += x.get_data() + return _ret + + def set_data(self, samples ): + if type(samples) == list: + for i,x in enumerate(samples): + if i < sdds_sn_payload.NUM_SAMPLES: + self.data[i] = x + else: + fit = min(len(samples), ctypes.sizeof(self)) + ctypes.memmove(ctypes.addressof(self), samples, fit) + + def asBuffer(self): + return buffer(self)[:] + + def asString(self): + return ctypes.string_at(ctypes.addressof(self),ctypes.sizeof(self)) + +class sdds_sf_payload(ctypes.BigEndianStructure): + NUM_SAMPLES=256 + PAYLOAD_SIZE=256 + _pack_ = 1 + _fields_ = [ ('data', ctypes.c_float * PAYLOAD_SIZE ) ] + + def __new__(cls,buf=None): + if buf: + return cls.from_buffer_copy(buf) + else: + return super(sdds_sf_payload,cls).__new__(cls) + + def __init__(self,data=None): + pass + + def get_data(self): + return self.data[:] + + def set_data(self, samples ): + if type(samples) == list: + for i,x in enumerate(samples): + if i < sdds_sf_payload.NUM_SAMPLES: + self.data[i] = x + else: + fit = min(len(samples), ctypes.sizeof(self)) + ctypes.memmove(ctypes.addressof(self), samples, fit) + + def asBuffer(self): + return buffer(self)[:] + + def asString(self): + return ctypes.string_at(ctypes.addressof(self),ctypes.sizeof(self)) + +class sdds_payload(ctypes.Union): + PAYLOAD_SIZE=1024 + _pack_ = 1 + _fields_ = [ ('raw', ctypes.c_uint8 *PAYLOAD_SIZE ), + ('sn', sdds_sn_payload ), + ('sb', sdds_sb_payload ), + ('cb', sdds_sb_payload ), + ('si', sdds_si_payload ), + ('ci', sdds_si_payload ), + ('sf', sdds_sf_payload ) + ] + + def __new__(cls,buf=None): + if buf: + return cls.from_buffer_copy(buf) + else: + return super(sdds_payload_struct,cls).__new__(cls) + + def __init__(self,data=None): + pass + + def __str__(self): + return ','.join( [ str(x) for x in self.raw[:40] ] ) + + def get_data(self): + return self.raw[:] + + def asBuffer(self): + return buffer(self)[:] + + def asString(self): + return ctypes.string_at(ctypes.addressof(self),ctypes.sizeof(self)) + + +class sdds_packet(ctypes.Structure): + FORMATS = { + 'SN' : { 'dmode': 0, 'bps': 4, 'cplx': 0, 'samples': 2048, 'get_data': sdds_sn_payload.get_data }, + 'SB' : { 'dmode': 1, 'bps': 8, 'cplx': 0, 'samples': 1024, 'get_data': sdds_sb_payload.get_data }, + 'CB' : { 'dmode': 1, 'bps': 8, 'cplx': 1, 'samples': 512, 'get_data': sdds_cb_payload.get_data}, + 'SI' : { 'dmode': 2, 'bps': 16, 'cplx': 0, 'samples': 512, 'get_data': sdds_si_payload.get_data}, + 'CI' : { 'dmode': 2, 'bps': 16, 'cplx': 1, 'samples': 256, 'get_data': sdds_ci_payload.get_data}, + 'SF' : { 'dmode': 7, 'bps': 32, 'cplx': 0, 'samples': 256, 'get_data': sdds_sf_payload.get_data}, + 'AD4' : { 'dmode': 5, 'bps': 8, 'cplx': 0, 'samples': 1024, 'get_data': sdds_sb_payload.get_data}, + 'AD12' : { 'dmode': 6, 'bps': 16, 'cplx': 0, 'samples': 512, 'get_data': sdds_si_payload.get_data}, + } + PKT_LEN=1080 + HEADER_LEN=56 + PAYLOAD_LEN=1024 + _pack_ = 1 + _fields_ = [ ('header', sdds_header ), + ('payload', sdds_payload ) + ] + + def __new__(cls,buf=None): + if buf: + return cls.from_buffer_copy(buf) + else: + return super(sdds_packet,cls).__new__(cls) + + def __init__(self,data=None, skip_parity=True): + self._skip_parity=skip_parity + pass + + def __str__(self): + return ''.join(str(self.header)) + '\n' +\ + ' payload: '+ ''.join(str(self.payload)) + + def inc(self): + self.header.inc() + + ## + ## Format Identifier + ## + def get_complex(self): + return self.header.get_complex() + + def set_complex(self, isComplex=False ): + self.header.set_complex(isComplex) + + def set_spectralsense(self, ison=False ): + self.header.set_spectralsense(ison) + + def get_spectralsense(self, ison=False ): + return self.header.get_spectralsense() + + def get_vw(self): + return self.header.get_vw() + + def set_vw(self, isVeryWide=False ): + self.header.set_vw( isVeryWide ) + + def get_bps(self): + return self.header.get_bps() + + def set_bps(self, bps ): + self.header.set_bps(bps) + + def set_dmode(self,dm, cplx=False, calc_bps=True, bps=None): + if self.ok_dmode(dm): + self.header.set_dmode(dm) + self.header.set_complex(cplx) + if calc_bps or bps==None: + self.header.set_bps( self.get_bps_for_mode(dm) ) + else: + self.header.set_bps(bps) + + def ok_dmode(self, dmode ): + return dmode == 0 or dmode == 1 or dmode == 2 or dmode == 5 or dmode == 6 or dmode == 7; + + def get_dmode(self): + return self.header.get_dmode() + + def get_bps_for_mode(self, dmode ): + bps=8 + if dmode == 0: + bps=4 + if dmode == 1 or dmode == 5: + bps=8 + if dmode == 2 or dmode == 6: + bps=16 + if dmode == 7: bps=32 + return bps + + ## + ## frame sequence + ## + def get_fsn(self): + return self.header.get_fsn() + + def set_fsn(self, v ): + self.header.set_fsn(v) + + ## + ## ttag - time tag + ## + def get_msptr( self ): + return self.header.get_msptr() + + def set_msptr( self, val ): + self.header.set_msptr(val) + + def clear_msptr( self): + self.header.clear_msptr() + + def get_msdelta( self ): + self.header.get_msdelta() + + def set_msdelta( self, val ): + self.header.set_msdelta(val) + + def set_msv(self, valid=True): + self.header.set_msv(valid) + + def get_msv(self): + self.header.get_msv() + + def get_ttv(self): + self.header.get_ttv() + + def set_ttv(self, valid=True): + self.header.set_ttv(valid) + + def get_sscv(self): + self.header.get_sscv() + + def set_sscv(self, valid=True): + self.header.set_sscv(valid) + + def set_time(self, ps250, pf250 ): + self.header.set_time(ps250, pf250) + + def set_SDDSTime(self, sdds_time, ): + self.header.set_SDDSTime(sdds_time) + + def get_SDDSTime(self): + return self.header.get_SDDSTime() + + ## + ## ssc - synchronous sample clock + ## + def get_freq(self): + return self.header.get_freq() + + def set_freq(self, freq): + self.header.set_freq(freq) + + def get_rate(self): + return self.header.get_rate() + + def set_rate(self, freq): + self.header.set_rate(freq) + + def get_dfdt(self): + return self.header.get_dfdt() + + def set_dfdt(self, freq): + self.freq.set_dfdt(freq) + + def get_format(self): + dm=self.header.get_dmode() + fmt='SB' + for k, v in sdds_packet.FORMATS.items(): + if v['dmode'] == dm : + fmt=k + return fmt + + def set_format(self, fmt): + ret=1 + if fmt in sdds_packet.FORMATS.keys(): + _fmt = sdds_packet.FORMATS[fmt] + ret=0 + cplx = _fmt['cplx'] + dm = _fmt['dmode'] + self.set_dmode( dm, cplx, bps=_fmt['bps']) + + + def get_data(self): + bps=self.header.get_bps() + for k, v in sdds_packet.FORMATS.items(): + if v['bps'] == bps : + attr = getattr(self.payload, k.lower()) + return v['get_data'](attr) + return self.payload.sb.get_data() + + def asBuffer(self): + return buffer(self)[:] + + def asString(self): + return ctypes.string_at(ctypes.addressof(self),ctypes.sizeof(self)) diff --git a/redhawk/src/base/framework/python/ossie/utils/sdds/sdds_time.py b/redhawk/src/base/framework/python/ossie/utils/sdds/sdds_time.py new file mode 100644 index 000000000..54c3b8c08 --- /dev/null +++ b/redhawk/src/base/framework/python/ossie/utils/sdds/sdds_time.py @@ -0,0 +1,157 @@ +# +# This file is protected by Copyright. Please refer to the COPYRIGHT file +# distributed with this source distribution. +# +# This file is part of REDHAWK rh.SourceSDDS. +# +# REDHAWK rh.SourceSDDS is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation, either version 3 of the License, or (at your option) any +# later version. +# +# REDHAWK rh.SourceSDDS is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +# details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/. +# +import time +import datetime +import calendar +import struct +import math +import copy as _copy + +def difference(t1, t2): + tmp = _copy.copy(t1) + if tmp.pf250_ >= t2.pf250_ : + tmp.pf250_ -= t2.pf250_ + tmp.ps250_ -= t2.ps250_ + else: + tmp.pf250_ = Time.Two32 + ( tmp.pf250_ - t2.pf250_ ) + tmp.ps250_ -= t2.ps250_ + 1; + +def sum( t1, t2 ): + tmp=_copy.copy(t1) + tfrac =long(tmp.pf250_) + t2.pf250_ + tmp.ps250_ += t2.ps250_ + int(tfrac>>32) + tmp.pf250_ = int(tfrac) + return tmp + +def add(t1, offset): + if isinstance(offset, Time): + return sum(t1, offset) + else: + return iadd(t1, offset) + +def iadd(t1, offset): + if not isinstance(t1, Time): + return t1 + tmp=_copy.copy(t1) + # make into tics + pfrac,pwhole = math.modf(offset*Time.TicFreq) + tfrac = long(tmp.pf250_) + int(pfrac * Time.Two32) + tmp.ps250_ += long(pwhole) + (tfrac>>32) + tmp.pf250_ = int(tfrac) + return tmp + +def sub(t1, other): + if isinstance(other, Time): + return difference(t1, other) + else: + return isub(t1, other) + +def isub(t1, offset): + return iadd(t1, -offset) + +def compare(t1, t2): + if not isinstance(t1, Time) or not isinstance(t2, Time): + return -1 + if t1.ps250_ == t2.ps250_: + return cmp(t1.pf250_,t2.pf250_) + else: + return cmp(t1.ps250_,t2.ps250_) + +class Time: + REDHAWK_FORMAT="%Y:%m:%d::%H:%M:%S" + Tic = 250e-12 + TicFreq = 4000000000.0 + TicFreqLong = 4000000000L + Two32 = 4294967296.0 + def __init__(self ): + + self.ps250_ = 0L + self.pf250_ = 0 + self.startofyear = self.startOfYear() + self.setFromTime() + + def setFromTime(self, time_sec=time.time() ): + """ + Create a sdds time object from the input parameter. If the time_sec is from the epoch + then we need to convert to the current year as per spec. + """ + if time_sec: + if time_sec >= self.startofyear: + # UTC.. need to convert to SDDS EPOCH + time_sec = time_sec - self.startofyear + + pfrac, pwhole = math.modf(time_sec*Time.TicFreq) + self.ps250_ = long(pwhole) + self.pf250_ = int( pfrac*Time.Two32) + #print "td: %12Lu %12u %16.2Lf " % ( self.ps250_, self.pf250_, pfrac ) + + def setFromPartial( self, integral, fractional ): + pfrac, pwhole= math.modf(fractional*Time.TicFreq) + self.ps250_ = long(integral*Time.TicFreqLong) + long(pwhole) + self.pf250_ = int( pfrac * Time.Two32) + #print "td: %12Lu %12u %16.2Lf " % ( self.ps250_, self.pf250_, pfrac ) + + def set( self, psec, pfsec ): + self.ps250_ = psec + self.pf250_ = pfsec + #print "td: %12Lu %12u " % ( self.ps250_, self.pf250_ ) + + def secondsThisYear( self ): + return self.ps250_*Time.Tic + self.pf250_ * (Time.Tic/Time.Two32) + + def seconds( self ): + return self.startofyear + self.secondsThisYear() + + def picoTicks( self ): + return self.ps250_ + + def picoTicksFractional( self ): + return self.pf250_ + + def gmtime( self): + return time.gmtime(self.startofyear+self.secondsThisYear()) + + @staticmethod + def toString(t1, fmt=None): + gmt = t1.gmtime() + frac = int(t1.pf250_ * (Time.Tic/Time.Two32)) + if not fmt: + fmt = Time.REDHAWK_FORMAT + xx=time.strftime(fmt,gmt) + return '%s.%06d' % (xx,frac) + else: + return time.strftime(fmt,gmt) + + def __str__(self): + return toString(self) + + + @staticmethod + def startOfYear(): + soy=datetime.datetime(datetime.date.today().year,1,1,0,0,0) + return calendar.timegm(soy.timetuple()) + +Time.__add__ = add +Time.__iadd__ = iadd +Time.__sub__ = sub +Time.__isub__ = isub +Time.__isub__ = isub +Time.__cmp__ = compare +Time.__str__ = Time.toString diff --git a/redhawk/src/testing/tests/test_13_SDDS.py b/redhawk/src/testing/tests/test_13_SDDS.py new file mode 100644 index 000000000..75c287906 --- /dev/null +++ b/redhawk/src/testing/tests/test_13_SDDS.py @@ -0,0 +1,374 @@ +#!/usr/bin/env python +# +# This file is protected by Copyright. Please refer to the COPYRIGHT file +# distributed with this source distribution. +# +# This file is part of REDHAWK core. +# +# REDHAWK core is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation, either version 3 of the License, or (at your option) any +# later version. +# +# REDHAWK core is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +# details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/. +# + +import unittest +import os +import sys +import time +import calendar +import contextlib +import cStringIO +import binascii +import struct +import re + +from ossie.utils.sdds import * + +@contextlib.contextmanager +def stdout_redirect(where): + sys.stdout = where + try: + yield where + finally: + sys.stdout = sys.__stdout__ + +class Test_SDDS_Time(unittest.TestCase): + + def setUp(self): + self.tfile = os.tmpfile() + self.cur_year = datetime.date.today().year + self.cur_year_str = str(self.cur_year) + + def _run_test(self, fmt_key): + conv=conversions[fmt_key] + config.strConfig(logcfg+conv[0]) + self.logger=logging.getLogger('') + self.console=self.logger.handlers[0] + self.console.stream=self.tfile + + pval=time.strftime(conv[1]) + + # + self.logger.info('test1') + self.tfile.seek(0) + logline=self.tfile.read() + logline=logline.strip() + if len(conv) > 2: + logline = logline.split(conv[2])[0] + pval = pval.split(conv[2])[0] + self.assertEquals( pval, logline) + + + def test_startofyear(self): + sdds_soy = Time.startOfYear() + + # calculate start of year + soy = datetime.datetime(*(time.strptime(self.cur_year_str+"-01-01 00:00:00", + "%Y-%m-%d %H:%M:%S")[0:6])) + soy_time=calendar.timegm(soy.timetuple()) + self.assertEqual( sdds_soy, soy_time ) + + sdds_time = Time() + sdds_time.setFromTime(soy_time) + # calculate start of year + self.assertEqual( sdds_time.gmtime(), time.gmtime(soy_time) ) + + + def test_init(self): + tod=time.time() + sdds_time = Time() + sdds_time.setFromTime(tod) + + # test current time of day + self.assertEqual( sdds_time.seconds(), tod ) + + # test current time of day struct + self.assertEqual( sdds_time.gmtime(), time.gmtime(tod)) + + # set parts + sdds_time.set( 1234, 5678 ) + self.assertEqual( sdds_time.picoTicks(), 1234 ) + self.assertEqual( sdds_time.picoTicksFractional(), 5678 ) + + # set partial + sdds_time.setFromPartial( 4, .001 ) + self.assertEqual( sdds_time.picoTicks(), (4000000000*4) + long(4000000000*0.001) ) + self.assertEqual( sdds_time.picoTicksFractional(), 0 ) + + + def test_add(self): + soy = Time.startOfYear() + + sdds_time = Time() + sdds_time.setFromTime(soy) + + # add 1 second + sdds_time = sdds_time + 1 + sdds_time_str = str(sdds_time) + + # calculate start of year + match_soy_str = self.cur_year_str+":01:01::00:00:01.000000" + self.assertEqual( sdds_time_str, match_soy_str ) + + # add 59 second + sdds_time = sdds_time + 59 + sdds_time_str = str(sdds_time) + + # + match_soy_str = self.cur_year_str+":01:01::00:01:00.000000" + self.assertEqual( sdds_time_str, match_soy_str ) + + # add 2 minutes + sdds_time = sdds_time + 120 + sdds_time_str = str(sdds_time) + + # + match_soy_str = self.cur_year_str+":01:01::00:03:00.000000" + self.assertEqual( sdds_time_str, match_soy_str ) + + # add 2 hours + sdds_time = sdds_time + (60*60*2) + sdds_time_str = str(sdds_time) + + # + match_soy_str = self.cur_year_str+":01:01::02:03:00.000000" + self.assertEqual( sdds_time_str, match_soy_str ) + + + def test_subtract(self): + soy = Time.startOfYear() + + sdds_time = Time() + sdds_time.setFromTime(soy) + + # add 2 hours + sdds_time = sdds_time + (60*60*2) + sdds_time_str = str(sdds_time) + + # set match + match_soy_str = self.cur_year_str+":01:01::02:00:00.000000" + self.assertEqual( sdds_time_str, match_soy_str ) + + # subtract 10 seconds + sdds_time = sdds_time -10 + sdds_time_str = str(sdds_time) + + # set match + match_soy_str = self.cur_year_str+":01:01::01:59:50.000000" + self.assertEqual( sdds_time_str, match_soy_str ) + + # subtract 9 minutes + sdds_time = sdds_time -(9*60) + sdds_time_str = str(sdds_time) + + # set match + match_soy_str = self.cur_year_str+":01:01::01:50:50.000000" + self.assertEqual( sdds_time_str, match_soy_str ) + + + +class Test_SDDS_Packet(unittest.TestCase): + + def setUp(self): + self.tfile = os.tmpfile() + self.cur_year = datetime.date.today().year + self.cur_year_str = str(self.cur_year) + + + def test_format_identifier_api(self): + + # get default format identifer.. sf=1, sos=1, dm=1 bps=8 all others 0 + res=binascii.unhexlify('2340') + formatid = format_identifier() + self.assertEqual( formatid.asString(), res ) + + # assign from values sf=1, sos=1, dm =4, bps=16 + formatid= format_identifier.from_buffer_copy('\x83\x80') + self.assertEqual( formatid.sf, 1 ) + self.assertEqual( formatid.sos, 1 ) + self.assertEqual( formatid.dm, 4 ) + self.assertEqual( formatid.bps, 16 ) + + # assign 32 bit value and get back + formatid= format_identifier() + formatid.set_bps(32) + self.assertEqual( formatid.bps, 31 ) + res=formatid.get_bps() + self.assertEqual( res, 32 ) + + # assign data mode... + formatid.set_dmode( [ 1,1,1 ] ) + self.assertEqual( formatid.dm, 7 ) + + formatid.set_dmode( 5 ) + self.assertEqual( formatid.dm, 5 ) + + + def test_frame_sequence(self): + + # get default frame sequence == 0 + res=binascii.unhexlify('0000') + fsn = frame_sequence() + self.assertEqual( fsn.asString(), res ) + + # test big endian format for number + seq=256 + res=struct.pack("!H",seq) + fsn.seq = seq + self.assertEqual( fsn.asString(), res ) + + # add one... + fsn.inc() + seq +=1 + res=struct.pack("!H",seq) + self.assertEqual( fsn.asString(), res ) + + # set for rollover + seq =65535 + fsn.seq = seq + res=struct.pack("!H",seq) + self.assertEqual( fsn.asString(), res ) + + # set for rollover + fsn.inc() + res=struct.pack("!H",0) + self.assertEqual( fsn.asString(), res ) + + def test_msptr_data(self): + + # get default frame sequence == 0 + msptr_=0 + msdelta_=0 + res=struct.pack("!HH",msptr_, msdelta_) + msptr = msptr_data() + self.assertEqual( msptr.asString(), res ) + + # test big endian format for number + msptr_=256 + msdelta_=256 + res=struct.pack("!HH",msptr_, msdelta_) + msptr.msptr=msptr_ + msptr.msdelta=msdelta_ + self.assertEqual( msptr.asString(), res ) + + # set max value + msptr_=2047 + msdelta_=65535 + res=struct.pack("!HH",msptr_, msdelta_) + msptr.msptr=msptr_ + msptr.msdelta=msdelta_ + self.assertEqual( msptr.asString(), res ) + + def test_ttag_info_struct(self): + + # get default + res=binascii.unhexlify('00000000') + ttag_info = ttag_info_struct() + self.assertEqual( ttag_info.asString(), res ) + + # test msv + res=binascii.unhexlify('00800000') + ttag_info.set_msv() + self.assertEqual( ttag_info.asString(), res ) + + res=binascii.unhexlify('00000000') + ttag_info.set_msv(False) + self.assertEqual( ttag_info.asString(), res ) + + # test ttv + res=binascii.unhexlify('00400000') + ttag_info.set_ttv() + self.assertEqual( ttag_info.asString(), res ) + + res=binascii.unhexlify('00000000') + ttag_info.set_ttv(False) + self.assertEqual( ttag_info.asString(), res ) + + # test sscv + res=binascii.unhexlify('0000000') + ttag_info.set_sscv() + self.assertEqual( ttag_info.asString(), res ) + + res=binascii.unhexlify('00000000') + ttag_info.set_sscv(False) + self.assertEqual( ttag_info.asString(), res ) + + # test pi + res=binascii.unhexlify('08000000') + ttag_info.set_pi() + self.assertEqual( ttag_info.asString(), res ) + + res=binascii.unhexlify('00000000') + ttag_info.set_pi(False) + self.assertEqual( ttag_info.asString(), res ) + + # test peo + res=binascii.unhexlify('10000000') + ttag_info.set_peo(True) + self.assertEqual( ttag_info.asString(), res ) + + res=binascii.unhexlify('00000000') + ttag_info.set_peo(False) + self.assertEqual( ttag_info.asString(), res ) + + def test_ttag_values(self): + ttag_=0 + ttage_=0 + res=struct.pack("!QI", ttag_, ttage_) + ttag_val = ttag_values() + self.assertEqual( ttag_val.asString(), res ) + + # test big endian format for number + ttag_= 4294967296 + ttage_= 8388608 + res=struct.pack("!QI", ttag_, ttage_) + ttag_val.ttag=ttag_ + ttag_val.ttage=ttage_ + self.assertEqual( ttag_val.asString(), res ) + + def test_ttag_info(self): + msptr_=0 + msdelta_=0 + ttag_=0 + ttage_=0 + res=struct.pack("!HHQI", msptr_, msdelta_, ttag_, ttage_) + ttag_val = ttag_info() + self.assertEqual( ttag_val.asString(), res ) + + # test big endian format for number + ttag_= 4294967296 + ttage_= 8388608 + msptr_=256 + msdelta_=256 + res=struct.pack("!HHQI", msptr_, msdelta_, ttag_, ttage_) + ttag_val.info.msptr.msptr=msptr_ + ttag_val.info.msptr.msdelta=msdelta_ + ttag_val.tstamp.ttag=ttag_ + ttag_val.tstamp.ttage=ttage_ + self.assertEqual( ttag_val.asString(), res ) + + ttag_val = ttag_info() + ttag_= 4294967296 + ttage_= 8388608 + msptr_=2047 + msdelta_=256 + ttag_val.tstamp.ttag=ttag_ + ttag_val.tstamp.ttage=ttage_ + ttag_val.info.msptr.msptr=msptr_ + ttag_val.info.msptr.msdelta=msdelta_ + ttag_val.info.info.set_msv() + ttag_val.info.info.set_ttv() + ttag_val.info.info.set_sscv() + res=struct.pack("!QI", ttag_, ttage_) + tinfo=binascii.unhexlify('07370100') + res=tinfo+res + self.assertEqual( ttag_val.asString(), res ) + From ad428d5e330afa383a0748a6ac544380211b3a0c Mon Sep 17 00:00:00 2001 From: 8530 <8530@vm-131.vsi-corp.com> Date: Mon, 1 May 2017 13:12:10 -0400 Subject: [PATCH 0784/1644] initial sdds data capture and packet parser using ctypes and structs to parser incoming packet definitions, (added missing files) --- .../python/ossie/utils/model/__init__.py | 8 +- .../python/ossie/utils/prop_helpers.py | 49 +++++++----- .../python/ossie/utils/sb/io_helpers.py | 79 ++++++++++++++++++- 3 files changed, 112 insertions(+), 24 deletions(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/model/__init__.py b/redhawk/src/base/framework/python/ossie/utils/model/__init__.py index a18f70892..e3b0f6113 100644 --- a/redhawk/src/base/framework/python/ossie/utils/model/__init__.py +++ b/redhawk/src/base/framework/python/ossie/utils/model/__init__.py @@ -1121,7 +1121,7 @@ def _getPropertySet(self, \ defValue = _convertType(propType, val) id_clean = _prop_helpers._cleanId(prop) # Add individual property - id_clean = _prop_helpers.addCleanName(id_clean, prop.get_id(), _displayNames, _duplicateNames) + id_clean = _prop_helpers.addCleanName(id_clean, prop.get_id(), _displayNames, _duplicateNames, namesp=structProp.get_id()) members.append((prop.get_id(), propType, defValue, id_clean)) structDefValue[prop.get_id()] = defValue for prop in structProp.get_simplesequence(): @@ -1133,7 +1133,7 @@ def _getPropertySet(self, \ defValue = None id_clean = _prop_helpers._cleanId(prop) # Add individual property - id_clean = _prop_helpers.addCleanName(id_clean, prop.get_id(), _displayNames, _duplicateNames) + id_clean = _prop_helpers.addCleanName(id_clean, prop.get_id(), _displayNames, _duplicateNames, namesp=structProp.get_id()) members.append((prop.get_id(), propType, defValue, id_clean)) structDefValue[prop.get_id()] = defValue @@ -1174,7 +1174,7 @@ def _getPropertySet(self, \ id_clean = _prop_helpers._cleanId(prp) # Add struct member members.append((prp.get_id(), propType, defValue, id_clean)) - _prop_helpers.addCleanName(id_clean, prp.get_id(), _displayNames, _duplicateNames) + _prop_helpers.addCleanName(id_clean, prp.get_id(), _displayNames, _duplicateNames, namesp=prop.get_id()) for prp in prop.get_struct().get_simplesequence(): propType = self._getPropType(prp) vals = prp.get_values() @@ -1185,7 +1185,7 @@ def _getPropertySet(self, \ id_clean = _prop_helpers._cleanId(prp) # Adds struct member members.append((prp.get_id(), propType, defValue, id_clean)) - _prop_helpers.addCleanName(id_clean, prp.get_id(), _displayNames, _duplicateNames) + _prop_helpers.addCleanName(id_clean, prp.get_id(), _displayNames, _duplicateNames, namesp=prop.get_id()) structSeqDefValue = None structValues = prop.get_structvalue() diff --git a/redhawk/src/base/framework/python/ossie/utils/prop_helpers.py b/redhawk/src/base/framework/python/ossie/utils/prop_helpers.py index d6b06a175..2b4f2f404 100644 --- a/redhawk/src/base/framework/python/ossie/utils/prop_helpers.py +++ b/redhawk/src/base/framework/python/ossie/utils/prop_helpers.py @@ -243,18 +243,23 @@ def getPropNameDict(prf): -Prevents duplicate entries within a component -Allows for get/set on components with invalid chars in ID ''' -def addCleanName(cleanName, id, _displayNames, _duplicateNames): +def addCleanName(cleanName, id, _displayNames, _duplicateNames, namesp=None): + retval=cleanName if not _displayNames.has_key(cleanName): _displayNames[cleanName] = id - _duplicateNames[cleanName] = 0 - return cleanName - elif _displayNames[cleanName] == id: - return cleanName - else: - count = _duplicateNames[cleanName] + 1 - _displayNames[cleanName + str(count)] = id - _duplicateNames[cleanName] = count - return cleanName + str(count) + # maintain a count of clean name for each namespace context + _duplicateNames[cleanName] = { namesp : 0 } + return retval + elif _displayNames[cleanName] != id: + if namesp in _duplicateNames[cleanName]: + count = _duplicateNames[cleanName][namespace] + 1 + _displayNames[cleanName + str(count)] = id + _duplicateNames[cleanName][namespace] = count + retval=cleanName + str(count) + else: + _duplicateNames[cleanName][namesp] = 0 + retval = cleanName + return retval def _cleanId(prop): translation = 48*"_"+_string.digits+7*"_"+_string.ascii_uppercase+6*"_"+_string.ascii_lowercase+133*"_" @@ -368,11 +373,14 @@ def _getStructsSimpleProps(self,simple,prop): if i.clean_name == prop.id_: for k in prop.get_configurationkind(): kinds.append(k.get_kindtype()) - if i.members[_cleanId(simple)]._enums != None: - enums = i.members[_cleanId(simple)]._enums + mname = _cleanId(simple) + if mname in i._memberNames: + mname = i._memberNames[mname] + if i.members[mname]._enums != None: + enums = i.members[mname]._enums if self.mode != "writeonly": - value = str(i.members[_cleanId(simple)]) - defVal = str(i.members[_cleanId(simple)].defValue) + value = str(i.members[mname]) + defVal = str(i.members[mname].defValue) type = str(self.compRef._getPropType(simple)) return defVal, value, type, kinds, enums @@ -385,12 +393,15 @@ def _getStructsSimpleSeqProps(self, sprop, prop): if i.clean_name == prop.id_: for k in prop.get_configurationkind(): kinds.append(k.get_kindtype()) - if i.members[_cleanId(sprop)].__dict__.has_key("_enums"): - if i.members[_cleanId(sprop)]._enums != None: - enums = i.members[_cleanId(sprop)]._enums + cname = _cleanId(sprop) + if cname in i._memberNames: + cname = i._memberNames[cname] + if i.members[cname].__dict__.has_key("_enums"): + if i.members[cname]._enums != None: + enums = i.members[cname]._enums if self.mode != "writeonly": - values = i.members[_cleanId(sprop)] - defVal = i.members[_cleanId(sprop)].defValue + values = i.members[cname] + defVal = i.members[cname].defValue type = str(self.compRef._getPropType(sprop)) return defVal, values, type, kinds, enums diff --git a/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py b/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py index 7a57face1..3e3a089b4 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py +++ b/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py @@ -1102,6 +1102,9 @@ def __init__(self): """ _SourceBase.__init__(self, bytesPerPush = 0, dataFormat='sdds', formats=['sdds']) self._src = _bulkio_data_helpers.SDDSSource() + self._blocking = True + self._streamdefs = {} + def attach(self, streamData=None, name=None): """ streamData: type BULKIO.SDDSStreamDefinition @@ -1122,6 +1125,8 @@ def attach(self, streamData=None, name=None): if not isinstance(name, str): raise Exception("name must be of ") retval = self._src.attach(streamData, name) + if retval: + self._streamdefs[name] = streamData return retval def detach(self, attachId=''): @@ -1132,10 +1137,80 @@ def detach(self, attachId=''): if not isinstance(attachId, str): raise Exception("attachId must be of ") self._src.detach(attachId) + try: + self._streamdefs.pop(attachid,None) + except: + pass def _createArraySrcInst(self, srcPortType): return self._src + def grabStreamDef( self, name=None, pkts=1000, block=True ): + # grab data if stream definition is available + sdef =None + aid=name + if not aid: + if len(self._streamdefs) == 0: + raise Exception("No attachment have been made, use grabData or call attach") + + aid = self._streamdefs.keys()[0] + print "Defaults to first entry, attach id = ", aid + sdef = self._streamdefs[aid] + else: + sdef = sefl._streamdefs[aid] + + if not sdef: + raise Exception("No SDDS stream definition for attach id:" + aid ) + + return self.grabData( sdef.multicastAddress, sdef.port, sdef.vlan, packets, block=block) + + + def grabData( self, mgroup, hostip, port=29495, vlan=0, pkts=1000, pktlen=1080, sdds=True, block=True ): + totalRead=0.0 + startTime = _time.time() + sock = None + ismulticast=False + blen=10240 + bytesRead=0 + requestedBytes=pkts*pktlen + data=None + rawdata='' + try: + try: + ip_class=int(mgroup.split('.')[0]) + if ip_class == '224' or ip_class == '239': + ismulticast=True + except: + pass + + print " mgroup ", mgroup, " host ", hostip, " port ", port + sock = _socket.socket(_socket.AF_INET, _socket.SOCK_DGRAM, _socket.IPPROTO_UDP) + sock.setsockopt(_socket.SOL_SOCKET, _socket.SO_REUSEADDR, 1) + print "Port ", port + sock.bind(("",port)) + if ismulticast: + mreq=struct.pack('4s4s',_socket.inet_aton(mgroup),_socket.inet_aton(hostip)) + sock.setsockopt(_socket.IPPROTO_IP, _socket.IP_ADD_MEMBERSHIP, mreq) + print "Capturing Socket Interface: (MULTICAST) Host Interface: " + hostip + " Multicast: " + mgroup + " Port: "+ str(port) + else: + print "Capturing Socket Interface: (UDP) Host Interface: " + hostip + " Source Address: " + mgroup + " Port: "+ str(port) + while bytesRead < requestedBytes: + rcvddata = sock.recv(blen,_socket.MSG_WAITALL) + rawdata=rawdata+rcvdata + data=data+list(rcvddata) + totalRead = totalRead + len(rcvddata) + except KeyboardInterrupt,e : + print "Exception during packet capture: " + str(e) + except Exception, e : + print "Exception during packet capture: " + str(e) + finally: + endTime=_time.time() + deltaTime=endTime -startTime + if sock: sock.close() + print "Elapsed Time: ", deltaTime, " Total Data (kB): ", totalRead/1000.0, " Rate (kBps): ", (totalRead/1000.0)/deltaTime + return data, rawdata, (pktlen,pkts,totalRead) + + class DataSource(_SourceBase): def __init__(self, data = None, @@ -1435,6 +1510,7 @@ def pushThread(self): candidateSri.keywords = keywords if self._sri==None or not compareSRI(candidateSri, self._sri): + print "New SRI ", candidateSri, " mode = ", candidateSri.mode self._sri = _copy.copy(candidateSri) self._pushSRIAllConnectedPorts(sri = self._sri) @@ -1568,6 +1644,7 @@ def _pushPacket(self, int(currentSampleTime), currentSampleTime - int(currentSampleTime)) if srcPortType != "_BULKIO__POA.dataXML": + print "Pushing DATA ", len(data) , " ============================== " _bulkio_data_helpers.ArraySource.pushPacket(arraySrcInst, data = data, T = T, @@ -1587,7 +1664,7 @@ def _pushSRIAllConnectedPorts(self, sri): def _pushSRI(self, arraySrcInst, srcPortType, sri): if srcPortType != "_BULKIO__POA.dataXML": - #print "_pushSRI ", sri + print "_pushSRI ", sri, " mode ", sri.mode _bulkio_data_helpers.ArraySource.pushSRI(arraySrcInst, sri) else: _bulkio_data_helpers.XmlArraySource.pushSRI(arraySrcInst, sri) From c733efa35c0d63037b85471a03cfd01d0de7fa54 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Mon, 1 May 2017 15:10:42 -0400 Subject: [PATCH 0785/1644] Refs CF-323. Added pager to the Python sandbox api function --- .../python/ossie/utils/formatting.py | 8 +++ .../python/ossie/utils/model/__init__.py | 72 ++++++++++++++----- .../python/ossie/utils/prop_helpers.py | 43 ++++++----- .../python/ossie/utils/redhawk/component.py | 19 +++-- .../python/ossie/utils/redhawk/core.py | 32 ++++++--- .../python/ossie/utils/redhawk/device.py | 18 +++-- .../python/ossie/utils/sandbox/model.py | 35 ++++++--- .../python/ossie/utils/sb/domainless.py | 31 ++++---- .../python/ossie/utils/sb/io_helpers.py | 46 +++++++++--- 9 files changed, 221 insertions(+), 83 deletions(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/formatting.py b/redhawk/src/base/framework/python/ossie/utils/formatting.py index 389bb44a6..019754f48 100644 --- a/redhawk/src/base/framework/python/ossie/utils/formatting.py +++ b/redhawk/src/base/framework/python/ossie/utils/formatting.py @@ -33,6 +33,8 @@ def __init__(self, *headers): self._lines = [] self._limits = [-1] * self.columns self._enable_header = True + self._parent = None + self._children = [] @property def columns(self): @@ -41,6 +43,12 @@ def columns(self): def enable_header(self, state): self._enable_header = state + def set_parent_table(self, parent): + self._parent = parent + + def add_child(self, child): + self._children = child + def limit_column(self, index, length): self._limits[index] = length diff --git a/redhawk/src/base/framework/python/ossie/utils/model/__init__.py b/redhawk/src/base/framework/python/ossie/utils/model/__init__.py index a18f70892..81474e916 100644 --- a/redhawk/src/base/framework/python/ossie/utils/model/__init__.py +++ b/redhawk/src/base/framework/python/ossie/utils/model/__init__.py @@ -42,6 +42,7 @@ from ossie.utils import prop_helpers from ossie.utils import rhtime import warnings as _warnings +import cStringIO, pydoc from connect import * _warnings.filterwarnings('once',category=DeprecationWarning) @@ -197,23 +198,41 @@ def __init__(self): self._providesPortDict = {} self._usesPortDict = {} - def _showPorts(self, ports): + def _showPorts(self, ports, destfile=None): + localdef_dest = False + if destfile == None: + localdef_dest = True + destfile = cStringIO.StringIO() + if ports: table = TablePrinter('Port Name', 'Port Interface') for port in ports.itervalues(): table.append(port['Port Name'], port['Port Interface']) - table.write() + table.write(f=destfile) else: - print "None" + print >>destfile, "None" + + if localdef_dest: + pydoc.pager(destfile.getvalue()) + destfile.close() + + def api(self, destfile=None): + localdef_dest = False + if destfile == None: + localdef_dest = True + destfile = cStringIO.StringIO() + + print >>destfile, "Provides (Input) Ports ==============" + self._showPorts(self._providesPortDict, destfile=destfile) + print >>destfile, "\n" - def api(self): - print "Provides (Input) Ports ==============" - self._showPorts(self._providesPortDict) - print + print >>destfile, "Uses (Output) Ports ==============" + self._showPorts(self._usesPortDict, destfile=destfile) + print >>destfile, "\n" - print "Uses (Output) Ports ==============" - self._showPorts(self._usesPortDict) - print + if localdef_dest: + pydoc.pager(destfile.getvalue()) + destfile.close() def _getUsesPort(self, name): if not name in self._usesPortDict: @@ -481,7 +500,14 @@ def query(self, props): else: return None - def api(self, externalPropInfo=None): + def api(self, externalPropInfo=None, destfile=None): + ''' + If destfile is None, output is sent to stdout + ''' + localdef_dest = False + if destfile == None: + localdef_dest = True + destfile = cStringIO.StringIO() properties = [p for p in self._properties if 'property' in p.kinds or 'configure' in p.kinds or 'execparam' in p.kinds] if not properties: return @@ -497,7 +523,7 @@ def api(self, externalPropInfo=None): extId, propId = externalPropInfo table.enable_header(False) else: - print "Properties ==============" + print >>destfile, "Properties ==============" for prop in properties: if externalPropInfo: # Searching for a particular external property @@ -549,7 +575,10 @@ def api(self, externalPropInfo=None): currentValue = _formatSimple(prop, currentValue,prop.id) table.append(name, '('+scaType+')', str(prop.defValue), currentValue) - table.write() + table.write(f=destfile) + if localdef_dest: + pydoc.pager(destfile.getvalue()) + destfile.close() class PropertyEmitter(PropertySet): @@ -890,10 +919,15 @@ def deallocateCapacity(self, props): if _DEBUG == True: print ("attempted to deallocate a non-existent allocation") - def api(self): - print 'Allocation Properties ======' + def api(self, destfile=None): + localdef_dest = False + if destfile == None: + localdef_dest = True + destfile = cStringIO.StringIO() + + print >>destfile, 'Allocation Properties ======' if not self._allocProps: - print 'None' + print >>destfile, 'None' return table = TablePrinter('Property Name', '(Data Type)', 'Action') @@ -906,8 +940,10 @@ def api(self): structdef = prop for member in structdef.members.itervalues(): table.append(' '+member.clean_name, member.type) - table.write() - + table.write(f=destfile) + if localdef_dest: + pydoc.pager(destfile.getvalue()) + destfile.close() class LoadableDevice(Device): def load(self, fs, fileName, loadKind): diff --git a/redhawk/src/base/framework/python/ossie/utils/prop_helpers.py b/redhawk/src/base/framework/python/ossie/utils/prop_helpers.py index d6b06a175..77e851e67 100644 --- a/redhawk/src/base/framework/python/ossie/utils/prop_helpers.py +++ b/redhawk/src/base/framework/python/ossie/utils/prop_helpers.py @@ -32,6 +32,7 @@ from omniORB import CORBA as _CORBA from omniORB import tcInternal as _tcInternal import copy as _copy +import cStringIO, pydoc import struct as _struct import string as _string import operator as _operator @@ -394,25 +395,30 @@ def _getStructsSimpleSeqProps(self, sprop, prop): type = str(self.compRef._getPropType(sprop)) return defVal, values, type, kinds, enums - def api(self): + def api(self, destfile=None): + localdef_dest = False + if destfile == None: + localdef_dest = True + destfile = cStringIO.StringIO() + kinds = [] - print "\nProperty\n--------" - print "% -*s %s" % (17,"ID:",self.id) - print "% -*s %s" % (17,"Type:",self.type) + print >>destfile, "\nProperty\n--------" + print >>destfile, "% -*s %s" % (17,"ID:",self.id) + print >>destfile, "% -*s %s" % (17,"Type:",self.type) simpleOrSequence = False if self.type != "structSeq" and self.type != "struct": simpleOrSequence = True - print "% -*s %s" % (17,"Default Value:", self.defValue) + print >>destfile, "% -*s %s" % (17,"Default Value:", self.defValue) if self.mode != "writeonly": - print "% -*s %s" % (17,"Value: ", self.queryValue()) + print >>destfile, "% -*s %s" % (17,"Value: ", self.queryValue()) try: if self._enums != None: - print "% -*s %s" % (17,"Enumumerations:", self._enums) + print >>destfile, "% -*s %s" % (17,"Enumumerations:", self._enums) except: simpleOrSequence = True if self.type != "struct": - print "% -*s %s" % (17,"Action:", self.action) - print "% -*s %s" % (17,"Mode: ", self.mode) + print >>destfile, "% -*s %s" % (17,"Action:", self.action) + print >>destfile, "% -*s %s" % (17,"Mode: ", self.mode) if self.type == "struct": structTable = TablePrinter('Name','Data Type','Default Value', 'Current Value','Enumerations') @@ -427,17 +433,17 @@ def api(self): defVal,value, type, kinds,enums = self._getStructsSimpleProps(sprop,prop) structTable.append(sprop.get_id(),type,str(defVal),str(value),enums) if first: - print "% -*s %s" % (17,"Kinds: ", ', '.join(kinds)) + print >>destfile, "% -*s %s" % (17,"Kinds: ", ', '.join(kinds)) first = False for sprop in prop.get_simplesequence(): defVal,values,type,kinds,enums = self._getStructsSimpleSeqProps(sprop, prop) structTable.append(sprop.get_id(),type,defVal,values,enums) if first: - print "% -*s %s" % (17,"Kinds: ",', '.join(kinds)) + print >>destfile, "% -*s %s" % (17,"Kinds: ",', '.join(kinds)) first = False structTable.write() elif self.type == "sequence": - print "sequence: ",type(self) + print >>destfile, "sequence: ",type(self) elif self.type == "structSeq": structNum = -1 @@ -451,8 +457,8 @@ def api(self): structTable.append(prop.id_, prop.get_type()) for prop in prop.get_struct().get_simplesequence(): structTable.append(prop.id_, prop.get_type()) - print "% -*s %s" % (17,"Kinds: ", ', '.join(kinds)) - print "\nStruct\n======" + print >>destfile, "% -*s %s" % (17,"Kinds: ", ', '.join(kinds)) + print >>destfile, "\nStruct\n======" structTable.write() simpleTable = TablePrinter('Index','Name','Value') @@ -465,7 +471,7 @@ def api(self): for key in s.keys(): simpleTable.append(str(structNum),key,str(s[key])) if self.mode != "writeonly": - print "\nSimple Properties\n=================" + print >>destfile, "\nSimple Properties\n=================" simpleTable.write() elif simpleOrSequence: @@ -473,8 +479,11 @@ def api(self): if prop.id_ == self.id: for kind in prop.get_kind(): kinds.append(kind.get_kindtype()) - print "% -*s %s" % (17,"Kinds: ", ', '.join(kinds)) - + print >>destfile, "% -*s %s" % (17,"Kinds: ", ', '.join(kinds)) + + if localdef_dest: + pydoc.pager(destfile.getvalue()) + destfile.close() def _isNested(self): return self._parent is not None diff --git a/redhawk/src/base/framework/python/ossie/utils/redhawk/component.py b/redhawk/src/base/framework/python/ossie/utils/redhawk/component.py index cf6e92c34..0f6af506c 100644 --- a/redhawk/src/base/framework/python/ossie/utils/redhawk/component.py +++ b/redhawk/src/base/framework/python/ossie/utils/redhawk/component.py @@ -18,6 +18,8 @@ # along with this program. If not, see http://www.gnu.org/licenses/. # +import cStringIO, pydoc + from ossie.utils.model import ComponentBase, Resource, PropertySet, PortSupplier class DomainComponent(ComponentBase): @@ -37,17 +39,26 @@ def __init__(self, profile, spd, scd, prf, instanceName, refid, impl, pid=0, dev ##################################### - def api(self, showComponentName=True, showInterfaces=True, showProperties=True, externalPropInfo=None): + def api(self, showComponentName=True, showInterfaces=True, showProperties=True, externalPropInfo=None, destfile=None): ''' Inspect interfaces and properties for the component ''' + localdef_dest = False + if destfile == None: + localdef_dest = True + destfile = cStringIO.StringIO() + className = self.__class__.__name__ if showComponentName == True: - print className+" [" + str(self.name) + "]:" + print >>destfile, className+" [" + str(self.name) + "]:" if showInterfaces == True: - PortSupplier.api(self) + PortSupplier.api(self, destfile=destfile) if showProperties == True and self._properties != None: - PropertySet.api(self, externalPropInfo) + PropertySet.api(self, externalPropInfo, destfile=destfile) + + if localdef_dest: + pydoc.pager(destfile.getvalue()) + destfile.close() class Component(DomainComponent, Resource): diff --git a/redhawk/src/base/framework/python/ossie/utils/redhawk/core.py b/redhawk/src/base/framework/python/ossie/utils/redhawk/core.py index e0e387171..cd9db8c8c 100644 --- a/redhawk/src/base/framework/python/ossie/utils/redhawk/core.py +++ b/redhawk/src/base/framework/python/ossie/utils/redhawk/core.py @@ -32,6 +32,7 @@ import sys as _sys import time as _time import datetime as _datetime +import cStringIO, pydoc import weakref import threading import logging @@ -421,25 +422,30 @@ def _populateComponents(self): if refid.find(self.assemblyController) >= 0: self._acRef = new_comp - def api(self): + def api(self, destfile=None): # Display components, their properties, and external ports - print "Waveform [" + self.ns_name + "]" - print "---------------------------------------------------" + localdef_dest = False + if destfile == None: + localdef_dest = True + destfile = cStringIO.StringIO() - print "External Ports ==============" - PortSupplier.api(self) + print >>destfile, "Waveform [" + self.ns_name + "]" + print >>destfile, "---------------------------------------------------" - print "Components ==============" + print >>destfile, "External Ports ==============" + PortSupplier.api(self, destfile=destfile) + + print >>destfile, "Components ==============" for count, comp_entry in enumerate(self.comps): name = comp_entry.name if comp_entry._get_identifier().find(self.assemblyController) != -1: name += " (Assembly Controller)" - print "%d. %s" % (count+1, name) - print "\n" + print >>destfile, "%d. %s" % (count+1, name) + print >>destfile, "\n" # Display AC props if self._acRef: - self._acRef.api(showComponentName=False, showInterfaces=False, showProperties=True) + self._acRef.api(showComponentName=False, showInterfaces=False, showProperties=True, destfile=destfile) # Loops through each external prop looking for a component to use to display the internal prop value for extId in self._externalProps.keys(): @@ -447,10 +453,14 @@ def api(self): for comp_entry in self.comps: if comp_entry._get_identifier().find(compRefId) != -1: # Pass along external prop info to component api() - comp_entry.api(showComponentName=False,showInterfaces=False,showProperties=True, externalPropInfo=(extId, propId)) + comp_entry.api(showComponentName=False,showInterfaces=False,showProperties=True, externalPropInfo=(extId, propId), destfile=destfile) break - print + print >>destfile, '\n' + + if localdef_dest: + pydoc.pager(destfile.getvalue()) + destfile.close() def _populatePorts(self, fs=None): """Add all port descriptions to the component instance""" diff --git a/redhawk/src/base/framework/python/ossie/utils/redhawk/device.py b/redhawk/src/base/framework/python/ossie/utils/redhawk/device.py index eacdbfdfc..5bbb769dc 100644 --- a/redhawk/src/base/framework/python/ossie/utils/redhawk/device.py +++ b/redhawk/src/base/framework/python/ossie/utils/redhawk/device.py @@ -19,6 +19,7 @@ # import warnings +import cStringIO, pydoc from ossie.cf import CF from ossie.utils.notify import notification @@ -164,10 +165,19 @@ def __operationalStateChangeEvent(self, deviceId, stateChangeFrom, stateChangeTo def __usageStateChangeEvent(self, deviceId, stateChangeFrom, stateChangeTo): self.__usageState.update(stateChangeTo) - def api(self): - super(DomainDevice,self).api() - print - model.Device.api(self) + def api(self, destfile=None): + localdef_dest = False + if destfile == None: + localdef_dest = True + destfile = cStringIO.StringIO() + + super(DomainDevice,self).api(destfile=destfile) + print >>destfile, '\n' + model.Device.api(self, destfile=destfile) + + if localdef_dest: + pydoc.pager(destfile.getvalue()) + destfile.close() class Device(DomainDevice, model.Device): def __init__(self, profile, spd, scd, prf, deviceRef, instanceName, refid, impl=None, idmListener=None): diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/model.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/model.py index 213457c9c..a389fdc24 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/model.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/model.py @@ -19,6 +19,7 @@ # import warnings +import cStringIO, pydoc from ossie.utils.model import CorbaObject from ossie.utils.model import PortSupplier, PropertySet, ComponentBase @@ -132,13 +133,22 @@ def releaseObject(self): # Allow the launcher to peform any follow-up cleanup. SandboxMixin._terminate(self) - def api(self): + def api(self, destfile=None): ''' Inspect interfaces and properties for the component ''' - print "Component [" + str(self._componentName) + "]:" - PortSupplier.api(self) - PropertySet.api(self) + localdef_dest = False + if destfile == None: + localdef_dest = True + destfile = cStringIO.StringIO() + + print >>destfile, "Component [" + str(self._componentName) + "]:" + PortSupplier.api(self, destfile=destfile) + PropertySet.api(self, destfile=destfile) + + if localdef_dest: + pydoc.pager(destfile.getvalue()) + destfile.close() def sendMessage(self, msg, msgId=None, msgPort=None, restrict=True ): """ @@ -177,10 +187,19 @@ def __init__(self, *args, **kwargs): def __repr__(self): return "<%s device '%s' at 0x%x>" % (self._sandbox.getType(), self._instanceName, id(self)) - def api(self): - SandboxResource.api(self) - print - Device.api(self) + def api(self, destfile=None): + localdef_dest = False + if destfile == None: + localdef_dest = True + destfile = cStringIO.StringIO() + + SandboxResource.api(self, destfile=destfile) + print >>destfile, '\n' + Device.api(self, destfile=destfile) + + if localdef_dest: + pydoc.pager(destfile.getvalue()) + destfile.close() class SandboxService(Service, SandboxMixin): diff --git a/redhawk/src/base/framework/python/ossie/utils/sb/domainless.py b/redhawk/src/base/framework/python/ossie/utils/sb/domainless.py index bd4a2d77b..23cc679a2 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sb/domainless.py +++ b/redhawk/src/base/framework/python/ossie/utils/sb/domainless.py @@ -104,7 +104,7 @@ import sys import logging import string as _string -import cStringIO +import cStringIO, pydoc import warnings import traceback from omniORB import CORBA, any @@ -1083,7 +1083,12 @@ def __new__(self, except RuntimeError, e: # Turn RuntimeErrors into AssertionErrors to match legacy expectation. raise AssertionError, "Unable to launch component: '%s'" % e -def api(descriptor, objType=None): +def api(descriptor, objType=None, destfile=None): + localdef_dest = False + if destfile == None: + localdef_dest = True + destfile = cStringIO.StringIO() + sdrRoot = _getSandbox().getSdrRoot() profile = sdrRoot.findProfile(descriptor, objType=objType) spd, scd, prf = sdrRoot.readProfile(profile) @@ -1098,21 +1103,21 @@ def api(descriptor, objType=None): else: description = spd.description if description: - print '\nDescription ======================\n' - print description - print '\nPorts ======================' - print '\nUses (output)' + print >>destfile, '\nDescription ======================\n' + print >>destfile, description + print >>destfile, '\nPorts ======================' + print >>destfile, '\nUses (output)' table = TablePrinter('Port Name', 'Port Interface') for uses in scd.get_componentfeatures().get_ports().get_uses(): table.append(uses.get_usesname(), uses.get_repid()) - table.write() - print '\nProvides (input)' + table.write(f=destfile) + print >>destfile, '\nProvides (input)' table = TablePrinter('Port Name', 'Port Interface') for provides in scd.get_componentfeatures().get_ports().get_provides(): table.append(provides.get_providesname(), provides.get_repid()) - table.write() + table.write(f=destfile) - print '\nProperties ======================\n' + print >>destfile, '\nProperties ======================\n' table = TablePrinter('id', 'type') if prf != None: for simple in prf.simple: @@ -1137,9 +1142,11 @@ def api(descriptor, objType=None): table.append(' '+prop.get_id(),prop.get_type()) for prop in struct.get_struct().get_simplesequence(): table.append(' '+prop.get_id(),prop.get_type()) - table.write() - + table.write(f=destfile) + if localdef_dest: + pydoc.pager(destfile.getvalue()) + destfile.close() def _get_started(): return _getSandbox()._get_started() diff --git a/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py b/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py index 7a57face1..77673f975 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py +++ b/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py @@ -38,6 +38,7 @@ import shlex as _shlex import time as _time import signal as _signal +import cStringIO, pydoc import os as _os import subprocess as _subprocess import Queue as _Queue @@ -189,9 +190,18 @@ def getPort(self, portName): log.error("MessageSink:getPort(): failed " + str(e)) return None - def api(self): - print "Component MessageSink :" - PortSupplier.api(self) + def api(self, destfile=None): + localdef_dest = False + if destfile == None: + localdef_dest = True + destfile = cStringIO.StringIO() + + print >>destfile, "Component MessageSink :" + PortSupplier.api(self, destfile=destfile) + + if localdef_dest: + pydoc.pager(destfile.getvalue()) + destfile.close() def start(self): if self._messagePort : self._messagePort.startPort() @@ -315,9 +325,18 @@ def getUsesPort(self): log.error("MessageSource:getUsesPort(): failed " + str(e)) return None - def api(self): - print "Component MessageSource :" - PortSupplier.api(self) + def api(self, destfile=None): + localdef_dest = False + if destfile == None: + localdef_dest = True + destfile = cStringIO.StringIO() + + print >>destfile, "Component MessageSource :" + PortSupplier.api(self, destfile=destfile) + + if localdef_dest: + pydoc.pager(destfile.getvalue()) + destfile.close() def start(self): self._flowOn = True @@ -590,13 +609,22 @@ def getPortByName(self, portName): # as the portName should be set via self.supportedPorts. raise Exception, "Port name " + portName + " not found." - def api(self): + def api(self, destfile=None): """ Prints application programming interface (API) information and returns. """ - print "Component " + self.__class__.__name__ + " :" - PortSupplier.api(self) + localdef_dest = False + if destfile == None: + localdef_dest = True + destfile = cStringIO.StringIO() + + print >>destfile, "Component " + self.__class__.__name__ + " :" + PortSupplier.api(self, destfile=destfile) + + if localdef_dest: + pydoc.pager(destfile.getvalue()) + destfile.close() class _SourceBase(_DataPortBase): From 6249d7dba579026a5f3adcf8e614f116ab5a2d84 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Tue, 2 May 2017 10:58:50 -0400 Subject: [PATCH 0786/1644] Refs CF-1004. Allow sending simple sequence SRI keywords in the sandbox artifacts --- .../python/ossie/utils/sb/io_helpers.py | 40 +++++++++++++------ redhawk/src/testing/tests/test_13_TestSB.py | 17 ++++++-- 2 files changed, 42 insertions(+), 15 deletions(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py b/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py index 77673f975..7f0d7093d 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py +++ b/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py @@ -47,6 +47,7 @@ import socket as _socket from omniORB import any as _any from omniORB import CORBA as _CORBA +from omniORB import tcInternal import copy as _copy import omniORB as _omniORB import CosEventComm__POA @@ -112,6 +113,13 @@ def compareKeywordLists( a, b ): return False return True +def _getAnyValue(key): + if key._format[0]=='[' and key._format[-1]==']': + expectedType = _properties.getTypeCode(key._format[1:-1]) + expectedTypeCode = tcInternal.createTypeCode((tcInternal.tv_sequence, expectedType._d, 0)) + return _CORBA.Any(expectedTypeCode, key._value) + else: + return _properties.to_tc_value(key._value,str(key._format)) def _checkComplex(data): for item in data: @@ -957,7 +965,7 @@ def setupFileReader(self): self._src = _bulkio_data_helpers.FileSource(eval(portType),self._byteswap, portTypes) keywords = [] for key in self._SRIKeywords: - keywords.append(_CF.DataType(key._name, _properties.to_tc_value(key._value,str(key._format)))) + keywords.append(_CF.DataType(key._name, _getAnyValue(key))) if self._streamID == None: self._streamID = self._filename.split('/')[-1] @@ -1235,7 +1243,7 @@ def sri(self): keywords = [] try: for key in self._SRIKeywords: - keywords.append(_CF.DataType(key._name, _properties.to_tc_value(key._value,str(key._format)))) + keywords.append(_CF.DataType(key._name, _getAnyValue(key))) except: pass candidateSri = _BULKIO.StreamSRI(1, 0.0, 1, 0, self._subsize, 0.0, 0, 0, 0, @@ -1396,7 +1404,7 @@ def pushThread(self): len(SRIKeywords) > 0: keywords = [] for key in self._SRIKeywords: - keywords.append(_CF.DataType(key._name, _properties.to_tc_value(key._value,str(key._format)))) + keywords.append(_CF.DataType(key._name, _getAnyValue(key))) candidateSri = _BULKIO.StreamSRI(1, 0.0, 1, 0, self._subsize, 0.0, 0, 0, 0, streamID, self._blocking, keywords) @@ -1452,7 +1460,7 @@ def pushThread(self): keywords = candidateSri.keywords[:] for key in self._SRIKeywords: # if current sri contains they keyword then overwrite else append - kw=_CF.DataType(key._name, _properties.to_tc_value(key._value,str(key._format))) + kw = _CF.DataType(key._name, _getAnyValue(key)) if key._name in ckeys: # replace that keyword for x in range(len(keywords)): @@ -1883,18 +1891,26 @@ class SRIKeyword(object): This is used in the Input series as the element in the SRIKeywords list name and value correspond to the id/value pair format is a string that describes the data type casting that needs to happen - - short, ushort - - float, double - - long, ulong - - longlong, ulonglong - - char - - octet + - short, ushort, complexShort, complexUShort + - float, double, complexFloat, complexDouble + - long, ulong, complexLong, complexULong + - longlong, ulonglong, complexLongLong, complexULongLong + - char, complexChar + - octet, complexOctet - string - - boolean + - boolean, complexBoolean + For sequences, encase the data type in brackets (e.g.: [short]) ''' def __init__(self, name, value, format): # validate format is legal type to convert to - if format in _properties.getTypeMap().keys(): + if format[0] == '[' and format[-1] == ']': + if format[1:-1] in _properties.getTypeMap().keys(): + self._name = name + self._value = value + self._format = format + else: + raise RuntimeError("Unsupported format type: " + format) + elif format in _properties.getTypeMap().keys(): self._name = name self._value = value self._format = format diff --git a/redhawk/src/testing/tests/test_13_TestSB.py b/redhawk/src/testing/tests/test_13_TestSB.py index 5b20e80de..0ad6763d7 100644 --- a/redhawk/src/testing/tests/test_13_TestSB.py +++ b/redhawk/src/testing/tests/test_13_TestSB.py @@ -32,7 +32,7 @@ import commands import struct -from omniORB import CORBA, any +from omniORB import CORBA, any, tcInternal from ossie import properties from ossie.cf import CF, StandardEvent @@ -69,7 +69,11 @@ def compareKeywordLists( a, b ): if keyA.id != keyB.id: return False if keyA.value._t != keyB.value._t: - return False + if isinstance(keyA.value._t,tcInternal.TypeCode_sequence): + if keyA.value._t.content_type() != keyB.value._t.content_type(): + return False + else: + return False if keyA.value._v != keyB.value._v: return False return True @@ -2076,11 +2080,18 @@ def wait_on_data( sink ): kws.append(sb.SRIKeyword('kw3',16,'short')) kws.append(sb.SRIKeyword('kw4', 200,'octet')) kws.append(sb.SRIKeyword('kw5','this is a test','string')) + kws.append(sb.SRIKeyword('kw6',[1,2],'[short]')) + + expectedType = properties.getTypeCode('short') + expectedTypeCode = tcInternal.createTypeCode((tcInternal.tv_sequence, expectedType._d, 0)) + kw6 = CORBA.Any(expectedTypeCode, [1,2]) + matchkws=[ CF.DataType(id='kw1', value=CORBA.Any(CORBA.TC_long, 1000)), CF.DataType(id='kw2', value=CORBA.Any(CORBA.TC_float, 12456.0)), CF.DataType(id='kw3', value=CORBA.Any(CORBA.TC_short, 16)), CF.DataType(id='kw4', value=CORBA.Any(CORBA.TC_octet, 200)), - CF.DataType(id='kw5', value=CORBA.Any(CORBA.TC_string, 'this is a test')) + CF.DataType(id='kw5', value=CORBA.Any(CORBA.TC_string, 'this is a test')), + CF.DataType(id='kw6', value=kw6) ] _srcData = [1,2,3,4] source.push(_srcData, SRIKeywords=kws ) From 0883d33d85d6471db880f2ed58cf1074aa568fdb Mon Sep 17 00:00:00 2001 From: Max Robert Date: Tue, 2 May 2017 15:09:32 -0400 Subject: [PATCH 0787/1644] Add argument to api usage to not page the output --- .../python/ossie/utils/model/__init__.py | 3 ++- .../python/ossie/utils/sb/io_helpers.py | 5 +++-- .../python/ossie/utils/sb/rh-inspect | 2 +- .../framework/python/ossie/utils/sb/rh-launch | 2 +- redhawk/src/testing/tests/test_13_TestSB.py | 22 +++++++++---------- 5 files changed, 18 insertions(+), 16 deletions(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/model/__init__.py b/redhawk/src/base/framework/python/ossie/utils/model/__init__.py index 81474e916..eac534465 100644 --- a/redhawk/src/base/framework/python/ossie/utils/model/__init__.py +++ b/redhawk/src/base/framework/python/ossie/utils/model/__init__.py @@ -20,6 +20,7 @@ import commands as _commands +import sys as _sys import os as _os import copy as _copy import logging @@ -1355,7 +1356,7 @@ def _buildAPI(self): if _DEBUG == True: try: - self.api() + self.api(destfile=_sys.stdout) except: pass diff --git a/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py b/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py index 7f0d7093d..11c836460 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py +++ b/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py @@ -39,6 +39,7 @@ import time as _time import signal as _signal import cStringIO, pydoc +import sys as _sys import os as _os import subprocess as _subprocess import Queue as _Queue @@ -721,7 +722,7 @@ def _buildAPI(self): if _domainless._DEBUG == True: print self.className + ":_buildAPI()" - self.api() + self.api(destfile=_sys.stdout) def getPort(self, name): if name in self._connections: @@ -767,7 +768,7 @@ def _buildAPI(self): if _domainless._DEBUG == True: print self.className + ":_buildAPI()" - self.api() + self.api(destfile=_sys.stdout) def getPortType(self, portName): """ diff --git a/redhawk/src/base/framework/python/ossie/utils/sb/rh-inspect b/redhawk/src/base/framework/python/ossie/utils/sb/rh-inspect index afbe458cf..33f90dae2 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sb/rh-inspect +++ b/redhawk/src/base/framework/python/ossie/utils/sb/rh-inspect @@ -39,7 +39,7 @@ if '__main__': # Instantiate component and build API, but don't actually launch component process comp = Component(componentDescriptor=arg,autoKick=False) print "rh-inspect " + str(arg) + "*******************************" - comp.api() + comp.api(destfile=sys.stdout) print "\n" except Exception, e: diff --git a/redhawk/src/base/framework/python/ossie/utils/sb/rh-launch b/redhawk/src/base/framework/python/ossie/utils/sb/rh-launch index 89d327662..3ec9c0b86 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sb/rh-launch +++ b/redhawk/src/base/framework/python/ossie/utils/sb/rh-launch @@ -69,7 +69,7 @@ if '__main__': components[componentNumber]["InputFile"] = {} components[componentNumber]["InputFile"]["Filename"] = inputFilename components[componentNumber]["InputFile"]["Object"] = InputFile(str(inputFilename), "short") - components[componentNumber]["InputFile"]["Object"].api() + components[componentNumber]["InputFile"]["Object"].api(destfile=sys.stdout) componentNumber = componentNumber + 1 needInputFileDataType = False elif arg.find("!") != -1: diff --git a/redhawk/src/testing/tests/test_13_TestSB.py b/redhawk/src/testing/tests/test_13_TestSB.py index 0ad6763d7..148d00c6c 100644 --- a/redhawk/src/testing/tests/test_13_TestSB.py +++ b/redhawk/src/testing/tests/test_13_TestSB.py @@ -297,7 +297,7 @@ def test_componentInit(self): # Make sure only one instance name and refid can be used comp = sb.launch(self.test_comp, "comp") - comp.api() + comp.api(destfile=sys.stdout) refid = comp._refid self.assertRaises(ValueError, sb.launch, self.test_comp, "comp") self.assertRaises(ValueError, sb.launch, self.test_comp, "new_comp", refid) @@ -420,7 +420,7 @@ def initValues(self, comp): def test_simpleComp(self): comp = sb.launch(self.test_comp) - comp.api() + comp.api(destfile=sys.stdout) # Check the init values self.initValues(comp) @@ -581,7 +581,7 @@ def test_simpleComp(self): def test_illegalPropertyNames(self): comp = sb.launch(self.test_comp) - comp.api() + comp.api(destfile=sys.stdout) self.initValues(comp) @@ -788,7 +788,7 @@ def test_loadSADFile_overload_external_props(self): def test_simplePropertyRange(self): comp = sb.launch('TestPythonPropsRange') - comp.api() + comp.api(destfile=sys.stdout) # Test upper range comp.my_octet_name = 255 @@ -843,7 +843,7 @@ def test_simplePropertyRange(self): def test_structPropertyRange(self): comp = sb.launch('TestPythonPropsRange') - comp.api() + comp.api(destfile=sys.stdout) # Test upper range comp.my_struct_name.struct_octet_name = 255 @@ -948,7 +948,7 @@ def test_structPropertyRange(self): def test_seqPropertyRange(self): comp = sb.launch('TestPythonPropsRange') - comp.api() + comp.api(destfile=sys.stdout) # Test upper and lower bounds comp.seq_octet_name[0] = 0 @@ -1011,7 +1011,7 @@ def test_seqPropertyRange(self): def test_structSeqPropertyRange(self): comp = sb.launch('TestPythonPropsRange') - comp.api() + comp.api(destfile=sys.stdout) # Test upper and lower bounds comp.my_structseq_name[0].ss_octet_name = 255 @@ -1130,7 +1130,7 @@ def test_structSeqPropertyRange(self): def test_readOnlyProps(self): comp = sb.launch('Sandbox') - comp.api() + comp.api(destfile=sys.stdout) # Properties should be able to be read, but not set, and all should throw the saem exception exception = None @@ -1513,10 +1513,10 @@ def test_ComplexListConversions(self): def test_apiBeforeLaunch(self): try: - sb.api("TestCppProps") - sb.api("SimpleDevice") + sb.api("TestCppProps", destfile=sys.stdout) + sb.api("SimpleDevice", destfile=sys.stdout) # Building Java support is not necessary to test sb.api() - sb.api("BasicService_java") + sb.api("BasicService_java", destfile=sys.stdout) except: self.fail("sb.api() failure") From 22882c5b5ec4008f2399e0167189df395697c913 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Tue, 2 May 2017 16:34:02 -0400 Subject: [PATCH 0788/1644] Refs CF-423. Added function to retrieve sri sequence from DataSink --- .../ossie/utils/bulkio/bulkio_data_helpers.py | 46 ++++++++++++------- .../python/ossie/utils/sb/io_helpers.py | 17 +++++-- .../framework/python/ossie/utils/sb/plots.py | 11 +++-- redhawk/src/testing/tests/test_13_TestSB.py | 30 ++++++++++++ 4 files changed, 78 insertions(+), 26 deletions(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/bulkio/bulkio_data_helpers.py b/redhawk/src/base/framework/python/ossie/utils/bulkio/bulkio_data_helpers.py index e449e9a49..2b6fd20e2 100644 --- a/redhawk/src/base/framework/python/ossie/utils/bulkio/bulkio_data_helpers.py +++ b/redhawk/src/base/framework/python/ossie/utils/bulkio/bulkio_data_helpers.py @@ -220,6 +220,7 @@ def __init__(self, porttype): self.sri=bulkio_helpers.defaultSRI self.data = [] self.timestamps = [] + self.sris = [] self.gotEOS = False self.breakBlock = False self.port_lock = threading.Lock() @@ -228,9 +229,11 @@ def __init__(self, porttype): class estimateStruct(): len_data=0 num_timestamps=0 - def __init__(self, data=[], timestamps=[]): + num_sris=0 + def __init__(self, data=[], timestamps=[], sris=[]): self.len_data = len(data) self.num_timestamps = len(timestamps) + self.num_sris = len(sris) def _isActive(self): return not self.gotEOS and not self.breakBlock @@ -271,6 +274,7 @@ def pushSRI(self, H): generate the header file """ self.sri = H + self.sris.append([len(self.data), H]) def pushPacket(self, data, ts, EOS, stream_id): """ @@ -295,11 +299,25 @@ def estimateData(self): self.port_cond.acquire() estimate = self.estimateStruct() try: - estimate = self.estimateStruct(self.data, self.timestamps) + estimate = self.estimateStruct(self.data, self.timestamps, self.sris) finally: self.port_cond.release() return estimate + def syncAssocData(self, reference): + retval = [] + length_to_erase = None + for i,(l,t) in enumerate(reference[::-1]): + if l > length: + reference[len(reference)-i-1][0] = l - length + continue + if length_to_erase == None: + length_to_erase = len(reference)-i + retval.append((l,t)) + if length_to_erase != None: + del reference[:length_to_erase] + return retval + def retrieveData(self, length=None): self.port_cond.acquire() try: @@ -325,17 +343,9 @@ def retrieveData(self, length=None): # More data is available than was requested. Return only # as much data as was asked for, and the associated # timestamps. - rettime = [] - length_to_erase = None - for i,(l,t) in enumerate(self.timestamps[::-1]): - if l > length: - self.timestamps[len(self.timestamps)-i-1][0] = l - length - continue - if length_to_erase == None: - length_to_erase = len(self.timestamps)-i - rettime.append((l,t)) - if length_to_erase != None: - del self.timestamps[:length_to_erase] + rettime = self.syncAssocData(self.timestamps) + retsris = self.syncAssocData(self.sris) + if self.sri.subsize == 0: retval = self.data[:length] else: @@ -344,23 +354,25 @@ def retrieveData(self, length=None): for idx in range(length/frameLength): retval.append(self.data[idx*frameLength:(idx+1)*frameLength]) del self.data[:length] - return (retval, rettime) + return (retval, rettime, retsris) # No length was provided, or length is equal to the length of data. # Return all data and timestamps. if self.sri == None: - (retval, rettime) = (self.data, self.timestamps) + (retval, rettime, retsris) = (self.data, self.timestamps, []) elif self.sri.subsize == 0: - (retval, rettime) = (self.data, self.timestamps) + (retval, rettime, retsris) = (self.data, self.timestamps, self.sris) else: retval = [] frameLength = self.sri.subsize if not self.sri.mode else 2*self.sri.subsize for idx in range(length/frameLength): retval.append(self.data[idx*frameLength:(idx+1)*frameLength]) rettime = self.timestamps + retsris = self.sris self.data = [] self.timestamps = [] - return (retval, rettime) + self.sris = [] + return (retval, rettime, retsris) finally: self.port_cond.release() diff --git a/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py b/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py index 11c836460..764a7723d 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py +++ b/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py @@ -1691,7 +1691,7 @@ def getDataEstimate(self): return None return self._sink.estimateData() - def getData(self, length=None, eos_block=False, tstamps=False): + def getData(self, length=None, eos_block=False, tstamps=False, sris=False): ''' Returns either an array of the received data elements or a tuple containing the received list and their associated time stamps @@ -1702,7 +1702,12 @@ def getData(self, length=None, eos_block=False, tstamps=False): eos_block: setting to True creates a blocking call until eos is received tstamps: setting to True makes the return value a tuple, where the first element is the data set and the second element is a series of tuples - containing the element index number of and timestamp + containing the element index number and the timestamp for that index + sris: setting to True makes the return value a tuple, where the first + element is the data set, the second element is the series of + timestamps (empty list if tstamps==False) and the third element is + a series of tuples containing the element index number and the + sri value for that index ''' isChar = self._sink.port_type == _BULKIO__POA.dataChar @@ -1710,7 +1715,7 @@ def getData(self, length=None, eos_block=False, tstamps=False): return None if eos_block: self._sink.waitEOS() - (retval, timestamps) = self._sink.retrieveData(length=length) + (retval, timestamps, _sris) = self._sink.retrieveData(length=length) if isChar: # Converts char values into their numeric equivalents def from_char(data): @@ -1723,8 +1728,12 @@ def from_char(data): retval = [from_char(frame) for frame in retval] else: retval = from_char(retval) - if tstamps: + if tstamps and not sris: return (retval,timestamps) + if not tstamps and sris: + return (retval, [], _sris) + if tstamps and sris: + return (retval,timestamps,_sris) else: return retval diff --git a/redhawk/src/base/framework/python/ossie/utils/sb/plots.py b/redhawk/src/base/framework/python/ossie/utils/sb/plots.py index 7534ab275..2b20b9bb9 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sb/plots.py +++ b/redhawk/src/base/framework/python/ossie/utils/sb/plots.py @@ -104,12 +104,13 @@ def sriChanged(self): return changed def retrieveData(self, length): - data, times = super(PlotSink,self).retrieveData(length) + data, times, sris = super(PlotSink,self).retrieveData(length) if self.sri.mode or self._forceComplex: - data2, times2 = super(PlotSink,self).retrieveData(length) + data2, times2, sris2 = super(PlotSink,self).retrieveData(length) data = bulkio_helpers.bulkioComplexToPythonComplexList(data + data2) times.extend(times2) - return data, times + sris.extend(sris2) + return data, times, sris class CharSink(PlotSink): def __init__(self): @@ -380,7 +381,7 @@ def _updateTrace(self, trace): line = trace['line'] # Read next frame. - data, timestamps = sink.retrieveData(length=self._frameSize) + data, timestamps, sris = sink.retrieveData(length=self._frameSize) if not data: return x_data, y_data = self._formatData(data, sink.sri) @@ -651,7 +652,7 @@ def _update(self): return False # Read and format data. - data, timestamps = self._sink.retrieveData(length=self._frameSize) + data, timestamps, sris = self._sink.retrieveData(length=self._frameSize) if not data: return sri = self._sink.sri diff --git a/redhawk/src/testing/tests/test_13_TestSB.py b/redhawk/src/testing/tests/test_13_TestSB.py index 148d00c6c..237785002 100644 --- a/redhawk/src/testing/tests/test_13_TestSB.py +++ b/redhawk/src/testing/tests/test_13_TestSB.py @@ -2036,6 +2036,36 @@ def test_DataSourceTimeStampParam(self): _rnd_toffset = int(round( (_toffset+len(_srcData)/_sampleRate) *10))/10.0 self.assertEquals(_rnd_pkt_time,_rnd_toffset ) + def test_DataSinkSRI(self): + """ + Verify that provide SRI is handled + """ + def wait_on_data( sink ): + _timeout = 1 + begin_time = time.time() + estimate = sink.getDataEstimate() + while estimate.num_timestamps != 3: + time.sleep(0.1) + estimate = sink.getDataEstimate() + if time.time() - begin_time > _timeout: + break + + src = sb.DataSource(dataFormat='float') + snk = sb.DataSink() + src.connect(snk) + sb.start() + src.push([1,2,3,4,5],sampleRate=100) + src.push([1,2,3,4,5],sampleRate=1000) + src.push([1,2,3,4,5],sampleRate=10000) + wait_on_data(snk) + data=snk.getData(tstamps=True,sris=True) + self.assertEquals(len(data[2]), 3) + self.assertEquals(data[2][0][0], 0) + self.assertEquals(data[2][1][0], 5) + self.assertEquals(data[2][2][0], 10) + self.assertEquals(data[2][0][1].xdelta, 0.01) + self.assertEquals(data[2][1][1].xdelta, 0.001) + self.assertEquals(data[2][2][1].xdelta, 0.0001) def test_DataSourceSRI(self): """ From 506b15635f9559abd781cd5ea9f948527138d2ed Mon Sep 17 00:00:00 2001 From: Max Robert Date: Wed, 3 May 2017 12:34:47 -0400 Subject: [PATCH 0789/1644] Refs CF-549. Simplified the creation of custom sandbox sinks --- .../python/ossie/utils/sb/io_helpers.py | 61 ++++++++++++------- redhawk/src/testing/tests/test_13_TestSB.py | 42 +++++++++++++ 2 files changed, 80 insertions(+), 23 deletions(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py b/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py index 764a7723d..5d2b75643 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py +++ b/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py @@ -29,8 +29,8 @@ import domainless as _domainless import threading as _threading import ossie.utils.bulkio.bulkio_helpers as _bulkio_helpers -import ossie.utils.bluefile.bluefile_helpers as _bluefile_helpers -import ossie.utils.bulkio.bulkio_data_helpers as _bulkio_data_helpers +from ossie.utils.bluefile import bluefile_helpers +from ossie.utils.bulkio import bulkio_data_helpers import ossie.utils.bluefile.bluefile as _bluefile from ossie import properties as _properties from ossie import events as _events @@ -735,7 +735,6 @@ def getPort(self, name): class _SinkBase(_DataPortBase): - def __init__(self, formats=None): """ Forward parameters to parent constructor. @@ -960,10 +959,10 @@ def setupFileReader(self): # If input file is a Midas Blue file if self._midasFile == True: # define source helper component - self._src = _bluefile_helpers.BlueFileReader(eval(portType)) + self._src = bluefile_helpers.BlueFileReader(eval(portType)) # else, input file is binary file else: - self._src = _bulkio_data_helpers.FileSource(eval(portType),self._byteswap, portTypes) + self._src = bulkio_data_helpers.FileSource(eval(portType),self._byteswap, portTypes) keywords = [] for key in self._SRIKeywords: keywords.append(_CF.DataType(key._name, _getAnyValue(key))) @@ -1020,9 +1019,15 @@ def stop(self): self._src.EOS = True class FileSink(_SinkBase): - def __init__(self,filename=None, midasFile=False): + """ + To use a different sink (for custom data processing) for regular files, assign the new class to sinkClass + To use a different sink for blue files, assign the new class to sinkBlueClass + """ + def __init__(self,filename=None, midasFile=False, sinkClass=bulkio_data_helpers.FileSink, sinkBlueClass=bluefile_helpers.BlueFileWriter): _SinkBase.__init__(self) + self.sinkClass = sinkClass + self.sinkBlueClass = sinkBlueClass if _domainless._DEBUG == True: print className + ":__init__() filename " + str(filename) print className + ":__init__() midasFile " + str(midasFile) @@ -1037,10 +1042,10 @@ def getPort(self, portName): # If output file is a Midas Blue file if self._midasFile == True: # define source helper component - self._sink = _bluefile_helpers.BlueFileWriter(self._filename,eval(self._sinkPortType)) + self._sink = self.sinkBlueClass(self._filename,eval(self._sinkPortType)) # else, output file is binary file else: - self._sink = _bulkio_data_helpers.FileSink(self._filename, eval(self._sinkPortType)) + self._sink = self.sinkClass(self._filename, eval(self._sinkPortType)) if self._sink != None: self._sinkPortObject = self._sink.getPort() @@ -1090,14 +1095,14 @@ class DataSinkSDDS(_SinkBase): It is the responsibility of the user to consume the SDDS data - DataSinkSDDS manages attachment Ids under the port (self._sink) dictionary attachments + DataSinkSDDS manages attachment Ids under the port (sinkClass) dictionary attachments register an attach callback by passing a function to registerAttachCallback register an detach callback by passing a function to registerDetachCallback """ - def __init__(self): + def __init__(self, sinkClass=bulkio_data_helpers.SDDSSink): _SinkBase.__init__(self, formats=['sdds']) - self._sink = _bulkio_data_helpers.SDDSSink(self) + self._sink = sinkClass(self) self.attach_cb = self.__attach_cb self.detach_cb = self.__detach_cb @@ -1138,7 +1143,7 @@ def __init__(self): Helper to handle the generation of SDDS metadata forwarding """ _SourceBase.__init__(self, bytesPerPush = 0, dataFormat='sdds', formats=['sdds']) - self._src = _bulkio_data_helpers.SDDSSource() + self._src = bulkio_data_helpers.SDDSSource() def attach(self, streamData=None, name=None): """ streamData: type BULKIO.SDDSStreamDefinition @@ -1219,9 +1224,9 @@ def __init__(self, def _createArraySrcInst(self, srcPortType): if srcPortType != "_BULKIO__POA.dataXML": - return _bulkio_data_helpers.ArraySource(eval(srcPortType)) + return bulkio_data_helpers.ArraySource(eval(srcPortType)) else: - return _bulkio_data_helpers.XmlArraySource(eval(srcPortType)) + return bulkio_data_helpers.XmlArraySource(eval(srcPortType)) def start(self): @@ -1605,13 +1610,13 @@ def _pushPacket(self, int(currentSampleTime), currentSampleTime - int(currentSampleTime)) if srcPortType != "_BULKIO__POA.dataXML": - _bulkio_data_helpers.ArraySource.pushPacket(arraySrcInst, + bulkio_data_helpers.ArraySource.pushPacket(arraySrcInst, data = data, T = T, EOS = EOS, streamID = streamID) else: - _bulkio_data_helpers.XmlArraySource.pushPacket(arraySrcInst, + bulkio_data_helpers.XmlArraySource.pushPacket(arraySrcInst, data = data, EOS = EOS, streamID = streamID) @@ -1625,9 +1630,9 @@ def _pushSRIAllConnectedPorts(self, sri): def _pushSRI(self, arraySrcInst, srcPortType, sri): if srcPortType != "_BULKIO__POA.dataXML": #print "_pushSRI ", sri - _bulkio_data_helpers.ArraySource.pushSRI(arraySrcInst, sri) + bulkio_data_helpers.ArraySource.pushSRI(arraySrcInst, sri) else: - _bulkio_data_helpers.XmlArraySource.pushSRI(arraySrcInst, sri) + bulkio_data_helpers.XmlArraySource.pushSRI(arraySrcInst, sri) def waitAllPacketsSent(self, timeout=None): """ @@ -1656,9 +1661,15 @@ def stop(self): raise AssertionError, self.className + ":stop() failed to exit thread" class DataSink(_SinkBase): - def __init__(self): + """ + To use a different sink (for custom data processing), assign the new class to sinkClass + To use a different sink for XML data, assign the new class to sinkXmlClass + """ + def __init__(self, sinkClass=bulkio_data_helpers.ArraySink, sinkXmlClass=bulkio_data_helpers.XmlArraySink): fmts=['char','short','long','float','double','longlong','octet','ushort', 'ulong', 'ulonglong', 'file','xml' ] _SinkBase.__init__(self, formats=fmts) + self.sinkClass = sinkClass + self.sinkXmlClass = sinkXmlClass def getPort(self, portName): if _domainless._DEBUG == True: @@ -1668,9 +1679,9 @@ def getPort(self, portName): # Set up output array sink if str(portName) == "xmlIn": - self._sink = _bulkio_data_helpers.XmlArraySink(eval(self._sinkPortType)) + self._sink = self.sinkXmlClass(eval(self._sinkPortType)) else: - self._sink = _bulkio_data_helpers.ArraySink(eval(self._sinkPortType)) + self._sink = self.sinkClass(eval(self._sinkPortType)) if self._sink != None: self._sinkPortObject = self._sink.getPort() @@ -1793,8 +1804,12 @@ def setup(self,portIOR, dataType=None, componentName=None, usesPortName=None): pass class probeBULKIO(_SinkBase): - def __init__(self): + """ + To use a different sink (for custom data processing), assign the new class to sinkClass + """ + def __init__(self, sinkClass=bulkio_data_helpers.ProbeSink): _SinkBase.__init__(self) + self._sinkClass = sinkClass def getPort(self, portName): if _domainless._DEBUG == True: @@ -1803,7 +1818,7 @@ def getPort(self, portName): self._sinkPortType = self.getPortType(portName) # Set up output array sink - self._sink = _bulkio_data_helpers.ProbeSink(eval(self._sinkPortType)) + self._sink = self._sinkClass(eval(self._sinkPortType)) if self._sink != None: self._sinkPortObject = self._sink.getPort() diff --git a/redhawk/src/testing/tests/test_13_TestSB.py b/redhawk/src/testing/tests/test_13_TestSB.py index 237785002..4da79aa51 100644 --- a/redhawk/src/testing/tests/test_13_TestSB.py +++ b/redhawk/src/testing/tests/test_13_TestSB.py @@ -39,6 +39,7 @@ from ossie.utils import sb, type_helpers from ossie.utils.bulkio import bulkio_helpers from ossie.events import ChannelManager, Subscriber, Publisher +from ossie.utils.bulkio import bulkio_data_helpers from _unitTestHelpers import scatest, runtestHelpers import traceback @@ -2067,6 +2068,47 @@ def wait_on_data( sink ): self.assertEquals(data[2][1][1].xdelta, 0.001) self.assertEquals(data[2][2][1].xdelta, 0.0001) + class customSink(bulkio_data_helpers.ArraySink): + def __init__(self, porttype): + bulkio_data_helpers.ArraySink.__init__(self, porttype) + + def pushSRI(self, H): + _H = H + _H.xdelta = H.xdelta * 2 + self.sri = _H + self.sris.append([len(self.data), _H]) + + def test_CustomDataSink(self): + """ + Verify that provide SRI is handled + """ + def wait_on_data( sink ): + _timeout = 1 + begin_time = time.time() + estimate = sink.getDataEstimate() + while estimate.num_timestamps != 3: + time.sleep(0.1) + estimate = sink.getDataEstimate() + if time.time() - begin_time > _timeout: + break + + src = sb.DataSource(dataFormat='float') + snk = sb.DataSink(sinkClass=self.customSink) + src.connect(snk) + sb.start() + src.push([1,2,3,4,5],sampleRate=100) + src.push([1,2,3,4,5],sampleRate=1000) + src.push([1,2,3,4,5],sampleRate=10000) + wait_on_data(snk) + data=snk.getData(tstamps=True,sris=True) + self.assertEquals(len(data[2]), 3) + self.assertEquals(data[2][0][0], 0) + self.assertEquals(data[2][1][0], 5) + self.assertEquals(data[2][2][0], 10) + self.assertEquals(data[2][0][1].xdelta, 0.02) + self.assertEquals(data[2][1][1].xdelta, 0.002) + self.assertEquals(data[2][2][1].xdelta, 0.0002) + def test_DataSourceSRI(self): """ Verify that provide SRI is handled From 0d5c20bddd8665513dde86136afd3bbd08815a10 Mon Sep 17 00:00:00 2001 From: 8530 <8530@vm-131.vsi-corp.com> Date: Fri, 5 May 2017 08:38:54 -0400 Subject: [PATCH 0790/1644] wip trying to clean up presentation when tracking changes in sdds header --- .../python/ossie/utils/sb/__init__.py | 3 + .../python/ossie/utils/sb/helpers.py | 34 ++ .../python/ossie/utils/sb/io_helpers.py | 28 +- .../python/ossie/utils/sdds/__init__.py | 1 + .../python/ossie/utils/sdds/sdds_analyzer.py | 172 +++++++++++ .../python/ossie/utils/sdds/sdds_pkt.py | 290 +++++++++++------- .../python/ossie/utils/sdds/sdds_time.py | 1 + 7 files changed, 420 insertions(+), 109 deletions(-) create mode 100644 redhawk/src/base/framework/python/ossie/utils/sb/helpers.py create mode 100644 redhawk/src/base/framework/python/ossie/utils/sdds/sdds_analyzer.py diff --git a/redhawk/src/base/framework/python/ossie/utils/sb/__init__.py b/redhawk/src/base/framework/python/ossie/utils/sb/__init__.py index 6fed9a281..5cf7038bc 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sb/__init__.py +++ b/redhawk/src/base/framework/python/ossie/utils/sb/__init__.py @@ -127,5 +127,8 @@ # BULKIO is not installed pass +import helpers +from helpers import * + from plots import * from audio import * diff --git a/redhawk/src/base/framework/python/ossie/utils/sb/helpers.py b/redhawk/src/base/framework/python/ossie/utils/sb/helpers.py new file mode 100644 index 000000000..27069fde2 --- /dev/null +++ b/redhawk/src/base/framework/python/ossie/utils/sb/helpers.py @@ -0,0 +1,34 @@ + +from pydoc import pager as _pager + +__all__ = [ 'PagerWithHeader', + 'Pager' + ] + +def PagerWithHeader( src_generator, num_lines=25, header=None, repeat_header=None): + """ + Apply simple pager controller to the ouptput of a specified generator. + + src_generator - a generator object that will yield lines to display + num_lines - number of lines to display before requesting manual input + header - a header row to display, this can be multi-line object + repeat_header - number of lines to repeat between header blocks + """ + for index,line in enumerate(src_generator): + if header and repeat_header: + if (index % repeat_header) == 0 : + if type(header) == list: + for x in header: + print x + else: + print header + if index % num_lines == 0 and index: + input=raw_input("Hit any key to continue press q to quit ") + if input.lower() == 'q': + break + else: + print line + + +def Pager( doc ): + _pager(doc) diff --git a/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py b/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py index 5d739cf1b..d2a059081 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py +++ b/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py @@ -50,6 +50,7 @@ import copy as _copy import omniORB as _omniORB import CosEventComm__POA +import traceback from ossie.utils.model import PortSupplier, OutputBase from ossie.utils.model.connect import ConnectionManager @@ -1133,6 +1134,12 @@ def __init__(self): self._blocking = True self._streamdefs = {} + def start(self): + pass + + def stop(self): + pass + def attach(self, streamData=None, name=None): """ streamData: type BULKIO.SDDSStreamDefinition @@ -1173,7 +1180,7 @@ def detach(self, attachId=''): def _createArraySrcInst(self, srcPortType): return self._src - def grabStreamDef( self, name=None, pkts=1000, block=True ): + def getStreamDef( self, name=None, pkts=1000, block=True, returnSddsAnalyzer=True): # grab data if stream definition is available sdef =None aid=name @@ -1193,7 +1200,7 @@ def grabStreamDef( self, name=None, pkts=1000, block=True ): return self.grabData( sdef.multicastAddress, sdef.port, sdef.vlan, packets, block=block) - def grabData( self, mgroup, hostip, port=29495, vlan=0, pkts=1000, pktlen=1080, sdds=True, block=True ): + def getData( self, mgroup, hostip, port=29495, vlan=0, pkts=1000, pktlen=1080, sdds=True, block=True, returnSddsAnalyzer=True): totalRead=0.0 startTime = _time.time() sock = None @@ -1201,7 +1208,7 @@ def grabData( self, mgroup, hostip, port=29495, vlan=0, pkts=1000, pktlen=1080, blen=10240 bytesRead=0 requestedBytes=pkts*pktlen - data=None + data=[] rawdata='' try: try: @@ -1222,21 +1229,30 @@ def grabData( self, mgroup, hostip, port=29495, vlan=0, pkts=1000, pktlen=1080, print "Capturing Socket Interface: (MULTICAST) Host Interface: " + hostip + " Multicast: " + mgroup + " Port: "+ str(port) else: print "Capturing Socket Interface: (UDP) Host Interface: " + hostip + " Source Address: " + mgroup + " Port: "+ str(port) - while bytesRead < requestedBytes: + ncnt=0 + while totalRead < requestedBytes: rcvddata = sock.recv(blen,_socket.MSG_WAITALL) - rawdata=rawdata+rcvdata + rawdata=rawdata+rcvddata data=data+list(rcvddata) totalRead = totalRead + len(rcvddata) + ncnt += 1 + print " read ", ncnt, " pkt ", len(rcvddata) except KeyboardInterrupt,e : + traceback.print_exc() print "Exception during packet capture: " + str(e) except Exception, e : + traceback.print_exc() print "Exception during packet capture: " + str(e) finally: endTime=_time.time() deltaTime=endTime -startTime if sock: sock.close() print "Elapsed Time: ", deltaTime, " Total Data (kB): ", totalRead/1000.0, " Rate (kBps): ", (totalRead/1000.0)/deltaTime - return data, rawdata, (pktlen,pkts,totalRead) + if returnSddsAnalyzer: + from ossie.utils.sdds import SDDSAnalyzer + return SDDSAnalyzer( pkts, data, rawdata, totalRead, pktlen ) + else: + return data, rawdata, (pktlen,pkts,totalRead) class DataSource(_SourceBase): diff --git a/redhawk/src/base/framework/python/ossie/utils/sdds/__init__.py b/redhawk/src/base/framework/python/ossie/utils/sdds/__init__.py index 58f1c6d33..7dd6a08ab 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sdds/__init__.py +++ b/redhawk/src/base/framework/python/ossie/utils/sdds/__init__.py @@ -20,3 +20,4 @@ from sdds_time import * from sdds_pkt import * +from sdds_analyzer import * diff --git a/redhawk/src/base/framework/python/ossie/utils/sdds/sdds_analyzer.py b/redhawk/src/base/framework/python/ossie/utils/sdds/sdds_analyzer.py new file mode 100644 index 000000000..b55716e3f --- /dev/null +++ b/redhawk/src/base/framework/python/ossie/utils/sdds/sdds_analyzer.py @@ -0,0 +1,172 @@ + +from binascii import hexlify as _hexify +from StringIO import StringIO +import ossie.utils.sb.helpers as _helpers +import sdds_pkt as _sdds_pkt +import traceback + +__all__ = [ 'SDDSAnalyzer' ] + +class SDDSAnalyzer(object): + """ + + Return a SDDS Analyzer object that can process a set list of raw bytes as SDDS packets and can perform the + following actions: + + trackChanges - montior fsn, bps, dmode, freq, sample rate, time stamps, ttv, changes between runs of packets + dumpRawPackets() - dump raw packets with contents managed by an optional Pager + dumpPackets() - dump packets with bit representations, contents managed by an optional Pager + getPackets - returns a generator object for access packets in a looping construct + + """ + _VAILID_VAL_='+' + _TRACK_OK_='-' + _TRACK_ERROR_='***' + + def __init__(self, pkts, data, raw_data, total_bytes_read, pkt_len=1080 ): + self.pkts_ = pkts + self.data_ = data + self.raw_data_ = raw_data + self.pkt_len_ = pkt_len + self.total_bytes_read = total_bytes_read + + def dumpRawPackets(self, pkt_start=0, pkt_end=None, row_width=80, bytes_per_group=2, pkt_len=None, use_pager=True ): + if pkt_end == None: + pkt_end = self.pkts_ + if pkt_len: + pkt_end = self.pkts_ + + if pkt_len == None: pkt_len = self.pkt_len_ + genf=self._gen_hex_dump( self.raw_data_, pkt_start, pkt_len, row_width, bytes_per_group ) + res = StringIO() + for i, line in enumerate(genf,pkt_start): + if i < pkt_end: + print >>res, 'pkt:'+str(i) + ' ' + line + else: + break + + if use_pager: + _helpers.Pager( res.getvalue() ) + else: + print res.getvalue() + + def dumpPackets(self, pkt_start=0, pkt_end=None, payload_start=0, payload_end=40, raw_payload=False, header_only=False, use_pager=True ): + genf=self._gen_packet( self.raw_data_, pkt_start ) + if pkt_end == None: pkt_end = self.pkts_ + res = StringIO() + for i, pkt in enumerate(genf,pkt_start): + if i < pkt_end: + print >>res, 'Packet: ', str(i) + print >>res, pkt.header_and_payload(payload_start, payload_end, header_only=header_only, raw=raw_payload ) + else: + break + + if use_pager: + _helpers.Pager( res.getvalue() ) + else: + print res.getvalue() + + def _cmp_pkt( self, res, last_pkt, next_pkt, last_tstamp, last_nsamps ): + if last_pkt: + last_pkt.inc() + if last_pkt.get_fsn() != next_pkt.get_fsn() : + res['fsn']=self._TRACK_ERROR_ + + if last_pkt and last_pkt.get_dmode() != next_pkt.get_dmode() : + res['dmode']=self._TRACK_ERROR_ + + if last_pkt and last_pkt.get_bps() != next_pkt.get_bps() : + res['bps']=self._TRACK_ERROR_ + + if last_pkt and last_pkt.get_freq() != next_pkt.get_freq() : + res['freq']=self._TRACK_ERROR_ + + if last_pkt and last_pkt.get_rate() != next_pkt.get_rate() : + res['rate']=self._TRACK_ERROR_ + + if last_pkt: + if last_pkt.get_ttv(): res['ttv']=self._VALID_VAL_ + if last_pkt.get_ttv() != next_pkt.get_ttv(): + res['ttv']=self._TRACK_ERROR_ + + if last_tstamp: + # check that we have a good timestamp to check against + if next_pkt.get_ttv(): + if res['freq'] == False: + rate=pkt.get_freq(); + t2 = next_pkt.get_time() + offset = 1.0/rate*last_nsamps + t_ck = sdds_time.add( last_tstamp, offset ) + if sdds_time.compare( t2, t_chk ) == False: + res['timeslip']=self._TRACK_ERROR_ + else: + res['timeslip']=self._TRACK_ERROR_ + + + def trackChanges(self, pkt_start=0, pkt_end=None, repeat_header=20, use_pager=True ): + genf=self._gen_packet( self.raw_data_, pkt_start ) + if pkt_end == None: pkt_end = self.pkts_ + res = StringIO() + keys = [ 'pkt', 'fsn', 'dmode', 'bps', 'freq', 'rate', 'timeslip', 'ttv' ] + hdrs = [ 'PKT', 'SEQ', 'FMT', 'BPS', 'FREQ', 'CLK', 'TIME SLIP', 'TIME VALID'] + hdr_fmt='{pkt:^5s} {fsn:^5s} {dmode:^5s} {bps:^5s} {freq:^5s} {rate:^5s} {timeslip:^9s} {ttv:^10s}' + line_fmt='{pkt:^5d} {fsn:^5s} {dmode:^5s} {bps:^5s} {freq:^5s} {rate:^5s} {timeslip:^9s} {ttv:^10s}' + last_pkt = None + last_tstamp=None + last_nsamps=0 + for i, pkt in enumerate(genf,pkt_start): + if ( i % repeat_header ) == 0: + print >>res, hdr_fmt.format( **dict(zip(keys,hdrs))) + + cmp_res = dict.fromkeys( keys, self._TRACK_OK_ ) + self._cmp_pkt( cmp_res, last_pkt, pkt, last_tstamp, last_nsamps ) + cmp_res['pkt']=i + + dline=line_fmt.format( **cmp_res ) + print >>res, dline + if pkt.get_ttv() : + last_tstamp=pkt.get_SDDSTime() + last_nsamp=0 + + # keep running count of samples + last_nsamps += pkt.get_samples_for_bps() + last_pkt=pkt + + if use_pager: + _helpers.Pager( res.getvalue() ) + else: + print res.getvalue() + + def getPacketIterator(self, pkt_start=0, pkt_end=None ): + genf=self._gen_packet( self.raw_data_, pkt_start ) + if pkt_end == None: pkt_end = self.pkts_ + for i, pkt in enumerate(genf,pkt_start): + if i < pkt_end: + yield i,pkt + else: + StopIteration + + def getPackets(self, pkt_start=0, pkt_end=None ): + res=[] + for i, pkt in self.getPacketIterator( pkt_start, pkt_end ): + res.append(pkt) + return res + + def _gen_hex_dump( self, data, pkt_start, pkt_len, max_row_width=80, bytes_per_group=2 ): + # break on pkt length + bstart = pkt_start*self.pkt_len_ + pkt_iter=xrange( bstart, len(data), pkt_len) + for x in pkt_iter: + raw_pkt = data[x:x+max_row_width] + d_iter = xrange(0, len(raw_pkt), bytes_per_group) + yield ' '.join( [ _hexify(raw_pkt[i:i+bytes_per_group]) for i in d_iter ] ) + + def _gen_packet( self, data, pkt_start ): + # break on pkt length + bstart = pkt_start*self.pkt_len_ + pkt_iter=xrange( bstart, len(data), self.pkt_len_ ) + for x in pkt_iter: + raw_pkt = data[x:x+self.pkt_len_] + pkt=_sdds_pkt.sdds_packet(raw_pkt) + yield pkt + diff --git a/redhawk/src/base/framework/python/ossie/utils/sdds/sdds_pkt.py b/redhawk/src/base/framework/python/ossie/utils/sdds/sdds_pkt.py index 353090de5..3c4cb1f5a 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sdds/sdds_pkt.py +++ b/redhawk/src/base/framework/python/ossie/utils/sdds/sdds_pkt.py @@ -21,6 +21,28 @@ import time import datetime +__all__ = [ + 'format_identifier', + 'frame_sequence', + 'msptr_data', + 'ttag_info_struct', + 'ttag_info_union', + 'ttag_values', + 'ttag_info', + 'ssc_info_struct', + 'ssd_data', + 'aad_data', + 'sdds_header', + 'sdds_sb_payload', + 'sdds_cb_payload', + 'sdds_si_payload', + 'sdds_ci_payload', + 'sdds_sn_sample', + 'sdds_sn_payload', + 'sdds_sf_payload', + 'sdds_payload', + 'sdds_packet', +] def BitsToNumber(sbits, reverse=False ): tbits=sbits[:] @@ -43,11 +65,13 @@ class format_identifier(ctypes.Structure): ('snp',ctypes.c_uint8,1), ('cx',ctypes.c_uint8,1) ] - def __new__(cls,buf=None): - if buf: - return cls.from_buffer_copy(buf) + def __new__(cls,*args, **kwargs ): + if len(args) > 0 or 'buf' in kwargs: + if len(args) > 0: + return cls.from_buffer_copy(args[0]) + return cls.from_buffer_copy(kwargs['buf']) else: - return super(format_identifier,cls).__new__(cls) + return super(format_identifier,cls).__new__(cls,*args,**kwags) def __init__(self,data=None): self.sf = 1 @@ -95,11 +119,13 @@ class frame_sequence(ctypes.BigEndianStructure): _pack_ = 1 _fields_ = [ ('seq',ctypes.c_ushort,16) ] - def __new__(cls,buf=None): - if buf: - return cls.from_buffer_copy(buf) + def __new__(cls,*args, **kwargs ): + if len(args) > 0 or 'buf' in kwargs: + if len(args) > 0: + return cls.from_buffer_copy(args[0]) + return cls.from_buffer_copy(kwargs['buf']) else: - return super(frame_sequence,cls).__new__(cls) + return super(frame_sequence,cls).__new__(cls,*args,**kwags) def __init__(self,data=None): self.seq = 0 @@ -127,11 +153,13 @@ class msptr_data (ctypes.Structure): _fields_ = [ ('msptr',ctypes.c_ushort,16), ('msdelta',ctypes.c_ushort,16) ] - def __new__(cls,buf=None): - if buf: - return cls.from_buffer_copy(buf) + def __new__(cls,*args, **kwargs ): + if len(args) > 0 or 'buf' in kwargs: + if len(args) > 0: + return cls.from_buffer_copy(args[0]) + return cls.from_buffer_copy(kwargs['buf']) else: - return super(msptr_data,cls).__new__(cls) + return super(msptr_data,cls).__new__(cls,*args,**kwags) def __init__(self,data=None): self.msptr=0 @@ -164,11 +192,13 @@ class ttag_info_struct(ctypes.Structure): ('pad1',ctypes.c_uint8,3), ('pad3',ctypes.c_uint16,16) ] - def __new__(cls,buf=None): - if buf: - return cls.from_buffer_copy(buf) + def __new__(cls,*args, **kwargs ): + if len(args) > 0 or 'buf' in kwargs: + if len(args) > 0: + return cls.from_buffer_copy(args[0]) + return cls.from_buffer_copy(kwargs['buf']) else: - return super(ttag_info_struct,cls).__new__(cls) + return super(ttag_info_struct,cls).__new__(cls,*args,**kwags) def __init__(self,data=None): self.ttv=0 @@ -239,11 +269,13 @@ class ttag_info_union(ctypes.Union): _fields_ = [ ('msptr', msptr_data), ('info', ttag_info_struct )] - def __new__(cls,buf=None): - if buf: - return cls.from_buffer_copy(buf) + def __new__(cls,*args, **kwargs ): + if len(args) > 0 or 'buf' in kwargs: + if len(args) > 0: + return cls.from_buffer_copy(args[0]) + return cls.from_buffer_copy(kwargs['buf']) else: - return super(ttag_info_union,cls).__new__(cls) + return super(ttag_info_union,cls).__new__(cls,*args,**kwags) def __init__(self,data=None): pass @@ -262,11 +294,13 @@ class ttag_values(ctypes.BigEndianStructure): _fields_ = [ ('ttag',ctypes.c_uint64), ('ttage',ctypes.c_uint32) ] - def __new__(cls,buf=None): - if buf: - return cls.from_buffer_copy(buf) + def __new__(cls,*args, **kwargs ): + if len(args) > 0 or 'buf' in kwargs: + if len(args) > 0: + return cls.from_buffer_copy(args[0]) + return cls.from_buffer_copy(kwargs['buf']) else: - return super(ttag_values,cls).__new__(cls) + return super(ttag_values,cls).__new__(cls,*args,**kwags) def __init__(self,data=None): self.ttag=0 @@ -302,11 +336,13 @@ class ttag_info(ctypes.Structure): _fields_ = [ ('info', ttag_info_union ), ('tstamp', ttag_values ) ] - def __new__(cls,buf=None): - if buf: - return cls.from_buffer_copy(buf) + def __new__(cls,*args, **kwargs ): + if len(args) > 0 or 'buf' in kwargs: + if len(args) > 0: + return cls.from_buffer_copy(args[0]) + return cls.from_buffer_copy(kwargs['buf']) else: - return super(ttag_info,cls).__new__(cls) + return super(ttag_info,cls).__new__(cls,*args,**kwags) def __init__(self,data=None): pass @@ -360,11 +396,13 @@ class ssc_info_struct(ctypes.BigEndianStructure): _fields_ = [ ('dfdt',ctypes.c_int32), ('freq',ctypes.c_uint64) ] - def __new__(cls,buf=None): - if buf: - return cls.from_buffer_copy(buf) + def __new__(cls,*args, **kwargs ): + if len(args) > 0 or 'buf' in kwargs: + if len(args) > 0: + return cls.from_buffer_copy(args[0]) + return cls.from_buffer_copy(kwargs['buf']) else: - return super(ssc_info_struct,cls).__new__(cls) + return super(ssc_info_struct,cls).__new__(cls,*args,**kwags) def __init__(self,data=None): pass @@ -402,11 +440,13 @@ class ssd_data(ctypes.BigEndianStructure): _pack_ = 1 _fields_ = [ ('data', ctypes.c_uint16* DATA_LEN ) ] - def __new__(cls,buf=None): - if buf: - return cls.from_buffer_copy(buf) + def __new__(cls,*args, **kwargs ): + if len(args) > 0 or 'buf' in kwargs: + if len(args) > 0: + return cls.from_buffer_copy(args[0]) + return cls.from_buffer_copy(kwargs['buf']) else: - return super(ssd_data,cls).__new__(cls) + return super(ssd_data,cls).__new__(cls,*args,**kwags) def __init__(self,data=None): pass @@ -425,11 +465,13 @@ class aad_data(ctypes.BigEndianStructure): _pack_ = 1 _fields_ = [ ('data', ctypes.c_uint8*DATA_LEN) ] - def __new__(cls,buf=None): - if buf: - return cls.from_buffer_copy(buf) + def __new__(cls,*args, **kwargs ): + if len(args) > 0 or 'buf' in kwargs: + if len(args) > 0: + return cls.from_buffer_copy(args[0]) + return cls.from_buffer_copy(kwargs['buf']) else: - return super(aad_data,cls).__new__(cls) + return super(aad_data,cls).__new__(cls,*args,**kwags) def __init__(self,data=None): pass @@ -456,14 +498,15 @@ class sdds_header(ctypes.Structure): ('aad', aad_data ), ] - def __new__(cls,buf=None): - if buf: - return cls.from_buffer_copy(buf) + def __new__(cls,*args, **kwargs ): + if len(args) > 0 or 'buf' in kwargs: + if len(args) > 0: + return cls.from_buffer_copy(args[0]) + return cls.from_buffer_copy(kwargs['buf']) else: - return super(sdds_header,cls).__new__(cls) + return super(sdds_header,cls).__new__(cls,*args,**kwags) def __init__(self,data=None, skip_parity=True): - self._skip_parity=skip_parity pass @@ -476,9 +519,9 @@ def __str__(self): ' aad: '+str(self.aad) - def inc(self): + def inc(self, skip_parity=None): self.fsn.inc() - if self._skip_parity: + if skip_parity or self._skip_parity: if self.fsn.seq % sdds_header.PARITY_SEQ_NUMBER == 31: self.fsn.inc() @@ -639,17 +682,19 @@ class sdds_sb_payload(ctypes.BigEndianStructure): _pack_ = 1 _fields_ = [ ('data', ctypes.c_uint8 *PAYLOAD_SIZE ) ] - def __new__(cls,buf=None): - if buf: - return cls.from_buffer_copy(buf) + def __new__(cls,*args, **kwargs ): + if len(args) > 0 or 'buf' in kwargs: + if len(args) > 0: + return cls.from_buffer_copy(args[0]) + return cls.from_buffer_copy(kwargs['buf']) else: - return super(sdds_sb_payload,cls).__new__(cls) + return super(sdds_sb_payload,cls).__new__(cls,*args,**kwags) def __init__(self,data=None): pass - def get_data(self): - return self.data[:] + def get_data(self, start=None, end=None): + return self.data[start:end] def set_data(self, samples ): if type(samples) == list: @@ -673,17 +718,19 @@ class sdds_cb_payload(ctypes.BigEndianStructure): _pack_ = 1 _fields_ = [ ('data', ctypes.c_uint8 *PAYLOAD_SIZE ) ] - def __new__(cls,buf=None): - if buf: - return cls.from_buffer_copy(buf) + def __new__(cls,*args, **kwargs ): + if len(args) > 0 or 'buf' in kwargs: + if len(args) > 0: + return cls.from_buffer_copy(args[0]) + return cls.from_buffer_copy(kwargs['buf']) else: - return super(sdds_cb_payload,cls).__new__(cls) + return super(sdds_cb_payload,cls).__new__(cls,*args,**kwags) def __init__(self,data=None): pass - def get_data(self): - return self.data[:] + def get_data(self, start=None, end=None): + return self.data[start:end] def set_data(self, samples ): if type(samples) == list: @@ -707,17 +754,19 @@ class sdds_si_payload(ctypes.BigEndianStructure): _pack_ = 1 _fields_ = [ ('data', ctypes.c_uint16 * PAYLOAD_SIZE) ] - def __new__(cls,buf=None): - if buf: - return cls.from_buffer_copy(buf) + def __new__(cls,*args, **kwargs ): + if len(args) > 0 or 'buf' in kwargs: + if len(args) > 0: + return cls.from_buffer_copy(args[0]) + return cls.from_buffer_copy(kwargs['buf']) else: - return super(sdds_si_payload,cls).__new__(cls) + return super(sdds_si_payload,cls).__new__(cls,*args,**kwags) def __init__(self,data=None): pass - def get_data(self): - return self.data[:] + def get_data(self, start=None, end=None): + return self.data[start:end] def set_data(self, samples ): if type(samples) == list: @@ -740,17 +789,19 @@ class sdds_ci_payload(ctypes.BigEndianStructure): _pack_ = 1 _fields_ = [ ('data', ctypes.c_uint16 * PAYLOAD_SIZE) ] - def __new__(cls,buf=None): - if buf: - return cls.from_buffer_copy(buf) + def __new__(cls,*args, **kwargs ): + if len(args) > 0 or 'buf' in kwargs: + if len(args) > 0: + return cls.from_buffer_copy(args[0]) + return cls.from_buffer_copy(kwargs['buf']) else: - return super(sdds_ci_payload,cls).__new__(cls) + return super(sdds_ci_payload,cls).__new__(cls,*args,**kwags) def __init__(self,data=None): pass - def get_data(self): - return self.data[:] + def get_data(self, start=None, end=None): + return self.data[start:end] def set_data(self, samples ): if type(samples) == list: @@ -773,11 +824,13 @@ class sdds_sn_sample(ctypes.BigEndianStructure): ('sn1', ctypes.c_uint8,4 ) ] - def __new__(cls,buf=None): - if buf: - return cls.from_buffer_copy(buf) + def __new__(cls,*args, **kwargs ): + if len(args) > 0 or 'buf' in kwargs: + if len(args) > 0: + return cls.from_buffer_copy(args[0]) + return cls.from_buffer_copy(kwargs['buf']) else: - return super(sdds_sn_sample,cls).__new__(cls) + return super(sdds_sn_sample,cls).__new__(cls,*args,**kwags) def __init__(self,data=None): pass @@ -797,18 +850,20 @@ class sdds_sn_payload(ctypes.Structure): _pack_ = 1 _fields_ = [ ('data', sdds_sn_sample*PAYLOAD_SIZE) ] - def __new__(cls,buf=None): - if buf: - return cls.from_buffer_copy(buf) + def __new__(cls,*args, **kwargs ): + if len(args) > 0 or 'buf' in kwargs: + if len(args) > 0: + return cls.from_buffer_copy(args[0]) + return cls.from_buffer_copy(kwargs['buf']) else: - return super(sdds_sn_payload,cls).__new__(cls) + return super(sdds_sn_payload,cls).__new__(cls,*args,**kwags) def __init__(self,data=None): pass - def get_data(self): + def get_data(self, start=None, end=None): _ret=[] - for x in self.data[:]: + for x in self.data[start:end]: _ret += x.get_data() return _ret @@ -833,17 +888,19 @@ class sdds_sf_payload(ctypes.BigEndianStructure): _pack_ = 1 _fields_ = [ ('data', ctypes.c_float * PAYLOAD_SIZE ) ] - def __new__(cls,buf=None): - if buf: - return cls.from_buffer_copy(buf) + def __new__(cls,*args, **kwargs ): + if len(args) > 0 or 'buf' in kwargs: + if len(args) > 0: + return cls.from_buffer_copy(args[0]) + return cls.from_buffer_copy(kwargs['buf']) else: - return super(sdds_sf_payload,cls).__new__(cls) + return super(sdds_sf_payload,cls).__new__(cls,*args,**kwags) def __init__(self,data=None): pass - def get_data(self): - return self.data[:] + def get_data(self, start=None, end=None): + return self.data[start:end] def set_data(self, samples ): if type(samples) == list: @@ -872,20 +929,25 @@ class sdds_payload(ctypes.Union): ('sf', sdds_sf_payload ) ] - def __new__(cls,buf=None): - if buf: - return cls.from_buffer_copy(buf) + def __new__(cls,*args, **kwargs ): + if len(args) > 0 or 'buf' in kwargs: + if len(args) > 0: + return cls.from_buffer_copy(args[0]) + return cls.from_buffer_copy(kwargs['buf']) else: - return super(sdds_payload_struct,cls).__new__(cls) + return super(sdds_payload,cls).__new__(cls,*args,**kwags) def __init__(self,data=None): - pass + pass def __str__(self): - return ','.join( [ str(x) for x in self.raw[:40] ] ) + return ','.join( [ str(x) for x in self.raw[:40] ] ) + + def trim_payload(self, start=0, end=40): + return ','.join( [ str(x) for x in self.raw[start:end] ] ) - def get_data(self): - return self.raw[:] + def get_data(self, start=None, end=None): + return self.raw[start:end] def asBuffer(self): return buffer(self)[:] @@ -912,12 +974,13 @@ class sdds_packet(ctypes.Structure): _fields_ = [ ('header', sdds_header ), ('payload', sdds_payload ) ] - - def __new__(cls,buf=None): - if buf: - return cls.from_buffer_copy(buf) + def __new__(cls,*args, **kwargs ): + if len(args) > 0 or 'buf' in kwargs: + if len(args) > 0: + return cls.from_buffer_copy(args[0]) + return cls.from_buffer_copy(kwargs['buf']) else: - return super(sdds_packet,cls).__new__(cls) + return super(sdds_packet,cls).__new__(cls,*args,**kwags) def __init__(self,data=None, skip_parity=True): self._skip_parity=skip_parity @@ -927,8 +990,19 @@ def __str__(self): return ''.join(str(self.header)) + '\n' +\ ' payload: '+ ''.join(str(self.payload)) + def header_and_payload(self, start=0, end=40, header_only=False, raw=False ): + pkt_line=''.join(str(self.header)) + if header_only == False: + if raw: + pkt_line = pkt_line + '\n' +\ + ' payload: '+ ''.join(str(self.payload.trim_payload(start,end))) + else: + pkt_line = pkt_line + '\n' +\ + ' payload: '+ ''.join(str(self.get_data(start,end))) + return pkt_line + def inc(self): - self.header.inc() + self.header.inc(self._skip_parity) ## ## Format Identifier @@ -983,6 +1057,16 @@ def get_bps_for_mode(self, dmode ): if dmode == 7: bps=32 return bps + def get_samples_for_bps(self, bps=None ): + if bps == None: + bps=self.get_bps() + + for x in self.FORMATS.values(): + if x.has_key('bps' ) and x['bps'] == bps: + return x['samples'] + + return None + ## ## frame sequence ## @@ -1076,13 +1160,13 @@ def set_format(self, fmt): self.set_dmode( dm, cplx, bps=_fmt['bps']) - def get_data(self): + def get_data(self, start=None, end=None ): bps=self.header.get_bps() for k, v in sdds_packet.FORMATS.items(): if v['bps'] == bps : attr = getattr(self.payload, k.lower()) return v['get_data'](attr) - return self.payload.sb.get_data() + return self.payload.sb.get_data(start,end) def asBuffer(self): return buffer(self)[:] diff --git a/redhawk/src/base/framework/python/ossie/utils/sdds/sdds_time.py b/redhawk/src/base/framework/python/ossie/utils/sdds/sdds_time.py index 54c3b8c08..89ad77fc7 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sdds/sdds_time.py +++ b/redhawk/src/base/framework/python/ossie/utils/sdds/sdds_time.py @@ -32,6 +32,7 @@ def difference(t1, t2): else: tmp.pf250_ = Time.Two32 + ( tmp.pf250_ - t2.pf250_ ) tmp.ps250_ -= t2.ps250_ + 1; + return tmp def sum( t1, t2 ): tmp=_copy.copy(t1) From 2076bd0a94fa6dc57e212e57c02393b05f2e75fa Mon Sep 17 00:00:00 2001 From: 8530 <8530@vm-131.vsi-corp.com> Date: Fri, 5 May 2017 17:47:28 -0400 Subject: [PATCH 0791/1644] added in first row of values and complex --- .../python/ossie/utils/sdds/sdds_analyzer.py | 28 +++++++++++++---- .../python/ossie/utils/sdds/sdds_pkt.py | 30 +++++++++---------- 2 files changed, 37 insertions(+), 21 deletions(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/sdds/sdds_analyzer.py b/redhawk/src/base/framework/python/ossie/utils/sdds/sdds_analyzer.py index b55716e3f..ee50e89e9 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sdds/sdds_analyzer.py +++ b/redhawk/src/base/framework/python/ossie/utils/sdds/sdds_analyzer.py @@ -72,6 +72,9 @@ def _cmp_pkt( self, res, last_pkt, next_pkt, last_tstamp, last_nsamps ): if last_pkt.get_fsn() != next_pkt.get_fsn() : res['fsn']=self._TRACK_ERROR_ + if last_pkt and last_pkt.get_complex() != next_pkt.get_complex() : + res['cplx']=self._TRACK_ERROR_ + if last_pkt and last_pkt.get_dmode() != next_pkt.get_dmode() : res['dmode']=self._TRACK_ERROR_ @@ -91,10 +94,10 @@ def _cmp_pkt( self, res, last_pkt, next_pkt, last_tstamp, last_nsamps ): if last_tstamp: # check that we have a good timestamp to check against + t2 = next_pkt.get_SDDSTime() if next_pkt.get_ttv(): if res['freq'] == False: rate=pkt.get_freq(); - t2 = next_pkt.get_time() offset = 1.0/rate*last_nsamps t_ck = sdds_time.add( last_tstamp, offset ) if sdds_time.compare( t2, t_chk ) == False: @@ -102,15 +105,25 @@ def _cmp_pkt( self, res, last_pkt, next_pkt, last_tstamp, last_nsamps ): else: res['timeslip']=self._TRACK_ERROR_ + def _first_pkt( self, res, next_pkt ): + res['fsn'] = str(next_pkt.get_fsn()) + res['dmode']=str(next_pkt.get_dmode()) + res['cplx']=str(next_pkt.get_complex()) + res['bps']=str(next_pkt.get_bps()) + res['freq']=str(next_pkt.get_freq()) + res['rate']=str(next_pkt.get_rate()) + res['ttv']=str(next_pkt.get_ttv()) + t2 = next_pkt.get_SDDSTime() + res['timeslip']=str(t2) def trackChanges(self, pkt_start=0, pkt_end=None, repeat_header=20, use_pager=True ): genf=self._gen_packet( self.raw_data_, pkt_start ) if pkt_end == None: pkt_end = self.pkts_ res = StringIO() - keys = [ 'pkt', 'fsn', 'dmode', 'bps', 'freq', 'rate', 'timeslip', 'ttv' ] - hdrs = [ 'PKT', 'SEQ', 'FMT', 'BPS', 'FREQ', 'CLK', 'TIME SLIP', 'TIME VALID'] - hdr_fmt='{pkt:^5s} {fsn:^5s} {dmode:^5s} {bps:^5s} {freq:^5s} {rate:^5s} {timeslip:^9s} {ttv:^10s}' - line_fmt='{pkt:^5d} {fsn:^5s} {dmode:^5s} {bps:^5s} {freq:^5s} {rate:^5s} {timeslip:^9s} {ttv:^10s}' + keys = [ 'pkt', 'fsn', 'dmode', 'cplx', 'bps', 'freq', 'rate', 'ttv', 'timeslip' ] + hdrs = [ 'PKT', 'SEQ', 'FMT', 'CPLX', 'BPS', ' FREQ ', ' CLK ', 'TIME VALID', 'TIME SLIP' ] + hdr_fmt='{pkt:^5s} {fsn:^5s} {dmode:^5s} {cplx:^4s} {bps:^5s} {freq:^12s} {rate:^12s} {ttv:^10s} {timeslip:^9s}' + line_fmt='{pkt:^5d} {fsn:^5s} {dmode:^5s} {cplx:^4s} {bps:^5s} {freq:^12s} {rate:^12s} {ttv:^10s} {timeslip:^9s}' last_pkt = None last_tstamp=None last_nsamps=0 @@ -119,7 +132,10 @@ def trackChanges(self, pkt_start=0, pkt_end=None, repeat_header=20, use_pager=Tr print >>res, hdr_fmt.format( **dict(zip(keys,hdrs))) cmp_res = dict.fromkeys( keys, self._TRACK_OK_ ) - self._cmp_pkt( cmp_res, last_pkt, pkt, last_tstamp, last_nsamps ) + if i == pkt_start : + self._first_pkt( cmp_res, pkt ) + else: + self._cmp_pkt( cmp_res, last_pkt, pkt, last_tstamp, last_nsamps ) cmp_res['pkt']=i dline=line_fmt.format( **cmp_res ) diff --git a/redhawk/src/base/framework/python/ossie/utils/sdds/sdds_pkt.py b/redhawk/src/base/framework/python/ossie/utils/sdds/sdds_pkt.py index 3c4cb1f5a..51907bac9 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sdds/sdds_pkt.py +++ b/redhawk/src/base/framework/python/ossie/utils/sdds/sdds_pkt.py @@ -1013,12 +1013,12 @@ def get_complex(self): def set_complex(self, isComplex=False ): self.header.set_complex(isComplex) - def set_spectralsense(self, ison=False ): - self.header.set_spectralsense(ison) - def get_spectralsense(self, ison=False ): return self.header.get_spectralsense() + def set_spectralsense(self, ison=False ): + self.header.set_spectralsense(ison) + def get_vw(self): return self.header.get_vw() @@ -1031,6 +1031,9 @@ def get_bps(self): def set_bps(self, bps ): self.header.set_bps(bps) + def get_dmode(self): + return self.header.get_dmode() + def set_dmode(self,dm, cplx=False, calc_bps=True, bps=None): if self.ok_dmode(dm): self.header.set_dmode(dm) @@ -1043,9 +1046,6 @@ def set_dmode(self,dm, cplx=False, calc_bps=True, bps=None): def ok_dmode(self, dmode ): return dmode == 0 or dmode == 1 or dmode == 2 or dmode == 5 or dmode == 6 or dmode == 7; - def get_dmode(self): - return self.header.get_dmode() - def get_bps_for_mode(self, dmode ): bps=8 if dmode == 0: @@ -1089,25 +1089,25 @@ def clear_msptr( self): self.header.clear_msptr() def get_msdelta( self ): - self.header.get_msdelta() + return self.header.get_msdelta() def set_msdelta( self, val ): self.header.set_msdelta(val) + def get_msv(self): + return self.header.get_msv() + def set_msv(self, valid=True): self.header.set_msv(valid) - def get_msv(self): - self.header.get_msv() - def get_ttv(self): - self.header.get_ttv() + return self.header.get_ttv() def set_ttv(self, valid=True): self.header.set_ttv(valid) def get_sscv(self): - self.header.get_sscv() + return self.header.get_sscv() def set_sscv(self, valid=True): self.header.set_sscv(valid) @@ -1115,12 +1115,12 @@ def set_sscv(self, valid=True): def set_time(self, ps250, pf250 ): self.header.set_time(ps250, pf250) - def set_SDDSTime(self, sdds_time, ): - self.header.set_SDDSTime(sdds_time) - def get_SDDSTime(self): return self.header.get_SDDSTime() + def set_SDDSTime(self, sdds_time, ): + self.header.set_SDDSTime(sdds_time) + ## ## ssc - synchronous sample clock ## From e82a5b12c62ae8e5fb75427facb3eb2fdd426a39 Mon Sep 17 00:00:00 2001 From: 8530 <8530@vm-131.vsi-corp.com> Date: Tue, 9 May 2017 14:58:10 -0400 Subject: [PATCH 0792/1644] adding some comments to source files --- .../python/ossie/utils/sb/io_helpers.py | 3 +- .../python/ossie/utils/sdds/sdds_analyzer.py | 21 +++-- .../python/ossie/utils/sdds/sdds_pkt.py | 92 ++++++++++++++++++- 3 files changed, 107 insertions(+), 9 deletions(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py b/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py index d2a059081..8a94849a8 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py +++ b/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py @@ -1218,10 +1218,9 @@ def getData( self, mgroup, hostip, port=29495, vlan=0, pkts=1000, pktlen=1080, s except: pass - print " mgroup ", mgroup, " host ", hostip, " port ", port + #print " Capturing ", mgroup, " host ", hostip, " port ", port sock = _socket.socket(_socket.AF_INET, _socket.SOCK_DGRAM, _socket.IPPROTO_UDP) sock.setsockopt(_socket.SOL_SOCKET, _socket.SO_REUSEADDR, 1) - print "Port ", port sock.bind(("",port)) if ismulticast: mreq=struct.pack('4s4s',_socket.inet_aton(mgroup),_socket.inet_aton(hostip)) diff --git a/redhawk/src/base/framework/python/ossie/utils/sdds/sdds_analyzer.py b/redhawk/src/base/framework/python/ossie/utils/sdds/sdds_analyzer.py index ee50e89e9..d37880c4f 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sdds/sdds_analyzer.py +++ b/redhawk/src/base/framework/python/ossie/utils/sdds/sdds_analyzer.py @@ -9,14 +9,23 @@ class SDDSAnalyzer(object): """ - - Return a SDDS Analyzer object that can process a set list of raw bytes as SDDS packets and can perform the + The SDDSAnalyzer class can process a block of raw bytes as SDDS packets and perform the following actions: - trackChanges - montior fsn, bps, dmode, freq, sample rate, time stamps, ttv, changes between runs of packets - dumpRawPackets() - dump raw packets with contents managed by an optional Pager - dumpPackets() - dump packets with bit representations, contents managed by an optional Pager - getPackets - returns a generator object for access packets in a looping construct + trackChanges - track changes in the packet data for the field values: + fsn - frame sequence number + bps - bits per sample + dmode - data mode + freq - collected signal frequency + sample rate - sample rate of the data + time stamps - changes in time (only if ttv=1) + ttv - time tag value (controls time stamp check) + + dumpRawPackets - Dump the entire content as a data buffer with the results + managed by a pager + dumpPackets - dump packet fields and their data values, contents managed by a pager + getPacketsIterator - returns a generator object for access packets in a looping construct + getPackets - returns a list of sdds_packet objects """ _VAILID_VAL_='+' diff --git a/redhawk/src/base/framework/python/ossie/utils/sdds/sdds_pkt.py b/redhawk/src/base/framework/python/ossie/utils/sdds/sdds_pkt.py index 51907bac9..e7bd12d6d 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sdds/sdds_pkt.py +++ b/redhawk/src/base/framework/python/ossie/utils/sdds/sdds_pkt.py @@ -20,6 +20,96 @@ import ctypes import time import datetime +""" +Class definitions that represent SDDS packet structure. The classes make use of python +ctypes to pack and unpack bit fields into class's members. The fields of arranged in +a set format to correctly unpack from data packets that are in BigEndian format. For +extact field definitions and values consult the SDDS packet specification. + +To unpack a raw data buffer from a socket to an SDDS packet you +would perform the following: + + pkt = sdds_packet(data_buffer) + +The pkt object provides extraction of sdds header as well as +payload overlays for accessing the each of the following formats: + + raw: 1024 8 bit samples + sn: 2048 samples representing the two 4 bit samples packed into a byte + sb: 1024 8 bit samples + cb: 512 samples of interleaved I & Q data + si: 512 samples of 16 bit data + ci: 256 samples of 16 bit data I & Q data + sf: 256 samples of (32 bit) scalar float data + +In addition to the overlays, the pkt.get_data() method returns a copy of the data samples +in the correct format. + + +Format Identifier + Complex field + def get_complex(self) + def set_complex(self, isComplex=False ) + + SpectralSense field + def get_spectralsense(self, ison=False ): + def set_spectralsense(self, ison=False ): + + Very Wideband field + def get_vw(self): + def set_vw(self, isVeryWide=False ): + + Bits per sample + def get_bps(self): + def set_bps(self, bps ): + + Data Mode + def get_dmode(self): + def set_dmode(self,dm, cplx=False, calc_bps=True, bps=None): + + def get_bps_for_mode(self, dmode ): + def get_samples_for_bps(self, bps=None ): + + Frame Sequence number + def get_fsn(self): + def set_fsn(self, v ): + + Time Tag fields + def get_msptr( self ): + def set_msptr( self, val ): + + def get_msdelta( self ): + def set_msdelta( self, val ): + + def get_msv(self): + def set_msv(self, valid=True): + + def get_ttv(self): + def set_ttv(self, valid=True): + + def get_sscv(self): + def set_sscv(self, valid=True): + + def set_time(self, ps250, pf250 ): + def get_SDDSTime(self): + def set_SDDSTime(self, sdds_time, ): + + Synchronous Sample Clock + def get_freq(self): + def set_freq(self, freq): + + def get_rate(self): + def set_rate(self, freq): + + def get_dfdt(self): + def set_dfdt(self, freq): + + Payload Processing + def get_format(self): + def set_format(self, fmt): + def get_data(self, start=None, end=None ): + +""" __all__ = [ 'format_identifier', @@ -1013,7 +1103,7 @@ def get_complex(self): def set_complex(self, isComplex=False ): self.header.set_complex(isComplex) - def get_spectralsense(self, ison=False ): + def get_spectralsense(self ): return self.header.get_spectralsense() def set_spectralsense(self, ison=False ): From 044c4f556ec018594e9b7563eb708309d3bfc950 Mon Sep 17 00:00:00 2001 From: Ryan Bauman Date: Wed, 10 May 2017 10:36:14 -0400 Subject: [PATCH 0793/1644] RELENG-621 - add redhawk-integration-dist package to @redhawk-development group [ci skip] --- redhawk/src/releng/yumgroups.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/redhawk/src/releng/yumgroups.xml b/redhawk/src/releng/yumgroups.xml index 5e98d9298..3adcfa8de 100644 --- a/redhawk/src/releng/yumgroups.xml +++ b/redhawk/src/releng/yumgroups.xml @@ -33,6 +33,7 @@ with this program. If not, see http://www.gnu.org/licenses/. redhawk-devel redhawk-debuginfo redhawk-ide + redhawk-integration-dist redhawk-qt-tools redhawk-sdrroot-dev-mgr redhawk-sdrroot-dom-mgr @@ -66,4 +67,4 @@ with this program. If not, see http://www.gnu.org/licenses/. omniEvents-bootscripts - \ No newline at end of file + From 327df82cfa8a046d3dfc9dde1e05a0137b5f5d88 Mon Sep 17 00:00:00 2001 From: 8530 <8530@vm-131.vsi-corp.com> Date: Wed, 10 May 2017 10:39:10 -0400 Subject: [PATCH 0794/1644] fixed default port name issues for matchAllocationIdToStreamId, CF-1730 --- .../jinja/java/component/frontend/templates/resource_base.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/redhawk-codegen/redhawk/codegen/jinja/java/component/frontend/templates/resource_base.java b/redhawk-codegen/redhawk/codegen/jinja/java/component/frontend/templates/resource_base.java index 0541bb331..70251251e 100644 --- a/redhawk-codegen/redhawk/codegen/jinja/java/component/frontend/templates/resource_base.java +++ b/redhawk-codegen/redhawk/codegen/jinja/java/component/frontend/templates/resource_base.java @@ -247,7 +247,7 @@ public void matchAllocationIdToStreamId(final String allocation_id, final String connection_descriptor_struct tmp = new connection_descriptor_struct(); /*{% for port in component.ports if port.multiout %}*/ tmp.connection_id.setValue(allocation_id); - tmp.port_name.setValue("${port.javaname}"); + tmp.port_name.setValue("${port.name}"); tmp.stream_id.setValue(stream_id); this.connectionTable.getValue().add(tmp); /*{% endfor %}*/ From f9ac6697987da2fe6def3063276f998271f7ba7b Mon Sep 17 00:00:00 2001 From: Max Robert Date: Thu, 11 May 2017 14:45:00 -0400 Subject: [PATCH 0795/1644] Refs CF-350. Added stream API to DataSink to handle multiple stream ID (and multiple SRI) --- .../ossie/utils/bulkio/bulkio_data_helpers.py | 577 +++++++++++++++--- .../python/ossie/utils/sb/io_helpers.py | 37 +- redhawk/src/testing/tests/test_13_TestSB.py | 265 ++++++-- 3 files changed, 719 insertions(+), 160 deletions(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/bulkio/bulkio_data_helpers.py b/redhawk/src/base/framework/python/ossie/utils/bulkio/bulkio_data_helpers.py index 2b6fd20e2..baa37c3d1 100644 --- a/redhawk/src/base/framework/python/ossie/utils/bulkio/bulkio_data_helpers.py +++ b/redhawk/src/base/framework/python/ossie/utils/bulkio/bulkio_data_helpers.py @@ -32,7 +32,7 @@ from bulkio.bulkioInterfaces import BULKIO, BULKIO__POA except: pass -from ossie.utils import _uuid +from ossie.utils import _uuid, rhtime logging.basicConfig() log = logging.getLogger(__name__) @@ -195,7 +195,388 @@ def run(self, data, sri=None, pktsize=1024, startTime=0.0, sampleRate=1.0, compl T = BULKIO.PrecisionUTCTime(BULKIO.TCM_CPU, BULKIO.TCS_VALID, 0.0, int(currentSampleTime), currentSampleTime - int(currentSampleTime)) self.pushPacket([], T, True, self.sri.streamID) +def addUTCTime(time_1, time_2): + ''' + Return a UTCTime (or PrecisionUTCTime) value incremented by time_2 + ''' + fulltime = (time_1.twsec+time_1.tfsec) + float(time_2) + if isinstance(time_1, CF.UTCTime): + retval = rhtime.now() + else: + retval = bulkio_helpers.createCPUTimestamp() + retval.twsec = int(fulltime) + retval.tfsec = fulltime - retval.twsec + return retval + +def subUTCTime(time_1, time_2): + ''' + Return a UTCTime (or PrecisionUTCTime) value reduced by time_2 + ''' + fulltime = (time_1.twsec+time_1.tfsec) - float(time_2) + if isinstance(time_1, CF.UTCTime): + retval = rhtime.now() + else: + retval = bulkio_helpers.createCPUTimestamp() + retval.twsec = int(fulltime) + retval.tfsec = fulltime - retval.twsec + return retval + +def diffUTCTime(time_1, time_2): + ''' + Return the difference in time between 2 UTCTime (or PrecisionUTCTime) values + ''' + retval = (time_1.twsec+time_1.tfsec) - (time_2.twsec+time_2.tfsec) + return retval + +class BaseStream(object): + def __init__(self, parent, sri): + self._sri = sri + self._parent = parent + def sri(self): + return self._sri + +class DataBlock(object): + def __init__(self, sri, data, tstamps, new_sri): + self._sri = sri + self._data = data + self._new_sri = new_sri + self._tstamps = tstamps + def data(self): + return self._data + def sri(self): + return self._sri + def xdelta(self): + return self._sri.xdelta + def sriChanged(self): + return self._new_sri + def inputQueueFlushed(self): + return False + def getStartTime(self): + return self._tstamps[0][0] + def getTimestamps(self): + return self._tstamps + def getNetTimeDrift(self): + if len(self._tstamps) == 1: + return 0 + diff_time = diffUTCTime(self._tstamps[-1][0], self._tstamps[0][0]) + synth_time = self._sri.xdelta * len(self._data) + return abs(diff_time - synth_time) + def getMaxTimeDrift(self): + max_drift = 0 + for _diff in range(len(self._tstamps)-1): + diff_time = diffUTCTime(self._tstamps[_diff][0], self._tstamps[_diff-1][0]) + synth_time = self._sri.xdelta * self._tstamps[_diff][1]-self._tstamps[_diff-1][1] + drift = abs(diff_time - synth_time) + if drift > max_drift: + max_drift = drift + return max_drift + +class _dataUnit(object): + def __init__(self, data, T, valid): + self._data = data + self._T = T + self._valid = valid + self._creation = time.time() + def getData(self): + return self._data + def delData(self, begin=0, end=-1): + if type(self._data) == str: + if end == -1: + end = len(_data) + self._data = self._data[:begin]+self._data[end:] + else: + del self._data[begin:end] + self._valid = False + def getCreateTime(self): + return self._creation + def getTstamp(self): + return self._T + def updateTstamp(self, offset): + if self._T: + self._T = addUTCTime(self._T, offset) + def cleanup(self, count, xdelta): + self.delData(end=count) + self.updateTstamp(count * xdelta) + def getValidTstamp(self): + return self._valid + +class _sriUnit(object): + def __init__(self, sri, offset): + self._offset = offset + self._sri = sri + def getOffset(self): + return self._offset + def changeOffset(self, delta): + self._offset = self._offset - delta + def getSri(self): + return self._sri + def getStreamID(self): + return self._sri.streamID + +class InputStream(BaseStream): + def __init__(self, parent, sri): + BaseStream.__init__(self, parent, sri) + self._enabled = True + self._data = [] + self._sri_idx = [] + self._eos = False + self._new_sri = True + + def streamID(self): + return self._sri.streamID + + def _updateSRI(self, sri): + # this sri applies to whatever packet is delivered next + if len(self._data) == 0: + self._new_sri = True + self._sri = sri + return + self._sri_idx.append(_sriUnit(sri, len(self._data))) + def _updateData(self, data, T, EOS): + self._parent.port_cond.acquire() + try: + self._data.append(_dataUnit(data, T, True)) + if EOS: + self._eos = True + self._parent.port_cond.notifyAll() + finally: + self._parent.port_cond.release() + + def getOldestCreateTime(self): + if len(self._data) != 0: + return self._data[0].getCreateTime() + else: + return None + + def _dataCurrSri(self): + upper_end = len(self._data) + if len(self._sri_idx) != 0: + upper_end = self._sri_idx[0].getOffset() + total_data = 0 + for total_data_idx in range(upper_end): + total_data += len(self._data[total_data_idx].getData()) + return total_data + + def read(self, count=None, consume=None, blocking=True): + ''' + Blocking read from the data buffer. + count: number of items read. All available if None + consumer: how far to move the read pointer. Move by count if None + + Note: if a new SRI was received, read all data until the new SRI + ''' + # if the amount of data left is 0, erase this from parent._streams + if len(self._data) == 0 and self._eos: + self._parent._removeStream(self) + return None + + if not count: + count = self.samplesAvailableSingleSRI() + if not consume: + consume = count + + while blocking: + # is there enough data for this sri? + # is there enough in the first packet? + if len(self._data) != 0: + if len(self._sri_idx) == 0: + if self._dataCurrSri() < count: + continue + ret_data = [] + tstamps = [] + total_read = actual_read = data_idx = curr_idx = consume_count = 0 + consume_count = consume + while total_read < count: + actual_read = len(self._data[data_idx].getData()) + if total_read + actual_read > count: + actual_read = count - total_read + ret_data += self._data[data_idx].getData()[:actual_read] + tstamps += [(self._data[data_idx].getTstamp(), curr_idx)] + curr_idx += len(self._data[data_idx].getData()) + total_read += actual_read + consume_now = actual_read + if consume_now > consume_count: + consume_now = consume_count + consume_count -= consume_now + self._data[data_idx].cleanup(consume_now, self._sri.xdelta) + data_idx += 1 + if self._sri.subsize != 0: + framelength = self._sri.subsize if not self._sri.mode else 2 * self._sri.subsize + if float(len(ret_data))/framelength != len(ret_data)/framelength: + print 'The data length ('+str(len(ret_data))+') divided by subsize ('+str(self._sri.subsize)+')is not a whole number' + return None + _ret_data = [] + for idx in range(len(ret_data)/framelength): + _ret_data.append(ret_data[idx*framelength:(idx+1)*framelength]) + ret_data = _ret_data + ret_block = DataBlock(self._sri, ret_data, tstamps, self._new_sri) + self._new_sri = False + while True: + if len(self._data) == 0: + break + if len(self._data[0].getData()) == 0: + self._data.pop(0) + else: + break + return ret_block + # are there other sri in the queue? + else: + ret_data = [] + tstamps = [] + curr_idx = 0 + number_data = self._sri_idx[0].getOffset() + total_data = self._dataCurrSri() + if total_data <= count: + # return it all for the current sri and queue up the next sri + for data_idx in range(number_data): + ret_data += self._data[data_idx].getData() + tstamps += [(self._data[data_idx].getTstamp(), curr_idx)] + curr_idx += len(self._data[data_idx].getData()) + number_pop = 0 + consume_count = consume + while consume_count != 0: + consume_now = len(self._data[0].getData()) + if consume_now <= consume_count: + self._data.pop(0) + consume_count -= consume_now + number_pop += 1 + continue + self._data[0].cleanup(consume_count, self._sri.xdelta) + consume_count = 0 + for _item_sri_idx in self._sri_idx: + _item_sri_idx.changeOffset(number_pop) + if self._sri.subsize != 0: + framelength = self._sri.subsize if not self._sri.mode else 2 * self._sri.subsize + if float(len(ret_data))/framelength != len(ret_data)/framelength: + print 'The data length ('+str(len(ret_data))+') divided by subsize ('+str(self._sri.subsize)+')is not a whole number' + return None + _ret_data = [] + for idx in range(len(ret_data)/framelength): + _ret_data.append(ret_data[idx*framelength:(idx+1)*framelength]) + ret_data = _ret_data + ret_block = DataBlock(self._sri, ret_data, tstamps, self._new_sri) + self._new_sri = True + self._sri = self._sri_idx.pop(0).getSri() + return ret_block + else: + # find a subset + total_read = actual_read = 0 + for data_idx in range(number_data): + actual_read = len(self._data[data_idx].getData()) + if total_read + actual_read > count: + actual_read = count - total_read + ret_data += self._data[data_idx].getData()[:actual_read] + tstamps += [(self._data[data_idx].getTstamp(), curr_idx)] + curr_idx += len(self._data[data_idx].getData()) + total_read += actual_read + if total_read == count: + break + number_pop = 0 + consume_count = consume + while consume_count != 0: + consume_now = len(self._data[0].getData()) + if consume_now <= consume_count: + self._data.pop(0) + consume_count -= consume_now + number_pop += 1 + continue + self._data[0].cleanup(consume_count, self._sri.xdelta) + consume_count = 0 + for _item_sri_idx in self._sri_idx: + _item_sri_idx.changeOffset(number_pop) + if self._sri.subsize != 0: + framelength = self._sri.subsize if not self._sri.mode else 2 * self._sri.subsize + if float(len(ret_data))/framelength != len(ret_data)/framelength: + print 'The data length ('+str(len(ret_data))+') divided by subsize ('+str(self._sri.subsize)+')is not a whole number' + return None + _ret_data = [] + for idx in range(len(ret_data)/framelength): + _ret_data.append(ret_data[idx*framelength:(idx+1)*framelength]) + ret_data = _ret_data + ret_block = DataBlock(self._sri, ret_data, tstamps, self._new_sri) + self._new_sri = False + return ret_block + # this sleep happens if len(self._sri_idx) == 0 and total_data < count + if blocking: + time.sleep(0.1) + return None + def tryread(self, count=None, consume=None): + ''' + Non-blocking read from the data buffer. + count: number of items read. All available if None + consumer: how far to move the read pointer. Move by count if None + + Note: if a new SRI was received, read all data until the new SRI + ''' + return self.read(count, consume, False) + + def skip(self, count=None): + ''' + Move forward the read pointer by count or the next SRI, whichever comes first. + Move to next SRI if None + Returns the number of skipped elements + ''' + number_pop = 0 + consume_count = count + total_consumed = 0 + while consume_count != 0: + consume_now = len(self._data[0].getData()) + if consume_now <= consume_count: + self._data.pop(0) + consume_count -= consume_now + total_consumed += consume_now + for _item_sri_idx in self._sri_idx: + _item_sri_idx.changeOffset(1) + if len(self._sri_idx) != 0: + if self._sri_idx[0].getOffset() <= 0: + self._sri = self._sri_idx[0].getSri() + self._new_sri = True + self._sri_idx.pop(0) + break + continue + total_consumed += consume_count + self._data[0].cleanup(consume_count, self._sri.xdelta) + consume_count = 0 + return total_consumed + def ready(self): + return self.samplesAvailable() > 0 + def dataEstimate(self): + len_data = tstamps = 0 + for _data in self._data: + len_data += len(_data.getData()) + tstamps += 1 + return (len_data,tstamps) + def samplesAvailable(self): + len_data = 0 + for _data in self._data: + len_data += len(_data.getData()) + return len_data + def samplesAvailableSingleSRI(self): + len_data = 0 + data_block_reads = len(self._data) + if len(self._sri_idx) != 0: + data_block_reads = self._sri_idx[0].getOffset() + for _data_idx in range(data_block_reads): + len_data += len(self._data[_data_idx].getData()) + return len_data + def enable(self): + ''' + Do not drop incoming data + ''' + self._enabled = True + def disable(self): + ''' + Drop all incoming data + ''' + self._enabled = False + def enabled(self): + return self._enabled + def eos(self): + ''' + Has EOS been received? + ''' + return self._eos class ArraySink(object): """ @@ -220,20 +601,19 @@ def __init__(self, porttype): self.sri=bulkio_helpers.defaultSRI self.data = [] self.timestamps = [] - self.sris = [] + self._streams = [] + self._livingStreams = {} self.gotEOS = False self.breakBlock = False self.port_lock = threading.Lock() self.port_cond = threading.Condition(self.port_lock) - + class estimateStruct(): len_data=0 num_timestamps=0 - num_sris=0 - def __init__(self, data=[], timestamps=[], sris=[]): - self.len_data = len(data) - self.num_timestamps = len(timestamps) - self.num_sris = len(sris) + def __init__(self, data=0, timestamps=0): + self.len_data = data + self.num_timestamps = timestamps def _isActive(self): return not self.gotEOS and not self.breakBlock @@ -243,6 +623,41 @@ def reset(self): self.gotEOS = False self.breakBlock = False + def getStream(self, streamID): + for _stream in self._streams: + if _stream.getStreamID() == streamID: + return _stream + for _stream in self._livingStreams: + if self._livingStreams[_stream].getStreamID() == streamID: + return self._livingStreams[_stream] + return None + + def getStreams(self): + retval = [] + for _stream in self._streams: + retval.append(_stream) + for _stream in self._livingStreams: + retval.append(self._livingStreams[_stream]) + return retval + + def getCurrentStream(self): + if len(self._streams) != 0: + return self._streams[0] + streams_with_data = [] + for _stream in self._livingStreams: + if self._livingStreams[_stream].samplesAvailable() != 0: + streams_with_data.append(_stream) + if len(streams_with_data) == 0: + return None + oldest = (0,'') + for _stream in streams_with_data: + if oldest[0] == 0: + oldest = (_stream, self._livingStreams[_stream].getOldestCreateTime()) + continue + if self._livingStreams[_stream].getOldestCreateTime() < oldest[1]: + oldest = (_stream, self._livingStreams[_stream].getOldestCreateTime()) + return self._livingStreams[oldest[0]] + def start(self): self.gotEOS = False self.breakBlock = False @@ -254,17 +669,28 @@ def stop(self): self.port_cond.release() def eos(self): + _stream = self.getCurrentStream() + if _stream: + return _stream.eos() return self.gotEOS def waitEOS(self): self.port_cond.acquire() try: while self._isActive(): + if self.eos(): + break self.port_cond.wait() return self.gotEOS finally: self.port_cond.release() + def _removeStream(self, stream): + for stream_idx in range(len(self._streams)): + if self._streams[stream_idx] == stream: + self._streams.pop(stream_idx) + break + def pushSRI(self, H): """ Stores the SteramSRI object regardless that there is no need for it @@ -274,7 +700,10 @@ def pushSRI(self, H): generate the header file """ self.sri = H - self.sris.append([len(self.data), H]) + if not self._livingStreams.has_key(H.streamID): + self._livingStreams[H.streamID] = InputStream(self, H) + else: + self._livingStreams[H.streamID]._updateSRI(H) def pushPacket(self, data, ts, EOS, stream_id): """ @@ -286,25 +715,40 @@ def pushPacket(self, data, ts, EOS, stream_id): Flag indicating if this is the End Of the Stream The unique stream id """ - self.port_cond.acquire() - try: - self.gotEOS = EOS - self.timestamps.append([len(self.data), ts]) - self.data += data - self.port_cond.notifyAll() - finally: - self.port_cond.release() + if not self._livingStreams.has_key(stream_id): + self._livingStreams[stream_id] = InputStream(self, BULKIO.StreamSRI(1, 0.0, 1.0, 1, 0, 0.0, 0.0, 0, 0, stream_id, False, [])) + _stream = self._livingStreams[stream_id] + _stream._updateData(data, ts, EOS) + if EOS: + self._streams.append(_stream) + self._livingStreams.pop(stream_id) + #self.port_cond.acquire() + #try: + # self.gotEOS = EOS + # self.timestamps.append([len(self.data), ts]) + # self.data += data + # self.port_cond.notifyAll() + #finally: + # self.port_cond.release() + + # legacy stuff + self.data += data def estimateData(self): self.port_cond.acquire() estimate = self.estimateStruct() - try: - estimate = self.estimateStruct(self.data, self.timestamps, self.sris) - finally: - self.port_cond.release() + _streams = self.getStreams() + _total_data = 0 + _total_tstamps = 0 + for _stream in _streams: + (data_len,tstamp_len) = _stream.dataEstimate() + _total_data += data_len + _total_tstamps += tstamp_len + estimate = self.estimateStruct(_total_data, _total_tstamps) + self.port_cond.release() return estimate - - def syncAssocData(self, reference): + + def __syncAssocData(self, reference): retval = [] length_to_erase = None for i,(l,t) in enumerate(reference[::-1]): @@ -321,60 +765,29 @@ def syncAssocData(self, reference): def retrieveData(self, length=None): self.port_cond.acquire() try: - if length is None: - # No length specified; get all of the data. - length = len(self.data) - - # have not received any data yet (and I need a minimum amount) - if self.sri == None and len(self.data) == 0 and length != 0: - self.port_cond.wait() - - if self.sri != None and self.sri.subsize != 0: - frameLength = self.sri.subsize if not self.sri.mode else 2*self.sri.subsize - if float(length)/frameLength != length/frameLength: - print 'The requested length divided by the subsize ('+str(length)+'/'+str(self.sri.subsize)+') is not a whole number. Cannot return framed data' - return (None,None) - - # Wait for there to be enough data. - while len(self.data) < length and self._isActive(): - self.port_cond.wait() - - if len(self.data) > length: - # More data is available than was requested. Return only - # as much data as was asked for, and the associated - # timestamps. - rettime = self.syncAssocData(self.timestamps) - retsris = self.syncAssocData(self.sris) - - if self.sri.subsize == 0: - retval = self.data[:length] - else: - retval = [] - frameLength = self.sri.subsize if not self.sri.mode else 2*self.sri.subsize - for idx in range(length/frameLength): - retval.append(self.data[idx*frameLength:(idx+1)*frameLength]) - del self.data[:length] - return (retval, rettime, retsris) - - # No length was provided, or length is equal to the length of data. - # Return all data and timestamps. - if self.sri == None: - (retval, rettime, retsris) = (self.data, self.timestamps, []) - elif self.sri.subsize == 0: - (retval, rettime, retsris) = (self.data, self.timestamps, self.sris) - else: - retval = [] - frameLength = self.sri.subsize if not self.sri.mode else 2*self.sri.subsize - for idx in range(length/frameLength): - retval.append(self.data[idx*frameLength:(idx+1)*frameLength]) - rettime = self.timestamps - retsris = self.sris - self.data = [] - self.timestamps = [] - self.sris = [] - return (retval, rettime, retsris) + retval = [] + rettime = [] + _stream = self.getCurrentStream() + if not _stream: + return None + done = False + goal = length + if length == None: + goal = _stream.samplesAvailable() + while True: + _block = _stream.read(count=length) + if not _block: + break + retval += _block.data() + rettime += _block.getTimestamps() + goal_offset = 1 + if _block.sri().subsize != 0: + goal_offset = _block.sri().subsize + if len(retval) == goal/goal_offset: + break finally: self.port_cond.release() + return (retval, rettime) def getPort(self): """ @@ -570,13 +983,13 @@ def pushPacket(self, data, EOS, stream_id): Flag indicating if this is the End Of the Stream The unique stream id """ - self.port_cond.acquire() - try: - self.gotEOS = EOS - self.data.append(data) - self.port_cond.notifyAll() - finally: - self.port_cond.release() + if not self._livingStreams.has_key(stream_id): + self._livingStreams[stream_id] = InputStream(self, BULKIO.StreamSRI(1, 0.0, 1.0, 1, 0, 0.0, 0.0, 0, 0, stream_id, False, [])) + _stream = self._livingStreams[stream_id] + _stream._updateData([data], None, EOS) + if EOS: + self._streams.append(_stream) + self._livingStreams.pop(stream_id) class XmlArraySource(ArraySource): "This sub-class exists to override pushPacket for dataXML ports." diff --git a/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py b/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py index 5d2b75643..c57199bba 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py +++ b/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py @@ -801,9 +801,11 @@ def eos(self): self._sink exists. """ - if self._sink == None: return False + _stream = self._sink.getCurrentStream() + if _stream: + return _stream.eos() return self._sink.gotEOS def sri(self): @@ -1702,7 +1704,16 @@ def getDataEstimate(self): return None return self._sink.estimateData() - def getData(self, length=None, eos_block=False, tstamps=False, sris=False): + def getStream(self, streamID): + return self._sink.getStream(streamID) + + def getStreams(self): + return self._sink.getStreams() + + def getCurrentStream(self): + return self._sink.getCurrentStream() + + def getData(self, length=None, eos_block=False, tstamps=False): ''' Returns either an array of the received data elements or a tuple containing the received list and their associated time stamps @@ -1714,11 +1725,6 @@ def getData(self, length=None, eos_block=False, tstamps=False, sris=False): tstamps: setting to True makes the return value a tuple, where the first element is the data set and the second element is a series of tuples containing the element index number and the timestamp for that index - sris: setting to True makes the return value a tuple, where the first - element is the data set, the second element is the series of - timestamps (empty list if tstamps==False) and the third element is - a series of tuples containing the element index number and the - sri value for that index ''' isChar = self._sink.port_type == _BULKIO__POA.dataChar @@ -1726,7 +1732,16 @@ def getData(self, length=None, eos_block=False, tstamps=False, sris=False): return None if eos_block: self._sink.waitEOS() - (retval, timestamps, _sris) = self._sink.retrieveData(length=length) + _retval = self._sink.retrieveData(length=length) + if not _retval: + if tstamps: + return ([],[]) + return [] + (retval, timestamps) = _retval + _tstamps = [] + for tstamp in timestamps: + _tstamps.append((tstamp[1],tstamp[0])) + timestamps = _tstamps if isChar: # Converts char values into their numeric equivalents def from_char(data): @@ -1739,12 +1754,8 @@ def from_char(data): retval = [from_char(frame) for frame in retval] else: retval = from_char(retval) - if tstamps and not sris: + if tstamps: return (retval,timestamps) - if not tstamps and sris: - return (retval, [], _sris) - if tstamps and sris: - return (retval,timestamps,_sris) else: return retval diff --git a/redhawk/src/testing/tests/test_13_TestSB.py b/redhawk/src/testing/tests/test_13_TestSB.py index 4da79aa51..61e40fe75 100644 --- a/redhawk/src/testing/tests/test_13_TestSB.py +++ b/redhawk/src/testing/tests/test_13_TestSB.py @@ -137,6 +137,16 @@ def test_NoInteractiveCppComponent(self): status, output=commands.getstatusoutput('sdr/dom/components/ECM_CPP/cpp/ECM_CPP -i') self.assertNotEquals(output.find(self.message),-1) +def wait_on_data( sink, number_timestamps ): + _timeout = 1 + begin_time = time.time() + estimate = sink.getDataEstimate() + while estimate.num_timestamps != number_timestamps: + time.sleep(0.1) + estimate = sink.getDataEstimate() + if time.time() - begin_time > _timeout: + break + class SBEventChannelTest(scatest.CorbaTestCase): def setUp(self): orb = CORBA.ORB_init() @@ -2038,19 +2048,6 @@ def test_DataSourceTimeStampParam(self): self.assertEquals(_rnd_pkt_time,_rnd_toffset ) def test_DataSinkSRI(self): - """ - Verify that provide SRI is handled - """ - def wait_on_data( sink ): - _timeout = 1 - begin_time = time.time() - estimate = sink.getDataEstimate() - while estimate.num_timestamps != 3: - time.sleep(0.1) - estimate = sink.getDataEstimate() - if time.time() - begin_time > _timeout: - break - src = sb.DataSource(dataFormat='float') snk = sb.DataSink() src.connect(snk) @@ -2058,15 +2055,157 @@ def wait_on_data( sink ): src.push([1,2,3,4,5],sampleRate=100) src.push([1,2,3,4,5],sampleRate=1000) src.push([1,2,3,4,5],sampleRate=10000) - wait_on_data(snk) - data=snk.getData(tstamps=True,sris=True) - self.assertEquals(len(data[2]), 3) - self.assertEquals(data[2][0][0], 0) - self.assertEquals(data[2][1][0], 5) - self.assertEquals(data[2][2][0], 10) - self.assertEquals(data[2][0][1].xdelta, 0.01) - self.assertEquals(data[2][1][1].xdelta, 0.001) - self.assertEquals(data[2][2][1].xdelta, 0.0001) + wait_on_data(snk, 3) + stream=snk.getCurrentStream() + block_1 = stream.read() + self.assertNotEqual(block_1, None) + block_2 = stream.read() + self.assertNotEqual(block_2, None) + block_3 = stream.read() + self.assertNotEqual(block_3, None) + self.assertEquals(len(block_1.data()), 5) + self.assertEquals(len(block_2.data()), 5) + self.assertEquals(len(block_3.data()), 5) + self.assertEquals(block_1.xdelta(), 0.01) + self.assertEquals(block_2.xdelta(), 0.001) + self.assertEquals(block_3.xdelta(), 0.0001) + + def test_DataSinkMultipleStream(self): + src = sb.DataSource(dataFormat='float') + snk = sb.DataSink() + src.connect(snk) + sb.start() + src.push([1,2,3,4,5],sampleRate=100, streamID='hello_1') + src.push([6,7,8,9,10],sampleRate=1000, streamID='hello_2') + src.push([11,12,13,14,15],sampleRate=10000, streamID='hello_3') + src.push([16,17,18,19,20],sampleRate=100, streamID='hello_1') + + wait_on_data(snk, 3) + + stream=snk.getCurrentStream() + block_1 = stream.read() + self.assertNotEqual(block_1, None) + + stream=snk.getCurrentStream() + block_2 = stream.read() + self.assertNotEqual(block_2, None) + block_2_2 = stream.read(blocking=False) + self.assertEquals(block_2_2, None) + + stream=snk.getCurrentStream() + block_3 = stream.read() + self.assertNotEqual(block_3, None) + block_3_2 = stream.read(blocking=False) + self.assertEquals(block_3_2, None) + + stream=snk.getCurrentStream() + block_1_2 = stream.read() + self.assertNotEqual(block_1_2, None) + block_1_3 = stream.read(blocking=False) + self.assertEqual(block_1_3, None) + + self.assertEquals(block_1.data(), [1,2,3,4,5]) + self.assertEquals(block_1_2.data(), [16,17,18,19,20]) + self.assertEquals(block_2.data(), [6,7,8,9,10]) + self.assertEquals(block_3.data(), [11,12,13,14,15]) + self.assertEquals(block_1.xdelta(), 0.01) + self.assertEquals(block_2.xdelta(), 0.001) + self.assertEquals(block_3.xdelta(), 0.0001) + + def test_DataSinkReadConsume(self): + src = sb.DataSource(dataFormat='float') + snk = sb.DataSink() + src.connect(snk) + sb.start() + src.push([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20],sampleRate=100, streamID='hello_1') + + wait_on_data(snk, 1) + + stream=snk.getCurrentStream() + block_1 = stream.read(count=10, consume=5) + self.assertNotEqual(block_1, None) + self.assertEquals(block_1.data(), [1,2,3,4,5,6,7,8,9,10]) + + block_1 = stream.read(count=10, consume=5) + self.assertNotEqual(block_1, None) + self.assertEquals(block_1.data(), [6,7,8,9,10,11,12,13,14,15]) + + block_1 = stream.read(count=10, consume=5) + self.assertNotEqual(block_1, None) + self.assertEquals(block_1.data(), [11,12,13,14,15,16,17,18,19,20]) + + block_1 = stream.read(count=5, consume=5) + self.assertNotEqual(block_1, None) + self.assertEquals(block_1.data(), [16,17,18,19,20]) + + block_1 = stream.read(blocking=False) + self.assertEquals(block_1, None) + + def test_DataSinkSkipDiffSRI(self): + src = sb.DataSource(dataFormat='float') + snk = sb.DataSink() + src.connect(snk) + sb.start() + src.push([1,2,3,4,5],sampleRate=100, streamID='hello_1') + src.push([6,7,8,9,10],sampleRate=1000, streamID='hello_1') + src.push([11,12,13,14,15,16,17,18,19,20,21,22,23,24,25],sampleRate=10000, streamID='hello_1') + + wait_on_data(snk, 4) + + stream=snk.getCurrentStream() + block_1 = stream.read(count=3) + self.assertNotEqual(block_1, None) + self.assertEquals(block_1.data(), [1,2,3]) + + skipped = stream.skip(10) + self.assertEquals(skipped, 2) + + block_1 = stream.read(count=2, consume=3) + self.assertNotEqual(block_1, None) + self.assertEquals(block_1.data(), [6,7]) + + skipped = stream.skip(10) + self.assertEquals(skipped, 2) + + block_1 = stream.read(count=2, consume=3) + self.assertNotEqual(block_1, None) + self.assertEquals(block_1.data(), [11,12]) + + skipped = stream.skip(10) + self.assertEquals(skipped, 10) + + block_1 = stream.read() + self.assertNotEqual(block_1, None) + self.assertEquals(block_1.data(), [23,24,25]) + + block_1 = stream.read(blocking=False) + self.assertEquals(block_1, None) + + def test_DataSinkSkip(self): + src = sb.DataSource(dataFormat='float') + snk = sb.DataSink() + src.connect(snk) + sb.start() + src.push([1,2,3,4,5],sampleRate=100, streamID='hello_1') + src.push([6,7,8,9,10],sampleRate=100, streamID='hello_1') + src.push([11,12,13,14,15],sampleRate=100, streamID='hello_1') + src.push([16,17,18,19,20],sampleRate=100, streamID='hello_1') + + wait_on_data(snk, 4) + + stream=snk.getCurrentStream() + block_1 = stream.read(count=3) + self.assertNotEqual(block_1, None) + self.assertEquals(block_1.data(), [1,2,3]) + + block_1 = stream.skip(10) + + block_1 = stream.read(count=3, consume=5) + self.assertNotEqual(block_1, None) + self.assertEquals(block_1.data(), [14,15,16]) + + block_1 = stream.read(blocking=False) + self.assertEquals(block_1, None) class customSink(bulkio_data_helpers.ArraySink): def __init__(self, porttype): @@ -2076,22 +2215,25 @@ def pushSRI(self, H): _H = H _H.xdelta = H.xdelta * 2 self.sri = _H - self.sris.append([len(self.data), _H]) + if not self._livingStreams.has_key(_H.streamID): + self._livingStreams[_H.streamID] = bulkio_data_helpers.InputStream(self, _H) + else: + self._livingStreams[_H.streamID]._updateSRI(_H) def test_CustomDataSink(self): - """ - Verify that provide SRI is handled - """ - def wait_on_data( sink ): - _timeout = 1 - begin_time = time.time() - estimate = sink.getDataEstimate() - while estimate.num_timestamps != 3: - time.sleep(0.1) - estimate = sink.getDataEstimate() - if time.time() - begin_time > _timeout: - break + src = sb.DataSource(dataFormat='float') + snk = sb.DataSink(sinkClass=self.customSink) + src.connect(snk) + sb.start() + src.push([1,2,3,4,5],sampleRate=100) + src.push([1,2,3,4,5],sampleRate=1000) + src.push([1,2,3,4,5],sampleRate=10000) + wait_on_data(snk, 3) + data=snk.getData(tstamps=True) + self.assertEquals(len(data[1]), 3) + self.assertEquals(len(data[0]), 15) + def test_CustomStreamDataSink(self): src = sb.DataSource(dataFormat='float') snk = sb.DataSink(sinkClass=self.customSink) src.connect(snk) @@ -2099,29 +2241,22 @@ def wait_on_data( sink ): src.push([1,2,3,4,5],sampleRate=100) src.push([1,2,3,4,5],sampleRate=1000) src.push([1,2,3,4,5],sampleRate=10000) - wait_on_data(snk) - data=snk.getData(tstamps=True,sris=True) - self.assertEquals(len(data[2]), 3) - self.assertEquals(data[2][0][0], 0) - self.assertEquals(data[2][1][0], 5) - self.assertEquals(data[2][2][0], 10) - self.assertEquals(data[2][0][1].xdelta, 0.02) - self.assertEquals(data[2][1][1].xdelta, 0.002) - self.assertEquals(data[2][2][1].xdelta, 0.0002) + wait_on_data(snk, 3) + stream=snk.getCurrentStream() + block_1 = stream.read() + self.assertNotEqual(block_1, None) + block_2 = stream.read() + self.assertNotEqual(block_2, None) + block_3 = stream.read() + self.assertNotEqual(block_3, None) + self.assertEquals(len(block_1.data()), 5) + self.assertEquals(len(block_2.data()), 5) + self.assertEquals(len(block_3.data()), 5) + self.assertEquals(block_1.xdelta(), 0.02) + self.assertEquals(block_2.xdelta(), 0.002) + self.assertEquals(block_3.xdelta(), 0.0002) def test_DataSourceSRI(self): - """ - Verify that provide SRI is handled - """ - def wait_on_data( sink ): - begin_time = time.time() - estimate = sink.getDataEstimate() - while estimate.num_timestamps != 1: - time.sleep(0.1) - estimate = sink.getDataEstimate() - if time.time() - begin_time > _timeout: - break - _timeout = 1 _startTime = 10 source = sb.DataSource(startTime=_startTime) @@ -2139,7 +2274,7 @@ def wait_on_data( sink ): # push samples down stream, with custom sri _srcData = [1,2,3,4] source.push(_srcData, sri=_sri ) - wait_on_data(sink) + wait_on_data(sink, 1) data=sink.getData() rsri=sink.sri() self.assertEquals(rsri.streamID, sid ) @@ -2168,7 +2303,7 @@ def wait_on_data( sink ): _srcData = [1,2,3,4] source.push(_srcData, SRIKeywords=kws ) begin_time = time.time() - wait_on_data(sink) + wait_on_data(sink, 1) data=sink.getData() rsri=sink.sri() self.assertEquals(rsri.streamID, sid ) @@ -2177,7 +2312,7 @@ def wait_on_data( sink ): # Repeat, making sure that a second push with keywords does not fail source.push(_srcData, SRIKeywords=kws) - wait_on_data(sink) + wait_on_data(sink, 1) data=sink.getData() self.assertTrue(data) @@ -2191,7 +2326,7 @@ def wait_on_data( sink ): _sri.keywords=copy.copy(matchkws) _srcData = [1,2,3,4] source.push(_srcData, sri=_sri ) - wait_on_data(sink) + wait_on_data(sink, 1) data=sink.getData() rsri=sink.sri() self.assertEquals(rsri.streamID, sid ) @@ -2203,7 +2338,7 @@ def wait_on_data( sink ): _sri.streamID=sid _srcData = [1,2,3,4] source.push(_srcData, sri=_sri ) - wait_on_data(sink) + wait_on_data(sink, 1) data=sink.getData() rsri=sink.sri() self.assertEquals(rsri.streamID, sid ) @@ -2211,7 +2346,7 @@ def wait_on_data( sink ): _sri.streamID='anewsri' _srcData = [1,2,3,4] source.push(_srcData, sri=_sri ) - wait_on_data(sink) + wait_on_data(sink, 1) data=sink.getData() rsri=sink.sri() self.assertEquals(rsri.streamID, 'anewsri' ) @@ -2219,7 +2354,7 @@ def wait_on_data( sink ): _sri.mode=1 _srcData = [1,2,3,4] source.push(_srcData, sri=_sri ) - wait_on_data(sink) + wait_on_data(sink, 1) data=sink.getData() rsri=sink.sri() self.assertEquals(rsri.mode, 1 ) @@ -2227,7 +2362,7 @@ def wait_on_data( sink ): _sri.mode=0 _srcData = [1,2,3,4] source.push(_srcData, sri=_sri ) - wait_on_data(sink) + wait_on_data(sink, 1) data=sink.getData() rsri=sink.sri() self.assertEquals(rsri.mode, 0 ) @@ -2235,7 +2370,7 @@ def wait_on_data( sink ): _sri.hversion=100 _srcData = [1,2,3,4] source.push(_srcData, sri=_sri ) - wait_on_data(sink) + wait_on_data(sink, 1) data=sink.getData() rsri=sink.sri() self.assertEquals(rsri.hversion, 100 ) From f53b767d240f09c5cc3d92dbe2b4c93acd16384f Mon Sep 17 00:00:00 2001 From: Max Robert Date: Thu, 11 May 2017 14:55:29 -0400 Subject: [PATCH 0796/1644] Refs CF-350. Fix to stream API when handling non-blocking reads --- .../python/ossie/utils/bulkio/bulkio_data_helpers.py | 7 ++++--- redhawk/src/testing/tests/test_13_TestSB.py | 8 ++++++-- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/bulkio/bulkio_data_helpers.py b/redhawk/src/base/framework/python/ossie/utils/bulkio/bulkio_data_helpers.py index baa37c3d1..6621db519 100644 --- a/redhawk/src/base/framework/python/ossie/utils/bulkio/bulkio_data_helpers.py +++ b/redhawk/src/base/framework/python/ossie/utils/bulkio/bulkio_data_helpers.py @@ -375,7 +375,7 @@ def read(self, count=None, consume=None, blocking=True): if not consume: consume = count - while blocking: + while True: # is there enough data for this sri? # is there enough in the first packet? if len(self._data) != 0: @@ -497,8 +497,9 @@ def read(self, count=None, consume=None, blocking=True): self._new_sri = False return ret_block # this sleep happens if len(self._sri_idx) == 0 and total_data < count - if blocking: - time.sleep(0.1) + if not blocking: + break + time.sleep(0.1) return None def tryread(self, count=None, consume=None): diff --git a/redhawk/src/testing/tests/test_13_TestSB.py b/redhawk/src/testing/tests/test_13_TestSB.py index 61e40fe75..f49909767 100644 --- a/redhawk/src/testing/tests/test_13_TestSB.py +++ b/redhawk/src/testing/tests/test_13_TestSB.py @@ -2141,7 +2141,7 @@ def test_DataSinkReadConsume(self): block_1 = stream.read(blocking=False) self.assertEquals(block_1, None) - def test_DataSinkSkipDiffSRI(self): + def _test_DataSinkSkipDiffSRI(self): src = sb.DataSource(dataFormat='float') snk = sb.DataSink() src.connect(snk) @@ -2198,12 +2198,16 @@ def test_DataSinkSkip(self): self.assertNotEqual(block_1, None) self.assertEquals(block_1.data(), [1,2,3]) - block_1 = stream.skip(10) + skipped = stream.skip(10) + self.assertEquals(skipped, 10) block_1 = stream.read(count=3, consume=5) self.assertNotEqual(block_1, None) self.assertEquals(block_1.data(), [14,15,16]) + block_1 = stream.read(blocking=False) + self.assertNotEqual(block_1, None) + self.assertEquals(block_1.data(), [17,18,19,20]) block_1 = stream.read(blocking=False) self.assertEquals(block_1, None) From 82162d1639ac70ffb1f91060fe09481f7923d29f Mon Sep 17 00:00:00 2001 From: Max Robert Date: Thu, 11 May 2017 15:06:46 -0400 Subject: [PATCH 0797/1644] Refs CF-350. Added a deprecation warning to getData --- .../base/framework/python/ossie/utils/sb/io_helpers.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py b/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py index c57199bba..74c97c9f1 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py +++ b/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py @@ -38,6 +38,7 @@ import shlex as _shlex import time as _time import signal as _signal +import warnings as _warnings import cStringIO, pydoc import sys as _sys import os as _os @@ -1711,10 +1712,15 @@ def getStreams(self): return self._sink.getStreams() def getCurrentStream(self): + ''' + Return the current data stream + ''' return self._sink.getCurrentStream() def getData(self, length=None, eos_block=False, tstamps=False): ''' + WARNING: This function is deprecated. Use getCurrentStream instead + Returns either an array of the received data elements or a tuple containing the received list and their associated time stamps @@ -1726,6 +1732,8 @@ def getData(self, length=None, eos_block=False, tstamps=False): element is the data set and the second element is a series of tuples containing the element index number and the timestamp for that index ''' + _warnings.warn("This function is deprecated. Use getCurrentStream instead") + isChar = self._sink.port_type == _BULKIO__POA.dataChar if not self._sink: From dd081839858568b7051929b94d2ea5136e0f422e Mon Sep 17 00:00:00 2001 From: Max Robert Date: Mon, 15 May 2017 14:19:07 -0400 Subject: [PATCH 0798/1644] Refs CF-350. Fixed broken API to retrieveData from the sink --- .../ossie/utils/bulkio/bulkio_data_helpers.py | 38 +++++++++++++------ .../python/ossie/utils/sb/io_helpers.py | 4 -- 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/bulkio/bulkio_data_helpers.py b/redhawk/src/base/framework/python/ossie/utils/bulkio/bulkio_data_helpers.py index 6621db519..fd0dff8db 100644 --- a/redhawk/src/base/framework/python/ossie/utils/bulkio/bulkio_data_helpers.py +++ b/redhawk/src/base/framework/python/ossie/utils/bulkio/bulkio_data_helpers.py @@ -252,20 +252,20 @@ def sriChanged(self): def inputQueueFlushed(self): return False def getStartTime(self): - return self._tstamps[0][0] + return self._tstamps[0][1] def getTimestamps(self): return self._tstamps def getNetTimeDrift(self): if len(self._tstamps) == 1: return 0 - diff_time = diffUTCTime(self._tstamps[-1][0], self._tstamps[0][0]) + diff_time = diffUTCTime(self._tstamps[-1][1], self._tstamps[0][1]) synth_time = self._sri.xdelta * len(self._data) return abs(diff_time - synth_time) def getMaxTimeDrift(self): max_drift = 0 for _diff in range(len(self._tstamps)-1): - diff_time = diffUTCTime(self._tstamps[_diff][0], self._tstamps[_diff-1][0]) - synth_time = self._sri.xdelta * self._tstamps[_diff][1]-self._tstamps[_diff-1][1] + diff_time = diffUTCTime(self._tstamps[_diff][1], self._tstamps[_diff-1][1]) + synth_time = self._sri.xdelta * self._tstamps[_diff][0]-self._tstamps[_diff-1][0] drift = abs(diff_time - synth_time) if drift > max_drift: max_drift = drift @@ -371,14 +371,18 @@ def read(self, count=None, consume=None, blocking=True): return None if not count: + self._parent.port_cond.acquire() count = self.samplesAvailableSingleSRI() + self._parent.port_cond.release() if not consume: consume = count while True: # is there enough data for this sri? # is there enough in the first packet? - if len(self._data) != 0: + try: + self._parent.port_cond.acquire() + if len(self._data) != 0: if len(self._sri_idx) == 0: if self._dataCurrSri() < count: continue @@ -391,7 +395,7 @@ def read(self, count=None, consume=None, blocking=True): if total_read + actual_read > count: actual_read = count - total_read ret_data += self._data[data_idx].getData()[:actual_read] - tstamps += [(self._data[data_idx].getTstamp(), curr_idx)] + tstamps += [(curr_idx, self._data[data_idx].getTstamp())] curr_idx += len(self._data[data_idx].getData()) total_read += actual_read consume_now = actual_read @@ -430,7 +434,7 @@ def read(self, count=None, consume=None, blocking=True): # return it all for the current sri and queue up the next sri for data_idx in range(number_data): ret_data += self._data[data_idx].getData() - tstamps += [(self._data[data_idx].getTstamp(), curr_idx)] + tstamps += [(curr_idx, self._data[data_idx].getTstamp())] curr_idx += len(self._data[data_idx].getData()) number_pop = 0 consume_count = consume @@ -466,7 +470,7 @@ def read(self, count=None, consume=None, blocking=True): if total_read + actual_read > count: actual_read = count - total_read ret_data += self._data[data_idx].getData()[:actual_read] - tstamps += [(self._data[data_idx].getTstamp(), curr_idx)] + tstamps += [(curr_idx, self._data[data_idx].getTstamp())] curr_idx += len(self._data[data_idx].getData()) total_read += actual_read if total_read == count: @@ -497,6 +501,8 @@ def read(self, count=None, consume=None, blocking=True): self._new_sri = False return ret_block # this sleep happens if len(self._sri_idx) == 0 and total_data < count + finally: + self._parent.port_cond.release() if not blocking: break time.sleep(0.1) @@ -764,17 +770,26 @@ def __syncAssocData(self, reference): return retval def retrieveData(self, length=None): - self.port_cond.acquire() + #self.port_cond.acquire() try: retval = [] rettime = [] - _stream = self.getCurrentStream() + while True: + self.port_cond.acquire() + _stream = self.getCurrentStream() + self.port_cond.release() + if not _stream and length != None: + time.sleep(0.1) + continue + break if not _stream: return None done = False goal = length + self.port_cond.acquire() if length == None: goal = _stream.samplesAvailable() + self.port_cond.release() while True: _block = _stream.read(count=length) if not _block: @@ -787,7 +802,8 @@ def retrieveData(self, length=None): if len(retval) == goal/goal_offset: break finally: - self.port_cond.release() + pass + # self.port_cond.release() return (retval, rettime) def getPort(self): diff --git a/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py b/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py index 74c97c9f1..53e8bab54 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py +++ b/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py @@ -1746,10 +1746,6 @@ def getData(self, length=None, eos_block=False, tstamps=False): return ([],[]) return [] (retval, timestamps) = _retval - _tstamps = [] - for tstamp in timestamps: - _tstamps.append((tstamp[1],tstamp[0])) - timestamps = _tstamps if isChar: # Converts char values into their numeric equivalents def from_char(data): From fcf41cb05fe88d62035eb97a82be6c8673f1d23a Mon Sep 17 00:00:00 2001 From: Max Robert Date: Mon, 15 May 2017 17:28:56 -0400 Subject: [PATCH 0799/1644] Refs CF-1763. Sandbox does not lock up when trying to release stopped components when the bulkio queue is full --- bulkioInterfaces/configure.ac | 2 + .../libsrc/cpp/bulkio_transport.cpp | 10 +- bulkioInterfaces/libsrc/testing/Makefile.am | 2 + .../components/snk_slow/cpp/Makefile.am | 45 ++++ .../components/snk_slow/cpp/Makefile.am.ide | 10 + .../testing/components/snk_slow/cpp/main.cpp | 11 + .../components/snk_slow/cpp/snk_slow.cpp | 253 ++++++++++++++++++ .../components/snk_slow/cpp/snk_slow.h | 18 ++ .../components/snk_slow/cpp/snk_slow_base.cpp | 65 +++++ .../components/snk_slow/cpp/snk_slow_base.h | 32 +++ .../components/snk_slow/snk_slow.prf.xml | 3 + .../components/snk_slow/snk_slow.scd.xml | 53 ++++ .../components/snk_slow/snk_slow.spd.xml | 27 ++ .../snk_slow/tests/test_snk_slow.py | 46 ++++ .../testing/components/src/cpp/Makefile.am | 49 ++++ .../components/src/cpp/Makefile.am.ide | 10 + .../testing/components/src/cpp/main.cpp | 11 + .../libsrc/testing/components/src/cpp/src.cpp | 253 ++++++++++++++++++ .../libsrc/testing/components/src/cpp/src.h | 19 ++ .../testing/components/src/cpp/src_base.cpp | 65 +++++ .../testing/components/src/cpp/src_base.h | 32 +++ .../libsrc/testing/components/src/src.prf.xml | 3 + .../libsrc/testing/components/src/src.scd.xml | 53 ++++ .../libsrc/testing/components/src/src.spd.xml | 27 ++ .../testing/components/src/tests/test_src.py | 57 ++++ .../libsrc/testing/tests/runtests | 8 + .../python/ossie/utils/model/connect.py | 3 + redhawk/src/base/include/ossie/UsesPort.h | 9 + 28 files changed, 1175 insertions(+), 1 deletion(-) create mode 100644 bulkioInterfaces/libsrc/testing/components/snk_slow/cpp/Makefile.am create mode 100644 bulkioInterfaces/libsrc/testing/components/snk_slow/cpp/Makefile.am.ide create mode 100644 bulkioInterfaces/libsrc/testing/components/snk_slow/cpp/main.cpp create mode 100644 bulkioInterfaces/libsrc/testing/components/snk_slow/cpp/snk_slow.cpp create mode 100644 bulkioInterfaces/libsrc/testing/components/snk_slow/cpp/snk_slow.h create mode 100644 bulkioInterfaces/libsrc/testing/components/snk_slow/cpp/snk_slow_base.cpp create mode 100644 bulkioInterfaces/libsrc/testing/components/snk_slow/cpp/snk_slow_base.h create mode 100644 bulkioInterfaces/libsrc/testing/components/snk_slow/snk_slow.prf.xml create mode 100644 bulkioInterfaces/libsrc/testing/components/snk_slow/snk_slow.scd.xml create mode 100644 bulkioInterfaces/libsrc/testing/components/snk_slow/snk_slow.spd.xml create mode 100755 bulkioInterfaces/libsrc/testing/components/snk_slow/tests/test_snk_slow.py create mode 100644 bulkioInterfaces/libsrc/testing/components/src/cpp/Makefile.am create mode 100644 bulkioInterfaces/libsrc/testing/components/src/cpp/Makefile.am.ide create mode 100644 bulkioInterfaces/libsrc/testing/components/src/cpp/main.cpp create mode 100644 bulkioInterfaces/libsrc/testing/components/src/cpp/src.cpp create mode 100644 bulkioInterfaces/libsrc/testing/components/src/cpp/src.h create mode 100644 bulkioInterfaces/libsrc/testing/components/src/cpp/src_base.cpp create mode 100644 bulkioInterfaces/libsrc/testing/components/src/cpp/src_base.h create mode 100644 bulkioInterfaces/libsrc/testing/components/src/src.prf.xml create mode 100644 bulkioInterfaces/libsrc/testing/components/src/src.scd.xml create mode 100644 bulkioInterfaces/libsrc/testing/components/src/src.spd.xml create mode 100755 bulkioInterfaces/libsrc/testing/components/src/tests/test_src.py diff --git a/bulkioInterfaces/configure.ac b/bulkioInterfaces/configure.ac index 0a60fbf69..3057e1a5b 100644 --- a/bulkioInterfaces/configure.ac +++ b/bulkioInterfaces/configure.ac @@ -170,6 +170,8 @@ if test "$enable_base_classes" != "no"; then libsrc/testing/components/CPP_Ports/cpp/Makefile \ libsrc/testing/components/Java_Ports/java/Makefile \ libsrc/testing/components/Oversized_framedata/cpp/Makefile \ + libsrc/testing/components/src/cpp/Makefile \ + libsrc/testing/components/snk_slow/cpp/Makefile \ libsrc/testing/components/Oversized_framedata/java/Makefile \ libsrc/testing/components/TestLargePush/cpp/Makefile \ libsrc/testing/components/TestLargePush/java/Makefile \ diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_transport.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_transport.cpp index 2d87add0c..a9d74506a 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_transport.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_transport.cpp @@ -65,9 +65,15 @@ namespace bulkio { void PortTransport::disconnect() { // Send an end-of-stream for all active streams + omniORB::setClientCallTimeout(1000); for (VersionMap::iterator stream = _sriVersions.begin(); stream != _sriVersions.end(); ++stream) { - this->_pushPacket(BufferType(), bulkio::time::utils::notSet(), true, stream->first); + try { + this->_pushPacket(BufferType(), bulkio::time::utils::notSet(), true, stream->first); + } catch (redhawk::TransportTimeoutError& e) { + // ignore the timeout. The destination is in a bad state + } } + omniORB::setClientCallTimeout(0); _sriVersions.clear(); } @@ -169,6 +175,8 @@ namespace bulkio { { try { _pushPacketImpl(data, T, EOS, streamID.c_str()); + } catch (const CORBA::TIMEOUT& exc) { + throw redhawk::TransportTimeoutError("Push timed out"); } catch (const CORBA::SystemException& exc) { throw redhawk::FatalTransportError(ossie::corba::describeException(exc)); } diff --git a/bulkioInterfaces/libsrc/testing/Makefile.am b/bulkioInterfaces/libsrc/testing/Makefile.am index b203caa45..82268ee15 100644 --- a/bulkioInterfaces/libsrc/testing/Makefile.am +++ b/bulkioInterfaces/libsrc/testing/Makefile.am @@ -22,6 +22,8 @@ SUBDIRS = components/CPP_Ports/cpp components/sri_changed_cpp/cpp SUBDIRS += components/TestLargePush/cpp SUBDIRS += components/multiout_attachable/cpp SUBDIRS += components/Oversized_framedata/cpp +SUBDIRS += components/src/cpp +SUBDIRS += components/snk_slow/cpp if HAVE_JAVASUPPORT SUBDIRS += components/TestLargePush/java SUBDIRS += components/Java_Ports/java diff --git a/bulkioInterfaces/libsrc/testing/components/snk_slow/cpp/Makefile.am b/bulkioInterfaces/libsrc/testing/components/snk_slow/cpp/Makefile.am new file mode 100644 index 000000000..9fa7b5dd5 --- /dev/null +++ b/bulkioInterfaces/libsrc/testing/components/snk_slow/cpp/Makefile.am @@ -0,0 +1,45 @@ +ACLOCAL_AMFLAGS = -I m4 -I${OSSIEHOME}/share/aclocal/ossie +AUTOMAKE_OPTIONS = subdir-objects + +ossieName = snk_slow +libdir = $(prefix)/dom/components/snk_slow/cpp +lib_LTLIBRARIES = snk_slow.la + +xmldir = $(prefix)/dom/components/snk_slow +dist_xml_DATA = ../snk_slow.scd.xml ../snk_slow.prf.xml ../snk_slow.spd.xml + +.PHONY: convenience-link clean-convenience-link + +all-local : convenience-link +clean-local : clean-convenience-link + +convenience-link : snk_slow.la + @ln -fs .libs/snk_slow.so + +clean-convenience-link: + @rm -f snk_slow.so + +distclean-local: + rm -rf m4 + rm -f config.* + rm -rf autom4te.cache + rm -f acinclude.m4 + rm -f aclocal.m4 + rm -f configure + rm -f depcomp + rm -f install-sh + rm -f ltmain.sh + rm -f Makefile.in + rm -f missing + rm -rf .deps + + +# Sources, libraries and library directories are auto-included from a file +# generated by the REDHAWK IDE. You can remove/modify the following lines if +# you wish to manually control these options. +include $(srcdir)/Makefile.am.ide +snk_slow_la_SOURCES = $(redhawk_SOURCES_auto) +snk_slow_la_LIBADD = $(SOFTPKG_LIBS) $(PROJECTDEPS_LIBS) $(BOOST_LDFLAGS) $(BOOST_THREAD_LIB) $(BOOST_REGEX_LIB) $(BOOST_SYSTEM_LIB) $(INTERFACEDEPS_LIBS) $(redhawk_LDADD_auto) +snk_slow_la_CXXFLAGS = -Wall $(SOFTPKG_CFLAGS) $(PROJECTDEPS_CFLAGS) $(BOOST_CPPFLAGS) $(INTERFACEDEPS_CFLAGS) $(redhawk_INCLUDES_auto) +snk_slow_la_LDFLAGS = -shared -module -export-dynamic -export-symbols-regex 'make_component' -avoid-version $(redhawk_LDFLAGS_auto) + diff --git a/bulkioInterfaces/libsrc/testing/components/snk_slow/cpp/Makefile.am.ide b/bulkioInterfaces/libsrc/testing/components/snk_slow/cpp/Makefile.am.ide new file mode 100644 index 000000000..355344fdf --- /dev/null +++ b/bulkioInterfaces/libsrc/testing/components/snk_slow/cpp/Makefile.am.ide @@ -0,0 +1,10 @@ +# This file is regularly auto-generated by the REDHAWK IDE. Do not modify! +# Files can be excluded by right-clicking on the file in the project explorer +# and choosing Resource Configurations -> Exclude from build. Re-include files +# by opening the Properties dialog of your project and choosing C/C++ Build -> +# Tool Chain Editor, and un-checking "Exclude resource from build " +redhawk_SOURCES_auto = main.cpp +redhawk_SOURCES_auto += snk_slow.cpp +redhawk_SOURCES_auto += snk_slow.h +redhawk_SOURCES_auto += snk_slow_base.cpp +redhawk_SOURCES_auto += snk_slow_base.h diff --git a/bulkioInterfaces/libsrc/testing/components/snk_slow/cpp/main.cpp b/bulkioInterfaces/libsrc/testing/components/snk_slow/cpp/main.cpp new file mode 100644 index 000000000..e2e125686 --- /dev/null +++ b/bulkioInterfaces/libsrc/testing/components/snk_slow/cpp/main.cpp @@ -0,0 +1,11 @@ +#include +#include "ossie/ossieSupport.h" + +#include "snk_slow.h" +extern "C" { + Resource_impl* make_component(const std::string& uuid, const std::string& identifier) + { + return new snk_slow_i(uuid.c_str(), identifier.c_str()); + } +} + diff --git a/bulkioInterfaces/libsrc/testing/components/snk_slow/cpp/snk_slow.cpp b/bulkioInterfaces/libsrc/testing/components/snk_slow/cpp/snk_slow.cpp new file mode 100644 index 000000000..f9f761de3 --- /dev/null +++ b/bulkioInterfaces/libsrc/testing/components/snk_slow/cpp/snk_slow.cpp @@ -0,0 +1,253 @@ +/************************************************************************** + + This is the component code. This file contains the child class where + custom functionality can be added to the component. Custom + functionality to the base class can be extended here. Access to + the ports can also be done from this class + +**************************************************************************/ + +#include "snk_slow.h" + +PREPARE_LOGGING(snk_slow_i) + +snk_slow_i::snk_slow_i(const char *uuid, const char *label) : + snk_slow_base(uuid, label) +{ + // Avoid placing constructor code here. Instead, use the "constructor" function. + +} + +snk_slow_i::~snk_slow_i() +{ +} + +void snk_slow_i::constructor() +{ + /*********************************************************************************** + This is the RH constructor. All properties are properly initialized before this function is called + ***********************************************************************************/ +} + +/*********************************************************************************************** + + Basic functionality: + + The service function is called by the serviceThread object (of type ProcessThread). + This call happens immediately after the previous call if the return value for + the previous call was NORMAL. + If the return value for the previous call was NOOP, then the serviceThread waits + an amount of time defined in the serviceThread's constructor. + + SRI: + To create a StreamSRI object, use the following code: + std::string stream_id = "testStream"; + BULKIO::StreamSRI sri = bulkio::sri::create(stream_id); + + Time: + To create a PrecisionUTCTime object, use the following code: + BULKIO::PrecisionUTCTime tstamp = bulkio::time::utils::now(); + + + Ports: + + Data is passed to the serviceFunction through by reading from input streams + (BulkIO only). The input stream class is a port-specific class, so each port + implementing the BulkIO interface will have its own type-specific input stream. + UDP multicast (dataSDDS and dataVITA49) ports do not support streams. + + The input stream from which to read can be requested with the getCurrentStream() + method. The optional argument to getCurrentStream() is a floating point number that + specifies the time to wait in seconds. A zero value is non-blocking. A negative value + is blocking. Constants have been defined for these values, bulkio::Const::BLOCKING and + bulkio::Const::NON_BLOCKING. + + More advanced uses of input streams are possible; refer to the REDHAWK documentation + for more details. + + Input streams return data blocks that automatically manage the memory for the data + and include the SRI that was in effect at the time the data was received. It is not + necessary to delete the block; it will be cleaned up when it goes out of scope. + + To send data using a BulkIO interface, create an output stream and write the + data to it. When done with the output stream, the close() method sends and end-of- + stream flag and cleans up. + + NOTE: If you have a BULKIO dataSDDS or dataVITA49 port, you must manually call + "port->updateStats()" to update the port statistics when appropriate. + + Example: + // This example assumes that the component has two ports: + // An input (provides) port of type bulkio::InShortPort called dataShort_in + // An output (uses) port of type bulkio::OutFloatPort called dataFloat_out + // The mapping between the port and the class is found + // in the component base class header file + + bulkio::InShortStream inputStream = dataShort_in->getCurrentStream(); + if (!inputStream) { // No streams are available + return NOOP; + } + + // Get the output stream, creating it if it doesn't exist yet + bulkio::OutFloatStream outputStream = dataFloat_out->getStream(inputStream.streamID()); + if (!outputStream) { + outputStream = dataFloat_out->createStream(inputStream.sri()); + } + + bulkio::ShortDataBlock block = inputStream.read(); + if (!block) { // No data available + // Propagate end-of-stream + if (inputStream.eos()) { + outputStream.close(); + } + return NOOP; + } + + if (block.sriChanged()) { + // Update output SRI + outputStream.sri(block.sri()); + } + + // Get read-only access to the input data + redhawk::shared_buffer inputData = block.buffer(); + + // Acquire a new buffer to hold the output data + redhawk::buffer outputData(inputData.size()); + + // Transform input data into output data + for (size_t index = 0; index < inputData.size(); ++index) { + outputData[index] = (float) inputData[index]; + } + + // Write to the output stream; outputData must not be modified after + // this method call + outputStream.write(outputData, block.getStartTime()); + + return NORMAL; + + If working with complex data (i.e., the "mode" on the SRI is set to + true), the data block's complex() method will return true. Data blocks + provide a cxbuffer() method that returns a complex interpretation of the + buffer without making a copy: + + if (block.complex()) { + redhawk::shared_buffer > inData = block.cxbuffer(); + redhawk::buffer > outData(inData.size()); + for (size_t index = 0; index < inData.size(); ++index) { + outData[index] = inData[index]; + } + outputStream.write(outData, block.getStartTime()); + } + + Interactions with non-BULKIO ports are left up to the component developer's discretion + + Messages: + + To receive a message, you need (1) an input port of type MessageEvent, (2) a message prototype described + as a structure property of kind message, (3) a callback to service the message, and (4) to register the callback + with the input port. + + Assuming a property of type message is declared called "my_msg", an input port called "msg_input" is declared of + type MessageEvent, create the following code: + + void snk_slow_i::my_message_callback(const std::string& id, const my_msg_struct &msg){ + } + + Register the message callback onto the input port with the following form: + this->msg_input->registerMessage("my_msg", this, &snk_slow_i::my_message_callback); + + To send a message, you need to (1) create a message structure, (2) a message prototype described + as a structure property of kind message, and (3) send the message over the port. + + Assuming a property of type message is declared called "my_msg", an output port called "msg_output" is declared of + type MessageEvent, create the following code: + + ::my_msg_struct msg_out; + this->msg_output->sendMessage(msg_out); + + Accessing the Application and Domain Manager: + + Both the Application hosting this Component and the Domain Manager hosting + the Application are available to the Component. + + To access the Domain Manager: + CF::DomainManager_ptr dommgr = this->getDomainManager()->getRef(); + To access the Application: + CF::Application_ptr app = this->getApplication()->getRef(); + + Properties: + + Properties are accessed directly as member variables. For example, if the + property name is "baudRate", it may be accessed within member functions as + "baudRate". Unnamed properties are given the property id as its name. + Property types are mapped to the nearest C++ type, (e.g. "string" becomes + "std::string"). All generated properties are declared in the base class + (snk_slow_base). + + Simple sequence properties are mapped to "std::vector" of the simple type. + Struct properties, if used, are mapped to C++ structs defined in the + generated file "struct_props.h". Field names are taken from the name in + the properties file; if no name is given, a generated name of the form + "field_n" is used, where "n" is the ordinal number of the field. + + Example: + // This example makes use of the following Properties: + // - A float value called scaleValue + // - A boolean called scaleInput + + if (scaleInput) { + dataOut[i] = dataIn[i] * scaleValue; + } else { + dataOut[i] = dataIn[i]; + } + + Callback methods can be associated with a property so that the methods are + called each time the property value changes. This is done by calling + addPropertyListener(, this, &snk_slow_i::) + in the constructor. + + The callback method receives two arguments, the old and new values, and + should return nothing (void). The arguments can be passed by value, + receiving a copy (preferred for primitive types), or by const reference + (preferred for strings, structs and vectors). + + Example: + // This example makes use of the following Properties: + // - A float value called scaleValue + // - A struct property called status + + //Add to snk_slow.cpp + snk_slow_i::snk_slow_i(const char *uuid, const char *label) : + snk_slow_base(uuid, label) + { + addPropertyListener(scaleValue, this, &snk_slow_i::scaleChanged); + addPropertyListener(status, this, &snk_slow_i::statusChanged); + } + + void snk_slow_i::scaleChanged(float oldValue, float newValue) + { + LOG_DEBUG(snk_slow_i, "scaleValue changed from" << oldValue << " to " << newValue); + } + + void snk_slow_i::statusChanged(const status_struct& oldValue, const status_struct& newValue) + { + LOG_DEBUG(snk_slow_i, "status changed"); + } + + //Add to snk_slow.h + void scaleChanged(float oldValue, float newValue); + void statusChanged(const status_struct& oldValue, const status_struct& newValue); + + +************************************************************************************************/ +int snk_slow_i::serviceFunction() +{ + bulkio::InFloatStream inputStream = this->dataFloat->getCurrentStream(); + if (!inputStream) { // No streams are available + return NOOP; + } + + bulkio::FloatDataBlock block = inputStream.read(); + return NOOP; +} + diff --git a/bulkioInterfaces/libsrc/testing/components/snk_slow/cpp/snk_slow.h b/bulkioInterfaces/libsrc/testing/components/snk_slow/cpp/snk_slow.h new file mode 100644 index 000000000..f4f9b0ef4 --- /dev/null +++ b/bulkioInterfaces/libsrc/testing/components/snk_slow/cpp/snk_slow.h @@ -0,0 +1,18 @@ +#ifndef SNK_SLOW_I_IMPL_H +#define SNK_SLOW_I_IMPL_H + +#include "snk_slow_base.h" + +class snk_slow_i : public snk_slow_base +{ + ENABLE_LOGGING + public: + snk_slow_i(const char *uuid, const char *label); + ~snk_slow_i(); + + void constructor(); + + int serviceFunction(); +}; + +#endif // SNK_SLOW_I_IMPL_H diff --git a/bulkioInterfaces/libsrc/testing/components/snk_slow/cpp/snk_slow_base.cpp b/bulkioInterfaces/libsrc/testing/components/snk_slow/cpp/snk_slow_base.cpp new file mode 100644 index 000000000..995fb71d3 --- /dev/null +++ b/bulkioInterfaces/libsrc/testing/components/snk_slow/cpp/snk_slow_base.cpp @@ -0,0 +1,65 @@ +#include "snk_slow_base.h" + +/******************************************************************************************* + + AUTO-GENERATED CODE. DO NOT MODIFY + + The following class functions are for the base class for the component class. To + customize any of these functions, do not modify them here. Instead, overload them + on the child class + +******************************************************************************************/ + +snk_slow_base::snk_slow_base(const char *uuid, const char *label) : + Component(uuid, label), + ThreadedComponent() +{ + setThreadName(label); + + loadProperties(); + + dataFloat = new bulkio::InFloatPort("dataFloat"); + addPort("dataFloat", dataFloat); +} + +snk_slow_base::~snk_slow_base() +{ + dataFloat->_remove_ref(); + dataFloat = 0; +} + +/******************************************************************************************* + Framework-level functions + These functions are generally called by the framework to perform housekeeping. +*******************************************************************************************/ +void snk_slow_base::start() throw (CORBA::SystemException, CF::Resource::StartError) +{ + Component::start(); + ThreadedComponent::startThread(); +} + +void snk_slow_base::stop() throw (CORBA::SystemException, CF::Resource::StopError) +{ + Component::stop(); + if (!ThreadedComponent::stopThread()) { + throw CF::Resource::StopError(CF::CF_NOTSET, "Processing thread did not die"); + } +} + +void snk_slow_base::releaseObject() throw (CORBA::SystemException, CF::LifeCycle::ReleaseError) +{ + // This function clears the component running condition so main shuts down everything + try { + stop(); + } catch (CF::Resource::StopError& ex) { + // TODO - this should probably be logged instead of ignored + } + + Component::releaseObject(); +} + +void snk_slow_base::loadProperties() +{ +} + + diff --git a/bulkioInterfaces/libsrc/testing/components/snk_slow/cpp/snk_slow_base.h b/bulkioInterfaces/libsrc/testing/components/snk_slow/cpp/snk_slow_base.h new file mode 100644 index 000000000..0945fd9e5 --- /dev/null +++ b/bulkioInterfaces/libsrc/testing/components/snk_slow/cpp/snk_slow_base.h @@ -0,0 +1,32 @@ +#ifndef SNK_SLOW_BASE_IMPL_BASE_H +#define SNK_SLOW_BASE_IMPL_BASE_H + +#include +#include +#include + +#include + +class snk_slow_base : public Component, protected ThreadedComponent +{ + public: + snk_slow_base(const char *uuid, const char *label); + ~snk_slow_base(); + + void start() throw (CF::Resource::StartError, CORBA::SystemException); + + void stop() throw (CF::Resource::StopError, CORBA::SystemException); + + void releaseObject() throw (CF::LifeCycle::ReleaseError, CORBA::SystemException); + + void loadProperties(); + + protected: + + // Ports + /// Port: dataFloat + bulkio::InFloatPort *dataFloat; + + private: +}; +#endif // SNK_SLOW_BASE_IMPL_BASE_H diff --git a/bulkioInterfaces/libsrc/testing/components/snk_slow/snk_slow.prf.xml b/bulkioInterfaces/libsrc/testing/components/snk_slow/snk_slow.prf.xml new file mode 100644 index 000000000..8f537d89f --- /dev/null +++ b/bulkioInterfaces/libsrc/testing/components/snk_slow/snk_slow.prf.xml @@ -0,0 +1,3 @@ + + + diff --git a/bulkioInterfaces/libsrc/testing/components/snk_slow/snk_slow.scd.xml b/bulkioInterfaces/libsrc/testing/components/snk_slow/snk_slow.scd.xml new file mode 100644 index 000000000..897f913be --- /dev/null +++ b/bulkioInterfaces/libsrc/testing/components/snk_slow/snk_slow.scd.xml @@ -0,0 +1,53 @@ + + + + 2.2 + + resource + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bulkioInterfaces/libsrc/testing/components/snk_slow/snk_slow.spd.xml b/bulkioInterfaces/libsrc/testing/components/snk_slow/snk_slow.spd.xml new file mode 100644 index 000000000..63a211cc5 --- /dev/null +++ b/bulkioInterfaces/libsrc/testing/components/snk_slow/snk_slow.spd.xml @@ -0,0 +1,27 @@ + + + + + + null + + + + + + + + + The implementation contains descriptive information about the template for a software resource. + + + cpp/snk_slow.so + + + + + + + + + diff --git a/bulkioInterfaces/libsrc/testing/components/snk_slow/tests/test_snk_slow.py b/bulkioInterfaces/libsrc/testing/components/snk_slow/tests/test_snk_slow.py new file mode 100755 index 000000000..508f510d7 --- /dev/null +++ b/bulkioInterfaces/libsrc/testing/components/snk_slow/tests/test_snk_slow.py @@ -0,0 +1,46 @@ +#!/usr/bin/env python + +import ossie.utils.testing +from ossie.utils import sb + +class ComponentTests(ossie.utils.testing.RHTestCase): + # Path to the SPD file, relative to this file. This must be set in order to + # launch the component. + SPD_FILE = '../snk_slow.spd.xml' + + # setUp is run before every function preceded by "test" is executed + # tearDown is run after every function preceded by "test" is executed + + # self.comp is a component using the sandbox API + # to create a data source, the package sb contains data sources like DataSource or FileSource + # to create a data sink, there are sinks like DataSink and FileSink + # to connect the component to get data from a file, process it, and write the output to a file, use the following syntax: + # src = sb.FileSource('myfile.dat') + # snk = sb.DataSink() + # src.connect(self.comp) + # self.comp.connect(snk) + # sb.start() + # + # components/sources/sinks need to be started. Individual components or elements can be started + # src.start() + # self.comp.start() + # + # every component/elements in the sandbox can be started + # sb.start() + + def setUp(self): + # Launch the component, using the selected implementation + self.comp = sb.launch(self.spd_file, impl=self.impl) + + def tearDown(self): + # Clean up all sandbox artifacts created during test + sb.release() + + def testBasicBehavior(self): + ####################################################################### + # Make sure start and stop can be called without throwing exceptions + self.comp.start() + self.comp.stop() + +if __name__ == "__main__": + ossie.utils.testing.main() # By default tests all implementations diff --git a/bulkioInterfaces/libsrc/testing/components/src/cpp/Makefile.am b/bulkioInterfaces/libsrc/testing/components/src/cpp/Makefile.am new file mode 100644 index 000000000..ae441b604 --- /dev/null +++ b/bulkioInterfaces/libsrc/testing/components/src/cpp/Makefile.am @@ -0,0 +1,49 @@ +# +# This file is part of REDHAWK bulkioInterfaces. +# +# REDHAWK bulkioInterfaces is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation, either version 3 of the License, or (at your option) any +# later version. +# +# REDHAWK bulkioInterfaces is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +# details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/. +# +ossieName = src +bindir = $(prefix)/dom/components/src/cpp +bin_PROGRAMS = src + +xmldir = $(prefix)/dom/components/src +dist_xml_DATA = ../src.scd.xml ../src.prf.xml ../src.spd.xml +ACLOCAL_AMFLAGS = -I m4 -I${OSSIEHOME}/share/aclocal/ossie +AUTOMAKE_OPTIONS = subdir-objects + +distclean-local: + rm -rf m4 + rm -f config.* + rm -rf autom4te.cache + rm -f acinclude.m4 + rm -f aclocal.m4 + rm -f configure + rm -f depcomp + rm -f install-sh + rm -f ltmain.sh + rm -f Makefile.in + rm -f missing + rm -rf .deps + + +# Sources, libraries and library directories are auto-included from a file +# generated by the REDHAWK IDE. You can remove/modify the following lines if +# you wish to manually control these options. +include $(srcdir)/Makefile.am.ide +src_SOURCES = $(redhawk_SOURCES_auto) +src_LDADD = $(SOFTPKG_LIBS) $(PROJECTDEPS_LIBS) $(BOOST_LDFLAGS) $(BOOST_THREAD_LIB) $(BOOST_REGEX_LIB) $(BOOST_SYSTEM_LIB) $(INTERFACEDEPS_LIBS) $(redhawk_LDADD_auto) +src_CXXFLAGS = -Wall $(SOFTPKG_CFLAGS) $(PROJECTDEPS_CFLAGS) $(BOOST_CPPFLAGS) $(INTERFACEDEPS_CFLAGS) $(redhawk_INCLUDES_auto) +src_LDFLAGS = -Wall $(redhawk_LDFLAGS_auto) + diff --git a/bulkioInterfaces/libsrc/testing/components/src/cpp/Makefile.am.ide b/bulkioInterfaces/libsrc/testing/components/src/cpp/Makefile.am.ide new file mode 100644 index 000000000..4056deef8 --- /dev/null +++ b/bulkioInterfaces/libsrc/testing/components/src/cpp/Makefile.am.ide @@ -0,0 +1,10 @@ +# This file is regularly auto-generated by the REDHAWK IDE. Do not modify! +# Files can be excluded by right-clicking on the file in the project explorer +# and choosing Resource Configurations -> Exclude from build. Re-include files +# by opening the Properties dialog of your project and choosing C/C++ Build -> +# Tool Chain Editor, and un-checking "Exclude resource from build " +redhawk_SOURCES_auto = main.cpp +redhawk_SOURCES_auto += src.cpp +redhawk_SOURCES_auto += src.h +redhawk_SOURCES_auto += src_base.cpp +redhawk_SOURCES_auto += src_base.h diff --git a/bulkioInterfaces/libsrc/testing/components/src/cpp/main.cpp b/bulkioInterfaces/libsrc/testing/components/src/cpp/main.cpp new file mode 100644 index 000000000..83ecfe617 --- /dev/null +++ b/bulkioInterfaces/libsrc/testing/components/src/cpp/main.cpp @@ -0,0 +1,11 @@ +#include +#include "ossie/ossieSupport.h" + +#include "src.h" +int main(int argc, char* argv[]) +{ + src_i* src_servant; + Component::start_component(src_servant, argc, argv); + return 0; +} + diff --git a/bulkioInterfaces/libsrc/testing/components/src/cpp/src.cpp b/bulkioInterfaces/libsrc/testing/components/src/cpp/src.cpp new file mode 100644 index 000000000..9e5919fae --- /dev/null +++ b/bulkioInterfaces/libsrc/testing/components/src/cpp/src.cpp @@ -0,0 +1,253 @@ +/************************************************************************** + + This is the component code. This file contains the child class where + custom functionality can be added to the component. Custom + functionality to the base class can be extended here. Access to + the ports can also be done from this class + +**************************************************************************/ + +#include "src.h" + +PREPARE_LOGGING(src_i) + +src_i::src_i(const char *uuid, const char *label) : + src_base(uuid, label) +{ + // Avoid placing constructor code here. Instead, use the "constructor" function. + +} + +src_i::~src_i() +{ +} + +void src_i::constructor() +{ + /*********************************************************************************** + This is the RH constructor. All properties are properly initialized before this function is called + ***********************************************************************************/ + stream = dataFloat->createStream("hello"); + stream.xdelta(0.4); + stream.blocking(true); +} + +/*********************************************************************************************** + + Basic functionality: + + The service function is called by the serviceThread object (of type ProcessThread). + This call happens immediately after the previous call if the return value for + the previous call was NORMAL. + If the return value for the previous call was NOOP, then the serviceThread waits + an amount of time defined in the serviceThread's constructor. + + SRI: + To create a StreamSRI object, use the following code: + std::string stream_id = "testStream"; + BULKIO::StreamSRI sri = bulkio::sri::create(stream_id); + + Time: + To create a PrecisionUTCTime object, use the following code: + BULKIO::PrecisionUTCTime tstamp = bulkio::time::utils::now(); + + + Ports: + + Data is passed to the serviceFunction through by reading from input streams + (BulkIO only). The input stream class is a port-specific class, so each port + implementing the BulkIO interface will have its own type-specific input stream. + UDP multicast (dataSDDS and dataVITA49) and string-based (dataString, dataXML and + dataFile) do not support streams. + + The input stream from which to read can be requested with the getCurrentStream() + method. The optional argument to getCurrentStream() is a floating point number that + specifies the time to wait in seconds. A zero value is non-blocking. A negative value + is blocking. Constants have been defined for these values, bulkio::Const::BLOCKING and + bulkio::Const::NON_BLOCKING. + + More advanced uses of input streams are possible; refer to the REDHAWK documentation + for more details. + + Input streams return data blocks that automatically manage the memory for the data + and include the SRI that was in effect at the time the data was received. It is not + necessary to delete the block; it will be cleaned up when it goes out of scope. + + To send data using a BulkIO interface, create an output stream and write the + data to it. When done with the output stream, the close() method sends and end-of- + stream flag and cleans up. + + NOTE: If you have a BULKIO dataSDDS or dataVITA49 port, you must manually call + "port->updateStats()" to update the port statistics when appropriate. + + Example: + // This example assumes that the component has two ports: + // An input (provides) port of type bulkio::InShortPort called dataShort_in + // An output (uses) port of type bulkio::OutFloatPort called dataFloat_out + // The mapping between the port and the class is found + // in the component base class header file + // The component class must have an output stream member; add to + // src.h: + // bulkio::OutFloatStream outputStream; + + bulkio::InShortStream inputStream = dataShort_in->getCurrentStream(); + if (!inputStream) { // No streams are available + return NOOP; + } + + bulkio::ShortDataBlock block = inputStream.read(); + if (!block) { // No data available + // Propagate end-of-stream + if (inputStream.eos()) { + outputStream.close(); + } + return NOOP; + } + + short* inputData = block.data(); + std::vector outputData; + outputData.resize(block.size()); + for (size_t index = 0; index < block.size(); ++index) { + outputData[index] = (float) inputData[index]; + } + + // If there is no output stream open, create one + if (!outputStream) { + outputStream = dataFloat_out->createStream(block.sri()); + } else if (block.sriChanged()) { + // Update output SRI + outputStream.sri(block.sri()); + } + + // Write to the output stream + outputStream.write(outputData, block.getTimestamps()); + + // Propagate end-of-stream + if (inputStream.eos()) { + outputStream.close(); + } + + return NORMAL; + + If working with complex data (i.e., the "mode" on the SRI is set to + true), the data block's complex() method will return true. Data blocks + provide functions that return the correct interpretation of the data + buffer and number of complex elements: + + if (block.complex()) { + std::complex* data = block.cxdata(); + for (size_t index = 0; index < block.cxsize(); ++index) { + data[index] = std::abs(data[index]); + } + outputStream.write(data, block.cxsize(), bulkio::time::utils::now()); + } + + Interactions with non-BULKIO ports are left up to the component developer's discretion + + Messages: + + To receive a message, you need (1) an input port of type MessageEvent, (2) a message prototype described + as a structure property of kind message, (3) a callback to service the message, and (4) to register the callback + with the input port. + + Assuming a property of type message is declared called "my_msg", an input port called "msg_input" is declared of + type MessageEvent, create the following code: + + void src_i::my_message_callback(const std::string& id, const my_msg_struct &msg){ + } + + Register the message callback onto the input port with the following form: + this->msg_input->registerMessage("my_msg", this, &src_i::my_message_callback); + + To send a message, you need to (1) create a message structure, (2) a message prototype described + as a structure property of kind message, and (3) send the message over the port. + + Assuming a property of type message is declared called "my_msg", an output port called "msg_output" is declared of + type MessageEvent, create the following code: + + ::my_msg_struct msg_out; + this->msg_output->sendMessage(msg_out); + + Accessing the Application and Domain Manager: + + Both the Application hosting this Component and the Domain Manager hosting + the Application are available to the Component. + + To access the Domain Manager: + CF::DomainManager_ptr dommgr = this->getDomainManager()->getRef(); + To access the Application: + CF::Application_ptr app = this->getApplication()->getRef(); + + Properties: + + Properties are accessed directly as member variables. For example, if the + property name is "baudRate", it may be accessed within member functions as + "baudRate". Unnamed properties are given the property id as its name. + Property types are mapped to the nearest C++ type, (e.g. "string" becomes + "std::string"). All generated properties are declared in the base class + (src_base). + + Simple sequence properties are mapped to "std::vector" of the simple type. + Struct properties, if used, are mapped to C++ structs defined in the + generated file "struct_props.h". Field names are taken from the name in + the properties file; if no name is given, a generated name of the form + "field_n" is used, where "n" is the ordinal number of the field. + + Example: + // This example makes use of the following Properties: + // - A float value called scaleValue + // - A boolean called scaleInput + + if (scaleInput) { + dataOut[i] = dataIn[i] * scaleValue; + } else { + dataOut[i] = dataIn[i]; + } + + Callback methods can be associated with a property so that the methods are + called each time the property value changes. This is done by calling + addPropertyListener(, this, &src_i::) + in the constructor. + + The callback method receives two arguments, the old and new values, and + should return nothing (void). The arguments can be passed by value, + receiving a copy (preferred for primitive types), or by const reference + (preferred for strings, structs and vectors). + + Example: + // This example makes use of the following Properties: + // - A float value called scaleValue + // - A struct property called status + + //Add to src.cpp + src_i::src_i(const char *uuid, const char *label) : + src_base(uuid, label) + { + addPropertyListener(scaleValue, this, &src_i::scaleChanged); + addPropertyListener(status, this, &src_i::statusChanged); + } + + void src_i::scaleChanged(float oldValue, float newValue) + { + LOG_DEBUG(src_i, "scaleValue changed from" << oldValue << " to " << newValue); + } + + void src_i::statusChanged(const status_struct& oldValue, const status_struct& newValue) + { + LOG_DEBUG(src_i, "status changed"); + } + + //Add to src.h + void scaleChanged(float oldValue, float newValue); + void statusChanged(const status_struct& oldValue, const status_struct& newValue); + + +************************************************************************************************/ +int src_i::serviceFunction() +{ + redhawk::buffer data(10000); + stream.write(data, bulkio::time::utils::now()); + + return NORMAL; +} + diff --git a/bulkioInterfaces/libsrc/testing/components/src/cpp/src.h b/bulkioInterfaces/libsrc/testing/components/src/cpp/src.h new file mode 100644 index 000000000..dc70e5199 --- /dev/null +++ b/bulkioInterfaces/libsrc/testing/components/src/cpp/src.h @@ -0,0 +1,19 @@ +#ifndef SRC_I_IMPL_H +#define SRC_I_IMPL_H + +#include "src_base.h" + +class src_i : public src_base +{ + ENABLE_LOGGING + public: + src_i(const char *uuid, const char *label); + ~src_i(); + + void constructor(); + + int serviceFunction(); + bulkio::OutFloatStream stream; +}; + +#endif // SRC_I_IMPL_H diff --git a/bulkioInterfaces/libsrc/testing/components/src/cpp/src_base.cpp b/bulkioInterfaces/libsrc/testing/components/src/cpp/src_base.cpp new file mode 100644 index 000000000..b7e3cf24e --- /dev/null +++ b/bulkioInterfaces/libsrc/testing/components/src/cpp/src_base.cpp @@ -0,0 +1,65 @@ +#include "src_base.h" + +/******************************************************************************************* + + AUTO-GENERATED CODE. DO NOT MODIFY + + The following class functions are for the base class for the component class. To + customize any of these functions, do not modify them here. Instead, overload them + on the child class + +******************************************************************************************/ + +src_base::src_base(const char *uuid, const char *label) : + Component(uuid, label), + ThreadedComponent() +{ + setThreadName(label); + + loadProperties(); + + dataFloat = new bulkio::OutFloatPort("dataFloat"); + addPort("dataFloat", dataFloat); +} + +src_base::~src_base() +{ + dataFloat->_remove_ref(); + dataFloat = 0; +} + +/******************************************************************************************* + Framework-level functions + These functions are generally called by the framework to perform housekeeping. +*******************************************************************************************/ +void src_base::start() throw (CORBA::SystemException, CF::Resource::StartError) +{ + Component::start(); + ThreadedComponent::startThread(); +} + +void src_base::stop() throw (CORBA::SystemException, CF::Resource::StopError) +{ + Component::stop(); + if (!ThreadedComponent::stopThread()) { + throw CF::Resource::StopError(CF::CF_NOTSET, "Processing thread did not die"); + } +} + +void src_base::releaseObject() throw (CORBA::SystemException, CF::LifeCycle::ReleaseError) +{ + // This function clears the component running condition so main shuts down everything + try { + stop(); + } catch (CF::Resource::StopError& ex) { + // TODO - this should probably be logged instead of ignored + } + + Component::releaseObject(); +} + +void src_base::loadProperties() +{ +} + + diff --git a/bulkioInterfaces/libsrc/testing/components/src/cpp/src_base.h b/bulkioInterfaces/libsrc/testing/components/src/cpp/src_base.h new file mode 100644 index 000000000..cbdfad230 --- /dev/null +++ b/bulkioInterfaces/libsrc/testing/components/src/cpp/src_base.h @@ -0,0 +1,32 @@ +#ifndef SRC_BASE_IMPL_BASE_H +#define SRC_BASE_IMPL_BASE_H + +#include +#include +#include + +#include + +class src_base : public Component, protected ThreadedComponent +{ + public: + src_base(const char *uuid, const char *label); + ~src_base(); + + void start() throw (CF::Resource::StartError, CORBA::SystemException); + + void stop() throw (CF::Resource::StopError, CORBA::SystemException); + + void releaseObject() throw (CF::LifeCycle::ReleaseError, CORBA::SystemException); + + void loadProperties(); + + protected: + + // Ports + /// Port: dataFloat + bulkio::OutFloatPort *dataFloat; + + private: +}; +#endif // SRC_BASE_IMPL_BASE_H diff --git a/bulkioInterfaces/libsrc/testing/components/src/src.prf.xml b/bulkioInterfaces/libsrc/testing/components/src/src.prf.xml new file mode 100644 index 000000000..8f537d89f --- /dev/null +++ b/bulkioInterfaces/libsrc/testing/components/src/src.prf.xml @@ -0,0 +1,3 @@ + + + diff --git a/bulkioInterfaces/libsrc/testing/components/src/src.scd.xml b/bulkioInterfaces/libsrc/testing/components/src/src.scd.xml new file mode 100644 index 000000000..a4abbbd6f --- /dev/null +++ b/bulkioInterfaces/libsrc/testing/components/src/src.scd.xml @@ -0,0 +1,53 @@ + + + + 2.2 + + resource + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bulkioInterfaces/libsrc/testing/components/src/src.spd.xml b/bulkioInterfaces/libsrc/testing/components/src/src.spd.xml new file mode 100644 index 000000000..946f1de02 --- /dev/null +++ b/bulkioInterfaces/libsrc/testing/components/src/src.spd.xml @@ -0,0 +1,27 @@ + + + + + + null + + + + + + + + + The implementation contains descriptive information about the template for a software resource. + + + cpp/src + + + + + + + + + diff --git a/bulkioInterfaces/libsrc/testing/components/src/tests/test_src.py b/bulkioInterfaces/libsrc/testing/components/src/tests/test_src.py new file mode 100755 index 000000000..8cb54079a --- /dev/null +++ b/bulkioInterfaces/libsrc/testing/components/src/tests/test_src.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python + +import ossie.utils.testing +from ossie.utils import sb +import time + +class ComponentTests(ossie.utils.testing.RHTestCase): + # Path to the SPD file, relative to this file. This must be set in order to + # launch the component. + SPD_FILE = '../src.spd.xml' + + # setUp is run before every function preceded by "test" is executed + # tearDown is run after every function preceded by "test" is executed + + # self.comp is a component using the sandbox API + # to create a data source, the package sb contains data sources like DataSource or FileSource + # to create a data sink, there are sinks like DataSink and FileSink + # to connect the component to get data from a file, process it, and write the output to a file, use the following syntax: + # src = sb.FileSource('myfile.dat') + # snk = sb.DataSink() + # src.connect(self.comp) + # self.comp.connect(snk) + # sb.start() + # + # components/sources/sinks need to be started. Individual components or elements can be started + # src.start() + # self.comp.start() + # + # every component/elements in the sandbox can be started + # sb.start() + + def setUp(self): + # Launch the component, using the selected implementation + self.comp = sb.launch('../../src/src.spd.xml') + self.snk = sb.launch('../../snk_slow/snk_slow.spd.xml') + + def tearDown(self): + # Clean up all sandbox artifacts created during test + sb.release() + + def testBasicBehavior(self): + ####################################################################### + # Make sure start and stop can be called without throwing exceptions + self.comp.connect(self.snk) + self.comp.start() + self.snk.start() + time.sleep(1) + try: + self.comp.stop() + except: + pass + self.snk.stop() + self.comp.releaseObject() + self.snk.releaseObject() + +if __name__ == "__main__": + ossie.utils.testing.main() # By default tests all implementations diff --git a/bulkioInterfaces/libsrc/testing/tests/runtests b/bulkioInterfaces/libsrc/testing/tests/runtests index 298359e3c..0660e96b8 100755 --- a/bulkioInterfaces/libsrc/testing/tests/runtests +++ b/bulkioInterfaces/libsrc/testing/tests/runtests @@ -96,6 +96,14 @@ cd ../components/Oversized_framedata/tests/ ./test_Oversized_framedata.py cd - +# +# Run port lock Test +# +# +cd ../components/src/tests/ +./test_src.py +cd - + # # Run jni reference resolution # diff --git a/redhawk/src/base/framework/python/ossie/utils/model/connect.py b/redhawk/src/base/framework/python/ossie/utils/model/connect.py index 23013058b..828d06579 100644 --- a/redhawk/src/base/framework/python/ossie/utils/model/connect.py +++ b/redhawk/src/base/framework/python/ossie/utils/model/connect.py @@ -20,6 +20,7 @@ import logging import threading +import omniORB log = logging.getLogger(__name__) @@ -204,11 +205,13 @@ def refreshConnections(self, components): def _breakConnection(self, identifier, uses, provides): log.debug("Breaking connection '%s'", identifier) + omniORB.setClientCallTimeout(1500) try: usesPort = uses.getReference() usesPort.disconnectPort(identifier) except: log.warn("Ignoring exception breaking connection '%s'", identifier) + omniORB.setClientCallTimeout(0) uses.disconnected(identifier) provides.disconnected(identifier) diff --git a/redhawk/src/base/include/ossie/UsesPort.h b/redhawk/src/base/include/ossie/UsesPort.h index c1e0635c6..f3b65c22e 100644 --- a/redhawk/src/base/include/ossie/UsesPort.h +++ b/redhawk/src/base/include/ossie/UsesPort.h @@ -43,6 +43,15 @@ namespace redhawk { } }; + class TransportTimeoutError : public TransportError + { + public: + TransportTimeoutError(const std::string& message) : + TransportError(message) + { + } + }; + class FatalTransportError : public TransportError { public: From 7c7240e7acf1a26ae384b12c39aca2d99a2185f4 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Tue, 16 May 2017 15:16:19 -0400 Subject: [PATCH 0800/1644] Refs CF-424. Added data rate throttling to FileSource and DataSource --- .../ossie/utils/bluefile/bluefile_helpers.py | 13 +++- .../ossie/utils/bulkio/bulkio_data_helpers.py | 10 ++- .../python/ossie/utils/sb/io_helpers.py | 26 +++++-- redhawk/src/testing/tests/test_13_TestSB.py | 76 ++++++++++++++++++- 4 files changed, 114 insertions(+), 11 deletions(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/bluefile/bluefile_helpers.py b/redhawk/src/base/framework/python/ossie/utils/bluefile/bluefile_helpers.py index f47c0ede6..657203d15 100644 --- a/redhawk/src/base/framework/python/ossie/utils/bluefile/bluefile_helpers.py +++ b/redhawk/src/base/framework/python/ossie/utils/bluefile/bluefile_helpers.py @@ -231,7 +231,7 @@ class BlueFileReader(object): Simple class used to send data to a port from an X-Midas file. It uses the header to generate a SRI. """ - def __init__(self, porttype): + def __init__(self, porttype, throttle=False): """ Instantiates a new object and generates a default StreamSRI. The porttype parameter corresponds to the type of data contained in the @@ -249,6 +249,7 @@ def __init__(self, porttype): 0.001, 1, 0, "sampleStream", True, []) self.port_lock = threading.Lock() + self._throttle=throttle self.done = False def connectPort(self, connection, connectionId): @@ -284,8 +285,13 @@ def pushSRI(self, H): def pushPacket(self, data, T, EOS, streamID): if self.refreshSRI: self.pushSRI(self.defaultStreamSRI) + self.port_lock.acquire() - try: + + if self._throttle: + time.sleep(len(data)*self.defaultStreamSRI.xdelta/2.0) + + try: try: for connId, port in self.outPorts.items(): if port != None: port.pushPacket(data, T, EOS, streamID) @@ -296,6 +302,9 @@ def pushPacket(self, data, T, EOS, streamID): finally: self.port_lock.release() + if self._throttle: + time.sleep(len(data)*self.defaultStreamSRI.xdelta/2.0) + def getPort(self): """ Returns a Port object of the type CF__POA.Port. diff --git a/redhawk/src/base/framework/python/ossie/utils/bulkio/bulkio_data_helpers.py b/redhawk/src/base/framework/python/ossie/utils/bulkio/bulkio_data_helpers.py index fd0dff8db..417de9756 100644 --- a/redhawk/src/base/framework/python/ossie/utils/bulkio/bulkio_data_helpers.py +++ b/redhawk/src/base/framework/python/ossie/utils/bulkio/bulkio_data_helpers.py @@ -1164,7 +1164,7 @@ class FileSource(object): """ Simple class used to push data into a port from a given array of data. """ - def __init__(self, porttype, byteswap=False, usesPortTypeDict=None): + def __init__(self, porttype, byteswap=False, usesPortTypeDict=None, throttle=False): """ Instantiates a new object and generates a default StreamSRI. The porttype parameter corresponds to the type of data contained in the @@ -1221,6 +1221,7 @@ def __init__(self, porttype, byteswap=False, usesPortTypeDict=None): self.connectionNormalization = {} self.connectionTranslation = {} self.usesPortTypeDict = usesPortTypeDict + self._throttle=throttle self.refreshSRI = False # Create default SRI self.sri=bulkio_helpers.defaultSRI @@ -1305,6 +1306,9 @@ def pushPacket(self, data, T, EOS, streamID): if EOS: # This deals with subsequent pushes with the same SRI self.refreshSRI = True + if self._throttle: + time.sleep(len(data)*self.sri.xdelta/2.0) + self.port_lock.acquire() try: try: @@ -1333,6 +1337,10 @@ def pushPacket(self, data, T, EOS, streamID): finally: self.port_lock.release() + if self._throttle: + time.sleep(len(data)*self.sri.xdelta/2.0) + + def getPort(self): """ Returns a Port object of the type CF__POA.Port. diff --git a/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py b/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py index 53e8bab54..2021d7c19 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py +++ b/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py @@ -833,7 +833,8 @@ def __init__(self, startTime = 0.0, streamID = None, blocking = True, - subsize = 0): + subsize = 0, + throttle = False): self._filename = filename self._midasFile = midasFile @@ -846,6 +847,7 @@ def __init__(self, self._streamID = streamID self._blocking = blocking self._sri = None + self._throttle = throttle self._byteswap = False self._defaultDataFormat = '16t' @@ -962,10 +964,10 @@ def setupFileReader(self): # If input file is a Midas Blue file if self._midasFile == True: # define source helper component - self._src = bluefile_helpers.BlueFileReader(eval(portType)) + self._src = bluefile_helpers.BlueFileReader(eval(portType), throttle=self._throttle) # else, input file is binary file else: - self._src = bulkio_data_helpers.FileSource(eval(portType),self._byteswap, portTypes) + self._src = bulkio_data_helpers.FileSource(eval(portType),self._byteswap, portTypes, throttle=self._throttle) keywords = [] for key in self._SRIKeywords: keywords.append(_CF.DataType(key._name, _getAnyValue(key))) @@ -1182,6 +1184,11 @@ def _createArraySrcInst(self, srcPortType): return self._src class DataSource(_SourceBase): + ''' + Soure of Bulk IO data. Supported data format strings: + char, short, long, float, double, longlong, octet, ushort, ulong, ulonglong + throttle: when True, data will match sampleRate (provided in the push function) + ''' def __init__(self, data = None, dataFormat = None, @@ -1190,7 +1197,8 @@ def __init__(self, startTime = 0.0, blocking = True, subsize = 0, - sri = None): + sri = None, + throttle = False): fmts=['char','short','long','float','double','longlong','octet','ushort', 'ulong', 'ulonglong', 'file','xml' ] self.threadExited = None @@ -1215,6 +1223,7 @@ def __init__(self, self._runThread = None self._dataQueue = _Queue.Queue() self._currentSampleTime = self._startTime + self._throttle = throttle # Track unsent packets so that callers can monitor for when all packets # have really been sent; checking for an empty queue only tells whether @@ -1612,6 +1621,10 @@ def _pushPacket(self, 0.0, int(currentSampleTime), currentSampleTime - int(currentSampleTime)) + if self._throttle: + if self._sampleRate != None: + _time.sleep(len(data)/(self._sampleRate*2.0)) + if srcPortType != "_BULKIO__POA.dataXML": bulkio_data_helpers.ArraySource.pushPacket(arraySrcInst, data = data, @@ -1623,6 +1636,9 @@ def _pushPacket(self, data = data, EOS = EOS, streamID = streamID) + if self._throttle: + if self._sampleRate != None: + _time.sleep(len(data)/(self._sampleRate*2.0)) def _pushSRIAllConnectedPorts(self, sri): for connection in self._connections.values(): @@ -1759,7 +1775,7 @@ def from_char(data): else: retval = from_char(retval) if tstamps: - return (retval,timestamps) + return (retval, timestamps) else: return retval diff --git a/redhawk/src/testing/tests/test_13_TestSB.py b/redhawk/src/testing/tests/test_13_TestSB.py index f49909767..5c20d641f 100644 --- a/redhawk/src/testing/tests/test_13_TestSB.py +++ b/redhawk/src/testing/tests/test_13_TestSB.py @@ -137,14 +137,20 @@ def test_NoInteractiveCppComponent(self): status, output=commands.getstatusoutput('sdr/dom/components/ECM_CPP/cpp/ECM_CPP -i') self.assertNotEquals(output.find(self.message),-1) -def wait_on_data( sink, number_timestamps ): - _timeout = 1 +def wait_on_data(sink, number_timestamps, timeout=1): begin_time = time.time() estimate = sink.getDataEstimate() while estimate.num_timestamps != number_timestamps: time.sleep(0.1) estimate = sink.getDataEstimate() - if time.time() - begin_time > _timeout: + if time.time() - begin_time > timeout: + break + +def wait_for_eos(sink, timeout=10): + begin_time = time.time() + while not sink.eos(): + time.sleep(0.1) + if time.time() - begin_time > timeout: break class SBEventChannelTest(scatest.CorbaTestCase): @@ -1837,6 +1843,7 @@ def test_DataSourceChunkedTimeStamp(self): break (_data, _tstamps) = sink.getData(tstamps=True) xdelta = sink.sri().xdelta + print _tstamps self.assertEquals(_tstamps[0][1].twsec, _startTime) self.assertEquals(_tstamps[1][1].twsec, _tstamps[1][0]*sink.sri().xdelta+_startTime) self.assertEquals(_tstamps[2][1].twsec, _tstamps[2][0]*sink.sri().xdelta+_startTime) @@ -2070,6 +2077,68 @@ def test_DataSinkSRI(self): self.assertEquals(block_2.xdelta(), 0.001) self.assertEquals(block_3.xdelta(), 0.0001) + def _fileSourceThrottle(self, _file, rate): + fp=open(_file, 'r') + contents = fp.read() + fp.close() + source = sb.FileSource(_file, dataFormat='octet', sampleRate=rate, throttle=True) + sink = sb.DataSink() + source.connect(sink) + time_estimate = len(contents)/float(rate) + sb.start() + begin_time = time.time() + wait_for_eos(sink) + time_diff = time.time()-begin_time + self.assertTrue(time_difftime_estimate*0.9) + sb.stop() + + def test_FileSourceThrottle(self): + infile = os.path.join(sb.getSDRROOT(), 'dom/mgr/DomainManager.spd.xml') + self._fileSourceThrottle(infile, 1000) + self._fileSourceThrottle(infile, 1500) + + def test_DataSourceThrottle(self): + src = sb.DataSource(dataFormat='float', throttle=True) + snk = sb.DataSink() + src.connect(snk) + sb.start() + _sampleRate = 500 + _dataLength = 100 + time_estimate = (3.0*_dataLength)/(_sampleRate) + begin_time = time.time() + src.push([float(x) for x in range(100)],sampleRate=_sampleRate) + src.push([float(x) for x in range(100)],sampleRate=_sampleRate) + src.push([float(x) for x in range(100)],sampleRate=_sampleRate) + wait_on_data(snk, 3, 5) + end_time = time.time() + time_diff = end_time-begin_time + self.assertTrue(time_difftime_estimate*0.9) + + stream=snk.getCurrentStream() + block_1 = stream.read() + self.assertNotEqual(block_1, None) + self.assertEquals(len(block_1.data()), 3.0*_dataLength) + + _sampleRate = 300 + _dataLength = 100 + time_estimate = (3.0*_dataLength)/(_sampleRate) + begin_time = time.time() + src.push([float(x) for x in range(100)],sampleRate=_sampleRate) + src.push([float(x) for x in range(100)],sampleRate=_sampleRate) + src.push([float(x) for x in range(100)],sampleRate=_sampleRate) + wait_on_data(snk, 3, 5) + end_time = time.time() + time_diff = end_time-begin_time + self.assertTrue(time_difftime_estimate*0.9) + + stream=snk.getCurrentStream() + block_1 = stream.read() + self.assertNotEqual(block_1, None) + self.assertEquals(len(block_1.data()), 3.0*_dataLength) + def test_DataSinkMultipleStream(self): src = sb.DataSource(dataFormat='float') snk = sb.DataSink() @@ -2234,6 +2303,7 @@ def test_CustomDataSink(self): src.push([1,2,3,4,5],sampleRate=10000) wait_on_data(snk, 3) data=snk.getData(tstamps=True) + print data self.assertEquals(len(data[1]), 3) self.assertEquals(len(data[0]), 15) From bc8ef95712324fcbf7f5ad1bb15ee94b46e7f63d Mon Sep 17 00:00:00 2001 From: Max Robert Date: Wed, 17 May 2017 11:56:58 -0400 Subject: [PATCH 0801/1644] Refs CF-337. Added jdb support to the sandbox --- .../python/ossie/utils/sandbox/debugger.py | 40 +++++++++++++++++++ .../python/ossie/utils/sandbox/launcher.py | 2 + .../python/ossie/utils/sandbox/local.py | 4 +- 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/debugger.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/debugger.py index 23bf308ec..ebfddbad9 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/debugger.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/debugger.py @@ -21,6 +21,7 @@ import commands import os import sys +import socket class Debugger(object): def __init__(self, command): @@ -35,6 +36,9 @@ def modifiesCommand(self): def canAttach(self): return False + def envUpdate(self): + return {} + class GDB(Debugger): def __init__(self, attach=True): status, gdb = commands.getstatusoutput('which gdb') @@ -79,6 +83,42 @@ def findPDB(): def name(self): return 'pdb' +class JDB(Debugger): + def __init__(self, attach=True): + status, jdb = commands.getstatusoutput('which jdb') + if status: + raise RuntimeError, 'jdb cannot be found' + super(JDB,self).__init__(jdb) + self._lastport = 5680 + self._attach = attach + + def modifiesCommand(self): + return False + + def canAttach(self): + return self._attach + + def attach(self, process): + return self.command, ['-attach', str(self._lastport)] + + def wrap(self, command, arguments): + return command, arguments + + def envUpdate(self): + _open = False + s=socket.socket(socket.AF_INET, socket.SOCK_STREAM) + while not _open: + try: + s.bind((socket.gethostbyname(socket.gethostname()), self._lastport)) + _open = True + s.close() + except: + self._lastport += 1 + return {'JAVA_TOOL_OPTIONS':'-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address='+str(self._lastport)} + + def name(self): + return 'jdb' + class Valgrind(Debugger): def __init__(self, quiet=False, verbose=False, **opts): status, valgrind = commands.getstatusoutput('which valgrind') diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/launcher.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/launcher.py index dd0403b27..482b0a20b 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/launcher.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/launcher.py @@ -206,6 +206,8 @@ def execute(self, entryPoint, deps, execparams, debugger, window, stdout=None): else: # Run the command directly. command = entryPoint + if debugger: + environment.update(debugger.envUpdate()) if window_mode == 'monitor': # Open up a window for component output. diff --git a/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py b/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py index 5d85916b5..8d8a94928 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py +++ b/redhawk/src/base/framework/python/ossie/utils/sandbox/local.py @@ -38,7 +38,7 @@ from devmgr import DeviceManagerStub from naming import ApplicationRegistrarStub import launcher -from debugger import GDB, PDB, Valgrind +from debugger import GDB, JDB, PDB, Valgrind import terminal warnings.filterwarnings('once',category=DeprecationWarning) @@ -176,6 +176,8 @@ def launch(self, comp): try: if debugger == 'pdb': debugger = PDB() + elif debugger == 'jdb': + debugger = JDB() elif debugger == 'gdb': debugger = GDB() elif debugger == 'valgrind': From b1fc9f15cb80948d451246005af3e0118601cc46 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Wed, 17 May 2017 12:07:26 -0400 Subject: [PATCH 0802/1644] Refs CF-337. Added pydoc for Java debugger --- redhawk/src/base/framework/python/ossie/utils/sb/domainless.py | 1 + 1 file changed, 1 insertion(+) diff --git a/redhawk/src/base/framework/python/ossie/utils/sb/domainless.py b/redhawk/src/base/framework/python/ossie/utils/sb/domainless.py index 23cc679a2..765500150 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sb/domainless.py +++ b/redhawk/src/base/framework/python/ossie/utils/sb/domainless.py @@ -1188,6 +1188,7 @@ def launch(descriptor, instanceName=None, refid=None, impl=None, impl - Implementation ID to execute. If not given, the first implementation whose entry point exists will be used. debugger - Debugger to attach to the executable (default: None). + Options: gdb (C++), jdb (Java), pdb (Python) window - Terminal to receive command input/output. If not given, output will be directed to stdout, and component will not receive input. From 2829dcf0ee9839b25b6761d8c5d0a99b38165473 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Fri, 26 May 2017 16:38:15 -0400 Subject: [PATCH 0803/1644] Refs CF-1761. Per-host collocation reservations. Also, reservations are now allocated --- GPP/GPP.prf.xml | 6 + GPP/cpp/GPP.cpp | 110 ++++++++- GPP/cpp/GPP.h | 10 + GPP/cpp/GPP_base.cpp | 9 + GPP/cpp/GPP_base.h | 2 + GPP/cpp/struct_props.h | 59 +++++ .../sdr/dom/waveforms/busy_w/busy_w.sad.xml | 2 +- .../waveforms/wav_floor_w/wav_floor_w.sad.xml | 54 +++++ .../wav_one_floor_w/wav_one_floor_w.sad.xml | 56 +++++ .../wav_two_floor_w/wav_two_floor_w.sad.xml | 57 +++++ GPP/tests/test_GPP.py | 190 ++++++++++++++- .../control/include/ossie/SoftwareAssembly.h | 35 +++ .../control/parser/internal/sad-parser.cpp | 4 + .../src/control/parser/internal/sad-pimpl.cpp | 41 +++- .../src/control/parser/internal/sad-pimpl.h | 23 ++ redhawk/src/control/parser/internal/sad.map | 1 + .../sdr/dommgr/ApplicationDeployment.cpp | 8 +- .../sdr/dommgr/ApplicationFactory_impl.cpp | 227 ++++++++++++++++-- redhawk/src/control/sdr/dommgr/createHelper.h | 22 +- .../python/test_collocation_device.py | 6 + .../python/test_collocation_device_base.py | 53 ++++ .../test_collocation_device.prf.xml | 6 + .../test_05_CollocationApplicationFactory.py | 31 +++ redhawk/src/xml/xsd/sad.xsd | 6 + 24 files changed, 986 insertions(+), 32 deletions(-) create mode 100644 GPP/tests/sdr/dom/waveforms/wav_floor_w/wav_floor_w.sad.xml create mode 100644 GPP/tests/sdr/dom/waveforms/wav_one_floor_w/wav_one_floor_w.sad.xml create mode 100644 GPP/tests/sdr/dom/waveforms/wav_two_floor_w/wav_two_floor_w.sad.xml diff --git a/GPP/GPP.prf.xml b/GPP/GPP.prf.xml index 188654e9c..fba6ddbfb 100644 --- a/GPP/GPP.prf.xml +++ b/GPP/GPP.prf.xml @@ -555,6 +555,12 @@ THRESHOLD_NOT_EXCEEDED: The measured value no longer exceeds the configured thr + + + + + + diff --git a/GPP/cpp/GPP.cpp b/GPP/cpp/GPP.cpp index e62717b7e..61b68779a 100644 --- a/GPP/cpp/GPP.cpp +++ b/GPP/cpp/GPP.cpp @@ -498,6 +498,9 @@ void GPP_i::_init() { setAllocationImpl("DCE:8dcef419-b440-4bcf-b893-cab79b6024fb", this, &GPP_i::allocate_memCapacity, &GPP_i::deallocate_memCapacity); //setAllocationImpl("diskCapacity", this, &GPP_i::allocate_diskCapacity, &GPP_i::deallocate_diskCapacity); + + // check reservation allocations + setAllocationImpl(this->redhawk__reservation_request, this, &GPP_i::allocate_reservation_request, &GPP_i::deallocate_reservation_request); } @@ -692,6 +695,19 @@ void GPP_i::process_ODM(const CORBA::Any &data) { } } } + const StandardEvent::DomainManagementObjectRemovedEventType* app_removed; + if (data >>= app_removed) { + if (app_removed->sourceCategory == StandardEvent::APPLICATION) { + WriteLock rlock(pidLock); + std::string producerId(app_removed->producerId); + for (ApplicationReservationMap::iterator app_it=applicationReservations.begin(); app_it!=applicationReservations.end(); app_it++) { + if (app_it->first == producerId) { + applicationReservations.erase(app_it); + break; + } + } + } + } } int GPP_i::_setupExecPartitions( const CpuList &bl_cpus ) { @@ -1072,6 +1088,9 @@ CF::ExecutableDevice::ProcessID_Type GPP_i::execute (const char* name, const CF: naming_context_ior = tmp_params["NAMING_CONTEXT_IOR"].toString(); std::string app_id; std::string component_id = tmp_params["COMPONENT_IDENTIFIER"].toString(); + if (applicationReservations.find(component_id) != applicationReservations.end()) { + applicationReservations.erase(component_id); + } std::string name_binding = tmp_params["NAME_BINDING"].toString(); CF::Application_var _app = CF::Application::_nil(); CORBA::Object_var obj = ossie::corba::Orb()->string_to_object(naming_context_ior.c_str()); @@ -2067,6 +2086,55 @@ void GPP_i::deallocate_mcastegress_capacity(const CORBA::Long &value) mcastnicEgressFree = mcastnicEgressCapacity; } +bool GPP_i::allocate_reservation_request(const redhawk__reservation_request_struct &value) +{ + if (isBusy()) { + return false; + } + LOG_DEBUG(GPP_i, __FUNCTION__ << ": allocating reservation_request allocation "); + { + WriteLock rlock(pidLock); + if (applicationReservations.find(value.obj_id) != applicationReservations.end()){ + LOG_INFO(GPP_i, __FUNCTION__ << ": Cannot make multiple reservations against the same application: "<first == value.obj_id) { + applicationReservations.erase(app_it); + break; + } + } +} + bool GPP_i::allocate_mcastingress_capacity(const CORBA::Long &value) @@ -2368,6 +2436,11 @@ void GPP_i::update() usage = i->get_pstat_usage(); if ( !i->app_started ) { + if ( applicationReservations.find(i->appName) != applicationReservations.end()) { + if (applicationReservations[i->appName].reservation.find("cpucores") != applicationReservations[i->appName].reservation.end()) { + continue; + } + } nres++; if ( i->reservation == -1) { reservation_set += idle_capacity_modifier; @@ -2404,6 +2477,9 @@ void GPP_i::update() ReadLock rlock(pidLock); ProcessList::iterator i=this->pids.begin(); int usage_out=0; + for (ApplicationReservationMap::iterator app_it=applicationReservations.begin(); app_it!=applicationReservations.end(); app_it++) { + app_it->second.usage = 0; + } for ( ; i!=pids.end(); i++, usage_out++) { usage = 0; @@ -2432,6 +2508,12 @@ void GPP_i::update() } #endif + if ( applicationReservations.find(i->appName) != applicationReservations.end()) { + if (applicationReservations[i->appName].reservation.find("cpucores") != applicationReservations[i->appName].reservation.end()) { + applicationReservations[i->appName].usage += percent_core; + } + } + if ( i->app_started ) { // if component is not using enough the add difference between minimum and current load @@ -2448,7 +2530,30 @@ void GPP_i::update() } } } - + + for (ApplicationReservationMap::iterator app_it=applicationReservations.begin(); app_it!=applicationReservations.end(); app_it++) { + if (app_it->second.reservation.find("cpucores") != app_it->second.reservation.end()) { + bool found_app = false; + for ( ProcessList::iterator _pid_it=this->pids.begin();_pid_it!=pids.end(); _pid_it++) { + if (applicationReservations.find(_pid_it->appName) != applicationReservations.end()) { + found_app = true; + break; + } + } + if (not found_app) { + if (app_it->second.reservation["cpucores"] == -1) { + reservation_set += idle_capacity_modifier; + } else { + reservation_set += 100.0 * app_it->second.reservation["cpucores"]/((float)processor_cores); + } + } else { + if (app_it->second.usage < app_it->second.reservation["cpucores"]) { + reservation_set += 100.00 * ( app_it->second.reservation["cpucores"] - app_it->second.usage)/((double)processor_cores); + } + } + } + } + LOG_TRACE(GPP_i, __FUNCTION__ << " Completed SECOND pass, record pstats for processes" ); aggregate_usage *= inverse_load_per_core; @@ -2720,6 +2825,9 @@ void GPP_i::addProcess(int pid, const std::string &appName, const std::string &i tmp.core_usage = 0; tmp.parent = this; pids.push_front( tmp ); + if (applicationReservations.find(appName) != applicationReservations.end()) { + applicationReservations[appName].component_pids.push_back(pid); + } LOG_DEBUG(GPP_i, "END Adding Process/RES: " << pid << "/" << req_reservation << " APP:" << appName ); } diff --git a/GPP/cpp/GPP.h b/GPP/cpp/GPP.h index 34991cfb3..eb2f67c01 100644 --- a/GPP/cpp/GPP.h +++ b/GPP/cpp/GPP.h @@ -80,6 +80,8 @@ class GPP_i : public GPP_base void deallocate_diskCapacity(const double &value); bool allocate_memCapacity(const CORBA::LongLong &value); void deallocate_memCapacity(const CORBA::LongLong &value); + bool allocate_reservation_request(const redhawk__reservation_request_struct &value); + void deallocate_reservation_request(const redhawk__reservation_request_struct &value); bool allocate_mcastegress_capacity(const CORBA::Long &value); void deallocate_mcastegress_capacity(const CORBA::Long &value); bool allocate_mcastingress_capacity(const CORBA::Long &value); @@ -174,6 +176,12 @@ class GPP_i : public GPP_base int64_t get_process_time(); }; + struct application_reservation { + std::vector component_pids; + std::map reservation; + float usage; + }; + void constructor(); protected: @@ -249,6 +257,7 @@ class GPP_i : public GPP_base typedef std::map ProcessMap; typedef std::deque< component_description > ProcessList; typedef std::deque< proc_redirect > ProcessFds; + typedef std::map ApplicationReservationMap; void addProcess(int pid, const std::string &appName, @@ -276,6 +285,7 @@ class GPP_i : public GPP_base SystemMonitorPtr system_monitor; ProcessLimitsPtr process_limits; ExecPartitionList execPartitions; + ApplicationReservationMap applicationReservations; Lock monitorLock; UpdateableSequence data_model; diff --git a/GPP/cpp/GPP_base.cpp b/GPP/cpp/GPP_base.cpp index 8c1c0d453..eec942b0b 100644 --- a/GPP/cpp/GPP_base.cpp +++ b/GPP/cpp/GPP_base.cpp @@ -508,6 +508,15 @@ void GPP_base::loadProperties() "external", "property"); + addProperty(redhawk__reservation_request, + redhawk__reservation_request_struct(), + "redhawk::reservation_request", + "", + "readwrite", + "", + "external", + "allocation"); + } diff --git a/GPP/cpp/GPP_base.h b/GPP/cpp/GPP_base.h index 0189bbc53..3ffa5910d 100644 --- a/GPP/cpp/GPP_base.h +++ b/GPP/cpp/GPP_base.h @@ -110,6 +110,8 @@ class GPP_base : public ExecutableDevice_impl, protected ThreadedComponent float reserved_capacity_per_component; /// Property processor_cores - number of cores the machine supports short processor_cores; + /// Property: redhawk__reservation_request + redhawk__reservation_request_struct redhawk__reservation_request; /// Property processor_monitor_list - list of the cores we are watching.. std::string processor_monitor_list; // Property affinity - controls affinity processing for the GPP diff --git a/GPP/cpp/struct_props.h b/GPP/cpp/struct_props.h index 458f4afca..b0e1c3f85 100644 --- a/GPP/cpp/struct_props.h +++ b/GPP/cpp/struct_props.h @@ -145,6 +145,65 @@ inline bool operator!= (const nic_allocation_struct& s1, const nic_allocation_st return !(s1==s2); }; +struct redhawk__reservation_request_struct { + redhawk__reservation_request_struct () + { + } + + static std::string getId() { + return std::string("redhawk::reservation_request"); + } + + static const char* getFormat() { + return "s[s][s]"; + } + + std::string obj_id; + std::vector kinds; + std::vector values; +}; + +inline bool operator>>= (const CORBA::Any& a, redhawk__reservation_request_struct& s) { + CF::Properties* temp; + if (!(a >>= temp)) return false; + const redhawk::PropertyMap& props = redhawk::PropertyMap::cast(*temp); + if (props.contains("redhawk::reservation_request::obj_id")) { + if (!(props["redhawk::reservation_request::obj_id"] >>= s.obj_id)) return false; + } + if (props.contains("redhawk::reservation_request::kinds")) { + if (!(props["redhawk::reservation_request::kinds"] >>= s.kinds)) return false; + } + if (props.contains("redhawk::reservation_request::values")) { + if (!(props["redhawk::reservation_request::values"] >>= s.values)) return false; + } + return true; +} + +inline void operator<<= (CORBA::Any& a, const redhawk__reservation_request_struct& s) { + redhawk::PropertyMap props; + + props["redhawk::reservation_request::obj_id"] = s.obj_id; + + props["redhawk::reservation_request::kinds"] = s.kinds; + + props["redhawk::reservation_request::values"] = s.values; + a <<= props; +} + +inline bool operator== (const redhawk__reservation_request_struct& s1, const redhawk__reservation_request_struct& s2) { + if (s1.obj_id!=s2.obj_id) + return false; + if (s1.kinds!=s2.kinds) + return false; + if (s1.values!=s2.values) + return false; + return true; +} + +inline bool operator!= (const redhawk__reservation_request_struct& s1, const redhawk__reservation_request_struct& s2) { + return !(s1==s2); +} + struct advanced_struct { advanced_struct () { diff --git a/GPP/tests/sdr/dom/waveforms/busy_w/busy_w.sad.xml b/GPP/tests/sdr/dom/waveforms/busy_w/busy_w.sad.xml index 87bc98e46..c1e4d48e8 100644 --- a/GPP/tests/sdr/dom/waveforms/busy_w/busy_w.sad.xml +++ b/GPP/tests/sdr/dom/waveforms/busy_w/busy_w.sad.xml @@ -29,7 +29,7 @@ with this program. If not, see http://www.gnu.org/licenses/. - busy_comp_1 + busy_cOmp_1 diff --git a/GPP/tests/sdr/dom/waveforms/wav_floor_w/wav_floor_w.sad.xml b/GPP/tests/sdr/dom/waveforms/wav_floor_w/wav_floor_w.sad.xml new file mode 100644 index 000000000..c2034961f --- /dev/null +++ b/GPP/tests/sdr/dom/waveforms/wav_floor_w/wav_floor_w.sad.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + busy_comp_1 + + + + + + + + + busy_comp_2 + + + + + + + + + + + diff --git a/GPP/tests/sdr/dom/waveforms/wav_one_floor_w/wav_one_floor_w.sad.xml b/GPP/tests/sdr/dom/waveforms/wav_one_floor_w/wav_one_floor_w.sad.xml new file mode 100644 index 000000000..d13020720 --- /dev/null +++ b/GPP/tests/sdr/dom/waveforms/wav_one_floor_w/wav_one_floor_w.sad.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + busy_comp_1 + + + + + + + + + + + busy_comp_2 + + + + + + + + + + + diff --git a/GPP/tests/sdr/dom/waveforms/wav_two_floor_w/wav_two_floor_w.sad.xml b/GPP/tests/sdr/dom/waveforms/wav_two_floor_w/wav_two_floor_w.sad.xml new file mode 100644 index 000000000..4b7b8d75d --- /dev/null +++ b/GPP/tests/sdr/dom/waveforms/wav_two_floor_w/wav_two_floor_w.sad.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + busy_comp_1 + + + + + + + + + + + + busy_comp_2 + + + + + + + + + + + diff --git a/GPP/tests/test_GPP.py b/GPP/tests/test_GPP.py index cdb302143..d1492cbe4 100755 --- a/GPP/tests/test_GPP.py +++ b/GPP/tests/test_GPP.py @@ -1558,7 +1558,7 @@ def testSystemReservation(self): comp_load = base_util['component_load'] #print "After App1 Create subnow(sub) " , sub_now, " sys_load", system_load_now, " sys_load_base ", system_load_base, " comp_load ", comp_load, " subscribed(base) ", subscribed, " extra ", extra_reservation, " res per", res_per_comp, " idle cap mod ", idle_cap_mod self.assertEquals(self.close(sub_now, extra_reservation), True) - + app_2=self.dom.createApplication('/waveforms/busy_w/busy_w.sad.xml','busy_w',[]) time.sleep(wait_amount) base_util = self.dom.devMgrs[0].devs[0].utilization[0] @@ -1583,8 +1583,6 @@ def testSystemReservation(self): else: self.assertEqual(self.close(sub_now, extra_reservation+res_per_comp), True) - - app_2.start() time.sleep(wait_amount) base_util = self.dom.devMgrs[0].devs[0].utilization[0] @@ -1612,6 +1610,192 @@ def testSystemReservation(self): self.assertEquals(self.close(sub_now, extra_reservation+res_per_comp ), True) self.assertEquals(self.float_eq(sub_now_pre, sub_now, eps=.01), True) + def _verifyReservations(self, extra, application, wait_amount): + base_util = self.dom.devMgrs[0].devs[0].utilization[0] + system_load_now = base_util['system_load'] + sub_now = base_util['subscribed'] + comp_load = base_util['component_load'] + self.assertEquals(self.close(sub_now, extra), True) + self.assertEquals(comp_load, 0) + + application.start() + time.sleep(wait_amount) + base_util = self.dom.devMgrs[0].devs[0].utilization[0] + system_load_now = base_util['system_load'] + sub_now = base_util['subscribed'] + comp_load = base_util['component_load'] + self.assertEquals(self.close(sub_now, extra), True) + self.assertEquals(self.close(comp_load, 2, margin=0.1), True) + + application.stop() + time.sleep(wait_amount) + base_util = self.dom.devMgrs[0].devs[0].utilization[0] + system_load_now = base_util['system_load'] + sub_now = base_util['subscribed'] + comp_load = base_util['component_load'] + self.assertEquals(self.close(sub_now, extra), True) + self.assertEquals(comp_load, 0) + + def testAppReservation(self): + self.assertEquals(os.path.isfile('sdr/dom/mgr/DomainManager'),True) + self.assertEquals(os.path.isfile('sdr/dev/mgr/DeviceManager'),True) + self._domainBooter, domMgr = self.launchDomainManager(domain_name='REDHAWK_TEST_'+str(os.getpid())) + self.assertNotEquals(domMgr,None) + self._deviceBooter, devMgr = self.launchDeviceManager("/nodes/DevMgr_sample/DeviceManager.dcd.xml", domainManager=self.dom.ref) + self.assertNotEquals(devMgr,None) + self.comp= self.dom.devMgrs[0].devs[0] + cpus = self.dom.devMgrs[0].devs[0].processor_cores + cpu_thresh = self.dom.devMgrs[0].devs[0].thresholds.cpu_idle + res_per_comp = self.dom.devMgrs[0].devs[0].reserved_capacity_per_component + idle_cap_mod = 100.0 * res_per_comp / (cpus*1.0) + upper_capacity = cpus - (cpus * (cpu_thresh/100)) + wait_amount = (self.dom.devMgrs[0].devs[0].threshold_cycle_time / 1000.0) * 4 + time.sleep(wait_amount) + self.assertEquals(self.close(upper_capacity, self.dom.devMgrs[0].devs[0].utilization[0]['maximum']), True) + + time.sleep(1) + + base_util = self.dom.devMgrs[0].devs[0].utilization[0] + subscribed = base_util['subscribed'] + system_load_base = base_util['system_load'] + + extra_reservation = 3 + _value=any.to_any(extra_reservation) + _value._t=CORBA.TC_double + self.assertRaises(CF.ApplicationFactory.CreateApplicationError, self.dom.createApplication, '/waveforms/wav_floor_w/wav_floor_w.sad.xml','busy_w',[CF.DataType(id='SPECIALIZED_CPU_RESERVATION',value=any.to_any([CF.DataType(id='busy_comp_1',value=any.to_any(_value))]))]) + app_1=self.dom.createApplication('/waveforms/wav_floor_w/wav_floor_w.sad.xml','busy_w',[]) + time.sleep(wait_amount) + self._verifyReservations(extra_reservation, app_1, wait_amount) + + app_1.releaseObject() + time.sleep(wait_amount) + base_util = self.dom.devMgrs[0].devs[0].utilization[0] + sub_now = base_util['subscribed'] + comp_load = base_util['component_load'] + self.assertEquals(sub_now, 0) + + def testAppOverloadGenericReservation(self): + self.assertEquals(os.path.isfile('sdr/dom/mgr/DomainManager'),True) + self.assertEquals(os.path.isfile('sdr/dev/mgr/DeviceManager'),True) + self._domainBooter, domMgr = self.launchDomainManager(domain_name='REDHAWK_TEST_'+str(os.getpid())) + self.assertNotEquals(domMgr,None) + self._deviceBooter, devMgr = self.launchDeviceManager("/nodes/DevMgr_sample/DeviceManager.dcd.xml", domainManager=self.dom.ref) + self.assertNotEquals(devMgr,None) + self.comp= self.dom.devMgrs[0].devs[0] + cpus = self.dom.devMgrs[0].devs[0].processor_cores + cpu_thresh = self.dom.devMgrs[0].devs[0].thresholds.cpu_idle + res_per_comp = self.dom.devMgrs[0].devs[0].reserved_capacity_per_component + idle_cap_mod = 100.0 * res_per_comp / (cpus*1.0) + upper_capacity = cpus - (cpus * (cpu_thresh/100)) + wait_amount = (self.dom.devMgrs[0].devs[0].threshold_cycle_time / 1000.0) * 4 + time.sleep(wait_amount) + self.assertEquals(self.close(upper_capacity, self.dom.devMgrs[0].devs[0].utilization[0]['maximum']), True) + + time.sleep(1) + + base_util = self.dom.devMgrs[0].devs[0].utilization[0] + subscribed = base_util['subscribed'] + system_load_base = base_util['system_load'] + + extra_reservation = 4 + _value=any.to_any(extra_reservation) + _value._t=CORBA.TC_double + app_1=self.dom.createApplication('/waveforms/wav_floor_w/wav_floor_w.sad.xml','busy_w',[CF.DataType(id='SPECIALIZED_CPU_RESERVATION',value=any.to_any([CF.DataType(id='',value=any.to_any(_value))]))]) + time.sleep(wait_amount) + self._verifyReservations(extra_reservation, app_1, wait_amount) + + def testAppOverloadSpecificReservation(self): + self.assertEquals(os.path.isfile('sdr/dom/mgr/DomainManager'),True) + self.assertEquals(os.path.isfile('sdr/dev/mgr/DeviceManager'),True) + self._domainBooter, domMgr = self.launchDomainManager(domain_name='REDHAWK_TEST_'+str(os.getpid())) + self.assertNotEquals(domMgr,None) + self._deviceBooter, devMgr = self.launchDeviceManager("/nodes/DevMgr_sample/DeviceManager.dcd.xml", domainManager=self.dom.ref) + self.assertNotEquals(devMgr,None) + self.comp= self.dom.devMgrs[0].devs[0] + cpus = self.dom.devMgrs[0].devs[0].processor_cores + cpu_thresh = self.dom.devMgrs[0].devs[0].thresholds.cpu_idle + res_per_comp = self.dom.devMgrs[0].devs[0].reserved_capacity_per_component + idle_cap_mod = 100.0 * res_per_comp / (cpus*1.0) + upper_capacity = cpus - (cpus * (cpu_thresh/100)) + wait_amount = (self.dom.devMgrs[0].devs[0].threshold_cycle_time / 1000.0) * 4 + time.sleep(wait_amount) + self.assertEquals(self.close(upper_capacity, self.dom.devMgrs[0].devs[0].utilization[0]['maximum']), True) + + time.sleep(1) + + base_util = self.dom.devMgrs[0].devs[0].utilization[0] + subscribed = base_util['subscribed'] + system_load_base = base_util['system_load'] + + extra_reservation = 4 + _value=any.to_any(extra_reservation) + _value._t=CORBA.TC_double + self.assertRaises(CF.ApplicationFactory.CreateApplicationError, self.dom.createApplication, '/waveforms/wav_floor_w/wav_floor_w.sad.xml','busy_w',[CF.DataType(id='SPECIALIZED_CPU_RESERVATION',value=any.to_any([CF.DataType(id='COLLOC_SET1',value=any.to_any(_value))]))]) + app_1=self.dom.createApplication('/waveforms/wav_floor_w/wav_floor_w.sad.xml','busy_w',[CF.DataType(id='SPECIALIZED_CPU_RESERVATION',value=any.to_any([CF.DataType(id='ID_TEST_SET1',value=any.to_any(_value))]))]) + time.sleep(wait_amount) + self._verifyReservations(extra_reservation, app_1, wait_amount) + + def testAppOverloadTwoSpecificReservation(self): + self.assertEquals(os.path.isfile('sdr/dom/mgr/DomainManager'),True) + self.assertEquals(os.path.isfile('sdr/dev/mgr/DeviceManager'),True) + self._domainBooter, domMgr = self.launchDomainManager(domain_name='REDHAWK_TEST_'+str(os.getpid())) + self.assertNotEquals(domMgr,None) + self._deviceBooter, devMgr = self.launchDeviceManager("/nodes/DevMgr_sample/DeviceManager.dcd.xml", domainManager=self.dom.ref) + self.assertNotEquals(devMgr,None) + self.comp= self.dom.devMgrs[0].devs[0] + cpus = self.dom.devMgrs[0].devs[0].processor_cores + cpu_thresh = self.dom.devMgrs[0].devs[0].thresholds.cpu_idle + res_per_comp = self.dom.devMgrs[0].devs[0].reserved_capacity_per_component + idle_cap_mod = 100.0 * res_per_comp / (cpus*1.0) + upper_capacity = cpus - (cpus * (cpu_thresh/100)) + wait_amount = (self.dom.devMgrs[0].devs[0].threshold_cycle_time / 1000.0) * 4 + time.sleep(wait_amount) + self.assertEquals(self.close(upper_capacity, self.dom.devMgrs[0].devs[0].utilization[0]['maximum']), True) + + time.sleep(1) + + base_util = self.dom.devMgrs[0].devs[0].utilization[0] + subscribed = base_util['subscribed'] + system_load_base = base_util['system_load'] + + extra_reservation = 4 + _value=any.to_any(extra_reservation/2) + _value._t=CORBA.TC_double + self.assertRaises(CF.ApplicationFactory.CreateApplicationError, self.dom.createApplication, '/waveforms/wav_floor_w/wav_floor_w.sad.xml','busy_w',[CF.DataType(id='SPECIALIZED_CPU_RESERVATION',value=any.to_any([CF.DataType(id='COLLOC_SET1',value=any.to_any(_value)),CF.DataType(id='ID_TEST_SET2',value=any.to_any(_value))]))]) + app_1=self.dom.createApplication('/waveforms/wav_two_floor_w/wav_two_floor_w.sad.xml','busy_w',[CF.DataType(id='SPECIALIZED_CPU_RESERVATION',value=any.to_any([CF.DataType(id='ID_TEST_SET1',value=any.to_any(_value)),CF.DataType(id='ID_TEST_SET2',value=any.to_any(_value))]))]) + time.sleep(wait_amount) + self._verifyReservations(extra_reservation, app_1, wait_amount) + + def testAppOverloadOneSpecificReservation(self): + self.assertEquals(os.path.isfile('sdr/dom/mgr/DomainManager'),True) + self.assertEquals(os.path.isfile('sdr/dev/mgr/DeviceManager'),True) + self._domainBooter, domMgr = self.launchDomainManager(domain_name='REDHAWK_TEST_'+str(os.getpid())) + self.assertNotEquals(domMgr,None) + self._deviceBooter, devMgr = self.launchDeviceManager("/nodes/DevMgr_sample/DeviceManager.dcd.xml", domainManager=self.dom.ref) + self.assertNotEquals(devMgr,None) + self.comp= self.dom.devMgrs[0].devs[0] + cpus = self.dom.devMgrs[0].devs[0].processor_cores + cpu_thresh = self.dom.devMgrs[0].devs[0].thresholds.cpu_idle + res_per_comp = self.dom.devMgrs[0].devs[0].reserved_capacity_per_component + idle_cap_mod = 100.0 * res_per_comp / (cpus*1.0) + upper_capacity = cpus - (cpus * (cpu_thresh/100)) + wait_amount = (self.dom.devMgrs[0].devs[0].threshold_cycle_time / 1000.0) * 4 + time.sleep(wait_amount) + self.assertEquals(self.close(upper_capacity, self.dom.devMgrs[0].devs[0].utilization[0]['maximum']), True) + + time.sleep(1) + + base_util = self.dom.devMgrs[0].devs[0].utilization[0] + subscribed = base_util['subscribed'] + system_load_base = base_util['system_load'] + + extra_reservation = 4 + _value=any.to_any(extra_reservation/2) + _value._t=CORBA.TC_double + app_1=self.dom.createApplication('/waveforms/wav_one_floor_w/wav_one_floor_w.sad.xml','busy_w',[CF.DataType(id='SPECIALIZED_CPU_RESERVATION',value=any.to_any([CF.DataType(id='ID_TEST_SET1',value=any.to_any(_value)),CF.DataType(id='ID_TEST_SET2',value=any.to_any(_value))]))]) + time.sleep(wait_amount) + self._verifyReservations(extra_reservation, app_1, wait_amount) + class LoadableDeviceVariableDirectoriesTest(DomainSupport): def setUp(self): diff --git a/redhawk/src/control/include/ossie/SoftwareAssembly.h b/redhawk/src/control/include/ossie/SoftwareAssembly.h index c7404c80e..416684e6d 100644 --- a/redhawk/src/control/include/ossie/SoftwareAssembly.h +++ b/redhawk/src/control/include/ossie/SoftwareAssembly.h @@ -31,6 +31,32 @@ #include "UsesDevice.h" namespace ossie { + + class Reservation { + public: + std::string kind; + std::string value; + + const std::string& getKind() const { + return kind; + } + + const std::string& getValue() const { + return value; + } + + void overloadValue(std::string& new_value) { + value = new_value; + } + + }; + + inline std::ostream& operator<<(std::ostream& out, const Reservation& resrv) + { + out << "Reservation kind: " << resrv.kind; + return out; + }; + class SoftwareAssembly { public: class HostCollocation { @@ -39,6 +65,7 @@ namespace ossie { std::string name; std::vector placements; std::vector usesdevicerefs; + std::vector reservations; const std::string& getID() const { return id; @@ -56,6 +83,14 @@ namespace ossie { return usesdevicerefs; } + const std::vector& getReservations() const { + return reservations; + } + + void overloadReservation(std::string &value, int idx) { + reservations[idx].overloadValue(value); + } + const ComponentInstantiation* getInstantiation(const std::string& refid) const; }; diff --git a/redhawk/src/control/parser/internal/sad-parser.cpp b/redhawk/src/control/parser/internal/sad-parser.cpp index 44cdfb9b0..e48090b5a 100644 --- a/redhawk/src/control/parser/internal/sad-parser.cpp +++ b/redhawk/src/control/parser/internal/sad-parser.cpp @@ -74,6 +74,7 @@ ossie::internalparser::parseSAD(std::istream& input) throw (ossie::parser_error) ::sad::devicerequires_pimpl devicerequires_p; ::sad::idvalue_pimpl idvalue_p; ::sad::usesdeviceref_pimpl usesdeviceref_p; + ::sad::reservation_pimpl reservation_p; // Connect the parsers together. @@ -165,11 +166,14 @@ ossie::internalparser::parseSAD(std::istream& input) throw (ossie::parser_error) hostcollocation_p.parsers (componentplacement_p, usesdeviceref_p, + reservation_p, string_p, string_p); usesdeviceref_p.parsers (string_p); + reservation_p.parsers (string_p, string_p); + assemblycontroller_p.parsers (componentinstantiationref_p); componentinstantiationref_p.parsers (string_p); diff --git a/redhawk/src/control/parser/internal/sad-pimpl.cpp b/redhawk/src/control/parser/internal/sad-pimpl.cpp index 95408fee2..d53b9dd37 100644 --- a/redhawk/src/control/parser/internal/sad-pimpl.cpp +++ b/redhawk/src/control/parser/internal/sad-pimpl.cpp @@ -938,6 +938,12 @@ namespace sad hostcollocation->usesdevicerefs.push_back(usesdeviceref); } + void hostcollocation_pimpl:: + reservation (const ::ossie::Reservation& reservation) + { + hostcollocation->reservations.push_back(reservation); + } + void hostcollocation_pimpl:: id (const ::std::string& id) { @@ -956,7 +962,6 @@ namespace sad return *hostcollocation; } - // usesdeviceref_pimpl // @@ -979,6 +984,40 @@ namespace sad } + // reservation_pimpl + // + + void reservation_pimpl:: + pre () + { + resrv = ossie::Reservation(); + } + + void reservation_pimpl:: + kind (const ::std::string& kind) + { + resrv.kind = kind; + } + + void reservation_pimpl:: + value (const ::std::string& value) + { + resrv.value = value; + } + + std::string reservation_pimpl::post_string() + { + resrv.value = this->post_string(); + return resrv.value; + } + + const ossie::Reservation& reservation_pimpl:: + post_reservation () + { + return resrv; + } + + // assemblycontroller_pimpl // diff --git a/redhawk/src/control/parser/internal/sad-pimpl.h b/redhawk/src/control/parser/internal/sad-pimpl.h index c73c4a7cd..c55c0a9c4 100644 --- a/redhawk/src/control/parser/internal/sad-pimpl.h +++ b/redhawk/src/control/parser/internal/sad-pimpl.h @@ -634,6 +634,9 @@ namespace sad virtual void usesdeviceref (const ::ossie::UsesDeviceRef&); + virtual void + reservation (const ::ossie::Reservation&); + virtual void id (const ::std::string&); @@ -663,6 +666,26 @@ namespace sad ossie::UsesDeviceRef udevref; }; + class reservation_pimpl: public virtual reservation_pskel + { + public: + virtual void + pre (); + + virtual void + kind (const ::std::string&); + + virtual void + value (const ::std::string&); + + virtual const ossie::Reservation& + post_reservation (); + + virtual std::string post_string (); + + private: + ossie::Reservation resrv; + }; class assemblycontroller_pimpl: public virtual assemblycontroller_pskel { diff --git a/redhawk/src/control/parser/internal/sad.map b/redhawk/src/control/parser/internal/sad.map index 595af8824..1d4877a76 100644 --- a/redhawk/src/control/parser/internal/sad.map +++ b/redhawk/src/control/parser/internal/sad.map @@ -68,5 +68,6 @@ namespace urn:mil:jpeojtrs:sca:sad { devicerequires "ossie::ComponentPropertyList &" "ossie::ComponentPropertyList &"; idvalue "const ossie::IdValue&" "const ossie::IdValue&"; usesdeviceref "const ossie::UsesDeviceRef&" "const ossie::UsesDeviceRef&"; + reservation "const ossie::Reservation&" "const ossie::Reservation&"; } diff --git a/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp b/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp index 46074792a..9d805178b 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationDeployment.cpp @@ -191,10 +191,12 @@ void ApplicationDeployment::applyCpuReservations(const CpuReservations& reservat CpuReservations::const_iterator reserved = reservations.find(deployment->getIdentifier()); if (reserved == reservations.end()) { // NB: Check for the usage name for consistency with 2.0, although - // the instantiation ID would make more sense. In most cases, this - // is probably a moot point, since the IDE uses the same value for - // both. + // the instantiation ID makes more sense. If the usage name does not apply, + // use the instantiation ID reserved = reservations.find(deployment->getInstantiation()->getUsageName()); + if (reserved == reservations.end()) { + reserved = reservations.find(deployment->getInstantiation()->getID()); + } } if (reserved != reservations.end()) { deployment->setCpuReservation(reserved->second); diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 66dc9e02f..12a8216cc 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -265,12 +265,13 @@ const std::string& ApplicationFactory_impl::getSoftwareProfile() const } void createHelper::assignPlacementsToDevices(redhawk::ApplicationDeployment& appDeployment, - const DeviceAssignmentMap& devices) + const DeviceAssignmentMap& devices, + const std::map& specialized_reservations) { // Try to place all of the collocations first, since they naturally have // more restrictive placement constraints BOOST_FOREACH(const SoftwareAssembly::HostCollocation& collocation, _appFact._sadParser.getHostCollocations()) { - _placeHostCollocation(appDeployment, collocation, devices); + _placeHostCollocation(appDeployment, collocation, devices, specialized_reservations); } // Place the remaining components one-by-one @@ -288,7 +289,7 @@ void createHelper::assignPlacementsToDevices(redhawk::ApplicationDeployment& app << " is assigned to device " << assigned_device); } redhawk::ComponentDeployment* deployment = appDeployment.createComponentDeployment(softpkg, &instantiation); - allocateComponent(appDeployment, deployment, assigned_device); + allocateComponent(appDeployment, deployment, assigned_device, specialized_reservations); // For components that run as shared libraries, create or reuse a // matching container deployment @@ -304,7 +305,7 @@ void createHelper::assignPlacementsToDevices(redhawk::ApplicationDeployment& app // Use whether the device is assigned as a sentinel to check // whether the container was already created, and if not, // allocate it to the device - allocateComponent(appDeployment, container, deployment->getAssignedDevice()->identifier); + allocateComponent(appDeployment, container, deployment->getAssignedDevice()->identifier, specialized_reservations); } deployment->setContainer(container); } @@ -340,6 +341,7 @@ bool createHelper::placeHostCollocation(redhawk::ApplicationDeployment& appDeplo DeploymentList::const_iterator current, ossie::DeviceList& deploymentDevices, const redhawk::PropertyMap& deviceRequires, + const ReservationList& reservations, const ProcessorList& processorDeps, const OSList& osDeps) @@ -350,7 +352,7 @@ bool createHelper::placeHostCollocation(redhawk::ApplicationDeployment& appDeplo if ( !deviceRequires.empty() ) { LOG_TRACE(ApplicationFactory_impl, "Collocation has devicerequires: " << deviceRequires ); } - return allocateHostCollocation(appDeployment, components, deploymentDevices, processorDeps, osDeps, deviceRequires ); + return allocateHostCollocation(appDeployment, components, deploymentDevices, processorDeps, osDeps, deviceRequires, reservations ); } // Try all of the implementations from the current component for matches @@ -384,7 +386,7 @@ bool createHelper::placeHostCollocation(redhawk::ApplicationDeployment& appDeplo // Set this implementation for deployment and recurse one more level deployment->setImplementation(implementation); - if (placeHostCollocation(appDeployment, components, current, deploymentDevices, deviceRequires, proc_list, os_list)) { + if (placeHostCollocation(appDeployment, components, current, deploymentDevices, deviceRequires, reservations, proc_list, os_list)) { return true; } } @@ -397,10 +399,24 @@ bool createHelper::allocateHostCollocation(redhawk::ApplicationDeployment& appDe ossie::DeviceList& deploymentDevices, const ProcessorList& processorDeps, const OSList& osDeps, - const redhawk::PropertyMap& deviceRequires ) + const redhawk::PropertyMap& deviceRequires, + const ReservationList& reservations ) { // Consolidate the allocation properties into a single list CF::Properties allocationProperties = _consolidateAllocations(appDeployment, components); + redhawk::PropertyMap &_allocationProperties = redhawk::PropertyMap::cast(allocationProperties); + if (reservations.size() != 0) { + redhawk::PropertyMap _struct; + std::vector _kinds, _values; + for (ReservationList::const_iterator it=reservations.begin(); it!=reservations.end(); it++) { + _kinds.push_back(it->kind); + _values.push_back(it->value); + } + _struct["redhawk::reservation_request::kinds"].setValue(_kinds); + _struct["redhawk::reservation_request::values"].setValue(_values); + _struct["redhawk::reservation_request::obj_id"].setValue(appDeployment.getIdentifier()); + _allocationProperties["redhawk::reservation_request"].setValue(_struct); + } LOG_TRACE(ApplicationFactory_impl, "Allocating deployment for " << components.size() << " collocated components"); @@ -414,7 +430,7 @@ bool createHelper::allocateHostCollocation(redhawk::ApplicationDeployment& appDe } const std::string requestid = ossie::generateUUID(); - ossie::AllocationResult response = _allocationMgr->allocateDeployment(requestid, allocationProperties, deploymentDevices, appDeployment.getIdentifier(), processorDeps, osDeps, deviceRequires); + ossie::AllocationResult response = _allocationMgr->allocateDeployment(requestid, _allocationProperties, deploymentDevices, appDeployment.getIdentifier(), processorDeps, osDeps, deviceRequires); if (!response.first.empty()) { // Ensure that all capacities get cleaned up, keeping ownership local // to this scope until it's clear that the device can support all of @@ -478,7 +494,8 @@ CF::Properties createHelper::_consolidateAllocations(redhawk::ApplicationDeploym void createHelper::_placeHostCollocation(redhawk::ApplicationDeployment& appDeployment, const ossie::SoftwareAssembly::HostCollocation& collocation, - const DeviceAssignmentMap& devices) + const DeviceAssignmentMap& devices, + const std::map& specialized_reservations) { LOG_TRACE(ApplicationFactory_impl, "Placing host collocation " << collocation.getID() << " " << collocation.getName()); @@ -555,7 +572,6 @@ void createHelper::_placeHostCollocation(redhawk::ApplicationDeployment& appDepl throw redhawk::PlacementFailure(collocation, os.str() ); } - // if there is a usesdevice in the collocation that filter out the GPPs that we can use. if ( req_usesDevices.size() > 0 ) { // from the remaining list of deploymentDevices filter out those that not on the same host @@ -586,9 +602,11 @@ void createHelper::_placeHostCollocation(redhawk::ApplicationDeployment& appDepl } + // load any collocation-based reservations + std::vector _overloadedReservations = overloadReservations(collocation, specialized_reservations); LOG_TRACE(ApplicationFactory_impl, "Placing " << deployments.size() << " components"); - if (!placeHostCollocation(appDeployment, deployments, deployments.begin(), deploymentDevices, devReq.second )) { + if (!placeHostCollocation(appDeployment, deployments, deployments.begin(), deploymentDevices, devReq.second, _overloadedReservations)) { if (_allDevicesBusy(deploymentDevices)) { throw redhawk::PlacementFailure(collocation, "all executable devices (GPPs) in the Domain are busy"); } @@ -607,7 +625,7 @@ void createHelper::_placeHostCollocation(redhawk::ApplicationDeployment& appDepl // Use whether the device is assigned as a sentinel to check // whether the container was already created, and if not, // allocate it to the device - allocateComponent(appDeployment, container, (*deployment)->getAssignedDevice()->identifier); + allocateComponent(appDeployment, container, (*deployment)->getAssignedDevice()->identifier, specialized_reservations); } (*deployment)->setContainer(container); } @@ -617,6 +635,74 @@ void createHelper::_placeHostCollocation(redhawk::ApplicationDeployment& appDepl << collocation.getID() << " Components Placed: " << deployments.size()); } +std::vector createHelper::overloadReservations(const ossie::SoftwareAssembly::HostCollocation& collocation, + const std::map& specialized_reservations) +{ + const std::vector& reservations = collocation.getReservations(); + std::vector retval = reservations; + if ((reservations.size() == 0) and (specialized_reservations.size() == 0)) { + return retval; + } + + int number_collocations = _appFact._sadParser.getHostCollocations().size(); + if (number_collocations == 0) { + return retval; + } + int number_blank_specialization = 0; + for (std::map::const_iterator _it=specialized_reservations.begin();_it!=specialized_reservations.end();_it++) { + if (_it->first.empty()) { + number_blank_specialization++; + } + } + if (number_blank_specialization > 1) { + throw std::logic_error("Ambiguous specialized CPU usage; cannot have more than one blank specialization"); + } + if ((number_blank_specialization == 1) and (number_collocations > 1)) { + throw std::logic_error("Ambiguous specialized CPU usage; more than one host collocation cannot be matched to a blank specialization"); + } + if ((number_blank_specialization == 1) and (number_collocations == 1)) { + if (reservations.size() != 0) { + for (std::vector::iterator _it=retval.begin();_it!=retval.end();_it++) { + if (_it->getKind() == "cpucores") { + std::string value_str; + std::ostringstream ss; + ss<second; + value_str = ss.str(); + _it->overloadValue(value_str); + } + } + } + return retval; + } + bool found_overload = false; + bool has_value = false; + for (std::map::const_iterator _it_spec=specialized_reservations.begin();_it_spec!=specialized_reservations.end();_it_spec++) { + if (_it_spec->first == collocation.getID()) { + has_value = true; + for (std::vector::iterator _it=retval.begin();_it!=retval.end();_it++) { + if (_it->getKind() == "cpucores") { + found_overload = true; + std::string value_str; + std::ostringstream ss; + ss<first)->second; + value_str = ss.str(); + _it->overloadValue(value_str); + } + } + } + } + if ((not found_overload) and has_value) { + Reservation res; + res.kind = "cpucores"; + std::string value_str; + std::ostringstream ss; + ss<second; + res.value = ss.str(); + retval.push_back(res); + } + return retval; +} + void createHelper::_handleUsesDevices(redhawk::ApplicationDeployment& appDeployment, const std::string& appName) { @@ -931,11 +1017,16 @@ CF::Application_ptr createHelper::create ( // require matching properties _resolveAssemblyController(app_deployment); + // check to make sure that there's no collision between sad-based and command-line reservations + if (specialized_reservations.size() != 0) { + verifyNoCpuSpecializationCollisions(_appFact._sadParser, specialized_reservations); + } + // Allocate any usesdevice capacities specified in the SAD file _handleUsesDevices(app_deployment, name); // Assign all components to devices - assignPlacementsToDevices(app_deployment, deviceAssignments); + assignPlacementsToDevices(app_deployment, deviceAssignments, specialized_reservations); // Assign CPU reservations to components app_deployment.applyCpuReservations(specialized_reservations); @@ -1067,6 +1158,86 @@ CF::Application_ptr createHelper::create ( return appObj._retn(); } +void createHelper::verifyNoCpuSpecializationCollisions(const ossie::SoftwareAssembly& sad, std::map specialized_reservations) { + std::vector host_collocation_names = this->getHostCollocationsIds(); + int number_empty = 0; + bool found_host_collocation = false; + BOOST_FOREACH(const SoftwareAssembly::HostCollocation& collocation, _appFact._sadParser.getHostCollocations()) { + if (collocation.getReservations().size() > 0) { + found_host_collocation = true; + break; + } + } + bool found_component = false; + bool name_is_nothing = false; + std::string bad_name; + for (std::map::iterator _reservation=specialized_reservations.begin();_reservation!=specialized_reservations.end();_reservation++) { + if (not _reservation->first.empty()) { + bool host_collocation = false; + for (std::vector::iterator _name=host_collocation_names.begin();_name!=host_collocation_names.end();_name++) { + if (*_name == _reservation->first) { + host_collocation = true; + found_host_collocation = true; + break; + } + } + if (not host_collocation) { + BOOST_FOREACH(const ComponentPlacement& placement, sad.getComponentPlacements()) { + if (placement.getInstantiations()[0].getID() == _reservation->first) { + found_component = true; + break; + } + } + BOOST_FOREACH(const SoftwareAssembly::HostCollocation& _hostcollocation, sad.getHostCollocations()) { + BOOST_FOREACH(const ComponentPlacement& placement, _hostcollocation.getComponents()) { + if (placement.getInstantiations()[0].getID() == _reservation->first) { + found_component = true; + break; + } + } + } + if (found_component) + break; + name_is_nothing = true; + bad_name = _reservation->first; + break; + } + } else { + number_empty++; + } + } + if (name_is_nothing) { + throw std::logic_error("'SPECIALIZED_CPU_RESERVATION must include a hostcollocation id, a component id, or (when not ambiguous), a blank, bad id is: "+bad_name+"'"); + } + if (number_empty > 1) { + throw std::logic_error("'SPECIALIZED_CPU_RESERVATION cannot have more than 1 hostcollocation without an id'"); + } + if (number_empty > 0) + found_host_collocation = true; + if (found_host_collocation and found_component) { + throw std::logic_error("'SPECIALIZED_CPU_RESERVATION cannot mix hostcollocation and component reservations'"); + } +} + +std::vector createHelper::getComponentUsageNames(redhawk::ApplicationDeployment& appDeployment) { + std::vector retval; + BOOST_FOREACH(const redhawk::ComponentDeployment* compdep, appDeployment.getComponentDeployments()) { + retval.push_back(compdep->getInstantiation()->usageName); + } + return retval; +} + +std::vector createHelper::getHostCollocationsIds() { + std::vector retval; + BOOST_FOREACH(const SoftwareAssembly::HostCollocation& collocation, _appFact._sadParser.getHostCollocations()) { + std::string _name; + if (not collocation.id.empty()) { + _name = collocation.id; + } + retval.push_back(_name); + } + return retval; +} void createHelper::_resolveAssemblyController( redhawk::ApplicationDeployment& appDeployment ) { @@ -1114,7 +1285,8 @@ CF::AllocationManager::AllocationResponseSequence* createHelper::allocateUsesDev */ void createHelper::allocateComponent(redhawk::ApplicationDeployment& appDeployment, redhawk::ComponentDeployment* deployment, - const std::string& assignedDeviceId) + const std::string& assignedDeviceId, + const std::map& specialized_reservations) { redhawk::PropertyMap alloc_context = deployment->getAllocationContext(); @@ -1154,7 +1326,8 @@ void createHelper::allocateComponent(redhawk::ApplicationDeployment& appDeployme // satisfied, now perform assignment/allocation of component to device LOG_DEBUG(ApplicationFactory_impl, "Trying to find the device"); ossie::AllocationResult response = allocateComponentToDevice(deployment, assignedDeviceId, - appDeployment.getIdentifier()); + appDeployment.getIdentifier(), + specialized_reservations); if (response.first.empty()) { LOG_DEBUG(ApplicationFactory_impl, "Unable to allocate device for component " @@ -1381,7 +1554,8 @@ void createHelper::_evaluateMATHinRequest(CF::Properties &request, const CF::Pro */ ossie::AllocationResult createHelper::allocateComponentToDevice(redhawk::ComponentDeployment* deployment, const std::string& assignedDeviceId, - const std::string& appIdentifier) + const std::string& appIdentifier, + const std::map& specialized_reservations) { const ossie::SPD::Implementation* implementation = deployment->getImplementation(); ossie::DeviceList devices = _registeredDevices; @@ -1460,14 +1634,31 @@ ossie::AllocationResult createHelper::allocateComponentToDevice(redhawk::Compone } } + redhawk::PropertyMap &_allocationProperties = redhawk::PropertyMap::cast(allocationProperties); + redhawk::PropertyMap _struct; + std::string instantiationId = deployment->getInstantiation()->instantiationId; + std::vector _kinds, _values; + _kinds.push_back("cpucores"); + if (specialized_reservations.find(instantiationId) == specialized_reservations.end()) { + _values.push_back("-1"); + } else { + std::ostringstream ss; + ss<second; + _values.push_back(ss.str()); + } + _struct["redhawk::reservation_request::kinds"].setValue(_kinds); + _struct["redhawk::reservation_request::values"].setValue(_values); + _struct["redhawk::reservation_request::obj_id"].setValue(deployment->getIdentifier()); + _allocationProperties["redhawk::reservation_request"].setValue(_struct); + ossie::AllocationResult response = this->_allocationMgr->allocateDeployment(requestid, - allocationProperties, + _allocationProperties, devices, appIdentifier, implementation->getProcessors(), implementation->getOsDeps(), deviceRequires ); - if (allocationProperties.contains("nic_allocation")) { + if (_allocationProperties.contains("nic_allocation")) { if (!response.first.empty()) { redhawk::PropertyMap query_props; query_props["nic_allocation_status"] = redhawk::Value(); diff --git a/redhawk/src/control/sdr/dommgr/createHelper.h b/redhawk/src/control/sdr/dommgr/createHelper.h index 8a3e68efa..c035084c8 100644 --- a/redhawk/src/control/sdr/dommgr/createHelper.h +++ b/redhawk/src/control/sdr/dommgr/createHelper.h @@ -100,22 +100,28 @@ class createHelper typedef std::vector ContainerList; typedef std::vector ProcessorList; typedef std::vector OSList; + typedef std::vector ReservationList; // createHelper helper methods void assignPlacementsToDevices(redhawk::ApplicationDeployment& appDeployment, - const DeviceAssignmentMap& devices); + const DeviceAssignmentMap& devices, + const std::map& specialized_reservations); void _resolveAssemblyController(redhawk::ApplicationDeployment& appDeployment); void _validateDAS(redhawk::ApplicationDeployment& appDeployment, const DeviceAssignmentMap& deviceAssignments); void setUpExternalPorts(redhawk::ApplicationDeployment& appDeployment, Application_impl* application); void setUpExternalProperties(redhawk::ApplicationDeployment& appDeployment, Application_impl* application); + std::vector overloadReservations(const ossie::SoftwareAssembly::HostCollocation& collocation, + const std::map& specialized_reservations); void _placeHostCollocation(redhawk::ApplicationDeployment& appDeployment, const ossie::SoftwareAssembly::HostCollocation& collocation, - const DeviceAssignmentMap& devices); + const DeviceAssignmentMap& devices, + const std::map& specialized_reservations); bool placeHostCollocation(redhawk::ApplicationDeployment& appDeployment, const DeploymentList& components, DeploymentList::const_iterator current, ossie::DeviceList& deploymentDevices, const redhawk::PropertyMap& deviceRequires=redhawk::PropertyMap(), + const ReservationList& reservations=ReservationList(), const ProcessorList& processorDeps=ProcessorList(), const OSList& osDeps=OSList()); @@ -139,11 +145,13 @@ class createHelper const CF::Properties& configureProperties); void allocateComponent(redhawk::ApplicationDeployment& appDeployment, redhawk::ComponentDeployment* deployment, - const std::string& assignedDeviceId); + const std::string& assignedDeviceId, + const std::map& specialized_reservations); ossie::AllocationResult allocateComponentToDevice(redhawk::ComponentDeployment* deployment, const std::string& assignedDeviceId, - const std::string& appIdentifier); + const std::string& appIdentifier, + const std::map& specialized_reservations); bool checkPartitionMatching( ossie::DeviceNode& node, const CF::Properties& devicerequires ); @@ -153,7 +161,8 @@ class createHelper ossie::DeviceList& deploymentDevices, const ProcessorList& processorDeps, const OSList& osDeps, - const redhawk::PropertyMap &); + const redhawk::PropertyMap &, + const ReservationList& reservations); bool resolveSoftpkgDependencies(redhawk::ApplicationDeployment& appDeployment, redhawk::SoftPkgDeployment* deployment, @@ -183,6 +192,9 @@ class createHelper std::string resolveLoggingConfiguration(redhawk::ComponentDeployment* deployment); std::vector getStartOrder(const DeploymentList& deployments); + void verifyNoCpuSpecializationCollisions(const ossie::SoftwareAssembly& sad, std::map specialized_reservations); + std::vector getComponentUsageNames(redhawk::ApplicationDeployment& appDeployment); + std::vector getHostCollocationsIds(); // Cleanup - used when create fails/doesn't succeed for some reason bool _isComplete; diff --git a/redhawk/src/testing/sdr/dev/devices/test_collocation_device/python/test_collocation_device.py b/redhawk/src/testing/sdr/dev/devices/test_collocation_device/python/test_collocation_device.py index 2ef1841c7..0620562c0 100755 --- a/redhawk/src/testing/sdr/dev/devices/test_collocation_device/python/test_collocation_device.py +++ b/redhawk/src/testing/sdr/dev/devices/test_collocation_device/python/test_collocation_device.py @@ -79,6 +79,12 @@ def deallocateCapacity(self, properties): self._log.exception("Error sending properties event") + def allocate_redhawk__reservation_request(self, value): + return True + + def deallocate_redhawk__reservation_request(self, value): + pass + def allocate_additional_supported_components(self, value): return True diff --git a/redhawk/src/testing/sdr/dev/devices/test_collocation_device/python/test_collocation_device_base.py b/redhawk/src/testing/sdr/dev/devices/test_collocation_device/python/test_collocation_device_base.py index 35626abbd..947cece38 100644 --- a/redhawk/src/testing/sdr/dev/devices/test_collocation_device/python/test_collocation_device_base.py +++ b/redhawk/src/testing/sdr/dev/devices/test_collocation_device/python/test_collocation_device_base.py @@ -32,6 +32,8 @@ from ossie.device import ExecutableDevice from ossie.properties import simple_property +from ossie.properties import simpleseq_property +from ossie.properties import struct_property from ossie.events import PropertyEventSupplier @@ -138,6 +140,57 @@ def releaseObject(self): # # DO NOT ADD NEW PROPERTIES HERE. You can add properties in your derived class, in the PRF xml file # or by using the IDE. + class RedhawkReservationRequest(object): + redhawk__reservation_request__obj_id = simple_property( + id_="redhawk::reservation_request::obj_id", + + type_="string") + + redhawk__reservation_request__kinds = simpleseq_property( + id_="redhawk::reservation_request::kinds", + + type_="string", + defvalue=[] + ) + + redhawk__reservation_request__values = simpleseq_property( + id_="redhawk::reservation_request::values", + + type_="string", + defvalue=[] + ) + + def __init__(self, **kw): + """Construct an initialized instance of this struct definition""" + for classattr in type(self).__dict__.itervalues(): + if isinstance(classattr, (simple_property, simpleseq_property)): + classattr.initialize(self) + for k,v in kw.items(): + setattr(self,k,v) + + def __str__(self): + """Return a string representation of this structure""" + d = {} + d["redhawk__reservation_request__obj_id"] = self.redhawk__reservation_request__obj_id + d["redhawk__reservation_request__kinds"] = self.redhawk__reservation_request__kinds + d["redhawk__reservation_request__values"] = self.redhawk__reservation_request__values + return str(d) + + @classmethod + def getId(cls): + return "redhawk::reservation_request" + + @classmethod + def isStruct(cls): + return True + + def getMembers(self): + return [("redhawk__reservation_request__obj_id",self.redhawk__reservation_request__obj_id),("redhawk__reservation_request__kinds",self.redhawk__reservation_request__kinds),("redhawk__reservation_request__values",self.redhawk__reservation_request__values)] + + redhawk__reservation_request = struct_property(id_="redhawk::reservation_request", + structdef=RedhawkReservationRequest, + configurationkind=("allocation",), + mode="readwrite") device_kind = simple_property(id_="DCE:cdc5ee18-7ceb-4ae6-bf4c-31f983179b4d", name="device_kind", type_="string", diff --git a/redhawk/src/testing/sdr/dev/devices/test_collocation_device/test_collocation_device.prf.xml b/redhawk/src/testing/sdr/dev/devices/test_collocation_device/test_collocation_device.prf.xml index 5fe58a758..74b5f595d 100644 --- a/redhawk/src/testing/sdr/dev/devices/test_collocation_device/test_collocation_device.prf.xml +++ b/redhawk/src/testing/sdr/dev/devices/test_collocation_device/test_collocation_device.prf.xml @@ -56,4 +56,10 @@ with this program. If not, see http://www.gnu.org/licenses/. + + + + + + diff --git a/redhawk/src/testing/tests/test_05_CollocationApplicationFactory.py b/redhawk/src/testing/tests/test_05_CollocationApplicationFactory.py index c692226f9..f424f2c6e 100644 --- a/redhawk/src/testing/tests/test_05_CollocationApplicationFactory.py +++ b/redhawk/src/testing/tests/test_05_CollocationApplicationFactory.py @@ -139,6 +139,37 @@ def test_collocationMixed(self): self._domMgr.uninstallApplication(appFact._get_identifier()) + def test_res(self): + nodebooter, domMgr = self.launchDomainManager() + self.assertNotEqual(domMgr, None) + nodebooter, devMgr = self.launchDeviceManager("/nodes/test_collocation_nodes_1dev4cap/DeviceManager.dcd.xml") + + self.assertNotEqual(devMgr, None) + + domMgr.installApplication("/waveforms/test_wav_res/test_wav_res.sad.xml") + self.assertEqual(len(domMgr._get_applicationFactories()), 1) + + appFact = domMgr._get_applicationFactories()[0] + + app = None + try: + app = appFact.create(appFact._get_name(), [], []) + except: + pass + + ## need to check that all the comopnents were allocated to devices from test_collocation_node1_2dev2cap + + self.assertNotEqual(app, None ) + + if ( app ) : + app.stop() + app.releaseObject() + + device = devMgr._get_registeredDevices()[0] + self.assertEqual(self._getProperty(device, 'allocation_attempts'), 1) + + self._domMgr.uninstallApplication(appFact._get_identifier()) + def test_collocationCombinedAllocationCall(self): nodebooter, domMgr = self.launchDomainManager() self.assertNotEqual(domMgr, None) diff --git a/redhawk/src/xml/xsd/sad.xsd b/redhawk/src/xml/xsd/sad.xsd index f2273aa69..c31b59aef 100644 --- a/redhawk/src/xml/xsd/sad.xsd +++ b/redhawk/src/xml/xsd/sad.xsd @@ -211,11 +211,17 @@ with this program. If not, see http://www.gnu.org/licenses/. + + + + + + From c2437a88e255dc55dfb59d992247c4455833a15f Mon Sep 17 00:00:00 2001 From: 8530 <8530@vm-131.vsi-corp.com> Date: Fri, 26 May 2017 17:07:52 -0400 Subject: [PATCH 0804/1644] merge with develop-2.0 --- GPP/cpp/GPP.cpp | 28 +-- GPP/cpp/utils/affinity.cpp | 16 +- .../base/framework/LoadableDevice_impl.cpp | 2 +- redhawk/src/base/framework/Resource_impl.cpp | 166 +++++++++++------- redhawk/src/control/framework/POACreator.cpp | 7 + .../control/sdr/dommgr/Application_impl.cpp | 28 ++- .../control/sdr/dommgr/RH_NamingContext.cpp | 3 +- redhawk/src/control/sdr/dommgr/main.cpp | 13 ++ 8 files changed, 176 insertions(+), 87 deletions(-) diff --git a/GPP/cpp/GPP.cpp b/GPP/cpp/GPP.cpp index 61b68779a..03e95a75b 100644 --- a/GPP/cpp/GPP.cpp +++ b/GPP/cpp/GPP.cpp @@ -1311,30 +1311,30 @@ CF::ExecutableDevice::ProcessID_Type GPP_i::do_execute (const char* name, const int returnval = 0; // - // log4cxx will cause dead locks between fork and execv, use the stdout logger object, this will only replace the new process' - // ExecutableDevice's logger object till execv envoked. + // log4cxx will cause dead locks between fork and execv, use the stdout logger object + // for all logging // - GPP_i::__logger = rh_logger::StdOutLogger::getRootLogger(); - GPP_i::__logger->setLevel(lvl); + rh_logger::LoggerPtr __logger = rh_logger::StdOutLogger::getRootLogger(); + __logger->setLevel(lvl); // set affinity logger method so we do not use log4cxx during affinity processing routine - redhawk::affinity::set_affinity_logger( GPP_i::__logger ) ; - LOG_DEBUG(GPP_i, " Calling set resource affinity....exec:" << name << " options=" << options.length()); + redhawk::affinity::set_affinity_logger( __logger ) ; + RH_DEBUG(__logger, " Calling set resource affinity....exec:" << name << " options=" << options.length()); // set affinity preference before exec try { - LOG_DEBUG(GPP_i, " Calling set resource affinity....exec:" << name << " options=" << options.length()); + RH_DEBUG(__logger, " Calling set resource affinity....exec:" << name << " options=" << options.length()); set_resource_affinity( options, getpid(), name ); } catch( redhawk::affinity::AffinityFailed &ex ) { - LOG_WARN(GPP_i, "Unable to satisfy affinity request for: " << name << " Reason: " << ex.what() ); + RH_WARN(__logger, "Unable to satisfy affinity request for: " << name << " Reason: " << ex.what() ); errno=EPERM<<2; returnval=-1; ossie::corba::OrbShutdown(true); exit(returnval); } catch( ... ) { - LOG_WARN(GPP_i, "Unhandled exception during affinity processing for resource: " << name ); + RH_WARN(__logger, "Unhandled exception during affinity processing for resource: " << name ); ossie::corba::OrbShutdown(true); exit(returnval); } @@ -1349,13 +1349,13 @@ CF::ExecutableDevice::ProcessID_Type GPP_i::do_execute (const char* name, const if ( _handle_io_redirects ) { if( dup2(comp_fd[1],STDERR_FILENO) ==-1 ) { - LOG_ERROR(GPP_i, "Failure to dup2 stderr for resource: " << name ); + RH_ERROR(__logger, "Failure to dup2 stderr for resource: " << name ); ossie::corba::OrbShutdown(true); exit(-1); } if( dup2(comp_fd[1],STDOUT_FILENO) ==-1 ) { - LOG_ERROR(GPP_i, "Failure to dup2 stdout for resource: " << name ); + RH_ERROR(__logger, "Failure to dup2 stdout for resource: " << name ); ossie::corba::OrbShutdown(true); exit(-1); } @@ -1380,16 +1380,16 @@ CF::ExecutableDevice::ProcessID_Type GPP_i::do_execute (const char* name, const break; // Only retry on "text file busy" error - LOG_WARN(GPP_i, "execv() failed, retrying... (cmd=" << path << " msg=\"" << strerror(errno) << "\" retries=" << num_retries << ")"); + RH_WARN(__logger, "execv() failed, retrying... (cmd=" << path << " msg=\"" << strerror(errno) << "\" retries=" << num_retries << ")"); usleep(100000); } if( returnval ) { - LOG_ERROR(GPP_i, "Error when calling execv() (cmd=" << path << " errno=" << errno << " msg=\"" << strerror(errno) << "\")"); + RH_ERROR(__logger, "Error when calling execv() (cmd=" << path << " errno=" << errno << " msg=\"" << strerror(errno) << "\")"); ossie::corba::OrbShutdown(true); } - LOG_DEBUG(GPP_i, "Exiting FAILED subprocess:" << returnval ); + RH_ERROR(__logger, "Exiting FAILED subprocess:" << returnval ); exit(returnval); } else if (pid < 0 ){ diff --git a/GPP/cpp/utils/affinity.cpp b/GPP/cpp/utils/affinity.cpp index edf0fbe4c..c5709bc31 100644 --- a/GPP/cpp/utils/affinity.cpp +++ b/GPP/cpp/utils/affinity.cpp @@ -89,14 +89,14 @@ namespace gpp { std::string pintr("/proc/interrupts"); std::ifstream in(pintr.c_str(), std::ifstream::in ); if ( in.fail() ) { - RH_NL_ERROR("gpp::affinity", "Unable to access /proc/interrupts"); + RH_ERROR(get_affinity_logger(), "Unable to access /proc/interrupts"); return cpus; } std::string line; while( std::getline( in, line ) ) { // check if the device is our interface - RH_NL_TRACE("gpp::affinity", "Processing /proc/interrupts.... line:" << line); + RH_TRACE(get_affinity_logger(), "Processing /proc/interrupts.... line:" << line); if ( line.rfind(iface) != std::string::npos ) { std::istringstream iss(line); int parts=0; @@ -108,14 +108,14 @@ namespace gpp { int icnt=0; try { icnt=boost::lexical_cast(tok); - RH_NL_TRACE("gpp::affinity", "identify cpus: CPU : " << parts-1 << " nic interrupts:" << icnt); + RH_TRACE(get_affinity_logger(), "identify cpus: CPU : " << parts-1 << " nic interrupts:" << icnt); if ( icnt > 0 ) { - RH_NL_TRACE("gpp::affinity", "identify cpus: Adding CPU : " << parts-1); + RH_TRACE(get_affinity_logger(), "identify cpus: Adding CPU : " << parts-1); cpus.push_back(parts-1); } } catch(...){ - RH_NL_TRACE("gpp::affinity", "Invalid Token: tok:" << tok); + RH_TRACE(get_affinity_logger(), "Invalid Token: tok:" << tok); } } parts++; @@ -126,7 +126,7 @@ namespace gpp { redhawk::affinity::CpuList::iterator citer=cpus.begin(); for (; citer != cpus.end(); citer++) { - RH_NL_DEBUG("gpp::affinity", "identified CPUS iface/cpu ...:" << iface << "/" << *citer); + RH_DEBUG(get_affinity_logger(), "identified CPUS iface/cpu ...:" << iface << "/" << *citer); } return cpus; @@ -145,11 +145,11 @@ namespace gpp { #ifdef HAVE_LIBNUMA int soc=-1; for( int i=0; i < (int)cpulist.size();i++ ) { - RH_NL_DEBUG("gpp::affinity", "Finding (processor socket) for NIC:" << iface << " socket :" << numa_node_of_cpu(cpulist[i]) ); + RH_DEBUG(get_affinity_logger(), "Finding (processor socket) for NIC:" << iface << " socket :" << numa_node_of_cpu(cpulist[i]) ); if ( std::count( bl.begin(), bl.end(), cpulist[i] ) != 0 ) continue; soc = numa_node_of_cpu(cpulist[i]); if ( soc != psoc && psoc != -1 && !findFirst ) { - RH_NL_WARN("gpp::affinity", "More than 1 socket servicing NIC:" << iface); + RH_WARN(get_affinity_logger(), "More than 1 socket servicing NIC:" << iface); psoc=-1; break; } diff --git a/redhawk/src/base/framework/LoadableDevice_impl.cpp b/redhawk/src/base/framework/LoadableDevice_impl.cpp index 0e54052df..a8361ea42 100644 --- a/redhawk/src/base/framework/LoadableDevice_impl.cpp +++ b/redhawk/src/base/framework/LoadableDevice_impl.cpp @@ -297,7 +297,7 @@ throw (CORBA::SystemException, CF::Device::InvalidState, throw (CF::InvalidFileName (CF::CF_ENOENT, "Cannot load. File name is invalid.")); } } catch ( ... ) { - LOG_ERROR(LoadableDevice_impl, "Exception raised when calling the file system") + LOG_ERROR(LoadableDevice_impl, "Exception raised when calling the file system: " << workingFileName ); throw; } diff --git a/redhawk/src/base/framework/Resource_impl.cpp b/redhawk/src/base/framework/Resource_impl.cpp index f7866a64d..6b40050ca 100644 --- a/redhawk/src/base/framework/Resource_impl.cpp +++ b/redhawk/src/base/framework/Resource_impl.cpp @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see http://www.gnu.org/licenses/. */ - +#include #include #include "ossie/Resource_impl.h" @@ -66,21 +66,31 @@ void Resource_impl::setAdditionalParameters(std::string& softwareProfile, std::s setDomainManager(CF::DomainManager::_nil()); return; } - CF::ApplicationRegistrar_ptr applicationRegistrar = ossie::corba::_narrowSafe(applicationRegistrarObject); + CF::ApplicationRegistrar_var applicationRegistrar = ossie::corba::_narrowSafe(applicationRegistrarObject); if (!CORBA::is_nil(applicationRegistrar)) { - RH_NL_TRACE("Resource", "Get DomainManager from Registrar object:" << application_registrar_ior ); - CF::DomainManager_var dm=applicationRegistrar->domMgr(); - setDomainManager(dm); - return; + try { + RH_NL_TRACE("Resource", "Get DomainManager from Registrar object:" << application_registrar_ior ); + CF::DomainManager_var dm=applicationRegistrar->domMgr(); + setDomainManager(dm); + return; + } + catch(...){ + RH_NL_WARN("Resource", "ApplicationRegistrar Failure to get DomainManager container"); + } } RH_NL_TRACE("Resource", "Resolve DeviceManager..."); CF::DeviceManager_var devMgr = ossie::corba::_narrowSafe(applicationRegistrarObject); if (!CORBA::is_nil(devMgr)) { - RH_NL_TRACE("Resource", "Resolving DomainManager from DeviceManager..."); - CF::DomainManager_var dm=devMgr->domMgr(); - setDomainManager(dm); - return; + try { + RH_NL_TRACE("Resource", "Resolving DomainManager from DeviceManager..."); + CF::DomainManager_var dm=devMgr->domMgr(); + setDomainManager(dm); + return; + } + catch(...){ + RH_NL_WARN("Resource", "DeviceManager... Failure to get DomainManager container"); + } } RH_NL_DEBUG("Resource", "All else failed.... use empty container"); @@ -250,22 +260,36 @@ Resource_impl* Resource_impl::create_component(Resource_impl::ctor_type ctor, co if (!application_registrar_ior.empty()) { CORBA::Object_var applicationRegistrarObject = ossie::corba::stringToObject(application_registrar_ior); CF::ApplicationRegistrar_var applicationRegistrar = ossie::corba::_narrowSafe(applicationRegistrarObject); + if (!CORBA::is_nil(applicationRegistrar)) { - // Set up the DomainManager container - CF::DomainManager_var domainManager = applicationRegistrar->domMgr(); - resource->setDomainManager(domainManager); - - // If it inherits from the Component class, set up the Application - // container as well - Component* component = dynamic_cast(resource); - if (component) { - CF::Application_var application = applicationRegistrar->app(); - component->setApplication(application); + try { + // Set up the DomainManager container + CF::DomainManager_var domainManager = applicationRegistrar->domMgr(); + resource->setDomainManager(domainManager); + + // If it inherits from the Component class, set up the Application + // container as well + Component* component = dynamic_cast(resource); + if (component) { + CF::Application_var application = applicationRegistrar->app(); + component->setApplication(application); + } + + // Register with the application + LOG_TRACE(Resource_impl, "Registering with application using name '" << name_binding << "'"); + applicationRegistrar->registerComponent(name_binding.c_str(), resource_obj); + } + catch( CF::InvalidObjectReference &e ) { + LOG_ERROR(Resource_impl, "Exception registering with registrar, comp: " << name_binding << " exception: InvalidObjectReference"); + } + catch( CF::DuplicateName &e ){ + LOG_ERROR(Resource_impl, "Exception registering with registrar, comp: " << name_binding << " exception: DuplicateName"); + } + catch(CORBA::SystemException &ex){ + LOG_ERROR(Resource_impl, "Exception registering with registrar, comp: " << name_binding << " exception: CORBA System Exception, terminating application"); + throw; } - // Register with the application - LOG_TRACE(Resource_impl, "Registering with application using name '" << name_binding << "'"); - applicationRegistrar->registerComponent(name_binding.c_str(), resource_obj); } else { LOG_TRACE(Resource_impl, "Binding component to naming context with name '" << name_binding << "'"); // the registrar is not available (because the invoking infrastructure only uses the name service) @@ -357,50 +381,74 @@ void Resource_impl::start_component(Resource_impl::ctor_type ctor, int argc, cha ossie::logging::Configure(logcfg_uri, debug_level, ctx); } - // Create the servant. - Resource_impl* resource = create_component(ctor, cmdlineProps); + try { + // Create the servant. + Resource_impl* resource = create_component(ctor, cmdlineProps); - if ( !skip_run ) { - // assign the logging context to the resource to support logging interface - resource->saveLoggingContext( logcfg_uri, debug_level, ctx ); - } + if ( !skip_run ) { + // assign the logging context to the resource to support logging interface + resource->saveLoggingContext( logcfg_uri, debug_level, ctx ); + } - std::string pathAndFile = argv[0]; - unsigned lastSlash = pathAndFile.find_last_of("/"); - std::string cwd = pathAndFile.substr(0, lastSlash); - resource->setCurrentWorkingDirectory(cwd); + std::string pathAndFile = argv[0]; + unsigned lastSlash = pathAndFile.find_last_of("/"); + std::string cwd = pathAndFile.substr(0, lastSlash); + resource->setCurrentWorkingDirectory(cwd); - if (skip_run){ - return; - } + if (skip_run){ + return; + } + + // Store away a reference to the main component and establish a handler for + // SIGINT that will break out of run() + main_component = resource; + struct sigaction sa; + sa.sa_handler = &sigint_handler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + sigaction(SIGINT, &sa, NULL); + + LOG_TRACE(Resource_impl, "Entering component run loop"); + resource->run(); + LOG_TRACE(Resource_impl, "Component run loop terminated"); - // Store away a reference to the main component and establish a handler for - // SIGINT that will break out of run() - main_component = resource; - struct sigaction sa; - sa.sa_handler = &sigint_handler; - sigemptyset(&sa.sa_mask); - sa.sa_flags = 0; - sigaction(SIGINT, &sa, NULL); + redhawk::events::Manager::Terminate(); - LOG_TRACE(Resource_impl, "Entering component run loop"); - resource->run(); - LOG_TRACE(Resource_impl, "Component run loop terminated"); + // Ignore SIGINT from here on out to ensure that the ORB gets shut down + // properly + sa.sa_handler = SIG_IGN; + sigemptyset(&sa.sa_mask); + sigaction(SIGINT, &sa, NULL); + main_component = 0; - redhawk::events::Manager::Terminate(); + LOG_TRACE(Resource_impl, "Deleting component"); + resource->_remove_ref(); + LOG_TRACE(Resource_impl, "Shutting down ORB"); - // Ignore SIGINT from here on out to ensure that the ORB gets shut down - // properly - sa.sa_handler = SIG_IGN; - sigemptyset(&sa.sa_mask); - sigaction(SIGINT, &sa, NULL); - main_component = 0; + ossie::logging::Terminate(); - LOG_TRACE(Resource_impl, "Deleting component"); - resource->_remove_ref(); - LOG_TRACE(Resource_impl, "Shutting down ORB"); + ossie::corba::OrbShutdown(true); + } + catch( CORBA::SystemException &e ){ + std::cerr << "Resource_impl: Unhandled CORBA exception, exiting comp: " << component_identifier << "/" << name_binding << std::endl; + try { + ossie::logging::Terminate(); + ossie::corba::OrbShutdown(true); + + } + catch(...){ + } + } + catch (...) { + std::cerr << "Resource_impl: Unknown exception, exiting comp: " << component_identifier << "/" << name_binding << std::endl; + try { + ossie::logging::Terminate(); + ossie::corba::OrbShutdown(true); + } + catch(...){ + } + + } - ossie::logging::Terminate(); - ossie::corba::OrbShutdown(true); } diff --git a/redhawk/src/control/framework/POACreator.cpp b/redhawk/src/control/framework/POACreator.cpp index 9ffffcf8e..8a1667a38 100644 --- a/redhawk/src/control/framework/POACreator.cpp +++ b/redhawk/src/control/framework/POACreator.cpp @@ -94,6 +94,13 @@ CORBA::Boolean POACreator::unknown_adapter (PortableServer::POA_ptr parent, cons lifespan = parent->create_lifespan_policy(PortableServer::TRANSIENT); idassignment = parent->create_id_assignment_policy(PortableServer::SYSTEM_ID); thread = parent->create_thread_policy(PortableServer::ORB_CTRL_MODEL); + } else if (child_name == "RH_NamingContext") { + if (parent_name != "RootPOA") { + return 0; + } + lifespan = parent->create_lifespan_policy(PortableServer::TRANSIENT); + idassignment = parent->create_id_assignment_policy(PortableServer::SYSTEM_ID); + thread = parent->create_thread_policy(PortableServer::ORB_CTRL_MODEL); } else if (child_name == "EventChannels") { if (parent_name != "DomainManager") { return 0; diff --git a/redhawk/src/control/sdr/dommgr/Application_impl.cpp b/redhawk/src/control/sdr/dommgr/Application_impl.cpp index 615d3db6d..f95a45f1f 100644 --- a/redhawk/src/control/sdr/dommgr/Application_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/Application_impl.cpp @@ -693,6 +693,13 @@ throw (CORBA::SystemException, CF::LifeCycle::InitializeError) CORBA::Object_ptr Application_impl::getPort (const char* _id) throw (CORBA::SystemException, CF::PortSupplier::UnknownPort) { + + SCOPED_LOCK( releaseObjectLock ); + if (_releaseAlreadyCalled) { + LOG_DEBUG(Application_impl, "skipping getPort because release has already been called"); + return CORBA::Object::_nil(); + } + const std::string identifier = _id; if (_ports.count(identifier)) { return CORBA::Object::_duplicate(_ports[identifier]); @@ -702,16 +709,25 @@ throw (CORBA::SystemException, CF::PortSupplier::UnknownPort) } } + + CF::PortSet::PortInfoSequence* Application_impl::getPortSet () { + SCOPED_LOCK( releaseObjectLock ); CF::PortSet::PortInfoSequence_var retval = new CF::PortSet::PortInfoSequence(); + + if (_releaseAlreadyCalled) { + LOG_DEBUG(Application_impl, "skipping getPortSet because release has alraeady been called"); + return retval._retn(); + } + std::vector comp_portsets; for (ComponentList::iterator _component_iter=this->_components.begin(); _component_iter!=this->_components.end(); _component_iter++) { try { CF::Resource_var comp = _component_iter->getResourcePtr(); comp_portsets.push_back(comp->getPortSet()); } catch ( ... ) { - // failed to get the port set from the component + LOG_ERROR(Application_impl, "Unhandled exception during getPortSet, application: " << _identifier << " comp:" << _component_iter->getIdentifier() << "/" << _component_iter->getNamingContext() ); } } for (std::map::iterator _port_val=_ports.begin(); _port_val!=_ports.end(); _port_val++) { @@ -1036,6 +1052,7 @@ throw (CORBA::SystemException) CF::Components* Application_impl::registeredComponents () { CF::Components_var result = new CF::Components(); + boost::mutex::scoped_lock lock(_registrationMutex); convert_sequence_if(result, _components, to_component_type, std::mem_fun_ref(&redhawk::ApplicationComponent::isRegistered)); return result._retn(); @@ -1145,6 +1162,7 @@ bool Application_impl::waitForComponents (std::set& identifiers, in CF::Application_ptr Application_impl::getComponentApplication () { + SCOPED_LOCK( releaseObjectLock ); if (_isAware) { return _this(); } else { @@ -1154,11 +1172,13 @@ CF::Application_ptr Application_impl::getComponentApplication () CF::DomainManager_ptr Application_impl::getComponentDomainManager () { + SCOPED_LOCK( releaseObjectLock ); + CF::DomainManager_var ret = CF::DomainManager::_nil(); if (_isAware) { - return _domainManager->_this(); - } else { - return CF::DomainManager::_nil(); + ret = _domainManager->_this(); } + + return CF::DomainManager::_duplicate(ret); } redhawk::ApplicationComponent* Application_impl::getComponent(const std::string& identifier) diff --git a/redhawk/src/control/sdr/dommgr/RH_NamingContext.cpp b/redhawk/src/control/sdr/dommgr/RH_NamingContext.cpp index 4b29563dd..764ab206b 100644 --- a/redhawk/src/control/sdr/dommgr/RH_NamingContext.cpp +++ b/redhawk/src/control/sdr/dommgr/RH_NamingContext.cpp @@ -167,7 +167,8 @@ CosNaming::NamingContext_ptr RH_NamingContext::GetNamingContext( const std::stri } else { if ( CORBA::is_nil(names_poa) ) { - names_poa = PortableServer::POA::_duplicate( ossie::corba::RootPOA()); + names_poa = ossie::corba::RootPOA()->find_POA("RH_NamingContext",1); + //names_poa = PortableServer::POA::_duplicate( ossie::corba::RootPOA()); } DB(std::cout << " Using DomainManager's NamingContext facility ##############################" << std::endl;); diff --git a/redhawk/src/control/sdr/dommgr/main.cpp b/redhawk/src/control/sdr/dommgr/main.cpp index 150dca1f7..c5a3cf104 100644 --- a/redhawk/src/control/sdr/dommgr/main.cpp +++ b/redhawk/src/control/sdr/dommgr/main.cpp @@ -97,6 +97,15 @@ static void raise_limit(int resource, const char* name, const rlim_t DEFAULT_MAX } +#if _HAMMER_TEST_ +static CORBA::Boolean CommFailureHandler(void* pCookie, CORBA::ULong nRetries, const CORBA::COMM_FAILURE& ex) +{ + std::cerr << std::endl << "CommFailure handler called. Minor: " << ex.minor() << "Retries = " << nRetries << std::endl << std::endl; + return ((nRetries < 1) ? 1 : 0); +} +#endif + + int old_main(int argc, char* argv[]) { // parse command line options @@ -344,6 +353,10 @@ int old_main(int argc, char* argv[]) orbProperties.push_back(std::make_pair("outConScanPeriod", "10")); CORBA::ORB_ptr orb = ossie::corba::OrbInit(argc, argv, orbProperties, enablePersistence); +#if _HAMMER_TEST_ + omniORB::installCommFailureExceptionHandler(NULL, CommFailureHandler); +#endif + PortableServer::POA_ptr root_poa = PortableServer::POA::_nil(); try { // Install an adaptor to automatically create our own POAs. From c967118139efc39f5cc7a1a7a3b8dbfbb4dc3547 Mon Sep 17 00:00:00 2001 From: 8530 <8530@vm-131.vsi-corp.com> Date: Fri, 2 Jun 2017 08:12:19 -0400 Subject: [PATCH 0805/1644] fix python parsers for new features for deployer and device requires, CF-1750 --- .../framework/python/ossie/parsers/dcd.py | 192 +++++++++++- .../framework/python/ossie/parsers/sad.py | 292 +++++++++++++++++- .../sdr/parser_tests/deployerrequires.dcd.xml | 46 +++ .../sdr/parser_tests/devicerequires.sad.xml | 58 ++++ .../sdr/parser_tests/usesdeviceref.sad.xml | 43 +++ .../testing/tests/test_07_PythonParsers.py | 134 ++++++++ 6 files changed, 759 insertions(+), 6 deletions(-) create mode 100644 redhawk/src/testing/sdr/parser_tests/deployerrequires.dcd.xml create mode 100644 redhawk/src/testing/sdr/parser_tests/devicerequires.sad.xml create mode 100644 redhawk/src/testing/sdr/parser_tests/usesdeviceref.sad.xml diff --git a/redhawk/src/base/framework/python/ossie/parsers/dcd.py b/redhawk/src/base/framework/python/ossie/parsers/dcd.py index 5c2b2e462..e35ca6f9c 100644 --- a/redhawk/src/base/framework/python/ossie/parsers/dcd.py +++ b/redhawk/src/base/framework/python/ossie/parsers/dcd.py @@ -1494,12 +1494,13 @@ class componentinstantiation(GeneratedsSuper): attribute is a DCE UUID that uniquely identifier the component.""" subclass = None superclass = None - def __init__(self, id_=None, usagename=None, componentproperties=None, affinity=None, loggingconfig=None ): + def __init__(self, id_=None, usagename=None, componentproperties=None, affinity=None, loggingconfig=None, deployerrequires=None ): self.id_ = _cast(None, id_) self.usagename = usagename self.componentproperties = componentproperties self.affinity = affinity self.loggingconfig = loggingconfig + self.deployerrequires = deployerrequires def factory(*args_, **kwargs_): if componentinstantiation.subclass: return componentinstantiation.subclass(*args_, **kwargs_) @@ -1518,6 +1519,9 @@ def set_affinity(self, affinity): self.affinity = affinity def get_loggingconfig(self): return self.loggingconfig def set_loggingconfig(self, loggingconfig): self.loggingconfig = loggingconfig loggingconfigProp = property(get_loggingconfig, set_loggingconfig) + def get_deployerrequires(self): return self.deployerrequires + def set_deployerrequires(self, deployerrequires): self.deployerrequires = deployerrequires + deployerrequiresProp = property(get_deployerrequires, set_deployerrequires) def get_id(self): return self.id_ def set_id(self, id): self.id_ = id idProp = property(get_id, set_id) @@ -1555,13 +1559,16 @@ def exportChildren(self, outfile, level, namespace_='', name_='componentinstanti self.affinity.export(outfile, level, namespace_, name_='affinity', pretty_print=pretty_print) if self.loggingconfig is not None: self.loggingconfig.export(outfile, level, namespace_, name_='loggingconfig', pretty_print=pretty_print) + if self.deployerrequires is not None: + self.deployerrequires.export(outfile, level, namespace_, name_='deployerrequires', pretty_print=pretty_print) def hasContent_(self): if ( self.usagename is not None or self.componentproperties is not None or self.affinity is not None or self.loggingconfig is not None or - self.findcomponent is not None + self.findcomponent is not None or + self.deployerrequires is not None ): return True else: @@ -1598,6 +1605,12 @@ def exportLiteralChildren(self, outfile, level, name_): self.loggingconfig.exportLiteral(outfile, level) showIndent(outfile, level) outfile.write('),\n') + if self.deployerrequires is not None: + showIndent(outfile, level) + outfile.write('deployerrequires=model_.deployerrequires(\n') + self.deployerrequires.exportLiteral(outfile, level) + showIndent(outfile, level) + outfile.write('),\n') def build(self, node): self.buildAttributes(node, node.attrib, []) @@ -1626,6 +1639,10 @@ def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): obj_ = loggingconfig.factory() obj_.build(child_) self.set_loggingconfig(obj_) + elif nodeName_ == 'deployerrequires': + obj_ = deployerrequires.factory() + obj_.build(child_) + self.set_deployerrequires(obj_) # end class componentinstantiation @@ -2051,6 +2068,176 @@ def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): pass # end class loggingconfig +class deployerrequires(GeneratedsSuper): + subclass = None + superclass = None + def __init__(self, requires=None,): + if requires is None: + self.requires=[] + else: + self.requires = requires + def factory(*args_, **kwargs_): + if requires.subclass: + return deployerrequires.subclass(*args_, **kwargs_) + else: + return deployerrequires(*args_, **kwargs_) + factory = staticmethod(factory) + def get_requires(self): return self.requires + def set_requires(self, requires): self.requires = requires + def add_requires(self, value): self.requires.append(value) + def insert_requires(self, index, value): self.requires[index] = value + requiresProp = property(get_requires, set_requires) + def export(self, outfile, level, namespace_='', name_='deployerrequires', namespacedef_='', pretty_print=True): + if pretty_print: + eol_ = '\n' + else: + eol_ = '' + showIndent(outfile, level, pretty_print) + outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', )) + already_processed = [] + self.exportAttributes(outfile, level, already_processed, namespace_, name_='deployerrequires') + if self.hasContent_(): + outfile.write('>%s' % (eol_, )) + self.exportChildren(outfile, level + 1, namespace_, name_, pretty_print=pretty_print) + showIndent(outfile, level, pretty_print) + outfile.write('%s' % (namespace_, name_, eol_)) + else: + outfile.write('/>%s' % (eol_, )) + def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='deployerrequires'): + pass + def exportChildren(self, outfile, level, namespace_='', name_='deployerrequires', fromsubclass_=False, pretty_print=True): + if pretty_print: + eol_ = '\n' + else: + eol_ = '' + for requires_ in self.requires: + requires_.export(outfile, level, namespace_, name_='requires', pretty_print=pretty_print) + def hasContent_(self): + if ( + self.requires + ): + return True + else: + return False + def exportLiteral(self, outfile, level, name_='deployerrequires'): + level += 1 + self.exportLiteralAttributes(outfile, level, [], name_) + if self.hasContent_(): + self.exportLiteralChildren(outfile, level, name_) + def exportLiteralAttributes(self, outfile, level, already_processed, name_): + pass + def exportLiteralChildren(self, outfile, level, name_): + showIndent(outfile, level) + outfile.write('requires=[\n') + level += 1 + for simpleref_ in self.simpleref: + showIndent(outfile, level) + outfile.write('model_.requires(\n') + simpleref_.exportLiteral(outfile, level) + showIndent(outfile, level) + outfile.write('),\n') + level -= 1 + showIndent(outfile, level) + outfile.write('],\n') + def build(self, node): + self.buildAttributes(node, node.attrib, []) + for child in node: + nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] + self.buildChildren(child, node, nodeName_) + def buildAttributes(self, node, attrs, already_processed): + pass + def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): + if nodeName_ == 'requires': + obj_ = requires.factory() + obj_.build(child_) + self.requires.append(obj_) +# end class deployerrequires + + +class requires(GeneratedsSuper): + subclass = None + superclass = None + def __init__(self, id=None, value=None): + self.id = _cast(None, id) + self.value = _cast(None, value) + pass + def factory(*args_, **kwargs_): + if requires.subclass: + return requires.subclass(*args_, **kwargs_) + else: + return requires(*args_, **kwargs_) + factory = staticmethod(factory) + def get_id(self): return self.id + def set_id(self, id): self.id = id + idProp = property(get_id, set_id) + def get_value(self): return self.value + def set_value(self, value): self.value = value + valueProp = property(get_value, set_value) + def export(self, outfile, level, namespace_='', name_='requires', namespacedef_='', pretty_print=True): + if pretty_print: + eol_ = '\n' + else: + eol_ = '' + showIndent(outfile, level, pretty_print) + outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', )) + already_processed = [] + self.exportAttributes(outfile, level, already_processed, namespace_, name_='requires') + if self.hasContent_(): + outfile.write('>%s' % (eol_, )) + self.exportChildren(outfile, level + 1, namespace_, name_, pretty_print=pretty_print) + outfile.write('%s' % (namespace_, name_, eol_)) + else: + outfile.write('/>%s' % (eol_, )) + def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='requires'): + if self.id is not None and 'id' not in already_processed: + already_processed.append('id') + outfile.write(' id=%s' % (self.gds_format_string(quote_attrib(self.id).encode(ExternalEncoding), input_name='id'), )) + if self.value is not None and 'value' not in already_processed: + already_processed.append('value') + outfile.write(' value=%s' % (self.gds_format_string(quote_attrib(self.value).encode(ExternalEncoding), input_name='value'), )) + def exportChildren(self, outfile, level, namespace_='', name_='requires', fromsubclass_=False, pretty_print=True): + pass + def hasContent_(self): + if ( + + ): + return True + else: + return False + def exportLiteral(self, outfile, level, name_='requires'): + level += 1 + self.exportLiteralAttributes(outfile, level, [], name_) + if self.hasContent_(): + self.exportLiteralChildren(outfile, level, name_) + def exportLiteralAttributes(self, outfile, level, already_processed, name_): + if self.id is not None and 'id' not in already_processed: + already_processed.append('id') + showIndent(outfile, level) + outfile.write('id = "%s",\n' % (self.id,)) + if self.value is not None and 'value' not in already_processed: + already_processed.append('value') + showIndent(outfile, level) + outfile.write('value = "%s",\n' % (self.value,)) + def exportLiteralChildren(self, outfile, level, name_): + pass + def build(self, node): + self.buildAttributes(node, node.attrib, []) + for child in node: + nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] + self.buildChildren(child, node, nodeName_) + def buildAttributes(self, node, attrs, already_processed): + value = find_attr_value_('id', node) + if value is not None and 'id' not in already_processed: + already_processed.append('id') + self.id = value + value = find_attr_value_('value', node) + if value is not None and 'value' not in already_processed: + already_processed.append('value') + self.value = value + def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): + pass +# end class requires + class devicethatloadedthiscomponentref(GeneratedsSuper): @@ -4063,6 +4250,7 @@ def main(): "connectinterface", "connections", "deployondevice", + "deployerrequires", "deviceconfiguration", "devicemanagersoftpkg", "devicepkgfile", diff --git a/redhawk/src/base/framework/python/ossie/parsers/sad.py b/redhawk/src/base/framework/python/ossie/parsers/sad.py index 20c09fbfd..76a833449 100644 --- a/redhawk/src/base/framework/python/ossie/parsers/sad.py +++ b/redhawk/src/base/framework/python/ossie/parsers/sad.py @@ -1178,7 +1178,7 @@ def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): class componentinstantiation(GeneratedsSuper): subclass = None superclass = None - def __init__(self, id_=None, startorder=None, usagename=None, componentproperties=None, affinity=None, loggingconfig=None, findcomponent=None ): + def __init__(self, id_=None, startorder=None, usagename=None, componentproperties=None, affinity=None, loggingconfig=None, findcomponent=None, devicerequires=None ): self.id_ = _cast(None, id_) self.startorder = _cast(None, startorder) self.usagename = usagename @@ -1186,6 +1186,7 @@ def __init__(self, id_=None, startorder=None, usagename=None, componentpropertie self.affinity = affinity self.loggingconfig = loggingconfig self.findcomponent = findcomponent + self.devicerequires = devicerequires def factory(*args_, **kwargs_): if componentinstantiation.subclass: return componentinstantiation.subclass(*args_, **kwargs_) @@ -1207,6 +1208,9 @@ def set_affinity(self, affinity): self.affinity = affinity def get_loggingconfig(self): return self.loggingconfig def set_loggingconfig(self, loggingconfig): self.loggingconfig = loggingconfig loggingconfigProp = property(get_loggingconfig, set_loggingconfig) + def get_devicerequires(self): return self.devicerequires + def set_devicerequires(self, devicerequires): self.devicerequires = devicerequires + devicerequiresProp = property(get_devicerequires, set_devicerequires) def get_id(self): return self.id_ def set_id(self, id): self.id_ = id idProp = property(get_id, set_id) @@ -1252,13 +1256,16 @@ def exportChildren(self, outfile, level, namespace_='', name_='componentinstanti self.loggingconfig.export(outfile, level, namespace_, name_='loggingconfig', pretty_print=pretty_print) if self.findcomponent is not None: self.findcomponent.export(outfile, level, namespace_, name_='findcomponent', pretty_print=pretty_print) + if self.devicerequires is not None: + self.devicerequires.export(outfile, level, namespace_, name_='devicerequires', pretty_print=pretty_print) def hasContent_(self): if ( self.usagename is not None or self.componentproperties is not None or self.affinity is not None or self.loggingconfig is not None or - self.findcomponent is not None + self.findcomponent is not None or + self.devicerequires is not None ): return True else: @@ -1305,6 +1312,12 @@ def exportLiteralChildren(self, outfile, level, name_): self.findcomponent.exportLiteral(outfile, level) showIndent(outfile, level) outfile.write('),\n') + if self.devicerequires is not None: + showIndent(outfile, level) + outfile.write('devicerequires=model_.devicerequires(\n') + self.devicerequires.exportLiteral(outfile, level) + showIndent(outfile, level) + outfile.write('),\n') def build(self, node): self.buildAttributes(node, node.attrib, []) for child in node: @@ -1340,6 +1353,10 @@ def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): obj_ = findcomponent.factory() obj_.build(child_) self.set_findcomponent(obj_) + elif nodeName_ == 'devicerequires': + obj_ = devicerequires.factory() + obj_.build(child_) + self.set_devicerequires(obj_) # end class componentinstantiation @@ -1856,6 +1873,176 @@ def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): self.set_namingservice(obj_) # end class findcomponent +class devicerequires(GeneratedsSuper): + subclass = None + superclass = None + def __init__(self, requires=None,): + if requires is None: + self.requires=[] + else: + self.requires = requires + def factory(*args_, **kwargs_): + if requires.subclass: + return devicerequires.subclass(*args_, **kwargs_) + else: + return devicerequires(*args_, **kwargs_) + factory = staticmethod(factory) + def get_requires(self): return self.requires + def set_requires(self, requires): self.requires = requires + def add_requires(self, value): self.requires.append(value) + def insert_requires(self, index, value): self.requires[index] = value + requiresProp = property(get_requires, set_requires) + def export(self, outfile, level, namespace_='', name_='devicerequires', namespacedef_='', pretty_print=True): + if pretty_print: + eol_ = '\n' + else: + eol_ = '' + showIndent(outfile, level, pretty_print) + outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', )) + already_processed = [] + self.exportAttributes(outfile, level, already_processed, namespace_, name_='devicerequires') + if self.hasContent_(): + outfile.write('>%s' % (eol_, )) + self.exportChildren(outfile, level + 1, namespace_, name_, pretty_print=pretty_print) + showIndent(outfile, level, pretty_print) + outfile.write('%s' % (namespace_, name_, eol_)) + else: + outfile.write('/>%s' % (eol_, )) + def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='devicerequires'): + pass + def exportChildren(self, outfile, level, namespace_='', name_='devicerequires', fromsubclass_=False, pretty_print=True): + if pretty_print: + eol_ = '\n' + else: + eol_ = '' + for requires_ in self.requires: + requires_.export(outfile, level, namespace_, name_='requires', pretty_print=pretty_print) + def hasContent_(self): + if ( + self.requires + ): + return True + else: + return False + def exportLiteral(self, outfile, level, name_='devicerequires'): + level += 1 + self.exportLiteralAttributes(outfile, level, [], name_) + if self.hasContent_(): + self.exportLiteralChildren(outfile, level, name_) + def exportLiteralAttributes(self, outfile, level, already_processed, name_): + pass + def exportLiteralChildren(self, outfile, level, name_): + showIndent(outfile, level) + outfile.write('requires=[\n') + level += 1 + for simpleref_ in self.simpleref: + showIndent(outfile, level) + outfile.write('model_.requires(\n') + simpleref_.exportLiteral(outfile, level) + showIndent(outfile, level) + outfile.write('),\n') + level -= 1 + showIndent(outfile, level) + outfile.write('],\n') + def build(self, node): + self.buildAttributes(node, node.attrib, []) + for child in node: + nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] + self.buildChildren(child, node, nodeName_) + def buildAttributes(self, node, attrs, already_processed): + pass + def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): + if nodeName_ == 'requires': + obj_ = requires.factory() + obj_.build(child_) + self.requires.append(obj_) +# end class devicerequires + + +class requires(GeneratedsSuper): + subclass = None + superclass = None + def __init__(self, id=None, value=None): + self.id = _cast(None, id) + self.value = _cast(None, value) + pass + def factory(*args_, **kwargs_): + if requires.subclass: + return requires.subclass(*args_, **kwargs_) + else: + return requires(*args_, **kwargs_) + factory = staticmethod(factory) + def get_id(self): return self.id + def set_id(self, id): self.id = id + idProp = property(get_id, set_id) + def get_value(self): return self.value + def set_value(self, value): self.value = value + valueProp = property(get_value, set_value) + def export(self, outfile, level, namespace_='', name_='requires', namespacedef_='', pretty_print=True): + if pretty_print: + eol_ = '\n' + else: + eol_ = '' + showIndent(outfile, level, pretty_print) + outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', )) + already_processed = [] + self.exportAttributes(outfile, level, already_processed, namespace_, name_='requires') + if self.hasContent_(): + outfile.write('>%s' % (eol_, )) + self.exportChildren(outfile, level + 1, namespace_, name_, pretty_print=pretty_print) + outfile.write('%s' % (namespace_, name_, eol_)) + else: + outfile.write('/>%s' % (eol_, )) + def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='requires'): + if self.id is not None and 'id' not in already_processed: + already_processed.append('id') + outfile.write(' id=%s' % (self.gds_format_string(quote_attrib(self.id).encode(ExternalEncoding), input_name='id'), )) + if self.value is not None and 'value' not in already_processed: + already_processed.append('value') + outfile.write(' value=%s' % (self.gds_format_string(quote_attrib(self.value).encode(ExternalEncoding), input_name='value'), )) + def exportChildren(self, outfile, level, namespace_='', name_='requires', fromsubclass_=False, pretty_print=True): + pass + def hasContent_(self): + if ( + + ): + return True + else: + return False + def exportLiteral(self, outfile, level, name_='requires'): + level += 1 + self.exportLiteralAttributes(outfile, level, [], name_) + if self.hasContent_(): + self.exportLiteralChildren(outfile, level, name_) + def exportLiteralAttributes(self, outfile, level, already_processed, name_): + if self.id is not None and 'id' not in already_processed: + already_processed.append('id') + showIndent(outfile, level) + outfile.write('id = "%s",\n' % (self.id,)) + if self.value is not None and 'value' not in already_processed: + already_processed.append('value') + showIndent(outfile, level) + outfile.write('value = "%s",\n' % (self.value,)) + def exportLiteralChildren(self, outfile, level, name_): + pass + def build(self, node): + self.buildAttributes(node, node.attrib, []) + for child in node: + nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] + self.buildChildren(child, node, nodeName_) + def buildAttributes(self, node, attrs, already_processed): + value = find_attr_value_('id', node) + if value is not None and 'id' not in already_processed: + already_processed.append('id') + self.id = value + value = find_attr_value_('value', node) + if value is not None and 'value' not in already_processed: + already_processed.append('value') + self.value = value + def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): + pass +# end class requires + class componentresourcefactoryref(GeneratedsSuper): @@ -3213,13 +3400,17 @@ def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): class hostcollocation(GeneratedsSuper): subclass = None superclass = None - def __init__(self, id_=None, name=None, componentplacement=None ): + def __init__(self, id_=None, name=None, componentplacement=None, usesdeviceref=None ): self.id_ = _cast(None, id_) self.name = _cast(None, name) if componentplacement is None: self.componentplacement = [] else: self.componentplacement = componentplacement + if usesdeviceref is None: + self.usesdeviceref = [] + else: + self.usesdeviceref = usesdeviceref def factory(*args_, **kwargs_): if hostcollocation.subclass: return hostcollocation.subclass(*args_, **kwargs_) @@ -3231,6 +3422,11 @@ def set_componentplacement(self, componentplacement): self.componentplacement = def add_componentplacement(self, value): self.componentplacement.append(value) def insert_componentplacement(self, index, value): self.componentplacement[index] = value componentplacementProp = property(get_componentplacement, set_componentplacement) + def get_usesdeviceref(self): return self.usesdeviceref + def set_usesdeviceref(self, usesdeviceref): self.usesdeviceref = usesdeviceref + def add_usesdeviceref(self, value): self.usesdeviceref.append(value) + def insert_usesdeviceref(self, index, value): self.usesdeviceref[index] = value + usesdevicerefProp = property(get_usesdeviceref, set_usesdeviceref) def get_id(self): return self.id_ def set_id(self, id): self.id_ = id idProp = property(get_id, set_id) @@ -3267,9 +3463,12 @@ def exportChildren(self, outfile, level, namespace_='', name_='hostcollocation', eol_ = '' for componentplacement_ in self.componentplacement: componentplacement_.export(outfile, level, namespace_, name_='componentplacement', pretty_print=pretty_print) + for usesdeviceref_ in self.usesdeviceref: + usesdeviceref_.export(outfile, level, namespace_, name_='usesdeviceref', pretty_print=pretty_print) def hasContent_(self): if ( - self.componentplacement + self.componentplacement or + self.usesdeviceref ): return True else: @@ -3301,6 +3500,17 @@ def exportLiteralChildren(self, outfile, level, name_): level -= 1 showIndent(outfile, level) outfile.write('],\n') + outfile.write('usesdeviceref=[\n') + level += 1 + for usesdeviceref_ in self.usesdeviceref: + showIndent(outfile, level) + outfile.write('model_.usesdeviceref(\n') + usesdeviceref_.exportLiteral(outfile, level) + showIndent(outfile, level) + outfile.write('),\n') + level -= 1 + showIndent(outfile, level) + outfile.write('],\n') def build(self, node): self.buildAttributes(node, node.attrib, []) @@ -3321,9 +3531,81 @@ def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): obj_ = componentplacement.factory() obj_.build(child_) self.componentplacement.append(obj_) + if nodeName_ == 'usesdeviceref': + obj_ = usesdeviceref.factory() + obj_.build(child_) + self.usesdeviceref.append(obj_) # end class hostcollocation +class usesdeviceref(GeneratedsSuper): + subclass = None + superclass = None + def __init__(self, refid=None): + self.refid = _cast(None, refid) + pass + def factory(*args_, **kwargs_): + if usesdeviceref.subclass: + return usesdeviceref.subclass(*args_, **kwargs_) + else: + return usesdeviceref(*args_, **kwargs_) + factory = staticmethod(factory) + def get_refid(self): return self.refid + def set_refid(self, refid): self.refid = refid + refidProp = property(get_refid, set_refid) + def export(self, outfile, level, namespace_='', name_='usesdeviceref', namespacedef_='', pretty_print=True): + if pretty_print: + eol_ = '\n' + else: + eol_ = '' + showIndent(outfile, level, pretty_print) + outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', )) + already_processed = [] + self.exportAttributes(outfile, level, already_processed, namespace_, name_='usesdeviceref') + if self.hasContent_(): + outfile.write('>%s' % (eol_, )) + self.exportChildren(outfile, level + 1, namespace_, name_, pretty_print=pretty_print) + outfile.write('%s' % (namespace_, name_, eol_)) + else: + outfile.write('/>%s' % (eol_, )) + def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='usesdeviceref'): + if self.refid is not None and 'refid' not in already_processed: + already_processed.append('refid') + outfile.write(' refid=%s' % (self.gds_format_string(quote_attrib(self.refid).encode(ExternalEncoding), input_name='refid'), )) + def exportChildren(self, outfile, level, namespace_='', name_='usesdeviceref', fromsubclass_=False, pretty_print=True): + pass + def hasContent_(self): + if ( + + ): + return True + else: + return False + def exportLiteral(self, outfile, level, name_='usesdeviceref'): + level += 1 + self.exportLiteralAttributes(outfile, level, [], name_) + if self.hasContent_(): + self.exportLiteralChildren(outfile, level, name_) + def exportLiteralAttributes(self, outfile, level, already_processed, name_): + if self.refid is not None and 'refid' not in already_processed: + already_processed.append('refid') + showIndent(outfile, level) + outfile.write('refid = "%s",\n' % (self.refid,)) + def exportLiteralChildren(self, outfile, level, name_): + pass + def build(self, node): + self.buildAttributes(node, node.attrib, []) + for child in node: + nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] + self.buildChildren(child, node, nodeName_) + def buildAttributes(self, node, attrs, already_processed): + value = find_attr_value_('refid', node) + if value is not None and 'refid' not in already_processed: + already_processed.append('refid') + self.refid = value + def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): + pass +# end class usesdeviceref class assemblycontroller(GeneratedsSuper): @@ -5012,6 +5294,7 @@ def main(): "connectinterface", "connections", "devicethatloadedthiscomponentref", + "devicerequires", "deviceusedbyapplication", "deviceusedbythiscomponentref", "domainfinder", @@ -5037,6 +5320,7 @@ def main(): "structvalue", "usesdevice", "usesdevicedependencies", + "usesdeviceref", "usesport", "values" ] diff --git a/redhawk/src/testing/sdr/parser_tests/deployerrequires.dcd.xml b/redhawk/src/testing/sdr/parser_tests/deployerrequires.dcd.xml new file mode 100644 index 000000000..140d8bf02 --- /dev/null +++ b/redhawk/src/testing/sdr/parser_tests/deployerrequires.dcd.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + test_GPP_green::GPP_1 + + + + + + + + + + diff --git a/redhawk/src/testing/sdr/parser_tests/devicerequires.sad.xml b/redhawk/src/testing/sdr/parser_tests/devicerequires.sad.xml new file mode 100644 index 000000000..9d39f68ea --- /dev/null +++ b/redhawk/src/testing/sdr/parser_tests/devicerequires.sad.xml @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + SimpleComponent_Red + + + + + + + + + + + + + SimpleComponent_Green + + + + + + + + + + + + + diff --git a/redhawk/src/testing/sdr/parser_tests/usesdeviceref.sad.xml b/redhawk/src/testing/sdr/parser_tests/usesdeviceref.sad.xml new file mode 100644 index 000000000..955ce1a42 --- /dev/null +++ b/redhawk/src/testing/sdr/parser_tests/usesdeviceref.sad.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + P1_1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/redhawk/src/testing/tests/test_07_PythonParsers.py b/redhawk/src/testing/tests/test_07_PythonParsers.py index 8bc649b70..500419e31 100644 --- a/redhawk/src/testing/tests/test_07_PythonParsers.py +++ b/redhawk/src/testing/tests/test_07_PythonParsers.py @@ -171,6 +171,110 @@ def test_SADParser(self): except OSError: pass + def test_SADParser_usesdeviceref(self): + sad = parsers.SADParser.parse("sdr/parser_tests/usesdeviceref.sad.xml") + self.assertEqual(sad.get_id(), "colloc_usesdev_1") + self.assertEqual(sad.get_name(), "colloc_usesdev") + self.assertEqual(len(sad.componentfiles.get_componentfile()), 1) + self.assertEqual(len(sad.partitioning.get_hostcollocation()), 1) + colloc=sad.partitioning.get_hostcollocation()[0] + self.assertEqual(len(colloc.get_componentplacement()),1) + comp_place =colloc.get_componentplacement()[0] + self.assertEqual(len(comp_place.get_componentinstantiation()),1) + comp_ci=comp_place.get_componentinstantiation()[0] + self.assertEqual(comp_ci.id_, "P1_1") + self.assertEqual(comp_ci.get_usagename(), "P1_1") + self.assertEqual(len(colloc.get_usesdeviceref()),1) + udev_ref =colloc.get_usesdeviceref()[0] + self.assertEqual(udev_ref.refid, "FrontEndTuner_1") + + # Verify that we can write the output and still be DTD valid + tmpfile = tempfile.mktemp() + try: + tmp = open(tmpfile, "w") + sad.export(tmp, 0) + tmp.close() + status = self._xmllint(tmpfile, "SAD") + self.assertEqual(status, 0, "Python parser did not emit DTD compliant XML") + finally: + try: + os.remove(tmpfile) + except OSError: + pass + + def test_SADParser_devicerequires(self): + sad = parsers.SADParser.parse("sdr/parser_tests/devicerequires.sad.xml") + self.assertEqual(sad.get_id(), "device_requires_multicolor") + self.assertEqual(sad.get_name(), "device_requires_multicolor") + self.assertEqual(len(sad.componentfiles.get_componentfile()), 1) + self.assertEqual(len(sad.partitioning.get_componentplacement()), 2) + comp_place=sad.partitioning.get_componentplacement()[0] + comp_in=comp_place.get_componentinstantiation()[0] + self.assertEqual(comp_place.componentfileref.refid, "SimpleComponent_SPD_1") + self.assertEqual(comp_in.id_, "SimpleComponent_Red") + self.assertEqual(comp_in.get_usagename(), "SimpleComponent_Red") + self.assertEqual(len(comp_in.devicerequires.get_requires()),2) + self.assertEqual(comp_in.devicerequires.get_requires()[0].id, "color") + self.assertEqual(comp_in.devicerequires.get_requires()[0].value, "RED") + self.assertEqual(comp_in.devicerequires.get_requires()[1].id, "rank") + self.assertEqual(comp_in.devicerequires.get_requires()[1].value, "15") + comp_place=sad.partitioning.get_componentplacement()[1] + comp_in=comp_place.get_componentinstantiation()[0] + self.assertEqual(comp_place.componentfileref.refid, "SimpleComponent_SPD_1") + self.assertEqual(comp_in.id_, "SimpleComponent_Green") + self.assertEqual(comp_in.get_usagename(), "SimpleComponent_Green") + self.assertEqual(len(comp_in.devicerequires.get_requires()),1) + self.assertEqual(comp_in.devicerequires.get_requires()[0].id, "color") + self.assertEqual(comp_in.devicerequires.get_requires()[0].value, "GREEN") + + + # Verify that we can write the output and still be DTD valid + tmpfile = tempfile.mktemp() + try: + tmp = open(tmpfile, "w") + sad.export(tmp, 0) + tmp.close() + status = self._xmllint(tmpfile, "SAD") + self.assertEqual(status, 0, "Python parser did not emit DTD compliant XML") + finally: + try: + os.remove(tmpfile) + except OSError: + pass + + def test_SADParser_loggingconfig(self): + sad = parsers.SADParser.parse("sdr/parser_tests/loggingconfig.sad.xml") + self.assertEqual(sad.get_id(), "device_requires_multicolor") + self.assertEqual(sad.get_name(), "device_requires_multicolor") + self.assertEqual(len(sad.componentfiles.get_componentfile()), 1) + self.assertEqual(len(sad.partitioning.get_componentplacement()), 2) + comp_place=sad.partitioning.get_componentplacement()[0] + comp_in=comp_place.get_componentinstantiation()[0] + self.assertEqual(comp_place.componentfileref.refid, "SimpleComponent_SPD_1") + self.assertEqual(comp_in.id_, "SimpleComponent_Red") + self.assertEqual(comp_in.get_usagename(), "SimpleComponent_Red") + self.assertEqual(comp_in.loggingconfig.level, "ERROR") + self.assertEqual(comp_in.loggingconfig.value, "path/to/my/log/file") + comp_place=sad.partitioning.get_componentplacement()[1] + comp_in=comp_place.get_componentinstantiation()[0] + self.assertEqual(comp_place.componentfileref.refid, "SimpleComponent_SPD_1") + self.assertEqual(comp_in.id_, "SimpleComponent_Green") + self.assertEqual(comp_in.get_usagename(), "SimpleComponent_Green") + self.assertEqual(comp_in.loggingconfig.value, "path/to/my/log/file2") + + # Verify that we can write the output and still be DTD valid + tmpfile = tempfile.mktemp() + try: + tmp = open(tmpfile, "w") + sad.export(tmp, 0) + tmp.close() + status = self._xmllint(tmpfile, "SAD") + self.assertEqual(status, 0, "Python parser did not emit DTD compliant XML") + finally: + try: + os.remove(tmpfile) + except OSError: + pass def test_SADParser_affinityconfig(self): sad = parsers.SADParser.parse("sdr/parser_tests/affinity.sad.xml") @@ -206,6 +310,36 @@ def test_SADParser_affinityconfig(self): except OSError: pass + def test_DCDParser_deployerrequires(self): + dcd = parsers.DCDParser.parse("sdr/parser_tests/deployerrequires.dcd.xml") + self.assertEqual(dcd.get_id(), "test_GPP_green") + self.assertEqual(dcd.get_name(), "test_GPP_green") + self.assertEqual(len(dcd.componentfiles.get_componentfile()), 1) + self.assertEqual(len(dcd.partitioning.get_componentplacement()), 1) + gpp=dcd.partitioning.get_componentplacement()[0] + gpp_ci=gpp.get_componentinstantiation()[0] + self.assertEqual(gpp.get_componentfileref().get_refid(), "GPP1_file_1") + self.assertEqual(gpp_ci.get_id(), "test_GPP_green::GPP_1") + self.assertEqual(gpp_ci.get_usagename(), "test_GPP_green::GPP_1") + self.assertEqual(len(gpp_ci.deployerrequires.get_requires()), 1) + self.assertEqual(gpp_ci.deployerrequires.get_requires()[0].id, "color") + self.assertEqual(gpp_ci.deployerrequires.get_requires()[0].value, "GREEN") + + # Verify that we can write the output and still be DTD valid + tmpfile = tempfile.mktemp() + try: + tmp = open(tmpfile, "w") + dcd.export(tmp, 0) + tmp.close() + status = self._xmllint(tmpfile, "DCD") + self.assertEqual(status, 0, "Python parser did not emit DTD compliant XML") + finally: + try: + os.remove(tmpfile) + except OSError: + pass + + def test_DCDParser_loggingconfig(self): dcd = parsers.DCDParser.parse("sdr/parser_tests/loggingconfig.dcd.xml") self.assertEqual(dcd.get_id(), "test_GPP_green") From 0b5d56189c18e5edf84d8cf82a13f76ecd7c2c1b Mon Sep 17 00:00:00 2001 From: Ryan Bauman Date: Mon, 5 Jun 2017 12:17:20 -0400 Subject: [PATCH 0806/1644] RELENG-593 - build packages for all 3 supported platforms; trigger tests pipeline as part of deployment --- .gitlab-ci.yml | 412 +++++++++++++++++++++++++++++-------------------- 1 file changed, 243 insertions(+), 169 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index e43900688..a9749bc71 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,223 +1,297 @@ variables: - REDHAWK_VERSION: '2.1.1' - FRONTEND_VERSION: '2.4.1' + rpm_release: "0.$CI_PIPELINE_ID" + specfile: $project.spec + other_repos: $yum_repo_url/redhawk-dependencies stages: - - build - - build-2 - - build-3 - - test - - deploy - - deploy-test + - package-redhawk-codegen + - package-bulkio-gpp + - package-burstio-fei + - deploy .rpmbuild: &rpmbuild - image: ${DOCKER_REGISTRY_URL}redhawk/buildenv:$PLATFORM - script: - - cd $PROJECT - - tar --transform "s,^,$PROJECT-$REDHAWK_VERSION/,S" -czf /root/rpmbuild/SOURCES/$PROJECT-$REDHAWK_VERSION.tar.gz * - - yum install -y ../*.rpm || true - - yum-builddep -y $PROJECT.spec - - bash -lc 'rpmbuild -bb $PROJECT.spec' - - cp -rv /root/rpmbuild/RPMS/*/*.rpm .. - -.core_rpmbuild: &core_rpmbuild - image: ${DOCKER_REGISTRY_URL}redhawk/buildenv:$PLATFORM - stage: build + image: docker:latest + tags: + - dind script: - - cd $PROJECT - - tar --transform "s,^,$PROJECT-$REDHAWK_VERSION/,S" -czf /root/rpmbuild/SOURCES/$PROJECT-$REDHAWK_VERSION.tar.gz * - - yum-builddep -y src/releng/redhawk.spec - - rpmbuild -bb src/releng/redhawk.spec - - cp -rv /root/rpmbuild/RPMS/*/*.rpm .. + # Ensure newest version of FROM image + - docker pull ${docker_registry}rpmbuild:${dist}-${arch}-onbuild + # Use RPM release from specfile if this is a tag + - if [ -n "$CI_COMMIT_TAG" ]; then rpm_release=""; fi + - if [ -f output/repo.tar.gz ]; then cd output; tar xvf repo.tar.gz; cd -; cp -r output $project; fi + - cd $project + - printf "FROM ${docker_registry}rpmbuild:${dist}-${arch}-onbuild" > Dockerfile + # Don't build redhawk tests as part of rpmbuild to save time + - if [ "$project" == "redhawk" ]; then sed -i 's|testing||' src/Makefile.am; fi + - proj_lower=$(echo $project | tr '[:upper:]' '[:lower:]') + - docker build --tag=${docker_registry}redhawk-rpmbuild:$proj_lower-$CI_COMMIT_SHA-${dist}-${arch} + --build-arg "project=$project" + --build-arg "target=$arch" + --build-arg "spec_file=$specfile" + --build-arg "rpm_release=$rpm_release" + --build-arg "other_repos=$other_repos/$dist/$arch" + --build-arg "local_repo=$local_repo" . + # Create a yum repository from the packages we just built and any packages we've built in a previous stage + - id=$(docker create -it ${docker_registry}redhawk-rpmbuild:$proj_lower-$CI_COMMIT_SHA-$dist-$arch bash -lc 'mkdir -p /tmp/repo; + for file in `find /usr/src/yum /root/rpmbuild/RPMS -name '*.rpm'`; do + cp -v $file /tmp/repo; + done; + cd /tmp/repo; + createrepo .; + tar czf repo.tar.gz *') + - docker start -a $id + #Cleanup any previous output we've inherited + - cd $CI_PROJECT_DIR + - rm -rf output && mkdir output + - docker cp $id:/tmp/repo/repo.tar.gz output/repo.tar.gz + - docker rm -f $id artifacts: + name: $CI_JOB_NAME paths: - - redhawk*.rpm + - output/ + expire_in: 3 days -.frontend_rpmbuild: &frontend_rpmbuild - image: ${DOCKER_REGISTRY_URL}redhawk/buildenv:$PLATFORM - stage: build-3 +.deploy-common: &deploy-common + image: centos:7 + stage: deploy + dependencies: [] script: - - cd $PROJECT - - tar --transform "s,^,$PROJECT-$FRONTEND_VERSION/,S" -czf /root/rpmbuild/SOURCES/$PROJECT-$FRONTEND_VERSION.tar.gz * - - yum install -y ../*.rpm || true - - yum-builddep -y $PROJECT.spec - - bash -lc 'rpmbuild -bb $PROJECT.spec' - - cp -rv /root/rpmbuild/RPMS/*/*.rpm .. - artifacts: - paths: - - frontend*.rpm + - if [ -n "$jenkins_url" ]; then + curl --insecure -X POST $jenkins_url/job/$jenkins_job/buildWithParameters?pipeline_id=$CI_PIPELINE_ID --user $jenkins_user:$jenkins_api_token; + fi -core-el6: +redhawk:el6-i386: + stage: package-redhawk-codegen variables: - PROJECT: 'redhawk' - PLATFORM: 'el6' - <<: *core_rpmbuild + dist: el6 + arch: i686 + project: redhawk + specfile: src/releng/redhawk.spec + local_repo: "" + <<: *rpmbuild -core-el7: +redhawk-codegen:el6-i386: + stage: package-redhawk-codegen variables: - PROJECT: 'redhawk' - PLATFORM: 'el7' - <<: *core_rpmbuild + dist: el6 + arch: i686 + project: redhawk-codegen + local_repo: "" + <<: *rpmbuild -codegen-el6: +bulkio:el6-i386: + stage: package-bulkio-gpp + dependencies: + - redhawk:el6-i386 variables: - PROJECT: 'redhawk-codegen' - PLATFORM: 'el6' - stage: build + dist: el6 + arch: i686 + project: bulkioInterfaces + local_repo: output <<: *rpmbuild - artifacts: - paths: - - redhawk*.rpm -codegen-el7: +gpp:el6-i386: + stage: package-bulkio-gpp + dependencies: + - redhawk:el6-i386 variables: - PROJECT: 'redhawk-codegen' - PLATFORM: 'el7' - stage: build + dist: el6 + arch: i686 + project: GPP + local_repo: output <<: *rpmbuild - artifacts: - paths: - - redhawk*.rpm -bulkio-el6: +burstio:el6-i386: + stage: package-burstio-fei + dependencies: + - bulkio:el6-i386 variables: - PROJECT: 'bulkioInterfaces' - PLATFORM: 'el6' - stage: build-2 + dist: el6 + arch: i686 + project: burstioInterfaces + local_repo: output + <<: *rpmbuild + +frontend:el6-i386: + stage: package-burstio-fei dependencies: - - core-el6 + - bulkio:el6-i386 + variables: + dist: el6 + arch: i686 + project: frontendInterfaces + version: $fei_version + local_repo: output <<: *rpmbuild - artifacts: - paths: - - bulkio*.rpm -bulkio-el7: +redhawk:el6: + stage: package-redhawk-codegen variables: - PROJECT: 'bulkioInterfaces' - PLATFORM: 'el7' - stage: build-2 - dependencies: - - core-el7 + dist: el6 + arch: x86_64 + project: redhawk + specfile: src/releng/redhawk.spec + local_repo: "" <<: *rpmbuild - artifacts: - paths: - - bulkio*.rpm -GPP-el6: +redhawk-codegen:el6: + stage: package-redhawk-codegen variables: - PROJECT: 'GPP' - PLATFORM: 'el6' - stage: build-2 - dependencies: - - core-el6 + dist: el6 + arch: x86_64 + project: redhawk-codegen + local_repo: "" <<: *rpmbuild - artifacts: - paths: - - GPP*.rpm -GPP-el7: +bulkio:el6: + stage: package-bulkio-gpp + dependencies: + - redhawk:el6 variables: - PROJECT: 'GPP' - PLATFORM: 'el7' - stage: build-2 + dist: el6 + arch: x86_64 + project: bulkioInterfaces + local_repo: output + <<: *rpmbuild + +gpp:el6: + stage: package-bulkio-gpp dependencies: - - core-el7 + - redhawk:el6 + variables: + dist: el6 + arch: x86_64 + project: GPP + local_repo: output <<: *rpmbuild - artifacts: - paths: - - GPP*.rpm -burstio-el6: +burstio:el6: + stage: package-burstio-fei + dependencies: + - bulkio:el6 variables: - PROJECT: 'burstioInterfaces' - PLATFORM: 'el6' - stage: build-3 + dist: el6 + arch: x86_64 + project: burstioInterfaces + local_repo: output + <<: *rpmbuild + +frontend:el6: + stage: package-burstio-fei dependencies: - - core-el6 - - bulkio-el6 + - bulkio:el6 + variables: + dist: el6 + arch: x86_64 + project: frontendInterfaces + version: $fei_version + local_repo: output <<: *rpmbuild - artifacts: - paths: - - burstio*.rpm -burstio-el7: +redhawk:el7: + stage: package-redhawk-codegen variables: - PROJECT: 'burstioInterfaces' - PLATFORM: 'el7' - stage: build-3 - dependencies: - - core-el7 - - bulkio-el7 + dist: el7 + arch: x86_64 + project: redhawk + specfile: src/releng/redhawk.spec + local_repo: "" <<: *rpmbuild - artifacts: - paths: - - burstio*.rpm -frontend-el6: +redhawk-codegen:el7: + stage: package-redhawk-codegen variables: - PROJECT: 'frontendInterfaces' - PLATFORM: 'el6' + dist: el7 + arch: x86_64 + project: redhawk-codegen + local_repo: "" + <<: *rpmbuild + +bulkio:el7: + stage: package-bulkio-gpp dependencies: - - core-el6 - - bulkio-el6 - <<: *frontend_rpmbuild + - redhawk:el7 + variables: + dist: el7 + arch: x86_64 + project: bulkioInterfaces + local_repo: output + <<: *rpmbuild -frontend-el7: +gpp:el7: + stage: package-bulkio-gpp + dependencies: + - redhawk:el7 variables: - PROJECT: 'frontendInterfaces' - PLATFORM: 'el7' + dist: el7 + arch: x86_64 + project: GPP + local_repo: output + <<: *rpmbuild + +burstio:el7: + stage: package-burstio-fei dependencies: - - core-el7 - - bulkio-el7 - <<: *frontend_rpmbuild + - bulkio:el7 + variables: + dist: el7 + arch: x86_64 + project: burstioInterfaces + local_repo: output + <<: *rpmbuild -test:install:el6: - image: centos:6 - stage: test +frontend:el7: + stage: package-burstio-fei dependencies: - - core-el6 - - bulkio-el6 - - burstio-el6 - - GPP-el6 - - frontend-el6 - - codegen-el6 - script: - - printf "[redhawk-deps]\nname=redhawk-deps\nbaseurl=$REDHAWK_DEPS_URL/el6/x86_64\nenabled=1\ngpgcheck=0" > /etc/yum.repos.d/redhawk-deps.repo - - yum install -y epel-release - - yum install -y *.rpm + - bulkio:el7 + variables: + dist: el7 + arch: x86_64 + project: frontendInterfaces + local_repo: output + <<: *rpmbuild + +#Trigger a Jenkins job to aggregate artifacts there +deploy: + variables: + jenkins_job: REDHAWK-core-framework-$CI_COMMIT_REF_NAME + <<: *deploy-common + only: + - branches + +deploy-release: + variables: + redhawk_version: '2.1.1' + jenkins_job: $redhawk_version/job/REDHAWK-core-framework-$redhawk_version + <<: *deploy-common + only: + - tags -deploy:el6: - image: ${DOCKER_REGISTRY_URL}redhawk/deploy +#Trigger separate tests pipeline +test-trigger: + image: centos:7 stage: deploy - tags: - - deployment - dependencies: - - core-el6 - - bulkio-el6 - - burstio-el6 - - GPP-el6 - - frontend-el6 - - codegen-el6 + dependencies: [] script: - - mkdir output - - cp *.rpm output - - cd output - - createrepo . - - eval "$(ssh-agent -s)" - - ssh-add - - rsync -avz --delete * $PUBLISH_URL:$PUBLISH_PATH/$CI_BUILD_REF_NAME/el6/x86_64/ - artifacts: - paths: - - output/*.rpm - - output/**/* + - curl --insecure -X POST -F ref=$CI_COMMIT_REF_NAME + -F token=$test_token + -F "variables[triggering_ref]=$CI_COMMIT_SHA" + -F "variables[triggering_ref_name]=$CI_COMMIT_REF_NAME" + $test_url + only: + - branches -test:deployed:el6: - image: centos:6 - stage: deploy-test - dependencies: - - deploy:el6 +test-trigger:release: + image: centos:7 + stage: deploy + dependencies: [] + variables: + redhawk_version: '2.1.1' script: - - printf "[redhawk-deps]\nname=redhawk-deps\nbaseurl=$REDHAWK_DEPS_URL/el6/x86_64\nenabled=1\ngpgcheck=0" > /etc/yum.repos.d/redhawk-deps.repo - - printf "[redhawk]\nname=redhawk\nbaseurl=$PUBLISH_WEB_URL/$CI_BUILD_REF_NAME/el6/x86_64/\nenabled=1\ngpgcheck=0" > /etc/yum.repos.d/redhawk.repo - - yum install -y epel-release - - yum install -y redhawk-devel redhawk-* bulkio* burstio* frontend* GPP* + - curl --insecure -X POST -F ref=$redhawk_version + -F token=$test_token + -F "variables[triggering_ref]=$CI_COMMIT_SHA" + -F "variables[triggering_ref_name]=$CI_COMMIT_REF_NAME" + $test_url + only: + - tags From 9b1ffeba9d84fbc8cf28336f363846edf646ee6a Mon Sep 17 00:00:00 2001 From: Max Robert Date: Mon, 5 Jun 2017 16:38:59 -0400 Subject: [PATCH 0807/1644] Refs CF-1761. Add per-host collocation reservations to the dtd. Also, make sure that the number of allowed children elements is kept consistent --- redhawk/src/xml/dtd/softwareassembly.dtd | 6 ++++ redhawk/src/xml/xsd/sad.xsd | 39 ++++++++++++++++++++---- 2 files changed, 39 insertions(+), 6 deletions(-) diff --git a/redhawk/src/xml/dtd/softwareassembly.dtd b/redhawk/src/xml/dtd/softwareassembly.dtd index b65fa6ace..6323a718b 100644 --- a/redhawk/src/xml/dtd/softwareassembly.dtd +++ b/redhawk/src/xml/dtd/softwareassembly.dtd @@ -193,6 +193,7 @@ with this program. If not, see http://www.gnu.org/licenses/. + + + diff --git a/redhawk/src/xml/xsd/sad.xsd b/redhawk/src/xml/xsd/sad.xsd index c31b59aef..447515115 100644 --- a/redhawk/src/xml/xsd/sad.xsd +++ b/redhawk/src/xml/xsd/sad.xsd @@ -207,15 +207,42 @@ with this program. If not, see http://www.gnu.org/licenses/. - - + + + + + + + + + + + + + + + + + - - - - + + + + + + + + From 9a550628da73a54787b9fe7994bea8d854dfaa56 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Mon, 5 Jun 2017 16:42:01 -0400 Subject: [PATCH 0808/1644] Removed commented-out code --- redhawk/src/xml/xsd/sad.xsd | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/redhawk/src/xml/xsd/sad.xsd b/redhawk/src/xml/xsd/sad.xsd index 447515115..bb8985f87 100644 --- a/redhawk/src/xml/xsd/sad.xsd +++ b/redhawk/src/xml/xsd/sad.xsd @@ -234,16 +234,6 @@ with this program. If not, see http://www.gnu.org/licenses/. - - From bf18afd9f981fe391bed872449a9d6d24e8e1512 Mon Sep 17 00:00:00 2001 From: Ryan Bauman Date: Mon, 5 Jun 2017 18:09:59 -0400 Subject: [PATCH 0809/1644] RELENG-593 - correct target arch build-arg --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index a9749bc71..9db217c3e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -26,7 +26,7 @@ stages: - proj_lower=$(echo $project | tr '[:upper:]' '[:lower:]') - docker build --tag=${docker_registry}redhawk-rpmbuild:$proj_lower-$CI_COMMIT_SHA-${dist}-${arch} --build-arg "project=$project" - --build-arg "target=$arch" + --build-arg "arch=$arch" --build-arg "spec_file=$specfile" --build-arg "rpm_release=$rpm_release" --build-arg "other_repos=$other_repos/$dist/$arch" From 9926bc074f830ed186ce559b467404aa08c28c1d Mon Sep 17 00:00:00 2001 From: Max Robert Date: Tue, 6 Jun 2017 10:39:17 -0400 Subject: [PATCH 0810/1644] Refs CF-1761. Added missing test file --- .../test_wav_res/test_wav_res.sad.xml | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 redhawk/src/testing/sdr/dom/waveforms/test_wav_res/test_wav_res.sad.xml diff --git a/redhawk/src/testing/sdr/dom/waveforms/test_wav_res/test_wav_res.sad.xml b/redhawk/src/testing/sdr/dom/waveforms/test_wav_res/test_wav_res.sad.xml new file mode 100644 index 000000000..97033a910 --- /dev/null +++ b/redhawk/src/testing/sdr/dom/waveforms/test_wav_res/test_wav_res.sad.xml @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + NOOP_ADDITIONAL_DEP_1 + + + + + + + + + NOOP_ROLL_2 + + + + + + + + + + + + From 566501c8a7f466481d3ca8e34d11daf7ae38cf86 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Tue, 6 Jun 2017 13:15:56 -0400 Subject: [PATCH 0811/1644] Refs CF-1761. Changed element order in test xml files --- .../waveforms/wav_floor_w/wav_floor_w.sad.xml | 2 +- .../wav_one_floor_w/wav_one_floor_w.sad.xml | 2 +- .../wav_two_floor_w/wav_two_floor_w.sad.xml | 4 ++-- GPP/tests/test_GPP.py | 16 ++++++++-------- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/GPP/tests/sdr/dom/waveforms/wav_floor_w/wav_floor_w.sad.xml b/GPP/tests/sdr/dom/waveforms/wav_floor_w/wav_floor_w.sad.xml index c2034961f..870949d32 100644 --- a/GPP/tests/sdr/dom/waveforms/wav_floor_w/wav_floor_w.sad.xml +++ b/GPP/tests/sdr/dom/waveforms/wav_floor_w/wav_floor_w.sad.xml @@ -27,7 +27,6 @@ with this program. If not, see http://www.gnu.org/licenses/. - @@ -46,6 +45,7 @@ with this program. If not, see http://www.gnu.org/licenses/. + diff --git a/GPP/tests/sdr/dom/waveforms/wav_one_floor_w/wav_one_floor_w.sad.xml b/GPP/tests/sdr/dom/waveforms/wav_one_floor_w/wav_one_floor_w.sad.xml index d13020720..b96a91939 100644 --- a/GPP/tests/sdr/dom/waveforms/wav_one_floor_w/wav_one_floor_w.sad.xml +++ b/GPP/tests/sdr/dom/waveforms/wav_one_floor_w/wav_one_floor_w.sad.xml @@ -27,7 +27,6 @@ with this program. If not, see http://www.gnu.org/licenses/. - @@ -37,6 +36,7 @@ with this program. If not, see http://www.gnu.org/licenses/. + diff --git a/GPP/tests/sdr/dom/waveforms/wav_two_floor_w/wav_two_floor_w.sad.xml b/GPP/tests/sdr/dom/waveforms/wav_two_floor_w/wav_two_floor_w.sad.xml index 4b7b8d75d..ae4e537fe 100644 --- a/GPP/tests/sdr/dom/waveforms/wav_two_floor_w/wav_two_floor_w.sad.xml +++ b/GPP/tests/sdr/dom/waveforms/wav_two_floor_w/wav_two_floor_w.sad.xml @@ -27,7 +27,6 @@ with this program. If not, see http://www.gnu.org/licenses/. - @@ -37,9 +36,9 @@ with this program. If not, see http://www.gnu.org/licenses/. + - @@ -49,6 +48,7 @@ with this program. If not, see http://www.gnu.org/licenses/. + diff --git a/GPP/tests/test_GPP.py b/GPP/tests/test_GPP.py index d1492cbe4..6bd8b8b57 100755 --- a/GPP/tests/test_GPP.py +++ b/GPP/tests/test_GPP.py @@ -1549,7 +1549,7 @@ def testSystemReservation(self): extra_reservation = 1 _value=any.to_any(extra_reservation) _value._t=CORBA.TC_double - app_1=self.dom.createApplication('/waveforms/busy_w/busy_w.sad.xml','busy_w',[CF.DataType(id='SPECIALIZED_CPU_RESERVATION',value=any.to_any([CF.DataType(id='busy_comp_1',value=any.to_any(_value))]))]) + app_1=self.dom.createApplication('/waveforms/busy_w/busy_w.sad.xml','busy_w',[CF.DataType(id='SPECIALIZED_CPU_RESERVATION',value=any.to_any([CF.DataType(id='busy_comp_1',value=_value)]))]) time.sleep(wait_amount) base_util = self.dom.devMgrs[0].devs[0].utilization[0] @@ -1662,7 +1662,7 @@ def testAppReservation(self): extra_reservation = 3 _value=any.to_any(extra_reservation) _value._t=CORBA.TC_double - self.assertRaises(CF.ApplicationFactory.CreateApplicationError, self.dom.createApplication, '/waveforms/wav_floor_w/wav_floor_w.sad.xml','busy_w',[CF.DataType(id='SPECIALIZED_CPU_RESERVATION',value=any.to_any([CF.DataType(id='busy_comp_1',value=any.to_any(_value))]))]) + self.assertRaises(CF.ApplicationFactory.CreateApplicationError, self.dom.createApplication, '/waveforms/wav_floor_w/wav_floor_w.sad.xml','busy_w',[CF.DataType(id='SPECIALIZED_CPU_RESERVATION',value=any.to_any([CF.DataType(id='busy_comp_1',value=_value)]))]) app_1=self.dom.createApplication('/waveforms/wav_floor_w/wav_floor_w.sad.xml','busy_w',[]) time.sleep(wait_amount) self._verifyReservations(extra_reservation, app_1, wait_amount) @@ -1700,7 +1700,7 @@ def testAppOverloadGenericReservation(self): extra_reservation = 4 _value=any.to_any(extra_reservation) _value._t=CORBA.TC_double - app_1=self.dom.createApplication('/waveforms/wav_floor_w/wav_floor_w.sad.xml','busy_w',[CF.DataType(id='SPECIALIZED_CPU_RESERVATION',value=any.to_any([CF.DataType(id='',value=any.to_any(_value))]))]) + app_1=self.dom.createApplication('/waveforms/wav_floor_w/wav_floor_w.sad.xml','busy_w',[CF.DataType(id='SPECIALIZED_CPU_RESERVATION',value=any.to_any([CF.DataType(id='',value=_value)]))]) time.sleep(wait_amount) self._verifyReservations(extra_reservation, app_1, wait_amount) @@ -1730,8 +1730,8 @@ def testAppOverloadSpecificReservation(self): extra_reservation = 4 _value=any.to_any(extra_reservation) _value._t=CORBA.TC_double - self.assertRaises(CF.ApplicationFactory.CreateApplicationError, self.dom.createApplication, '/waveforms/wav_floor_w/wav_floor_w.sad.xml','busy_w',[CF.DataType(id='SPECIALIZED_CPU_RESERVATION',value=any.to_any([CF.DataType(id='COLLOC_SET1',value=any.to_any(_value))]))]) - app_1=self.dom.createApplication('/waveforms/wav_floor_w/wav_floor_w.sad.xml','busy_w',[CF.DataType(id='SPECIALIZED_CPU_RESERVATION',value=any.to_any([CF.DataType(id='ID_TEST_SET1',value=any.to_any(_value))]))]) + self.assertRaises(CF.ApplicationFactory.CreateApplicationError, self.dom.createApplication, '/waveforms/wav_floor_w/wav_floor_w.sad.xml','busy_w',[CF.DataType(id='SPECIALIZED_CPU_RESERVATION',value=any.to_any([CF.DataType(id='COLLOC_SET1',value=_value)]))]) + app_1=self.dom.createApplication('/waveforms/wav_floor_w/wav_floor_w.sad.xml','busy_w',[CF.DataType(id='SPECIALIZED_CPU_RESERVATION',value=any.to_any([CF.DataType(id='ID_TEST_SET1',value=_value)]))]) time.sleep(wait_amount) self._verifyReservations(extra_reservation, app_1, wait_amount) @@ -1761,8 +1761,8 @@ def testAppOverloadTwoSpecificReservation(self): extra_reservation = 4 _value=any.to_any(extra_reservation/2) _value._t=CORBA.TC_double - self.assertRaises(CF.ApplicationFactory.CreateApplicationError, self.dom.createApplication, '/waveforms/wav_floor_w/wav_floor_w.sad.xml','busy_w',[CF.DataType(id='SPECIALIZED_CPU_RESERVATION',value=any.to_any([CF.DataType(id='COLLOC_SET1',value=any.to_any(_value)),CF.DataType(id='ID_TEST_SET2',value=any.to_any(_value))]))]) - app_1=self.dom.createApplication('/waveforms/wav_two_floor_w/wav_two_floor_w.sad.xml','busy_w',[CF.DataType(id='SPECIALIZED_CPU_RESERVATION',value=any.to_any([CF.DataType(id='ID_TEST_SET1',value=any.to_any(_value)),CF.DataType(id='ID_TEST_SET2',value=any.to_any(_value))]))]) + self.assertRaises(CF.ApplicationFactory.CreateApplicationError, self.dom.createApplication, '/waveforms/wav_floor_w/wav_floor_w.sad.xml','busy_w',[CF.DataType(id='SPECIALIZED_CPU_RESERVATION',value=any.to_any([CF.DataType(id='COLLOC_SET1',value=any.to_any(_value)),CF.DataType(id='ID_TEST_SET2',value=_value)]))]) + app_1=self.dom.createApplication('/waveforms/wav_two_floor_w/wav_two_floor_w.sad.xml','busy_w',[CF.DataType(id='SPECIALIZED_CPU_RESERVATION',value=any.to_any([CF.DataType(id='ID_TEST_SET1',value=any.to_any(_value)),CF.DataType(id='ID_TEST_SET2',value=_value)]))]) time.sleep(wait_amount) self._verifyReservations(extra_reservation, app_1, wait_amount) @@ -1792,7 +1792,7 @@ def testAppOverloadOneSpecificReservation(self): extra_reservation = 4 _value=any.to_any(extra_reservation/2) _value._t=CORBA.TC_double - app_1=self.dom.createApplication('/waveforms/wav_one_floor_w/wav_one_floor_w.sad.xml','busy_w',[CF.DataType(id='SPECIALIZED_CPU_RESERVATION',value=any.to_any([CF.DataType(id='ID_TEST_SET1',value=any.to_any(_value)),CF.DataType(id='ID_TEST_SET2',value=any.to_any(_value))]))]) + app_1=self.dom.createApplication('/waveforms/wav_one_floor_w/wav_one_floor_w.sad.xml','busy_w',[CF.DataType(id='SPECIALIZED_CPU_RESERVATION',value=any.to_any([CF.DataType(id='ID_TEST_SET1',value=any.to_any(_value)),CF.DataType(id='ID_TEST_SET2',value=_value)]))]) time.sleep(wait_amount) self._verifyReservations(extra_reservation, app_1, wait_amount) From 710d9a2746c4e1e451dbf2ef23d24fbe139505f0 Mon Sep 17 00:00:00 2001 From: 8530 <8530@vm-131.vsi-corp.com> Date: Wed, 7 Jun 2017 11:13:16 -0400 Subject: [PATCH 0812/1644] added debug option to kickDomain for both domain and device managers, tracking processes for cleanup, added set log level to domain manager, CF-1765 --- .../framework/python/ossie/logger/__init__.py | 24 ++ .../python/ossie/utils/redhawk/base.py | 91 +++++- .../python/ossie/utils/redhawk/core.py | 47 ++- .../control/sdr/dommgr/DomainManager_impl.cpp | 4 +- .../control/sdr/dommgr/DomainManager_impl.h | 3 +- redhawk/src/control/sdr/dommgr/main.cpp | 51 +--- redhawk/src/idl/ossie/CF/cf.idl | 2 +- .../src/testing/_unitTestHelpers/scatest.py | 24 ++ .../sdr/dom/logcfg/log4j.kickdomain.cfg | 21 ++ .../testing/tests/test_13_RedhawkModule.py | 281 +++++++++++++++++- 10 files changed, 489 insertions(+), 59 deletions(-) create mode 100644 redhawk/src/testing/sdr/dom/logcfg/log4j.kickdomain.cfg diff --git a/redhawk/src/base/framework/python/ossie/logger/__init__.py b/redhawk/src/base/framework/python/ossie/logger/__init__.py index 2979ca644..c20501898 100644 --- a/redhawk/src/base/framework/python/ossie/logger/__init__.py +++ b/redhawk/src/base/framework/python/ossie/logger/__init__.py @@ -251,6 +251,30 @@ def ConvertToLog4Level( newLevel ): return level + +def ConvertLevelNameToDebugLevel( level_name ): + if level_name == "OFF" : return 0 + if level_name == "FATAL" : return 0 + if level_name == "ERROR" : return 1 + if level_name == "WARN" : return 2 + if level_name == "INFO" : return 3 + if level_name == "DEBUG" : return 4 + if level_name == "TRACE": return 5 + if level_name == "ALL" : return 5 + return 3 + +def ConvertLevelNameToCFLevel( level_name ): + if level_name == "OFF" : return CF.LogLevels.OFF + if level_name == "FATAL" : return CF.LogLevels.FATAL + if level_name == "ERROR" : return CF.LogLevels.ERROR + if level_name == "WARN" : return CF.LogLevels.WARN + if level_name == "INFO" : return CF.LogLevels.INFO + if level_name == "DEBUG" : return CF.LogLevels.DEBUG + if level_name == "TRACE": return CF.LogLevels.TRACE + if level_name == "ALL" : return CF.LogLevels.ALL + return CF.LogLevels.INFO + + def SupportedCFLevel( newLevel ): level = True if newLevel != CF.LogLevels.OFF and \ diff --git a/redhawk/src/base/framework/python/ossie/utils/redhawk/base.py b/redhawk/src/base/framework/python/ossie/utils/redhawk/base.py index 3380476b4..714f1d8c0 100644 --- a/redhawk/src/base/framework/python/ossie/utils/redhawk/base.py +++ b/redhawk/src/base/framework/python/ossie/utils/redhawk/base.py @@ -27,30 +27,70 @@ from ossie.cf import CF as _CF import ossie.utils as _utils from ossie.utils.sca import importIDL as _importIDL +from ossie.logger import ConvertLevelNameToDebugLevel import atexit +import signal as _signal +import time as _time +import traceback class _envContainer(object): - def __init__(self, domain, stdout): - self.domain = int(domain) + def __init__(self, process, stdout): + self.process = process self.stdout = stdout +def __waitTermination( process, timeout=5.0, pause=0.1): + while process and process.poll() is None and timeout > 0.0: + timeout -= pause + _time.sleep(pause) + return process.poll() != None + +def __terminate_process( process, signals=(_signal.SIGINT, _signal.SIGTERM, _signal.SIGKILL) ): + if process and process.poll() != None: + return + try: + for sig in signals: + _os.kill(process.pid, sig) + if __waitTermination(process): + break + process.wait() + except OSError, e: + pass + finally: + pass + def _cleanup_domain(): try: - _os.kill(globals()['currentdomain'].domain,2) + if globals().has_key('currentdomain'): + __terminate_process( globals()['currentdomain'].process) + x = globals().pop('currentdomain') + if x : del x except: + traceback.print_exc() pass + if globals().has_key('currentdevmgrs'): + for x in globals()['currentdevmgrs']: + try: + __terminate_process(x.process) + except: + traceback.print_exc() + pass + x = globals().pop('currentdevmgrs') + if x : del x atexit.register(_cleanup_domain) -def kickDomain(domain_name=None, kick_device_managers=True, device_managers=[], detached=False, sdrroot=None, stdout=None, logfile=None): +def kickDomain(domain_name=None, kick_device_managers=True, device_managers=[], detached=False, sdrroot=None, stdout=None, logfile=None, debug_level=None, device_managers_debug_levels=[]): """Kick-start a REDHAWK domain. domain_name: the name that should be used kick_device_managers: one or more Device Managers should be automatically started device_managers: if kick_device_managers set to True, list of Device Managers to start. If the list is empty, then start all Device Managers in - $SDRROOT/dev/nodes + $SDRROOT/dev/nodes. List can be node names i.e. GPP_node or absolute path to DCD files detached: determine whether the life cycle of the started Domain and Device Managers should follow the lifecycle of the current Python session sdrroot: use this sdr root. If set to None, then use $SDRROOT stdout: filename where stdout should be redirected. None sends stdout to /dev/null + debug_level: debug level to pass on command line: FATAL, ERROR, WARN, INFO, DEBUG, TRACE + device_managers_debug_levels = list of debug levels to pass on command line with corresponding device_managers + """ if sdrroot == None: @@ -66,6 +106,10 @@ def kickDomain(domain_name=None, kick_device_managers=True, device_managers=[], if logfile: args.append('-logcfgfile') args.append(logfile) + + if debug_level: + args.append('-debug') + args.append(str(ConvertLevelNameToDebugLevel(debug_level))) if domain_name != None: args.append('--domainname') @@ -102,9 +146,10 @@ def kickDomain(domain_name=None, kick_device_managers=True, device_managers=[], if globals().has_key('currentdomain'): globals()['currentdomain'] = None - globals()['currentdomain'] = _envContainer(sp.pid, stdout_fp) + globals()['currentdomain'] = _envContainer(sp, stdout_fp) if kick_device_managers: + dm_procs=[] if len(device_managers) == 0: base = sdrroot + '/dev/nodes' for (directory,sub,files) in _os.walk(base): @@ -117,6 +162,26 @@ def kickDomain(domain_name=None, kick_device_managers=True, device_managers=[], break if foundDCD: device_managers.append(directory[len(sdrroot)+4:]+'/'+filename) + else: + dm_list=[] + for dm in device_managers: + base = sdrroot + '/dev/nodes' + fname = dm + if dm.startswith("/") == False: + fname = base + '/' + dm + + try: + if fname.endswith(".dcd.xml") == False: + fname = fname + "/DeviceManager.dcd.xml" + f=open(fname) + dm_list.append(fname) + f.close() + except: + #traceback.print_exc() + print "Unable to locate DCD file for :" + dm + " file: " + fname + device_managers = dm_list + + idx=0 for device_manager in device_managers: args = ['nodeBooter'] args.append('-d') @@ -128,7 +193,21 @@ def kickDomain(domain_name=None, kick_device_managers=True, device_managers=[], if logfile: args.append('-logcfgfile') args.append(logfile) + if device_managers_debug_levels and len(device_managers_debug_levels) > 0 : + dlevel = None + if idx < len(device_managers_debug_levels): + dlevel = device_managers_debug_levels[idx] + if dlevel: + args.append('-debug') + args.append(str(ConvertLevelNameToDebugLevel(dlevel))) + idx = idx + 1 sp = _utils.Popen(args, executable=None, cwd=_os.getcwd(), close_fds=True, stdin=_devnull, stdout=stdout_fp, preexec_fn=_os.setpgrp) + dm_procs.append( _envContainer(sp, stdout_fp) ) + + if globals().has_key('currentdevmgrs'): + globals()['currentdevmgrs'].append(dm_procs) + else: + globals()['currentdevmgrs'] = dm_procs dom = attach(domain_name) diff --git a/redhawk/src/base/framework/python/ossie/utils/redhawk/core.py b/redhawk/src/base/framework/python/ossie/utils/redhawk/core.py index cd9db8c8c..81aa421be 100644 --- a/redhawk/src/base/framework/python/ossie/utils/redhawk/core.py +++ b/redhawk/src/base/framework/python/ossie/utils/redhawk/core.py @@ -2003,7 +2003,7 @@ def getEventChannelMgr(self): except: raise return self.__eventChannelMgr - + def _get_allocationMgr(self): if self.ref and self.__allocationMgr == None : try: @@ -2028,6 +2028,51 @@ def _get_eventChannelMgr(self): raise return self.__eventChannelMgr + def _get_log_level(self): + ret=None + if self.ref : + try: + ret=self.ref._get_log_level() + except: + raise + return ret + + def _set_log_level(self, cf_log_lvl ): + if self.ref : + try: + self.ref._set_log_level(cf_log_lvl) + except: + raise + + def getLogConfig(self): + if self.ref : + try: + return self.ref.getLogConfig() + except: + raise + return None + + def setLogConfig(self, cfg): + if self.ref : + try: + self.ref.setLogConfig(cfg) + except: + raise + + def setLogConfigURL(self, cfg_url): + if self.ref : + try: + self.ref.setLogConfigURL(cfg_url) + except: + raise + + def setLogLevel(self, logger_id, cf_log_lvl ): + if self.ref : + try: + self.ref.setLogLevel(logger_id, cf_log_lvl) + except: + raise + # End external Domain Manager API ######################################## diff --git a/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp b/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp index 626fc1a42..b61695a6f 100644 --- a/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp @@ -70,7 +70,7 @@ static const ComponentInstantiation* findComponentInstantiation (const std::vect return 0; } -PREPARE_CF_LOGGING(DomainManager_impl) +PREPARE_LOGGING(DomainManager_impl) // If _overrideDomainName == NULL read the domain name from the DMD file DomainManager_impl::DomainManager_impl (const char* dmdFile, const char* _rootpath, const char* domainName, @@ -189,8 +189,6 @@ DomainManager_impl::DomainManager_impl (const char* dmdFile, const char* _rootpa _exit(EXIT_FAILURE); } - - // \todo lookup and install any services specified in the DMD LOG_TRACE(DomainManager_impl, "Looking for ApplicationFactories POA"); diff --git a/redhawk/src/control/sdr/dommgr/DomainManager_impl.h b/redhawk/src/control/sdr/dommgr/DomainManager_impl.h index 1f6455bde..31d39c073 100644 --- a/redhawk/src/control/sdr/dommgr/DomainManager_impl.h +++ b/redhawk/src/control/sdr/dommgr/DomainManager_impl.h @@ -33,6 +33,7 @@ #include #include +#include #include #include #include @@ -51,7 +52,7 @@ class AllocationManager_impl; class ConnectionManager_impl; -class DomainManager_impl: public virtual POA_CF::DomainManager, public PropertySet_impl, public ossie::ComponentLookup, public ossie::DomainLookup, public ossie::Runnable +class DomainManager_impl: public virtual POA_CF::DomainManager, public PropertySet_impl, public Logging_impl, public ossie::ComponentLookup, public ossie::DomainLookup, public ossie::Runnable { ENABLE_LOGGING diff --git a/redhawk/src/control/sdr/dommgr/main.cpp b/redhawk/src/control/sdr/dommgr/main.cpp index c5a3cf104..978dbaa5f 100644 --- a/redhawk/src/control/sdr/dommgr/main.cpp +++ b/redhawk/src/control/sdr/dommgr/main.cpp @@ -225,53 +225,12 @@ int old_main(int argc, char* argv[]) dpath= os.str(); // setup logging context for a component resource - ossie::logging::ResourceCtxPtr ctx( new ossie::logging::DomainCtx(name_binding, domainName, dpath ) ); - std::string logcfg_uri = logfile_uri; - if ( !logfile_uri.empty() ) { - // Determine the scheme, if any. This isn't a full fledged URI parser so we can - // get tripped up on complex URIs. We should probably incorporate a URI parser - // library for this sooner rather than later - std::string scheme; - fs::path path; - - std::string::size_type colonIdx = logfile_uri.find(":"); // Find the scheme separator - if (colonIdx == std::string::npos) { - - scheme = "file"; - path = logfile_uri; - // Make the path absolute - fs::path logfile_path(path); - if (! logfile_path.is_complete()) { - // Get the root path so we can resolve relative paths - fs::path root = fs::initial_path(); - logfile_path = fs::path(root / path); - } - path = logfile_path; - logfile_uri = "file://" + path.string(); - - } else { - - scheme = logfile_uri.substr(0, colonIdx); - colonIdx += 1; - if ((logfile_uri.at(colonIdx + 1) == '/') && (logfile_uri.at(colonIdx + 2) == '/')) { - colonIdx += 2; - } - path = logfile_uri.substr(colonIdx, logfile_uri.length() - colonIdx); - } - - if (scheme == "file") { - std::string fpath((char*)path.string().c_str()); - logcfg_uri = "file://" + fpath; - } - if (scheme == "sca") { - std::string fpath((char*)fs::path(domRootPath / path).string().c_str()); - logcfg_uri = "file://" + fpath; - } - } + ossie::logging::DomainCtx *ctx_=new ossie::logging::DomainCtx( name_binding, domainName, dpath ); + ctx_->configure( logcfg_uri, debugLevel, logfile_uri ); + ossie::logging::ResourceCtxPtr ctx(ctx_); // configure the logging library - ossie::logging::Configure(logcfg_uri, debugLevel, ctx); // This log statement is exempt from the "NO LOG STATEMENTS" warning below if ( logfile_uri == "") { LOG_INFO(DomainManager, "Loading DEFAULT logging configuration. " ); @@ -287,7 +246,7 @@ int old_main(int argc, char* argv[]) } #endif -#if 0 +#if 0 // test logger configuration.... LOG_FATAL(DomainManager, "FATAL MESSAGE " ); LOG_ERROR(DomainManager, "ERROR MESSAGE " ); @@ -415,7 +374,7 @@ int old_main(int argc, char* argv[]) // set logging level for the DomainManager's logger if ( DomainManager_servant ) { - DomainManager_servant->getLogger()->setLevel( ossie::logging::ConvertDebugToRHLevel(debugLevel) ); + DomainManager_servant->saveLoggingContext( logfile_uri, debugLevel, ctx ); } } catch (const CORBA::Exception& ex) { diff --git a/redhawk/src/idl/ossie/CF/cf.idl b/redhawk/src/idl/ossie/CF/cf.idl index a37bbbd6d..c8e4076bb 100644 --- a/redhawk/src/idl/ossie/CF/cf.idl +++ b/redhawk/src/idl/ossie/CF/cf.idl @@ -702,7 +702,7 @@ module CF { }; /* The DomainManager interface is for the control and configuration of the radio domain. */ - interface DomainManager : PropertyEmitter { + interface DomainManager : PropertyEmitter, Logging { /* This exception is raised when an Application installation has not completed correctly. The message provides additional information describing the reason for the error. */ exception ApplicationInstallationError { CF::ErrorNumberType errorNumber; diff --git a/redhawk/src/testing/_unitTestHelpers/scatest.py b/redhawk/src/testing/_unitTestHelpers/scatest.py index 7ed1c00b5..02e9201f3 100644 --- a/redhawk/src/testing/_unitTestHelpers/scatest.py +++ b/redhawk/src/testing/_unitTestHelpers/scatest.py @@ -569,6 +569,30 @@ def waitDeviceManager(self, devBooter, dcdFile, domainManager=None): self._addDeviceManager(devMgr) return devMgr + def waitForDeviceManager(self, node_dir): + dcdPath = getSdrPath()+"/dev/nodes/"+node_dir+"/DeviceManager.dcd.xml" + + dcd = DCDParser.parse(dcdPath) + if dcd.get_partitioning(): + numDevices = len(dcd.get_partitioning().get_componentplacement()) + else: + numDevices = 0 + + dm = self._getDomainManager() + + devMgr = None + while devMgr == None: + devMgr = self._getDeviceManager(dm, dcd.get_id()) + if devMgr: + break + time.sleep(0.1) + + if devMgr: + self._waitRegisteredDevices(devMgr, numDevices) + self._addDeviceManager(devMgr) + return devMgr + + def _waitRegisteredDevices(self, devMgr, numDevices, timeout=5.0, pause=0.1): while timeout > 0.0: if (len(devMgr._get_registeredDevices())+len(devMgr._get_registeredServices())) == numDevices: diff --git a/redhawk/src/testing/sdr/dom/logcfg/log4j.kickdomain.cfg b/redhawk/src/testing/sdr/dom/logcfg/log4j.kickdomain.cfg new file mode 100644 index 000000000..cd3f3b8b0 --- /dev/null +++ b/redhawk/src/testing/sdr/dom/logcfg/log4j.kickdomain.cfg @@ -0,0 +1,21 @@ +log4j.rootLogger=INFO,stdout + +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c:%L - %m%n + +log4j.appender.dom_stdout=org.apache.log4j.ConsoleAppender +log4j.appender.dom_stdout.Target=System.out +log4j.appender.dom_stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.dom_stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c:%L - %m%n + +log4j.appender.dev_stdout=org.apache.log4j.ConsoleAppender +log4j.appender.dev_stdout.Target=System.out +log4j.appender.dev_stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.dev_stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c:%L - %m%n + +log4j.category.DomainManager_impl=INFO, dom_stdout +log4j.additivity.DomainManager_impl=False + +log4j.category.DeviceManager_impl=INFO, dev_stdout +log4j.additivity.DeviceManager_impl=False diff --git a/redhawk/src/testing/tests/test_13_RedhawkModule.py b/redhawk/src/testing/tests/test_13_RedhawkModule.py index c8f9e9a09..798bdc221 100644 --- a/redhawk/src/testing/tests/test_13_RedhawkModule.py +++ b/redhawk/src/testing/tests/test_13_RedhawkModule.py @@ -21,6 +21,11 @@ import unittest from _unitTestHelpers import scatest import time +import contextlib +import cStringIO +import tempfile +import re +import sys as _sys from omniORB import CORBA from omniORB import any as _any from xml.dom import minidom @@ -35,6 +40,7 @@ from ossie.utils.model import NoMatchingPorts from ossie.events import Subscriber, Publisher from ossie.cf import CF +import traceback class RedhawkModuleEventChannelTest(scatest.CorbaTestCase): def setUp(self): @@ -122,7 +128,8 @@ def test_API_remap(self): remap_api = dir(self._rhDom) not_remap = ['_NP_RepositoryId','_Object__release','__getattribute__','__getstate__','__hash__','__setattr__','__setstate__','__weakref__', '__methods__','_duplicate','_dynamic_op','_hash','_is_a','_is_equivalent','_narrow','_nil','_obj', - '__del__','__omni_obj','_release','_unchecked_narrow', '_non_existent'] + '__del__','__omni_obj','_release','_unchecked_narrow', '_non_existent', + 'retrieve_records', 'retrieve_records_by_date', 'retrieve_records_from_date' ] for entry in orig_api: if entry in not_remap: continue @@ -915,3 +922,275 @@ def test_BadApplicationConnection(self): sink = sb.DataSink() self.assertRaises(NoMatchingPorts, app.connect, source) + + +class DomainMgrLoggingAPI(scatest.CorbaTestCase): + def setUp(self): + self.lcfg=_os.environ['OSSIEUNITTESTSLOGCONFIG'] + _os.environ['OSSIEUNITTESTSLOGCONFIG']="" + domBooter, self._domMgr = self.launchDomainManager() + self.dom = redhawk.attach(scatest.getTestDomainName()) + + def tearDown(self): + redhawk.core._cleanUpLaunchedApps() + scatest.CorbaTestCase.tearDown(self) + time.sleep(0.1) + _os.environ['OSSIEUNITTESTSLOGCONFIG']=self.lcfg + + def test123log_level(self): + """ + Tests set debug level api is working + """ + from ossie.cf import CF + self.assertNotEqual( self.dom, None ) + + self.dom.ref._set_log_level( CF.LogLevels.TRACE ) + ret=self.dom.ref._get_log_level( ) + self.assertEqual( ret, CF.LogLevels.TRACE ) + + self.dom.ref._set_log_level( CF.LogLevels.DEBUG ) + ret=self.dom.ref._get_log_level() + self.assertEqual( ret, CF.LogLevels.DEBUG ) + + self.dom.ref._set_log_level( CF.LogLevels.INFO ) + ret=self.dom.ref._get_log_level() + self.assertEqual( ret, CF.LogLevels.INFO ) + + self.dom.ref._set_log_level( CF.LogLevels.WARN ) + ret=self.dom.ref._get_log_level() + self.assertEqual( ret, CF.LogLevels.WARN ) + + self.dom.ref._set_log_level( CF.LogLevels.ERROR ) + ret=self.dom.ref._get_log_level() + self.assertEqual( ret, CF.LogLevels.ERROR ) + + self.dom.ref._set_log_level( CF.LogLevels.FATAL ) + ret=self.dom.ref._get_log_level() + self.assertEqual( ret, CF.LogLevels.FATAL ) + + def test_default_logconfig(self): + cfg = "log4j.rootLogger=INFO,STDOUT\n" + \ + "# Direct log messages to STDOUT\n" + \ + "log4j.appender.STDOUT=org.apache.log4j.ConsoleAppender\n" + \ + "log4j.appender.STDOUT.layout=org.apache.log4j.PatternLayout\n" + \ + "log4j.appender.STDOUT.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n\n" + + c_cfg=self.dom.ref.getLogConfig() + + ## remove extra white space + cfg=cfg.replace(" ","") + c_cfg=c_cfg.replace(" ","") + self.assertEquals( cfg, c_cfg) + + + def test_logconfig(self): + cfg = "log4j.rootLogger=ERROR,STDOUT\n" + \ + "# Direct log messages to STDOUT\n" + \ + "log4j.appender.STDOUT=org.apache.log4j.ConsoleAppender\n" + \ + "log4j.appender.STDOUT.layout=org.apache.log4j.PatternLayout\n" + \ + "log4j.appender.STDOUT.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n\n" + + self.dom.ref.setLogConfig(cfg) + + c_cfg=self.dom.ref.getLogConfig() + cfg=cfg.replace(" ","") + c_cfg=c_cfg.replace(" ","") + self.assertEquals( cfg, c_cfg) + + + def test_macro_config(self): + cfg = "log4j.rootLogger=ERROR,STDOUT\n " + \ + "# Direct log messages to STDOUT\n" + \ + "log4j.appender.STDOUT=org.apache.log4j.ConsoleAppender\n" + \ + "log4j.appender.STDOUT.layout=org.apache.log4j.PatternLayout\n" + \ + "log4j.appender.STDOUT.layout.ConversionPattern=@@@DOMAIN.NAME@@@\n" + + self.dom.ref.setLogConfig(cfg) + + c_cfg=self.dom.ref.getLogConfig() + + res=c_cfg.find(scatest.getTestDomainName()) + + self.assertNotEquals( res, -1 ) + + def test_macro_config2(self): + cfg = "@@@DOMAIN.NAME@@@" + self.dom.ref.setLogConfig(cfg) + c_cfg=self.dom.ref.getLogConfig() + res=c_cfg.find(scatest.getTestDomainName()) + self.assertNotEquals( res, -1 ) + + + + +class RedhawkStartup(scatest.CorbaTestCase): + def setUp(self): + pass + + def tearDown(self): + redhawk.base._cleanup_domain() + scatest.CorbaTestCase.tearDown(self) + import commands + try: + s,o = commands.getstatusoutput('pkill -9 -f nodeBooter ') + s,o = commands.getstatusoutput('pkill -9 -f dev/devices ') + s,o = commands.getstatusoutput('pkill -9 -f DomainManager ') + s,o = commands.getstatusoutput('pkill -9 -f DeviceManager ') + except: + pass + + def _try_kick_domain(self, logcfg, epatterns, debug_level=None, kick_device_managers=False, dev_mgrs=[], dev_mgr_levels=[] ): + + tmpfile=tempfile.mktemp() + self._rhDom = redhawk.kickDomain(domain_name=scatest.getTestDomainName(), + logfile=scatest.getSdrPath()+'/dom/logcfg/'+logcfg, + kick_device_managers=kick_device_managers, + device_managers = dev_mgrs, + stdout=tmpfile, + debug_level=debug_level, + device_managers_debug_levels = dev_mgr_levels ) + + if kick_device_managers and len(dev_mgrs)> 0 : + for devm in dev_mgrs: + try: + self.waitForDeviceManager(devm) + except: + traceback.print_exc() + pass + new_stdout=open(tmpfile,'r') + for k, epat in epatterns.iteritems(): + epat.setdefault('results',[]) + + for x in new_stdout.readlines(): + #print "Line -> ", x + for k, pat in epatterns.iteritems(): + for epat in pat['patterns' ]: + m=re.search( epat, x ) + if m : + #print "MATCH -> ", epat, " LINE ", x + pat['results'].append(True) + + for k,pat in epatterns.iteritems(): + if type(pat['match']) == list: + lmatch = len(pat['results']) == len(pat['match']) and pat['results'] == pat['match'] + self.assertEqual(lmatch, True ) + + if type(pat['match']) == int: + # ignore + if pat['match'] == -1 : + pass + else: + self.assertEqual( pat['match'] , len(pat['results']) ) + + + def test_kick_trace(self): + self._try_kick_domain('log4j.kickdomain.cfg', + epatterns={ + "yes" : { 'patterns': [" TRACE ", " DEBUG ", " INFO ", " WARN ", " ERROR ", " FATAL " ], 'match': -1 }, + }, + debug_level="TRACE") + + def test_kick_trace_both(self): + self._try_kick_domain('log4j.kickdomain.cfg', + epatterns={ + "yes" : { 'patterns': [" TRACE ", " DEBUG ", " INFO ", " WARN ", " ERROR ", " FATAL " ], 'match': -1 }, + }, + debug_level="TRACE", + kick_device_managers=True, + dev_mgrs = [ 'test_BasicTestDevice_node' ], + dev_mgr_levels= [ "TRACE" ], + ) + + def test_kick_debug(self): + self._try_kick_domain('log4j.kickdomain.cfg', + epatterns={ "no" : { 'patterns': [" TRACE " ], 'match': [] }, + "yes" : { 'patterns': [" DEBUG ", " INFO ", " WARN ", " ERROR ", " FATAL " ], 'match': -1 }, + }, + debug_level="DEBUG") + + + def test_kick_debug_both(self): + self._try_kick_domain('log4j.kickdomain.cfg', + epatterns={ "no" : { 'patterns': [" TRACE " ], 'match': [] }, + "yes" : { 'patterns': [ " DEBUG ", " INFO ", " WARN ", " ERROR ", " FATAL " ], 'match': -1 }, + }, + debug_level="DEBUG", + kick_device_managers=True, + dev_mgrs = [ 'test_BasicTestDevice_node', "test_BasicTestDevice2_node" ], + dev_mgr_levels= [ "DEBUG", "DEBUG" ] + ) + + def test_kick_info(self): + self._try_kick_domain('log4j.kickdomain.cfg', + epatterns={ "no" : { 'patterns': [" TRACE ", " DEBUG " ], 'match': [] }, + "yes" : { 'patterns': [ " INFO ", " WARN ", " ERROR ", " FATAL " ], 'match': -1 }, + }, + debug_level="INFO") + + def test_kick_info_both(self): + self._try_kick_domain('log4j.kickdomain.cfg', + epatterns={ "no" : { 'patterns': [" TRACE ", " DEBUG " ], 'match': [] }, + "yes" : { 'patterns': [ " INFO ", " WARN ", " ERROR ", " FATAL " ], 'match': -1 }, + }, + debug_level="INFO", + kick_device_managers=True, + dev_mgrs = [ 'test_BasicTestDevice_node', "test_BasicTestDevice2_node" ], + dev_mgr_levels= [ "INFO", "INFO" ] + ) + + def test_kick_warn(self): + self._try_kick_domain('log4j.kickdomain.cfg', + epatterns={ "no" : { 'patterns': [" TRACE ", " DEBUG ", " INFO ", ], 'match': 2 }, + "yes" : { 'patterns': [" WARN ", " ERROR ", " FATAL " ], 'match': -1 }, + }, + debug_level="WARN") + + def test_kick_warn_both(self): + self._try_kick_domain('log4j.kickdomain.cfg', + epatterns={ "no" : { 'patterns': [" TRACE ", " DEBUG " ], 'match': [] }, + "no2" : { 'patterns': [ " INFO ", ], 'match': 12 }, + "yes" : { 'patterns': [ " WARN ", " ERROR ", " FATAL " ], 'match': -1 }, + }, + debug_level="WARN", + kick_device_managers=True, + dev_mgrs = [ 'test_BasicTestDevice_node', "test_BasicTestDevice2_node" ], + dev_mgr_levels= [ "WARN", "WARN" ] + ) + + def test_kick_error(self): + self._try_kick_domain('log4j.kickdomain.cfg', + epatterns={ "no" : { 'patterns': [" TRACE ", " DEBUG ", " INFO ", " WARN " ], 'match': 2 }, + "yes" : { 'patterns': [ " ERROR ", " FATAL " ], 'match': -1 }, + }, + debug_level="ERROR") + + def test_kick_error_both(self): + self._try_kick_domain('log4j.kickdomain.cfg', + epatterns={ "no" : { 'patterns': [" TRACE ", " DEBUG " ] , 'match': [] }, + "no2" : { 'patterns': [ " INFO ", " WARN " ], 'match': 14 }, + "yes" : { 'patterns': [ " ERROR ", " FATAL " ], 'match': -1 }, + }, + debug_level="ERROR", + kick_device_managers=True, + dev_mgrs = [ 'test_BasicTestDevice_node', "test_BasicTestDevice2_node" ], + dev_mgr_levels= [ "ERROR", "ERROR" ] + ) + + def test_kick_fatal(self): + self._try_kick_domain('log4j.kickdomain.cfg', + epatterns={ "no" : { 'patterns': [" TRACE ", " DEBUG ", " INFO ", " WARN ", " ERROR " ], 'match': 2 }, + "yes" : { 'patterns': [" FATAL " ], 'match': -1 }, + }, + debug_level="ERROR") + + def test_kick_fatal_both(self): + self._try_kick_domain('log4j.kickdomain.cfg', + epatterns={ "no" : { 'patterns': [" TRACE ", " DEBUG ", " ERROR " ], 'match': [] }, + "no2" : { 'patterns': [ " INFO ", " WARN " ], 'match': 14 }, + "yes" : { 'patterns': [ " FATAL " ], 'match': -1 }, + }, + debug_level="FATAL", + kick_device_managers=True, + dev_mgrs = [ 'test_BasicTestDevice_node', "test_BasicTestDevice2_node" ], + dev_mgr_levels= [ "FATAL", "FATAL" ] + ) From 4bdc1ad904e7b36de5e2258975269e240d4714fa Mon Sep 17 00:00:00 2001 From: Max Robert Date: Thu, 8 Jun 2017 15:58:47 -0400 Subject: [PATCH 0813/1644] Refs CF-1771. Removed prompt for api call in testing --- redhawk/src/testing/tests/test_13_RedhawkModule.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/redhawk/src/testing/tests/test_13_RedhawkModule.py b/redhawk/src/testing/tests/test_13_RedhawkModule.py index 798bdc221..6e860c9f3 100644 --- a/redhawk/src/testing/tests/test_13_RedhawkModule.py +++ b/redhawk/src/testing/tests/test_13_RedhawkModule.py @@ -31,6 +31,7 @@ from xml.dom import minidom import os as _os import Queue +import StringIO from ossie.cf import CF from ossie.utils import redhawk from ossie.utils import type_helpers @@ -178,8 +179,9 @@ def test_createApplication1(self): self.assertEquals(len(self._rhDom.apps), 1) # Ensure that api() works. + _destfile=StringIO.StringIO() try: - app.api() + app.api(destfile=_destfile) except: self.fail('App.api() raised an exception') @@ -232,8 +234,9 @@ def test_createApplicationNoCleanup(self): self.assertEquals(len(self._rhDom.apps), 1) # Ensure that api() works. + _destfile=StringIO.StringIO() try: - app.api() + app.api(destfile=_destfile) except: self.fail('App.api() raised an exception') @@ -298,7 +301,8 @@ def test_apiHostCollocation(self): self.assertEquals(provides_ports, {}) uses_ports = object.__getattribute__(app,'_usesPortDict') self.assertEquals(uses_ports, {}) - app.api() + _destfile=StringIO.StringIO() + app.api(destfile=_destfile) provides_ports = object.__getattribute__(app,'_providesPortDict') self.assertEquals(len(provides_ports), 1) self.assertEquals(provides_ports.keys()[0], 'input') From 8b6d5296742d1ae2dc4d12559317fc43da196aba Mon Sep 17 00:00:00 2001 From: Max Robert Date: Fri, 9 Jun 2017 09:25:21 -0400 Subject: [PATCH 0814/1644] Refs CF-1593. Added scanner device --- .../idl/redhawk/FRONTEND/TunerControl.idl | 129 ++++++++++++++++-- 1 file changed, 117 insertions(+), 12 deletions(-) diff --git a/frontendInterfaces/idl/redhawk/FRONTEND/TunerControl.idl b/frontendInterfaces/idl/redhawk/FRONTEND/TunerControl.idl index 0e06e2724..3cddb1eee 100644 --- a/frontendInterfaces/idl/redhawk/FRONTEND/TunerControl.idl +++ b/frontendInterfaces/idl/redhawk/FRONTEND/TunerControl.idl @@ -22,6 +22,8 @@ #define _FRONTEND_TUNERCONTROL_IDL_ #include "redhawk/FRONTEND/Frontend.idl" +#include "ossie/BULKIO/bulkioDataTypes.idl" +#include "ossie/CF/PortTypes.idl" module FRONTEND { @@ -31,7 +33,7 @@ module FRONTEND { Frontend mandates three property structures outside of normal REDHAWK properties of "device_kind" and "device_model" : (1) FRONTEND::tuner_allocation - allocation structure to acquire capability on a tuner based off tuner settings. Name || ID || Type || Description - - tuner_type || FRONTEND::tuner_allocation::tuner_type || string || Example Tuner Types: TX, RX, CHANNELIZER, DDC, RX_DIGITIZER, RX_DIGITIZER_CHANNELIZER + - tuner_type || FRONTEND::tuner_allocation::tuner_type || string || Example Tuner Types: TX, RX, CHANNELIZER, DDC, RX_DIGITIZER, RX_DIGITIZER_CHANNELIZER, RX_SCANNER_DIGITIZER - allocation_id || FRONTEND::tuner_allocation::allocation_id || string || The allocation_id set by the caller. Used by the caller to reference the device uniquely - center_frequency || FRONTEND::tuner_allocation::center_frequency || double || Requested center frequency in Hz - bandwidth || FRONTEND::tuner_allocation::bandwidth || double || Requested Bandwidth in Hz @@ -42,12 +44,21 @@ module FRONTEND { to any currently tasked device that satisfies the parameters (essentually a listener) - group_id || FRONTEND::tuner_allocation::group_id || string || Unique identifier that specifies a group of device. Must match group_id on the device - rf_flow_id || FRONTEND::tuner_allocation::rf_flow_id || string || Optional. Specifies a certain RF flow to allocate against. If left empty, it will match all frontend devices. - (2) FRONTEND::listener_allocation - additional allocation structure to acquire "listener" capability on a tuner based off a previous allocation. "Listeners" have the ability to receive the data + (2) FRONTEND::scanner_allocation + Allocation structure to acquire capability on a scanning tuner (must be used in conjunction with FRONTEND::tuner_allocation). + Note that the allocation does not contain enough information to setup the scan strategy. Once the device is allocated, the strategy must be set through the control API + Name || ID || Type || Description + - min_freq || FRONTEND::scanner_allocation::min_freq || double || Requested lower edge of the scanning band + - max_freq || FRONTEND::scanner_allocation::max_freq || double || Requested upper edge of the scanning band + - mode || FRONTEND::scanner_allocation::mode || string || SPAN_SCAN or DISCRETE_SCAN + - control_mode || FRONTEND::scanner_allocation::control_mode || string|| TIME_BASED or SAMPLE_BASED + - control_limit || FRONTEND::scanner_allocation::control_limit || double || Either the fastest hop rate (TIME_BASED) or shortest set of samples (SAMPLE_BASED) that the scanner is expected to support. In samples, the number that will be needed before the next retune, equivalent to control_limit >= sample_rate/(max_settle_time+min_dwell_time) is met before the next retune + (3) FRONTEND::listener_allocation - additional allocation structure to acquire "listener" capability on a tuner based off a previous allocation. "Listeners" have the ability to receive the data but can not modify the settings of the tuner Name || ID || Type || Description - existing_allocation_id || FRONTEND::listener_allocation::existing_allocation_id || string || Allocation ID for an existing allocation. Could be either control or listener - listener_allocation_id || FRONTEND::listener_allocation::listener_allocation_id || string || New Listener ID - (3) FRONTEND::tuner_status - a struct sequence containing the status of all tuners. There are optional and required fields for this structure. The required fields are listed below: + (4) FRONTEND::tuner_status - a struct sequence containing the status of all tuners. There are optional and required fields for this structure. The required fields are listed below: Name || ID || Type || Description - tuner_type || FRONTEND::tuner_status::tuner_type || string || Example Tuner Types: TX, RX, CHANNELIZER, DDC, RX_DIGITIZER, RX_DIGTIZIER_CHANNELIZER - allocation_id_csv || FRONTEND::tuner_status::allocation_id_csv || string || Comma seperated list of currrent allocation ids, both control and listeners. @@ -57,6 +68,8 @@ module FRONTEND { - group_id || FRONTEND::tuner_status::group_id || string || Unique identifier that specifies a group of device. - rf_flow_id || FRONTEND::tuner_status::rf_flow_id || string || Specifies a certain RF flow to allocate against. - enabled || FRONTEND::tuner_status::enabled || boolean || True is tuner is enabled. Can be allocated but disabled + - mode_enabled || FRONTEND::tuner_status::scan_mode_enabled || boolean || True is scan mode is enabled. False is Manual Tune is enabled + - supports_scan || FRONTEND::tuner_status::supports_scan || boolean || True if scan allocated Usual port additions include a input (provides) port for the tuner control as well as an output (uses) BULKIO data port that follows the naming convention [interface]_[in/out]. Examples include dataShort_out, dataSDDS_out, dataOctet_in, and DigitalTuner_in. @@ -109,11 +122,11 @@ module FRONTEND { const string TUNER_TYPE_TX = "TX"; const string TUNER_TYPE_RX = "RX"; const string TUNER_TYPE_RX_DIGITIZER = "RX_DIGITIZER"; + const string TUNER_TYPE_RX_SCANNER_DIGITIZER = "RX_SCANNER_DIGITIZER"; const string TUNER_TYPE_CHANNELIZER = "CHANNELIZER"; const string TUNER_TYPE_DDC = "DDC"; const string TUNER_TYPE_RX_DIGITIZER_CHANNELIZER = "RX_DIGITIZER_CHANNELIZER"; - /*************************/ /*** INTERFACE */ /*************************/ @@ -152,27 +165,27 @@ module FRONTEND { raises (FrontendException, BadParameterException, NotSupportedException); /** Set/Get tuner bandwidth */ - void setTunerBandwidth(in string id,in double bw) + void setTunerBandwidth(in string id, in double bw) raises (FrontendException, BadParameterException, NotSupportedException); double getTunerBandwidth(in string id) raises (FrontendException, BadParameterException, NotSupportedException); /** MGC/AGC */ - void setTunerAgcEnable(in string id,in boolean enable) + void setTunerAgcEnable(in string id, in boolean enable) raises (FrontendException, BadParameterException, NotSupportedException); boolean getTunerAgcEnable(in string id) raises (FrontendException, BadParameterException, NotSupportedException); - /** MGC Gain (where negative gain is attentuation)*/ - void setTunerGain(in string id,in float gain) + /** MGC Gain (where negative gain is attenuation)*/ + void setTunerGain(in string id, in float gain) raises (FrontendException, BadParameterException, NotSupportedException); float getTunerGain(in string id) raises (FrontendException, BadParameterException, NotSupportedException); - /** Tuner Reference Source: 0 = internal, 1 = external*/ - void setTunerReferenceSource(in string id,in long source) + /** Tuner Reference Source: 0 = internal, 1 = external*/ + void setTunerReferenceSource(in string id, in long source) raises (FrontendException, BadParameterException, NotSupportedException); - long getTunerReferenceSource(in string id) + long getTunerReferenceSource(in string id) raises (FrontendException, BadParameterException, NotSupportedException); /** Enable/Disable Tuner - Expected to keep current tuner settings on a disable and an EOS to be sent */ @@ -180,7 +193,7 @@ module FRONTEND { raises (FrontendException, BadParameterException, NotSupportedException); boolean getTunerEnable(in string id) raises (FrontendException, BadParameterException, NotSupportedException); - }; + }; interface DigitalTuner : AnalogTuner @@ -190,8 +203,100 @@ module FRONTEND { raises (FRONTEND::FrontendException, FRONTEND::BadParameterException, FRONTEND::NotSupportedException); double getTunerOutputSampleRate(in string id) raises (FRONTEND::FrontendException, FRONTEND::BadParameterException, FRONTEND::NotSupportedException); + }; + + /** + TUNER SCAN MODE + The tuner SCAN mode is being added to reduce aggregate tune delays when there is a need for a series of fast + retunes. The objective is to let the tuner asset perform the retuning in an automated fashion. + + The scan_mode property in the tuner_allocation structure is used for device allocation. If scan_mode is set to + "Scan" and the device has the capability, it will be allocated. The scan_rate property is also available in the + tuner_allocation structure. It is used as a allocation property if the user specifies a desired rate for the scan + operation. It is an optional allocation parameter. + + Tuner SCAN Mode allows the tuner to internally perform a scan where the tuner itself retunes to cover the desired + spectrum. There are two types of automated scans: Span scan and discrete frequency scan, and a single non-automated scan: Manual (the way devices normally operate). + The scan_mode_type value determines the scan type. If the only scanning that the device allows is manual, then the device does not support scanning. + A Span scan is created using a series of start/stop frequencies. A Discrete Frequency Scan is created from a series of discrete + frequencies. Each of these are inputs are used to create a series of center tune frequencies. Based on the selected bandwidth, + the tuner scan generates as a series of center frequency retunes to cover the spectrum between the start/stop frequencies or + discrete frequencies. + + If the scan_mode_enable is toggled from "OFF" to "ON", the tuner will begin to generate retunes for each center tune frequency + that was generated to cover the spectrum. It will then tune, dwell for a specific number of samples based on the dwell setting + and then move to the next center frequency. It is imperative to guarantee accurate data that the tuner not output samples until + the tuner settling time has been internally accounted for. + + The start_time allows for synchronous sampling between multiple tuners. + + The ScanStatus structure contains the settings for the scan. + */ + + interface ScanningTuner + { + /************************/ + /* STRUCTURES */ + /************************/ + enum ScanMode { + MANUAL_SCAN, + SPAN_SCAN, + DISCRETE_SCAN + }; + enum OutputControlMode { + TIME_BASED, + SAMPLE_BASED + }; + /** Basic Scan Structure */ + /** Note: the bandwidth is set by the tuner base interface. The scanning interface manages the center frequency and duration of dwell **/ + struct ScanSpanRange { + double begin_frequency; /* beginning center frequency for a Scan span (Hz) */ + double end_frequency; /* limit center frequency for a Scan span (Hz) */ + double step; /* change in center frequency (Hz) */ + }; + typedef sequence ScanSpanRanges; + typedef sequence Frequencies; + + union ScanModeDefinition switch(ScanMode) { + case MANUAL_SCAN: + double center_frequency; + case SPAN_SCAN: + ScanSpanRanges freq_scan_list; + case DISCRETE_SCAN: + Frequencies discrete_freq_list; + }; + struct ScanStrategy { + ScanMode scan_mode; /* determines the scan mode type: Manual: MANUAL_SCAN, Span Scan: SPAN_SCAN, Discrete Frequency Scan: DISCRETE_SCAN */ + ScanModeDefinition scan_definition; /* manual, span, or discrete frequency */ + OutputControlMode control_mode; /* time-based or sample-based */ + double control_value; /* time (in seconds) for time-based, or samples (truncated) for sample-based */ + }; + + struct ScanStatus { + ScanStrategy strategy; /* describes the scanning strategy (i.e.: time-based or sample-based) */ + BULKIO::PrecisionUTCTime start_time; /* Scheduled (or actual) start */ + Frequencies center_tune_frequencies; /* list of frequencies derived from the scanning plan (computed by the scanner device) */ + boolean started; /* True, scan plan in process */ + }; + + ScanStatus getScanStatus(in string id) + raises (FRONTEND::FrontendException, FRONTEND::BadParameterException, FRONTEND::NotSupportedException); + /** Set Tuner Scan Start Time. Set to time zero or any time in the past with a valid tcstatus flag to start immediately. Set to invalid tcstatus to disable */ + void setScanStartTime(in string id,in BULKIO::PrecisionUTCTime start_time) + raises (FRONTEND::FrontendException, FRONTEND::BadParameterException, FRONTEND::NotSupportedException); + + void setScanStrategy(in string id,in ScanStrategy scan_strategy) + raises (FRONTEND::FrontendException, FRONTEND::BadParameterException, FRONTEND::NotSupportedException); }; + interface AnalogScanningTuner : ScanningTuner, AnalogTuner + { + }; + + interface DigitalScanningTuner : ScanningTuner, DigitalTuner + { + }; + }; #endif From fd26b5ce509ecc8fe4afef1531f2ce76152b1fa7 Mon Sep 17 00:00:00 2001 From: 8530 <8530@vm-131.vsi-corp.com> Date: Fri, 9 Jun 2017 10:01:52 -0400 Subject: [PATCH 0815/1644] additional unit tests, CF-408 --- .../python/ossie/utils/sb/io_helpers.py | 2 +- .../python/ossie/utils/sdds/sdds_analyzer.py | 42 ++- .../python/ossie/utils/sdds/sdds_pkt.py | 176 ++++++--- redhawk/src/testing/tests/test_13_SDDS.py | 333 +++++++++++++++++- 4 files changed, 474 insertions(+), 79 deletions(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py b/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py index 8a94849a8..ac74dd5e9 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py +++ b/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py @@ -1249,7 +1249,7 @@ def getData( self, mgroup, hostip, port=29495, vlan=0, pkts=1000, pktlen=1080, s print "Elapsed Time: ", deltaTime, " Total Data (kB): ", totalRead/1000.0, " Rate (kBps): ", (totalRead/1000.0)/deltaTime if returnSddsAnalyzer: from ossie.utils.sdds import SDDSAnalyzer - return SDDSAnalyzer( pkts, data, rawdata, totalRead, pktlen ) + return SDDSAnalyzer( rawdata, pkts, pktlen, totalRead ) else: return data, rawdata, (pktlen,pkts,totalRead) diff --git a/redhawk/src/base/framework/python/ossie/utils/sdds/sdds_analyzer.py b/redhawk/src/base/framework/python/ossie/utils/sdds/sdds_analyzer.py index d37880c4f..ff0a8b590 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sdds/sdds_analyzer.py +++ b/redhawk/src/base/framework/python/ossie/utils/sdds/sdds_analyzer.py @@ -26,24 +26,40 @@ class SDDSAnalyzer(object): dumpPackets - dump packet fields and their data values, contents managed by a pager getPacketsIterator - returns a generator object for access packets in a looping construct getPackets - returns a list of sdds_packet objects - + + __iter__ - The iterable returns a tuple (pkt number,sdds_packet) + __len__ - returns the number of packets + """ _VAILID_VAL_='+' _TRACK_OK_='-' _TRACK_ERROR_='***' - def __init__(self, pkts, data, raw_data, total_bytes_read, pkt_len=1080 ): - self.pkts_ = pkts - self.data_ = data + def __init__(self, raw_data, npkts, pkt_len=1080, total_bytes=None): + self.npkts_ = npkts self.raw_data_ = raw_data self.pkt_len_ = pkt_len - self.total_bytes_read = total_bytes_read + dsize=len(raw_data) + expected_size = pkt_len * npkts + + if expected_size > dsize : + raise RuntimeError("Invalid parameters, pkt_len*npkts is greater than raw_data size ") + + # adjust total bytes if necessary + if total_bytes: + if total_bytes > dsize: + total_bytes=dsize + else: + total_bytes = dsize + + self.total_bytes_=total_bytes + def dumpRawPackets(self, pkt_start=0, pkt_end=None, row_width=80, bytes_per_group=2, pkt_len=None, use_pager=True ): if pkt_end == None: - pkt_end = self.pkts_ + pkt_end = self.npkts_ if pkt_len: - pkt_end = self.pkts_ + pkt_end = self.npkts_ if pkt_len == None: pkt_len = self.pkt_len_ genf=self._gen_hex_dump( self.raw_data_, pkt_start, pkt_len, row_width, bytes_per_group ) @@ -61,7 +77,7 @@ def dumpRawPackets(self, pkt_start=0, pkt_end=None, row_width=80, bytes_per_grou def dumpPackets(self, pkt_start=0, pkt_end=None, payload_start=0, payload_end=40, raw_payload=False, header_only=False, use_pager=True ): genf=self._gen_packet( self.raw_data_, pkt_start ) - if pkt_end == None: pkt_end = self.pkts_ + if pkt_end == None: pkt_end = self.npkts_ res = StringIO() for i, pkt in enumerate(genf,pkt_start): if i < pkt_end: @@ -127,7 +143,7 @@ def _first_pkt( self, res, next_pkt ): def trackChanges(self, pkt_start=0, pkt_end=None, repeat_header=20, use_pager=True ): genf=self._gen_packet( self.raw_data_, pkt_start ) - if pkt_end == None: pkt_end = self.pkts_ + if pkt_end == None: pkt_end = self.npkts_ res = StringIO() keys = [ 'pkt', 'fsn', 'dmode', 'cplx', 'bps', 'freq', 'rate', 'ttv', 'timeslip' ] hdrs = [ 'PKT', 'SEQ', 'FMT', 'CPLX', 'BPS', ' FREQ ', ' CLK ', 'TIME VALID', 'TIME SLIP' ] @@ -164,13 +180,19 @@ def trackChanges(self, pkt_start=0, pkt_end=None, repeat_header=20, use_pager=Tr def getPacketIterator(self, pkt_start=0, pkt_end=None ): genf=self._gen_packet( self.raw_data_, pkt_start ) - if pkt_end == None: pkt_end = self.pkts_ + if pkt_end == None: pkt_end = self.npkts_ for i, pkt in enumerate(genf,pkt_start): if i < pkt_end: yield i,pkt else: StopIteration + def __iter__(self): + return self.getPacketIterator() + + def __len__(self): + return self.npkts_ + def getPackets(self, pkt_start=0, pkt_end=None ): res=[] for i, pkt in self.getPacketIterator( pkt_start, pkt_end ): diff --git a/redhawk/src/base/framework/python/ossie/utils/sdds/sdds_pkt.py b/redhawk/src/base/framework/python/ossie/utils/sdds/sdds_pkt.py index e7bd12d6d..48eabd404 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sdds/sdds_pkt.py +++ b/redhawk/src/base/framework/python/ossie/utils/sdds/sdds_pkt.py @@ -141,7 +141,6 @@ def BitsToNumber(sbits, reverse=False ): f = [x << n for n, x in enumerate(tbits)] return reduce(lambda x, y: x + y, f) - class format_identifier(ctypes.Structure): _pack_ = 1 _fields_ = [ ('dm',ctypes.c_uint8,3), @@ -161,7 +160,7 @@ def __new__(cls,*args, **kwargs ): return cls.from_buffer_copy(args[0]) return cls.from_buffer_copy(kwargs['buf']) else: - return super(format_identifier,cls).__new__(cls,*args,**kwags) + return super(format_identifier,cls).__new__(cls,*args,**kwargs) def __init__(self,data=None): self.sf = 1 @@ -215,7 +214,7 @@ def __new__(cls,*args, **kwargs ): return cls.from_buffer_copy(args[0]) return cls.from_buffer_copy(kwargs['buf']) else: - return super(frame_sequence,cls).__new__(cls,*args,**kwags) + return super(frame_sequence,cls).__new__(cls,*args,**kwargs) def __init__(self,data=None): self.seq = 0 @@ -238,7 +237,7 @@ def asBuffer(self): def asString(self): return ctypes.string_at(ctypes.addressof(self),ctypes.sizeof(self)) -class msptr_data (ctypes.Structure): +class msptr_data (ctypes.BigEndianStructure): _pack_ = 1 _fields_ = [ ('msptr',ctypes.c_ushort,16), ('msdelta',ctypes.c_ushort,16) ] @@ -249,7 +248,7 @@ def __new__(cls,*args, **kwargs ): return cls.from_buffer_copy(args[0]) return cls.from_buffer_copy(kwargs['buf']) else: - return super(msptr_data,cls).__new__(cls,*args,**kwags) + return super(msptr_data,cls).__new__(cls,*args,**kwargs) def __init__(self,data=None): self.msptr=0 @@ -265,6 +264,12 @@ def set_msptr( self, val ): def get_msptr( self ): return self.msptr + def set_msdelta( self, val ): + self.msdelta = val + + def get_msdelta( self ): + return self.msdelta + def asBuffer(self): return buffer(self)[:] @@ -273,14 +278,16 @@ def asString(self): class ttag_info_struct(ctypes.Structure): _pack_ = 1 - _fields_ = [ ('pad2',ctypes.c_uint8,8), - ('msv',ctypes.c_uint8,1), - ('ttv',ctypes.c_uint8,1), - ('sscv',ctypes.c_uint8,1), - ('pi',ctypes.c_uint8,1), + _fields_ = [ ('pad1',ctypes.c_uint8,1), + ('pad2',ctypes.c_uint8,1), + ('pad3',ctypes.c_uint8,1), ('peo',ctypes.c_uint8,1), - ('pad1',ctypes.c_uint8,3), - ('pad3',ctypes.c_uint16,16) ] + ('pi',ctypes.c_uint8,1), + ('sscv',ctypes.c_uint8,1), + ('ttv',ctypes.c_uint8,1), + ('msv',ctypes.c_uint8,1), + ('pad4',ctypes.c_uint8,8), + ('pad5',ctypes.c_uint16,16) ] def __new__(cls,*args, **kwargs ): if len(args) > 0 or 'buf' in kwargs: @@ -288,7 +295,7 @@ def __new__(cls,*args, **kwargs ): return cls.from_buffer_copy(args[0]) return cls.from_buffer_copy(kwargs['buf']) else: - return super(ttag_info_struct,cls).__new__(cls,*args,**kwags) + return super(ttag_info_struct,cls).__new__(cls,*args,**kwargs) def __init__(self,data=None): self.ttv=0 @@ -365,7 +372,7 @@ def __new__(cls,*args, **kwargs ): return cls.from_buffer_copy(args[0]) return cls.from_buffer_copy(kwargs['buf']) else: - return super(ttag_info_union,cls).__new__(cls,*args,**kwags) + return super(ttag_info_union,cls).__new__(cls,*args,**kwargs) def __init__(self,data=None): pass @@ -390,7 +397,7 @@ def __new__(cls,*args, **kwargs ): return cls.from_buffer_copy(args[0]) return cls.from_buffer_copy(kwargs['buf']) else: - return super(ttag_values,cls).__new__(cls,*args,**kwags) + return super(ttag_values,cls).__new__(cls,*args,**kwargs) def __init__(self,data=None): self.ttag=0 @@ -432,7 +439,7 @@ def __new__(cls,*args, **kwargs ): return cls.from_buffer_copy(args[0]) return cls.from_buffer_copy(kwargs['buf']) else: - return super(ttag_info,cls).__new__(cls,*args,**kwags) + return super(ttag_info,cls).__new__(cls,*args,**kwargs) def __init__(self,data=None): pass @@ -492,10 +499,12 @@ def __new__(cls,*args, **kwargs ): return cls.from_buffer_copy(args[0]) return cls.from_buffer_copy(kwargs['buf']) else: - return super(ssc_info_struct,cls).__new__(cls,*args,**kwags) + return super(ssc_info_struct,cls).__new__(cls,*args,**kwargs) def __init__(self,data=None): - pass + self.dfdt=0 + self.freq=0 + def __str__(self): return 'freq: '+ str(self.get_freq())+' dfdt: '+ str(self.get_dfdt()) @@ -508,7 +517,7 @@ def get_freq(self): def set_freq(self, freq): # frequency units resolution 2^63/125mhz sfreq= freq* 73786976294.838211 - self.freq = long(sfreq) + self.freq = long(sfreq) def get_dfdt(self): sdfdt = self.dfdt * 9.3132257461547852e-10 @@ -516,7 +525,7 @@ def get_dfdt(self): def set_dfdt(self, val ): sdfdt = val * 1073741824.0 - self.dfdt = ctypes.c_int32(int(sdfdt)) + self.dfdt = int(sdfdt) def asBuffer(self): return buffer(self)[:] @@ -536,7 +545,7 @@ def __new__(cls,*args, **kwargs ): return cls.from_buffer_copy(args[0]) return cls.from_buffer_copy(kwargs['buf']) else: - return super(ssd_data,cls).__new__(cls,*args,**kwags) + return super(ssd_data,cls).__new__(cls,*args,**kwargs) def __init__(self,data=None): pass @@ -561,7 +570,7 @@ def __new__(cls,*args, **kwargs ): return cls.from_buffer_copy(args[0]) return cls.from_buffer_copy(kwargs['buf']) else: - return super(aad_data,cls).__new__(cls,*args,**kwags) + return super(aad_data,cls).__new__(cls,*args,**kwargs) def __init__(self,data=None): pass @@ -594,7 +603,7 @@ def __new__(cls,*args, **kwargs ): return cls.from_buffer_copy(args[0]) return cls.from_buffer_copy(kwargs['buf']) else: - return super(sdds_header,cls).__new__(cls,*args,**kwags) + return super(sdds_header,cls).__new__(cls,*args,**kwargs) def __init__(self,data=None, skip_parity=True): self._skip_parity=skip_parity @@ -621,6 +630,46 @@ def inc(self, skip_parity=None): ## ## Format Identifier ## + def get_standardformat(self): + return self.formatid.sf + + def set_standardformat(self, sf=False ): + self.formatid.sf=0 + if sf: + self.formatid.sf=1 + + def get_startofsequence(self): + return self.formatid.sos + + def set_startofsequence(self, sos=False ): + self.formatid.sos=0 + if sos: + self.formatid.sos=1 + + def get_paritypacket(self): + return self.formatid.pp + + def set_paritypacket(self, pp=False ): + self.formatid.pp=0 + if pp: + self.formatid.pp=1 + + def get_originalformat(self): + return self.formatid.of + + def set_originalformat(self, of=False ): + self.formatid.of=0 + if of: + self.formatid.of=1 + + def get_spectralsense(self): + return self.formatid.ss + + def set_spectralsense(self, ss=False ): + self.formatid.ss=0 + if ss: + self.formatid.ss=1 + def get_complex(self): return self.formatid.cx @@ -635,14 +684,6 @@ def set_dmode(self,dm): def get_dmode(self): return self.formatid.dm - def set_spectralsense(self, ison=False ): - self.formatid.ss= 0 - if isone: - self.formatid.ss= 1 - - def get_spectralsense(self): - return self.formatid.ss - def get_vw(self): return self.formatid.vw @@ -667,42 +708,44 @@ def get_fsn(self): def set_fsn(self, v ): self.fsn.set(v) + def inc_fsn(self): + self.fsn.inc() + ## ## ttag - time tag ## def get_msptr( self ): - return self.ttag.info.msptr.get_msptr() + return self.ttag.get_msptr() def set_msptr( self, val ): - self.ttag.info.msptr.set_msptr(val) + self.ttag.set_msptr(val) def get_msdelta( self ): - return self.ttag.info.msptr.get_msdelta() + return self.ttag.get_msdelta() def set_msdelta( self, val ): - self.ttag.info.msptr.set_msdelta(val) + self.ttag.set_msdelta(val) def clear_msptr(self): - self.ttag.info.msptr.msptr = 0 - self.ttag.info.msptr.msdelta = 0 + self.ttag.clean_msptr() def set_msv(self, valid=True): - self.ttag.info.info.set_msv(valid) + self.ttag.set_msv(valid) def get_msv(self): - return self.ttag.info.info.get_msv() + return self.ttag.get_msv() def get_ttv(self): - return self.ttag.info.info.get_ttv() + return self.ttag.get_ttv() def set_ttv(self, valid=True): - self.ttag.info.info.set_ttv(valid) + self.ttag.set_ttv(valid) def get_sscv(self): - return self.ttag.info.info.get_sscv() + return self.ttag.get_sscv() def set_sscv(self, valid=True): - self.ttag.info.info.set_sscv(valid) + self.ttag.set_sscv(valid) def set_time(self, ps250, pf250 ): self.ttag.tstamp.ttag = ps250 @@ -778,7 +821,7 @@ def __new__(cls,*args, **kwargs ): return cls.from_buffer_copy(args[0]) return cls.from_buffer_copy(kwargs['buf']) else: - return super(sdds_sb_payload,cls).__new__(cls,*args,**kwags) + return super(sdds_sb_payload,cls).__new__(cls,*args,**kwargs) def __init__(self,data=None): pass @@ -814,7 +857,7 @@ def __new__(cls,*args, **kwargs ): return cls.from_buffer_copy(args[0]) return cls.from_buffer_copy(kwargs['buf']) else: - return super(sdds_cb_payload,cls).__new__(cls,*args,**kwags) + return super(sdds_cb_payload,cls).__new__(cls,*args,**kwargs) def __init__(self,data=None): pass @@ -850,7 +893,7 @@ def __new__(cls,*args, **kwargs ): return cls.from_buffer_copy(args[0]) return cls.from_buffer_copy(kwargs['buf']) else: - return super(sdds_si_payload,cls).__new__(cls,*args,**kwags) + return super(sdds_si_payload,cls).__new__(cls,*args,**kwargs) def __init__(self,data=None): pass @@ -885,7 +928,7 @@ def __new__(cls,*args, **kwargs ): return cls.from_buffer_copy(args[0]) return cls.from_buffer_copy(kwargs['buf']) else: - return super(sdds_ci_payload,cls).__new__(cls,*args,**kwags) + return super(sdds_ci_payload,cls).__new__(cls,*args,**kwargs) def __init__(self,data=None): pass @@ -920,7 +963,7 @@ def __new__(cls,*args, **kwargs ): return cls.from_buffer_copy(args[0]) return cls.from_buffer_copy(kwargs['buf']) else: - return super(sdds_sn_sample,cls).__new__(cls,*args,**kwags) + return super(sdds_sn_sample,cls).__new__(cls,*args,**kwargs) def __init__(self,data=None): pass @@ -946,7 +989,7 @@ def __new__(cls,*args, **kwargs ): return cls.from_buffer_copy(args[0]) return cls.from_buffer_copy(kwargs['buf']) else: - return super(sdds_sn_payload,cls).__new__(cls,*args,**kwags) + return super(sdds_sn_payload,cls).__new__(cls,*args,**kwargs) def __init__(self,data=None): pass @@ -984,7 +1027,7 @@ def __new__(cls,*args, **kwargs ): return cls.from_buffer_copy(args[0]) return cls.from_buffer_copy(kwargs['buf']) else: - return super(sdds_sf_payload,cls).__new__(cls,*args,**kwags) + return super(sdds_sf_payload,cls).__new__(cls,*args,**kwargs) def __init__(self,data=None): pass @@ -1025,7 +1068,7 @@ def __new__(cls,*args, **kwargs ): return cls.from_buffer_copy(args[0]) return cls.from_buffer_copy(kwargs['buf']) else: - return super(sdds_payload,cls).__new__(cls,*args,**kwags) + return super(sdds_payload,cls).__new__(cls,*args,**kwargs) def __init__(self,data=None): pass @@ -1070,7 +1113,7 @@ def __new__(cls,*args, **kwargs ): return cls.from_buffer_copy(args[0]) return cls.from_buffer_copy(kwargs['buf']) else: - return super(sdds_packet,cls).__new__(cls,*args,**kwags) + return super(sdds_packet,cls).__new__(cls,*args,**kwargs) def __init__(self,data=None, skip_parity=True): self._skip_parity=skip_parity @@ -1097,6 +1140,30 @@ def inc(self): ## ## Format Identifier ## + def get_standardformat(self): + return self.header.get_standardformat() + + def set_standardformat(self, sf=False ): + self.header.set_standardformat(sf) + + def get_startofsequence(self): + return self.header.get_startofsequence() + + def set_startofsequence(self, sos=False ): + self.header.set_startofsequence(sos) + + def get_paritypacket(self): + return self.header.get_paritypacket() + + def set_paritypacket(self, pp=False ): + self.header.set_paritypacket(pp) + + def get_originalformat(self): + return self.header.get_originalformat() + + def set_originalformat(self, of=False ): + self.header.set_originalformat(of) + def get_complex(self): return self.header.get_complex() @@ -1166,6 +1233,9 @@ def get_fsn(self): def set_fsn(self, v ): self.header.set_fsn(v) + def inc_fsn(self): + self.header.inc_fsn() + ## ## ttag - time tag ## @@ -1230,7 +1300,7 @@ def get_dfdt(self): return self.header.get_dfdt() def set_dfdt(self, freq): - self.freq.set_dfdt(freq) + self.header.set_dfdt(freq) def get_format(self): dm=self.header.get_dmode() diff --git a/redhawk/src/testing/tests/test_13_SDDS.py b/redhawk/src/testing/tests/test_13_SDDS.py index 75c287906..4d9c14a95 100644 --- a/redhawk/src/testing/tests/test_13_SDDS.py +++ b/redhawk/src/testing/tests/test_13_SDDS.py @@ -186,12 +186,12 @@ def setUp(self): def test_format_identifier_api(self): # get default format identifer.. sf=1, sos=1, dm=1 bps=8 all others 0 - res=binascii.unhexlify('2340') + res=binascii.a2b_hex('C108') formatid = format_identifier() self.assertEqual( formatid.asString(), res ) # assign from values sf=1, sos=1, dm =4, bps=16 - formatid= format_identifier.from_buffer_copy('\x83\x80') + formatid= format_identifier.from_buffer_copy('\xC4\x10') self.assertEqual( formatid.sf, 1 ) self.assertEqual( formatid.sos, 1 ) self.assertEqual( formatid.dm, 4 ) @@ -211,11 +211,45 @@ def test_format_identifier_api(self): formatid.set_dmode( 5 ) self.assertEqual( formatid.dm, 5 ) + + def test_format_identifier_packet(self): + pkt = sdds_pkt.sdds_packet() + + pkt.set_standardformat(True) + self.assertEquals(pkt.get_standardformat(),True) + + pkt.set_startofsequence(True) + self.assertEquals(pkt.get_startofsequence(),True) + + pkt.set_paritypacket(True) + self.assertEquals(pkt.get_paritypacket(),True) + + pkt.set_spectralsense(True) + self.assertEquals(pkt.get_spectralsense(),True) + + pkt.set_originalformat(True) + self.assertEquals(pkt.get_originalformat(),True) + + pkt.set_complex(True) + self.assertEquals(pkt.get_complex(),True) + + pkt.set_vw(True) + self.assertEquals(pkt.get_vw(),True) + + for x in [ 2, 4, 8, 12 ]: + pkt.set_bps(x) + self.assertEquals(pkt.get_bps(),x) + + for x in [ 0,1,2,5,6,7]: + pkt.set_dmode(x) + self.assertEquals(pkt.get_dmode(),x) + + def test_frame_sequence(self): # get default frame sequence == 0 - res=binascii.unhexlify('0000') + res=binascii.a2b_hex('0000') fsn = frame_sequence() self.assertEqual( fsn.asString(), res ) @@ -242,6 +276,40 @@ def test_frame_sequence(self): res=struct.pack("!H",0) self.assertEqual( fsn.asString(), res ) + + def test_frame_sequence_packet(self): + pkt = sdds_pkt.sdds_packet() + res=binascii.a2b_hex('0000') + self.assertEqual( pkt.header.fsn.asString(), res ) + + # test big endian format for number + seq=256 + res=struct.pack("!H",seq) + pkt.set_fsn(seq) + self.assertEqual( pkt.header.fsn.asString(), res ) + self.assertEqual( pkt.get_fsn(), seq ) + + # add one... + seq +=1 + res=struct.pack("!H",seq) + pkt.inc_fsn() + self.assertEqual( pkt.header.fsn.asString(), res ) + self.assertEqual( pkt.get_fsn(), seq ) + + # set for rollover + seq =65535 + res=struct.pack("!H",seq) + pkt.set_fsn(seq) + self.assertEqual( pkt.header.fsn.asString(), res ) + self.assertEqual( pkt.get_fsn(), seq ) + + # set for rollover + res=struct.pack("!H",0) + pkt.inc_fsn() + self.assertEqual( pkt.header.fsn.asString(), res ) + self.assertEqual( pkt.get_fsn(), 0 ) + + def test_msptr_data(self): # get default frame sequence == 0 @@ -267,58 +335,120 @@ def test_msptr_data(self): msptr.msdelta=msdelta_ self.assertEqual( msptr.asString(), res ) + + def test_msptr_packet(self): + pkt = sdds_pkt.sdds_packet() + + # get default frame sequence == 0 + msptr_=0 + msdelta_=0 + res=struct.pack("!HH",msptr_, msdelta_) + pkt.set_msptr(msptr_) + pkt.set_msdelta(msdelta_) + self.assertEqual( pkt.header.ttag.info.asString(), res ) + self.assertEqual( pkt.get_msptr(), msptr_ ) + self.assertEqual( pkt.get_msdelta(), msdelta_ ) + + # test big endian format for number + msptr_=256 + msdelta_=256 + res=struct.pack("!HH",msptr_, msdelta_) + pkt.set_msptr(msptr_) + pkt.set_msdelta(msdelta_) + self.assertEqual( pkt.header.ttag.info.asString(), res ) + self.assertEqual( pkt.get_msptr(), msptr_ ) + self.assertEqual( pkt.get_msdelta(), msdelta_ ) + + # set max value + msptr_=2047 + msdelta_=65535 + res=struct.pack("!HH",msptr_, msdelta_) + pkt.set_msptr(msptr_) + pkt.set_msdelta(msdelta_) + self.assertEqual( pkt.header.ttag.info.asString(), res ) + self.assertEqual( pkt.get_msptr(), msptr_ ) + self.assertEqual( pkt.get_msdelta(), msdelta_ ) + + def test_ttag_info_struct(self): # get default - res=binascii.unhexlify('00000000') + res=binascii.a2b_hex('00000000') ttag_info = ttag_info_struct() self.assertEqual( ttag_info.asString(), res ) # test msv - res=binascii.unhexlify('00800000') + res=binascii.a2b_hex('80000000') ttag_info.set_msv() self.assertEqual( ttag_info.asString(), res ) - res=binascii.unhexlify('00000000') + res=binascii.a2b_hex('00000000') ttag_info.set_msv(False) self.assertEqual( ttag_info.asString(), res ) # test ttv - res=binascii.unhexlify('00400000') + res=binascii.a2b_hex('40000000') ttag_info.set_ttv() self.assertEqual( ttag_info.asString(), res ) - res=binascii.unhexlify('00000000') + res=binascii.a2b_hex('00000000') ttag_info.set_ttv(False) self.assertEqual( ttag_info.asString(), res ) # test sscv - res=binascii.unhexlify('0000000') + res=binascii.a2b_hex('20000000') ttag_info.set_sscv() self.assertEqual( ttag_info.asString(), res ) - res=binascii.unhexlify('00000000') + res=binascii.a2b_hex('00000000') ttag_info.set_sscv(False) self.assertEqual( ttag_info.asString(), res ) # test pi - res=binascii.unhexlify('08000000') + res=binascii.a2b_hex('10000000') ttag_info.set_pi() self.assertEqual( ttag_info.asString(), res ) - res=binascii.unhexlify('00000000') + res=binascii.a2b_hex('00000000') ttag_info.set_pi(False) self.assertEqual( ttag_info.asString(), res ) # test peo - res=binascii.unhexlify('10000000') + res=binascii.a2b_hex('08000000') ttag_info.set_peo(True) self.assertEqual( ttag_info.asString(), res ) - res=binascii.unhexlify('00000000') + res=binascii.a2b_hex('00000000') ttag_info.set_peo(False) self.assertEqual( ttag_info.asString(), res ) + + def test_ttag_info_packet(self): + pkt = sdds_pkt.sdds_packet() + + res=binascii.a2b_hex('00000000') + self.assertEqual( pkt.header.ttag.info.asString(), res ) + self.assertEqual( pkt.get_msv(), 0 ) + + res=binascii.a2b_hex('80000000') + pkt.set_msv() + self.assertEqual( pkt.header.ttag.info.asString(), res ) + self.assertEqual( pkt.get_msv(), 1 ) + pkt.set_msv(False) + + res=binascii.a2b_hex('40000000') + pkt.set_ttv() + self.assertEqual( pkt.header.ttag.info.asString(), res ) + self.assertEqual( pkt.get_ttv(), 1 ) + pkt.set_ttv(False) + + res=binascii.a2b_hex('20000000') + pkt.set_sscv() + self.assertEqual( pkt.header.ttag.info.asString(), res ) + self.assertEqual( pkt.get_sscv(), 1 ) + pkt.set_sscv(False) + + def test_ttag_values(self): ttag_=0 ttage_=0 @@ -334,6 +464,32 @@ def test_ttag_values(self): ttag_val.ttage=ttage_ self.assertEqual( ttag_val.asString(), res ) + def test_ttag_values_packet(self): + pkt = sdds_pkt.sdds_packet() + + ttag_=0 + ttage_=0 + sddstime=Time() + sddstime.set(ttag_,ttage_) + res=struct.pack("!QI", ttag_, ttage_) + pkt.set_time( ttag_, ttage_) + self.assertEqual( pkt.header.ttag.tstamp.asString(), res ) + self.assertEqual( pkt.get_SDDSTime(), sddstime ) + pkt.set_SDDSTime( sddstime ) + self.assertEqual( pkt.get_SDDSTime(), sddstime ) + + ttag_= 4294967296 + ttage_= 8388608 + sddstime=Time() + sddstime.set(ttag_,ttage_) + res=struct.pack("!QI", ttag_, ttage_) + res=struct.pack("!QI", ttag_, ttage_) + pkt.set_time( ttag_, ttage_) + self.assertEqual( pkt.header.ttag.tstamp.asString(), res ) + self.assertEqual( pkt.get_SDDSTime(), sddstime ) + pkt.set_SDDSTime( sddstime ) + self.assertEqual( pkt.get_SDDSTime(), sddstime ) + def test_ttag_info(self): msptr_=0 msdelta_=0 @@ -355,6 +511,117 @@ def test_ttag_info(self): ttag_val.tstamp.ttage=ttage_ self.assertEqual( ttag_val.asString(), res ) + def test_ttag_info_msv(self): + msptr_=0 + msdelta_=0 + ttag_=0 + ttage_=0 + res=struct.pack("!HHQI", msptr_, msdelta_, ttag_, ttage_) + ttag_val = ttag_info() + self.assertEqual( ttag_val.asString(), res ) + + # test big endian format for number + ttag_= 4294967296 + ttage_= 8388608 + msptr_=2047 + msdelta_=256 + res=struct.pack("!HHQI", msptr_, msdelta_, ttag_, ttage_) + ttag_val.info.msptr.msptr=msptr_ + ttag_val.info.msptr.msdelta=msdelta_ + ttag_val.tstamp.ttag=ttag_ + ttag_val.tstamp.ttage=ttage_ + self.assertEqual( ttag_val.asString(), res ) + + ttag_val.info.info.set_msv() + + res=struct.pack("!QI", ttag_, ttage_) + # first bit is msv + tinfo=binascii.a2b_hex('87FF0100') + res=tinfo+res + self.assertEqual( ttag_val.asString(), res ) + + + def test_ttag_info_ttv(self): + msptr_=0 + msdelta_=0 + ttag_=0 + ttage_=0 + res=struct.pack("!HHQI", msptr_, msdelta_, ttag_, ttage_) + ttag_val = ttag_info() + self.assertEqual( ttag_val.asString(), res ) + + # test big endian format for number + ttag_= 4294967296 + ttage_= 8388608 + msptr_=2047 + msdelta_=256 + res=struct.pack("!HHQI", msptr_, msdelta_, ttag_, ttage_) + ttag_val.info.msptr.msptr=msptr_ + ttag_val.info.msptr.msdelta=msdelta_ + ttag_val.tstamp.ttag=ttag_ + ttag_val.tstamp.ttage=ttage_ + self.assertEqual( ttag_val.asString(), res ) + + ttag_val.info.info.set_ttv() + + res=struct.pack("!QI", ttag_, ttage_) + # first bit is msv + tinfo=binascii.a2b_hex('47FF0100') + res=tinfo+res + self.assertEqual( ttag_val.asString(), res ) + + + def test_ttag_info_sscv(self): + msptr_=0 + msdelta_=0 + ttag_=0 + ttage_=0 + res=struct.pack("!HHQI", msptr_, msdelta_, ttag_, ttage_) + ttag_val = ttag_info() + self.assertEqual( ttag_val.asString(), res ) + + # test big endian format for number + ttag_= 4294967296 + ttage_= 8388608 + msptr_=2047 + msdelta_=256 + res=struct.pack("!HHQI", msptr_, msdelta_, ttag_, ttage_) + ttag_val.info.msptr.msptr=msptr_ + ttag_val.info.msptr.msdelta=msdelta_ + ttag_val.tstamp.ttag=ttag_ + ttag_val.tstamp.ttage=ttage_ + self.assertEqual( ttag_val.asString(), res ) + + ttag_val.info.info.set_sscv() + + res=struct.pack("!QI", ttag_, ttage_) + # first bit is msv + tinfo=binascii.a2b_hex('27FF0100') + res=tinfo+res + self.assertEqual( ttag_val.asString(), res ) + + + def test_ttag_info_all_bits(self): + msptr_=0 + msdelta_=0 + ttag_=0 + ttage_=0 + res=struct.pack("!HHQI", msptr_, msdelta_, ttag_, ttage_) + ttag_val = ttag_info() + self.assertEqual( ttag_val.asString(), res ) + + # test big endian format for number + ttag_= 4294967296 + ttage_= 8388608 + msptr_=2047 + msdelta_=256 + res=struct.pack("!HHQI", msptr_, msdelta_, ttag_, ttage_) + ttag_val.info.msptr.msptr=msptr_ + ttag_val.info.msptr.msdelta=msdelta_ + ttag_val.tstamp.ttag=ttag_ + ttag_val.tstamp.ttage=ttage_ + self.assertEqual( ttag_val.asString(), res ) + ttag_val = ttag_info() ttag_= 4294967296 ttage_= 8388608 @@ -368,7 +635,43 @@ def test_ttag_info(self): ttag_val.info.info.set_ttv() ttag_val.info.info.set_sscv() res=struct.pack("!QI", ttag_, ttage_) - tinfo=binascii.unhexlify('07370100') + tinfo=binascii.a2b_hex('E7FF0100') res=tinfo+res self.assertEqual( ttag_val.asString(), res ) + def test_ssc_info_struct(self): + + ssc = sdds_pkt.ssc_info_struct() + self.assertEqual(ssc.get_freq(),0) + self.assertEqual(ssc.get_dfdt(),0) + + ssc.set_freq(5000000) + self.assertEqual(ssc.get_freq(),5000000) + + ssc.set_dfdt(.15) + self.assertAlmostEqual(ssc.get_dfdt(),.15, places=3) + + def test_ssc_info_header(self): + + ssc = sdds_pkt.sdds_header() + self.assertEqual(ssc.get_freq(),0) + self.assertEqual(ssc.get_dfdt(),0) + + ssc.set_freq(5000000) + self.assertEqual(ssc.get_freq(),5000000) + + ssc.set_dfdt(.15) + self.assertAlmostEqual(ssc.get_dfdt(),.15, places=3) + + def test_ssc_info_packet(self): + + ssc = sdds_pkt.sdds_packet() + self.assertEqual(ssc.get_freq(),0) + self.assertEqual(ssc.get_dfdt(),0) + + ssc.set_freq(5000000) + self.assertEqual(ssc.get_freq(),5000000) + + ssc.set_dfdt(.15) + self.assertAlmostEqual(ssc.get_dfdt(),.15, places=3) + From 0c525a0e5fbff0c245c0f4293a5eed6c761770e5 Mon Sep 17 00:00:00 2001 From: 8530 <8530@vm-131.vsi-corp.com> Date: Fri, 9 Jun 2017 14:22:43 -0400 Subject: [PATCH 0816/1644] resolve startup issue in centos 7 --- redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp b/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp index b61695a6f..8f5a96285 100644 --- a/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp @@ -70,7 +70,7 @@ static const ComponentInstantiation* findComponentInstantiation (const std::vect return 0; } -PREPARE_LOGGING(DomainManager_impl) +rh_logger::LoggerPtr DomainManager_impl::__logger; // If _overrideDomainName == NULL read the domain name from the DMD file DomainManager_impl::DomainManager_impl (const char* dmdFile, const char* _rootpath, const char* domainName, @@ -84,6 +84,7 @@ DomainManager_impl::DomainManager_impl (const char* dmdFile, const char* _rootpa _strict_spd_validation(false), _bindToDomain(bindToDomain) { + __logger = rh_logger::Logger::getResourceLogger("DomainManager_impl"); TRACE_ENTER(DomainManager_impl) LOG_TRACE(DomainManager_impl, "Looking for DomainManager POA"); From d3ef2cc3200867d590fda460fb009ccabde868b6 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Fri, 9 Jun 2017 14:29:38 -0400 Subject: [PATCH 0817/1644] Refs CF-1759. Improved swith processing for --user and --group --- redhawk/src/control/framework/nodebooter.cpp | 90 ++++++++----------- .../src/testing/tests/test_01_nodeBooter.py | 44 ++++++++- 2 files changed, 80 insertions(+), 54 deletions(-) diff --git a/redhawk/src/control/framework/nodebooter.cpp b/redhawk/src/control/framework/nodebooter.cpp index aa20dd2a7..a94bca3d8 100644 --- a/redhawk/src/control/framework/nodebooter.cpp +++ b/redhawk/src/control/framework/nodebooter.cpp @@ -154,7 +154,7 @@ void loadPRFExecParams (const std::string& prfFile, ExecParams& execParams) const ossie::SimpleProperty* simpleProp; simpleProp = dynamic_cast(*prop); if (!simpleProp) { - LOG_WARN(nodebooter, "Only execparams of type \"simple\" supported"); + LOG_WARN(nodebooter, "Only execp arams of type \"simple\" supported"); continue; } else if (!simpleProp->getValue()) { continue; @@ -334,6 +334,7 @@ static void setOwners(const std::string& user, const std::string& group) err << "]: " << strerror(errno); throw std::runtime_error(err.str()); } + setgid(gids[0]); std::cout << "Running as group: [ "; for (unsigned int gr_idx=0; gr_idx < groups.size(); gr_idx++) { @@ -368,6 +369,7 @@ static void setOwners(const std::string& user, const std::string& group) } else { setgroups(ngroups, groups); } + setgid(groups[0]); std::cout << "Running as group: [ "; for (unsigned int gr_idx=0; gr_idx < ngroups; gr_idx++) { std::cout << getgrgid(groups[gr_idx])->gr_name << "(gid=" << groups[gr_idx] << ") "; @@ -852,11 +854,8 @@ int main(int argc, char* argv[]) dmdFile = tmpdmdfile; } } - startDomainManagerRequested = true; - } - - if( strcmp( argv[i], "-d" ) == 0 ) { + } else if( strcmp( argv[i], "-d" ) == 0 ) { if( i + 1 < argc && strcmp( argv[i + 1], "--" ) != 0) { dcdFile = argv[i+1]; if( dcdFile.find(".dcd.xml") == string::npos ) { @@ -870,9 +869,7 @@ int main(int argc, char* argv[]) usage(); exit(EXIT_FAILURE); } - } - - if( strcmp( argv[i], "-sdrroot" ) == 0 ) { + } else if( strcmp( argv[i], "-sdrroot" ) == 0 ) { if( i + 1 < argc && strcmp( argv[i + 1], "--" ) != 0) { sdrRoot = argv[i+1]; } else { @@ -880,9 +877,7 @@ int main(int argc, char* argv[]) usage(); exit(EXIT_FAILURE); } - } - - if( strcmp( argv[i], "-sdrcache" ) == 0 ) { + } else if( strcmp( argv[i], "-sdrcache" ) == 0 ) { if( i + 1 < argc && strcmp( argv[i + 1], "--" ) != 0) { sdrCache = argv[i+1]; } else { @@ -890,9 +885,7 @@ int main(int argc, char* argv[]) usage(); exit(EXIT_FAILURE); } - } - - if( strcmp( argv[i], "-domainname" ) == 0 ) { + } else if( strcmp( argv[i], "-domainname" ) == 0 ) { if( i + 1 < argc && strcmp( argv[i + 1], "--" ) != 0) { domainName = argv[i+1]; std::cerr << "[nodeBooter] warning: -domainname is deprecated. Please use --domainname\n"; @@ -902,9 +895,7 @@ int main(int argc, char* argv[]) usage(); exit(EXIT_FAILURE); } - } - - if( strcmp( argv[i], "--domainname" ) == 0 ) { + } else if( strcmp( argv[i], "--domainname" ) == 0 ) { if( i + 1 < argc && strcmp( argv[i + 1], "--" ) != 0) { domainName = argv[i+1]; } @@ -913,15 +904,9 @@ int main(int argc, char* argv[]) usage(); exit(EXIT_FAILURE); } - } - - - if (( strcmp( argv[i], "--bindapps" ) == 0 )) { + } else if (( strcmp( argv[i], "--bindapps" ) == 0 )) { bind_apps = true; - } - - - if (( strcmp( argv[i], "-log4cxx" ) == 0 ) || ( strcmp( argv[i], "-logcfgfile" ) == 0 )) { + } else if (( strcmp( argv[i], "-log4cxx" ) == 0 ) || ( strcmp( argv[i], "-logcfgfile" ) == 0 )) { if( i + 1 Date: Mon, 12 Jun 2017 14:42:35 -0400 Subject: [PATCH 0818/1644] Fix regression with timestamp offsets in DataSink.getData(); get rid of duplicative tests --- .../python/ossie/utils/bulkio/bulkio_data_helpers.py | 8 +++++++- .../base/framework/python/ossie/utils/sb/io_helpers.py | 1 - redhawk/src/testing/tests/test_14_bluefile.py | 3 --- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/bulkio/bulkio_data_helpers.py b/redhawk/src/base/framework/python/ossie/utils/bulkio/bulkio_data_helpers.py index 417de9756..806de8de3 100644 --- a/redhawk/src/base/framework/python/ossie/utils/bulkio/bulkio_data_helpers.py +++ b/redhawk/src/base/framework/python/ossie/utils/bulkio/bulkio_data_helpers.py @@ -790,15 +790,21 @@ def retrieveData(self, length=None): if length == None: goal = _stream.samplesAvailable() self.port_cond.release() + sample_offset = 0 while True: _block = _stream.read(count=length) if not _block: break retval += _block.data() - rettime += _block.getTimestamps() + # The block timestamp offsets are relative to the start of that + # block, so adjust for any previous data offsets + rettime += [(off+sample_offset, ts) for off, ts in _block.getTimestamps()] goal_offset = 1 if _block.sri().subsize != 0: goal_offset = _block.sri().subsize + sample_offset += sum(len(frame) for frame in _block.data()) + else: + sample_offset += len(_block.data()) if len(retval) == goal/goal_offset: break finally: diff --git a/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py b/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py index ddd1bae4a..8a3d09c28 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py +++ b/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py @@ -1579,7 +1579,6 @@ def pushThread(self): candidateSri.keywords = keywords if self._sri==None or not compareSRI(candidateSri, self._sri): - print "New SRI ", candidateSri, " mode = ", candidateSri.mode self._sri = _copy.copy(candidateSri) self._pushSRIAllConnectedPorts(sri = self._sri) diff --git a/redhawk/src/testing/tests/test_14_bluefile.py b/redhawk/src/testing/tests/test_14_bluefile.py index eaa75f47a..3c170c103 100644 --- a/redhawk/src/testing/tests/test_14_bluefile.py +++ b/redhawk/src/testing/tests/test_14_bluefile.py @@ -389,9 +389,6 @@ def test_FileSinkTimecode(self): time_out = bluefile_helpers.j1950_to_unix(hdr['timecode']) self.assertAlmostEqual(time_in, time_out) - -class BlueFileHelpersKW(BlueFileHelpers): - def test_keywords_retrieval_int(self): filename='bf-kw-test.out' self._tempfiles.append(filename) From 246f386c497b48ba6ac82b6fe006ff393a28c2ef Mon Sep 17 00:00:00 2001 From: 8530 <8530@vm-131.vsi-corp.com> Date: Wed, 14 Jun 2017 13:48:21 -0400 Subject: [PATCH 0819/1644] fix for variance in startup messages, CF-1765 --- .../testing/tests/test_13_RedhawkModule.py | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/redhawk/src/testing/tests/test_13_RedhawkModule.py b/redhawk/src/testing/tests/test_13_RedhawkModule.py index 6e860c9f3..384dc2af8 100644 --- a/redhawk/src/testing/tests/test_13_RedhawkModule.py +++ b/redhawk/src/testing/tests/test_13_RedhawkModule.py @@ -125,12 +125,15 @@ def preconditions(self): self.assertNotEqual(self._devMgr, None, "DeviceManager not available") def test_API_remap(self): + import _omnipy + v=int(_omnipy.__version__[0]) orig_api = dir(self._rhDom.ref) remap_api = dir(self._rhDom) not_remap = ['_NP_RepositoryId','_Object__release','__getattribute__','__getstate__','__hash__','__setattr__','__setstate__','__weakref__', '__methods__','_duplicate','_dynamic_op','_hash','_is_a','_is_equivalent','_narrow','_nil','_obj', '__del__','__omni_obj','_release','_unchecked_narrow', '_non_existent', - 'retrieve_records', 'retrieve_records_by_date', 'retrieve_records_from_date' ] + 'retrieve_records', 'retrieve_records_by_date', 'retrieve_records_from_date' ] + if v > 3 : not_remap += ['log_level'] for entry in orig_api: if entry in not_remap: continue @@ -1061,6 +1064,8 @@ def _try_kick_domain(self, logcfg, epatterns, debug_level=None, kick_device_man except: traceback.print_exc() pass + + time.sleep(2) new_stdout=open(tmpfile,'r') for k, epat in epatterns.iteritems(): epat.setdefault('results',[]) @@ -1079,6 +1084,12 @@ def _try_kick_domain(self, logcfg, epatterns, debug_level=None, kick_device_man lmatch = len(pat['results']) == len(pat['match']) and pat['results'] == pat['match'] self.assertEqual(lmatch, True ) + if type(pat['match']) == tuple: + reslen=len(pat['results']) + c=pat['match'] + res=eval("'" + str(reslen) + " " + str(c[0]) + " " + str(c[1]) + "'") + self.assertTrue(res) + if type(pat['match']) == int: # ignore if pat['match'] == -1 : @@ -1152,7 +1163,7 @@ def test_kick_warn(self): def test_kick_warn_both(self): self._try_kick_domain('log4j.kickdomain.cfg', epatterns={ "no" : { 'patterns': [" TRACE ", " DEBUG " ], 'match': [] }, - "no2" : { 'patterns': [ " INFO ", ], 'match': 12 }, + "no2" : { 'patterns': [ " INFO ", ], 'match': ("<=", 12 ) }, "yes" : { 'patterns': [ " WARN ", " ERROR ", " FATAL " ], 'match': -1 }, }, debug_level="WARN", @@ -1171,7 +1182,7 @@ def test_kick_error(self): def test_kick_error_both(self): self._try_kick_domain('log4j.kickdomain.cfg', epatterns={ "no" : { 'patterns': [" TRACE ", " DEBUG " ] , 'match': [] }, - "no2" : { 'patterns': [ " INFO ", " WARN " ], 'match': 14 }, + "no2" : { 'patterns': [ " INFO ", " WARN " ], 'match': ('<=', 18) }, "yes" : { 'patterns': [ " ERROR ", " FATAL " ], 'match': -1 }, }, debug_level="ERROR", @@ -1190,7 +1201,7 @@ def test_kick_fatal(self): def test_kick_fatal_both(self): self._try_kick_domain('log4j.kickdomain.cfg', epatterns={ "no" : { 'patterns': [" TRACE ", " DEBUG ", " ERROR " ], 'match': [] }, - "no2" : { 'patterns': [ " INFO ", " WARN " ], 'match': 14 }, + "no2" : { 'patterns': [ " INFO ", " WARN " ], 'match': ('<=', 18 ) }, "yes" : { 'patterns': [ " FATAL " ], 'match': -1 }, }, debug_level="FATAL", From 301eb454641818be850378a4b2c0789b8612d25a Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 15 Jun 2017 09:26:14 -0400 Subject: [PATCH 0820/1644] CF-1772 Remove unneeded import in TunerControl.idl to fix Python IDL import problem --- frontendInterfaces/idl/redhawk/FRONTEND/TunerControl.idl | 1 - 1 file changed, 1 deletion(-) diff --git a/frontendInterfaces/idl/redhawk/FRONTEND/TunerControl.idl b/frontendInterfaces/idl/redhawk/FRONTEND/TunerControl.idl index 3cddb1eee..181411afc 100644 --- a/frontendInterfaces/idl/redhawk/FRONTEND/TunerControl.idl +++ b/frontendInterfaces/idl/redhawk/FRONTEND/TunerControl.idl @@ -23,7 +23,6 @@ #include "redhawk/FRONTEND/Frontend.idl" #include "ossie/BULKIO/bulkioDataTypes.idl" -#include "ossie/CF/PortTypes.idl" module FRONTEND { From b1da70c08279ce15d887647ee1eca4a86eedbdb0 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 15 Jun 2017 12:55:51 -0400 Subject: [PATCH 0821/1644] Fix compilation warning --- redhawk/src/base/framework/prop_helpers.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/redhawk/src/base/framework/prop_helpers.cpp b/redhawk/src/base/framework/prop_helpers.cpp index 4d4fb169b..54e7c6ae6 100644 --- a/redhawk/src/base/framework/prop_helpers.cpp +++ b/redhawk/src/base/framework/prop_helpers.cpp @@ -400,11 +400,10 @@ namespace redhawk { unsigned int minute; double second; int retval = sscanf(formatted.c_str(), "%d:%d:%d::%d:%d:%lf",&year,&month,&day,&hour,&minute,&second); - CF::UTCTime utctime; if (retval != 6) { - utctime.tcstatus=0; - return utctime; + return notSet(); } + CF::UTCTime utctime; utctime.tcstatus=1; struct tm t = {0}; t.tm_year = year - 1900; From 4206c74554908dbffbd81c08ed36d73ccae2c6f4 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 15 Jun 2017 13:07:42 -0400 Subject: [PATCH 0822/1644] CF-1774 Always launch the domain with persistence disabled in redhawk.kickDomain() --- .../src/base/framework/python/ossie/utils/redhawk/base.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/redhawk/base.py b/redhawk/src/base/framework/python/ossie/utils/redhawk/base.py index 714f1d8c0..ca4996ed1 100644 --- a/redhawk/src/base/framework/python/ossie/utils/redhawk/base.py +++ b/redhawk/src/base/framework/python/ossie/utils/redhawk/base.py @@ -110,7 +110,11 @@ def kickDomain(domain_name=None, kick_device_managers=True, device_managers=[], if debug_level: args.append('-debug') args.append(str(ConvertLevelNameToDebugLevel(debug_level))) - + + # Unconditionally turn off persistence; if persistence support is desired, + # a "dburi" argument can be added + args.append('--nopersist') + if domain_name != None: args.append('--domainname') args.append(domain_name) From acbed71793d461fb6058312330d78b85373948fb Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 15 Jun 2017 14:56:50 -0400 Subject: [PATCH 0823/1644] CF-1773 Restore support for providing SDRROOT-relative DCD paths to redhawk.kickDomain() --- .../python/ossie/utils/redhawk/base.py | 52 +++++++++++-------- .../testing/tests/test_13_RedhawkModule.py | 28 ++++++++++ 2 files changed, 59 insertions(+), 21 deletions(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/redhawk/base.py b/redhawk/src/base/framework/python/ossie/utils/redhawk/base.py index ca4996ed1..be7c5400f 100644 --- a/redhawk/src/base/framework/python/ossie/utils/redhawk/base.py +++ b/redhawk/src/base/framework/python/ossie/utils/redhawk/base.py @@ -79,6 +79,31 @@ def _cleanup_domain(): atexit.register(_cleanup_domain) +def _getDCDFile(sdrroot, dcdFile): + """ + Try to find the DCD file, either as an absolute path or relative to SDRROOT + """ + # The DCD file may just be a directory name under $SDRROOT/dev/nodes + if not dcdFile.endswith('.dcd.xml'): + # Path did not include a final DCD file + node_path = _os.path.join(sdrroot, 'dev/nodes/') + dcdFile + node_path += '/DeviceManager.dcd.xml' + if _os.path.exists(node_path): + return node_path + + # If the file exists as-is, return it + if _os.path.exists(dcdFile): + return dcdFile + + # Try an SDR-relative path + sdr_path = _os.path.join(sdrroot, 'dev/') + dcdFile + if _os.path.exists(sdr_path): + return sdr_path + + # Could not fine any matching path + return None + + def kickDomain(domain_name=None, kick_device_managers=True, device_managers=[], detached=False, sdrroot=None, stdout=None, logfile=None, debug_level=None, device_managers_debug_levels=[]): """Kick-start a REDHAWK domain. domain_name: the name that should be used @@ -166,30 +191,16 @@ def kickDomain(domain_name=None, kick_device_managers=True, device_managers=[], break if foundDCD: device_managers.append(directory[len(sdrroot)+4:]+'/'+filename) - else: - dm_list=[] - for dm in device_managers: - base = sdrroot + '/dev/nodes' - fname = dm - if dm.startswith("/") == False: - fname = base + '/' + dm - try: - if fname.endswith(".dcd.xml") == False: - fname = fname + "/DeviceManager.dcd.xml" - f=open(fname) - dm_list.append(fname) - f.close() - except: - #traceback.print_exc() - print "Unable to locate DCD file for :" + dm + " file: " + fname - device_managers = dm_list + for idx, device_manager in enumerate(device_managers): + dcd_file = _getDCDFile(sdrroot, device_manager) + if not dcd_file: + print "Unable to locate DCD file for '%s'" % device_manager + continue - idx=0 - for device_manager in device_managers: args = ['nodeBooter'] args.append('-d') - args.append(device_manager) + args.append(dcd_file) args.append('-sdrroot') args.append(sdrroot) args.append('--domainname') @@ -204,7 +215,6 @@ def kickDomain(domain_name=None, kick_device_managers=True, device_managers=[], if dlevel: args.append('-debug') args.append(str(ConvertLevelNameToDebugLevel(dlevel))) - idx = idx + 1 sp = _utils.Popen(args, executable=None, cwd=_os.getcwd(), close_fds=True, stdin=_devnull, stdout=stdout_fp, preexec_fn=_os.setpgrp) dm_procs.append( _envContainer(sp, stdout_fp) ) diff --git a/redhawk/src/testing/tests/test_13_RedhawkModule.py b/redhawk/src/testing/tests/test_13_RedhawkModule.py index 384dc2af8..54023556d 100644 --- a/redhawk/src/testing/tests/test_13_RedhawkModule.py +++ b/redhawk/src/testing/tests/test_13_RedhawkModule.py @@ -1209,3 +1209,31 @@ def test_kick_fatal_both(self): dev_mgrs = [ 'test_BasicTestDevice_node', "test_BasicTestDevice2_node" ], dev_mgr_levels= [ "FATAL", "FATAL" ] ) + + def test_kick_devmgr_path(self): + """ + Test $SDRROOT/dev relative paths for DeviceManagers in kickDomain() + """ + dom = redhawk.kickDomain(domain_name=scatest.getTestDomainName(), + kick_device_managers=True, + device_managers=['/nodes/test_GPP_node/DeviceManager.dcd.xml']) + + def check_devmgr(): + return len(dom.devMgrs) == 1 + + self.assertPredicateWithWait(check_devmgr, 'test_GPP_node did not launch') + self.assertEqual(dom.devMgrs[0].label, 'test_GPP_node') + + def test_kick_devmgr_name(self): + """ + Test using node names for DeviceManagers in kickDomain() + """ + dom = redhawk.kickDomain(domain_name=scatest.getTestDomainName(), + kick_device_managers=True, + device_managers=['test_GPP_node']) + + def check_devmgr(): + return len(dom.devMgrs) == 1 + + self.assertPredicateWithWait(check_devmgr, 'test_GPP_node did not launch') + self.assertEqual(dom.devMgrs[0].label, 'test_GPP_node') From 591a1ebed3b15c85f7e805428230579d414d648e Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 15 Jun 2017 16:52:30 -0400 Subject: [PATCH 0824/1644] CF-1775 Prevent hangs in DataSink.getData() --- .../ossie/utils/bulkio/bulkio_data_helpers.py | 11 +++++------ .../python/ossie/utils/sb/io_helpers.py | 2 +- redhawk/src/testing/tests/test_13_TestSB.py | 17 +++++++++++++++++ 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/bulkio/bulkio_data_helpers.py b/redhawk/src/base/framework/python/ossie/utils/bulkio/bulkio_data_helpers.py index 806de8de3..e96fd0665 100644 --- a/redhawk/src/base/framework/python/ossie/utils/bulkio/bulkio_data_helpers.py +++ b/redhawk/src/base/framework/python/ossie/utils/bulkio/bulkio_data_helpers.py @@ -790,7 +790,7 @@ def retrieveData(self, length=None): if length == None: goal = _stream.samplesAvailable() self.port_cond.release() - sample_offset = 0 + samples_read = 0 while True: _block = _stream.read(count=length) if not _block: @@ -798,14 +798,13 @@ def retrieveData(self, length=None): retval += _block.data() # The block timestamp offsets are relative to the start of that # block, so adjust for any previous data offsets - rettime += [(off+sample_offset, ts) for off, ts in _block.getTimestamps()] + rettime += [(off+samples_read, ts) for off, ts in _block.getTimestamps()] goal_offset = 1 if _block.sri().subsize != 0: - goal_offset = _block.sri().subsize - sample_offset += sum(len(frame) for frame in _block.data()) + samples_read += sum(len(frame) for frame in _block.data()) else: - sample_offset += len(_block.data()) - if len(retval) == goal/goal_offset: + samples_read += len(_block.data()) + if samples_read >= goal: break finally: pass diff --git a/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py b/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py index 8a3d09c28..4b54bd346 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py +++ b/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py @@ -1838,7 +1838,7 @@ def getData(self, length=None, eos_block=False, tstamps=False): element is the data set and the second element is a series of tuples containing the element index number and the timestamp for that index ''' - _warnings.warn("This function is deprecated. Use getCurrentStream instead") + _warnings.warn("This function is deprecated. Use getCurrentStream instead", DeprecationWarning) isChar = self._sink.port_type == _BULKIO__POA.dataChar diff --git a/redhawk/src/testing/tests/test_13_TestSB.py b/redhawk/src/testing/tests/test_13_TestSB.py index 5c20d641f..5c5e8fc9e 100644 --- a/redhawk/src/testing/tests/test_13_TestSB.py +++ b/redhawk/src/testing/tests/test_13_TestSB.py @@ -2479,6 +2479,23 @@ def test_SubsizeComplex(self): self.assertEqual(len(recData),_frames/2) self.assertEqual(len(recData[0]),_subsize*2) + def test_SubsizeComplexNoEOS(self): + # Test interleaved-to-complex + _subsize = 10 + _frames = 4 + inData = range(_subsize * _frames) + src=sb.DataSource(dataFormat='short',subsize=_subsize) + snk=sb.DataSink() + sb.start() + src.connect(snk) + src.push(inData,complexData=True) + + wait_on_data(snk, 1) + recData = snk.getData() + + self.assertEqual(len(recData),_frames/2) + self.assertEqual(len(recData[0]),_subsize*2) + def test_DataSinkChar(self): src=sb.DataSource(dataFormat='char') snk=sb.DataSink() From 052f6d209edd4138cbf1ac5536b28c2c9581e74f Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 16 Jun 2017 13:37:37 -0400 Subject: [PATCH 0825/1644] Revert changes for CF-350, due to new CA test failures that resulted --- .../ossie/utils/bulkio/bulkio_data_helpers.py | 601 +++--------------- .../python/ossie/utils/sb/io_helpers.py | 43 +- redhawk/src/testing/tests/test_13_TestSB.py | 214 +------ 3 files changed, 118 insertions(+), 740 deletions(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/bulkio/bulkio_data_helpers.py b/redhawk/src/base/framework/python/ossie/utils/bulkio/bulkio_data_helpers.py index e96fd0665..32aadab81 100644 --- a/redhawk/src/base/framework/python/ossie/utils/bulkio/bulkio_data_helpers.py +++ b/redhawk/src/base/framework/python/ossie/utils/bulkio/bulkio_data_helpers.py @@ -32,7 +32,7 @@ from bulkio.bulkioInterfaces import BULKIO, BULKIO__POA except: pass -from ossie.utils import _uuid, rhtime +from ossie.utils import _uuid logging.basicConfig() log = logging.getLogger(__name__) @@ -195,395 +195,7 @@ def run(self, data, sri=None, pktsize=1024, startTime=0.0, sampleRate=1.0, compl T = BULKIO.PrecisionUTCTime(BULKIO.TCM_CPU, BULKIO.TCS_VALID, 0.0, int(currentSampleTime), currentSampleTime - int(currentSampleTime)) self.pushPacket([], T, True, self.sri.streamID) -def addUTCTime(time_1, time_2): - ''' - Return a UTCTime (or PrecisionUTCTime) value incremented by time_2 - ''' - fulltime = (time_1.twsec+time_1.tfsec) + float(time_2) - if isinstance(time_1, CF.UTCTime): - retval = rhtime.now() - else: - retval = bulkio_helpers.createCPUTimestamp() - retval.twsec = int(fulltime) - retval.tfsec = fulltime - retval.twsec - return retval - -def subUTCTime(time_1, time_2): - ''' - Return a UTCTime (or PrecisionUTCTime) value reduced by time_2 - ''' - fulltime = (time_1.twsec+time_1.tfsec) - float(time_2) - if isinstance(time_1, CF.UTCTime): - retval = rhtime.now() - else: - retval = bulkio_helpers.createCPUTimestamp() - retval.twsec = int(fulltime) - retval.tfsec = fulltime - retval.twsec - return retval - -def diffUTCTime(time_1, time_2): - ''' - Return the difference in time between 2 UTCTime (or PrecisionUTCTime) values - ''' - retval = (time_1.twsec+time_1.tfsec) - (time_2.twsec+time_2.tfsec) - return retval - -class BaseStream(object): - def __init__(self, parent, sri): - self._sri = sri - self._parent = parent - def sri(self): - return self._sri - -class DataBlock(object): - def __init__(self, sri, data, tstamps, new_sri): - self._sri = sri - self._data = data - self._new_sri = new_sri - self._tstamps = tstamps - def data(self): - return self._data - def sri(self): - return self._sri - def xdelta(self): - return self._sri.xdelta - def sriChanged(self): - return self._new_sri - def inputQueueFlushed(self): - return False - def getStartTime(self): - return self._tstamps[0][1] - def getTimestamps(self): - return self._tstamps - def getNetTimeDrift(self): - if len(self._tstamps) == 1: - return 0 - diff_time = diffUTCTime(self._tstamps[-1][1], self._tstamps[0][1]) - synth_time = self._sri.xdelta * len(self._data) - return abs(diff_time - synth_time) - def getMaxTimeDrift(self): - max_drift = 0 - for _diff in range(len(self._tstamps)-1): - diff_time = diffUTCTime(self._tstamps[_diff][1], self._tstamps[_diff-1][1]) - synth_time = self._sri.xdelta * self._tstamps[_diff][0]-self._tstamps[_diff-1][0] - drift = abs(diff_time - synth_time) - if drift > max_drift: - max_drift = drift - return max_drift - -class _dataUnit(object): - def __init__(self, data, T, valid): - self._data = data - self._T = T - self._valid = valid - self._creation = time.time() - def getData(self): - return self._data - def delData(self, begin=0, end=-1): - if type(self._data) == str: - if end == -1: - end = len(_data) - self._data = self._data[:begin]+self._data[end:] - else: - del self._data[begin:end] - self._valid = False - def getCreateTime(self): - return self._creation - def getTstamp(self): - return self._T - def updateTstamp(self, offset): - if self._T: - self._T = addUTCTime(self._T, offset) - def cleanup(self, count, xdelta): - self.delData(end=count) - self.updateTstamp(count * xdelta) - def getValidTstamp(self): - return self._valid - -class _sriUnit(object): - def __init__(self, sri, offset): - self._offset = offset - self._sri = sri - def getOffset(self): - return self._offset - def changeOffset(self, delta): - self._offset = self._offset - delta - def getSri(self): - return self._sri - def getStreamID(self): - return self._sri.streamID - -class InputStream(BaseStream): - def __init__(self, parent, sri): - BaseStream.__init__(self, parent, sri) - self._enabled = True - self._data = [] - self._sri_idx = [] - self._eos = False - self._new_sri = True - - def streamID(self): - return self._sri.streamID - - def _updateSRI(self, sri): - # this sri applies to whatever packet is delivered next - if len(self._data) == 0: - self._new_sri = True - self._sri = sri - return - self._sri_idx.append(_sriUnit(sri, len(self._data))) - def _updateData(self, data, T, EOS): - self._parent.port_cond.acquire() - try: - self._data.append(_dataUnit(data, T, True)) - if EOS: - self._eos = True - self._parent.port_cond.notifyAll() - finally: - self._parent.port_cond.release() - - def getOldestCreateTime(self): - if len(self._data) != 0: - return self._data[0].getCreateTime() - else: - return None - - def _dataCurrSri(self): - upper_end = len(self._data) - if len(self._sri_idx) != 0: - upper_end = self._sri_idx[0].getOffset() - total_data = 0 - for total_data_idx in range(upper_end): - total_data += len(self._data[total_data_idx].getData()) - return total_data - - def read(self, count=None, consume=None, blocking=True): - ''' - Blocking read from the data buffer. - count: number of items read. All available if None - consumer: how far to move the read pointer. Move by count if None - - Note: if a new SRI was received, read all data until the new SRI - ''' - # if the amount of data left is 0, erase this from parent._streams - if len(self._data) == 0 and self._eos: - self._parent._removeStream(self) - return None - - if not count: - self._parent.port_cond.acquire() - count = self.samplesAvailableSingleSRI() - self._parent.port_cond.release() - if not consume: - consume = count - - while True: - # is there enough data for this sri? - # is there enough in the first packet? - try: - self._parent.port_cond.acquire() - if len(self._data) != 0: - if len(self._sri_idx) == 0: - if self._dataCurrSri() < count: - continue - ret_data = [] - tstamps = [] - total_read = actual_read = data_idx = curr_idx = consume_count = 0 - consume_count = consume - while total_read < count: - actual_read = len(self._data[data_idx].getData()) - if total_read + actual_read > count: - actual_read = count - total_read - ret_data += self._data[data_idx].getData()[:actual_read] - tstamps += [(curr_idx, self._data[data_idx].getTstamp())] - curr_idx += len(self._data[data_idx].getData()) - total_read += actual_read - consume_now = actual_read - if consume_now > consume_count: - consume_now = consume_count - consume_count -= consume_now - self._data[data_idx].cleanup(consume_now, self._sri.xdelta) - data_idx += 1 - if self._sri.subsize != 0: - framelength = self._sri.subsize if not self._sri.mode else 2 * self._sri.subsize - if float(len(ret_data))/framelength != len(ret_data)/framelength: - print 'The data length ('+str(len(ret_data))+') divided by subsize ('+str(self._sri.subsize)+')is not a whole number' - return None - _ret_data = [] - for idx in range(len(ret_data)/framelength): - _ret_data.append(ret_data[idx*framelength:(idx+1)*framelength]) - ret_data = _ret_data - ret_block = DataBlock(self._sri, ret_data, tstamps, self._new_sri) - self._new_sri = False - while True: - if len(self._data) == 0: - break - if len(self._data[0].getData()) == 0: - self._data.pop(0) - else: - break - return ret_block - # are there other sri in the queue? - else: - ret_data = [] - tstamps = [] - curr_idx = 0 - number_data = self._sri_idx[0].getOffset() - total_data = self._dataCurrSri() - if total_data <= count: - # return it all for the current sri and queue up the next sri - for data_idx in range(number_data): - ret_data += self._data[data_idx].getData() - tstamps += [(curr_idx, self._data[data_idx].getTstamp())] - curr_idx += len(self._data[data_idx].getData()) - number_pop = 0 - consume_count = consume - while consume_count != 0: - consume_now = len(self._data[0].getData()) - if consume_now <= consume_count: - self._data.pop(0) - consume_count -= consume_now - number_pop += 1 - continue - self._data[0].cleanup(consume_count, self._sri.xdelta) - consume_count = 0 - for _item_sri_idx in self._sri_idx: - _item_sri_idx.changeOffset(number_pop) - if self._sri.subsize != 0: - framelength = self._sri.subsize if not self._sri.mode else 2 * self._sri.subsize - if float(len(ret_data))/framelength != len(ret_data)/framelength: - print 'The data length ('+str(len(ret_data))+') divided by subsize ('+str(self._sri.subsize)+')is not a whole number' - return None - _ret_data = [] - for idx in range(len(ret_data)/framelength): - _ret_data.append(ret_data[idx*framelength:(idx+1)*framelength]) - ret_data = _ret_data - ret_block = DataBlock(self._sri, ret_data, tstamps, self._new_sri) - self._new_sri = True - self._sri = self._sri_idx.pop(0).getSri() - return ret_block - else: - # find a subset - total_read = actual_read = 0 - for data_idx in range(number_data): - actual_read = len(self._data[data_idx].getData()) - if total_read + actual_read > count: - actual_read = count - total_read - ret_data += self._data[data_idx].getData()[:actual_read] - tstamps += [(curr_idx, self._data[data_idx].getTstamp())] - curr_idx += len(self._data[data_idx].getData()) - total_read += actual_read - if total_read == count: - break - number_pop = 0 - consume_count = consume - while consume_count != 0: - consume_now = len(self._data[0].getData()) - if consume_now <= consume_count: - self._data.pop(0) - consume_count -= consume_now - number_pop += 1 - continue - self._data[0].cleanup(consume_count, self._sri.xdelta) - consume_count = 0 - for _item_sri_idx in self._sri_idx: - _item_sri_idx.changeOffset(number_pop) - if self._sri.subsize != 0: - framelength = self._sri.subsize if not self._sri.mode else 2 * self._sri.subsize - if float(len(ret_data))/framelength != len(ret_data)/framelength: - print 'The data length ('+str(len(ret_data))+') divided by subsize ('+str(self._sri.subsize)+')is not a whole number' - return None - _ret_data = [] - for idx in range(len(ret_data)/framelength): - _ret_data.append(ret_data[idx*framelength:(idx+1)*framelength]) - ret_data = _ret_data - ret_block = DataBlock(self._sri, ret_data, tstamps, self._new_sri) - self._new_sri = False - return ret_block - # this sleep happens if len(self._sri_idx) == 0 and total_data < count - finally: - self._parent.port_cond.release() - if not blocking: - break - time.sleep(0.1) - return None - def tryread(self, count=None, consume=None): - ''' - Non-blocking read from the data buffer. - count: number of items read. All available if None - consumer: how far to move the read pointer. Move by count if None - - Note: if a new SRI was received, read all data until the new SRI - ''' - return self.read(count, consume, False) - - def skip(self, count=None): - ''' - Move forward the read pointer by count or the next SRI, whichever comes first. - Move to next SRI if None - Returns the number of skipped elements - ''' - number_pop = 0 - consume_count = count - total_consumed = 0 - while consume_count != 0: - consume_now = len(self._data[0].getData()) - if consume_now <= consume_count: - self._data.pop(0) - consume_count -= consume_now - total_consumed += consume_now - for _item_sri_idx in self._sri_idx: - _item_sri_idx.changeOffset(1) - if len(self._sri_idx) != 0: - if self._sri_idx[0].getOffset() <= 0: - self._sri = self._sri_idx[0].getSri() - self._new_sri = True - self._sri_idx.pop(0) - break - continue - total_consumed += consume_count - self._data[0].cleanup(consume_count, self._sri.xdelta) - consume_count = 0 - return total_consumed - def ready(self): - return self.samplesAvailable() > 0 - def dataEstimate(self): - len_data = tstamps = 0 - for _data in self._data: - len_data += len(_data.getData()) - tstamps += 1 - return (len_data,tstamps) - def samplesAvailable(self): - len_data = 0 - for _data in self._data: - len_data += len(_data.getData()) - return len_data - def samplesAvailableSingleSRI(self): - len_data = 0 - data_block_reads = len(self._data) - if len(self._sri_idx) != 0: - data_block_reads = self._sri_idx[0].getOffset() - for _data_idx in range(data_block_reads): - len_data += len(self._data[_data_idx].getData()) - return len_data - def enable(self): - ''' - Do not drop incoming data - ''' - self._enabled = True - def disable(self): - ''' - Drop all incoming data - ''' - self._enabled = False - def enabled(self): - return self._enabled - def eos(self): - ''' - Has EOS been received? - ''' - return self._eos class ArraySink(object): """ @@ -608,19 +220,20 @@ def __init__(self, porttype): self.sri=bulkio_helpers.defaultSRI self.data = [] self.timestamps = [] - self._streams = [] - self._livingStreams = {} + self.sris = [] self.gotEOS = False self.breakBlock = False self.port_lock = threading.Lock() self.port_cond = threading.Condition(self.port_lock) - + class estimateStruct(): len_data=0 num_timestamps=0 - def __init__(self, data=0, timestamps=0): - self.len_data = data - self.num_timestamps = timestamps + num_sris=0 + def __init__(self, data=[], timestamps=[], sris=[]): + self.len_data = len(data) + self.num_timestamps = len(timestamps) + self.num_sris = len(sris) def _isActive(self): return not self.gotEOS and not self.breakBlock @@ -630,41 +243,6 @@ def reset(self): self.gotEOS = False self.breakBlock = False - def getStream(self, streamID): - for _stream in self._streams: - if _stream.getStreamID() == streamID: - return _stream - for _stream in self._livingStreams: - if self._livingStreams[_stream].getStreamID() == streamID: - return self._livingStreams[_stream] - return None - - def getStreams(self): - retval = [] - for _stream in self._streams: - retval.append(_stream) - for _stream in self._livingStreams: - retval.append(self._livingStreams[_stream]) - return retval - - def getCurrentStream(self): - if len(self._streams) != 0: - return self._streams[0] - streams_with_data = [] - for _stream in self._livingStreams: - if self._livingStreams[_stream].samplesAvailable() != 0: - streams_with_data.append(_stream) - if len(streams_with_data) == 0: - return None - oldest = (0,'') - for _stream in streams_with_data: - if oldest[0] == 0: - oldest = (_stream, self._livingStreams[_stream].getOldestCreateTime()) - continue - if self._livingStreams[_stream].getOldestCreateTime() < oldest[1]: - oldest = (_stream, self._livingStreams[_stream].getOldestCreateTime()) - return self._livingStreams[oldest[0]] - def start(self): self.gotEOS = False self.breakBlock = False @@ -676,28 +254,17 @@ def stop(self): self.port_cond.release() def eos(self): - _stream = self.getCurrentStream() - if _stream: - return _stream.eos() return self.gotEOS def waitEOS(self): self.port_cond.acquire() try: while self._isActive(): - if self.eos(): - break self.port_cond.wait() return self.gotEOS finally: self.port_cond.release() - def _removeStream(self, stream): - for stream_idx in range(len(self._streams)): - if self._streams[stream_idx] == stream: - self._streams.pop(stream_idx) - break - def pushSRI(self, H): """ Stores the SteramSRI object regardless that there is no need for it @@ -707,10 +274,7 @@ def pushSRI(self, H): generate the header file """ self.sri = H - if not self._livingStreams.has_key(H.streamID): - self._livingStreams[H.streamID] = InputStream(self, H) - else: - self._livingStreams[H.streamID]._updateSRI(H) + self.sris.append([len(self.data), H]) def pushPacket(self, data, ts, EOS, stream_id): """ @@ -722,40 +286,25 @@ def pushPacket(self, data, ts, EOS, stream_id): Flag indicating if this is the End Of the Stream The unique stream id """ - if not self._livingStreams.has_key(stream_id): - self._livingStreams[stream_id] = InputStream(self, BULKIO.StreamSRI(1, 0.0, 1.0, 1, 0, 0.0, 0.0, 0, 0, stream_id, False, [])) - _stream = self._livingStreams[stream_id] - _stream._updateData(data, ts, EOS) - if EOS: - self._streams.append(_stream) - self._livingStreams.pop(stream_id) - #self.port_cond.acquire() - #try: - # self.gotEOS = EOS - # self.timestamps.append([len(self.data), ts]) - # self.data += data - # self.port_cond.notifyAll() - #finally: - # self.port_cond.release() - - # legacy stuff - self.data += data + self.port_cond.acquire() + try: + self.gotEOS = EOS + self.timestamps.append([len(self.data), ts]) + self.data += data + self.port_cond.notifyAll() + finally: + self.port_cond.release() def estimateData(self): self.port_cond.acquire() estimate = self.estimateStruct() - _streams = self.getStreams() - _total_data = 0 - _total_tstamps = 0 - for _stream in _streams: - (data_len,tstamp_len) = _stream.dataEstimate() - _total_data += data_len - _total_tstamps += tstamp_len - estimate = self.estimateStruct(_total_data, _total_tstamps) - self.port_cond.release() + try: + estimate = self.estimateStruct(self.data, self.timestamps, self.sris) + finally: + self.port_cond.release() return estimate - - def __syncAssocData(self, reference): + + def syncAssocData(self, reference): retval = [] length_to_erase = None for i,(l,t) in enumerate(reference[::-1]): @@ -770,46 +319,62 @@ def __syncAssocData(self, reference): return retval def retrieveData(self, length=None): - #self.port_cond.acquire() + self.port_cond.acquire() try: - retval = [] - rettime = [] - while True: - self.port_cond.acquire() - _stream = self.getCurrentStream() - self.port_cond.release() - if not _stream and length != None: - time.sleep(0.1) - continue - break - if not _stream: - return None - done = False - goal = length - self.port_cond.acquire() - if length == None: - goal = _stream.samplesAvailable() - self.port_cond.release() - samples_read = 0 - while True: - _block = _stream.read(count=length) - if not _block: - break - retval += _block.data() - # The block timestamp offsets are relative to the start of that - # block, so adjust for any previous data offsets - rettime += [(off+samples_read, ts) for off, ts in _block.getTimestamps()] - goal_offset = 1 - if _block.sri().subsize != 0: - samples_read += sum(len(frame) for frame in _block.data()) + if length is None: + # No length specified; get all of the data. + length = len(self.data) + + # have not received any data yet (and I need a minimum amount) + if self.sri == None and len(self.data) == 0 and length != 0: + self.port_cond.wait() + + if self.sri != None and self.sri.subsize != 0: + frameLength = self.sri.subsize if not self.sri.mode else 2*self.sri.subsize + if float(length)/frameLength != length/frameLength: + print 'The requested length divided by the subsize ('+str(length)+'/'+str(self.sri.subsize)+') is not a whole number. Cannot return framed data' + return (None,None) + + # Wait for there to be enough data. + while len(self.data) < length and self._isActive(): + self.port_cond.wait() + + if len(self.data) > length: + # More data is available than was requested. Return only + # as much data as was asked for, and the associated + # timestamps. + rettime = self.syncAssocData(self.timestamps) + retsris = self.syncAssocData(self.sris) + + if self.sri.subsize == 0: + retval = self.data[:length] else: - samples_read += len(_block.data()) - if samples_read >= goal: - break + retval = [] + frameLength = self.sri.subsize if not self.sri.mode else 2*self.sri.subsize + for idx in range(length/frameLength): + retval.append(self.data[idx*frameLength:(idx+1)*frameLength]) + del self.data[:length] + return (retval, rettime, retsris) + + # No length was provided, or length is equal to the length of data. + # Return all data and timestamps. + if self.sri == None: + (retval, rettime, retsris) = (self.data, self.timestamps, []) + elif self.sri.subsize == 0: + (retval, rettime, retsris) = (self.data, self.timestamps, self.sris) + else: + retval = [] + frameLength = self.sri.subsize if not self.sri.mode else 2*self.sri.subsize + for idx in range(length/frameLength): + retval.append(self.data[idx*frameLength:(idx+1)*frameLength]) + rettime = self.timestamps + retsris = self.sris + self.data = [] + self.timestamps = [] + self.sris = [] + return (retval, rettime, retsris) finally: - pass - # self.port_cond.release() - return (retval, rettime) + self.port_cond.release() def getPort(self): """ @@ -1005,13 +570,13 @@ def pushPacket(self, data, EOS, stream_id): Flag indicating if this is the End Of the Stream The unique stream id """ - if not self._livingStreams.has_key(stream_id): - self._livingStreams[stream_id] = InputStream(self, BULKIO.StreamSRI(1, 0.0, 1.0, 1, 0, 0.0, 0.0, 0, 0, stream_id, False, [])) - _stream = self._livingStreams[stream_id] - _stream._updateData([data], None, EOS) - if EOS: - self._streams.append(_stream) - self._livingStreams.pop(stream_id) + self.port_cond.acquire() + try: + self.gotEOS = EOS + self.data.append(data) + self.port_cond.notifyAll() + finally: + self.port_cond.release() class XmlArraySource(ArraySource): "This sub-class exists to override pushPacket for dataXML ports." diff --git a/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py b/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py index 4b54bd346..13ef1a744 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py +++ b/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py @@ -38,7 +38,6 @@ import shlex as _shlex import time as _time import signal as _signal -import warnings as _warnings import cStringIO, pydoc import sys as _sys import os as _os @@ -803,11 +802,9 @@ def eos(self): self._sink exists. """ + if self._sink == None: return False - _stream = self._sink.getCurrentStream() - if _stream: - return _stream.eos() return self._sink.gotEOS def sri(self): @@ -1811,22 +1808,8 @@ def getDataEstimate(self): return None return self._sink.estimateData() - def getStream(self, streamID): - return self._sink.getStream(streamID) - - def getStreams(self): - return self._sink.getStreams() - - def getCurrentStream(self): - ''' - Return the current data stream - ''' - return self._sink.getCurrentStream() - - def getData(self, length=None, eos_block=False, tstamps=False): + def getData(self, length=None, eos_block=False, tstamps=False, sris=False): ''' - WARNING: This function is deprecated. Use getCurrentStream instead - Returns either an array of the received data elements or a tuple containing the received list and their associated time stamps @@ -1837,21 +1820,19 @@ def getData(self, length=None, eos_block=False, tstamps=False): tstamps: setting to True makes the return value a tuple, where the first element is the data set and the second element is a series of tuples containing the element index number and the timestamp for that index + sris: setting to True makes the return value a tuple, where the first + element is the data set, the second element is the series of + timestamps (empty list if tstamps==False) and the third element is + a series of tuples containing the element index number and the + sri value for that index ''' - _warnings.warn("This function is deprecated. Use getCurrentStream instead", DeprecationWarning) - isChar = self._sink.port_type == _BULKIO__POA.dataChar if not self._sink: return None if eos_block: self._sink.waitEOS() - _retval = self._sink.retrieveData(length=length) - if not _retval: - if tstamps: - return ([],[]) - return [] - (retval, timestamps) = _retval + (retval, timestamps, _sris) = self._sink.retrieveData(length=length) if isChar: # Converts char values into their numeric equivalents def from_char(data): @@ -1864,8 +1845,12 @@ def from_char(data): retval = [from_char(frame) for frame in retval] else: retval = from_char(retval) - if tstamps: - return (retval, timestamps) + if tstamps and not sris: + return (retval,timestamps) + if not tstamps and sris: + return (retval, [], _sris) + if tstamps and sris: + return (retval,timestamps,_sris) else: return retval diff --git a/redhawk/src/testing/tests/test_13_TestSB.py b/redhawk/src/testing/tests/test_13_TestSB.py index 5c5e8fc9e..aba2cbbe7 100644 --- a/redhawk/src/testing/tests/test_13_TestSB.py +++ b/redhawk/src/testing/tests/test_13_TestSB.py @@ -2063,19 +2063,14 @@ def test_DataSinkSRI(self): src.push([1,2,3,4,5],sampleRate=1000) src.push([1,2,3,4,5],sampleRate=10000) wait_on_data(snk, 3) - stream=snk.getCurrentStream() - block_1 = stream.read() - self.assertNotEqual(block_1, None) - block_2 = stream.read() - self.assertNotEqual(block_2, None) - block_3 = stream.read() - self.assertNotEqual(block_3, None) - self.assertEquals(len(block_1.data()), 5) - self.assertEquals(len(block_2.data()), 5) - self.assertEquals(len(block_3.data()), 5) - self.assertEquals(block_1.xdelta(), 0.01) - self.assertEquals(block_2.xdelta(), 0.001) - self.assertEquals(block_3.xdelta(), 0.0001) + data=snk.getData(tstamps=True,sris=True) + self.assertEquals(len(data[2]), 3) + self.assertEquals(data[2][0][0], 0) + self.assertEquals(data[2][1][0], 5) + self.assertEquals(data[2][2][0], 10) + self.assertEquals(data[2][0][1].xdelta, 0.01) + self.assertEquals(data[2][1][1].xdelta, 0.001) + self.assertEquals(data[2][2][1].xdelta, 0.0001) def _fileSourceThrottle(self, _file, rate): fp=open(_file, 'r') @@ -2116,10 +2111,8 @@ def test_DataSourceThrottle(self): self.assertTrue(time_difftime_estimate*0.9) - stream=snk.getCurrentStream() - block_1 = stream.read() - self.assertNotEqual(block_1, None) - self.assertEquals(len(block_1.data()), 3.0*_dataLength) + data=snk.getData() + self.assertEquals(len(data), 3.0*_dataLength) _sampleRate = 300 _dataLength = 100 @@ -2134,151 +2127,8 @@ def test_DataSourceThrottle(self): self.assertTrue(time_difftime_estimate*0.9) - stream=snk.getCurrentStream() - block_1 = stream.read() - self.assertNotEqual(block_1, None) - self.assertEquals(len(block_1.data()), 3.0*_dataLength) - - def test_DataSinkMultipleStream(self): - src = sb.DataSource(dataFormat='float') - snk = sb.DataSink() - src.connect(snk) - sb.start() - src.push([1,2,3,4,5],sampleRate=100, streamID='hello_1') - src.push([6,7,8,9,10],sampleRate=1000, streamID='hello_2') - src.push([11,12,13,14,15],sampleRate=10000, streamID='hello_3') - src.push([16,17,18,19,20],sampleRate=100, streamID='hello_1') - - wait_on_data(snk, 3) - - stream=snk.getCurrentStream() - block_1 = stream.read() - self.assertNotEqual(block_1, None) - - stream=snk.getCurrentStream() - block_2 = stream.read() - self.assertNotEqual(block_2, None) - block_2_2 = stream.read(blocking=False) - self.assertEquals(block_2_2, None) - - stream=snk.getCurrentStream() - block_3 = stream.read() - self.assertNotEqual(block_3, None) - block_3_2 = stream.read(blocking=False) - self.assertEquals(block_3_2, None) - - stream=snk.getCurrentStream() - block_1_2 = stream.read() - self.assertNotEqual(block_1_2, None) - block_1_3 = stream.read(blocking=False) - self.assertEqual(block_1_3, None) - - self.assertEquals(block_1.data(), [1,2,3,4,5]) - self.assertEquals(block_1_2.data(), [16,17,18,19,20]) - self.assertEquals(block_2.data(), [6,7,8,9,10]) - self.assertEquals(block_3.data(), [11,12,13,14,15]) - self.assertEquals(block_1.xdelta(), 0.01) - self.assertEquals(block_2.xdelta(), 0.001) - self.assertEquals(block_3.xdelta(), 0.0001) - - def test_DataSinkReadConsume(self): - src = sb.DataSource(dataFormat='float') - snk = sb.DataSink() - src.connect(snk) - sb.start() - src.push([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20],sampleRate=100, streamID='hello_1') - - wait_on_data(snk, 1) - - stream=snk.getCurrentStream() - block_1 = stream.read(count=10, consume=5) - self.assertNotEqual(block_1, None) - self.assertEquals(block_1.data(), [1,2,3,4,5,6,7,8,9,10]) - - block_1 = stream.read(count=10, consume=5) - self.assertNotEqual(block_1, None) - self.assertEquals(block_1.data(), [6,7,8,9,10,11,12,13,14,15]) - - block_1 = stream.read(count=10, consume=5) - self.assertNotEqual(block_1, None) - self.assertEquals(block_1.data(), [11,12,13,14,15,16,17,18,19,20]) - - block_1 = stream.read(count=5, consume=5) - self.assertNotEqual(block_1, None) - self.assertEquals(block_1.data(), [16,17,18,19,20]) - - block_1 = stream.read(blocking=False) - self.assertEquals(block_1, None) - - def _test_DataSinkSkipDiffSRI(self): - src = sb.DataSource(dataFormat='float') - snk = sb.DataSink() - src.connect(snk) - sb.start() - src.push([1,2,3,4,5],sampleRate=100, streamID='hello_1') - src.push([6,7,8,9,10],sampleRate=1000, streamID='hello_1') - src.push([11,12,13,14,15,16,17,18,19,20,21,22,23,24,25],sampleRate=10000, streamID='hello_1') - - wait_on_data(snk, 4) - - stream=snk.getCurrentStream() - block_1 = stream.read(count=3) - self.assertNotEqual(block_1, None) - self.assertEquals(block_1.data(), [1,2,3]) - - skipped = stream.skip(10) - self.assertEquals(skipped, 2) - - block_1 = stream.read(count=2, consume=3) - self.assertNotEqual(block_1, None) - self.assertEquals(block_1.data(), [6,7]) - - skipped = stream.skip(10) - self.assertEquals(skipped, 2) - - block_1 = stream.read(count=2, consume=3) - self.assertNotEqual(block_1, None) - self.assertEquals(block_1.data(), [11,12]) - - skipped = stream.skip(10) - self.assertEquals(skipped, 10) - - block_1 = stream.read() - self.assertNotEqual(block_1, None) - self.assertEquals(block_1.data(), [23,24,25]) - - block_1 = stream.read(blocking=False) - self.assertEquals(block_1, None) - - def test_DataSinkSkip(self): - src = sb.DataSource(dataFormat='float') - snk = sb.DataSink() - src.connect(snk) - sb.start() - src.push([1,2,3,4,5],sampleRate=100, streamID='hello_1') - src.push([6,7,8,9,10],sampleRate=100, streamID='hello_1') - src.push([11,12,13,14,15],sampleRate=100, streamID='hello_1') - src.push([16,17,18,19,20],sampleRate=100, streamID='hello_1') - - wait_on_data(snk, 4) - - stream=snk.getCurrentStream() - block_1 = stream.read(count=3) - self.assertNotEqual(block_1, None) - self.assertEquals(block_1.data(), [1,2,3]) - - skipped = stream.skip(10) - self.assertEquals(skipped, 10) - - block_1 = stream.read(count=3, consume=5) - self.assertNotEqual(block_1, None) - self.assertEquals(block_1.data(), [14,15,16]) - - block_1 = stream.read(blocking=False) - self.assertNotEqual(block_1, None) - self.assertEquals(block_1.data(), [17,18,19,20]) - block_1 = stream.read(blocking=False) - self.assertEquals(block_1, None) + data=snk.getData() + self.assertEquals(len(data), 3.0*_dataLength) class customSink(bulkio_data_helpers.ArraySink): def __init__(self, porttype): @@ -2288,10 +2138,7 @@ def pushSRI(self, H): _H = H _H.xdelta = H.xdelta * 2 self.sri = _H - if not self._livingStreams.has_key(_H.streamID): - self._livingStreams[_H.streamID] = bulkio_data_helpers.InputStream(self, _H) - else: - self._livingStreams[_H.streamID]._updateSRI(_H) + self.sris.append([len(self.data), _H]) def test_CustomDataSink(self): src = sb.DataSource(dataFormat='float') @@ -2302,33 +2149,14 @@ def test_CustomDataSink(self): src.push([1,2,3,4,5],sampleRate=1000) src.push([1,2,3,4,5],sampleRate=10000) wait_on_data(snk, 3) - data=snk.getData(tstamps=True) - print data - self.assertEquals(len(data[1]), 3) - self.assertEquals(len(data[0]), 15) - - def test_CustomStreamDataSink(self): - src = sb.DataSource(dataFormat='float') - snk = sb.DataSink(sinkClass=self.customSink) - src.connect(snk) - sb.start() - src.push([1,2,3,4,5],sampleRate=100) - src.push([1,2,3,4,5],sampleRate=1000) - src.push([1,2,3,4,5],sampleRate=10000) - wait_on_data(snk, 3) - stream=snk.getCurrentStream() - block_1 = stream.read() - self.assertNotEqual(block_1, None) - block_2 = stream.read() - self.assertNotEqual(block_2, None) - block_3 = stream.read() - self.assertNotEqual(block_3, None) - self.assertEquals(len(block_1.data()), 5) - self.assertEquals(len(block_2.data()), 5) - self.assertEquals(len(block_3.data()), 5) - self.assertEquals(block_1.xdelta(), 0.02) - self.assertEquals(block_2.xdelta(), 0.002) - self.assertEquals(block_3.xdelta(), 0.0002) + data=snk.getData(tstamps=True,sris=True) + self.assertEquals(len(data[2]), 3) + self.assertEquals(data[2][0][0], 0) + self.assertEquals(data[2][1][0], 5) + self.assertEquals(data[2][2][0], 10) + self.assertEquals(data[2][0][1].xdelta, 0.02) + self.assertEquals(data[2][1][1].xdelta, 0.002) + self.assertEquals(data[2][2][1].xdelta, 0.0002) def test_DataSourceSRI(self): _timeout = 1 From fbdabbc7220f3c7b9c7acc38051cd6542b6d127f Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 16 Jun 2017 14:47:32 -0400 Subject: [PATCH 0826/1644] CF-1777 Use 'requireLog4cxx' decorator on kickDomain() tests that use a logging config file --- redhawk/src/testing/tests/test_13_RedhawkModule.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/redhawk/src/testing/tests/test_13_RedhawkModule.py b/redhawk/src/testing/tests/test_13_RedhawkModule.py index 54023556d..6e2fc260f 100644 --- a/redhawk/src/testing/tests/test_13_RedhawkModule.py +++ b/redhawk/src/testing/tests/test_13_RedhawkModule.py @@ -1097,7 +1097,7 @@ def _try_kick_domain(self, logcfg, epatterns, debug_level=None, kick_device_man else: self.assertEqual( pat['match'] , len(pat['results']) ) - + @scatest.requireLog4cxx def test_kick_trace(self): self._try_kick_domain('log4j.kickdomain.cfg', epatterns={ @@ -1105,6 +1105,7 @@ def test_kick_trace(self): }, debug_level="TRACE") + @scatest.requireLog4cxx def test_kick_trace_both(self): self._try_kick_domain('log4j.kickdomain.cfg', epatterns={ @@ -1116,6 +1117,7 @@ def test_kick_trace_both(self): dev_mgr_levels= [ "TRACE" ], ) + @scatest.requireLog4cxx def test_kick_debug(self): self._try_kick_domain('log4j.kickdomain.cfg', epatterns={ "no" : { 'patterns': [" TRACE " ], 'match': [] }, @@ -1124,6 +1126,7 @@ def test_kick_debug(self): debug_level="DEBUG") + @scatest.requireLog4cxx def test_kick_debug_both(self): self._try_kick_domain('log4j.kickdomain.cfg', epatterns={ "no" : { 'patterns': [" TRACE " ], 'match': [] }, @@ -1135,6 +1138,7 @@ def test_kick_debug_both(self): dev_mgr_levels= [ "DEBUG", "DEBUG" ] ) + @scatest.requireLog4cxx def test_kick_info(self): self._try_kick_domain('log4j.kickdomain.cfg', epatterns={ "no" : { 'patterns': [" TRACE ", " DEBUG " ], 'match': [] }, @@ -1142,6 +1146,7 @@ def test_kick_info(self): }, debug_level="INFO") + @scatest.requireLog4cxx def test_kick_info_both(self): self._try_kick_domain('log4j.kickdomain.cfg', epatterns={ "no" : { 'patterns': [" TRACE ", " DEBUG " ], 'match': [] }, @@ -1153,6 +1158,7 @@ def test_kick_info_both(self): dev_mgr_levels= [ "INFO", "INFO" ] ) + @scatest.requireLog4cxx def test_kick_warn(self): self._try_kick_domain('log4j.kickdomain.cfg', epatterns={ "no" : { 'patterns': [" TRACE ", " DEBUG ", " INFO ", ], 'match': 2 }, @@ -1160,6 +1166,7 @@ def test_kick_warn(self): }, debug_level="WARN") + @scatest.requireLog4cxx def test_kick_warn_both(self): self._try_kick_domain('log4j.kickdomain.cfg', epatterns={ "no" : { 'patterns': [" TRACE ", " DEBUG " ], 'match': [] }, @@ -1172,6 +1179,7 @@ def test_kick_warn_both(self): dev_mgr_levels= [ "WARN", "WARN" ] ) + @scatest.requireLog4cxx def test_kick_error(self): self._try_kick_domain('log4j.kickdomain.cfg', epatterns={ "no" : { 'patterns': [" TRACE ", " DEBUG ", " INFO ", " WARN " ], 'match': 2 }, @@ -1179,6 +1187,7 @@ def test_kick_error(self): }, debug_level="ERROR") + @scatest.requireLog4cxx def test_kick_error_both(self): self._try_kick_domain('log4j.kickdomain.cfg', epatterns={ "no" : { 'patterns': [" TRACE ", " DEBUG " ] , 'match': [] }, @@ -1191,6 +1200,7 @@ def test_kick_error_both(self): dev_mgr_levels= [ "ERROR", "ERROR" ] ) + @scatest.requireLog4cxx def test_kick_fatal(self): self._try_kick_domain('log4j.kickdomain.cfg', epatterns={ "no" : { 'patterns': [" TRACE ", " DEBUG ", " INFO ", " WARN ", " ERROR " ], 'match': 2 }, @@ -1198,6 +1208,7 @@ def test_kick_fatal(self): }, debug_level="ERROR") + @scatest.requireLog4cxx def test_kick_fatal_both(self): self._try_kick_domain('log4j.kickdomain.cfg', epatterns={ "no" : { 'patterns': [" TRACE ", " DEBUG ", " ERROR " ], 'match': [] }, From d072ee88f62437622889576b80c914d953d498d3 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Mon, 19 Jun 2017 10:31:11 -0400 Subject: [PATCH 0827/1644] Refs CF-423. Undo multiple sris for DataSink until a later version --- .../ossie/utils/bulkio/bulkio_data_helpers.py | 46 +++++++------------ .../python/ossie/utils/sb/io_helpers.py | 17 ++----- .../framework/python/ossie/utils/sb/plots.py | 11 ++--- redhawk/src/testing/tests/test_13_TestSB.py | 29 +----------- 4 files changed, 28 insertions(+), 75 deletions(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/bulkio/bulkio_data_helpers.py b/redhawk/src/base/framework/python/ossie/utils/bulkio/bulkio_data_helpers.py index 32aadab81..beaa085bf 100644 --- a/redhawk/src/base/framework/python/ossie/utils/bulkio/bulkio_data_helpers.py +++ b/redhawk/src/base/framework/python/ossie/utils/bulkio/bulkio_data_helpers.py @@ -220,7 +220,6 @@ def __init__(self, porttype): self.sri=bulkio_helpers.defaultSRI self.data = [] self.timestamps = [] - self.sris = [] self.gotEOS = False self.breakBlock = False self.port_lock = threading.Lock() @@ -229,11 +228,9 @@ def __init__(self, porttype): class estimateStruct(): len_data=0 num_timestamps=0 - num_sris=0 - def __init__(self, data=[], timestamps=[], sris=[]): + def __init__(self, data=[], timestamps=[]): self.len_data = len(data) self.num_timestamps = len(timestamps) - self.num_sris = len(sris) def _isActive(self): return not self.gotEOS and not self.breakBlock @@ -274,7 +271,6 @@ def pushSRI(self, H): generate the header file """ self.sri = H - self.sris.append([len(self.data), H]) def pushPacket(self, data, ts, EOS, stream_id): """ @@ -299,25 +295,11 @@ def estimateData(self): self.port_cond.acquire() estimate = self.estimateStruct() try: - estimate = self.estimateStruct(self.data, self.timestamps, self.sris) + estimate = self.estimateStruct(self.data, self.timestamps) finally: self.port_cond.release() return estimate - def syncAssocData(self, reference): - retval = [] - length_to_erase = None - for i,(l,t) in enumerate(reference[::-1]): - if l > length: - reference[len(reference)-i-1][0] = l - length - continue - if length_to_erase == None: - length_to_erase = len(reference)-i - retval.append((l,t)) - if length_to_erase != None: - del reference[:length_to_erase] - return retval - def retrieveData(self, length=None): self.port_cond.acquire() try: @@ -343,9 +325,17 @@ def retrieveData(self, length=None): # More data is available than was requested. Return only # as much data as was asked for, and the associated # timestamps. - rettime = self.syncAssocData(self.timestamps) - retsris = self.syncAssocData(self.sris) - + rettime = [] + length_to_erase = None + for i,(l,t) in enumerate(self.timestamps[::-1]): + if l > length: + self.timestamps[len(self.timestamps)-i-1][0] = l - length + continue + if length_to_erase == None: + length_to_erase = len(self.timestamps)-i + rettime.append((l,t)) + if length_to_erase != None: + del self.timestamps[:length_to_erase] if self.sri.subsize == 0: retval = self.data[:length] else: @@ -354,25 +344,23 @@ def retrieveData(self, length=None): for idx in range(length/frameLength): retval.append(self.data[idx*frameLength:(idx+1)*frameLength]) del self.data[:length] - return (retval, rettime, retsris) + return (retval, rettime) # No length was provided, or length is equal to the length of data. # Return all data and timestamps. if self.sri == None: - (retval, rettime, retsris) = (self.data, self.timestamps, []) + (retval, rettime) = (self.data, self.timestamps) elif self.sri.subsize == 0: - (retval, rettime, retsris) = (self.data, self.timestamps, self.sris) + (retval, rettime) = (self.data, self.timestamps) else: retval = [] frameLength = self.sri.subsize if not self.sri.mode else 2*self.sri.subsize for idx in range(length/frameLength): retval.append(self.data[idx*frameLength:(idx+1)*frameLength]) rettime = self.timestamps - retsris = self.sris self.data = [] self.timestamps = [] - self.sris = [] - return (retval, rettime, retsris) + return (retval, rettime) finally: self.port_cond.release() diff --git a/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py b/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py index 13ef1a744..ac6570462 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py +++ b/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py @@ -1808,7 +1808,7 @@ def getDataEstimate(self): return None return self._sink.estimateData() - def getData(self, length=None, eos_block=False, tstamps=False, sris=False): + def getData(self, length=None, eos_block=False, tstamps=False): ''' Returns either an array of the received data elements or a tuple containing the received list and their associated time stamps @@ -1819,12 +1819,7 @@ def getData(self, length=None, eos_block=False, tstamps=False, sris=False): eos_block: setting to True creates a blocking call until eos is received tstamps: setting to True makes the return value a tuple, where the first element is the data set and the second element is a series of tuples - containing the element index number and the timestamp for that index - sris: setting to True makes the return value a tuple, where the first - element is the data set, the second element is the series of - timestamps (empty list if tstamps==False) and the third element is - a series of tuples containing the element index number and the - sri value for that index + containing the element index number of and timestamp ''' isChar = self._sink.port_type == _BULKIO__POA.dataChar @@ -1832,7 +1827,7 @@ def getData(self, length=None, eos_block=False, tstamps=False, sris=False): return None if eos_block: self._sink.waitEOS() - (retval, timestamps, _sris) = self._sink.retrieveData(length=length) + (retval, timestamps) = self._sink.retrieveData(length=length) if isChar: # Converts char values into their numeric equivalents def from_char(data): @@ -1845,12 +1840,8 @@ def from_char(data): retval = [from_char(frame) for frame in retval] else: retval = from_char(retval) - if tstamps and not sris: + if tstamps: return (retval,timestamps) - if not tstamps and sris: - return (retval, [], _sris) - if tstamps and sris: - return (retval,timestamps,_sris) else: return retval diff --git a/redhawk/src/base/framework/python/ossie/utils/sb/plots.py b/redhawk/src/base/framework/python/ossie/utils/sb/plots.py index 2b20b9bb9..7534ab275 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sb/plots.py +++ b/redhawk/src/base/framework/python/ossie/utils/sb/plots.py @@ -104,13 +104,12 @@ def sriChanged(self): return changed def retrieveData(self, length): - data, times, sris = super(PlotSink,self).retrieveData(length) + data, times = super(PlotSink,self).retrieveData(length) if self.sri.mode or self._forceComplex: - data2, times2, sris2 = super(PlotSink,self).retrieveData(length) + data2, times2 = super(PlotSink,self).retrieveData(length) data = bulkio_helpers.bulkioComplexToPythonComplexList(data + data2) times.extend(times2) - sris.extend(sris2) - return data, times, sris + return data, times class CharSink(PlotSink): def __init__(self): @@ -381,7 +380,7 @@ def _updateTrace(self, trace): line = trace['line'] # Read next frame. - data, timestamps, sris = sink.retrieveData(length=self._frameSize) + data, timestamps = sink.retrieveData(length=self._frameSize) if not data: return x_data, y_data = self._formatData(data, sink.sri) @@ -652,7 +651,7 @@ def _update(self): return False # Read and format data. - data, timestamps, sris = self._sink.retrieveData(length=self._frameSize) + data, timestamps = self._sink.retrieveData(length=self._frameSize) if not data: return sri = self._sink.sri diff --git a/redhawk/src/testing/tests/test_13_TestSB.py b/redhawk/src/testing/tests/test_13_TestSB.py index aba2cbbe7..d3971551d 100644 --- a/redhawk/src/testing/tests/test_13_TestSB.py +++ b/redhawk/src/testing/tests/test_13_TestSB.py @@ -2054,24 +2054,6 @@ def test_DataSourceTimeStampParam(self): _rnd_toffset = int(round( (_toffset+len(_srcData)/_sampleRate) *10))/10.0 self.assertEquals(_rnd_pkt_time,_rnd_toffset ) - def test_DataSinkSRI(self): - src = sb.DataSource(dataFormat='float') - snk = sb.DataSink() - src.connect(snk) - sb.start() - src.push([1,2,3,4,5],sampleRate=100) - src.push([1,2,3,4,5],sampleRate=1000) - src.push([1,2,3,4,5],sampleRate=10000) - wait_on_data(snk, 3) - data=snk.getData(tstamps=True,sris=True) - self.assertEquals(len(data[2]), 3) - self.assertEquals(data[2][0][0], 0) - self.assertEquals(data[2][1][0], 5) - self.assertEquals(data[2][2][0], 10) - self.assertEquals(data[2][0][1].xdelta, 0.01) - self.assertEquals(data[2][1][1].xdelta, 0.001) - self.assertEquals(data[2][2][1].xdelta, 0.0001) - def _fileSourceThrottle(self, _file, rate): fp=open(_file, 'r') contents = fp.read() @@ -2138,7 +2120,6 @@ def pushSRI(self, H): _H = H _H.xdelta = H.xdelta * 2 self.sri = _H - self.sris.append([len(self.data), _H]) def test_CustomDataSink(self): src = sb.DataSource(dataFormat='float') @@ -2149,14 +2130,8 @@ def test_CustomDataSink(self): src.push([1,2,3,4,5],sampleRate=1000) src.push([1,2,3,4,5],sampleRate=10000) wait_on_data(snk, 3) - data=snk.getData(tstamps=True,sris=True) - self.assertEquals(len(data[2]), 3) - self.assertEquals(data[2][0][0], 0) - self.assertEquals(data[2][1][0], 5) - self.assertEquals(data[2][2][0], 10) - self.assertEquals(data[2][0][1].xdelta, 0.02) - self.assertEquals(data[2][1][1].xdelta, 0.002) - self.assertEquals(data[2][2][1].xdelta, 0.0002) + data=snk.getData(tstamps=True) + self.assertEquals(snk._sink.sri.xdelta, 0.0002) def test_DataSourceSRI(self): _timeout = 1 From 211e148fcc9503545908d76e67a6a92dd3a25ce7 Mon Sep 17 00:00:00 2001 From: 8530 <8530@vm-131.vsi-corp.com> Date: Mon, 19 Jun 2017 10:40:51 -0400 Subject: [PATCH 0828/1644] fix issue from change in import statement, CF-1780 --- .../base/framework/python/ossie/utils/sb/io_helpers.py | 2 +- redhawk/src/testing/tests/test_13_TestSB.py | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py b/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py index ac6570462..696c3f662 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py +++ b/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py @@ -1146,7 +1146,7 @@ def __init__(self): Helper to handle the generation of SDDS metadata forwarding """ _SourceBase.__init__(self, bytesPerPush = 0, dataFormat='sdds', formats=['sdds']) - self._src = _bulkio_data_helpers.SDDSSource() + self._src = bulkio_data_helpers.SDDSSource() self._blocking = True self._streamdefs = {} diff --git a/redhawk/src/testing/tests/test_13_TestSB.py b/redhawk/src/testing/tests/test_13_TestSB.py index d3971551d..8d2cc80fa 100644 --- a/redhawk/src/testing/tests/test_13_TestSB.py +++ b/redhawk/src/testing/tests/test_13_TestSB.py @@ -1584,6 +1584,14 @@ def test_NotSharedComponent(self): self.assertNotEqual(int(comp1.pid), int(comp2.pid)) +class Test_DataSDDSSource(unittest.TestCase): + + def test_CreateSDDSSource(self): + source = sb.DataSourceSDDS() + self.assertNotEquals(source, None) + + + class BulkioTest(unittest.TestCase): XMLDATA = """ From 6c8df8313ee76f18f0fdc442da60d7c967fb733b Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 23 Jun 2017 14:01:43 -0400 Subject: [PATCH 0829/1644] CF-1574 Remove --disable-xml-validation configure flag --- redhawk/src/configure.ac | 10 ---------- redhawk/src/control/parser/Makefile.am | 2 +- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/redhawk/src/configure.ac b/redhawk/src/configure.ac index c2a4d31d5..7960949eb 100644 --- a/redhawk/src/configure.ac +++ b/redhawk/src/configure.ac @@ -150,16 +150,6 @@ OSSIE_ENABLE_PERSISTENCE m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) -AC_ARG_ENABLE([xml_validation], AS_HELP_STRING([--disable-xml-validation], [Disable xml validation in the parsers])) -AC_MSG_CHECKING([if xml parsers should perform validation]) -if test "x$enable_xml_validation" != "xno"; then - AC_SUBST(OSSIE_XSDFLAGS, "--generate-validation") - AC_MSG_RESULT([yes]) -else - AC_SUBST(OSSIE_XSDFLAGS, "--suppress-validation") - AC_MSG_RESULT([no]) -fi - # Allow user to explictly prevent JAVA compilation AC_ARG_ENABLE([java], AS_HELP_STRING([--disable-java], [Disable framework java support])) diff --git a/redhawk/src/control/parser/Makefile.am b/redhawk/src/control/parser/Makefile.am index 8c9d1ccc4..c7f90109f 100644 --- a/redhawk/src/control/parser/Makefile.am +++ b/redhawk/src/control/parser/Makefile.am @@ -76,7 +76,7 @@ libossieparser_la_LDFLAGS = $(EXPAT_LDFLAGS) AM_CPPFLAGS = -I../include -I. -I$(top_srcdir)/base/include -XSDFLAGS = --hxx-suffix .h --cxx-suffix .cpp --xml-parser expat --output-dir internal $(OSSIE_XSDFLAGS) +XSDFLAGS = --hxx-suffix .h --cxx-suffix .cpp --xml-parser expat --output-dir internal --generate-validation # Pattern rule to generate *-pskel files using the corresponding .xsd and .map # files. We need to keep xmlns items in the XSD, but we have to remove them From 31dbaabe9568d43225498aae96583059119f5ac5 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Fri, 23 Jun 2017 14:13:09 -0400 Subject: [PATCH 0830/1644] CF-1783 Remove --disable-base-classes configure flag in BulkIO The Frontend configure.ac didn't offer a --disable-base-classes flag, but did include a conditional (that was always true) --- bulkioInterfaces/Makefile.am | 6 +-- bulkioInterfaces/configure.ac | 82 +++++++++++++++------------------ frontendInterfaces/Makefile.am | 4 +- frontendInterfaces/configure.ac | 12 ++--- 4 files changed, 45 insertions(+), 59 deletions(-) diff --git a/bulkioInterfaces/Makefile.am b/bulkioInterfaces/Makefile.am index 48d34829e..55a85243c 100644 --- a/bulkioInterfaces/Makefile.am +++ b/bulkioInterfaces/Makefile.am @@ -177,11 +177,7 @@ distclean-local: # Always build the current directory first (this is hack-ish, but the # alternative is to combine the Makefile.am's) -SUBDIRS = . - -if BUILD_BASE_CLASSES -SUBDIRS += libsrc -endif +SUBDIRS = . libsrc ############################################################################### # C++ (via automake and libtool) diff --git a/bulkioInterfaces/configure.ac b/bulkioInterfaces/configure.ac index 3057e1a5b..6db17caad 100644 --- a/bulkioInterfaces/configure.ac +++ b/bulkioInterfaces/configure.ac @@ -49,23 +49,17 @@ RH_PKG_IDLDIR([OSSIE], [ossie]) PKG_CHECK_MODULES([OMNICOS], [omniCOS4 >= 4.0.0]) RH_PKG_IDLDIR([OMNICOS], [omniCOS4]) -# Optionally include BULKIO base class libraries -AC_ARG_ENABLE([base-classes], AS_HELP_STRING([--disable-base-classes], [Disable BULKIO base class libraries])) -AM_CONDITIONAL([BUILD_BASE_CLASSES], [test "$enable_base_classes" != "no"]) - -if test "$enable_base_classes" != "no"; then - AC_SUBST([BULKIO_SO_VERSION], [0:0:0]) - AC_SUBST([BULKIO_API_VERSION], [2.1]) - - AX_BOOST_BASE([1.41]) - AX_BOOST_THREAD - AX_BOOST_SYSTEM - OSSIE_ENABLE_LOG4CXX - CHECK_VECTOR_IMPL - - AC_SUBST(BULKIOINTERFACES_CFLAGS, "-I \$(top_srcdir)/src/cpp -I \$(top_srcdir)/src/cpp/ossie") - AC_SUBST(BULKIOINTERFACES_LIBS, "-L\$(top_srcdir) -lbulkioInterfaces") -fi +AC_SUBST([BULKIO_SO_VERSION], [0:0:0]) +AC_SUBST([BULKIO_API_VERSION], [2.1]) + +AX_BOOST_BASE([1.41]) +AX_BOOST_THREAD +AX_BOOST_SYSTEM +OSSIE_ENABLE_LOG4CXX +CHECK_VECTOR_IMPL + +AC_SUBST(BULKIOINTERFACES_CFLAGS, "-I \$(top_srcdir)/src/cpp -I \$(top_srcdir)/src/cpp/ossie") +AC_SUBST(BULKIOINTERFACES_LIBS, "-L\$(top_srcdir) -lbulkioInterfaces") # Optionally include java support AC_ARG_ENABLE([java], AS_HELP_STRING([--disable-java], [Disable framework java support])) @@ -152,34 +146,32 @@ AC_SUBST(BULKIO_CFLAGS, "-I ${bulkio_includedir} -I ${bulkio_includedir}/bulkio AC_SUBST(BULKIO_LIBS, "-L\$(top_srcdir)/libsrc -lbulkio-${BULKIO_API_VERSION} ${BULKIOINTERFACES_LIBS}") AC_CONFIG_FILES([bulkioInterfaces.pc setup.py Makefile jni/Makefile]) -if test "$enable_base_classes" != "no"; then - if test "$HAVE_JAVASUPPORT = yes"; then - AC_CONFIG_FILES([libsrc/java/META-INF/MANIFEST.MF]) - fi - AC_SUBST(PROJECTDEPS_CFLAGS, "\$(OSSIE_CFLAGS)") - AC_SUBST(PROJECTDEPS_LIBS, "\$(OSSIE_LIBS)") - AC_SUBST(INTERFACEDEPS_CFLAGS, "\$(BULKIO_CFLAGS)") - AC_SUBST(INTERFACEDEPS_LIBS, "\$(BULKIO_LIBS)") - AC_SUBST(REDHAWK_CLASSPATH, "\$(OSSIE_CLASSPATH)") - AC_SUBST(BULKIO_CLASSPATH, "\$(top_srcdir)/libsrc/bulkio.jar:\$(top_srcdir)/BULKIOInterfaces.jar") - AC_CONFIG_FILES([libsrc/Makefile \ - libsrc/bulkio.pc \ - libsrc/testing/Makefile \ - libsrc/testing/tests/cpp/Makefile \ - libsrc/testing/tests/java/Makefile \ - libsrc/testing/components/CPP_Ports/cpp/Makefile \ - libsrc/testing/components/Java_Ports/java/Makefile \ - libsrc/testing/components/Oversized_framedata/cpp/Makefile \ - libsrc/testing/components/src/cpp/Makefile \ - libsrc/testing/components/snk_slow/cpp/Makefile \ - libsrc/testing/components/Oversized_framedata/java/Makefile \ - libsrc/testing/components/TestLargePush/cpp/Makefile \ - libsrc/testing/components/TestLargePush/java/Makefile \ - libsrc/testing/components/multiout_attachable/cpp/Makefile \ - libsrc/testing/components/multiout_attachable/java/Makefile \ - libsrc/testing/components/sri_changed_cpp/cpp/Makefile \ - libsrc/testing/devices/dev_snk/java/Makefile \ - libsrc/testing/devices/dev_src/java/Makefile]) +if test "$HAVE_JAVASUPPORT = yes"; then + AC_CONFIG_FILES([libsrc/java/META-INF/MANIFEST.MF]) fi +AC_SUBST(PROJECTDEPS_CFLAGS, "\$(OSSIE_CFLAGS)") +AC_SUBST(PROJECTDEPS_LIBS, "\$(OSSIE_LIBS)") +AC_SUBST(INTERFACEDEPS_CFLAGS, "\$(BULKIO_CFLAGS)") +AC_SUBST(INTERFACEDEPS_LIBS, "\$(BULKIO_LIBS)") +AC_SUBST(REDHAWK_CLASSPATH, "\$(OSSIE_CLASSPATH)") +AC_SUBST(BULKIO_CLASSPATH, "\$(top_srcdir)/libsrc/bulkio.jar:\$(top_srcdir)/BULKIOInterfaces.jar") +AC_CONFIG_FILES([libsrc/Makefile \ + libsrc/bulkio.pc \ + libsrc/testing/Makefile \ + libsrc/testing/tests/cpp/Makefile \ + libsrc/testing/tests/java/Makefile \ + libsrc/testing/components/CPP_Ports/cpp/Makefile \ + libsrc/testing/components/Java_Ports/java/Makefile \ + libsrc/testing/components/Oversized_framedata/cpp/Makefile \ + libsrc/testing/components/src/cpp/Makefile \ + libsrc/testing/components/snk_slow/cpp/Makefile \ + libsrc/testing/components/Oversized_framedata/java/Makefile \ + libsrc/testing/components/TestLargePush/cpp/Makefile \ + libsrc/testing/components/TestLargePush/java/Makefile \ + libsrc/testing/components/multiout_attachable/cpp/Makefile \ + libsrc/testing/components/multiout_attachable/java/Makefile \ + libsrc/testing/components/sri_changed_cpp/cpp/Makefile \ + libsrc/testing/devices/dev_snk/java/Makefile \ + libsrc/testing/devices/dev_src/java/Makefile]) AC_OUTPUT diff --git a/frontendInterfaces/Makefile.am b/frontendInterfaces/Makefile.am index 40e031151..67e3debac 100644 --- a/frontendInterfaces/Makefile.am +++ b/frontendInterfaces/Makefile.am @@ -92,9 +92,7 @@ clean-local: clean-python clean-java clean-cpp # Always build the current directory first (this is hack-ish, but the # # alternative is to combine the Makefile.am's) -SUBDIRS = . - -SUBDIRS += libsrc +SUBDIRS = . libsrc ############################################################################### # C++ (via automake and libtool) diff --git a/frontendInterfaces/configure.ac b/frontendInterfaces/configure.ac index 5ab228d35..dff8d1a77 100644 --- a/frontendInterfaces/configure.ac +++ b/frontendInterfaces/configure.ac @@ -87,11 +87,11 @@ if test "x$enable_java" != "xno"; then fi AM_CONDITIONAL(HAVE_JAVASUPPORT, test $HAVE_JAVASUPPORT = yes) -AC_CONFIG_FILES([Makefile frontendInterfaces.pc]) -if test "$enable_base_classes" != "no"; then - if test "$HAVE_JAVASUPPORT = yes"; then - AC_CONFIG_FILES([libsrc/java/META-INF/MANIFEST.MF]) - fi - AC_CONFIG_FILES([libsrc/Makefile libsrc/frontend.pc]) +AC_CONFIG_FILES([Makefile \ + frontendInterfaces.pc \ + libsrc/Makefile \ + libsrc/frontend.pc]) +if test "$HAVE_JAVASUPPORT = yes"; then + AC_CONFIG_FILES([libsrc/java/META-INF/MANIFEST.MF]) fi AC_OUTPUT From 71935db23efb7a9e4dfdfafa503d4c12043780bf Mon Sep 17 00:00:00 2001 From: 8530 <8530@vm-131.vsi-corp.com> Date: Mon, 26 Jun 2017 15:50:36 -0400 Subject: [PATCH 0831/1644] add in sdds to python setup, fix parameter mismatch and call for getdata --- .../base/framework/python/ossie/utils/sb/io_helpers.py | 9 ++++++--- redhawk/src/base/framework/python/setup.py | 1 + 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py b/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py index 696c3f662..110ea71dd 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py +++ b/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py @@ -1196,7 +1196,7 @@ def detach(self, attachId=''): def _createArraySrcInst(self, srcPortType): return self._src - def getStreamDef( self, name=None, pkts=1000, block=True, returnSddsAnalyzer=True): + def getStreamDef( self, name=None, hostip=None, pkts=1000, block=True, returnSddsAnalyzer=True): # grab data if stream definition is available sdef =None aid=name @@ -1212,11 +1212,14 @@ def getStreamDef( self, name=None, pkts=1000, block=True, returnSddsAnalyzer=Tru if not sdef: raise Exception("No SDDS stream definition for attach id:" + aid ) + + if not hostip: + hostip = _socket.gethostbyname(_socket.gethostname()) - return self.grabData( sdef.multicastAddress, sdef.port, sdef.vlan, packets, block=block) + return self.getData( sdef.multicastAddress, hostip, sdef.port, packets, block=block, returnSDDSAnalyzer=returnSDDSAnalyzer) - def getData( self, mgroup, hostip, port=29495, vlan=0, pkts=1000, pktlen=1080, sdds=True, block=True, returnSddsAnalyzer=True): + def getData( self, mgroup, hostip, port=29495, pkts=1000, pktlen=1080, block=True, returnSddsAnalyzer=True): totalRead=0.0 startTime = _time.time() sock = None diff --git a/redhawk/src/base/framework/python/setup.py b/redhawk/src/base/framework/python/setup.py index d99d31d17..b6ae5ff89 100644 --- a/redhawk/src/base/framework/python/setup.py +++ b/redhawk/src/base/framework/python/setup.py @@ -74,6 +74,7 @@ 'ossie/utils/sca', 'ossie/utils/testing', 'ossie/utils/tools', + 'ossie/utils/sdds', 'ossie/utils/rhtime', 'ossie/utils/rhconnection', 'ossie/utils/allocations', From 47c98e8185c1c7565a312f452b426912c9c75a5e Mon Sep 17 00:00:00 2001 From: 8530 <8530@vm-131.vsi-corp.com> Date: Wed, 28 Jun 2017 12:22:40 -0400 Subject: [PATCH 0832/1644] change debug_level to log_level, CF_1754 --- .../sdr/dommgr/ApplicationFactory_impl.cpp | 11 ++++++++--- redhawk/src/control/sdr/dommgr/Deployment.cpp | 16 ++++++++-------- .../TestCpp/TestCpp_props_debug.sad.xml | 2 +- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index 6198fd27b..dc24ea562 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -2006,14 +2006,19 @@ void createHelper::resolveLoggingConfiguration(redhawk::ComponentDeployment* dep LOG_TRACE(ApplicationFactory_impl, "resolveLoggingConfig: exec parameter provided debug_level: " << debug_level); } + if ( execParams.contains("LOG_LEVEL") ) { + debug_level = resolveDebugLevel( execParams["LOG_LEVEL"].toString() ); + LOG_TRACE(ApplicationFactory_impl, "resolveLoggingConfig: exec parameter provided log_level: " << debug_level); + } + // check if logging configuration is part of component placement redhawk::PropertyMap log_config=deployment->getLoggingConfiguration(); if ( log_config.contains("LOGGING_CONFIG_URI") ) { logging_uri = log_config["LOGGING_CONFIG_URI"].toString(); LOG_TRACE(ApplicationFactory_impl, "resolveLoggingConfig: loggingconfig log config: " << logging_uri); } - if ( log_config.contains("DEBUG_LEVEL") ) { - debug_level = resolveDebugLevel(log_config["DEBUG_LEVEL"].toString()); + if ( log_config.contains("LOG_LEVEL") ) { + debug_level = resolveDebugLevel(log_config["LOG_LEVEL"].toString()); LOG_TRACE(ApplicationFactory_impl, "resolveLoggingConfig: loggingconfig debug_level: " << debug_level); } @@ -2065,7 +2070,7 @@ void createHelper::resolveLoggingConfiguration(redhawk::ComponentDeployment* dep // if debug level is resolved, then add as execparam if ( debug_level != -1 ) { execParams["DEBUG_LEVEL"] = static_cast(debug_level); - LOG_DEBUG(ApplicationFactory_impl, "resolveLoggingConfiguration: COMP: " << deployment->getIdentifier() << " DEBUG_LEVEL: " << debug_level ); + LOG_DEBUG(ApplicationFactory_impl, "resolveLoggingConfiguration: COMP: " << deployment->getIdentifier() << " LOG_LEVEL: " << debug_level ); } } diff --git a/redhawk/src/control/sdr/dommgr/Deployment.cpp b/redhawk/src/control/sdr/dommgr/Deployment.cpp index fd487451d..313408068 100644 --- a/redhawk/src/control/sdr/dommgr/Deployment.cpp +++ b/redhawk/src/control/sdr/dommgr/Deployment.cpp @@ -281,8 +281,8 @@ ComponentDeployment::ComponentDeployment(const SoftPkg* softpkg, loggingConfig["LOGGING_CONFIG_URI"] = lcfg.first; } if ( !lcfg.second.empty() ){ - RH_NL_TRACE("ApplicationFactory_impl", "Logging Debug: <" << lcfg.second << ">" ); - loggingConfig["DEBUG_LEVEL"] = lcfg.second; + RH_NL_TRACE("ApplicationFactory_impl", "Logging Level: <" << lcfg.second << ">" ); + loggingConfig["LOG_LEVEL"] = lcfg.second; } if (!instantiation->getAffinity().empty()) { @@ -633,8 +633,8 @@ redhawk::PropertyMap ComponentDeployment::getLoggingConfiguration() const } } - if (overrides.contains("DEBUG_LEVEL") ) { - override = overrides.find("DEBUG_LEVEL"); + if (overrides.contains("LOG_LEVEL") ) { + override = overrides.find("LOG_LEVEL"); if (!override->getValue().isNil()) { debug_level = override->getValue().toString(); } @@ -649,7 +649,7 @@ redhawk::PropertyMap ComponentDeployment::getLoggingConfiguration() const } } - propref = getPropertyOverride("DEBUG_LEVEL"); + propref = getPropertyOverride("LOG_LEVEL"); if (propref) { const SimplePropertyRef* simple = dynamic_cast(propref); if (simple) { @@ -664,8 +664,8 @@ redhawk::PropertyMap ComponentDeployment::getLoggingConfiguration() const logcfg_uri = loggingConfig["LOGGING_CONFIG_URI"].toString(); } - if ( loggingConfig.contains("DEBUG_LEVEL") ) { - debug_level = loggingConfig["DEBUG_LEVEL"].toString(); + if ( loggingConfig.contains("LOG_LEVEL") ) { + debug_level = loggingConfig["LOG_LEVEL"].toString(); } if ( !logcfg_uri.empty() ) { @@ -673,7 +673,7 @@ redhawk::PropertyMap ComponentDeployment::getLoggingConfiguration() const } if ( !debug_level.empty() ) { - ret["DEBUG_LEVEL"]=debug_level; + ret["LOG_LEVEL"]=debug_level; } return ret; diff --git a/redhawk/src/testing/sdr/dom/waveforms/loggingconfig/TestCpp/TestCpp_props_debug.sad.xml b/redhawk/src/testing/sdr/dom/waveforms/loggingconfig/TestCpp/TestCpp_props_debug.sad.xml index cecddc83c..d50100c7f 100644 --- a/redhawk/src/testing/sdr/dom/waveforms/loggingconfig/TestCpp/TestCpp_props_debug.sad.xml +++ b/redhawk/src/testing/sdr/dom/waveforms/loggingconfig/TestCpp/TestCpp_props_debug.sad.xml @@ -33,7 +33,7 @@ with this program. If not, see http://www.gnu.org/licenses/. C2_1 - + From ac1fd1c8e2a9fc3aa2892813be00227d6069b859 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 28 Jun 2017 12:22:10 -0400 Subject: [PATCH 0833/1644] Always create a new symlink to $SDDROOT/dom/mgr in codegen tests --- codegenTesting/runtests.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/codegenTesting/runtests.py b/codegenTesting/runtests.py index 7bfac150d..307e9bbc2 100755 --- a/codegenTesting/runtests.py +++ b/codegenTesting/runtests.py @@ -29,8 +29,8 @@ # ComponentHost for shared library components sdrroot = os.path.join(os.getcwd(), "sdr") mgrpath = os.path.join(sdrroot, 'dom/mgr') -if not os.path.islink(mgrpath): - os.symlink(os.path.join(os.environ['SDRROOT'], 'dom/mgr'), mgrpath) +os.unlink(mgrpath) +os.symlink(os.path.join(os.environ['SDRROOT'], 'dom/mgr'), mgrpath) # Point to the testing SDR folder os.environ['SDRROOT'] = sdrroot From 7041044fb68cb94901bf77c5524797aada4a374c Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 28 Jun 2017 12:44:58 -0400 Subject: [PATCH 0834/1644] CF-1746 Generate enumeration values in C++, Java and Python components --- .../dom/components/EnumTest/.EnumTest.wavedev | 33 ++ .../dom/components/EnumTest/EnumTest.prf.xml | 78 ++++ .../dom/components/EnumTest/EnumTest.scd.xml | 64 +++ .../dom/components/EnumTest/EnumTest.spd.xml | 69 ++++ .../dom/components/EnumTest/cpp/EnumTest.cpp | 330 ++++++++++++++++ .../dom/components/EnumTest/cpp/EnumTest.h | 44 +++ .../java/src/enumtest/java/EnumTest.java | 367 ++++++++++++++++++ .../components/EnumTest/python/EnumTest.py | 225 +++++++++++ .../EnumTest/tests/test_EnumTest.py | 93 +++++ .../component/pull/templates/resource_base.h | 11 + .../codegen/jinja/cpp/properties/mapping.py | 6 + .../cpp/properties/templates/properties.cpp | 23 +- .../redhawk/codegen/jinja/environment.py | 1 + .../component/base/templates/properties.java | 23 ++ .../pull/templates/resource_base.java | 13 + .../redhawk/codegen/jinja/java/properties.py | 8 + .../redhawk/codegen/jinja/mapping.py | 26 +- .../component/base/templates/properties.py | 20 + .../component/pull/templates/resource_base.py | 9 +- .../codegen/jinja/python/properties.py | 6 + .../redhawk/codegen/jinja/tests.py | 17 + .../redhawk/codegen/model/properties.py | 3 + 22 files changed, 1465 insertions(+), 4 deletions(-) create mode 100644 codegenTesting/sdr/dom/components/EnumTest/.EnumTest.wavedev create mode 100644 codegenTesting/sdr/dom/components/EnumTest/EnumTest.prf.xml create mode 100644 codegenTesting/sdr/dom/components/EnumTest/EnumTest.scd.xml create mode 100644 codegenTesting/sdr/dom/components/EnumTest/EnumTest.spd.xml create mode 100644 codegenTesting/sdr/dom/components/EnumTest/cpp/EnumTest.cpp create mode 100644 codegenTesting/sdr/dom/components/EnumTest/cpp/EnumTest.h create mode 100644 codegenTesting/sdr/dom/components/EnumTest/java/src/enumtest/java/EnumTest.java create mode 100755 codegenTesting/sdr/dom/components/EnumTest/python/EnumTest.py create mode 100644 codegenTesting/sdr/dom/components/EnumTest/tests/test_EnumTest.py diff --git a/codegenTesting/sdr/dom/components/EnumTest/.EnumTest.wavedev b/codegenTesting/sdr/dom/components/EnumTest/.EnumTest.wavedev new file mode 100644 index 000000000..7b18962ef --- /dev/null +++ b/codegenTesting/sdr/dom/components/EnumTest/.EnumTest.wavedev @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + diff --git a/codegenTesting/sdr/dom/components/EnumTest/EnumTest.prf.xml b/codegenTesting/sdr/dom/components/EnumTest/EnumTest.prf.xml new file mode 100644 index 000000000..67120a68c --- /dev/null +++ b/codegenTesting/sdr/dom/components/EnumTest/EnumTest.prf.xml @@ -0,0 +1,78 @@ + + + + + + 0.0 + + + + + + + + + start + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + + + + + + + + body + + + + + + + + + + \ No newline at end of file diff --git a/codegenTesting/sdr/dom/components/EnumTest/EnumTest.scd.xml b/codegenTesting/sdr/dom/components/EnumTest/EnumTest.scd.xml new file mode 100644 index 000000000..712f34aea --- /dev/null +++ b/codegenTesting/sdr/dom/components/EnumTest/EnumTest.scd.xml @@ -0,0 +1,64 @@ + + + + + 2.2 + + resource + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/codegenTesting/sdr/dom/components/EnumTest/EnumTest.spd.xml b/codegenTesting/sdr/dom/components/EnumTest/EnumTest.spd.xml new file mode 100644 index 000000000..78ecd77c1 --- /dev/null +++ b/codegenTesting/sdr/dom/components/EnumTest/EnumTest.spd.xml @@ -0,0 +1,69 @@ + + + + + + + null + + + + + + + + + The implementation contains descriptive information about the template for a software resource. + + + cpp/EnumTest.so + + + + + + + + + + The implementation contains descriptive information about the template for a software resource. + + + java/startJava.sh + + + + + + + + + The implementation contains descriptive information about the template for a software resource. + + + python/EnumTest.py + + + + + + + \ No newline at end of file diff --git a/codegenTesting/sdr/dom/components/EnumTest/cpp/EnumTest.cpp b/codegenTesting/sdr/dom/components/EnumTest/cpp/EnumTest.cpp new file mode 100644 index 000000000..0f4001d4d --- /dev/null +++ b/codegenTesting/sdr/dom/components/EnumTest/cpp/EnumTest.cpp @@ -0,0 +1,330 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK codegenTesting. + * + * REDHAWK codegenTesting is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK codegenTesting is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ +/************************************************************************** + + This is the component code. This file contains the child class where + custom functionality can be added to the component. Custom + functionality to the base class can be extended here. Access to + the ports can also be done from this class + +**************************************************************************/ + +#include + +#include "EnumTest.h" + +PREPARE_LOGGING(EnumTest_i) + +EnumTest_i::EnumTest_i(const char *uuid, const char *label) : + EnumTest_base(uuid, label) +{ + // Avoid placing constructor code here. Instead, use the "constructor" function. + +} + +EnumTest_i::~EnumTest_i() +{ +} + +void EnumTest_i::constructor() +{ + /*********************************************************************************** + This is the RH constructor. All properties are properly initialized before this function is called + ***********************************************************************************/ +} + +/*********************************************************************************************** + + Basic functionality: + + The service function is called by the serviceThread object (of type ProcessThread). + This call happens immediately after the previous call if the return value for + the previous call was NORMAL. + If the return value for the previous call was NOOP, then the serviceThread waits + an amount of time defined in the serviceThread's constructor. + + SRI: + To create a StreamSRI object, use the following code: + std::string stream_id = "testStream"; + BULKIO::StreamSRI sri = bulkio::sri::create(stream_id); + + Time: + To create a PrecisionUTCTime object, use the following code: + BULKIO::PrecisionUTCTime tstamp = bulkio::time::utils::now(); + + + Ports: + + Data is passed to the serviceFunction through by reading from input streams + (BulkIO only). The input stream class is a port-specific class, so each port + implementing the BulkIO interface will have its own type-specific input stream. + UDP multicast (dataSDDS and dataVITA49) ports do not support streams. + + The input stream from which to read can be requested with the getCurrentStream() + method. The optional argument to getCurrentStream() is a floating point number that + specifies the time to wait in seconds. A zero value is non-blocking. A negative value + is blocking. Constants have been defined for these values, bulkio::Const::BLOCKING and + bulkio::Const::NON_BLOCKING. + + More advanced uses of input streams are possible; refer to the REDHAWK documentation + for more details. + + Input streams return data blocks that automatically manage the memory for the data + and include the SRI that was in effect at the time the data was received. It is not + necessary to delete the block; it will be cleaned up when it goes out of scope. + + To send data using a BulkIO interface, create an output stream and write the + data to it. When done with the output stream, the close() method sends and end-of- + stream flag and cleans up. + + NOTE: If you have a BULKIO dataSDDS or dataVITA49 port, you must manually call + "port->updateStats()" to update the port statistics when appropriate. + + Example: + // This example assumes that the component has two ports: + // An input (provides) port of type bulkio::InShortPort called dataShort_in + // An output (uses) port of type bulkio::OutFloatPort called dataFloat_out + // The mapping between the port and the class is found + // in the component base class header file + + bulkio::InShortStream inputStream = dataShort_in->getCurrentStream(); + if (!inputStream) { // No streams are available + return NOOP; + } + + // Get the output stream, creating it if it doesn't exist yet + bulkio::OutFloatStream outputStream = dataFloat_out->getStream(inputStream.streamID()); + if (!outputStream) { + outputStream = dataFloat_out->createStream(inputStream.sri()); + } + + bulkio::ShortDataBlock block = inputStream.read(); + if (!block) { // No data available + // Propagate end-of-stream + if (inputStream.eos()) { + outputStream.close(); + } + return NOOP; + } + + if (block.sriChanged()) { + // Update output SRI + outputStream.sri(block.sri()); + } + + // Get read-only access to the input data + redhawk::shared_buffer inputData = block.buffer(); + + // Acquire a new buffer to hold the output data + redhawk::buffer outputData(inputData.size()); + + // Transform input data into output data + for (size_t index = 0; index < inputData.size(); ++index) { + outputData[index] = (float) inputData[index]; + } + + // Write to the output stream; outputData must not be modified after + // this method call + outputStream.write(outputData, block.getStartTime()); + + return NORMAL; + + If working with complex data (i.e., the "mode" on the SRI is set to + true), the data block's complex() method will return true. Data blocks + provide a cxbuffer() method that returns a complex interpretation of the + buffer without making a copy: + + if (block.complex()) { + redhawk::shared_buffer > inData = block.cxbuffer(); + redhawk::buffer > outData(inData.size()); + for (size_t index = 0; index < inData.size(); ++index) { + outData[index] = inData[index]; + } + outputStream.write(outData, block.getStartTime()); + } + + Interactions with non-BULKIO ports are left up to the component developer's discretion + + Messages: + + To receive a message, you need (1) an input port of type MessageEvent, (2) a message prototype described + as a structure property of kind message, (3) a callback to service the message, and (4) to register the callback + with the input port. + + Assuming a property of type message is declared called "my_msg", an input port called "msg_input" is declared of + type MessageEvent, create the following code: + + void EnumTest_i::my_message_callback(const std::string& id, const my_msg_struct &msg){ + } + + Register the message callback onto the input port with the following form: + this->msg_input->registerMessage("my_msg", this, &EnumTest_i::my_message_callback); + + To send a message, you need to (1) create a message structure, (2) a message prototype described + as a structure property of kind message, and (3) send the message over the port. + + Assuming a property of type message is declared called "my_msg", an output port called "msg_output" is declared of + type MessageEvent, create the following code: + + ::my_msg_struct msg_out; + this->msg_output->sendMessage(msg_out); + + Accessing the Application and Domain Manager: + + Both the Application hosting this Component and the Domain Manager hosting + the Application are available to the Component. + + To access the Domain Manager: + CF::DomainManager_ptr dommgr = this->getDomainManager()->getRef(); + To access the Application: + CF::Application_ptr app = this->getApplication()->getRef(); + + Properties: + + Properties are accessed directly as member variables. For example, if the + property name is "baudRate", it may be accessed within member functions as + "baudRate". Unnamed properties are given the property id as its name. + Property types are mapped to the nearest C++ type, (e.g. "string" becomes + "std::string"). All generated properties are declared in the base class + (EnumTest_base). + + Simple sequence properties are mapped to "std::vector" of the simple type. + Struct properties, if used, are mapped to C++ structs defined in the + generated file "struct_props.h". Field names are taken from the name in + the properties file; if no name is given, a generated name of the form + "field_n" is used, where "n" is the ordinal number of the field. + + Example: + // This example makes use of the following Properties: + // - A float value called scaleValue + // - A boolean called scaleInput + + if (scaleInput) { + dataOut[i] = dataIn[i] * scaleValue; + } else { + dataOut[i] = dataIn[i]; + } + + Callback methods can be associated with a property so that the methods are + called each time the property value changes. This is done by calling + addPropertyListener(, this, &EnumTest_i::) + in the constructor. + + The callback method receives two arguments, the old and new values, and + should return nothing (void). The arguments can be passed by value, + receiving a copy (preferred for primitive types), or by const reference + (preferred for strings, structs and vectors). + + Example: + // This example makes use of the following Properties: + // - A float value called scaleValue + // - A struct property called status + + //Add to EnumTest.cpp + EnumTest_i::EnumTest_i(const char *uuid, const char *label) : + EnumTest_base(uuid, label) + { + addPropertyListener(scaleValue, this, &EnumTest_i::scaleChanged); + addPropertyListener(status, this, &EnumTest_i::statusChanged); + } + + void EnumTest_i::scaleChanged(float oldValue, float newValue) + { + LOG_DEBUG(EnumTest_i, "scaleValue changed from" << oldValue << " to " << newValue); + } + + void EnumTest_i::statusChanged(const status_struct& oldValue, const status_struct& newValue) + { + LOG_DEBUG(EnumTest_i, "status changed"); + } + + //Add to EnumTest.h + void scaleChanged(float oldValue, float newValue); + void statusChanged(const status_struct& oldValue, const status_struct& newValue); + + +************************************************************************************************/ +int EnumTest_i::serviceFunction() +{ + LOG_DEBUG(EnumTest_i, "serviceFunction() example log message"); + + return NOOP; +} + +void EnumTest_i::runTest(CORBA::ULong testid, CF::Properties& testValues) throw (CF::UnknownProperties, CF::TestableObject::UnknownTest, CORBA::SystemException) +{ + redhawk::PropertyMap& testProps = redhawk::PropertyMap::cast(testValues); + switch (testid) { + case 0: + runEnumTest(testProps); + break; + default: + throw CF::TestableObject::UnknownTest(); + } +} + +void EnumTest_i::runEnumTest(redhawk::PropertyMap& testValues) +{ + redhawk::PropertyMap unknown; + + BOOST_FOREACH(redhawk::PropertyType& prop, testValues) { + const std::string prop_id = prop.getId(); + redhawk::PropertyMap value; + if (prop_id == "floatenum") { + value["DEFAULT"] = enums::floatenum::DEFAULT; + value["OTHER"] = enums::floatenum::OTHER; + } else if (prop_id == "stringenum") { + value["START"] = enums::stringenum::START; + value["STOPPED"] = enums::stringenum::STOPPED; + } else if (prop_id == "structprop") { + redhawk::PropertyMap number_enums; + number_enums["ZERO"] = enums::structprop::number::ZERO; + number_enums["ONE"] = enums::structprop::number::ONE; + number_enums["TWO"] = enums::structprop::number::TWO; + value["structprop::number"] = number_enums; + + redhawk::PropertyMap alpha_enums; + alpha_enums["ABC"] = enums::structprop::alpha::ABC; + alpha_enums["DEF"] = enums::structprop::alpha::DEF; + value["structprop::alpha"] = alpha_enums; + } else if (prop_id == "structseq") { + redhawk::PropertyMap number_enums; + number_enums["POSITIVE"] = enums::structseq_struct::number::POSITIVE; + number_enums["ZERO"] = enums::structseq_struct::number::ZERO; + number_enums["NEGATIVE"] = enums::structseq_struct::number::NEGATIVE; + value["structseq::number"] = number_enums; + + redhawk::PropertyMap text_enums; + text_enums["HEADER"] = enums::structseq_struct::text::HEADER; + text_enums["BODY"] = enums::structseq_struct::text::BODY; + text_enums["FOOTER"] = enums::structseq_struct::text::FOOTER; + value["structseq::text"] = text_enums; + } else { + LOG_ERROR(EnumTest_i, "Unknown property " << prop_id); + unknown.push_back(prop); + continue; + } + prop.setValue(value); + } + + if (!unknown.empty()) { + throw CF::UnknownProperties(unknown); + } +} diff --git a/codegenTesting/sdr/dom/components/EnumTest/cpp/EnumTest.h b/codegenTesting/sdr/dom/components/EnumTest/cpp/EnumTest.h new file mode 100644 index 000000000..bd4944968 --- /dev/null +++ b/codegenTesting/sdr/dom/components/EnumTest/cpp/EnumTest.h @@ -0,0 +1,44 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK codegenTesting. + * + * REDHAWK codegenTesting is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK codegenTesting is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ +#ifndef ENUMTEST_I_IMPL_H +#define ENUMTEST_I_IMPL_H + +#include "EnumTest_base.h" + +#include + +class EnumTest_i : public EnumTest_base +{ + ENABLE_LOGGING + public: + EnumTest_i(const char *uuid, const char *label); + ~EnumTest_i(); + + void constructor(); + + int serviceFunction(); + + void runTest(CORBA::ULong testid, CF::Properties& testValues) throw (CF::UnknownProperties, CF::TestableObject::UnknownTest, CORBA::SystemException); + + private: + void runEnumTest(redhawk::PropertyMap& testValues); +}; + +#endif // ENUMTEST_I_IMPL_H diff --git a/codegenTesting/sdr/dom/components/EnumTest/java/src/enumtest/java/EnumTest.java b/codegenTesting/sdr/dom/components/EnumTest/java/src/enumtest/java/EnumTest.java new file mode 100644 index 000000000..28996d320 --- /dev/null +++ b/codegenTesting/sdr/dom/components/EnumTest/java/src/enumtest/java/EnumTest.java @@ -0,0 +1,367 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK codegenTesting. + * + * REDHAWK codegenTesting is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK codegenTesting is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ +package enumtest.java; + +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; + +/** + * This is the component code. This file contains the derived class where custom + * functionality can be added to the component. You may add methods and code to + * this class to handle property changes, respond to incoming data, and perform + * general component housekeeping + * + * Source: EnumTest.spd.xml + */ +public class EnumTest extends EnumTest_base { + /** + * This is the component constructor. In this method, you may add + * additional functionality to properties such as listening for changes + * or handling allocation, register message handlers and set up internal + * state for your component. + * + * A component may listen for external changes to properties (i.e., by a + * call to configure) using the PropertyListener interface. Listeners are + * registered by calling addChangeListener() on the property instance + * with an object that implements the PropertyListener interface for that + * data type (e.g., "PropertyListener" for a float property). More + * than one listener can be connected to a property. + * + * Example: + * // This example makes use of the following properties: + * // - A float value called scaleValue + * // The file must import "org.ossie.properties.PropertyListener" + * // Add the following import to the top of the file: + * import org.ossie.properties.PropertyListener; + * + * //Add the following to the class constructor: + * this.scaleValue.addChangeListener(new PropertyListener() { + * public void valueChanged(Float oldValue, Float newValue) { + * scaleValueChanged(oldValue, newValue); + * } + * }); + * + * //Add the following method to the class: + * private void scaleValueChanged(Float oldValue, Float newValue) + * { + * logger.debug("Changed scaleValue " + oldValue + " to " + newValue); + * } + * + * The recommended practice is for the implementation of valueChanged() to + * contain only glue code to dispatch the call to a private method on the + * component class. + * Accessing the Application and Domain Manager: + * + * Both the Application hosting this Component and the Domain Manager hosting + * the Application are available to the Component. + * + * To access the Domain Manager: + * CF.DomainManager dommgr = this.getDomainManager().getRef(); + * To access the Application: + * CF.Application app = this.getApplication().getRef(); + * + * Messages: + * + * To send or receive messages, you must have at least one message + * prototype described as a struct property of kind "message." + * + * Receiving: + * + * To receive a message, you must have an input port of type MessageEvent + * (marked as "bi-dir" in the Ports editor). For each message type the + * component supports, you must register a message handler callback with + * the message input port. Message handlers implement the MessageListener + * interface. + * + * A callback is registered by calling registerMessage() on the message + * input port with the message ID, the message struct's Class object and + * an object that implements the MessageListener interface for that + * message struct (e.g., "MessageListener" for a + * message named "my_message"). + * + * Example: + * // Assume the component has a message type called "my_message" and + * // an input MessageEvent port called "message_in". + * // Add the following to the top of the file: + * import org.ossie.events.MessageListener; + * + * // Register the callback in the class constructor: + * this.message_in.registerMessage("my_message", my_message_struct.class, new MessageListener() { + * public void messageReceived(String messageId, my_message_struct messageData) { + * my_message_received(messageData); + * } + * }); + * + * // Implement the message handler method: + * private void my_message_received(my_message_struct messageData) { + * // Respond to the message + * } + * + * The recommended practice is for the implementation of messageReceived() + * to contain only glue code to dispatch the call to a private method on + * the component class. + * + * Sending: + * + * To send a message, you must have an output port of type MessageEvent. + * Create an instance of the message struct type and call sendMessage() + * to send a single message. + * + * Example: + * // Assume the component has a message type called "my_message" and + * // an output MessageEvent port called "message_out". + * my_message_struct message = new my_message_struct(); + * this.message_out.sendMessage(message); + * + * You may also send a batch of messages at once with the sendMessages() + * method. + */ + + public EnumTest() + { + super(); + } + + public void constructor() + { + } + + + /** + * + * Main processing function + * + * General functionality: + * + * The serviceFunction() is called repeatedly by the component's processing + * thread, which runs independently of the main thread. Each invocation + * should perform a single unit of work, such as reading and processing one + * data packet. + * + * The return status of serviceFunction() determines how soon the next + * invocation occurs: + * - NORMAL: the next call happens immediately + * - NOOP: the next call happens after a pre-defined delay (100 ms) + * - FINISH: no more calls occur + * + * StreamSRI: + * To create a StreamSRI object, use the following code: + * String stream_id = "testStream"; + * BULKIO.StreamSRI sri = new BULKIO.StreamSRI(); + * sri.mode = 0; + * sri.xdelta = 0.0; + * sri.ydelta = 1.0; + * sri.subsize = 0; + * sri.xunits = 1; // TIME_S + * sri.streamID = (stream_id != null) ? stream_id : ""; + * + * PrecisionUTCTime: + * To create a PrecisionUTCTime object, use the following code: + * BULKIO.PrecisionUTCTime tstamp = bulkio.time.utils.now(); + * + * Ports: + * + * Each port instance is accessed through members of the following form: + * + * this.port_ + * + * Input BULKIO data is obtained by calling getPacket on the provides + * port. The getPacket method takes one argument: the time to wait for + * data to arrive, in milliseconds. A timeout of 0 causes getPacket to + * return immediately, while a negative timeout indicates an indefinite + * wait. If no data is queued and no packet arrives during the waiting + * period, getPacket returns null. + * + * Output BULKIO data is sent by calling pushPacket on the uses port. In + * the case of numeric data, the pushPacket method takes a primitive + * array (e.g., "float[]"), a timestamp, an end-of-stream flag and a + * stream ID. You must make at least one call to pushSRI to associate a + * StreamSRI with the stream ID before calling pushPacket, or receivers + * may drop the data. + * + * When all processing on a stream is complete, a call should be made to + * pushPacket with the end-of-stream flag set to "true". + * + * Interactions with non-BULKIO ports are left up to the discretion of + * the component developer. + * + * Properties: + * + * Properties are accessed through members of the same name; characters + * that are invalid for a Java identifier are replaced with "_". The + * current value of the property is read with getValue and written with + * setValue: + * + * float val = this.float_prop.getValue(); + * ... + * this.float_prop.setValue(1.5f); + * + * Primitive data types are stored using the corresponding Java object + * wrapper class. For example, a property of type "float" is stored as a + * Float. Java will automatically box and unbox primitive types where + * appropriate. + * + * Numeric properties support assignment via setValue from any numeric + * type. The standard Java type coercion rules apply (e.g., truncation + * of floating point values when converting to integer types). + * + * Example: + * + * This example assumes that the component has two ports: + * - A bulkio.InShortPort provides (input) port called dataShort_in + * - A bulkio.OutFloatPort uses (output) port called dataFloat_out + * The mapping between the port and the class is found in the component + * base class file. + * This example also makes use of the following Properties: + * - A float value called amplitude with a default value of 2.0 + * - A boolean called increaseAmplitude with a default value of true + * + * bulkio.InShortPort.Packet data = this.port_dataShort_in.getPacket(125); + * + * if (data != null) { + * float[] outData = new float[data.getData().length]; + * for (int i = 0; i < data.getData().length; i++) { + * if (this.increaseAmplitude.getValue()) { + * outData[i] = (float)data.getData()[i] * this.amplitude.getValue(); + * } else { + * outData[i] = (float)data.getData()[i]; + * } + * } + * + * // NOTE: You must make at least one valid pushSRI call + * if (data.sriChanged()) { + * this.port_dataFloat_out.pushSRI(data.getSRI()); + * } + * this.port_dataFloat_out.pushPacket(outData, data.getTime(), data.getEndOfStream(), data.getStreamID()); + * } + * + */ + protected int serviceFunction() { + logger.debug("serviceFunction() example log message"); + + return NOOP; + } + + @Override + public void runTest(int testid, CF.PropertiesHolder testValues) throws CF.UnknownProperties, CF.TestableObjectPackage.UnknownTest + { + switch (testid) { + case 0: + this.runEnumTest(testValues); + break; + default: + throw new CF.TestableObjectPackage.UnknownTest(); + } + } + + private CF.DataType[] toProperties(List props) + { + return props.toArray(new CF.DataType[props.size()]); + } + + private CF.DataType createDataType(String id, float value) + { + org.omg.CORBA.Any any = orb.create_any(); + any.insert_float(value); + return new CF.DataType(id, any); + } + + private CF.DataType createDataType(String id, int value) + { + org.omg.CORBA.Any any = orb.create_any(); + any.insert_long(value); + return new CF.DataType(id, any); + } + + private CF.DataType createDataType(String id, String value) + { + org.omg.CORBA.Any any = orb.create_any(); + any.insert_string(value); + return new CF.DataType(id, any); + } + + private CF.DataType createDataType(String id, CF.DataType[] value) + { + org.omg.CORBA.Any any = orb.create_any(); + CF.PropertiesHelper.insert(any, value); + return new CF.DataType(id, any); + } + + private void runEnumTest(CF.PropertiesHolder testValues) throws CF.UnknownProperties + { + List unknown = new ArrayList(); + + for (CF.DataType prop : testValues.value) { + List value = new ArrayList(); + if (prop.id.equals("floatenum")) { + value.add(createDataType("DEFAULT", enums.floatenum.DEFAULT)); + value.add(createDataType("OTHER", enums.floatenum.OTHER)); + } else if (prop.id.equals("stringenum")) { + value.add(createDataType("START", enums.stringenum.START)); + value.add(createDataType("STOPPED", enums.stringenum.STOPPED)); + } else if (prop.id.equals("structprop")) { + List number_enums = new ArrayList(); + number_enums.add(createDataType("ZERO", enums.structprop.number.ZERO)); + number_enums.add(createDataType("ONE", enums.structprop.number.ONE)); + number_enums.add(createDataType("TWO", enums.structprop.number.TWO)); + value.add(createDataType("structprop::number", toProperties(number_enums))); + + List alpha_enums = new ArrayList(); + alpha_enums.add(createDataType("ABC", enums.structprop.alpha.ABC)); + alpha_enums.add(createDataType("DEF", enums.structprop.alpha.DEF)); + value.add(createDataType("structprop::alpha", toProperties(alpha_enums))); + } else if (prop.id.equals("structseq")) { + List number_enums = new ArrayList(); + number_enums.add(createDataType("POSITIVE", enums.structseq_struct.number.POSITIVE)); + number_enums.add(createDataType("ZERO", enums.structseq_struct.number.ZERO)); + number_enums.add(createDataType("NEGATIVE", enums.structseq_struct.number.NEGATIVE)); + value.add(createDataType("structseq::number", toProperties(number_enums))); + + List text_enums = new ArrayList(); + text_enums.add(createDataType("HEADER", enums.structseq_struct.text.HEADER)); + text_enums.add(createDataType("BODY", enums.structseq_struct.text.BODY)); + text_enums.add(createDataType("FOOTER", enums.structseq_struct.text.FOOTER)); + value.add(createDataType("structseq::text", toProperties(text_enums))); + } else { + _logger.error("Unknown property " + prop.id); + unknown.add(prop); + continue; + } + prop.value = orb.create_any(); + CF.PropertiesHelper.insert(prop.value, toProperties(value)); + } + + if (unknown.size() > 0) { + throw new CF.UnknownProperties(toProperties(unknown)); + } + } + + /** + * Set additional options for ORB startup. For example: + * + * orbProps.put("com.sun.CORBA.giop.ORBFragmentSize", Integer.toString(fragSize)); + * + * @param orbProps + */ + public static void configureOrb(final Properties orbProps) { + } + +} diff --git a/codegenTesting/sdr/dom/components/EnumTest/python/EnumTest.py b/codegenTesting/sdr/dom/components/EnumTest/python/EnumTest.py new file mode 100755 index 000000000..acec870bb --- /dev/null +++ b/codegenTesting/sdr/dom/components/EnumTest/python/EnumTest.py @@ -0,0 +1,225 @@ +#!/usr/bin/env python +# +# This file is protected by Copyright. Please refer to the COPYRIGHT file +# distributed with this source distribution. +# +# This file is part of REDHAWK codegenTesting. +# +# REDHAWK codegenTesting is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation, either version 3 of the License, or (at your option) any +# later version. +# +# REDHAWK codegenTesting is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +# details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/. +# +# +# +# AUTO-GENERATED +# +# Source: EnumTest.spd.xml +from ossie.resource import start_component +import logging + +from EnumTest_base import EnumTest_base, enums, NOOP + +from ossie import properties +from ossie.cf import CF + +class EnumTest_i(EnumTest_base): + """""" + def constructor(self): + """ + This is called by the framework immediately after your component registers with the system. + + In general, you should add customization here and not in the __init__ constructor. If you have + a custom port implementation you can override the specific implementation here with a statement + similar to the following: + self.some_port = MyPortImplementation() + + """ + # TODO add customization here. + + def process(self): + """ + Basic functionality: + + The process method should process a single "chunk" of data and then return. This method + will be called from the processing thread again, and again, and again until it returns + FINISH or stop() is called on the component. If no work is performed, then return NOOP. + + StreamSRI: + To create a StreamSRI object, use the following code (this generates a normalized SRI that does not flush the queue when full): + sri = bulkio.sri.create("my_stream_id") + + PrecisionUTCTime: + To create a PrecisionUTCTime object, use the following code: + tstamp = bulkio.timestamp.now() + + Ports: + + Each port instance is accessed through members of the following form: self.port_ + + Data is obtained in the process function through the getPacket call (BULKIO only) on a + provides port member instance. The optional argument is a timeout value, in seconds. + A zero value is non-blocking, while a negative value is blocking. Constants have been + defined for these values, bulkio.const.BLOCKING and bulkio.const.NON_BLOCKING. If no + timeout is given, it defaults to non-blocking. + + The return value is a named tuple with the following fields: + - dataBuffer + - T + - EOS + - streamID + - SRI + - sriChanged + - inputQueueFlushed + If no data is available due to a timeout, all fields are None. + + To send data, call the appropriate function in the port directly. In the case of BULKIO, + convenience functions have been added in the port classes that aid in output. + + Interactions with non-BULKIO ports are left up to the component developer's discretion. + + Messages: + + To receive a message, you need (1) an input port of type MessageEvent, (2) a message prototype described + as a structure property of kind message, (3) a callback to service the message, and (4) to register the callback + with the input port. + + Assuming a property of type message is declared called "my_msg", an input port called "msg_input" is declared of + type MessageEvent, create the following code: + + def msg_callback(self, msg_id, msg_value): + print msg_id, msg_value + + Register the message callback onto the input port with the following form: + self.port_input.registerMessage("my_msg", EnumTest_i.MyMsg, self.msg_callback) + + To send a message, you need to (1) create a message structure, and (2) send the message over the port. + + Assuming a property of type message is declared called "my_msg", an output port called "msg_output" is declared of + type MessageEvent, create the following code: + + msg_out = EnumTest_i.MyMsg() + this.port_msg_output.sendMessage(msg_out) + + Accessing the Device Manager and Domain Manager: + + Both the Device Manager hosting this Device and the Domain Manager hosting + the Device Manager are available to the Device. + + To access the Domain Manager: + dommgr = self.getDomainManager().getRef(); + To access the Device Manager: + devmgr = self.getDeviceManager().getRef(); + Properties: + + Properties are accessed directly as member variables. If the property name is baudRate, + then accessing it (for reading or writing) is achieved in the following way: self.baudRate. + + To implement a change callback notification for a property, create a callback function with the following form: + + def mycallback(self, id, old_value, new_value): + pass + + where id is the property id, old_value is the previous value, and new_value is the updated value. + + The callback is then registered on the component as: + self.addPropertyChangeListener('baudRate', self.mycallback) + + + Example: + + # This example assumes that the component has two ports: + # - A provides (input) port of type bulkio.InShortPort called dataShort_in + # - A uses (output) port of type bulkio.OutFloatPort called dataFloat_out + # The mapping between the port and the class if found in the component + # base class. + # This example also makes use of the following Properties: + # - A float value called amplitude + # - A boolean called increaseAmplitude + + packet = self.port_dataShort_in.getPacket() + + if packet.dataBuffer is None: + return NOOP + + outData = range(len(packet.dataBuffer)) + for i in range(len(packet.dataBuffer)): + if self.increaseAmplitude: + outData[i] = float(packet.dataBuffer[i]) * self.amplitude + else: + outData[i] = float(packet.dataBuffer[i]) + + # NOTE: You must make at least one valid pushSRI call + if packet.sriChanged: + self.port_dataFloat_out.pushSRI(packet.SRI); + + self.port_dataFloat_out.pushPacket(outData, packet.T, packet.EOS, packet.streamID) + return NORMAL + + """ + + # TODO fill in your code here + self._log.debug("process() example log message") + return NOOP + + def runTest(self, testid, testValues): + if testid == 0: + return self.runEnumTest(testValues) + else: + raise CF.TestableObject.UnknownTest() + + def runEnumTest(self, testValues): + unknown = [] + + for prop in testValues: + value = {} + if prop.id == "floatenum": + value['DEFAULT'] = enums.floatenum.DEFAULT + value['OTHER'] = enums.floatenum.OTHER + elif prop.id == "stringenum": + value['START'] = enums.stringenum.START + value['STOPPED'] = enums.stringenum.STOPPED + elif prop.id == "structprop": + number_enums = {} + number_enums['ZERO'] = enums.structprop.number.ZERO + number_enums['ONE'] = enums.structprop.number.ONE + number_enums['TWO'] = enums.structprop.number.TWO + value['structprop::number'] = number_enums + + alpha_enums = {} + alpha_enums['ABC'] = enums.structprop.alpha.ABC + alpha_enums['DEF'] = enums.structprop.alpha.DEF + value['structprop::alpha'] = alpha_enums + elif prop.id == "structseq": + number_enums = {} + number_enums['POSITIVE'] = enums.structseq_struct.number.POSITIVE + number_enums['ZERO'] = enums.structseq_struct.number.ZERO + number_enums['NEGATIVE'] = enums.structseq_struct.number.NEGATIVE + value['structseq::number'] = number_enums + + text_enums = {} + text_enums['HEADER'] = enums.structseq_struct.text.HEADER + text_enums['BODY'] = enums.structseq_struct.text.BODY + text_enums['FOOTER'] = enums.structseq_struct.text.FOOTER + value['structseq::text'] = text_enums + else: + unknown.append(prop) + prop.value = properties.props_to_any(properties.props_from_dict(value)) + + if unknown: + raise CF.UnknownProperties(unknown) + + return testValues + +if __name__ == '__main__': + logging.getLogger().setLevel(logging.INFO) + logging.debug("Starting Component") + start_component(EnumTest_i) diff --git a/codegenTesting/sdr/dom/components/EnumTest/tests/test_EnumTest.py b/codegenTesting/sdr/dom/components/EnumTest/tests/test_EnumTest.py new file mode 100644 index 000000000..1b4a090de --- /dev/null +++ b/codegenTesting/sdr/dom/components/EnumTest/tests/test_EnumTest.py @@ -0,0 +1,93 @@ +#!/usr/bin/env python +# +# This file is protected by Copyright. Please refer to the COPYRIGHT file +# distributed with this source distribution. +# +# This file is part of REDHAWK codegenTesting. +# +# REDHAWK codegenTesting is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation, either version 3 of the License, or (at your option) any +# later version. +# +# REDHAWK codegenTesting is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +# details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/. +# + +import ossie.utils.testing +from ossie.utils import sb +from ossie import properties + +class ComponentTests(ossie.utils.testing.RHTestCase): + # Path to the SPD file, relative to this file. This must be set in order to + # launch the component. + SPD_FILE = '../EnumTest.spd.xml' + + # setUp is run before every function preceded by "test" is executed + # tearDown is run after every function preceded by "test" is executed + + # self.comp is a component using the sandbox API + # to create a data source, the package sb contains data sources like DataSource or FileSource + # to create a data sink, there are sinks like DataSink and FileSink + # to connect the component to get data from a file, process it, and write the output to a file, use the following syntax: + # src = sb.FileSource('myfile.dat') + # snk = sb.DataSink() + # src.connect(self.comp) + # self.comp.connect(snk) + # sb.start() + # + # components/sources/sinks need to be started. Individual components or elements can be started + # src.start() + # self.comp.start() + # + # every component/elements in the sandbox can be started + # sb.start() + + def setUp(self): + # Launch the component, using the selected implementation + self.comp = sb.launch(self.spd_file, impl=self.impl) + + def tearDown(self): + # Clean up all sandbox artifacts created during test + sb.release() + + def _propsToDict(self, props): + return dict((dt['id'], dt['value']) for dt in props) + + def _runTests(self, props): + props = properties.props_from_dict(dict((p, None) for p in props)) + result = self.comp.runTest(0, props) + return properties.props_to_dict(result) + + def testSimpleEnums(self): + result = self._runTests(['floatenum', 'stringenum']) + self.assertEqual(result['floatenum'], self.comp.floatenum._enums) + self.assertEqual(result['stringenum'], self.comp.stringenum._enums) + + def testStructEnums(self): + result = self._runTests(['structprop']) + enums = result['structprop'] + + number_enums = self._propsToDict(enums['structprop::number']) + self.assertEqual(number_enums, self.comp.structprop.number._enums) + + alpha_enums = self._propsToDict(enums['structprop::alpha']) + self.assertEqual(alpha_enums, self.comp.structprop.alpha._enums) + + def testStructSequenceEnums(self): + result = self._runTests(['structseq']) + enums = result['structseq'] + + number_enums = self._propsToDict(enums['structseq::number']) + self.assertEqual(number_enums, self.comp.structseq.structDef.number._enums) + + text_enums = self._propsToDict(enums['structseq::text']) + self.assertEqual(text_enums, self.comp.structseq.structDef.text._enums) + +if __name__ == "__main__": + ossie.utils.testing.main() # By default tests all implementations diff --git a/redhawk-codegen/redhawk/codegen/jinja/cpp/component/pull/templates/resource_base.h b/redhawk-codegen/redhawk/codegen/jinja/cpp/component/pull/templates/resource_base.h index a1bc4d598..3bdf6f382 100644 --- a/redhawk-codegen/redhawk/codegen/jinja/cpp/component/pull/templates/resource_base.h +++ b/redhawk-codegen/redhawk/codegen/jinja/cpp/component/pull/templates/resource_base.h @@ -50,6 +50,17 @@ /*# Allow child templates to add #define statements #*/ /*{% endblock %}*/ +/*{% from "properties/properties.cpp" import enumvalues %}*/ +/*{% for prop in component.properties if prop.enums %}*/ +/*{% if loop.first %}*/ +namespace enums { +/*{% endif %}*/ + ${enumvalues(prop)|indent(4)} +/*{% if loop.last %}*/ +} + +/*{% endif %}*/ +/*{% endfor %}*/ /*{% block classPrototype %}*/ class ${className} : public ${component.superclasses|join(', public ', attribute='name')}, protected ThreadedComponent /*{% endblock %}*/ diff --git a/redhawk-codegen/redhawk/codegen/jinja/cpp/properties/mapping.py b/redhawk-codegen/redhawk/codegen/jinja/cpp/properties/mapping.py index 79f0bbf6f..92bcd6bfc 100644 --- a/redhawk-codegen/redhawk/codegen/jinja/cpp/properties/mapping.py +++ b/redhawk-codegen/redhawk/codegen/jinja/cpp/properties/mapping.py @@ -77,6 +77,12 @@ def mapSimpleProperty(self, prop): cppprop['format'] = self._getSimpleFormat(prop, False) return cppprop + def mapEnumeration(self, prop, label, value): + cppenum = {} + cppenum['cpplabel'] = cpp.identifier(label) + cppenum['cppvalue'] = cpp.literal(value, prop.type(), prop.isComplex()) + return cppenum + def mapSimpleSequenceProperty(self, prop): cppprop = self.mapProperty(prop) cppprop['cpptype'] = cpp.sequenceType(prop.type(), prop.isComplex()) diff --git a/redhawk-codegen/redhawk/codegen/jinja/cpp/properties/templates/properties.cpp b/redhawk-codegen/redhawk/codegen/jinja/cpp/properties/templates/properties.cpp index 37d4a9aa5..f3427828d 100644 --- a/redhawk-codegen/redhawk/codegen/jinja/cpp/properties/templates/properties.cpp +++ b/redhawk-codegen/redhawk/codegen/jinja/cpp/properties/templates/properties.cpp @@ -72,7 +72,19 @@ addProperty(${prop.cppname}, /*{%- endmacro %}*/ /*{% macro structdef(struct) %}*/ -/*{% from "properties/properties.cpp" import initsequence %}*/ +/*{% for field in struct.fields if field.enums %}*/ +/*{% if loop.first %}*/ +namespace enums { + // Enumerated values for ${struct.identifier} + namespace ${struct.cppname} { +/*{% endif %}*/ + ${enumvalues(field)|indent(8)} +/*{% if loop.last %}*/ + } +} + +/*{% endif %}*/ +/*{% endfor %}*/ struct ${struct.cpptype}${' : public '+struct.baseclass if struct.baseclass} { ${struct.cpptype} ()${' : '+struct.baseclass+'()' if struct.baseclass} { @@ -191,3 +203,12 @@ inline bool operator!= (const ${struct.cpptype}& s1, const ${struct.cpptype}& s2 return !(s1==s2); } /*{%- endmacro %}*/ + +/*{% macro enumvalues(prop) %}*/ +// Enumerated values for ${prop.identifier} +namespace ${prop.cppname} { +/*{% for enum in prop.enums %}*/ + static const ${prop.cpptype} ${enum.cpplabel} = ${enum.cppvalue}; +/*{% endfor %}*/ +} +/*{%- endmacro %}*/ diff --git a/redhawk-codegen/redhawk/codegen/jinja/environment.py b/redhawk-codegen/redhawk/codegen/jinja/environment.py index 6d3a99fa1..150fc98e3 100644 --- a/redhawk-codegen/redhawk/codegen/jinja/environment.py +++ b/redhawk-codegen/redhawk/codegen/jinja/environment.py @@ -49,6 +49,7 @@ def __init__(self, *args, **kwargs): self.tests['simplesequence'] = tests.is_simplesequence self.tests['struct'] = tests.is_struct self.tests['structsequence'] = tests.is_structsequence + self.tests['enumerated'] = tests.is_enumerated self.tests['provides'] = tests.is_provides self.tests['uses'] = tests.is_uses self.tests['bidir'] = tests.is_bidir diff --git a/redhawk-codegen/redhawk/codegen/jinja/java/component/base/templates/properties.java b/redhawk-codegen/redhawk/codegen/jinja/java/component/base/templates/properties.java index d875ce1f0..18518530a 100644 --- a/redhawk-codegen/redhawk/codegen/jinja/java/component/base/templates/properties.java +++ b/redhawk-codegen/redhawk/codegen/jinja/java/component/base/templates/properties.java @@ -173,3 +173,26 @@ public String getId() { ${structsequence(prop)} /*{% endif %}*/ /*{% endmacro %}*/ + +/*{% macro enumvalues(prop) %}*/ +/*{% if prop is structsequence %}*/ +/*{% set prop = prop.structdef %}*/ +/*{% endif %}*/ +/** + * Enumerated values for ${prop.identifier} + */ +public static class ${prop.javaname} { +/*{% if prop is struct %}*/ +/*{% for field in prop.fields if field.enums %}*/ +/*{% if not loop.first %}*/ + +/*{% endif %}*/ + ${enumvalues(field)|indent(4)} +/*{% endfor %}*/ +/*{% else %}*/ +/*{% for enum in prop.enums %}*/ + public static final ${enum.javatype} ${enum.javalabel} = ${enum.javavalue}; +/*{% endfor %}*/ +/*{% endif %}*/ +} +/*{% endmacro %}*/ diff --git a/redhawk-codegen/redhawk/codegen/jinja/java/component/pull/templates/resource_base.java b/redhawk-codegen/redhawk/codegen/jinja/java/component/pull/templates/resource_base.java index 2613ef028..4e75f90ca 100644 --- a/redhawk-codegen/redhawk/codegen/jinja/java/component/pull/templates/resource_base.java +++ b/redhawk-codegen/redhawk/codegen/jinja/java/component/pull/templates/resource_base.java @@ -116,6 +116,19 @@ public abstract class ${classname} extends ${superClass} { public final static Logger logger = Logger.getLogger(${classname}.class.getName()); /*{% import "base/properties.java" as properties with context %}*/ +/*{% for prop in component.properties if prop is enumerated %}*/ +/*{% if loop.first %}*/ + /** + * Enumerated values for properties + */ + public static class enums { +/*{% endif %}*/ + ${properties.enumvalues(prop)|indent(8)} +/*{% if loop.last %}*/ + } +/*{% endif %}*/ + +/*{% endfor %}*/ /*{% for prop in component.properties %}*/ /*{% if not prop.inherited %}*/ ${properties.create(prop)|indent(4)} diff --git a/redhawk-codegen/redhawk/codegen/jinja/java/properties.py b/redhawk-codegen/redhawk/codegen/jinja/java/properties.py index dae449a82..273f9d7c2 100644 --- a/redhawk-codegen/redhawk/codegen/jinja/java/properties.py +++ b/redhawk-codegen/redhawk/codegen/jinja/java/properties.py @@ -107,6 +107,14 @@ def mapSimpleProperty(self, prop): javaprop['isOptional'] = prop.isOptional() return javaprop + def mapEnumeration(self, prop, label, value): + javaenum = {} + enumtype = self.javaType(prop.type()) + javaenum['javatype'] = enumtype + javaenum['javalabel'] = java.identifier(label) + javaenum['javavalue'] = java.literal(value, enumtype, prop.isComplex()) + return javaenum + def mapSimpleSequenceProperty(self, prop): javaprop, javatype = self._createComplexJavaProp(prop) values = [] diff --git a/redhawk-codegen/redhawk/codegen/jinja/mapping.py b/redhawk-codegen/redhawk/codegen/jinja/mapping.py index 2da5b1f1c..4b242f2c6 100644 --- a/redhawk-codegen/redhawk/codegen/jinja/mapping.py +++ b/redhawk-codegen/redhawk/codegen/jinja/mapping.py @@ -19,6 +19,7 @@ # import os +import warnings from redhawk.codegen.model.properties import Kinds from redhawk.codegen.model.softwarecomponent import ComponentTypes @@ -43,12 +44,24 @@ def _mapProperty(self, prop, propclass): def _mapSimple(self, prop): propdict = self._mapProperty(prop, 'simple') propdict['type'] = prop.type() + if prop.hasEnumerations(): + propdict['enums'] = [self._mapEnumeration(prop, l, v) for (l, v) in prop.enumerations()] propdict.update(self.mapSimpleProperty(prop)) return propdict def mapSimpleProperty(self, prop): return {} + def _mapEnumeration(self, prop, label, value): + enumdict = {} + enumdict['label'] = label + enumdict['value'] = value + enumdict.update(self.mapEnumeration(prop, label, value)) + return enumdict + + def mapEnumeration(self, prop, label, value): + return {} + def _mapSimpleSequence(self, prop): propdict = self._mapProperty(prop, 'simplesequence') propdict['type'] = prop.type() @@ -60,8 +73,7 @@ def mapSimpleSequenceProperty(self, prop): def _mapStruct(self, prop): propdict = self._mapProperty(prop, 'struct') - fields = [self._mapSimple(s) for s in prop.fields() if isinstance(s, redhawk.codegen.model.properties.SimpleProperty)] - fields += [self._mapSimpleSequence(s) for s in prop.fields() if isinstance(s, redhawk.codegen.model.properties.SimpleSequenceProperty)] + fields = [self._mapField(f) for f in prop.fields()] propdict['fields'] = fields propdict.update(self.mapStructProperty(prop, fields)) return propdict @@ -81,6 +93,16 @@ def _mapStructSequence(self, prop): def mapStructSequenceProperty(self, prop, structdef): return {} + def _mapField(self, prop): + # NB: This does not support struct or struct sequences as fields; + # however, if at some point the PRF is extended to add them, + if prop.isStruct(): + warnings.warn('Only simple and simplesequence properties may appear in a struct') + elif prop.isSequence(): + return self._mapSimpleSequence(prop) + else: + return self._mapSimple(prop) + def mapProperties(self, softpkg): simple = [self._mapSimple(s) for s in softpkg.getSimpleProperties()] simplesequence = [self._mapSimpleSequence(s) for s in softpkg.getSimpleSequenceProperties()] diff --git a/redhawk-codegen/redhawk/codegen/jinja/python/component/base/templates/properties.py b/redhawk-codegen/redhawk/codegen/jinja/python/component/base/templates/properties.py index 9c125afb7..498e8963a 100644 --- a/redhawk-codegen/redhawk/codegen/jinja/python/component/base/templates/properties.py +++ b/redhawk-codegen/redhawk/codegen/jinja/python/component/base/templates/properties.py @@ -243,3 +243,23 @@ def getMembers(self): ${structsequence(prop)} #{% endif %} #{% endmacro %} + +#{% macro enumvalues(prop) %} +#{% if prop is structsequence %} +#{% set prop = prop.structdef %} +#{% endif %} +# Enumerated values for ${prop.identifier} +class ${prop.pyname}: +#{% if prop is struct %} +#{% for field in prop.fields if field.enums %} +#{% if not loop.first %} + +#{% endif %} + ${enumvalues(field)|indent(4)} +#{% endfor %} +#{% else %} +#{% for enum in prop.enums %} + ${enum.pylabel} = ${enum.pyvalue} +#{% endfor %} +#{% endif %} +#{% endmacro %} diff --git a/redhawk-codegen/redhawk/codegen/jinja/python/component/pull/templates/resource_base.py b/redhawk-codegen/redhawk/codegen/jinja/python/component/pull/templates/resource_base.py index 4242b9dc6..769bed800 100644 --- a/redhawk-codegen/redhawk/codegen/jinja/python/component/pull/templates/resource_base.py +++ b/redhawk-codegen/redhawk/codegen/jinja/python/component/pull/templates/resource_base.py @@ -63,6 +63,14 @@ #{# Allow additional child class imports #} #{% endblock %} +#{% import "base/properties.py" as properties with context %} +#{% for prop in component.properties if prop is enumerated %} +#{% if loop.first %} +class enums: +#{% endif %} + ${properties.enumvalues(prop)|indent(4)} + +#{% endfor %} class ${className}(${component.poaclass}, ${component.superclasses|join(', ', attribute='name')}, ThreadedComponent): # These values can be altered in the __init__ of your derived class @@ -160,7 +168,6 @@ class ${portgen.templateClass()}(${portgen.poaClass()}): # # DO NOT ADD NEW PROPERTIES HERE. You can add properties in your derived class, in the PRF xml file # or by using the IDE. -#{% import "base/properties.py" as properties with context %} #{% filter codealign %} #{% for prop in component.properties %} #{% if prop is struct and not prop.builtin %} diff --git a/redhawk-codegen/redhawk/codegen/jinja/python/properties.py b/redhawk-codegen/redhawk/codegen/jinja/python/properties.py index f5582c531..4164e2bca 100644 --- a/redhawk-codegen/redhawk/codegen/jinja/python/properties.py +++ b/redhawk-codegen/redhawk/codegen/jinja/python/properties.py @@ -47,6 +47,12 @@ def mapSimpleProperty(self, simple): pyprop['value'] = simple.value() return pyprop + def mapEnumeration(self, prop, label, value): + pyenum = {} + pyenum['pylabel'] = python.identifier(label) + pyenum['pyvalue'] = python.literal(value, prop.type(), prop.isComplex()) + return pyenum + def mapSimpleSequenceProperty(self, simplesequence): pyprop = self.mapProperty(simplesequence) pyprop['isComplex'] = simplesequence.isComplex() diff --git a/redhawk-codegen/redhawk/codegen/jinja/tests.py b/redhawk-codegen/redhawk/codegen/jinja/tests.py index 2651128e8..134f29127 100644 --- a/redhawk-codegen/redhawk/codegen/jinja/tests.py +++ b/redhawk-codegen/redhawk/codegen/jinja/tests.py @@ -89,6 +89,23 @@ def is_structsequence(prop): """ return prop['class'] == 'structsequence' +def is_enumerated(prop): + """ + Returns True if the property, or one of its nested properties, has + enumerated values. + """ + if is_simple(prop): + return 'enums' in prop + elif is_struct(prop): + # If any field is enumerated, return True + return any(is_enumerated(f) for f in prop['fields']) + elif is_structsequence(prop): + # Check the struct defintion + return is_enumerated(prop['structdef']) + else: + # Simple sequence properties do not support enumerations + return False + def _getvalue(obj, name): """ Looks up the item or attribute 'name' in obj. If the item is callable, diff --git a/redhawk-codegen/redhawk/codegen/model/properties.py b/redhawk-codegen/redhawk/codegen/model/properties.py index 456efd4c6..68d0f47d3 100644 --- a/redhawk-codegen/redhawk/codegen/model/properties.py +++ b/redhawk-codegen/redhawk/codegen/model/properties.py @@ -154,6 +154,9 @@ def hasValue(self): def value(self): return self.xml.value + def hasEnumerations(self): + return bool(self.xml.enumerations) + def enumerations(self): if self.xml.enumerations: return [(e.label, e.value) for e in self.xml.enumerations.enumeration] From 8fca348f909efe68ad1ca10f67d0bd88eb1c950a Mon Sep 17 00:00:00 2001 From: Ryan Bauman Date: Wed, 28 Jun 2017 17:49:21 -0400 Subject: [PATCH 0835/1644] RELENG-658 - bump for 2.1.1-rc2 --- .gitlab-ci.yml | 7 ++++--- GPP/GPP.spec | 5 ++++- bulkioInterfaces/bulkioInterfaces.spec | 5 ++++- burstioInterfaces/burstioInterfaces.spec | 5 ++++- frontendInterfaces/frontendInterfaces.spec | 2 +- redhawk-codegen/redhawk-codegen.spec | 5 ++++- redhawk/src/releng/redhawk.spec | 5 ++++- 7 files changed, 25 insertions(+), 9 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 9db217c3e..e1733a48d 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -24,7 +24,8 @@ stages: # Don't build redhawk tests as part of rpmbuild to save time - if [ "$project" == "redhawk" ]; then sed -i 's|testing||' src/Makefile.am; fi - proj_lower=$(echo $project | tr '[:upper:]' '[:lower:]') - - docker build --tag=${docker_registry}redhawk-rpmbuild:$proj_lower-$CI_COMMIT_SHA-${dist}-${arch} + - safe_ref=$(echo ${CI_COMMIT_REF_NAME} | tr -d /| tr '[:upper:]' '[:lower:]') + - docker build --tag=${docker_registry}redhawk-rpmbuild:$proj_lower-$safe_ref-${dist}-${arch} --build-arg "project=$project" --build-arg "arch=$arch" --build-arg "spec_file=$specfile" @@ -32,7 +33,7 @@ stages: --build-arg "other_repos=$other_repos/$dist/$arch" --build-arg "local_repo=$local_repo" . # Create a yum repository from the packages we just built and any packages we've built in a previous stage - - id=$(docker create -it ${docker_registry}redhawk-rpmbuild:$proj_lower-$CI_COMMIT_SHA-$dist-$arch bash -lc 'mkdir -p /tmp/repo; + - id=$(docker create -it ${docker_registry}redhawk-rpmbuild:$proj_lower-$safe_ref-$dist-$arch bash -lc 'mkdir -p /tmp/repo; for file in `find /usr/src/yum /root/rpmbuild/RPMS -name '*.rpm'`; do cp -v $file /tmp/repo; done; @@ -44,7 +45,7 @@ stages: - cd $CI_PROJECT_DIR - rm -rf output && mkdir output - docker cp $id:/tmp/repo/repo.tar.gz output/repo.tar.gz - - docker rm -f $id + - docker rm -f $id || true artifacts: name: $CI_JOB_NAME paths: diff --git a/GPP/GPP.spec b/GPP/GPP.spec index a070b246e..e695ec463 100644 --- a/GPP/GPP.spec +++ b/GPP/GPP.spec @@ -32,7 +32,7 @@ Prefix: %{_prefix} Name: GPP Version: 2.1.1 -Release: 1%{?dist} +Release: 2%{?dist} Summary: REDHAWK GPP Group: Applications/Engineering @@ -120,6 +120,9 @@ find %{_prefix}/dev/nodes -type d -name 'DevMgr_*' -uid 0 -exec chown -R redhawk %changelog +* Wed Jun 28 2017 Ryan Bauman - 2.1.1-2 +- Bump for 2.1.1-rc2 + * Fri Jan 9 2015 1.11.0-1 - Update for cpp GPP diff --git a/bulkioInterfaces/bulkioInterfaces.spec b/bulkioInterfaces/bulkioInterfaces.spec index 0ecbc4d11..17c325cc7 100644 --- a/bulkioInterfaces/bulkioInterfaces.spec +++ b/bulkioInterfaces/bulkioInterfaces.spec @@ -29,7 +29,7 @@ Prefix: %{_prefix} Name: bulkioInterfaces Version: 2.1.1 -Release: 1%{?dist} +Release: 2%{?dist} Summary: The bulkio library for REDHAWK Group: Applications/Engineering @@ -97,6 +97,9 @@ rm -rf --preserve-root $RPM_BUILD_ROOT %changelog +* Wed Jun 28 2017 Ryan Bauman - 2.1.1-2 +- Bump for 2.1.1-rc2 + * Fri Mar 21 2014 1.10.0-1 - Improve OS version detection for RHEL/CentOS/Fedora diff --git a/burstioInterfaces/burstioInterfaces.spec b/burstioInterfaces/burstioInterfaces.spec index 22f471dbf..6df8fd2c9 100644 --- a/burstioInterfaces/burstioInterfaces.spec +++ b/burstioInterfaces/burstioInterfaces.spec @@ -29,7 +29,7 @@ Prefix: %{_prefix} Name: burstioInterfaces Version: 2.1.1 -Release: 1%{?dist} +Release: 2%{?dist} Summary: BURSTIO interfaces for REDHAWK Group: Applications/Engineering @@ -109,5 +109,8 @@ rm -rf --preserve-root $RPM_BUILD_ROOT %changelog +* Wed Jun 28 2017 Ryan Bauman - 2.1.1-2 +- Bump for 2.1.1-rc2 + * Thu Feb 20 2014 1.10.0 - Initial commit diff --git a/frontendInterfaces/frontendInterfaces.spec b/frontendInterfaces/frontendInterfaces.spec index e5f2c0457..f6852be5c 100644 --- a/frontendInterfaces/frontendInterfaces.spec +++ b/frontendInterfaces/frontendInterfaces.spec @@ -35,7 +35,7 @@ Prefix: %{_prefix} Summary: The frontend library for REDHAWK Name: frontendInterfaces Version: 2.4.1 -Release: 1%{?dist} +Release: 2%{?dist} License: LGPLv3+ Group: REDHAWK/Interfaces Source: %{name}-%{version}.tar.gz diff --git a/redhawk-codegen/redhawk-codegen.spec b/redhawk-codegen/redhawk-codegen.spec index 60f0d71f5..65c5c5ec4 100644 --- a/redhawk-codegen/redhawk-codegen.spec +++ b/redhawk-codegen/redhawk-codegen.spec @@ -24,7 +24,7 @@ Prefix: %{_prefix} Name: redhawk-codegen Version: 2.1.1 -Release: 1%{?dist} +Release: 2%{?dist} Summary: Redhawk Code Generators Group: Applications/Engineering @@ -93,6 +93,9 @@ rm -rf $RPM_BUILD_ROOT %endif %changelog +* Wed Jun 28 2017 Ryan Bauman - 2.1.1-2 +- Bump for 2.1.1-rc2 + * Thu May 21 2015 - 2.0.0-2 - Update python-jinja2 package for el7 diff --git a/redhawk/src/releng/redhawk.spec b/redhawk/src/releng/redhawk.spec index 17bf1f6d3..01471b591 100644 --- a/redhawk/src/releng/redhawk.spec +++ b/redhawk/src/releng/redhawk.spec @@ -27,7 +27,7 @@ Prefix: %{_sysconfdir} Name: redhawk Version: 2.1.1 -Release: 1%{?dist} +Release: 2%{?dist} Summary: REDHAWK is a Software Defined Radio framework Group: Applications/Engineering @@ -271,6 +271,9 @@ fi %changelog +* Wed Jun 28 2017 Ryan Bauman - 2.1.1-2 +- Bump for 2.1.1-rc2 + * Sat Nov 26 2016 - 2.0.4 - Added service directory in redhawk-sdrroot-dev-mgr From cf3dd1e396d5a8ca9b24e5b624357434ce2f4ac8 Mon Sep 17 00:00:00 2001 From: Ryan Bauman Date: Wed, 28 Jun 2017 18:08:40 -0400 Subject: [PATCH 0836/1644] RELENG-658 - update versions for 2.1.2 release --- .gitlab-ci.yml | 4 ++-- GPP/GPP.spd.xml | 2 +- GPP/GPP.spec | 7 +++++-- GPP/build.sh | 6 +++--- GPP/cpp/configure.ac | 2 +- bulkioInterfaces/build.sh | 6 +++--- bulkioInterfaces/bulkioInterfaces.spec | 7 +++++-- bulkioInterfaces/configure.ac | 4 ++-- bulkioInterfaces/libsrc/setup.py | 2 +- burstioInterfaces/burstioInterfaces.spec | 7 +++++-- burstioInterfaces/configure.ac | 4 ++-- frontendInterfaces/build.sh | 6 +++--- frontendInterfaces/configure.ac | 4 ++-- frontendInterfaces/frontendInterfaces.spec | 12 ++++++------ frontendInterfaces/libsrc/setup.py | 2 +- redhawk-codegen/redhawk-codegen.spec | 7 +++++-- redhawk-codegen/redhawk/codegen/versions.py | 2 +- redhawk/src/base/framework/python/ossie/version.py | 2 +- redhawk/src/configure.ac | 2 +- redhawk/src/releng/redhawk.spec | 7 +++++-- redhawk/src/testing/setup.py | 2 +- 21 files changed, 56 insertions(+), 41 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index e1733a48d..d8c0db021 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -262,7 +262,7 @@ deploy: deploy-release: variables: - redhawk_version: '2.1.1' + redhawk_version: '2.1.2' jenkins_job: $redhawk_version/job/REDHAWK-core-framework-$redhawk_version <<: *deploy-common only: @@ -287,7 +287,7 @@ test-trigger:release: stage: deploy dependencies: [] variables: - redhawk_version: '2.1.1' + redhawk_version: '2.1.2' script: - curl --insecure -X POST -F ref=$redhawk_version -F token=$test_token diff --git a/GPP/GPP.spd.xml b/GPP/GPP.spd.xml index a85806866..a561b4d79 100644 --- a/GPP/GPP.spd.xml +++ b/GPP/GPP.spd.xml @@ -19,7 +19,7 @@ details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see http://www.gnu.org/licenses/. --> - + Redhawk GPP null diff --git a/GPP/GPP.spec b/GPP/GPP.spec index e695ec463..1368c551f 100644 --- a/GPP/GPP.spec +++ b/GPP/GPP.spec @@ -31,8 +31,8 @@ Prefix: %{_prefix} %define _infodir %{_prefix}/info Name: GPP -Version: 2.1.1 -Release: 2%{?dist} +Version: 2.1.2 +Release: 1%{?dist} Summary: REDHAWK GPP Group: Applications/Engineering @@ -120,6 +120,9 @@ find %{_prefix}/dev/nodes -type d -name 'DevMgr_*' -uid 0 -exec chown -R redhawk %changelog +* Wed Jun 28 2017 Ryan Bauman - 2.1.2-1 +- Update for 2.1.2-rc1 + * Wed Jun 28 2017 Ryan Bauman - 2.1.1-2 - Bump for 2.1.1-rc2 diff --git a/GPP/build.sh b/GPP/build.sh index 02d81ed5d..63475b831 100755 --- a/GPP/build.sh +++ b/GPP/build.sh @@ -24,9 +24,9 @@ if [ "$1" = "rpm" ]; then if [ -e GPP.spec ]; then mydir=`dirname $0` tmpdir=`mktemp -d` - cp -r ${mydir} ${tmpdir}/GPP-2.1.1 - tar czf ${tmpdir}/GPP-2.1.1.tar.gz --exclude=".svn" -C ${tmpdir} GPP-2.1.1 - rpmbuild -ta ${tmpdir}/GPP-2.1.1.tar.gz + cp -r ${mydir} ${tmpdir}/GPP-2.1.2 + tar czf ${tmpdir}/GPP-2.1.2.tar.gz --exclude=".svn" -C ${tmpdir} GPP-2.1.2 + rpmbuild -ta ${tmpdir}/GPP-2.1.2.tar.gz rm -rf $tmpdir else echo "Missing RPM spec file in" `pwd` diff --git a/GPP/cpp/configure.ac b/GPP/cpp/configure.ac index 5a47d725b..d902e675e 100644 --- a/GPP/cpp/configure.ac +++ b/GPP/cpp/configure.ac @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see http://www.gnu.org/licenses/. */ -AC_INIT(GPP, 2.1.1) +AC_INIT(GPP, 2.1.2) AM_INIT_AUTOMAKE([foreign nostdinc subdir-objects]) AC_CONFIG_MACRO_DIR([m4]) diff --git a/bulkioInterfaces/build.sh b/bulkioInterfaces/build.sh index 28273ddf1..d8fe80654 100755 --- a/bulkioInterfaces/build.sh +++ b/bulkioInterfaces/build.sh @@ -25,9 +25,9 @@ elif [ "$1" = "rpm" ]; then # A very simplistic RPM build scenario mydir=`dirname $0` tmpdir=`mktemp -d` - cp -r ${mydir} ${tmpdir}/bulkioInterfaces-2.1.1 - tar czf ${tmpdir}/bulkioInterfaces-2.1.1.tar.gz --exclude=".git" -C ${tmpdir} bulkioInterfaces-2.1.1 - rpmbuild -ta ${tmpdir}/bulkioInterfaces-2.1.1.tar.gz + cp -r ${mydir} ${tmpdir}/bulkioInterfaces-2.1.2 + tar czf ${tmpdir}/bulkioInterfaces-2.1.2.tar.gz --exclude=".git" -C ${tmpdir} bulkioInterfaces-2.1.2 + rpmbuild -ta ${tmpdir}/bulkioInterfaces-2.1.2.tar.gz rm -rf $tmpdir else # Checks if build is newer than makefile (based on modification time) diff --git a/bulkioInterfaces/bulkioInterfaces.spec b/bulkioInterfaces/bulkioInterfaces.spec index 17c325cc7..4550ae18a 100644 --- a/bulkioInterfaces/bulkioInterfaces.spec +++ b/bulkioInterfaces/bulkioInterfaces.spec @@ -28,8 +28,8 @@ Prefix: %{_prefix} %bcond_without java Name: bulkioInterfaces -Version: 2.1.1 -Release: 2%{?dist} +Version: 2.1.2 +Release: 1%{?dist} Summary: The bulkio library for REDHAWK Group: Applications/Engineering @@ -97,6 +97,9 @@ rm -rf --preserve-root $RPM_BUILD_ROOT %changelog +* Wed Jun 28 2017 Ryan Bauman - 2.1.2-1 +- Bump for 2.1.2-rc2 + * Wed Jun 28 2017 Ryan Bauman - 2.1.1-2 - Bump for 2.1.1-rc2 diff --git a/bulkioInterfaces/configure.ac b/bulkioInterfaces/configure.ac index 6db17caad..62053abb2 100644 --- a/bulkioInterfaces/configure.ac +++ b/bulkioInterfaces/configure.ac @@ -18,7 +18,7 @@ # along with this program. If not, see http://www.gnu.org/licenses/. # -AC_INIT(bulkioInterfaces, 2.1.1) +AC_INIT(bulkioInterfaces, 2.1.2) AC_CONFIG_MACRO_DIR([m4]) AC_SUBST([LIBBULKIOINTERFACES_VERSION_INFO], [3:0:1]) @@ -44,7 +44,7 @@ fi PKG_CHECK_MODULES([OMNIORB], [omniORB4 >= 4.1.0]) RH_PKG_IDLDIR([OMNIORB], [omniORB4]) -PKG_CHECK_MODULES([OSSIE], [ossie >= 2.1.1]) +PKG_CHECK_MODULES([OSSIE], [ossie >= 2.1.2]) RH_PKG_IDLDIR([OSSIE], [ossie]) PKG_CHECK_MODULES([OMNICOS], [omniCOS4 >= 4.0.0]) RH_PKG_IDLDIR([OMNICOS], [omniCOS4]) diff --git a/bulkioInterfaces/libsrc/setup.py b/bulkioInterfaces/libsrc/setup.py index 1c62ebb42..1227d3217 100644 --- a/bulkioInterfaces/libsrc/setup.py +++ b/bulkioInterfaces/libsrc/setup.py @@ -29,7 +29,7 @@ # replaces it (i.e. a developer does a command-line build), use 1.X.X version='__VERSION__' if version.find('__') == 0: - version = '2.1.1' + version = '2.1.2' setup( name='bulkio', diff --git a/burstioInterfaces/burstioInterfaces.spec b/burstioInterfaces/burstioInterfaces.spec index 6df8fd2c9..1eea0e335 100644 --- a/burstioInterfaces/burstioInterfaces.spec +++ b/burstioInterfaces/burstioInterfaces.spec @@ -28,8 +28,8 @@ Prefix: %{_prefix} %bcond_without java Name: burstioInterfaces -Version: 2.1.1 -Release: 2%{?dist} +Version: 2.1.2 +Release: 1%{?dist} Summary: BURSTIO interfaces for REDHAWK Group: Applications/Engineering @@ -109,6 +109,9 @@ rm -rf --preserve-root $RPM_BUILD_ROOT %changelog +* Wed Jun 28 2017 Ryan Bauman - 2.1.2-1 +- Update for 2.1.2-rc1 + * Wed Jun 28 2017 Ryan Bauman - 2.1.1-2 - Bump for 2.1.1-rc2 diff --git a/burstioInterfaces/configure.ac b/burstioInterfaces/configure.ac index 68442dbe4..9711b0e65 100644 --- a/burstioInterfaces/configure.ac +++ b/burstioInterfaces/configure.ac @@ -18,7 +18,7 @@ # along with this program. If not, see http://www.gnu.org/licenses/. # -AC_INIT(burstioInterfaces, 2.1.1) +AC_INIT(burstioInterfaces, 2.1.2) AC_CONFIG_SRCDIR([src/cpp/Makefile.am]) AC_CONFIG_MACRO_DIR([m4]) @@ -42,7 +42,7 @@ fi AC_LANG_PUSH([C++]) PKG_CHECK_MODULES([OMNIORB], [omniORB4 >= 4.1.0]) -PKG_CHECK_MODULES(OSSIE, ossie >= 2.1.1,,exit) +PKG_CHECK_MODULES(OSSIE, ossie >= 2.1.2,,exit) RH_PKG_IDLDIR([OSSIE], [ossie]) PKG_CHECK_MODULES([BULKIO], [bulkio >= 2.1]) diff --git a/frontendInterfaces/build.sh b/frontendInterfaces/build.sh index 9df463656..1af3a88f1 100755 --- a/frontendInterfaces/build.sh +++ b/frontendInterfaces/build.sh @@ -25,9 +25,9 @@ elif [ "$1" = "rpm" ]; then # A very simplistic RPM build scenario mydir=`dirname $0` tmpdir=`mktemp -d` - cp -r ${mydir} ${tmpdir}/frontendInterfaces-2.4.1 - tar czf ${tmpdir}/frontendInterfaces-2.4.1.tar.gz --exclude=".svn" -C ${tmpdir} frontendInterfaces-2.4.1 - rpmbuild -ta ${tmpdir}/frontendInterfaces-2.4.1.tar.gz + cp -r ${mydir} ${tmpdir}/frontendInterfaces-2.4.2 + tar czf ${tmpdir}/frontendInterfaces-2.4.2.tar.gz --exclude=".svn" -C ${tmpdir} frontendInterfaces-2.4.2 + rpmbuild -ta ${tmpdir}/frontendInterfaces-2.4.2.tar.gz rm -rf $tmpdir else # Checks if build is newer than makefile (based on modification time) diff --git a/frontendInterfaces/configure.ac b/frontendInterfaces/configure.ac index dff8d1a77..e003afbad 100644 --- a/frontendInterfaces/configure.ac +++ b/frontendInterfaces/configure.ac @@ -18,7 +18,7 @@ # along with this program. If not, see http://www.gnu.org/licenses/. # -AC_INIT(frontendInterfaces, 2.4.1) +AC_INIT(frontendInterfaces, 2.4.2) AM_INIT_AUTOMAKE(nostdinc) AC_PROG_CC @@ -41,7 +41,7 @@ if test "$IDL" = no; then fi AC_LANG_PUSH([C++]) PKG_CHECK_MODULES([OMNIORB], [omniORB4 >= 4.1.0]) -PKG_CHECK_MODULES([OSSIE], [ossie >= 2.1.1]) +PKG_CHECK_MODULES([OSSIE], [ossie >= 2.1.2]) RH_PKG_IDLDIR([OSSIE], [ossie]) # If you depend on other IDL modules, such as CF or BULKIO add them here diff --git a/frontendInterfaces/frontendInterfaces.spec b/frontendInterfaces/frontendInterfaces.spec index f6852be5c..0ce85f29f 100644 --- a/frontendInterfaces/frontendInterfaces.spec +++ b/frontendInterfaces/frontendInterfaces.spec @@ -34,8 +34,8 @@ Prefix: %{_prefix} Summary: The frontend library for REDHAWK Name: frontendInterfaces -Version: 2.4.1 -Release: 2%{?dist} +Version: 2.4.2 +Release: 1%{?dist} License: LGPLv3+ Group: REDHAWK/Interfaces Source: %{name}-%{version}.tar.gz @@ -43,10 +43,10 @@ Vendor: REDHAWK BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot -Requires: redhawk >= 2.1.1 -Requires: bulkioInterfaces >= 2.1.1 -BuildRequires: redhawk-devel >= 2.1.1 -BuildRequires: bulkioInterfaces >= 2.1.1 +Requires: redhawk >= 2.1.2 +Requires: bulkioInterfaces >= 2.1.2 +BuildRequires: redhawk-devel >= 2.1.2 +BuildRequires: bulkioInterfaces >= 2.1.2 %description Libraries and interface definitions for frontend. diff --git a/frontendInterfaces/libsrc/setup.py b/frontendInterfaces/libsrc/setup.py index b04d72c22..17ef35d2d 100644 --- a/frontendInterfaces/libsrc/setup.py +++ b/frontendInterfaces/libsrc/setup.py @@ -29,7 +29,7 @@ # replaces it (i.e. a developer does a command-line build), use 1.X.X version='__VERSION__' if version.find('__') == 0: - version = '2.4.1' + version = '2.4.2' setup( name='frontend', diff --git a/redhawk-codegen/redhawk-codegen.spec b/redhawk-codegen/redhawk-codegen.spec index 65c5c5ec4..0dd41d303 100644 --- a/redhawk-codegen/redhawk-codegen.spec +++ b/redhawk-codegen/redhawk-codegen.spec @@ -23,8 +23,8 @@ Prefix: %{_prefix} Name: redhawk-codegen -Version: 2.1.1 -Release: 2%{?dist} +Version: 2.1.2 +Release: 1%{?dist} Summary: Redhawk Code Generators Group: Applications/Engineering @@ -93,6 +93,9 @@ rm -rf $RPM_BUILD_ROOT %endif %changelog +* Wed Jun 28 2017 Ryan Bauman - 2.1.2-1 +- Bump for 2.1.2-rc1 + * Wed Jun 28 2017 Ryan Bauman - 2.1.1-2 - Bump for 2.1.1-rc2 diff --git a/redhawk-codegen/redhawk/codegen/versions.py b/redhawk-codegen/redhawk/codegen/versions.py index 961a28d50..ddfd34096 100644 --- a/redhawk-codegen/redhawk/codegen/versions.py +++ b/redhawk-codegen/redhawk/codegen/versions.py @@ -17,7 +17,7 @@ # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see http://www.gnu.org/licenses/. # -codegen = '2.1.1' +codegen = '2.1.2' redhawk = '2.1' jinja2 = '2.6' boost = '1.41' diff --git a/redhawk/src/base/framework/python/ossie/version.py b/redhawk/src/base/framework/python/ossie/version.py index 2f49373df..7ea172d60 100644 --- a/redhawk/src/base/framework/python/ossie/version.py +++ b/redhawk/src/base/framework/python/ossie/version.py @@ -18,4 +18,4 @@ # along with this program. If not, see http://www.gnu.org/licenses/. # -__version__='2.1.1' +__version__='2.1.2' diff --git a/redhawk/src/configure.ac b/redhawk/src/configure.ac index 7960949eb..d4ac92fc9 100644 --- a/redhawk/src/configure.ac +++ b/redhawk/src/configure.ac @@ -19,7 +19,7 @@ # dnl Update this version number immedately after a release -AC_INIT([ossie],[2.1.1]) +AC_INIT([ossie],[2.1.2]) #AM_INIT_AUTOMAKE(nostdinc) # allows filenames over 99 characters long during dist AM_INIT_AUTOMAKE([1.9 tar-pax subdir-objects]) diff --git a/redhawk/src/releng/redhawk.spec b/redhawk/src/releng/redhawk.spec index 01471b591..079e8e4b8 100644 --- a/redhawk/src/releng/redhawk.spec +++ b/redhawk/src/releng/redhawk.spec @@ -26,8 +26,8 @@ Prefix: %{_sdrroot} Prefix: %{_sysconfdir} Name: redhawk -Version: 2.1.1 -Release: 2%{?dist} +Version: 2.1.2 +Release: 1%{?dist} Summary: REDHAWK is a Software Defined Radio framework Group: Applications/Engineering @@ -271,6 +271,9 @@ fi %changelog +* Wed Jun 28 2017 Ryan Bauman - 2.1.2-1 +- Update for 2.1.2-rc1 + * Wed Jun 28 2017 Ryan Bauman - 2.1.1-2 - Bump for 2.1.1-rc2 diff --git a/redhawk/src/testing/setup.py b/redhawk/src/testing/setup.py index b5ec387ba..fd6eb0642 100644 --- a/redhawk/src/testing/setup.py +++ b/redhawk/src/testing/setup.py @@ -47,7 +47,7 @@ '_unitTestHelpers.runtestHelpers', '_unitTestHelpers.buildconfig'] -version='2.1.1' +version='2.1.2' setup( name='unitTestHelper', From 46d74225d1895d299931bf7f2c31f379b90f8233 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Thu, 29 Jun 2017 08:26:02 -0400 Subject: [PATCH 0837/1644] Only remove the codegen testing link to $SDRROOT/dom/mgr if it exists. Fixes running the tests in a clean environment (like CI). --- codegenTesting/runtests.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/codegenTesting/runtests.py b/codegenTesting/runtests.py index 307e9bbc2..a8cc6dd22 100755 --- a/codegenTesting/runtests.py +++ b/codegenTesting/runtests.py @@ -29,7 +29,8 @@ # ComponentHost for shared library components sdrroot = os.path.join(os.getcwd(), "sdr") mgrpath = os.path.join(sdrroot, 'dom/mgr') -os.unlink(mgrpath) +if os.path.exists(mgrpath): + os.unlink(mgrpath) os.symlink(os.path.join(os.environ['SDRROOT'], 'dom/mgr'), mgrpath) # Point to the testing SDR folder From fffb8a08b38e385716f480040f9b80eddda5910c Mon Sep 17 00:00:00 2001 From: Max Robert Date: Fri, 30 Jun 2017 14:02:51 -0400 Subject: [PATCH 0838/1644] Refs CF-350 and CF-423. Added stream interface to DataSink --- bulkioInterfaces/libsrc/python/__init__.py | 2 + .../libsrc/python/input_stream.py | 487 ++++++++++++++++++ .../ossie/utils/bulkio/bulkio_data_helpers.py | 194 +++---- .../python/ossie/utils/sb/io_helpers.py | 34 +- redhawk/src/testing/tests/test_13_TestSB.py | 214 +++++++- 5 files changed, 823 insertions(+), 108 deletions(-) create mode 100644 bulkioInterfaces/libsrc/python/input_stream.py diff --git a/bulkioInterfaces/libsrc/python/__init__.py b/bulkioInterfaces/libsrc/python/__init__.py index 650b7831e..b7cc3c63e 100644 --- a/bulkioInterfaces/libsrc/python/__init__.py +++ b/bulkioInterfaces/libsrc/python/__init__.py @@ -48,6 +48,8 @@ import const +from input_stream import InputStream, StreamMgr + from input_ports import * from output_ports import * diff --git a/bulkioInterfaces/libsrc/python/input_stream.py b/bulkioInterfaces/libsrc/python/input_stream.py new file mode 100644 index 000000000..9853b00bc --- /dev/null +++ b/bulkioInterfaces/libsrc/python/input_stream.py @@ -0,0 +1,487 @@ + +from ossie.cf import CF, CF__POA +from bulkio.bulkioInterfaces import BULKIO, BULKIO__POA +import time + +def createCPUTimestamp(): + """ + Generates a BULKIO.PrecisionUTCTime object using the current + CPU time that you can use in the pushPacket call + """ + ts = time.time() + return BULKIO.PrecisionUTCTime(BULKIO.TCM_CPU, + BULKIO.TCS_VALID, 0.0, + int(ts), ts - int(ts)) + +def addUTCTime(time_1, time_2): + ''' + Return a UTCTime (or PrecisionUTCTime) value incremented by time_2 + ''' + fulltime = (time_1.twsec+time_1.tfsec) + float(time_2) + if isinstance(time_1, CF.UTCTime): + retval = rhtime.now() + else: + retval = createCPUTimestamp() + retval.twsec = int(fulltime) + retval.tfsec = fulltime - retval.twsec + return retval + +def subUTCTime(time_1, time_2): + ''' + Return a UTCTime (or PrecisionUTCTime) value reduced by time_2 + ''' + fulltime = (time_1.twsec+time_1.tfsec) - float(time_2) + if isinstance(time_1, CF.UTCTime): + retval = rhtime.now() + else: + retval = createCPUTimestamp() + retval.twsec = int(fulltime) + retval.tfsec = fulltime - retval.twsec + return retval + +def diffUTCTime(time_1, time_2): + ''' + Return the difference in time between 2 UTCTime (or PrecisionUTCTime) values + ''' + retval = (time_1.twsec+time_1.tfsec) - (time_2.twsec+time_2.tfsec) + return retval + +class BaseStream(object): + def __init__(self, parent, sri): + self._sri = sri + self._parent = parent + def sri(self): + return self._sri + +class DataBlock(object): + def __init__(self, sri, data, tstamps, new_sri, flushed=False): + self._sri = sri + self._data = data + self._new_sri = new_sri + self._tstamps = tstamps + self._flushed = flushed + def data(self): + return self._data + def sri(self): + return self._sri + def xdelta(self): + return self._sri.xdelta + def sriChanged(self): + return self._new_sri + def inputQueueFlushed(self): + return self._flushed + def getStartTime(self): + return self._tstamps[0][1] + def getTimestamps(self): + return self._tstamps + def getNetTimeDrift(self): + if len(self._tstamps) == 1: + return 0 + diff_time = diffUTCTime(self._tstamps[-1][1], self._tstamps[0][1]) + synth_time = self._sri.xdelta * len(self._data) + return abs(diff_time - synth_time) + def getMaxTimeDrift(self): + max_drift = 0 + for _diff in range(len(self._tstamps)-1): + diff_time = diffUTCTime(self._tstamps[_diff][1], self._tstamps[_diff-1][1]) + synth_time = self._sri.xdelta * self._tstamps[_diff][0]-self._tstamps[_diff-1][0] + drift = abs(diff_time - synth_time) + if drift > max_drift: + max_drift = drift + return max_drift + +class _dataUnit(object): + def __init__(self, data, T, valid): + self._data = data + self._T = T + self._valid = valid + self._creation = time.time() + def getData(self): + return self._data + def delData(self, begin=0, end=-1): + if type(self._data) == str: + if end == -1: + end = len(_data) + self._data = self._data[:begin]+self._data[end:] + else: + del self._data[begin:end] + self._valid = False + def getCreateTime(self): + return self._creation + def getTstamp(self): + return self._T + def updateTstamp(self, offset): + if self._T: + self._T = addUTCTime(self._T, offset) + def cleanup(self, count, xdelta): + self.delData(end=count) + self.updateTstamp(count * xdelta) + def getValidTstamp(self): + return self._valid + +class _sriUnit(object): + def __init__(self, sri, offset): + self._offset = offset + self._sri = sri + def getOffset(self): + return self._offset + def changeOffset(self, delta): + self._offset = self._offset - delta + def getSri(self): + return self._sri + def getStreamID(self): + return self._sri.streamID + +class StreamMgr(object): + def __init__(self): + self._streams = [] + self._livingStreams = {} + + def getStream(self, streamID): + for _stream in self._streams: + if _stream.getStreamID() == streamID: + return _stream + for _stream in self._livingStreams: + if self._livingStreams[_stream].getStreamID() == streamID: + return self._livingStreams[_stream] + return None + + def getStreams(self): + retval = [] + for _stream in self._streams: + retval.append(_stream) + for _stream in self._livingStreams: + retval.append(self._livingStreams[_stream]) + return retval + + def getCurrentStream(self): + if len(self._streams) != 0: + return self._streams[0] + streams_with_data = [] + for _stream in self._livingStreams: + if self._livingStreams[_stream].samplesAvailable() != 0: + streams_with_data.append(_stream) + if len(streams_with_data) == 0: + return None + oldest = (0,'') + for _stream in streams_with_data: + if oldest[0] == 0: + oldest = (_stream, self._livingStreams[_stream].getOldestCreateTime()) + continue + if self._livingStreams[_stream].getOldestCreateTime() < oldest[1]: + oldest = (_stream, self._livingStreams[_stream].getOldestCreateTime()) + return self._livingStreams[oldest[0]] + + def _removeStream(self, stream): + for stream_idx in range(len(self._streams)): + if self._streams[stream_idx] == stream: + self._streams.pop(stream_idx) + break + +class _notificationList(list): + def __init__(self, *args): + list.__init__(self, *args) + self._popCallback = self.defaultCallback + def defaultCallback(self): + pass + def addPopCallback(self, fn): + self._popCallback = fn + def pop(self, arg): + retval = list.pop(self, arg) + self._popCallback() + return retval + +class InputStream(BaseStream): + def __init__(self, parent, sri): + BaseStream.__init__(self, parent, sri) + self._enabled = True + self._data = _notificationList() + self._sri_idx = [] + self._eos = False + self._new_sri = True + self._flushed = False + + def streamID(self): + return self._sri.streamID + + def _updateSRI(self, sri): + # this sri applies to whatever packet is delivered next + if len(self._data) == 0: + self._new_sri = True + self._sri = sri + return + self._sri_idx.append(_sriUnit(sri, len(self._data))) + + def _flushData(self): + self._parent.port_cond.acquire() + try: + self._data = [] + self._flushed = True + finally: + self._parent.port_cond.release() + + def setDataPopCallback(self, fn): + self._data.addPopCallback(fn) + + def _updateData(self, data, T, EOS): + self._parent.port_cond.acquire() + try: + self._data.append(_dataUnit(data, T, True)) + if EOS: + self._eos = True + self._parent.port_cond.notifyAll() + finally: + self._parent.port_cond.release() + + def getOldestCreateTime(self): + if len(self._data) != 0: + return self._data[0].getCreateTime() + else: + return None + + def _dataCurrSri(self): + upper_end = len(self._data) + if len(self._sri_idx) != 0: + upper_end = self._sri_idx[0].getOffset() + total_data = 0 + for total_data_idx in range(upper_end): + total_data += len(self._data[total_data_idx].getData()) + return total_data + + def _packetRemoved(self): + ''' + this function exists to inform any class that overloads this class that the self._data queue has been decremented by 1 + ''' + pass + + def read(self, count=None, consume=None, blocking=True): + ''' + Blocking read from the data buffer. + count: number of items read. All available if None + consumer: how far to move the read pointer. Move by count if None + + Note: if a new SRI was received, read all data until the new SRI + ''' + # if the amount of data left is 0, erase this from parent._streams + if len(self._data) == 0 and self._eos: + self._parent._removeStream(self) + return None + + if not count: + self._parent.port_cond.acquire() + count = self.samplesAvailableSingleSRI() + self._parent.port_cond.release() + if not consume: + consume = count + + while True: + # is there enough data for this sri? + # is there enough in the first packet? + try: + self._parent.port_cond.acquire() + if len(self._data) != 0: + if len(self._sri_idx) == 0: + if self._dataCurrSri() < count: + continue + ret_data = [] + tstamps = [] + total_read = actual_read = data_idx = curr_idx = consume_count = 0 + consume_count = consume + while total_read < count: + actual_read = len(self._data[data_idx].getData()) + if total_read + actual_read > count: + actual_read = count - total_read + ret_data += self._data[data_idx].getData()[:actual_read] + tstamps += [(curr_idx, self._data[data_idx].getTstamp())] + curr_idx += len(self._data[data_idx].getData()) + total_read += actual_read + consume_now = actual_read + if consume_now > consume_count: + consume_now = consume_count + consume_count -= consume_now + self._data[data_idx].cleanup(consume_now, self._sri.xdelta) + data_idx += 1 + if self._sri.subsize != 0: + framelength = self._sri.subsize if not self._sri.mode else 2 * self._sri.subsize + if float(len(ret_data))/framelength != len(ret_data)/framelength: + print 'The data length ('+str(len(ret_data))+') divided by subsize ('+str(self._sri.subsize)+')is not a whole number' + return None + _ret_data = [] + for idx in range(len(ret_data)/framelength): + _ret_data.append(ret_data[idx*framelength:(idx+1)*framelength]) + ret_data = _ret_data + ret_block = DataBlock(self._sri, ret_data, tstamps, self._new_sri, self._flushed) + if self._flushed: + self._flushed = False + self._new_sri = False + while True: + if len(self._data) == 0: + break + if len(self._data[0].getData()) == 0: + self._data.pop(0) + else: + break + return ret_block + # are there other sri in the queue? + else: + ret_data = [] + tstamps = [] + curr_idx = 0 + number_data = self._sri_idx[0].getOffset() + total_data = self._dataCurrSri() + if total_data <= count: + # return it all for the current sri and queue up the next sri + for data_idx in range(number_data): + ret_data += self._data[data_idx].getData() + tstamps += [(curr_idx, self._data[data_idx].getTstamp())] + curr_idx += len(self._data[data_idx].getData()) + number_pop = 0 + consume_count = consume + while consume_count != 0: + consume_now = len(self._data[0].getData()) + if consume_now <= consume_count: + self._data.pop(0) + consume_count -= consume_now + number_pop += 1 + continue + self._data[0].cleanup(consume_count, self._sri.xdelta) + consume_count = 0 + for _item_sri_idx in self._sri_idx: + _item_sri_idx.changeOffset(number_pop) + if self._sri.subsize != 0: + framelength = self._sri.subsize if not self._sri.mode else 2 * self._sri.subsize + if float(len(ret_data))/framelength != len(ret_data)/framelength: + print 'The data length ('+str(len(ret_data))+') divided by subsize ('+str(self._sri.subsize)+')is not a whole number' + return None + _ret_data = [] + for idx in range(len(ret_data)/framelength): + _ret_data.append(ret_data[idx*framelength:(idx+1)*framelength]) + ret_data = _ret_data + ret_block = DataBlock(self._sri, ret_data, tstamps, self._new_sri, self._flushed) + if self._flushed: + self._flushed = False + self._new_sri = True + self._sri = self._sri_idx.pop(0).getSri() + return ret_block + else: + # find a subset + total_read = actual_read = 0 + for data_idx in range(number_data): + actual_read = len(self._data[data_idx].getData()) + if total_read + actual_read > count: + actual_read = count - total_read + ret_data += self._data[data_idx].getData()[:actual_read] + tstamps += [(curr_idx, self._data[data_idx].getTstamp())] + curr_idx += len(self._data[data_idx].getData()) + total_read += actual_read + if total_read == count: + break + number_pop = 0 + consume_count = consume + while consume_count != 0: + consume_now = len(self._data[0].getData()) + if consume_now <= consume_count: + self._data.pop(0) + consume_count -= consume_now + number_pop += 1 + continue + self._data[0].cleanup(consume_count, self._sri.xdelta) + consume_count = 0 + for _item_sri_idx in self._sri_idx: + _item_sri_idx.changeOffset(number_pop) + if self._sri.subsize != 0: + framelength = self._sri.subsize if not self._sri.mode else 2 * self._sri.subsize + if float(len(ret_data))/framelength != len(ret_data)/framelength: + print 'The data length ('+str(len(ret_data))+') divided by subsize ('+str(self._sri.subsize)+')is not a whole number' + return None + _ret_data = [] + for idx in range(len(ret_data)/framelength): + _ret_data.append(ret_data[idx*framelength:(idx+1)*framelength]) + ret_data = _ret_data + ret_block = DataBlock(self._sri, ret_data, tstamps, self._new_sri) + self._new_sri = False + return ret_block + # this sleep happens if len(self._sri_idx) == 0 and total_data < count + finally: + self._parent.port_cond.release() + if not blocking: + break + time.sleep(0.1) + return None + + def tryread(self, count=None, consume=None): + ''' + Non-blocking read from the data buffer. + count: number of items read. All available if None + consumer: how far to move the read pointer. Move by count if None + + Note: if a new SRI was received, read all data until the new SRI + ''' + return self.read(count, consume, False) + + def skip(self, count=None): + ''' + Move forward the read pointer by count or the next SRI, whichever comes first. + Move to next SRI if None + Returns the number of skipped elements + ''' + number_pop = 0 + consume_count = count + total_consumed = 0 + while consume_count != 0: + consume_now = len(self._data[0].getData()) + if consume_now <= consume_count: + self._data.pop(0) + consume_count -= consume_now + total_consumed += consume_now + for _item_sri_idx in self._sri_idx: + _item_sri_idx.changeOffset(1) + if len(self._sri_idx) != 0: + if self._sri_idx[0].getOffset() <= 0: + self._sri = self._sri_idx[0].getSri() + self._new_sri = True + self._sri_idx.pop(0) + break + continue + total_consumed += consume_count + self._data[0].cleanup(consume_count, self._sri.xdelta) + consume_count = 0 + return total_consumed + def ready(self): + return self.samplesAvailable() > 0 + def dataEstimate(self): + len_data = tstamps = 0 + for _data in self._data: + len_data += len(_data.getData()) + tstamps += 1 + return (len_data,tstamps) + def samplesAvailable(self): + len_data = 0 + for _data in self._data: + len_data += len(_data.getData()) + return len_data + def samplesAvailableSingleSRI(self): + len_data = 0 + data_block_reads = len(self._data) + if len(self._sri_idx) != 0: + data_block_reads = self._sri_idx[0].getOffset() + for _data_idx in range(data_block_reads): + len_data += len(self._data[_data_idx].getData()) + return len_data + def enable(self): + ''' + Do not drop incoming data + ''' + self._enabled = True + def disable(self): + ''' + Drop all incoming data + ''' + self._enabled = False + def enabled(self): + return self._enabled + def eos(self): + ''' + Has EOS been received? + ''' + return self._eos diff --git a/redhawk/src/base/framework/python/ossie/utils/bulkio/bulkio_data_helpers.py b/redhawk/src/base/framework/python/ossie/utils/bulkio/bulkio_data_helpers.py index beaa085bf..0421391aa 100644 --- a/redhawk/src/base/framework/python/ossie/utils/bulkio/bulkio_data_helpers.py +++ b/redhawk/src/base/framework/python/ossie/utils/bulkio/bulkio_data_helpers.py @@ -23,16 +23,17 @@ import os import array import threading -import bulkio_helpers +from ossie.utils.bulkio import bulkio_helpers import time import logging from new import classobj from ossie.utils.redhawk.base import attach try: + from bulkio import InputStream, StreamMgr from bulkio.bulkioInterfaces import BULKIO, BULKIO__POA -except: +except Exception, e: pass -from ossie.utils import _uuid +from ossie.utils import _uuid, rhtime logging.basicConfig() log = logging.getLogger(__name__) @@ -195,9 +196,7 @@ def run(self, data, sri=None, pktsize=1024, startTime=0.0, sampleRate=1.0, compl T = BULKIO.PrecisionUTCTime(BULKIO.TCM_CPU, BULKIO.TCS_VALID, 0.0, int(currentSampleTime), currentSampleTime - int(currentSampleTime)) self.pushPacket([], T, True, self.sri.streamID) - - -class ArraySink(object): +class ArraySink(StreamMgr): """ Simple class used to receive data from a port and store it in a python array. @@ -216,6 +215,7 @@ def __init__(self, porttype): Inputs: The BULKIO__POA data type """ + StreamMgr.__init__(self) self.port_type = porttype self.sri=bulkio_helpers.defaultSRI self.data = [] @@ -224,13 +224,24 @@ def __init__(self, porttype): self.breakBlock = False self.port_lock = threading.Lock() self.port_cond = threading.Condition(self.port_lock) - + + def __getattribute__(self, name): + if name == 'gotEOS': + _stream = object.__getattribute__(self, 'getCurrentStream')() + if _stream: + return _stream.eos() + attr = object.__getattribute__(self, name) + return attr + else: + attr = object.__getattribute__(self, name) + return attr + class estimateStruct(): len_data=0 num_timestamps=0 - def __init__(self, data=[], timestamps=[]): - self.len_data = len(data) - self.num_timestamps = len(timestamps) + def __init__(self, data=0, timestamps=0): + self.len_data = data + self.num_timestamps = timestamps def _isActive(self): return not self.gotEOS and not self.breakBlock @@ -251,12 +262,17 @@ def stop(self): self.port_cond.release() def eos(self): + _stream = self.getCurrentStream() + if _stream: + return _stream.eos() return self.gotEOS def waitEOS(self): self.port_cond.acquire() try: while self._isActive(): + if self.eos(): + break self.port_cond.wait() return self.gotEOS finally: @@ -271,6 +287,10 @@ def pushSRI(self, H): generate the header file """ self.sri = H + if not self._livingStreams.has_key(H.streamID): + self._livingStreams[H.streamID] = InputStream(self, H) + else: + self._livingStreams[H.streamID]._updateSRI(H) def pushPacket(self, data, ts, EOS, stream_id): """ @@ -282,87 +302,81 @@ def pushPacket(self, data, ts, EOS, stream_id): Flag indicating if this is the End Of the Stream The unique stream id """ - self.port_cond.acquire() - try: - self.gotEOS = EOS - self.timestamps.append([len(self.data), ts]) - self.data += data - self.port_cond.notifyAll() - finally: - self.port_cond.release() + if not self._livingStreams.has_key(stream_id): + self._livingStreams[stream_id] = InputStream(self, BULKIO.StreamSRI(1, 0.0, 1.0, 1, 0, 0.0, 0.0, 0, 0, stream_id, False, [])) + _stream = self._livingStreams[stream_id] + _stream._updateData(data, ts, EOS) + if EOS: + self._streams.append(_stream) + self._livingStreams.pop(stream_id) + + # legacy stuff + self.data += data def estimateData(self): self.port_cond.acquire() estimate = self.estimateStruct() - try: - estimate = self.estimateStruct(self.data, self.timestamps) - finally: - self.port_cond.release() + _streams = self.getStreams() + _total_data = 0 + _total_tstamps = 0 + for _stream in _streams: + (data_len,tstamp_len) = _stream.dataEstimate() + _total_data += data_len + _total_tstamps += tstamp_len + estimate = self.estimateStruct(_total_data, _total_tstamps) + self.port_cond.release() return estimate - + + def __syncAssocData(self, reference): + retval = [] + length_to_erase = None + for i,(l,t) in enumerate(reference[::-1]): + if l > length: + reference[len(reference)-i-1][0] = l - length + continue + if length_to_erase == None: + length_to_erase = len(reference)-i + retval.append((l,t)) + if length_to_erase != None: + del reference[:length_to_erase] + return retval + def retrieveData(self, length=None): + retval = [] + rettime = [] + while True: + self.port_cond.acquire() + _stream = self.getCurrentStream() + self.port_cond.release() + if not _stream and length != None: + time.sleep(0.1) + continue + break + if not _stream: + return None + done = False + goal = length self.port_cond.acquire() - try: - if length is None: - # No length specified; get all of the data. - length = len(self.data) - - # have not received any data yet (and I need a minimum amount) - if self.sri == None and len(self.data) == 0 and length != 0: - self.port_cond.wait() - - if self.sri != None and self.sri.subsize != 0: - frameLength = self.sri.subsize if not self.sri.mode else 2*self.sri.subsize - if float(length)/frameLength != length/frameLength: - print 'The requested length divided by the subsize ('+str(length)+'/'+str(self.sri.subsize)+') is not a whole number. Cannot return framed data' - return (None,None) - - # Wait for there to be enough data. - while len(self.data) < length and self._isActive(): - self.port_cond.wait() - - if len(self.data) > length: - # More data is available than was requested. Return only - # as much data as was asked for, and the associated - # timestamps. - rettime = [] - length_to_erase = None - for i,(l,t) in enumerate(self.timestamps[::-1]): - if l > length: - self.timestamps[len(self.timestamps)-i-1][0] = l - length - continue - if length_to_erase == None: - length_to_erase = len(self.timestamps)-i - rettime.append((l,t)) - if length_to_erase != None: - del self.timestamps[:length_to_erase] - if self.sri.subsize == 0: - retval = self.data[:length] - else: - retval = [] - frameLength = self.sri.subsize if not self.sri.mode else 2*self.sri.subsize - for idx in range(length/frameLength): - retval.append(self.data[idx*frameLength:(idx+1)*frameLength]) - del self.data[:length] - return (retval, rettime) - - # No length was provided, or length is equal to the length of data. - # Return all data and timestamps. - if self.sri == None: - (retval, rettime) = (self.data, self.timestamps) - elif self.sri.subsize == 0: - (retval, rettime) = (self.data, self.timestamps) + if length == None: + goal = _stream.samplesAvailable() + self.port_cond.release() + samples_read = 0 + while True: + _block = _stream.read(count=length) + if not _block: + break + retval += _block.data() + # The block timestamp offsets are relative to the start of that + # block, so adjust for any previous data offsets + rettime += [(off+samples_read, ts) for off, ts in _block.getTimestamps()] + goal_offset = 1 + if _block.sri().subsize != 0: + samples_read += sum(len(frame) for frame in _block.data()) else: - retval = [] - frameLength = self.sri.subsize if not self.sri.mode else 2*self.sri.subsize - for idx in range(length/frameLength): - retval.append(self.data[idx*frameLength:(idx+1)*frameLength]) - rettime = self.timestamps - self.data = [] - self.timestamps = [] - return (retval, rettime) - finally: - self.port_cond.release() + samples_read += len(_block.data()) + if samples_read >= goal: + break + return (retval, rettime) def getPort(self): """ @@ -558,13 +572,13 @@ def pushPacket(self, data, EOS, stream_id): Flag indicating if this is the End Of the Stream The unique stream id """ - self.port_cond.acquire() - try: - self.gotEOS = EOS - self.data.append(data) - self.port_cond.notifyAll() - finally: - self.port_cond.release() + if not self._livingStreams.has_key(stream_id): + self._livingStreams[stream_id] = InputStream(self, BULKIO.StreamSRI(1, 0.0, 1.0, 1, 0, 0.0, 0.0, 0, 0, stream_id, False, [])) + _stream = self._livingStreams[stream_id] + _stream._updateData([data], None, EOS) + if EOS: + self._streams.append(_stream) + self._livingStreams.pop(stream_id) class XmlArraySource(ArraySource): "This sub-class exists to override pushPacket for dataXML ports." diff --git a/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py b/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py index 110ea71dd..e31ff87e5 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py +++ b/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py @@ -38,6 +38,7 @@ import shlex as _shlex import time as _time import signal as _signal +import warnings as _warnings import cStringIO, pydoc import sys as _sys import os as _os @@ -802,9 +803,11 @@ def eos(self): self._sink exists. """ - if self._sink == None: return False + _stream = self._sink.getCurrentStream() + if _stream: + return _stream.eos() return self._sink.gotEOS def sri(self): @@ -1146,7 +1149,7 @@ def __init__(self): Helper to handle the generation of SDDS metadata forwarding """ _SourceBase.__init__(self, bytesPerPush = 0, dataFormat='sdds', formats=['sdds']) - self._src = bulkio_data_helpers.SDDSSource() + self._src = _bulkio_data_helpers.SDDSSource() self._blocking = True self._streamdefs = {} @@ -1811,8 +1814,22 @@ def getDataEstimate(self): return None return self._sink.estimateData() + def getStream(self, streamID): + return self._sink.getStream(streamID) + + def getStreams(self): + return self._sink.getStreams() + + def getCurrentStream(self): + ''' + Return the current data stream + ''' + return self._sink.getCurrentStream() + def getData(self, length=None, eos_block=False, tstamps=False): ''' + WARNING: This function is deprecated. Use getCurrentStream instead + Returns either an array of the received data elements or a tuple containing the received list and their associated time stamps @@ -1822,15 +1839,22 @@ def getData(self, length=None, eos_block=False, tstamps=False): eos_block: setting to True creates a blocking call until eos is received tstamps: setting to True makes the return value a tuple, where the first element is the data set and the second element is a series of tuples - containing the element index number of and timestamp + containing the element index number and the timestamp for that index ''' + _warnings.warn("This function is deprecated. Use getCurrentStream instead", DeprecationWarning) + isChar = self._sink.port_type == _BULKIO__POA.dataChar if not self._sink: return None if eos_block: self._sink.waitEOS() - (retval, timestamps) = self._sink.retrieveData(length=length) + _retval = self._sink.retrieveData(length=length) + if not _retval: + if tstamps: + return ([],[]) + return [] + (retval, timestamps) = _retval if isChar: # Converts char values into their numeric equivalents def from_char(data): @@ -1844,7 +1868,7 @@ def from_char(data): else: retval = from_char(retval) if tstamps: - return (retval,timestamps) + return (retval, timestamps) else: return retval diff --git a/redhawk/src/testing/tests/test_13_TestSB.py b/redhawk/src/testing/tests/test_13_TestSB.py index 8d2cc80fa..567e79b19 100644 --- a/redhawk/src/testing/tests/test_13_TestSB.py +++ b/redhawk/src/testing/tests/test_13_TestSB.py @@ -1584,14 +1584,6 @@ def test_NotSharedComponent(self): self.assertNotEqual(int(comp1.pid), int(comp2.pid)) -class Test_DataSDDSSource(unittest.TestCase): - - def test_CreateSDDSSource(self): - source = sb.DataSourceSDDS() - self.assertNotEquals(source, None) - - - class BulkioTest(unittest.TestCase): XMLDATA = """ @@ -2062,6 +2054,29 @@ def test_DataSourceTimeStampParam(self): _rnd_toffset = int(round( (_toffset+len(_srcData)/_sampleRate) *10))/10.0 self.assertEquals(_rnd_pkt_time,_rnd_toffset ) + def test_DataSinkSRI(self): + src = sb.DataSource(dataFormat='float') + snk = sb.DataSink() + src.connect(snk) + sb.start() + src.push([1,2,3,4,5],sampleRate=100) + src.push([1,2,3,4,5],sampleRate=1000) + src.push([1,2,3,4,5],sampleRate=10000) + wait_on_data(snk, 3) + stream=snk.getCurrentStream() + block_1 = stream.read() + self.assertNotEqual(block_1, None) + block_2 = stream.read() + self.assertNotEqual(block_2, None) + block_3 = stream.read() + self.assertNotEqual(block_3, None) + self.assertEquals(len(block_1.data()), 5) + self.assertEquals(len(block_2.data()), 5) + self.assertEquals(len(block_3.data()), 5) + self.assertEquals(block_1.xdelta(), 0.01) + self.assertEquals(block_2.xdelta(), 0.001) + self.assertEquals(block_3.xdelta(), 0.0001) + def _fileSourceThrottle(self, _file, rate): fp=open(_file, 'r') contents = fp.read() @@ -2101,8 +2116,10 @@ def test_DataSourceThrottle(self): self.assertTrue(time_difftime_estimate*0.9) - data=snk.getData() - self.assertEquals(len(data), 3.0*_dataLength) + stream=snk.getCurrentStream() + block_1 = stream.read() + self.assertNotEqual(block_1, None) + self.assertEquals(len(block_1.data()), 3.0*_dataLength) _sampleRate = 300 _dataLength = 100 @@ -2117,8 +2134,151 @@ def test_DataSourceThrottle(self): self.assertTrue(time_difftime_estimate*0.9) - data=snk.getData() - self.assertEquals(len(data), 3.0*_dataLength) + stream=snk.getCurrentStream() + block_1 = stream.read() + self.assertNotEqual(block_1, None) + self.assertEquals(len(block_1.data()), 3.0*_dataLength) + + def test_DataSinkMultipleStream(self): + src = sb.DataSource(dataFormat='float') + snk = sb.DataSink() + src.connect(snk) + sb.start() + src.push([1,2,3,4,5],sampleRate=100, streamID='hello_1') + src.push([6,7,8,9,10],sampleRate=1000, streamID='hello_2') + src.push([11,12,13,14,15],sampleRate=10000, streamID='hello_3') + src.push([16,17,18,19,20],sampleRate=100, streamID='hello_1') + + wait_on_data(snk, 3) + + stream=snk.getCurrentStream() + block_1 = stream.read() + self.assertNotEqual(block_1, None) + + stream=snk.getCurrentStream() + block_2 = stream.read() + self.assertNotEqual(block_2, None) + block_2_2 = stream.read(blocking=False) + self.assertEquals(block_2_2, None) + + stream=snk.getCurrentStream() + block_3 = stream.read() + self.assertNotEqual(block_3, None) + block_3_2 = stream.read(blocking=False) + self.assertEquals(block_3_2, None) + + stream=snk.getCurrentStream() + block_1_2 = stream.read() + self.assertNotEqual(block_1_2, None) + block_1_3 = stream.read(blocking=False) + self.assertEqual(block_1_3, None) + + self.assertEquals(block_1.data(), [1,2,3,4,5]) + self.assertEquals(block_1_2.data(), [16,17,18,19,20]) + self.assertEquals(block_2.data(), [6,7,8,9,10]) + self.assertEquals(block_3.data(), [11,12,13,14,15]) + self.assertEquals(block_1.xdelta(), 0.01) + self.assertEquals(block_2.xdelta(), 0.001) + self.assertEquals(block_3.xdelta(), 0.0001) + + def test_DataSinkReadConsume(self): + src = sb.DataSource(dataFormat='float') + snk = sb.DataSink() + src.connect(snk) + sb.start() + src.push([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20],sampleRate=100, streamID='hello_1') + + wait_on_data(snk, 1) + + stream=snk.getCurrentStream() + block_1 = stream.read(count=10, consume=5) + self.assertNotEqual(block_1, None) + self.assertEquals(block_1.data(), [1,2,3,4,5,6,7,8,9,10]) + + block_1 = stream.read(count=10, consume=5) + self.assertNotEqual(block_1, None) + self.assertEquals(block_1.data(), [6,7,8,9,10,11,12,13,14,15]) + + block_1 = stream.read(count=10, consume=5) + self.assertNotEqual(block_1, None) + self.assertEquals(block_1.data(), [11,12,13,14,15,16,17,18,19,20]) + + block_1 = stream.read(count=5, consume=5) + self.assertNotEqual(block_1, None) + self.assertEquals(block_1.data(), [16,17,18,19,20]) + + block_1 = stream.read(blocking=False) + self.assertEquals(block_1, None) + + def _test_DataSinkSkipDiffSRI(self): + src = sb.DataSource(dataFormat='float') + snk = sb.DataSink() + src.connect(snk) + sb.start() + src.push([1,2,3,4,5],sampleRate=100, streamID='hello_1') + src.push([6,7,8,9,10],sampleRate=1000, streamID='hello_1') + src.push([11,12,13,14,15,16,17,18,19,20,21,22,23,24,25],sampleRate=10000, streamID='hello_1') + + wait_on_data(snk, 4) + + stream=snk.getCurrentStream() + block_1 = stream.read(count=3) + self.assertNotEqual(block_1, None) + self.assertEquals(block_1.data(), [1,2,3]) + + skipped = stream.skip(10) + self.assertEquals(skipped, 2) + + block_1 = stream.read(count=2, consume=3) + self.assertNotEqual(block_1, None) + self.assertEquals(block_1.data(), [6,7]) + + skipped = stream.skip(10) + self.assertEquals(skipped, 2) + + block_1 = stream.read(count=2, consume=3) + self.assertNotEqual(block_1, None) + self.assertEquals(block_1.data(), [11,12]) + + skipped = stream.skip(10) + self.assertEquals(skipped, 10) + + block_1 = stream.read() + self.assertNotEqual(block_1, None) + self.assertEquals(block_1.data(), [23,24,25]) + + block_1 = stream.read(blocking=False) + self.assertEquals(block_1, None) + + def test_DataSinkSkip(self): + src = sb.DataSource(dataFormat='float') + snk = sb.DataSink() + src.connect(snk) + sb.start() + src.push([1,2,3,4,5],sampleRate=100, streamID='hello_1') + src.push([6,7,8,9,10],sampleRate=100, streamID='hello_1') + src.push([11,12,13,14,15],sampleRate=100, streamID='hello_1') + src.push([16,17,18,19,20],sampleRate=100, streamID='hello_1') + + wait_on_data(snk, 4) + + stream=snk.getCurrentStream() + block_1 = stream.read(count=3) + self.assertNotEqual(block_1, None) + self.assertEquals(block_1.data(), [1,2,3]) + + skipped = stream.skip(10) + self.assertEquals(skipped, 10) + + block_1 = stream.read(count=3, consume=5) + self.assertNotEqual(block_1, None) + self.assertEquals(block_1.data(), [14,15,16]) + + block_1 = stream.read(blocking=False) + self.assertNotEqual(block_1, None) + self.assertEquals(block_1.data(), [17,18,19,20]) + block_1 = stream.read(blocking=False) + self.assertEquals(block_1, None) class customSink(bulkio_data_helpers.ArraySink): def __init__(self, porttype): @@ -2128,6 +2288,10 @@ def pushSRI(self, H): _H = H _H.xdelta = H.xdelta * 2 self.sri = _H + if not self._livingStreams.has_key(_H.streamID): + self._livingStreams[_H.streamID] = bulkio_data_helpers.InputStream(self, _H) + else: + self._livingStreams[_H.streamID]._updateSRI(_H) def test_CustomDataSink(self): src = sb.DataSource(dataFormat='float') @@ -2139,7 +2303,31 @@ def test_CustomDataSink(self): src.push([1,2,3,4,5],sampleRate=10000) wait_on_data(snk, 3) data=snk.getData(tstamps=True) - self.assertEquals(snk._sink.sri.xdelta, 0.0002) + self.assertEquals(len(data[1]), 3) + self.assertEquals(len(data[0]), 15) + + def test_CustomStreamDataSink(self): + src = sb.DataSource(dataFormat='float') + snk = sb.DataSink(sinkClass=self.customSink) + src.connect(snk) + sb.start() + src.push([1,2,3,4,5],sampleRate=100) + src.push([1,2,3,4,5],sampleRate=1000) + src.push([1,2,3,4,5],sampleRate=10000) + wait_on_data(snk, 3) + stream=snk.getCurrentStream() + block_1 = stream.read() + self.assertNotEqual(block_1, None) + block_2 = stream.read() + self.assertNotEqual(block_2, None) + block_3 = stream.read() + self.assertNotEqual(block_3, None) + self.assertEquals(len(block_1.data()), 5) + self.assertEquals(len(block_2.data()), 5) + self.assertEquals(len(block_3.data()), 5) + self.assertEquals(block_1.xdelta(), 0.02) + self.assertEquals(block_2.xdelta(), 0.002) + self.assertEquals(block_3.xdelta(), 0.0002) def test_DataSourceSRI(self): _timeout = 1 From 2179432968621d63a2e28c5dfca61c87ace7ba30 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 3 Jul 2017 08:42:08 -0400 Subject: [PATCH 0839/1644] CF-1791 Ignore the "SPD" command line parameter in DomainManager --- redhawk/src/control/sdr/dommgr/main.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/redhawk/src/control/sdr/dommgr/main.cpp b/redhawk/src/control/sdr/dommgr/main.cpp index 978dbaa5f..92c735400 100644 --- a/redhawk/src/control/sdr/dommgr/main.cpp +++ b/redhawk/src/control/sdr/dommgr/main.cpp @@ -180,6 +180,8 @@ int old_main(int argc, char* argv[]) forceRebind = (value == "true"); } else if (param == "-ORBendPoint") { endPoint = true; + } else if (param == "SPD") { + // The SPD value is ignored at present } else if ( ii > 0 ) { // any other argument besides the first one is part of the execparams execparams[param] = argv[ii]; } From 63c41673742a1d635be003e0e9d21853c7a22fc7 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 3 Jul 2017 08:29:06 -0400 Subject: [PATCH 0840/1644] CF-1792 DOMAIN_NAME and SDRCACHE are processed separately from generic execparms --- redhawk/src/control/sdr/devmgr/main.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/redhawk/src/control/sdr/devmgr/main.cpp b/redhawk/src/control/sdr/devmgr/main.cpp index fa0ed41e0..f40d01184 100644 --- a/redhawk/src/control/sdr/devmgr/main.cpp +++ b/redhawk/src/control/sdr/devmgr/main.cpp @@ -222,10 +222,8 @@ int main(int argc, char* argv[]) spdFile = argv[ii]; } else if (param == "SDRCACHE") { sdrCache = argv[ii]; - execparams[param] = argv[ii]; } else if (param == "DOMAIN_NAME") { domainName = argv[ii]; - execparams[param] = argv[ii]; } else if (param == "LOGGING_CONFIG_URI") { logfile_uri = argv[ii]; } else if (pupper == "NOLOGCFG") { From dad9827d8e002016a20f2152ac6f261bce7ffa5d Mon Sep 17 00:00:00 2001 From: Max Robert Date: Mon, 3 Jul 2017 12:26:31 -0400 Subject: [PATCH 0841/1644] Refs CF-1644. Added test for working directory and cache directory to shared address space component --- GPP/build.sh | 5 + .../check_cwd_cpp_so/check_cwd_cpp_so.prf.xml | 8 + .../check_cwd_cpp_so/check_cwd_cpp_so.scd.xml | 45 ++++ .../check_cwd_cpp_so/check_cwd_cpp_so.spd.xml | 27 ++ .../check_cwd_cpp_so/cpp/Makefile.am | 61 +++++ .../check_cwd_cpp_so/cpp/Makefile.am.ide | 10 + .../check_cwd_cpp_so/cpp/check_cwd_cpp_so.cpp | 254 ++++++++++++++++++ .../check_cwd_cpp_so/cpp/check_cwd_cpp_so.h | 18 ++ .../cpp/check_cwd_cpp_so_base.cpp | 68 +++++ .../cpp/check_cwd_cpp_so_base.h | 30 +++ .../check_cwd_cpp_so/cpp/configure.ac | 26 ++ .../components/check_cwd_cpp_so/cpp/main.cpp | 11 + .../components/check_cwd_cpp_so/cpp/reconf | 6 + .../check_cwd_cpp_so_w.sad.xml | 23 ++ GPP/tests/test_GPP.py | 25 +- 15 files changed, 612 insertions(+), 5 deletions(-) create mode 100644 GPP/tests/sdr/dom/components/check_cwd_cpp_so/check_cwd_cpp_so.prf.xml create mode 100644 GPP/tests/sdr/dom/components/check_cwd_cpp_so/check_cwd_cpp_so.scd.xml create mode 100644 GPP/tests/sdr/dom/components/check_cwd_cpp_so/check_cwd_cpp_so.spd.xml create mode 100644 GPP/tests/sdr/dom/components/check_cwd_cpp_so/cpp/Makefile.am create mode 100644 GPP/tests/sdr/dom/components/check_cwd_cpp_so/cpp/Makefile.am.ide create mode 100644 GPP/tests/sdr/dom/components/check_cwd_cpp_so/cpp/check_cwd_cpp_so.cpp create mode 100644 GPP/tests/sdr/dom/components/check_cwd_cpp_so/cpp/check_cwd_cpp_so.h create mode 100644 GPP/tests/sdr/dom/components/check_cwd_cpp_so/cpp/check_cwd_cpp_so_base.cpp create mode 100644 GPP/tests/sdr/dom/components/check_cwd_cpp_so/cpp/check_cwd_cpp_so_base.h create mode 100644 GPP/tests/sdr/dom/components/check_cwd_cpp_so/cpp/configure.ac create mode 100644 GPP/tests/sdr/dom/components/check_cwd_cpp_so/cpp/main.cpp create mode 100755 GPP/tests/sdr/dom/components/check_cwd_cpp_so/cpp/reconf create mode 100644 GPP/tests/sdr/dom/waveforms/check_cwd_cpp_so_w/check_cwd_cpp_so_w.sad.xml diff --git a/GPP/build.sh b/GPP/build.sh index 63475b831..f14bb9d26 100755 --- a/GPP/build.sh +++ b/GPP/build.sh @@ -50,6 +50,11 @@ else ./build.sh $* fi cd - + cd tests/sdr/dom/components/check_cwd_cpp_so/cpp + if [ -e build.sh ]; then + ./build.sh $* + fi + cd - cd tests/sdr/dom/components/check_cwd_java if [ -e build.sh ]; then ./build.sh $* diff --git a/GPP/tests/sdr/dom/components/check_cwd_cpp_so/check_cwd_cpp_so.prf.xml b/GPP/tests/sdr/dom/components/check_cwd_cpp_so/check_cwd_cpp_so.prf.xml new file mode 100644 index 000000000..38b330346 --- /dev/null +++ b/GPP/tests/sdr/dom/components/check_cwd_cpp_so/check_cwd_cpp_so.prf.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/GPP/tests/sdr/dom/components/check_cwd_cpp_so/check_cwd_cpp_so.scd.xml b/GPP/tests/sdr/dom/components/check_cwd_cpp_so/check_cwd_cpp_so.scd.xml new file mode 100644 index 000000000..df94ceaf5 --- /dev/null +++ b/GPP/tests/sdr/dom/components/check_cwd_cpp_so/check_cwd_cpp_so.scd.xml @@ -0,0 +1,45 @@ + + + + 2.2 + + resource + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/GPP/tests/sdr/dom/components/check_cwd_cpp_so/check_cwd_cpp_so.spd.xml b/GPP/tests/sdr/dom/components/check_cwd_cpp_so/check_cwd_cpp_so.spd.xml new file mode 100644 index 000000000..fd894459f --- /dev/null +++ b/GPP/tests/sdr/dom/components/check_cwd_cpp_so/check_cwd_cpp_so.spd.xml @@ -0,0 +1,27 @@ + + + + + + null + + + + + + + + + The implementation contains descriptive information about the template for a software resource. + + + cpp/check_cwd_cpp_so.so + + + + + + + + + diff --git a/GPP/tests/sdr/dom/components/check_cwd_cpp_so/cpp/Makefile.am b/GPP/tests/sdr/dom/components/check_cwd_cpp_so/cpp/Makefile.am new file mode 100644 index 000000000..6120cd4ae --- /dev/null +++ b/GPP/tests/sdr/dom/components/check_cwd_cpp_so/cpp/Makefile.am @@ -0,0 +1,61 @@ +# +# This file is protected by Copyright. Please refer to the COPYRIGHT file +# distributed with this source distribution. +# +# This file is part of REDHAWK core. +# +# REDHAWK core is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation, either version 3 of the License, or (at your option) any +# later version. +# +# REDHAWK core is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +# details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/. +# +ACLOCAL_AMFLAGS = -I m4 -I${OSSIEHOME}/share/aclocal/ossie +AUTOMAKE_OPTIONS = subdir-objects + +ossieName = check_cwd_cpp_so +libdir = $(prefix)/dom/components/check_cwd_cpp_so/cpp +lib_LTLIBRARIES = check_cwd_cpp_so.la + +.PHONY: convenience-link clean-convenience-link + +all-local : convenience-link +clean-local : clean-convenience-link + +convenience-link : check_cwd_cpp_so.la + @ln -fs .libs/check_cwd_cpp_so.so + +clean-convenience-link: + @rm -f check_cwd_cpp_so.so + +distclean-local: + rm -rf m4 + rm -f config.* + rm -rf autom4te.cache + rm -f acinclude.m4 + rm -f aclocal.m4 + rm -f configure + rm -f depcomp + rm -f install-sh + rm -f ltmain.sh + rm -f Makefile.in + rm -f missing + rm -rf .deps + + +# Sources, libraries and library directories are auto-included from a file +# generated by the REDHAWK IDE. You can remove/modify the following lines if +# you wish to manually control these options. +include $(srcdir)/Makefile.am.ide +check_cwd_cpp_so_la_SOURCES = $(redhawk_SOURCES_auto) +check_cwd_cpp_so_la_LIBADD = $(SOFTPKG_LIBS) $(PROJECTDEPS_LIBS) $(BOOST_LDFLAGS) $(BOOST_THREAD_LIB) $(BOOST_REGEX_LIB) $(BOOST_SYSTEM_LIB) $(INTERFACEDEPS_LIBS) $(redhawk_LDADD_auto) +check_cwd_cpp_so_la_CXXFLAGS = -Wall $(SOFTPKG_CFLAGS) $(PROJECTDEPS_CFLAGS) $(BOOST_CPPFLAGS) $(INTERFACEDEPS_CFLAGS) $(redhawk_INCLUDES_auto) +check_cwd_cpp_so_la_LDFLAGS = -shared -module -export-dynamic -export-symbols-regex 'make_component' -avoid-version $(redhawk_LDFLAGS_auto) + diff --git a/GPP/tests/sdr/dom/components/check_cwd_cpp_so/cpp/Makefile.am.ide b/GPP/tests/sdr/dom/components/check_cwd_cpp_so/cpp/Makefile.am.ide new file mode 100644 index 000000000..3991ba858 --- /dev/null +++ b/GPP/tests/sdr/dom/components/check_cwd_cpp_so/cpp/Makefile.am.ide @@ -0,0 +1,10 @@ +# This file is regularly auto-generated by the REDHAWK IDE. Do not modify! +# Files can be excluded by right-clicking on the file in the project explorer +# and choosing Resource Configurations -> Exclude from build. Re-include files +# by opening the Properties dialog of your project and choosing C/C++ Build -> +# Tool Chain Editor, and un-checking "Exclude resource from build " +redhawk_SOURCES_auto = check_cwd_cpp_so.cpp +redhawk_SOURCES_auto += check_cwd_cpp_so.h +redhawk_SOURCES_auto += check_cwd_cpp_so_base.cpp +redhawk_SOURCES_auto += check_cwd_cpp_so_base.h +redhawk_SOURCES_auto += main.cpp diff --git a/GPP/tests/sdr/dom/components/check_cwd_cpp_so/cpp/check_cwd_cpp_so.cpp b/GPP/tests/sdr/dom/components/check_cwd_cpp_so/cpp/check_cwd_cpp_so.cpp new file mode 100644 index 000000000..ada9e9f11 --- /dev/null +++ b/GPP/tests/sdr/dom/components/check_cwd_cpp_so/cpp/check_cwd_cpp_so.cpp @@ -0,0 +1,254 @@ +/************************************************************************** + + This is the component code. This file contains the child class where + custom functionality can be added to the component. Custom + functionality to the base class can be extended here. Access to + the ports can also be done from this class + +**************************************************************************/ + +#include "check_cwd_cpp_so.h" + +PREPARE_LOGGING(check_cwd_cpp_so_i) + +check_cwd_cpp_so_i::check_cwd_cpp_so_i(const char *uuid, const char *label) : + check_cwd_cpp_so_base(uuid, label) +{ + // Avoid placing constructor code here. Instead, use the "constructor" function. + +} + +check_cwd_cpp_so_i::~check_cwd_cpp_so_i() +{ +} + +void check_cwd_cpp_so_i::constructor() +{ + /*********************************************************************************** + This is the RH constructor. All properties are properly initialized before this function is called + ***********************************************************************************/ + char *tmp = getcwd(NULL, 200); + if (tmp != NULL) { + this->cwd = std::string(tmp); + free(tmp); + } +} + +/*********************************************************************************************** + + Basic functionality: + + The service function is called by the serviceThread object (of type ProcessThread). + This call happens immediately after the previous call if the return value for + the previous call was NORMAL. + If the return value for the previous call was NOOP, then the serviceThread waits + an amount of time defined in the serviceThread's constructor. + + SRI: + To create a StreamSRI object, use the following code: + std::string stream_id = "testStream"; + BULKIO::StreamSRI sri = bulkio::sri::create(stream_id); + + Time: + To create a PrecisionUTCTime object, use the following code: + BULKIO::PrecisionUTCTime tstamp = bulkio::time::utils::now(); + + + Ports: + + Data is passed to the serviceFunction through by reading from input streams + (BulkIO only). The input stream class is a port-specific class, so each port + implementing the BulkIO interface will have its own type-specific input stream. + UDP multicast (dataSDDS and dataVITA49) ports do not support streams. + + The input stream from which to read can be requested with the getCurrentStream() + method. The optional argument to getCurrentStream() is a floating point number that + specifies the time to wait in seconds. A zero value is non-blocking. A negative value + is blocking. Constants have been defined for these values, bulkio::Const::BLOCKING and + bulkio::Const::NON_BLOCKING. + + More advanced uses of input streams are possible; refer to the REDHAWK documentation + for more details. + + Input streams return data blocks that automatically manage the memory for the data + and include the SRI that was in effect at the time the data was received. It is not + necessary to delete the block; it will be cleaned up when it goes out of scope. + + To send data using a BulkIO interface, create an output stream and write the + data to it. When done with the output stream, the close() method sends and end-of- + stream flag and cleans up. + + NOTE: If you have a BULKIO dataSDDS or dataVITA49 port, you must manually call + "port->updateStats()" to update the port statistics when appropriate. + + Example: + // This example assumes that the component has two ports: + // An input (provides) port of type bulkio::InShortPort called dataShort_in + // An output (uses) port of type bulkio::OutFloatPort called dataFloat_out + // The mapping between the port and the class is found + // in the component base class header file + + bulkio::InShortStream inputStream = dataShort_in->getCurrentStream(); + if (!inputStream) { // No streams are available + return NOOP; + } + + // Get the output stream, creating it if it doesn't exist yet + bulkio::OutFloatStream outputStream = dataFloat_out->getStream(inputStream.streamID()); + if (!outputStream) { + outputStream = dataFloat_out->createStream(inputStream.sri()); + } + + bulkio::ShortDataBlock block = inputStream.read(); + if (!block) { // No data available + // Propagate end-of-stream + if (inputStream.eos()) { + outputStream.close(); + } + return NOOP; + } + + if (block.sriChanged()) { + // Update output SRI + outputStream.sri(block.sri()); + } + + // Get read-only access to the input data + redhawk::shared_buffer inputData = block.buffer(); + + // Acquire a new buffer to hold the output data + redhawk::buffer outputData(inputData.size()); + + // Transform input data into output data + for (size_t index = 0; index < inputData.size(); ++index) { + outputData[index] = (float) inputData[index]; + } + + // Write to the output stream; outputData must not be modified after + // this method call + outputStream.write(outputData, block.getStartTime()); + + return NORMAL; + + If working with complex data (i.e., the "mode" on the SRI is set to + true), the data block's complex() method will return true. Data blocks + provide a cxbuffer() method that returns a complex interpretation of the + buffer without making a copy: + + if (block.complex()) { + redhawk::shared_buffer > inData = block.cxbuffer(); + redhawk::buffer > outData(inData.size()); + for (size_t index = 0; index < inData.size(); ++index) { + outData[index] = inData[index]; + } + outputStream.write(outData, block.getStartTime()); + } + + Interactions with non-BULKIO ports are left up to the component developer's discretion + + Messages: + + To receive a message, you need (1) an input port of type MessageEvent, (2) a message prototype described + as a structure property of kind message, (3) a callback to service the message, and (4) to register the callback + with the input port. + + Assuming a property of type message is declared called "my_msg", an input port called "msg_input" is declared of + type MessageEvent, create the following code: + + void check_cwd_cpp_so_i::my_message_callback(const std::string& id, const my_msg_struct &msg){ + } + + Register the message callback onto the input port with the following form: + this->msg_input->registerMessage("my_msg", this, &check_cwd_cpp_so_i::my_message_callback); + + To send a message, you need to (1) create a message structure, (2) a message prototype described + as a structure property of kind message, and (3) send the message over the port. + + Assuming a property of type message is declared called "my_msg", an output port called "msg_output" is declared of + type MessageEvent, create the following code: + + ::my_msg_struct msg_out; + this->msg_output->sendMessage(msg_out); + + Accessing the Application and Domain Manager: + + Both the Application hosting this Component and the Domain Manager hosting + the Application are available to the Component. + + To access the Domain Manager: + CF::DomainManager_ptr dommgr = this->getDomainManager()->getRef(); + To access the Application: + CF::Application_ptr app = this->getApplication()->getRef(); + + Properties: + + Properties are accessed directly as member variables. For example, if the + property name is "baudRate", it may be accessed within member functions as + "baudRate". Unnamed properties are given the property id as its name. + Property types are mapped to the nearest C++ type, (e.g. "string" becomes + "std::string"). All generated properties are declared in the base class + (check_cwd_cpp_so_base). + + Simple sequence properties are mapped to "std::vector" of the simple type. + Struct properties, if used, are mapped to C++ structs defined in the + generated file "struct_props.h". Field names are taken from the name in + the properties file; if no name is given, a generated name of the form + "field_n" is used, where "n" is the ordinal number of the field. + + Example: + // This example makes use of the following Properties: + // - A float value called scaleValue + // - A boolean called scaleInput + + if (scaleInput) { + dataOut[i] = dataIn[i] * scaleValue; + } else { + dataOut[i] = dataIn[i]; + } + + Callback methods can be associated with a property so that the methods are + called each time the property value changes. This is done by calling + addPropertyListener(, this, &check_cwd_cpp_so_i::) + in the constructor. + + The callback method receives two arguments, the old and new values, and + should return nothing (void). The arguments can be passed by value, + receiving a copy (preferred for primitive types), or by const reference + (preferred for strings, structs and vectors). + + Example: + // This example makes use of the following Properties: + // - A float value called scaleValue + // - A struct property called status + + //Add to check_cwd_cpp_so.cpp + check_cwd_cpp_so_i::check_cwd_cpp_so_i(const char *uuid, const char *label) : + check_cwd_cpp_so_base(uuid, label) + { + addPropertyListener(scaleValue, this, &check_cwd_cpp_so_i::scaleChanged); + addPropertyListener(status, this, &check_cwd_cpp_so_i::statusChanged); + } + + void check_cwd_cpp_so_i::scaleChanged(float oldValue, float newValue) + { + LOG_DEBUG(check_cwd_cpp_so_i, "scaleValue changed from" << oldValue << " to " << newValue); + } + + void check_cwd_cpp_so_i::statusChanged(const status_struct& oldValue, const status_struct& newValue) + { + LOG_DEBUG(check_cwd_cpp_so_i, "status changed"); + } + + //Add to check_cwd_cpp_so.h + void scaleChanged(float oldValue, float newValue); + void statusChanged(const status_struct& oldValue, const status_struct& newValue); + + +************************************************************************************************/ +int check_cwd_cpp_so_i::serviceFunction() +{ + LOG_DEBUG(check_cwd_cpp_so_i, "serviceFunction() example log message"); + + return NOOP; +} + diff --git a/GPP/tests/sdr/dom/components/check_cwd_cpp_so/cpp/check_cwd_cpp_so.h b/GPP/tests/sdr/dom/components/check_cwd_cpp_so/cpp/check_cwd_cpp_so.h new file mode 100644 index 000000000..09096e99a --- /dev/null +++ b/GPP/tests/sdr/dom/components/check_cwd_cpp_so/cpp/check_cwd_cpp_so.h @@ -0,0 +1,18 @@ +#ifndef CHECK_CWD_CPP_SO_I_IMPL_H +#define CHECK_CWD_CPP_SO_I_IMPL_H + +#include "check_cwd_cpp_so_base.h" + +class check_cwd_cpp_so_i : public check_cwd_cpp_so_base +{ + ENABLE_LOGGING + public: + check_cwd_cpp_so_i(const char *uuid, const char *label); + ~check_cwd_cpp_so_i(); + + void constructor(); + + int serviceFunction(); +}; + +#endif // CHECK_CWD_CPP_SO_I_IMPL_H diff --git a/GPP/tests/sdr/dom/components/check_cwd_cpp_so/cpp/check_cwd_cpp_so_base.cpp b/GPP/tests/sdr/dom/components/check_cwd_cpp_so/cpp/check_cwd_cpp_so_base.cpp new file mode 100644 index 000000000..c7d29131e --- /dev/null +++ b/GPP/tests/sdr/dom/components/check_cwd_cpp_so/cpp/check_cwd_cpp_so_base.cpp @@ -0,0 +1,68 @@ +#include "check_cwd_cpp_so_base.h" + +/******************************************************************************************* + + AUTO-GENERATED CODE. DO NOT MODIFY + + The following class functions are for the base class for the component class. To + customize any of these functions, do not modify them here. Instead, overload them + on the child class + +******************************************************************************************/ + +check_cwd_cpp_so_base::check_cwd_cpp_so_base(const char *uuid, const char *label) : + Component(uuid, label), + ThreadedComponent() +{ + setThreadName(label); + + loadProperties(); +} + +check_cwd_cpp_so_base::~check_cwd_cpp_so_base() +{ +} + +/******************************************************************************************* + Framework-level functions + These functions are generally called by the framework to perform housekeeping. +*******************************************************************************************/ +void check_cwd_cpp_so_base::start() throw (CORBA::SystemException, CF::Resource::StartError) +{ + Component::start(); + ThreadedComponent::startThread(); +} + +void check_cwd_cpp_so_base::stop() throw (CORBA::SystemException, CF::Resource::StopError) +{ + Component::stop(); + if (!ThreadedComponent::stopThread()) { + throw CF::Resource::StopError(CF::CF_NOTSET, "Processing thread did not die"); + } +} + +void check_cwd_cpp_so_base::releaseObject() throw (CORBA::SystemException, CF::LifeCycle::ReleaseError) +{ + // This function clears the component running condition so main shuts down everything + try { + stop(); + } catch (CF::Resource::StopError& ex) { + // TODO - this should probably be logged instead of ignored + } + + Component::releaseObject(); +} + +void check_cwd_cpp_so_base::loadProperties() +{ + addProperty(cwd, + "cwd", + "", + "readonly", + "", + "external", + "property"); + +} + + diff --git a/GPP/tests/sdr/dom/components/check_cwd_cpp_so/cpp/check_cwd_cpp_so_base.h b/GPP/tests/sdr/dom/components/check_cwd_cpp_so/cpp/check_cwd_cpp_so_base.h new file mode 100644 index 000000000..82523f2e8 --- /dev/null +++ b/GPP/tests/sdr/dom/components/check_cwd_cpp_so/cpp/check_cwd_cpp_so_base.h @@ -0,0 +1,30 @@ +#ifndef CHECK_CWD_CPP_SO_BASE_IMPL_BASE_H +#define CHECK_CWD_CPP_SO_BASE_IMPL_BASE_H + +#include +#include +#include + + +class check_cwd_cpp_so_base : public Component, protected ThreadedComponent +{ + public: + check_cwd_cpp_so_base(const char *uuid, const char *label); + ~check_cwd_cpp_so_base(); + + void start() throw (CF::Resource::StartError, CORBA::SystemException); + + void stop() throw (CF::Resource::StopError, CORBA::SystemException); + + void releaseObject() throw (CF::LifeCycle::ReleaseError, CORBA::SystemException); + + void loadProperties(); + + protected: + // Member variables exposed as properties + /// Property: cwd + std::string cwd; + + private: +}; +#endif // CHECK_CWD_CPP_SO_BASE_IMPL_BASE_H diff --git a/GPP/tests/sdr/dom/components/check_cwd_cpp_so/cpp/configure.ac b/GPP/tests/sdr/dom/components/check_cwd_cpp_so/cpp/configure.ac new file mode 100644 index 000000000..26ff2f8c8 --- /dev/null +++ b/GPP/tests/sdr/dom/components/check_cwd_cpp_so/cpp/configure.ac @@ -0,0 +1,26 @@ +AC_INIT(check_cwd_cpp_so, 1.0.0) +AM_INIT_AUTOMAKE([nostdinc foreign]) +AC_CONFIG_MACRO_DIR([m4]) +LT_INIT([dlopen]) + +AC_PROG_CC +AC_PROG_CXX +AC_PROG_INSTALL + +AC_CORBA_ORB +OSSIE_CHECK_OSSIE +OSSIE_SDRROOT_AS_PREFIX + +m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) + +# Dependencies +PKG_CHECK_MODULES([PROJECTDEPS], [ossie >= 2.1 omniORB4 >= 4.1.0]) +OSSIE_ENABLE_LOG4CXX +AX_BOOST_BASE([1.41]) +AX_BOOST_SYSTEM +AX_BOOST_THREAD +AX_BOOST_REGEX + +AC_CONFIG_FILES([Makefile]) +AC_OUTPUT + diff --git a/GPP/tests/sdr/dom/components/check_cwd_cpp_so/cpp/main.cpp b/GPP/tests/sdr/dom/components/check_cwd_cpp_so/cpp/main.cpp new file mode 100644 index 000000000..40fe9261a --- /dev/null +++ b/GPP/tests/sdr/dom/components/check_cwd_cpp_so/cpp/main.cpp @@ -0,0 +1,11 @@ +#include +#include "ossie/ossieSupport.h" + +#include "check_cwd_cpp_so.h" +extern "C" { + Resource_impl* make_component(const std::string& uuid, const std::string& identifier) + { + return new check_cwd_cpp_so_i(uuid.c_str(), identifier.c_str()); + } +} + diff --git a/GPP/tests/sdr/dom/components/check_cwd_cpp_so/cpp/reconf b/GPP/tests/sdr/dom/components/check_cwd_cpp_so/cpp/reconf new file mode 100755 index 000000000..8ff01d431 --- /dev/null +++ b/GPP/tests/sdr/dom/components/check_cwd_cpp_so/cpp/reconf @@ -0,0 +1,6 @@ +#!/bin/sh + +rm -f config.cache +[ -d m4 ] || mkdir m4 +autoreconf -i + diff --git a/GPP/tests/sdr/dom/waveforms/check_cwd_cpp_so_w/check_cwd_cpp_so_w.sad.xml b/GPP/tests/sdr/dom/waveforms/check_cwd_cpp_so_w/check_cwd_cpp_so_w.sad.xml new file mode 100644 index 000000000..a28d90169 --- /dev/null +++ b/GPP/tests/sdr/dom/waveforms/check_cwd_cpp_so_w/check_cwd_cpp_so_w.sad.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + check_cwd_cpp_so_1 + + + + + + + + + + diff --git a/GPP/tests/test_GPP.py b/GPP/tests/test_GPP.py index 71af823c1..268e89a1e 100755 --- a/GPP/tests/test_GPP.py +++ b/GPP/tests/test_GPP.py @@ -1884,8 +1884,8 @@ def test_PyCompConfigCacheCWD(self): if 'cache/components/check_cwd/python' in root: found_dir = True break - self.assertEquals(found_dir, True) - + self.assertTrue(found_dir) + def test_CppCompConfigCacheCWD(self): self.assertNotEqual(self._domMgr, None) nodebooter, devMgr = self.launchDeviceManager("/nodes/test_VarCache_node/DeviceManager.dcd.xml", domainManager=self.dom.ref) @@ -1899,8 +1899,23 @@ def test_CppCompConfigCacheCWD(self): if 'cache/components/check_cwd_cpp/cpp' in root: found_dir = True break - self.assertEquals(found_dir, True) - + self.assertTrue(found_dir) + + def test_CppSoCompConfigCacheCWD(self): + self.assertNotEqual(self._domMgr, None) + nodebooter, devMgr = self.launchDeviceManager("/nodes/test_VarCache_node/DeviceManager.dcd.xml", domainManager=self.dom.ref) + self.assertNotEqual(devMgr, None) + app = self._rhDom.createApplication('/waveforms/check_cwd_cpp_so_w/check_cwd_cpp_so_w.sad.xml') + self.assertNotEqual(app, None) + self.assertEquals(app.comps[0].cwd, self.cwd_dir) + found_dir = False + for root, dirs, files in os.walk(self.base_dir): + if 'check_cwd_cpp_so.so' in files: + if 'cache/components/check_cwd_cpp_so/cpp' in root: + found_dir = True + break + self.assertTrue(found_dir) + def test_JavaCompConfigCacheCWD(self): self.assertNotEqual(self._domMgr, None) nodebooter, devMgr = self.launchDeviceManager("/nodes/test_VarCache_node/DeviceManager.dcd.xml", domainManager=self.dom.ref) @@ -1914,7 +1929,7 @@ def test_JavaCompConfigCacheCWD(self): if 'cache/components/check_cwd_java/java/bin/check_cwd_java/java' in root: found_dir = True break - self.assertEquals(found_dir, True) + self.assertTrue(found_dir) class LoadableDeviceVariableCacheDirTest(DomainSupport): def setUp(self): From e6c67e0052ebb226d7021c0a117ad0107d91bed8 Mon Sep 17 00:00:00 2001 From: Ryan Bauman Date: Wed, 5 Jul 2017 11:49:42 -0400 Subject: [PATCH 0842/1644] RELENG-659 - add enterprise-integration yum group [ci skip] --- redhawk/src/releng/yumgroups.xml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/redhawk/src/releng/yumgroups.xml b/redhawk/src/releng/yumgroups.xml index 1e2da7bb4..22a72eebc 100644 --- a/redhawk/src/releng/yumgroups.xml +++ b/redhawk/src/releng/yumgroups.xml @@ -67,4 +67,16 @@ with this program. If not, see http://www.gnu.org/licenses/. omniEvents-bootscripts + + redhawk-enterprise-integration + REDHAWK Enterprise Integration + true + REDHAWK Enterprise Integration + true + + redhawk-enterprise-integration-demo-dist + redhawk-enterprise-integration-dist + redhawk-enterprise-integration-docs + + From 80c1840790ed50be72a6d09b1b2936fce113c78e Mon Sep 17 00:00:00 2001 From: Max Robert Date: Thu, 6 Jul 2017 13:49:14 -0400 Subject: [PATCH 0843/1644] Remove stream from the parent pending list if eos is read or if the read function is invoked when the data length is 0 --- bulkioInterfaces/libsrc/python/input_stream.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bulkioInterfaces/libsrc/python/input_stream.py b/bulkioInterfaces/libsrc/python/input_stream.py index 9853b00bc..e42ca95da 100644 --- a/bulkioInterfaces/libsrc/python/input_stream.py +++ b/bulkioInterfaces/libsrc/python/input_stream.py @@ -484,4 +484,6 @@ def eos(self): ''' Has EOS been received? ''' + if len(self._data) == 0 and self._eos: + self._parent._removeStream(self) return self._eos From cd9031b13ff8ab59642b8ef5688196c78d255863 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Thu, 6 Jul 2017 13:55:30 -0400 Subject: [PATCH 0844/1644] Refs CF-423. Cleaned up deprecation message --- redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py b/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py index e31ff87e5..d234eddb3 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py +++ b/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py @@ -1841,7 +1841,7 @@ def getData(self, length=None, eos_block=False, tstamps=False): element is the data set and the second element is a series of tuples containing the element index number and the timestamp for that index ''' - _warnings.warn("This function is deprecated. Use getCurrentStream instead", DeprecationWarning) + _warnings.warn("The function getData is deprecated. Use getCurrentStream instead", DeprecationWarning) isChar = self._sink.port_type == _BULKIO__POA.dataChar From a79b69704939eb12ee69b05983fb0e73c6ed6499 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Thu, 6 Jul 2017 15:39:43 -0400 Subject: [PATCH 0845/1644] Refs CF-423. Correctly update remaining data counter for legacy API in DataSink --- .../framework/python/ossie/utils/bulkio/bulkio_data_helpers.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/redhawk/src/base/framework/python/ossie/utils/bulkio/bulkio_data_helpers.py b/redhawk/src/base/framework/python/ossie/utils/bulkio/bulkio_data_helpers.py index 0421391aa..04a53202d 100644 --- a/redhawk/src/base/framework/python/ossie/utils/bulkio/bulkio_data_helpers.py +++ b/redhawk/src/base/framework/python/ossie/utils/bulkio/bulkio_data_helpers.py @@ -376,6 +376,8 @@ def retrieveData(self, length=None): samples_read += len(_block.data()) if samples_read >= goal: break + if len(self.data) >= len(retval): + self.data[:len(retval)] = [] return (retval, rettime) def getPort(self): From 6b4250a63ce92f46575938ccec8e8e05d01d9ebd Mon Sep 17 00:00:00 2001 From: 8530 <8530@vm-131.vsi-corp.com> Date: Tue, 11 Jul 2017 14:54:30 -0400 Subject: [PATCH 0846/1644] change default tuner type fo RX_DIGIIZER, CF-1804 --- frontendInterfaces/libsrc/python/tuner_device.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontendInterfaces/libsrc/python/tuner_device.py b/frontendInterfaces/libsrc/python/tuner_device.py index c147dd9c5..b51f3194c 100644 --- a/frontendInterfaces/libsrc/python/tuner_device.py +++ b/frontendInterfaces/libsrc/python/tuner_device.py @@ -291,7 +291,7 @@ def validateRequestVsDevice(request, rfinfo, mode, min_device_center_freq, max_d return True -def createTunerAllocation(tuner_type='DDC',allocation_id=None,center_frequency=0.0,bandwidth=0.0,sample_rate=1.0, +def createTunerAllocation(tuner_type='RX_DIGITIZER',allocation_id=None,center_frequency=0.0,bandwidth=0.0,sample_rate=1.0, device_control=True,group_id='',rf_flow_id='',bandwidth_tolerance=0.0,sample_rate_tolerance=0.0,returnDict=True): if returnDict: retval = {'FRONTEND::tuner_allocation':{'FRONTEND::tuner_allocation::tuner_type':tuner_type,'FRONTEND::tuner_allocation::allocation_id':allocation_id, @@ -324,7 +324,7 @@ def createTunerAllocation(tuner_type='DDC',allocation_id=None,center_frequency=0 retval = CF.DataType(id='FRONTEND::tuner_allocation',value=CORBA.Any(CF._tc_Properties,alloc)) return retval -def createTunerGenericListenerAllocation(tuner_type='DDC',allocation_id=None,center_frequency=0.0,bandwidth=0.0,sample_rate=1.0, +def createTunerGenericListenerAllocation(tuner_type='RX_DIGITIZER',allocation_id=None,center_frequency=0.0,bandwidth=0.0,sample_rate=1.0, device_control=False,group_id='',rf_flow_id='',bandwidth_tolerance=0.0,sample_rate_tolerance=0.0,returnDict=True): if returnDict: retval = {'FRONTEND::tuner_allocation':{'FRONTEND::tuner_allocation::tuner_type':tuner_type,'FRONTEND::tuner_allocation::allocation_id':allocation_id, From 687405783102d7814d01d88e864dbb51b23d5ca3 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Tue, 11 Jul 2017 16:33:11 -0400 Subject: [PATCH 0847/1644] Refs CF-1790. Removed warning message from nodeBooter about commandline properties --- redhawk/src/control/framework/nodebooter.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/redhawk/src/control/framework/nodebooter.cpp b/redhawk/src/control/framework/nodebooter.cpp index a94bca3d8..20e952958 100644 --- a/redhawk/src/control/framework/nodebooter.cpp +++ b/redhawk/src/control/framework/nodebooter.cpp @@ -154,7 +154,7 @@ void loadPRFExecParams (const std::string& prfFile, ExecParams& execParams) const ossie::SimpleProperty* simpleProp; simpleProp = dynamic_cast(*prop); if (!simpleProp) { - LOG_WARN(nodebooter, "Only execp arams of type \"simple\" supported"); + LOG_WARN(nodebooter, "Only exec params of type \"simple\" supported"); continue; } else if (!simpleProp->getValue()) { continue; @@ -168,7 +168,7 @@ void loadPRFExecParams (const std::string& prfFile, ExecParams& execParams) const ossie::SimpleProperty* simpleProp; simpleProp = dynamic_cast(*prop); if (!simpleProp) { - LOG_WARN(nodebooter, "Only execparams of type \"simple\" supported"); + // property properties that are not simples cannot be commandline, so no warning is needed continue; } else if (!simpleProp->getValue()) { continue; From 12e3e9748d71012203edcc5d67a11f7a82e8b9f7 Mon Sep 17 00:00:00 2001 From: 8530 <8530@vm-131.vsi-corp.com> Date: Wed, 12 Jul 2017 14:46:20 -0400 Subject: [PATCH 0848/1644] added qualified property names for hw_load_request and hw_load_status structure, CF-1537 --- .../tests/test_ProgrammableDevice.py | 202 ++++++++++++++++++ .../templates/programmable_base.h | 61 +++++- 2 files changed, 254 insertions(+), 9 deletions(-) create mode 100644 codegenTesting/sdr/dev/devices/ProgrammableDevice/tests/test_ProgrammableDevice.py diff --git a/codegenTesting/sdr/dev/devices/ProgrammableDevice/tests/test_ProgrammableDevice.py b/codegenTesting/sdr/dev/devices/ProgrammableDevice/tests/test_ProgrammableDevice.py new file mode 100644 index 000000000..84072e68e --- /dev/null +++ b/codegenTesting/sdr/dev/devices/ProgrammableDevice/tests/test_ProgrammableDevice.py @@ -0,0 +1,202 @@ +#!/usr/bin/env python + +import ossie.utils.testing +from ossie.utils import sb +import frontend +from omniORB import CORBA, any +from ossie.cf import CF +from ossie.properties import * +from ossie.utils import uuid + +class HwLoadRequest(object): + request_id = simple_property( + id_="hw_load_request::request_id", + name="request_id", + type_="string") + + requester_id = simple_property( + id_="hw_load_request::requester_id", + name="requester_id", + type_="string") + + hardware_id = simple_property( + id_="hw_load_request::hardware_id", + name="hardware_id", + type_="string") + + load_filepath = simple_property( + id_="hw_load_request::load_filepath", + name="load_filepath", + type_="string") + + def __init__(self, **kw): + """Construct an initialized instance of this struct definition""" + for classattr in type(self).__dict__.itervalues(): + if isinstance(classattr, (simple_property, simpleseq_property)): + classattr.initialize(self) + for k,v in kw.items(): + setattr(self,k,v) + + def __str__(self): + """Return a string representation of this structure""" + d = {} + d["request_id"] = self.request_id + d["requester_id"] = self.requester_id + d["hardware_id"] = self.hardware_id + d["load_filepath"] = self.load_filepath + return str(d) + + @classmethod + def getId(cls): + return "hw_load_request" + + @classmethod + def isStruct(cls): + return True + + def getMembers(self): + return [("request_id",self.request_id),("requester_id",self.requester_id),("hardware_id",self.hardware_id),("load_filepath",self.load_filepath)] + +hw_load_request = struct_property(id_="hw_load_request", + name="hw_load_request", + structdef=HwLoadRequest, + configurationkind=("property",), + mode="readwrite") + + +class HwLoadStatus(object): + request_id = simple_property( + id_="hw_load_status::request_id", + name="request_id", + type_="string") + + requester_id = simple_property( + id_="hw_load_status::requester_id", + name="requester_id", + type_="string") + + hardware_id = simple_property( + id_="hw_load_status::hardware_id", + name="hardware_id", + type_="string") + + load_filepath = simple_property( + id_="hw_load_status::load_filepath", + name="load_filepath", + type_="string") + + state = simple_property( + id_="hw_load_status::state", + name="state", + type_="short") + + def __init__(self, **kw): + """Construct an initialized instance of this struct definition""" + for classattr in type(self).__dict__.itervalues(): + if isinstance(classattr, (simple_property, simpleseq_property)): + classattr.initialize(self) + for k,v in kw.items(): + setattr(self,k,v) + + def __str__(self): + """Return a string representation of this structure""" + d = {} + d["request_id"] = self.request_id + d["requester_id"] = self.requester_id + d["hardware_id"] = self.hardware_id + d["load_filepath"] = self.load_filepath + d["state"] = self.state + return str(d) + + @classmethod + def getId(cls): + return "hw_load_status" + + @classmethod + def isStruct(cls): + return True + + def getMembers(self): + return [("request_id",self.request_id),("requester_id",self.requester_id),("hardware_id",self.hardware_id),("load_filepath",self.load_filepath),("state",self.state)] + + +hw_load_status = struct_property(id_="hw_load_status", + name="hw_load_status", + structdef=HwLoadStatus, + configurationkind=("property",), + mode="readwrite") + +hw_load_requests = structseq_property(id_="hw_load_requests", + name="hw_load_requests", + structdef=HwLoadRequest, + defvalue=[], + configurationkind=("property",), + mode="readwrite") + + + +class DeviceTests(ossie.utils.testing.RHTestCase): + # Path to the SPD file, relative to this file. This must be set in order to + # launch the device. + SPD_FILE = '../ProgrammableDevice.spd.xml' + + # setUp is run before every function preceded by "test" is executed + # tearDown is run after every function preceded by "test" is executed + + # self.comp is a device using the sandbox API + # to create a data source, the package sb contains data sources like DataSource or FileSource + # to create a data sink, there are sinks like DataSink and FileSink + # to connect the component to get data from a file, process it, and write the output to a file, use the following syntax: + # src = sb.FileSource('myfile.dat') + # snk = sb.DataSink() + # src.connect(self.comp) + # self.comp.connect(snk) + # sb.start() + # + # components/sources/sinks need to be started. Individual components or elements can be started + # src.start() + # self.comp.start() + # + # every component/elements in the sandbox can be started + # sb.start() + + def setUp(self): + # Launch the device, using the selected implementation + self.comp = sb.launch(self.spd_file, impl=self.impl) + pass + + def tearDown(self): + # Clean up all sandbox artifacts created during test + sb.release() + + def test_hw_load_request(self): + ####################################################################### + # Make sure start and stop can be called without throwing exceptions + + my_request = HwLoadRequest() + my_request.request_id = str(uuid.uuid1()) + my_request.requestor_id = "PG_TESTER" + my_request.hardware_id = "PG_TESTER:1" + my_request.load_filepath = "/the/path/file/to/load.bin" + + my_request_any = CORBA.Any(CORBA.TypeCode("IDL:CF/Properties:1.0"), struct_to_props(my_request)) + + my_requests = CF.DataType(id='hw_load_requests', + value=CORBA.Any(CORBA.TypeCode("IDL:omg.org/CORBA/AnySeq:1.0"), + [ my_request_any ] )) + + + hw_load_requests = structseq_property(id_="hw_load_requests", + name="hw_load_requests", + structdef=HwLoadRequest, + defvalue=[], + configurationkind=("property",), + mode="readwrite") + + self.comp.start() + # allocation should fail since there are no hardware resources to program + ret= self.comp.allocateCapacity([my_requests]) + self.assertEquals( ret, False ) + +if __name__ == "__main__": + ossie.utils.testing.main() # By default tests all implementations diff --git a/redhawk-codegen/redhawk/codegen/jinja/cpp/component/programmable/templates/programmable_base.h b/redhawk-codegen/redhawk/codegen/jinja/cpp/component/programmable/templates/programmable_base.h index 0d4dbca1b..34e3cf891 100644 --- a/redhawk-codegen/redhawk/codegen/jinja/cpp/component/programmable/templates/programmable_base.h +++ b/redhawk-codegen/redhawk/codegen/jinja/cpp/component/programmable/templates/programmable_base.h @@ -61,7 +61,7 @@ namespace HW_LOAD { }; static std::string getId() { - return std::string("hw_load_request"); + return std::string("hw_load_status"); }; std::string request_id; @@ -84,16 +84,16 @@ inline bool operator>>= (const CORBA::Any& a, HW_LOAD::default_hw_load_request_s if (!(a >>= temp)) return false; CF::Properties& props = *temp; for (unsigned int idx = 0; idx < props.length(); idx++) { - if (!strcmp("request_id", props[idx].id)) { + if (!strcmp("hw_load_request::request_id", props[idx].id)) { if (!(props[idx].value >>= s.request_id)) return false; } - if (!strcmp("requester_id", props[idx].id)) { + if (!strcmp("hw_load_request::requester_id", props[idx].id)) { if (!(props[idx].value >>= s.requester_id)) return false; } - if (!strcmp("hardware_id", props[idx].id)) { + if (!strcmp("hw_load_request::hardware_id", props[idx].id)) { if (!(props[idx].value >>= s.hardware_id)) return false; } - if (!strcmp("load_filepath", props[idx].id)) { + if (!strcmp("hw_load_request:load_filepath", props[idx].id)) { if (!(props[idx].value >>= s.load_filepath)) return false; } } @@ -103,17 +103,60 @@ inline bool operator>>= (const CORBA::Any& a, HW_LOAD::default_hw_load_request_s inline void operator<<= (CORBA::Any& a, const HW_LOAD::default_hw_load_request_struct& s) { CF::Properties props; props.length(4); - props[0].id = CORBA::string_dup("request_id"); + props[0].id = CORBA::string_dup("hw_load_request::request_id"); + props[0].value <<= s.request_id; + props[1].id = CORBA::string_dup("hw_load_request::requester_id"); + props[1].value <<= s.requester_id; + props[2].id = CORBA::string_dup("hw_load_request::hardware_id"); + props[2].value <<= s.hardware_id; + props[3].id = CORBA::string_dup("hw_load_request::load_filepath"); + props[3].value <<= s.load_filepath; + a <<= props; +}; + + + +inline bool operator>>= (const CORBA::Any& a, HW_LOAD::default_hw_load_status_struct& s) { + CF::Properties* temp; + if (!(a >>= temp)) return false; + CF::Properties& props = *temp; + for (unsigned int idx = 0; idx < props.length(); idx++) { + if (!strcmp("hw_load_status::request_id", props[idx].id)) { + if (!(props[idx].value >>= s.request_id)) return false; + } + if (!strcmp("hw_load_status::requester_id", props[idx].id)) { + if (!(props[idx].value >>= s.requester_id)) return false; + } + if (!strcmp("hw_load_status::hardware_id", props[idx].id)) { + if (!(props[idx].value >>= s.hardware_id)) return false; + } + if (!strcmp("hw_load_status:load_filepath", props[idx].id)) { + if (!(props[idx].value >>= s.load_filepath)) return false; + } + if (!strcmp("hw_load_status:state", props[idx].id)) { + if (!(props[idx].value >>= s.state)) return false; + } + } + return true; +}; + +inline void operator<<= (CORBA::Any& a, const HW_LOAD::default_hw_load_status_struct& s) { + CF::Properties props; + props.length(4); + props[0].id = CORBA::string_dup("hw_load_status::request_id"); props[0].value <<= s.request_id; - props[1].id = CORBA::string_dup("requester_id"); + props[1].id = CORBA::string_dup("hw_load_status::requester_id"); props[1].value <<= s.requester_id; - props[2].id = CORBA::string_dup("hardware_id"); + props[2].id = CORBA::string_dup("hw_load_status::hardware_id"); props[2].value <<= s.hardware_id; - props[3].id = CORBA::string_dup("load_filepath"); + props[3].id = CORBA::string_dup("hw_load_status::load_filepath"); props[3].value <<= s.load_filepath; + props[3].id = CORBA::string_dup("hw_load_status::state"); + props[3].value <<= s.state; a <<= props; }; + /*{% if component is device %}*/ typedef std::string ${executeType.capitalize()}Id; typedef std::map<${executeType.capitalize()}Id, ${executeClass}*> ${executeType.capitalize()}Map; From 3b1836008613df1ce31ea43128ecd68ffc30c333 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Fri, 14 Jul 2017 10:15:21 -0400 Subject: [PATCH 0849/1644] Refs CF-1763. Added test where the sink is stopped, and then the source is stopped --- .../testing/components/src/tests/test_src.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/bulkioInterfaces/libsrc/testing/components/src/tests/test_src.py b/bulkioInterfaces/libsrc/testing/components/src/tests/test_src.py index 8cb54079a..0e4d60f40 100755 --- a/bulkioInterfaces/libsrc/testing/components/src/tests/test_src.py +++ b/bulkioInterfaces/libsrc/testing/components/src/tests/test_src.py @@ -38,7 +38,7 @@ def tearDown(self): # Clean up all sandbox artifacts created during test sb.release() - def testBasicBehavior(self): + def testSrcSnkBehavior(self): ####################################################################### # Make sure start and stop can be called without throwing exceptions self.comp.connect(self.snk) @@ -53,5 +53,20 @@ def testBasicBehavior(self): self.comp.releaseObject() self.snk.releaseObject() + def testSnkSrcBehavior(self): + ####################################################################### + # Make sure start and stop can be called without throwing exceptions + self.comp.connect(self.snk) + self.comp.start() + self.snk.start() + time.sleep(1) + self.snk.stop() + try: + self.comp.stop() + except: + pass + self.comp.releaseObject() + self.snk.releaseObject() + if __name__ == "__main__": ossie.utils.testing.main() # By default tests all implementations From 746d077701c115e0283101db9f4cc90c52cf6412 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Mon, 24 Jul 2017 10:23:02 -0400 Subject: [PATCH 0850/1644] Refs CF-1751. Added application-level metrics for GPP utilization --- .../idl/redhawk/FRONTEND/TunerControl.idl | 11 +- .../python/ossie/utils/redhawk/core.py | 13 +- redhawk/src/configure.ac | 1 + .../control/sdr/dommgr/Application_impl.cpp | 238 ++ .../src/control/sdr/dommgr/Application_impl.h | 12 +- .../control/sdr/dommgr/FakeApplication.cpp | 6 + .../src/control/sdr/dommgr/FakeApplication.h | 2 + redhawk/src/idl/ossie/CF/cf.idl | 6 + redhawk/src/testing/Makefile.am | 3 +- .../testing/sdr/dev/devices/GPP/GPP.prf.xml | 320 ++- .../testing/sdr/dev/devices/GPP/cpp/GPP.cpp | 2327 +++++++++++++++-- .../src/testing/sdr/dev/devices/GPP/cpp/GPP.h | 464 ++-- .../sdr/dev/devices/GPP/cpp/GPP_base.cpp | 322 ++- .../sdr/dev/devices/GPP/cpp/GPP_base.h | 66 +- .../sdr/dev/devices/GPP/cpp/Makefile.am | 8 +- .../sdr/dev/devices/GPP/cpp/NicFacade.cpp | 19 + .../sdr/dev/devices/GPP/cpp/NicFacade.h | 1 + .../sdr/dev/devices/GPP/cpp/affinity_struct.h | 6 +- .../testing/sdr/dev/devices/GPP/cpp/main.cpp | 9 +- .../GPP/cpp/parsers/ProcMeminfoParser.cpp | 9 +- .../GPP/cpp/parsers/ProcStatParser.cpp | 1 - .../reports/FreeMemoryThresholdMonitor.cpp | 8 +- .../cpp/reports/FreeMemoryThresholdMonitor.h | 42 +- .../reports/NicThroughputThresholdMonitor.cpp | 2 +- .../reports/NicThroughputThresholdMonitor.h | 2 +- .../cpp/reports/SystemMonitorReporting.cpp | 118 +- .../GPP/cpp/reports/SystemMonitorReporting.h | 55 +- .../GPP/cpp/reports/ThresholdMonitor.h | 2 +- .../dev/devices/GPP/cpp/states/ProcMeminfo.h | 2 +- .../dev/devices/GPP/cpp/states/ProcStat.cpp | 23 + .../sdr/dev/devices/GPP/cpp/states/ProcStat.h | 1 + .../GPP/cpp/statistics/CpuUsageStats.cpp | 68 +- .../GPP/cpp/statistics/CpuUsageStats.h | 8 + .../sdr/dev/devices/GPP/cpp/struct_props.h | 509 +++- .../dev/devices/GPP/cpp/utils/affinity.cpp | 432 +-- .../sdr/dev/devices/GPP/cpp/utils/affinity.h | 2 + .../dom/components/busycomp/busycomp.prf.xml | 3 + .../dom/components/busycomp/busycomp.scd.xml | 45 + .../dom/components/busycomp/busycomp.spd.xml | 27 + .../dom/components/busycomp/cpp/Makefile.am | 58 + .../dom/components/busycomp/cpp/busycomp.cpp | 249 ++ .../dom/components/busycomp/cpp/busycomp.h | 18 + .../components/busycomp/cpp/busycomp_base.cpp | 60 + .../components/busycomp/cpp/busycomp_base.h | 27 + .../sdr/dom/components/busycomp/cpp/main.cpp | 11 + .../waveforms/busycomp_w/busycomp_w.sad.xml | 44 + .../tests/test_04_ApplicationMetrics.py | 192 ++ 47 files changed, 4920 insertions(+), 932 deletions(-) create mode 100644 redhawk/src/testing/sdr/dom/components/busycomp/busycomp.prf.xml create mode 100644 redhawk/src/testing/sdr/dom/components/busycomp/busycomp.scd.xml create mode 100644 redhawk/src/testing/sdr/dom/components/busycomp/busycomp.spd.xml create mode 100644 redhawk/src/testing/sdr/dom/components/busycomp/cpp/Makefile.am create mode 100644 redhawk/src/testing/sdr/dom/components/busycomp/cpp/busycomp.cpp create mode 100644 redhawk/src/testing/sdr/dom/components/busycomp/cpp/busycomp.h create mode 100644 redhawk/src/testing/sdr/dom/components/busycomp/cpp/busycomp_base.cpp create mode 100644 redhawk/src/testing/sdr/dom/components/busycomp/cpp/busycomp_base.h create mode 100644 redhawk/src/testing/sdr/dom/components/busycomp/cpp/main.cpp create mode 100644 redhawk/src/testing/sdr/dom/waveforms/busycomp_w/busycomp_w.sad.xml create mode 100644 redhawk/src/testing/tests/test_04_ApplicationMetrics.py diff --git a/frontendInterfaces/idl/redhawk/FRONTEND/TunerControl.idl b/frontendInterfaces/idl/redhawk/FRONTEND/TunerControl.idl index 181411afc..8b5fe4a05 100644 --- a/frontendInterfaces/idl/redhawk/FRONTEND/TunerControl.idl +++ b/frontendInterfaces/idl/redhawk/FRONTEND/TunerControl.idl @@ -29,7 +29,7 @@ module FRONTEND { /** Mandated Structures and Ports: ------------------------------ - Frontend mandates three property structures outside of normal REDHAWK properties of "device_kind" and "device_model" : + Frontend mandates four property structures outside of normal REDHAWK properties of "device_kind" and "device_model" : (1) FRONTEND::tuner_allocation - allocation structure to acquire capability on a tuner based off tuner settings. Name || ID || Type || Description - tuner_type || FRONTEND::tuner_allocation::tuner_type || string || Example Tuner Types: TX, RX, CHANNELIZER, DDC, RX_DIGITIZER, RX_DIGITIZER_CHANNELIZER, RX_SCANNER_DIGITIZER @@ -59,7 +59,7 @@ module FRONTEND { - listener_allocation_id || FRONTEND::listener_allocation::listener_allocation_id || string || New Listener ID (4) FRONTEND::tuner_status - a struct sequence containing the status of all tuners. There are optional and required fields for this structure. The required fields are listed below: Name || ID || Type || Description - - tuner_type || FRONTEND::tuner_status::tuner_type || string || Example Tuner Types: TX, RX, CHANNELIZER, DDC, RX_DIGITIZER, RX_DIGTIZIER_CHANNELIZER + - tuner_type || FRONTEND::tuner_status::tuner_type || string || Example Tuner Types: TX, RX, CHANNELIZER, DDC, RX_DIGITIZER, RX_DIGITIZER_CHANNELIZER, RX_SCANNER_DIGITIZER - allocation_id_csv || FRONTEND::tuner_status::allocation_id_csv || string || Comma seperated list of currrent allocation ids, both control and listeners. - center_frequency || FRONTEND::tuner_status::center_frequency || double || Current center frequency in Hz - bandwidth || FRONTEND::tuner_status::bandwidth || double || Current Bandwidth in Hz @@ -67,8 +67,8 @@ module FRONTEND { - group_id || FRONTEND::tuner_status::group_id || string || Unique identifier that specifies a group of device. - rf_flow_id || FRONTEND::tuner_status::rf_flow_id || string || Specifies a certain RF flow to allocate against. - enabled || FRONTEND::tuner_status::enabled || boolean || True is tuner is enabled. Can be allocated but disabled - - mode_enabled || FRONTEND::tuner_status::scan_mode_enabled || boolean || True is scan mode is enabled. False is Manual Tune is enabled - - supports_scan || FRONTEND::tuner_status::supports_scan || boolean || True if scan allocated + - scan_mode_enabled || FRONTEND::tuner_status::scan_mode_enabled || boolean || True is scan mode is enabled. False is Manual Tune is enabled + - supports_scan || FRONTEND::tuner_status::supports_scan || boolean || True if scan is supported Usual port additions include a input (provides) port for the tuner control as well as an output (uses) BULKIO data port that follows the naming convention [interface]_[in/out]. Examples include dataShort_out, dataSDDS_out, dataOctet_in, and DigitalTuner_in. @@ -84,7 +84,8 @@ module FRONTEND { - CHANNELIZER: Accepts digitized wideband and provides DDC's (allocation against a channelizer ensures that the input port is not shared) - DDC: Digital Down Converter. Channel that is extracted from a wider bandwidth (ie - Channelizer). Similar to a RX_DIGITIZER but often much cheaper. - RX_DIGITIZER_CHANNELIZER: RX_DIGITIZER and CHANNELIZER combo. The reason they are combined is because they are a single device that cannot operate - independetly (ie - RX_DIGITIZER can not output full-rate or the CHANNELIZER can not accept external input) + independetly (ie - RX_DIGITIZER can not output full-rate or the CHANNELIZER can not accept external input) + - RX_SCANNER_DIGITIZER diff --git a/redhawk/src/base/framework/python/ossie/utils/redhawk/core.py b/redhawk/src/base/framework/python/ossie/utils/redhawk/core.py index 81aa421be..9f04ba60c 100644 --- a/redhawk/src/base/framework/python/ossie/utils/redhawk/core.py +++ b/redhawk/src/base/framework/python/ossie/utils/redhawk/core.py @@ -220,7 +220,16 @@ def releaseObject(self): self._domain.removeApplication(self) except: raise - + + def metrics(self, components, attributes): + retval = None + if self.ref: + try: + retval = self.ref.metrics(components, attributes) + except: + raise + return retval + @property def aware(self): retval = False @@ -1895,7 +1904,7 @@ def query(self, props): except: raise return retval - + def registerDevice(self, device, deviceManager): if self.ref: try: diff --git a/redhawk/src/configure.ac b/redhawk/src/configure.ac index 6da67e1f0..5f5cad76c 100644 --- a/redhawk/src/configure.ac +++ b/redhawk/src/configure.ac @@ -386,6 +386,7 @@ AC_CONFIG_FILES(Makefile \ testing/sdr/dom/components/PropertyChange_J1/java/Makefile \ testing/sdr/dom/components/Property_CPP/cpp/Makefile \ testing/sdr/dom/components/msg_through_cpp/cpp/Makefile \ + testing/sdr/dom/components/busycomp/cpp/Makefile \ testing/sdr/dom/components/commandline_prop/cpp/Makefile \ testing/sdr/dom/components/timeprop_cpp/cpp/Makefile \ testing/sdr/dom/components/time_cp_now/cpp/Makefile \ diff --git a/redhawk/src/control/sdr/dommgr/Application_impl.cpp b/redhawk/src/control/sdr/dommgr/Application_impl.cpp index 295595a6e..12c6549d5 100644 --- a/redhawk/src/control/sdr/dommgr/Application_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/Application_impl.cpp @@ -1139,6 +1139,244 @@ CF::Components* Application_impl::registeredComponents () return result._retn(); } +bool Application_impl::haveAttribute(std::vector &atts, std::string att) +{ + if (std::find(atts.begin(), atts.end(), att) == atts.end()) { + return false; + } + return true; +} + +CF::Properties* Application_impl::metrics(const CF::StringSequence& components, const CF::StringSequence& attributes) +throw (CF::Application::InvalidMetric, CORBA::SystemException) +{ + CF::Properties_var result_ugly = new CF::Properties(); + // Make sure releaseObject hasn't already been called + { + boost::mutex::scoped_lock lock(releaseObjectLock); + + if (_releaseAlreadyCalled) { + LOG_DEBUG(Application_impl, "skipping metrics call because releaseObject has been called"); + return result_ugly._retn(); + } + } + + boost::mutex::scoped_lock lock(metricsLock); + measuredDevices.clear(); + std::vector valid_attributes; + valid_attributes.push_back("valid"); + valid_attributes.push_back("shared"); + valid_attributes.push_back("cores"); + valid_attributes.push_back("memory"); + valid_attributes.push_back("processes"); + valid_attributes.push_back("threads"); + valid_attributes.push_back("files"); + valid_attributes.push_back("componenthost"); + std::vector mod_attributes; + mod_attributes.resize(attributes.length()); + for (unsigned int _att=0; _att component_map; + std::vector component_list; + for (ComponentList::iterator _component_iter=this->_components.begin(); _component_iter!=this->_components.end(); _component_iter++) { + if (_component_iter->isVisible()) { + component_list.push_back(_component_iter->getName()); + component_map[_component_iter->getName()] = &(*_component_iter); + } + } + ossie::DeviceList _registeredDevices = _domainManager->getRegisteredDevices(); + redhawk::PropertyMap& result = redhawk::PropertyMap::cast(result_ugly); + redhawk::PropertyMap measuredComponents; + std::vector mod_requests; + if (components.length() == 0) { + mod_requests.insert(mod_requests.begin(), component_list.begin(), component_list.end()); + mod_requests.push_back("application utilization"); + } else { + mod_requests.resize(components.length()); + for (unsigned int _req=0; _req::iterator _comp=component_list.begin();_comp!=component_list.end();_comp++) { + measuredComponents[*_comp] = measureComponent(*component_map[*_comp]); + if (not measuredComponents[*_comp].asProperties()["valid"].toBoolean()) + valid = false; + } + redhawk::PropertyMap _util; + if (valid) { + if (haveAttribute(mod_attributes, "cores")) + _util["cores"] = (float)0; + if (haveAttribute(mod_attributes, "memory")) + _util["memory"] = (float)0; + if (haveAttribute(mod_attributes, "processes")) + _util["processes"] = (unsigned long)0; + if (haveAttribute(mod_attributes, "threads")) + _util["threads"] = (unsigned long)0; + if (haveAttribute(mod_attributes, "files")) + _util["files"] = (unsigned long)0; + if (haveAttribute(mod_attributes, "valid")) + _util["valid"] = true; + std::vector already_measured; + for (std::vector::iterator _comp=component_list.begin();_comp!=component_list.end();_comp++) { + redhawk::PropertyMap _mC = measuredComponents[*_comp].asProperties(); + if (haveAttribute(already_measured, _mC["componenthost"].toString())) + continue; + already_measured.push_back(_mC["componenthost"].toString()); + if (haveAttribute(mod_attributes, "cores")) + _util["cores"] = _util["cores"].toFloat() + _mC["cores"].toFloat(); + if (haveAttribute(mod_attributes, "memory")) + _util["memory"] = _util["memory"].toFloat() + _mC["memory"].toFloat(); + if (haveAttribute(mod_attributes, "processes")) + _util["processes"] = _util["processes"].toULong() + _mC["processes"].toULong(); + if (haveAttribute(mod_attributes, "threads")) + _util["threads"] = _util["threads"].toULong() + _mC["threads"].toULong(); + if (haveAttribute(mod_attributes, "files")) + _util["files"] = _util["files"].toULong() + _mC["files"].toULong(); + } + result[_request] = _util; + } else { + redhawk::PropertyMap _util; + if (haveAttribute(mod_attributes, "valid")) + _util["valid"] = false; + result[_request] = _util; + } + } + } + // find out if all components need to be queried + for (unsigned int _req=0; _req::iterator _comp=component_list.begin();_comp!=component_list.end();_comp++) { + if (_request == *_comp) { + redhawk::PropertyMap tmp = measureComponent(*component_map[*_comp]); + result[_request] = filterAttributes(tmp, mod_attributes); + found_component = true; + break; + } + } + if (not found_component) { + CF::StringSequence _components; + CF::StringSequence _attributes; + ossie::corba::push_back(_components, _request.c_str()); + throw CF::Application::InvalidMetric(_components, _attributes); + } + } + } + } + return result_ugly._retn(); +} + +redhawk::PropertyMap Application_impl::filterAttributes(redhawk::PropertyMap &attributes, std::vector &filter) +{ + redhawk::PropertyMap retval; + if (haveAttribute(filter, "cores")) + retval["cores"] = attributes["cores"]; + if (haveAttribute(filter, "memory")) + retval["memory"] = attributes["memory"]; + if (haveAttribute(filter, "valid")) + retval["valid"] = attributes["valid"]; + if (haveAttribute(filter, "shared")) + retval["shared"] = attributes["shared"]; + if (haveAttribute(filter, "processes")) + retval["processes"] = attributes["processes"]; + if (haveAttribute(filter, "threads")) + retval["threads"] = attributes["threads"]; + if (haveAttribute(filter, "files")) + retval["files"] = attributes["files"]; + if (haveAttribute(filter, "componenthost")) + retval["componenthost"] = attributes["componenthost"]; + return retval; +} + +redhawk::PropertyMap Application_impl::measureComponent(redhawk::ApplicationComponent &component) +{ + redhawk::PropertyMap retval; + retval["valid"] = false; + if (component.getComponentHost() != NULL) { + retval["shared"] = true; + } else { + retval["shared"] = false; + } + ossie::DeviceList _registeredDevices = _domainManager->getRegisteredDevices(); + for (ossie::DeviceList::iterator _dev=_registeredDevices.begin(); _dev!=_registeredDevices.end(); _dev++) { + if (component.getAssignedDevice()->identifier == (*_dev)->identifier) { + retval["valid"] = false; + redhawk::PropertyMap query; + if (measuredDevices.find(component.getAssignedDevice()->identifier) == measuredDevices.end()) { + query["component_monitor"] = NULL; + try { + (*_dev)->device->query(query); + } catch ( ... ) { + LOG_WARN(Application_impl, "Unable to query 'component_monitor' on "<identifier); + continue; + } + measuredDevices[component.getAssignedDevice()->identifier] = query; + } else { + query = measuredDevices[component.getAssignedDevice()->identifier]; + } + const redhawk::ValueSequence& values = query["component_monitor"].asSequence(); + std::string target_id = component.getIdentifier(); + if (retval["shared"].toBoolean()) + target_id = component.getComponentHost()->getIdentifier(); + if (values.size()!=0) { + for (unsigned int i=0; iidentifier); + continue; + } + if (single["component_monitor::component_monitor::waveform_id"].toString() != _identifier) { + continue; + } + if (not single.contains("component_monitor::component_monitor::component_id")) { + LOG_WARN(Application_impl, "Unable to query 'component_monitor' missing 'component_id' on "<identifier); + continue; + } + if (single["component_monitor::component_monitor::component_id"].toString() != target_id) { + continue; + } + if ((not single.contains("component_monitor::component_monitor::cores")) or + (not single.contains("component_monitor::component_monitor::mem_rss")) or + (not single.contains("component_monitor::component_monitor::num_processes")) or + (not single.contains("component_monitor::component_monitor::num_threads")) or + (not single.contains("component_monitor::component_monitor::num_files"))) { + LOG_WARN(Application_impl, "Unable to query 'component_monitor' missing 'cores', 'mem_rss', 'num_processes', 'num_threads', or 'num_files' on "<identifier); + continue; + } + retval["cores"] = single["component_monitor::component_monitor::cores"].toFloat(); + retval["memory"] = single["component_monitor::component_monitor::mem_rss"].toFloat(); + retval["processes"] = single["component_monitor::component_monitor::num_processes"].toULong(); + retval["threads"] = single["component_monitor::component_monitor::num_threads"].toULong(); + retval["files"] = single["component_monitor::component_monitor::num_files"].toULong(); + retval["componenthost"] = target_id; + retval["valid"] = true; + break; + } + } + } + } + return retval; +} + CF::ApplicationRegistrar_ptr Application_impl::appReg (void) { return _registrar->_this(); diff --git a/redhawk/src/control/sdr/dommgr/Application_impl.h b/redhawk/src/control/sdr/dommgr/Application_impl.h index 5ab515add..6db3281ee 100644 --- a/redhawk/src/control/sdr/dommgr/Application_impl.h +++ b/redhawk/src/control/sdr/dommgr/Application_impl.h @@ -88,6 +88,10 @@ class Application_impl : public virtual POA_CF::Application, public Logging_impl void query (CF::Properties& configProperties) throw (CF::UnknownProperties, CORBA::SystemException); + // The core framework provides an implementation for this method. + CF::Properties* metrics (const CF::StringSequence& components, const CF::StringSequence& attributes) + throw (CF::Application::InvalidMetric, CORBA::SystemException); + char *registerPropertyListener( CORBA::Object_ptr listener, const CF::StringSequence &prop_ids, const CORBA::Float interval) throw(CF::UnknownProperties, CF::InvalidObjectReference); @@ -162,7 +166,7 @@ class Application_impl : public virtual POA_CF::Application, public Logging_impl CF::Application_ptr getComponentApplication(); CF::DomainManager_ptr getComponentDomainManager(); - + redhawk::ApplicationComponent* getComponent(const std::string& identifier); private: @@ -180,6 +184,11 @@ class Application_impl : public virtual POA_CF::Application, public Logging_impl typedef std::vector< PropertyChangeRecord > PropertyChangeRecords; typedef std::map< std::string, PropertyChangeRecords > PropertyChangeRegistry; + std::map measuredDevices; + bool haveAttribute(std::vector &atts, std::string att); + redhawk::PropertyMap measureComponent(redhawk::ApplicationComponent &component); + redhawk::PropertyMap filterAttributes(redhawk::PropertyMap &attributes, std::vector &filter); + void registerComponent(CF::Resource_ptr resource); bool _checkRegistrations(std::set& identifiers); @@ -215,6 +224,7 @@ class Application_impl : public virtual POA_CF::Application, public Logging_impl bool _releaseAlreadyCalled; boost::mutex releaseObjectLock; + boost::mutex metricsLock; PropertyChangeRegistry _propertyChangeRegistrations; diff --git a/redhawk/src/control/sdr/dommgr/FakeApplication.cpp b/redhawk/src/control/sdr/dommgr/FakeApplication.cpp index 2027c1472..bb1e4a540 100644 --- a/redhawk/src/control/sdr/dommgr/FakeApplication.cpp +++ b/redhawk/src/control/sdr/dommgr/FakeApplication.cpp @@ -59,6 +59,12 @@ void FakeApplication::query (CF::Properties& configProperties) throw CF::UnknownProperties(); } +CF::Properties* FakeApplication::metrics(const CF::StringSequence& components, const CF::StringSequence& attributes) + throw (CF::Application::InvalidMetric, CORBA::SystemException) +{ + throw CF::Application::InvalidMetric(components, attributes); +} + char * FakeApplication::registerPropertyListener( CORBA::Object_ptr listener, const CF::StringSequence &prop_ids, const CORBA::Float interval) throw(CF::UnknownProperties, CF::InvalidObjectReference) { diff --git a/redhawk/src/control/sdr/dommgr/FakeApplication.h b/redhawk/src/control/sdr/dommgr/FakeApplication.h index 1a5b0f888..95279b2ee 100644 --- a/redhawk/src/control/sdr/dommgr/FakeApplication.h +++ b/redhawk/src/control/sdr/dommgr/FakeApplication.h @@ -43,6 +43,8 @@ class FakeApplication : public virtual POA_CF::Application, public Logging_impl void initializeProperties (const CF::Properties& configProperties){}; void configure (const CF::Properties& configProperties); void query (CF::Properties& configProperties); + CF::Properties* metrics (const CF::StringSequence& components, const CF::StringSequence& attributes) + throw (CF::Application::InvalidMetric, CORBA::SystemException); char *registerPropertyListener( CORBA::Object_ptr listener, const CF::StringSequence &prop_ids, const CORBA::Float interval) throw(CF::UnknownProperties, CF::InvalidObjectReference); void unregisterPropertyListener( const char *reg_id ) diff --git a/redhawk/src/idl/ossie/CF/cf.idl b/redhawk/src/idl/ossie/CF/cf.idl index c8e4076bb..44a8c180b 100644 --- a/redhawk/src/idl/ossie/CF/cf.idl +++ b/redhawk/src/idl/ossie/CF/cf.idl @@ -1040,6 +1040,12 @@ module CF { /*readonly attribute ApplicationRegistrar appReg;*/ /* This boolean attribute contains the aware state of Application. This attribute shows whether the Components in the Application are given a pointer to the Application and Domain Manager. */ readonly attribute boolean aware; + exception InvalidMetric { + CF::StringSequence components; + CF::StringSequence attributes; + }; + /* The metrics method returns the requested metrics for the Application. An empty sequence returns all metrics. */ + CF::Properties metrics(in CF::StringSequence components, in CF::StringSequence attributes) raises (CF::Application::InvalidMetric); }; /* This interface extends the Device interface by adding software loading and unloading behavior to a Device. */ interface LoadableDevice : Device { diff --git a/redhawk/src/testing/Makefile.am b/redhawk/src/testing/Makefile.am index 1081e2004..526e3f807 100644 --- a/redhawk/src/testing/Makefile.am +++ b/redhawk/src/testing/Makefile.am @@ -77,7 +77,8 @@ SUBDIRS = sdr/dom/deps/cpp_dep1/cpp \ sdr/dom/components/cpp_with_deps/cpp \ sdr/dom/components/timeprop_cpp/cpp \ sdr/dom/components/time_cp_now/cpp \ - sdr/dom/components/msg_through_cpp/cpp + sdr/dom/components/msg_through_cpp/cpp \ + sdr/dom/components/busycomp/cpp if HAVE_JAVASUPPORT SUBDIRS += sdr/dom/deps/java_dep1/java \ diff --git a/redhawk/src/testing/sdr/dev/devices/GPP/GPP.prf.xml b/redhawk/src/testing/sdr/dev/devices/GPP/GPP.prf.xml index 45b5ca2cd..27a6a2e53 100644 --- a/redhawk/src/testing/sdr/dev/devices/GPP/GPP.prf.xml +++ b/redhawk/src/testing/sdr/dev/devices/GPP/GPP.prf.xml @@ -29,36 +29,53 @@ with this program. If not, see http://www.gnu.org/licenses/. This specifies the specific device - + REDHAWK GPP + SCA required property describing the CPU type x86_64 - + SCA required property describing the Operating System Name Linux - + SCA required property describing the Operating System Version + Host name on which the device is deployed - + + + If true, GNU screen will be used for the execution of components. + False + + + + + + If provided, all component output will be redirected to this file. The GPP will not delete or rotate these logs. The provided value may contain environment variables or reference component exec-params with @EXEC_PARAM@. For example, this would be a valid value $SDRROOT/logs/@COMPONENT_IDENTIFIER@.log + + + + + + DCE:e4e86070-a121-45d4-a144-00386f2188e3 @@ -181,29 +198,73 @@ Optional - - If true, GNU screen will be used for the execution of components. - False + + + The Multicast NIC interface associated with this GPP (e.g. eth1). If not provided no multicast allocations are permitted. + - - The amount of load capacity remaining to be allocated. - + + Total NIC bandwidth for the interfaces defined in mcastnicInterface. This must be specified in the PRF or DCD because ethtool requires super-user privs. + 0 + Mb/s + + + + + Total NIC bandwidth for the interfaces defined in mcastnicInterface. This must be specified in the PRF or DCD because ethtool requires super-user privs. + 0 + Mb/s + - + Amount of ingress multicast NIC capacity in the GPP not allocated to an application Mb/s + - - Amount of RAM in the GPP not allocated to an application - MiB + + Amount of egress multicast NIC capacity in the GPP not allocated to an application + Mb/s + + + + + Free NIC bandwidth for the interfaces defined in mcastnicInterface. + 0 + Mb/s + + + + + + Free NIC bandwidth for the interfaces defined in mcastnicInterface. + 0 + Mb/s + + + + + + + Percentage of total Multicast NIC this GPP can use for capacity management + 80 + % + + + + + When queired, returns the list of vlans on this host. When used as an allocation, defines the list of VLANS the component requires. + + + + 80.0 @@ -216,6 +277,7 @@ Optional e.* + @@ -232,6 +294,7 @@ Optional + Identifier of component or device that generated this message @@ -266,64 +329,247 @@ THRESHOLD_NOT_EXCEEDED: The measured value no longer exceeds the configured thr + + + cycle time between updates of metric capture, calculations and threshold evaluations. + 500 + milliseconds + + + + + + Report reason why the GPP had it's usage state set to BUSY. + + + + + + + Select a cache directory other than the default. + + + + + + + Select a working directory other than the default. + + + + + - The thresholds that cause a failure for pawn allocations + The thresholds that cause a failure for allocations + + false + + + 10 % - + + + + 80 + % + - 100 + 10 MB - 900 MB/s - + + + + The percentage of file handles remaining to the GPP that triggers a threshold condition + 3 + % + + + + + The percentage of threads available to the GPP that triggers a threshold condition + 3 + % + - + + + Amount of RAM in the GPP not in use (measured) + MiB + + + + + + Amount of RAM in the GPP not allocated to an application + MiB + + + + + Equal to "processor_cores" x "loadCapacityPerCore". + + + + The performance ratio of this machine, relative to the benchmark machine. 1.0 - - - - + deprecated 80 % - - 0.25 + + Equal to loadCapacity + + + + + + The amount of load capacity remaining to be allocated. + + + + + + + The current load average, as reported by /proc/loadavg. Each core on a computer can have a load average between 0.0 and 1.0. This differs greatly from CPU percentage (as reported by top). Load averages differ in two significant ways: 1) they measure the trend of CPU utlization, and 2) they include all demand for the CPU not only how much was active at the time of measurement. Load averages do not include any processes or threads waiting on I/O, networking, databases, or anything else not demanding the CPU. + + + + + + + + + + + + + + + + + + 0.1 + + + + + + + + list of cpu ids that are being monitored for loadavg and idle utilization. + + + + + + + The current number of threads for the GPP + + + The maximum number of threads allowed for the GPP + + + The current number of open file handles for the GPP + + + The maximum number of open file handles allowed for the GPP + + + + + + + The current number of threads running on the system + + + The maximum number of threads allowed to run on the system + + + The current number of open file on the system. + + + The maximum number of open file handles allowed for the system + + + + + + + + + + + + + + + + + + + + + + % + + + MB + + + % + + + + + + + + + + + + + + + The context specification for the exec_directive_class. See numa library manpage for socket(numa node) and cpu list specifications. For cgroup/cpuset option then a pre-existing cgroup name is required. + 0 - The classification of the affinity policy to apply. + socket @@ -331,54 +577,34 @@ THRESHOLD_NOT_EXCEEDED: The measured value no longer exceeds the configured thr - determines if the specified affinity policy (exec_directive_value, exec_directive_class) is inherited by RH resources started from this GPP. false - list of cpu ids to black list when making affinity requests. see numa library manpage for cpu list specifications. - If no affinity specification is provide during deployment, then enabling this will deploy resources on next available processor socket. (force_override will ignore this) false - controls if affinity requests are processed by the GPP. true - - - - list of cpu ids that are being monitored for loadavg and idle utilization. - - - - - - cycle time between updates of metric capture, calculations and threshold evaluations. - 500 - milliseconds - - - - diff --git a/redhawk/src/testing/sdr/dev/devices/GPP/cpp/GPP.cpp b/redhawk/src/testing/sdr/dev/devices/GPP/cpp/GPP.cpp index 965106b18..34ec44e7f 100644 --- a/redhawk/src/testing/sdr/dev/devices/GPP/cpp/GPP.cpp +++ b/redhawk/src/testing/sdr/dev/devices/GPP/cpp/GPP.cpp @@ -25,27 +25,62 @@ the ports can also be done from this class **************************************************************************/ +#include +#include #include +#include #include -#include #include #include +#include +#include +#include +#include +#include +#include #include +#include #include +#include #include #include +#include #include #include -#ifdef HAVE_LIBNUMA +#include +#include +#include +#include +#include +#ifdef HAVE_LIBNUMA #include #endif +#ifdef HAVE_STDLIB_H +#include +#endif + +#ifdef HAVE_SYS_TYPES_H +#include +#endif + +#ifdef HAVE_SYS_WAIT_H +#include +#endif + +#ifdef HAVE_UNISTD_H +#include +#endif + #include "ossie/Events.h" #include "ossie/affinity.h" + #include "GPP.h" #include "utils/affinity.h" #include "utils/SymlinkReader.h" #include "utils/ReferenceWrapper.h" +#include "parsers/PidProcStatParser.h" +#include "states/ProcStat.h" #include "states/ProcMeminfo.h" #include "statistics/CpuUsageStats.h" #include "reports/NicThroughputThresholdMonitor.h" @@ -57,10 +92,160 @@ +class SigChildThread : public ThreadedComponent { + friend class GPP_i; +public: + SigChildThread( GPP_i &p): + parent(p) + {}; + int serviceFunction() { + return parent.sigchld_handler(0); + } +private: + GPP_i &parent; +}; -PREPARE_LOGGING(GPP_i) -extern GPP_i *devicePtr; +class RedirectedIO : public ThreadedComponent { + friend class GPP_i; +public: + RedirectedIO( GPP_i &p): + parent(p) + {}; + int serviceFunction() { + return parent.redirected_io_handler(); + } +private: + GPP_i &parent; +}; + + +uint64_t conv_units( const std::string &units ) { + uint64_t unit_m=1024*1024; + if ( units == "Kb" ) unit_m = 1e3; + if ( units == "Mb" ) unit_m = 1e6; + if ( units == "Gb" ) unit_m = 1e9; + if ( units == "Tb" ) unit_m = 1e12; + if ( units == "KB" ) unit_m = 1024; + if ( units == "MB" || units == "MiB" ) unit_m = 1024*1024; + if ( units == "GB" ) unit_m = 1024*1024*1024; + if ( units == "TB" ) unit_m = (uint64_t)1024*1024*1024*1024; + return unit_m; +} + + +const std::string __ExpandEnvVars(const std::string& original) { + + typedef std::list< std::pair > t2StrLst; + + std::string result = original; + const boost::regex envscan("\\$([0-9A-Za-z_]*)"); + const boost::sregex_iterator end; + t2StrLst replacements; + for (boost::sregex_iterator rit(result.begin(), result.end(), envscan); rit != end; ++rit) + replacements.push_back(std::make_pair((*rit)[0],(*rit)[1])); + for (t2StrLst::const_iterator lit = replacements.begin(); lit != replacements.end(); ++lit) { + const char* expanded = std::getenv(lit->second.c_str()); + if (expanded == NULL) + continue; + boost::replace_all(result, lit->first, expanded); + } + + replacements.clear(); + + const boost::regex envscan2("\\$\\{([0-9A-Za-z_]*)\\}"); + for (boost::sregex_iterator rit(result.begin(), result.end(), envscan2); rit != end; ++rit) + replacements.push_back(std::make_pair((*rit)[0],(*rit)[1])); + for (t2StrLst::const_iterator lit = replacements.begin(); lit != replacements.end(); ++lit) + { + const char* expanded = std::getenv(lit->second.c_str()); + if (expanded == NULL) + continue; + boost::replace_all(result, lit->first, expanded); + } + + return result; +} + + +const std::string __ExpandProperties(const std::string& original, const CF::Properties &props) { + std::string result = original; + const boost::regex envscan("@([0-9A-Za-z_]*)@"); + const boost::sregex_iterator end; + typedef std::list< std::pair > t2StrLst; + t2StrLst replacements; + for (boost::sregex_iterator rit(result.begin(), result.end(), envscan); rit != end; ++rit) + replacements.push_back(std::make_pair((*rit)[0],(*rit)[1])); + const redhawk::PropertyMap& pmap = redhawk::PropertyMap::cast(props); + for (t2StrLst::const_iterator lit = replacements.begin(); lit != replacements.end(); ++lit) + { + if ( pmap.find(lit->second.c_str()) != pmap.end()) { + std::string expanded = pmap[lit->second.c_str()].toString(); + boost::replace_all(result, lit->first, expanded); + } + } + return result; +} + + + +// +// resolve StdOutLogger symbol for compiler... +// +namespace rh_logger { + class StdOutLogger : public Logger { + public: + static LoggerPtr getRootLogger( ); + }; +}; + + +// +// proc_redirect class and helpers +// +class FindRedirect : public std::binary_function< GPP_i::proc_redirect, int, bool > { + +public: + bool operator() ( const GPP_i::proc_redirect &a, const int &pid ) const { + return a.pid == pid; + }; +}; + + +GPP_i::proc_redirect::proc_redirect( int _pid, int _cout, int _cerr ): + pid(_pid), cout(_cout), cerr(_cerr), fname("") + { + }; + +GPP_i::proc_redirect::proc_redirect( const std::string &_fname, int _pid, int _cout, int _cerr ): + pid(_pid), cout(_cout), cerr(_cerr), fname(_fname) + { + }; + +void GPP_i::proc_redirect::close() { + if ( cout > -1 ) ::close(cout); + if ( cerr > -1 ) ::close(cerr); +} + +// +// component_description class and helpers +// + +class FindPid : public std::binary_function< GPP_i::component_description, int, bool > { + +public: + bool operator() ( const GPP_i::component_description &a, const int &pid ) const { + return a.pid == pid; + } +}; + +class FindApp : public std::binary_function< GPP_i::component_description, std::string, bool > { + +public: + bool operator() ( const GPP_i::component_description &a, const std::string &appName ) const { + return a.appName == appName; + } +}; inline bool operator== (const GPP_i::component_description& s1, const GPP_i::component_description& s2) { @@ -72,26 +257,134 @@ inline bool operator== (const GPP_i::component_description& s1, }; +GPP_i::component_description::component_description() : + pid(-1), + appName(""), + identifier(""), + app_started(false), + reservation(-1.0), + terminated(false), + pstat_idx(0) +{ memset(pstat_history, 0, sizeof(pstat_history) ); } + + +GPP_i::component_description::component_description( const std::string &appId) : + pid(-1), + appName(appId), + identifier(""), + app_started(false), + reservation(-1.0), + terminated(false), + pstat_idx(0) +{ memset(pstat_history, 0, sizeof(pstat_history) ); } + + +int64_t GPP_i::component_description::get_process_time() +{ + int64_t retval = 0; + if (parent->grp_children.find(pid) == parent->grp_children.end()) + return retval; + BOOST_FOREACH(const int &_pid, parent->grp_children[pid].pids) { + PidProcStatParser pstat_file(_pid); + if ( pstat_file.parse() < 0 ) { + return -1; + } + retval += pstat_file.get_ticks(); + } + return retval; +} + +void GPP_i::component_description::add_history( int64_t ptime ) { + if ( ptime == -1 ) ptime=0; /// Log error .. + pstat_idx = (pstat_idx + 1)% pstat_history_len; + pstat_history[pstat_idx] = ptime; +} + +void GPP_i::component_description::add_history( ) { + int64_t ptime = get_process_time(); + if ( ptime < 0 ) ptime=0; /// Log error .. + pstat_idx = (pstat_idx + 1)% pstat_history_len; + pstat_history[pstat_idx] = ptime; +} + +int64_t GPP_i::component_description::get_pstat_usage( bool refresh) { + if ( refresh) add_history(); + int64_t retval=0; + int8_t p1_idx = pstat_idx -1; + if ( p1_idx < 0 ) p1_idx = pstat_history_len-1; + uint64_t p1=pstat_history[p1_idx]; + uint64_t p2=pstat_history[pstat_idx]; + retval=p2-p1; + if ( (p2-p1) < 0 )retval=p1-p2; + return retval; +} + +int64_t GPP_i::component_description::get_pstat_usage( uint64_t &p2, uint64_t &p1 ){ + int64_t retval=0; + p2 = pstat_history[pstat_idx]; + int8_t p1_idx = pstat_idx -1; + if ( p1_idx < 0 ) p1_idx = pstat_history_len-1; + p1=pstat_history[p1_idx]; + retval=p2-p1; + if ( (p2-p1) < 0 )retval=p1-p2; + return retval; +} + + +PREPARE_LOGGING(GPP_i) + +extern GPP_i *devicePtr; + +std::string GPP_i::format_up_time(unsigned long secondsUp) +{ + std::stringstream formattedUptime; + int days; + int hours; + int minutes; + int seconds; + + int leftover; + + days = (int) secondsUp / (60 * 60 * 24); + leftover = (int) secondsUp - (days * (60 * 60 * 24) ); + hours = (int) leftover / (60 * 60); + leftover = leftover - (hours * (60 * 60) ); + minutes = (int) leftover / 60; + seconds = leftover - (minutes * 60); + + formattedUptime << days << "d " << hours << "h " << minutes << "m " << seconds << "s"; + + return formattedUptime.str(); +} + GPP_i::GPP_i(char *devMgr_ior, char *id, char *lbl, char *sftwrPrfl) : - GPP_base(devMgr_ior, id, lbl, sftwrPrfl) + GPP_base(devMgr_ior, id, lbl, sftwrPrfl), + _signalThread( new SigChildThread(*this), 0.1 ), + _redirectedIO( new RedirectedIO(*this), 0.1 ) { _init(); } GPP_i::GPP_i(char *devMgr_ior, char *id, char *lbl, char *sftwrPrfl, char *compDev) : - GPP_base(devMgr_ior, id, lbl, sftwrPrfl, compDev) + GPP_base(devMgr_ior, id, lbl, sftwrPrfl, compDev), + _signalThread( new SigChildThread(*this), 0.1 ), + _redirectedIO( new RedirectedIO(*this), 0.1 ) { - _init(); + _init(); } GPP_i::GPP_i(char *devMgr_ior, char *id, char *lbl, char *sftwrPrfl, CF::Properties capacities) : - GPP_base(devMgr_ior, id, lbl, sftwrPrfl, capacities) + GPP_base(devMgr_ior, id, lbl, sftwrPrfl, capacities), + _signalThread( new SigChildThread(*this), 0.1 ), + _redirectedIO( new RedirectedIO(*this), 0.1 ) { _init(); } GPP_i::GPP_i(char *devMgr_ior, char *id, char *lbl, char *sftwrPrfl, CF::Properties capacities, char *compDev) : - GPP_base(devMgr_ior, id, lbl, sftwrPrfl, capacities, compDev) + GPP_base(devMgr_ior, id, lbl, sftwrPrfl, capacities, compDev), + _signalThread( new SigChildThread(*this), 0.1 ), + _redirectedIO( new RedirectedIO(*this), 0.1 ) { _init(); } @@ -103,8 +396,21 @@ GPP_i::~GPP_i() void GPP_i::_init() { + // get the user id + uid_t tmp_user_id = getuid(); + std::ostringstream s; + s << tmp_user_id; + user_id = s.str(); + limit_check_count = 0; + n_reservations =0; sig_fd = -1; + // + // io redirection for child processes + // + _handle_io_redirects = false; + _componentOutputLog =""; + // // add our local set affinity method that performs numa library calls // @@ -138,6 +444,7 @@ void GPP_i::_init() { // default cycle time setting for updating data model, metrics and state threshold_cycle_time = 500; + thresholds.ignore = false; // // Add property change listeners and allocation modifiers @@ -149,11 +456,39 @@ void GPP_i::_init() { // add property change listener addPropertyChangeListener("reserved_capacity_per_component", this, &GPP_i::reservedChanged); + // add property change listener + addPropertyChangeListener("DCE:c80f6c5a-e3ea-4f57-b0aa-46b7efac3176", this, &GPP_i::_component_output_changed); + + // add property change listener + addPropertyChangeListener("DCE:89be90ae-6a83-4399-a87d-5f4ae30ef7b1", this, &GPP_i::mcastnicThreshold_changed); + + // add property change listener thresholds + addPropertyChangeListener("thresholds", this, &GPP_i::thresholds_changed); + + utilization_entry_struct cpu; + cpu.description = "CPU cores"; + cpu.component_load = 0; + cpu.system_load = 0; + cpu.subscribed = 0; + cpu.maximum = 0; + utilization.push_back(cpu); + + // shadow property to allow for disabling of values + __thresholds = thresholds; + + setPropertyQueryImpl(this->component_monitor, this, &GPP_i::get_component_monitor); + // tie allocation modifier callbacks to identifiers // nic allocation setAllocationImpl("nic_allocation", this, &GPP_i::allocateCapacity_nic_allocation, &GPP_i::deallocateCapacity_nic_allocation); + // support for older nic ingress/egress allocators + setAllocationImpl("DCE:eb08e43f-11c7-45a0-8750-edff439c8b24", this, &GPP_i::allocate_mcastegress_capacity, &GPP_i::deallocate_mcastegress_capacity); + + // support for older nic ingress/egress allocators + setAllocationImpl("DCE:506102d6-04a9-4532-9420-a323d818ddec", this, &GPP_i::allocate_mcastingress_capacity, &GPP_i::deallocate_mcastingress_capacity); + // load capacity allocations setAllocationImpl("DCE:72c1c4a9-2bcf-49c5-bafd-ae2c1d567056", this, &GPP_i::allocate_loadCapacity, &GPP_i::deallocate_loadCapacity); @@ -161,9 +496,32 @@ void GPP_i::_init() { setAllocationImpl("DCE:8dcef419-b440-4bcf-b893-cab79b6024fb", this, &GPP_i::allocate_memCapacity, &GPP_i::deallocate_memCapacity); //setAllocationImpl("diskCapacity", this, &GPP_i::allocate_diskCapacity, &GPP_i::deallocate_diskCapacity); + + // check reservation allocations + setAllocationImpl(this->redhawk__reservation_request, this, &GPP_i::allocate_reservation_request, &GPP_i::deallocate_reservation_request); } +void GPP_i::constructor() +{ + if (this->workingDirectory.empty() or this->cacheDirectory.empty()) { + char* tmp; + std::string path; + tmp = getcwd(NULL, 200); + if (tmp != NULL) { + path = std::string(tmp); + free(tmp); + } + if (this->workingDirectory.empty()) { + this->workingDirectory = path; + } + if (this->cacheDirectory.empty()) { + this->cacheDirectory = path; + } + } +} + + void GPP_i::postConstruction (std::string &profile, std::string ®istrar_ior, const std::string &idm_channel_ior, @@ -181,31 +539,204 @@ void GPP_i::postConstruction (std::string &profile, throw std::runtime_error("unable configure signal handler"); } + _signalThread.start(); + +} + +void GPP_i::update_grp_child_pids() { + glob_t globbuf; + std::vector pids_now; + glob("/proc/[0-9]*", GLOB_NOSORT, NULL, &globbuf); + for (unsigned int i = 0; i < globbuf.gl_pathc; i++) { + std::string stat_filename(globbuf.gl_pathv[globbuf.gl_pathc - i - 1]); + std::string proc_id(stat_filename.substr(stat_filename.rfind("/")+1)); + try { + pids_now.push_back(boost::lexical_cast(proc_id)); + } + catch(...){ + std::stringstream errstr; + errstr << "Unable to process id: "<(*i) * getpagesize() / (1024*1024); + continue; + } + if ( fcnt == 19 ) { // threads + tmp.num_threads = boost::lexical_cast(*i); + continue; + } + if ( fcnt == 4 ) { // process group id + tmp.pgrpid = boost::lexical_cast(*i); + continue; + } + if ( fcnt == 0 ) { // pid + pid = boost::lexical_cast(*i); + continue; + } + } + + } catch ( ... ) { + std::stringstream errstr; + errstr << "Invalid line format in stat file, pid :" << _pid << " field number " << fcnt << " line " << line ; + LOG_WARN(GPP_i, __FUNCTION__ << ": " << errstr.str() ); + continue; + } + + } catch ( ... ) { + std::stringstream errstr; + errstr << "Unable to read "</stat: "<=37 received=" << fcnt << ")"; + LOG_DEBUG(GPP_i, __FUNCTION__ << ": " << errstr.str() ); + continue; + } + parsed_stat[pid] = tmp; + if (grp_children.find(tmp.pgrpid) == grp_children.end()) { + grp_children[tmp.pgrpid].num_processes = 1; + grp_children[tmp.pgrpid].mem_rss = tmp.mem_rss; + grp_children[tmp.pgrpid].num_threads = tmp.num_threads; + grp_children[tmp.pgrpid].pgrpid = tmp.pgrpid; + grp_children[tmp.pgrpid].pids.push_back(pid); + } else { + grp_children[tmp.pgrpid].num_processes += 1; + grp_children[tmp.pgrpid].mem_rss += tmp.mem_rss; + grp_children[tmp.pgrpid].num_threads += tmp.num_threads; + grp_children[tmp.pgrpid].pids.push_back(pid); + } + } + } + std::vector parsed_stat_to_erase; + for(std::map::iterator _it = parsed_stat.begin(); _it != parsed_stat.end(); _it++) { + if (std::find(pids_now.begin(), pids_now.end(), _it->first) == pids_now.end()) { // it is not on the current process list + if (grp_children.find(parsed_stat[_it->first].pgrpid) != grp_children.end()) { + std::vector::iterator it = std::find(grp_children[parsed_stat[_it->first].pgrpid].pids.begin(), grp_children[parsed_stat[_it->first].pgrpid].pids.end(), _it->first); + if (it != grp_children[parsed_stat[_it->first].pgrpid].pids.end()) + grp_children[parsed_stat[_it->first].pgrpid].pids.erase(it); + } + parsed_stat_to_erase.push_back(_it->first); + } + } + BOOST_FOREACH(const int &_pid, parsed_stat_to_erase) { + parsed_stat.erase(_pid); + } } +std::vector GPP_i::get_component_monitor() { + ReadLock rlock(pidLock); + std::vector retval; + struct sysinfo info; + sysinfo(&info); + BOOST_FOREACH(const component_description &_pid, pids) { + if ( !_pid.terminated ) { + if ((grp_children.find(_pid.pid) == grp_children.end()) or (parsed_stat.find(_pid.pid) == parsed_stat.end())) { + std::stringstream errstr; + errstr << "Could not find /proc/"<<_pid.pid<<"/stat. The process corresponding to component "<<_pid.identifier<<" is no longer there"; + LOG_WARN(GPP_i, __FUNCTION__ << ": " << errstr.str() ); + continue; + } + component_monitor_struct tmp; + tmp.waveform_id = _pid.appName; + tmp.pid = _pid.pid; + tmp.component_id = _pid.identifier; + tmp.num_processes = grp_children[_pid.pid].num_processes; + tmp.cores = _pid.core_usage; + + tmp.mem_rss = grp_children[_pid.pid].mem_rss; + tmp.mem_percent = (double) grp_children[_pid.pid].mem_rss * (1024*1024) / ((double)info.totalram * info.mem_unit) * 100; + tmp.num_threads = grp_children[_pid.pid].num_threads; + + tmp.num_files = 0; + BOOST_FOREACH(const int &actual_pid, grp_children[_pid.pid].pids) { + std::stringstream fd_dirname; + DIR * dirp; + struct dirent * entry; + fd_dirname <<"/proc/"<d_type != DT_DIR) { // If the entry is not a directory + tmp.num_files++; + } + } + closedir (dirp); + } + } + + retval.push_back(tmp); + } + } + + return retval; +} void GPP_i::process_ODM(const CORBA::Any &data) { - boost::mutex::scoped_lock lock(pidLock); const ExtendedEvent::ResourceStateChangeEventType* app_state_change; if (data >>= app_state_change) { - std::string appName = ossie::corba::returnString(app_state_change->sourceName); + std::string appId = ossie::corba::returnString(app_state_change->sourceId); if (app_state_change->stateChangeTo == ExtendedEvent::STARTED) { - RH_NL_TRACE("GPP", "ODM CHANNEL EVENT --> APP STARTED app: " << appName ); - for (std::vector::iterator it=reservations.begin();it!=reservations.end();it++) { - if ((*it).appName == appName) { - tableReservation(*it); - break; - } - } + RH_NL_TRACE("GPP", "ODM CHANNEL EVENT --> APP STARTED app: " << appId ); + ReadLock rlock(pidLock); + ProcessList::iterator i = pids.begin(); + // set app_started ... turns off reservation + while ( i != pids.end() ) { + i=std::find_if( i, pids.end(), std::bind2nd( FindApp(), appId ) ); + if ( i != pids.end() ) { + i->app_started = true; + LOG_TRACE(GPP_i, "Monitor_Processes.. APP STARTED:" << i->pid << " app: " << i->appName ); + i++; + } + } } else if (app_state_change->stateChangeTo == ExtendedEvent::STOPPED) { - RH_NL_TRACE("GPP", "ODM CHANNEL EVENT --> APP STOPPED app: " << appName ); - for (std::vector::iterator it=tabled_reservations.begin();it!=tabled_reservations.end();it++) { - if ((*it).appName == appName) { - restoreReservation(*it); - break; - } - } - } + RH_NL_TRACE("GPP", "ODM CHANNEL EVENT --> APP STOPPED app: " << appId ); + ReadLock rlock(pidLock); + ProcessList::iterator i = pids.begin(); + // set app_started ... turns on reservation + while ( i != pids.end() ) { + i=std::find_if( i, pids.end(), std::bind2nd( FindApp(), appId ) ); + if ( i != pids.end() ) { + i->app_started = false; + LOG_TRACE(GPP_i, "Monitor_Processes.. APP STOPPED :" << i->pid << " app: " << i->appName ); + i++; + } + } + } + } + const StandardEvent::DomainManagementObjectRemovedEventType* app_removed; + if (data >>= app_removed) { + if (app_removed->sourceCategory == StandardEvent::APPLICATION) { + WriteLock rlock(pidLock); + std::string producerId(app_removed->producerId); + for (ApplicationReservationMap::iterator app_it=applicationReservations.begin(); app_it!=applicationReservations.end(); app_it++) { + if (app_it->first == producerId) { + applicationReservations.erase(app_it); + break; + } + } + } } } @@ -239,7 +770,7 @@ int GPP_i::_setupExecPartitions( const CpuList &bl_cpus ) { CpuUsageStats cpu_usage(cpus); soc.cpus = cpus; soc.stats = cpu_usage; - soc.idle_threshold = thresholds.cpu_idle; + soc.idle_threshold = __thresholds.cpu_idle; soc.load_capacity.max = cpus.size() * 1.0; soc.load_capacity.measured = 0.0; soc.load_capacity.allocated = 0.0; @@ -252,7 +783,7 @@ int GPP_i::_setupExecPartitions( const CpuList &bl_cpus ) { if ( execPartitions.size() ) { ExecPartitionList::iterator iter = execPartitions.begin(); std::ostringstream ss; - ss << boost::format("%-6s %-4s %-7s %-7s %-7s ") % "SOCKET" % "CPUS" % "USER" % "SYSTEM" % "IDLE" << std::endl; + ss << boost::format("%-6s %-4s %-7s %-7s %-7s ") % "SOCKET" % "CPUS" % "USER" % "SYSTEM" % "IDLE" ; LOG_INFO(GPP_i, ss.str() ); ss.clear(); ss.str(""); @@ -269,14 +800,6 @@ int GPP_i::_setupExecPartitions( const CpuList &bl_cpus ) { } - -void GPP_i::initializeMemoryMonitor() -{ - // add available memory monitor, mem_free defaults to MB - addThresholdMonitor( new FreeMemoryThresholdMonitor(_identifier, MakeCref(thresholds.mem_free), - ConversionWrapper(memCapacity, 1048576, std::divides() ) ) ); -} - void GPP_i::initializeNetworkMonitor() { @@ -290,31 +813,37 @@ GPP_i::initializeNetworkMonitor() data_model.push_back( nic_facade ); std::vector nic_devices( nic_facade->get_devices() ); + std::vector filtered_devices( nic_facade->get_filtered_devices() ); for( size_t i=0; i(modified_thresholds.nic_usage), - boost::bind(&NicFacade::get_throughput_by_device, nic_facade, nic_devices[i]) ) ); + NicMonitorPtr nic_m = NicMonitorPtr( new NicThroughputThresholdMonitor(_identifier, + nic_devices[i], + MakeCref(modified_thresholds.nic_usage), + boost::bind(&NicFacade::get_throughput_by_device, nic_facade, nic_devices[i]) ) ); + + // monitors that affect busy state... + for ( size_t ii=0; ii < filtered_devices.size(); ii++ ) { + if ( nic_devices[i] == filtered_devices[ii] ) { + nic_monitors.push_back(nic_m); + break; + } + } + addThresholdMonitor(nic_m); } } void -GPP_i::initializeCpuMonitor() +GPP_i::initializeResourceMonitors() { - // add memory state reader - ProcMeminfoPtr mem_state( new ProcMeminfo() ); // add cpu utilization calculator RH_NL_INFO("GPP", " initialize CPU Montior --- wl size " << wl_cpus.size()); - CpuUsageStatsPtr cpu_usage_stats( new CpuUsageStats( wl_cpus ) ); - // provide required system metrics to this GPP - system_monitor.reset( new SystemMonitor( cpu_usage_stats, - mem_state ) ); - // seed system monitor + // request a system monitor for this GPP + system_monitor.reset( new SystemMonitor( wl_cpus ) ); + + // seed system monitor history for ( int i=0; i<5; i++ ) { system_monitor->report(); boost::this_thread::sleep( boost::posix_time::milliseconds( 200 ) ); @@ -322,18 +851,37 @@ GPP_i::initializeCpuMonitor() data_model.push_back( system_monitor ); + // add system limits reader + process_limits.reset( new ProcessLimits( getpid() ) ); + + data_model.push_back( process_limits ); + // observer to monitor when cpu idle pass threshold value - addThresholdMonitor( new CpuThresholdMonitor(_identifier, &modified_thresholds.cpu_idle, *cpu_usage_stats, false ) ); + addThresholdMonitor( ThresholdMonitorPtr( new CpuThresholdMonitor(_identifier, &modified_thresholds.cpu_idle, + *(system_monitor->getCpuStats()), false ))); + + // add available memory monitor, mem_free defaults to MB + addThresholdMonitor( ThresholdMonitorPtr( new FreeMemoryThresholdMonitor(_identifier, + MakeCref(modified_thresholds.mem_free), + ConversionWrapper(memCapacity, mem_cap_units, std::multiplies() ) ))); } void -GPP_i::addThresholdMonitor( ThresholdMonitor* threshold_monitor ) +GPP_i::addThresholdMonitor( ThresholdMonitorPtr t ) { - boost::shared_ptr t( threshold_monitor ); - t->attach_listener( boost::bind(&GPP_i::send_threshold_event, this, _1) ); - threshold_monitors.push_back( t ); + t->attach_listener( boost::bind(&GPP_i::send_threshold_event, this, _1) ); + threshold_monitors.push_back( t ); } +void +GPP_i::setShadowThresholds( const thresholds_struct &nv ) { + if ( nv.cpu_idle >= 0.0 ) __thresholds.cpu_idle = nv.cpu_idle; + if ( nv.load_avg >= 0.0 ) __thresholds.load_avg = nv.load_avg; + if ( nv.mem_free >= 0 ) __thresholds.mem_free = nv.mem_free; + if ( nv.nic_usage >= 0 ) __thresholds.nic_usage = nv.nic_usage; + if ( nv.files_available >= 0.0 ) __thresholds.files_available = nv.files_available; + if ( nv.threads >= 0.0 ) __thresholds.threads = nv.threads; +} // // Device LifeCycle API @@ -341,10 +889,9 @@ GPP_i::addThresholdMonitor( ThresholdMonitor* threshold_monitor ) void GPP_i::initialize() throw (CF::LifeCycle::InitializeError, CORBA::SystemException) { - RH_NL_TRACE("GPP", "initialize()"); - + RH_NL_INFO("GPP", "initialize()"); // - // subscribe to ODM_Channel for receiving state changes from Application object + // subscribe to ODM_Channel for receiving state changes from Application objects // try { mymgr = redhawk::events::Manager::GetManager(this); @@ -354,7 +901,18 @@ void GPP_i::initialize() throw (CF::LifeCycle::InitializeError, CORBA::SystemExc LOG_WARN(GPP_i, "Unable to register with EventChannelManager, disabling domain event notification."); } - + // + // check if componentOutputLog is set.. if so enable redirected io operations + // + if ( componentOutputLog != "" ) { + _componentOutputLog =__ExpandEnvVars(componentOutputLog); + _handle_io_redirects = true; + LOG_INFO(GPP_i, "Turning on Component Output Redirection file: " << _componentOutputLog ); + } + else { + LOG_INFO(GPP_i, "Component Output Redirection is DISABLED." << componentOutputLog ); + } + // // Setup affinity settings context // @@ -364,24 +922,94 @@ void GPP_i::initialize() throw (CF::LifeCycle::InitializeError, CORBA::SystemExc // setup execution partitions for performing socket based deployments, we need to know the current black list // _setupExecPartitions( bl_cpus ); + + // + // Get units for conversion operations + // + std::string munit("MB"); + PropertyInterface *p = getPropertyFromId("thresholds::mem_free"); + if (p) { + munit = p->units; + } + thresh_mem_free_units=conv_units(munit); + + munit="MB"; + p = getPropertyFromId("memFree"); + if (p) { + munit = p->units; + } + mem_free_units=conv_units(munit); + + munit="MB"; + p = getPropertyFromId("memCapacity"); + if (p) { + munit = p->units; + } + mem_cap_units=conv_units(munit); // // setup the data model for the GPP // threshold_monitors.clear(); - initializeCpuMonitor(); - initializeMemoryMonitor(); + initializeResourceMonitors(); initializeNetworkMonitor(); std::for_each( data_model.begin(), data_model.end(), boost::bind( &Updateable::update, _1 ) ); std::for_each( execPartitions.begin(), execPartitions.end(), boost::bind( &Updateable::update, _1 ) ); // - // System wide metrics + // get monitored system values... + // + const SystemMonitor::Report &rpt = system_monitor->getReport(); + + // thresholds can be individually disabled, use shadow thresholds for actual calculations and conditions + setShadowThresholds( thresholds ); + + // + // load average attributes // - loadCapacity_counter = 0; + loadTotal = loadCapacityPerCore * (float)processor_cores; + loadCapacity = loadTotal * ((double)__thresholds.load_avg / 100.0); + loadFree = loadCapacity; idle_capacity_modifier = 100.0 * reserved_capacity_per_component/((float)processor_cores); + + // + // memory capacity tracking attributes + // + memInitVirtFree=rpt.virtual_memory_free; // assume current state to be total available + int64_t init_mem_free = (int64_t) memInitVirtFree; + memInitCapacityPercent = (double)( (int64_t)init_mem_free - (int64_t)(__thresholds.mem_free*thresh_mem_free_units) )/ (double)init_mem_free; + if ( memInitCapacityPercent < 0.0 ) memInitCapacityPercent = 100.0; + memFree = init_mem_free / mem_free_units; + memCapacity = ((int64_t)( init_mem_free * memInitCapacityPercent)) / mem_cap_units ; + memCapacityThreshold = memCapacity; + + // + // set initial modified thresholds + // modified_thresholds = thresholds; + modified_thresholds.mem_free = __thresholds.mem_free*thresh_mem_free_units; + modified_thresholds.load_avg = loadTotal * ( (double)__thresholds.load_avg / 100.0); + modified_thresholds.cpu_idle = __thresholds.cpu_idle; + + loadAverage.onemin = rpt.load.one_min; + loadAverage.fivemin = rpt.load.five_min; + loadAverage.fifteenmin = rpt.load.fifteen_min; + + // + // transfer limits to properties + // + const Limits::Contents &sys_rpt = rpt.sys_limits; + sys_limits.current_threads = sys_rpt.threads; + sys_limits.max_threads = sys_rpt.threads_limit; + sys_limits.current_open_files = sys_rpt.files; + sys_limits.max_open_files = sys_rpt.files_limit; + + const Limits::Contents &pid_rpt = process_limits->get(); + gpp_limits.current_threads = pid_rpt.threads; + gpp_limits.max_threads = pid_rpt.threads_limit; + gpp_limits.current_open_files = pid_rpt.files; + gpp_limits.max_open_files = pid_rpt.files_limit; // enable monitors to push out state change events.. MonitorSequence::iterator iter=threshold_monitors.begin(); @@ -389,17 +1017,79 @@ void GPP_i::initialize() throw (CF::LifeCycle::InitializeError, CORBA::SystemExc if ( *iter ) (*iter)->enable_dispatch(); } + // + // setup mcast interface allocations, used by older systems -- need to deprecate + // + mcastnicIngressThresholdValue = mcastnicIngressTotal * ( mcastnicThreshold / 100.0) ; + mcastnicIngressCapacity = mcastnicIngressThresholdValue; + mcastnicIngressFree = mcastnicIngressCapacity; + mcastnicEgressThresholdValue = mcastnicEgressTotal * ( mcastnicThreshold / 100.0) ; + mcastnicEgressCapacity = mcastnicEgressThresholdValue; + mcastnicEgressFree = mcastnicEgressCapacity; + + // grab nic_metrics for the specified interface + _set_vlan_property(); + // use by service function to mark update time for monitors, states, and stats time_mark = boost::posix_time::microsec_clock::local_time(); + // start capturing IO redirections + _redirectedIO.start(); + GPP_base::start(); GPP_base::initialize(); } + +void GPP_i::thresholds_changed(const thresholds_struct *ov, const thresholds_struct *nv) { + + if ( !(nv->mem_free < 0 ) && ov->mem_free != nv->mem_free ) { + LOG_DEBUG(GPP_i, __FUNCTION__ << " THRESHOLDS.MEM_FREE CHANGED old/new " << ov->mem_free << "/" << nv->mem_free ); + WriteLock wlock(pidLock); + int64_t init_mem_free = (int64_t) memInitVirtFree; + // type cast required for correct calc on 32bit os + memInitCapacityPercent = (double)( (int64_t)init_mem_free - (int64_t)(nv->mem_free*thresh_mem_free_units) )/ (double) init_mem_free; + if ( memInitCapacityPercent < 0.0 ) memInitCapacityPercent = 100.0; + memCapacity = ((int64_t)( init_mem_free * memInitCapacityPercent) ) / mem_cap_units ; + memCapacityThreshold = memCapacity; + modified_thresholds.mem_free = nv->mem_free*thresh_mem_free_units; + } + + + if ( !(nv->load_avg < 0.0) && !(fabs(ov->load_avg - nv->load_avg ) < std::numeric_limits::epsilon()) ) { + LOG_DEBUG(GPP_i, __FUNCTION__ << " THRESHOLDS.LOAD_AVG CHANGED old/new " << ov->load_avg << "/" << nv->load_avg ); + WriteLock wlock(pidLock); + loadCapacity = loadTotal * ((double)nv->load_avg / 100.0); + loadFree = loadCapacity; + modified_thresholds.load_avg = loadTotal * ( (double)nv->load_avg / 100.0); + } + + if ( !(nv->cpu_idle < 0.0) && !(fabs(ov->cpu_idle - nv->cpu_idle ) < std::numeric_limits::epsilon())) { + LOG_DEBUG(GPP_i, __FUNCTION__ << " THRESHOLDS.CPU_IDLE CHANGED old/new " << ov->cpu_idle << "/" << nv->cpu_idle ); + WriteLock wlock(pidLock); + modified_thresholds.cpu_idle = nv->cpu_idle; + } + + + if ( !(nv->nic_usage < 0) && !(fabs(ov->nic_usage - nv->nic_usage ) < std::numeric_limits::epsilon())) { + LOG_DEBUG(GPP_i, __FUNCTION__ << " THRESHOLDS.NIC_USAGE CHANGED old/new " << ov->nic_usage << "/" << nv->nic_usage ); + WriteLock wlock(monitorLock); + modified_thresholds.nic_usage = nv->nic_usage; + } + + setShadowThresholds( *nv ); + +} + void GPP_i::releaseObject() throw (CORBA::SystemException, CF::LifeCycle::ReleaseError) { - if ( odm_consumer ) odm_consumer.reset(); - GPP_base::releaseObject(); + _signalThread.stop(); + _signalThread.release(); + _handle_io_redirects = false; + _redirectedIO.stop(); + _redirectedIO.release(); + if ( odm_consumer ) odm_consumer.reset(); + GPP_base::releaseObject(); } @@ -424,10 +1114,27 @@ CF::ExecutableDevice::ProcessID_Type GPP_i::execute (const char* name, const CF: std::vector prepend_args; std::string naming_context_ior; - const redhawk::PropertyMap& tmp_params = redhawk::PropertyMap::cast(parameters); + CF::Properties variable_parameters; + variable_parameters = parameters; + redhawk::PropertyMap& tmp_params = redhawk::PropertyMap::cast(variable_parameters); + float reservation_value = -1; + if (tmp_params.find("RH::GPP::MODIFIED_CPU_RESERVATION_VALUE") != tmp_params.end()) { + double reservation_value_d; + if (!tmp_params["RH::GPP::MODIFIED_CPU_RESERVATION_VALUE"].getValue(reservation_value)) { + if (tmp_params["RH::GPP::MODIFIED_CPU_RESERVATION_VALUE"].getValue(reservation_value_d)) { + reservation_value = reservation_value_d; + } else { + reservation_value = -1; + } + } + tmp_params.erase("RH::GPP::MODIFIED_CPU_RESERVATION_VALUE"); + } naming_context_ior = tmp_params["NAMING_CONTEXT_IOR"].toString(); std::string app_id; std::string component_id = tmp_params["COMPONENT_IDENTIFIER"].toString(); + if (applicationReservations.find(component_id) != applicationReservations.end()) { + applicationReservations.erase(component_id); + } std::string name_binding = tmp_params["NAME_BINDING"].toString(); CF::Application_var _app = CF::Application::_nil(); CORBA::Object_var obj = ossie::corba::Orb()->string_to_object(naming_context_ior.c_str()); @@ -441,11 +1148,11 @@ CF::ExecutableDevice::ProcessID_Type GPP_i::execute (const char* name, const CF: } else { _app = _appRegistrar->app(); if (not CORBA::is_nil(_app)) { - app_id = ossie::corba::returnString(_app->name()); + app_id = ossie::corba::returnString(_app->identifier()); } } } - if (this->useScreen) { + if (useScreen) { std::string ld_lib_path(getenv("LD_LIBRARY_PATH")); setenv("GPP_LD_LIBRARY_PATH",ld_lib_path.c_str(),1); @@ -496,70 +1203,568 @@ CF::ExecutableDevice::ProcessID_Type GPP_i::execute (const char* name, const CF: } CF::ExecutableDevice::ProcessID_Type ret_pid; try { - ret_pid = ExecutableDevice_impl::do_execute(name, options, parameters, prepend_args); - this->addPid(ret_pid, app_id, component_id); - this->addReservation( getComponentDescription(ret_pid) ); + ret_pid = do_execute(name, options, tmp_params, prepend_args); + addProcess(ret_pid, app_id, component_id, reservation_value); } catch ( ... ) { throw; } return ret_pid; } -void GPP_i::terminate (CF::ExecutableDevice::ProcessID_Type processId) throw (CORBA::SystemException, CF::ExecutableDevice::InvalidProcess, CF::Device::InvalidState) + + + +/* execute ***************************************************************** + - executes a process on the device +************************************************************************* */ +CF::ExecutableDevice::ProcessID_Type GPP_i::do_execute (const char* name, const CF::Properties& options, const CF::Properties& parameters, const std::vector prepend_args) throw (CORBA::SystemException, CF::Device::InvalidState, CF::ExecutableDevice::InvalidFunction, CF::ExecutableDevice::InvalidParameters, CF::ExecutableDevice::InvalidOptions, CF::InvalidFileName, CF::ExecutableDevice::ExecuteFail) { - boost::recursive_mutex::scoped_lock lock(load_execute_lock); - try { - ExecutableDevice_impl::terminate(processId); - this->removeReservation( getComponentDescription(processId)) ; + CF::Properties invalidOptions; + std::string path; + char* tmp; + + // throw and error if name does not begin with a / + if (strncmp(name, "/", 1) != 0) + throw CF::InvalidFileName(CF::CF_EINVAL, "Filename must be absolute"); + if (isLocked()) + throw CF::Device::InvalidState("System is locked down"); + if (isDisabled()) + throw CF::Device::InvalidState("System is disabled"); + + //process options and throw InvalidOptions errors if they are not ULong + for (CORBA::ULong i = 0; i < options.length(); ++i) { + if (options[i].id == CF::ExecutableDevice::PRIORITY_ID) { + CORBA::TypeCode_var atype = options[i].value.type(); + if (atype->kind() != CORBA::tk_ulong) { + invalidOptions.length(invalidOptions.length() + 1); + invalidOptions[invalidOptions.length() - 1].id = options[i].id; + invalidOptions[invalidOptions.length() - 1].value + = options[i].value; + } else + LOG_WARN(GPP_i, "Received a PRIORITY_ID execute option...ignoring.") + } + if (options[i].id == CF::ExecutableDevice::STACK_SIZE_ID) { + CORBA::TypeCode_var atype = options[i].value.type(); + if (atype->kind() != CORBA::tk_ulong) { + invalidOptions.length(invalidOptions.length() + 1); + invalidOptions[invalidOptions.length() - 1].id = options[i].id; + invalidOptions[invalidOptions.length() - 1].value + = options[i].value; + } else + LOG_WARN(GPP_i, "Received a STACK_SIZE_ID execute option...ignoring.") + } } - catch(...){ + + if (invalidOptions.length() > 0) { + throw CF::ExecutableDevice::InvalidOptions(invalidOptions); } - this->removePid(processId); -} + // retrieve current working directory + if (this->cacheDirectory.empty()) { + tmp = getcwd(NULL, 200); + if (tmp != NULL) { + path = std::string(tmp); + free(tmp); + } + } else { + path = this->cacheDirectory; + if (!path.compare(path.length()-1, 1, "/")) { + path = path.erase(path.length()-1); + } + } -// -// -// Executable/Device method overrides... -// -// + // append relative path of the executable + path.append(name); -void GPP_i::updateUsageState() -{ - if (system_monitor->get_idle_percent() < modified_thresholds.cpu_idle) { - if ( system_monitor->get_idle_average() < modified_thresholds.cpu_idle) - setUsageState(CF::Device::BUSY); - } - else if (system_monitor->get_mem_free() < (unsigned long)modified_thresholds.mem_free) - setUsageState(CF::Device::BUSY); - else if (this->getPids().size() == 0) - setUsageState(CF::Device::IDLE); - else - setUsageState(CF::Device::ACTIVE); -} + // check file existence + if (access(path.c_str(), F_OK) == -1) { + std::string errMsg = "File could not be found " + path; + throw CF::InvalidFileName(CF::CF_EINVAL, + CORBA::string_dup(errMsg.c_str())); + } + // change permissions to 7-- + if (chmod(path.c_str(), S_IRWXU) != 0) { + LOG_ERROR(GPP_i, "Unable to change permission on executable"); + throw CF::ExecutableDevice::ExecuteFail(CF::CF_EACCES, + "Unable to change permission on executable"); + } -/** - override ExecutableDevice::set_resource_affinity to handle localized settings. - */ -void GPP_i::set_resource_affinity( const CF::Properties& options, const pid_t rsc_pid, const char *rsc_name, const std::vector &bl ) + // assemble argument list + std::vector args = prepend_args; + if (getenv("VALGRIND")) { + char* valgrind = getenv("VALGRIND"); + if (strlen(valgrind) == 0) { + // Assume that valgrind is somewhere on the path + args.push_back("valgrind"); + } else { + // Environment variable is path to valgrind executable + args.push_back(valgrind); + } + // Put the log file in the cache next to the component entrypoint; + // include the pid to avoid clobbering existing files + std::string logFile = "--log-file="; + char* name_temp = strdup(path.c_str()); + logFile += dirname(name_temp); + free(name_temp); + logFile += "/valgrind.%p.log"; + args.push_back(logFile); + } + args.push_back(path); + + LOG_DEBUG(GPP_i, "Building param list for process " << path); + for (CORBA::ULong i = 0; i < parameters.length(); ++i) { + LOG_DEBUG(GPP_i, "id=" << ossie::corba::returnString(parameters[i].id) << " value=" << ossie::any_to_string(parameters[i].value)); + CORBA::TypeCode_var atype = parameters[i].value.type(); + args.push_back(ossie::corba::returnString(parameters[i].id)); + args.push_back(ossie::any_to_string(parameters[i].value)); + } + + LOG_DEBUG(GPP_i, "Forking process " << path); + + std::vector argv(args.size() + 1, NULL); + for (std::size_t i = 0; i < args.size(); ++i) { + // const_cast because execv does not modify values in argv[]. + // See: http://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html + argv[i] = const_cast (args[i].c_str()); + } + + rh_logger::LevelPtr lvl = GPP_i::__logger->getLevel(); + + // setup to capture stdout and stderr from children. + int comp_fd[2]; + if ( _handle_io_redirects ) { + if ( pipe( comp_fd ) == -1 ) { + LOG_ERROR(GPP_i, "Failure to create redirected IO for:" << path); + throw CF::ExecutableDevice::ExecuteFail(CF::CF_EPERM, "Failure to create redirected IO for component"); + } + + if ( fcntl( comp_fd[0], F_SETFD, FD_CLOEXEC ) == -1 ) { + LOG_ERROR(GPP_i, "Failure to support redirected IO for:" << path); + throw CF::ExecutableDevice::ExecuteFail(CF::CF_EPERM, "Failure to support redirected IO for component"); + } + + } + + // fork child process + int pid = fork(); + + if (pid == 0) { + + int num_retries = 5; + int returnval = 0; + + // + // log4cxx will cause dead locks between fork and execv, use the stdout logger object + // for all logging + // + rh_logger::LoggerPtr __logger = rh_logger::StdOutLogger::getRootLogger(); + __logger->setLevel(lvl); + + // set affinity logger method so we do not use log4cxx during affinity processing routine + redhawk::affinity::set_affinity_logger( __logger ) ; + RH_DEBUG(__logger, " Calling set resource affinity....exec:" << name << " options=" << options.length()); + + // set affinity preference before exec + try { + RH_DEBUG(__logger, " Calling set resource affinity....exec:" << name << " options=" << options.length()); + set_resource_affinity( options, getpid(), name ); + } + catch( redhawk::affinity::AffinityFailed &ex ) { + RH_WARN(__logger, "Unable to satisfy affinity request for: " << name << " Reason: " << ex.what() ); + errno=EPERM<<2; + returnval=-1; + ossie::corba::OrbShutdown(true); + exit(returnval); + } + catch( ... ) { + RH_WARN(__logger, "Unhandled exception during affinity processing for resource: " << name ); + ossie::corba::OrbShutdown(true); + exit(returnval); + } + + // reset mutex in child... + pthread_mutex_init(load_execute_lock.native_handle(),0); + + // set the forked component as the process group leader + setpgid(getpid(), 0); + + // apply io redirection for stdout and stderr + if ( _handle_io_redirects ) { + + if( dup2(comp_fd[1],STDERR_FILENO) ==-1 ) { + RH_ERROR(__logger, "Failure to dup2 stderr for resource: " << name ); + ossie::corba::OrbShutdown(true); + exit(-1); + } + + if( dup2(comp_fd[1],STDOUT_FILENO) ==-1 ) { + RH_ERROR(__logger, "Failure to dup2 stdout for resource: " << name ); + ossie::corba::OrbShutdown(true); + exit(-1); + } + + close(comp_fd[0]); + close(comp_fd[1]); + } + + + // Run executable + while(true) + { + if (strcmp(argv[0], "valgrind") == 0) { + // Find valgrind in the path + returnval = execvp(argv[0], &argv[0]); + } else { + returnval = execv(argv[0], &argv[0]); + } + + num_retries--; + if( num_retries <= 0 || errno!=ETXTBSY) + break; + + // Only retry on "text file busy" error + RH_WARN(__logger, "execv() failed, retrying... (cmd=" << path << " msg=\"" << strerror(errno) << "\" retries=" << num_retries << ")"); + usleep(100000); + } + + if( returnval ) { + RH_ERROR(__logger, "Error when calling execv() (cmd=" << path << " errno=" << errno << " msg=\"" << strerror(errno) << "\")"); + ossie::corba::OrbShutdown(true); + } + + RH_ERROR(__logger, "Exiting FAILED subprocess:" << returnval ); + exit(returnval); + } + else if (pid < 0 ){ + LOG_ERROR(GPP_i, "Error forking child process (errno: " << errno << " msg=\"" << strerror(errno) << "\")" ); + switch (errno) { + case E2BIG: + throw CF::ExecutableDevice::ExecuteFail(CF::CF_E2BIG, + "Argument list too long"); + case EACCES: + throw CF::ExecutableDevice::ExecuteFail(CF::CF_EACCES, + "Permission denied"); + case ENAMETOOLONG: + throw CF::ExecutableDevice::ExecuteFail(CF::CF_ENAMETOOLONG, + "File name too long"); + case ENOENT: + throw CF::ExecutableDevice::ExecuteFail(CF::CF_ENOENT, + "No such file or directory"); + case ENOEXEC: + throw CF::ExecutableDevice::ExecuteFail(CF::CF_ENOEXEC, + "Exec format error"); + case ENOMEM: + throw CF::ExecutableDevice::ExecuteFail(CF::CF_ENOMEM, + "Out of memory"); + case ENOTDIR: + throw CF::ExecutableDevice::ExecuteFail(CF::CF_ENOTDIR, + "Not a directory"); + case EPERM: + throw CF::ExecutableDevice::ExecuteFail(CF::CF_EPERM, + "Operation not permitted"); + default: + throw CF::ExecutableDevice::ExecuteFail(CF::CF_NOTSET, + "ERROR ON FORK"); + } + } + + if ( _handle_io_redirects ) { + close(comp_fd[1]); + LOG_TRACE(GPP_i, "Adding Task for IO Redirection PID:" << pid << " : stdout "<< comp_fd[0] ); + WriteLock wlock(fdsLock); + // trans form file name if contains env or exec param expansion + std::string rfname=__ExpandEnvVars(componentOutputLog); + rfname=__ExpandProperties(rfname, parameters ); + redirectedFds.push_front( proc_redirect( rfname, pid, comp_fd[0] ) ); + } + + + LOG_DEBUG(GPP_i, "Execute success: name:" << name << " : "<< path); + + return pid; +} + + +void GPP_i::terminate (CF::ExecutableDevice::ProcessID_Type processId) throw (CORBA::SystemException, CF::ExecutableDevice::InvalidProcess, CF::Device::InvalidState) +{ + LOG_TRACE(GPP_i, " Terminate request, processID: " << processId); + component_description comp; + try { + markPidTerminated( processId ); + ExecutableDevice_impl::terminate(processId); + } + catch(...){ + } + removeProcess(processId); +} + +bool GPP_i::_component_cleanup( const int child_pid, const int exit_status ) { + + + bool ret=false; + component_description comp; + try { + comp = getComponentDescription(child_pid); + ret=true; + if ( !comp.terminated ) { + // release of component can exit process before terminate is called + if ( WIFEXITED(exit_status) == 0 ) { + LOG_ERROR(GPP_i, " Unexpected Component Failure, App/Identifier/Process: " << + comp.appName << "/" << comp.identifier << "/" << comp.terminated << "/" << child_pid << + " STATUS==" << WIFEXITED(exit_status) << "," << WEXITSTATUS(exit_status) << + "," <get_threshold_value(); + actual += monitor->get_measured_value(); + + LOG_TRACE(GPP_i, __FUNCTION__ << ": NicThreshold: " << monitor->get_resource_id() << " exceeded " << monitor->is_threshold_exceeded() << " threshold=" << monitor->get_threshold() << " measured=" << monitor->get_measured()); + if ( monitor->is_threshold_exceeded() ) nic_exceeded++; + } + + if ( nic_monitors.size() != 0 && nic_monitors.size() == nic_exceeded ) { + std::ostringstream oss; + oss << "Threshold (cumulative) : " << threshold << " Actual (cumulative) : " << actual; + _setReason( "NIC USAGE ", oss.str() ); + retval = true; + } + + return retval; +} + +bool GPP_i::_check_limits( const thresholds_struct &thresholds) +{ + limit_check_count = (limit_check_count + 1) % 10; + if ( limit_check_count ) { + return false; + } + + float _tthreshold = 1 - __thresholds.threads * .01; + + if (gpp_limits.max_threads != -1) { + // + // check current process limits + // + LOG_TRACE(GPP_i, "_gpp_check_limits threads (cur/max): " << gpp_limits.current_threads << "/" << gpp_limits.max_threads ); + if (gpp_limits.current_threads>(gpp_limits.max_threads*_tthreshold)) { + LOG_WARN(GPP_i, "GPP process thread limit threshold exceeded, count/threshold: " << gpp_limits.current_threads << "/" << (gpp_limits.max_threads*_tthreshold) ); + return true; + } + } + + if ( sys_limits.max_threads != -1 ) { + // + // check current system limits + // + LOG_TRACE(GPP_i, "_sys_check_limits threads (cur/max): " << sys_limits.current_threads << "/" << sys_limits.max_threads ); + if (sys_limits.current_threads>( sys_limits.max_threads *_tthreshold)) { + LOG_WARN(GPP_i, "SYSTEM thread limit threshold exceeded, count/threshold: " << sys_limits.current_threads << "/" << (sys_limits.max_threads*_tthreshold) ); + return true; + } + } + + return false; +} + + +// +// +// Executable/Device method overrides... +// +// + +void GPP_i::updateUsageState() +{ + // allow for global ignore of thresholds + if ( thresholds.ignore == true ) { + LOG_TRACE(GPP_i, "Ignoring threshold checks "); + if (getPids().size() == 0) { + LOG_TRACE(GPP_i, "Usage State IDLE (trigger) pids === 0... "); + _resetReason(); + setUsageState(CF::Device::IDLE); + } + else { + LOG_TRACE(GPP_i, "Usage State ACTIVE..... "); + _resetReason(); + setUsageState(CF::Device::ACTIVE); + } + return; + } + + double sys_idle = system_monitor->get_idle_percent(); + double sys_idle_avg = system_monitor->get_idle_average(); + double sys_load = system_monitor->get_loadavg(); + int64_t mem_free = system_monitor->get_mem_free(); + + // get reservation state + double max_allowable_load = utilization[0].maximum; + double subscribed = utilization[0].subscribed; + + + { + std::stringstream oss; + ReadLock rlock(monitorLock); + NicMonitorSequence::iterator iter=nic_monitors.begin(); + for( ; iter != nic_monitors.end(); iter++ ) { + NicMonitorPtr m = *iter; + oss << " Nic: " << m->get_resource_id() << " exceeded " << m->is_threshold_exceeded() << " threshold=" << m->get_threshold() << " measured=" << m->get_measured() << std::endl; + } + + LOG_TRACE(GPP_i, "USAGE STATE: " << std::endl << + " CPU: threshold " << modified_thresholds.cpu_idle << " Actual: " << sys_idle << " Avg: " << sys_idle_avg << std::endl << + " MEM: threshold " << modified_thresholds.mem_free << " Actual: " << mem_free << std::endl << + " LOAD: threshold " << modified_thresholds.load_avg << " Actual: " << sys_load << std::endl << + " RESRV: threshold " << max_allowable_load << " Actual: " << subscribed << std::endl << + " Ingress threshold: " << mcastnicIngressThresholdValue << " capacity: " << mcastnicIngressCapacity << std::endl << + " Egress threshold: " << mcastnicEgressThresholdValue << " capacity: " << mcastnicEgressCapacity << std::endl << + " Threads threshold: " << gpp_limits.max_threads << " Actual: " << gpp_limits.current_threads << std::endl << + " NIC: " << std::endl << oss.str() + ); + } + + if ( !(thresholds.cpu_idle < 0) ) { + if (sys_idle < modified_thresholds.cpu_idle) { + if ( sys_idle_avg < modified_thresholds.cpu_idle) { + std::ostringstream oss; + oss << "Threshold: " << modified_thresholds.cpu_idle << " Actual/Average: " << sys_idle << "/" << sys_idle_avg ; + _setReason( "CPU IDLE", oss.str() ); + setUsageState(CF::Device::BUSY); + return; + } + } + } + + if ( !(thresholds.mem_free < 0) && (mem_free < modified_thresholds.mem_free)) { + std::ostringstream oss; + oss << "Threshold: " << modified_thresholds.mem_free << " Actual: " << mem_free; + _setReason( "FREE MEMORY", oss.str() ); + setUsageState(CF::Device::BUSY); + } + + else if ( !(thresholds.load_avg < 0) && ( sys_load > modified_thresholds.load_avg )) { + std::ostringstream oss; + oss << "Threshold: " << modified_thresholds.load_avg << " Actual: " << sys_load; + _setReason( "LOAD AVG", oss.str() ); + setUsageState(CF::Device::BUSY); + } + else if ( reserved_capacity_per_component != 0 && (subscribed > max_allowable_load) ) { + std::ostringstream oss; + oss << "Threshold: " << max_allowable_load << " Actual(subscribed) " << subscribed; + _setReason( "RESERVATION CAPACITY", oss.str() ); + setUsageState(CF::Device::BUSY); + } + else if ( !(thresholds.nic_usage < 0) && _check_nic_thresholds() ) { + setUsageState(CF::Device::BUSY); + } + else if (_check_limits(thresholds)) { + std::ostringstream oss; + oss << "Threshold: " << gpp_limits.max_threads << " Actual: " << gpp_limits.current_threads; + _setReason( "ULIMIT (MAX_THREADS)", oss.str() ); + setUsageState(CF::Device::BUSY); + } + else if (getPids().size() == 0) { + LOG_TRACE(GPP_i, "Usage State IDLE (trigger) pids === 0... "); + _resetReason(); + setUsageState(CF::Device::IDLE); + } + else { + LOG_TRACE(GPP_i, "Usage State ACTIVE..... "); + _resetReason(); + setUsageState(CF::Device::ACTIVE); + } +} + + +void GPP_i::_resetReason() { + _setReason("",""); +} + +void GPP_i::_setReason( const std::string &reason, const std::string &event, const bool enable_timestamp ) { + + if ( reason != "" ) { + if ( reason != _busy_reason ) { + LOG_INFO(GPP_i, "GPP BUSY, REASON: " << reason << " " << event ); + _busy_timestamp = boost::posix_time::microsec_clock::local_time(); + _busy_mark = boost::posix_time::microsec_clock::local_time(); + _busy_reason = reason; + std::ostringstream oss; + oss << "(time: " << _busy_timestamp << ") REASON: " << _busy_reason << " EXCEEDED " << event; + busy_reason = oss.str(); + } + else if ( reason == _busy_reason ) { + boost::posix_time::ptime now = boost::posix_time::microsec_clock::local_time(); + boost::posix_time::time_duration dur = now - _busy_timestamp; + boost::posix_time::time_duration last_msg = now - _busy_mark; + std::ostringstream oss; + oss << "(first/duration: " << _busy_timestamp << "/" << dur << ") REASON: " << _busy_reason << " EXCEEDED " << event; + busy_reason = oss.str(); + if ( last_msg.total_seconds() > 2 ) { + _busy_mark = now; + LOG_INFO(GPP_i, "GPP BUSY, " << oss.str() ); + } + } + } + else { + _busy_timestamp = boost::posix_time::microsec_clock::local_time(); + _busy_mark = _busy_timestamp; + busy_reason = reason; + _busy_reason = reason; + } +} + +/** + override ExecutableDevice::set_resource_affinity to handle localized settings. + + NOTE: the get_affinity_logger method is required to get the rh_logger object used after the "fork" method is + called. ExecutableDevice will provide the logger to use.... + + log4cxx will lock in the child process before execv is call for high frequency component deployments. + */ +void GPP_i::set_resource_affinity( const CF::Properties& options, const pid_t rsc_pid, const char *rsc_name, const std::vector &bl ) { + + RH_DEBUG( redhawk::affinity::get_affinity_logger(), "Affinity Options....GPP/Resource: " << label() << "/" << rsc_name << " options" << options.length() ); + boost::recursive_mutex::scoped_lock(load_execute_lock); + // check if we override incoming affinity requests... if ( affinity.force_override ) { if ( redhawk::affinity::is_disabled() == false ) { - LOG_WARN(GPP_i, "Enforcing GPP affinity property settings to resource, GPP/pid: " << label() << "/" << rsc_pid ); + RH_WARN(redhawk::affinity::get_affinity_logger(), "Enforcing GPP affinity property settings to resource, GPP/pid: " << label() << "/" << rsc_pid ); if ( _apply_affinity( affinity, rsc_pid, rsc_name ) < 0 ) { throw redhawk::affinity::AffinityFailed("Failed to apply GPP affinity settings to resource"); } } else { - LOG_WARN(GPP_i, "Affinity processing disabled, unable to apply GPP affinity settings to resource, GPP/rsc/pid: " << label() << "/" << rsc_name << "/" << rsc_pid ); + RH_WARN(redhawk::affinity::get_affinity_logger(), "Affinity processing disabled, unable to apply GPP affinity settings to resource, GPP/rsc/pid: " << label() << "/" << rsc_name << "/" << rsc_pid ); } } else if ( affinity.deploy_per_socket && redhawk::affinity::has_nic_affinity(options) == false ) { if ( execPartitions.size() == 0 ) { - LOG_WARN(GPP_i, "Skipping deploy_per_socket request. Reason: No execute partitions found, check numa settings. GPP/resource: " << label() << "/" << rsc_name ); + RH_WARN(redhawk::affinity::get_affinity_logger(), "Skipping deploy_per_socket request. Reason: No execute partitions found, check numa settings. GPP/resource: " << label() << "/" << rsc_name ); return; } @@ -569,7 +1774,7 @@ void GPP_i::set_resource_affinity( const CF::Properties& options, const pid_t rs if ( psoc < 0 ) { throw redhawk::affinity::AffinityFailed("Failed to apply PROCESSOR SOCKET affinity settings to resource"); } - LOG_DEBUG(GPP_i, "Enforcing PROCESSOR SOCKET affinity settings to resource, GPP/pid/socket: " << label() << "/" << rsc_pid << "/" << psoc ); + RH_DEBUG(redhawk::affinity::get_affinity_logger(), "Enforcing PROCESSOR SOCKET affinity settings to resource, GPP/pid/socket: " << label() << "/" << rsc_pid << "/" << psoc ); std::ostringstream os; os << psoc; if ( _apply_affinity( rsc_pid, rsc_name, "socket", os.str(), bl_cpus ) < 0 ) { @@ -579,39 +1784,34 @@ void GPP_i::set_resource_affinity( const CF::Properties& options, const pid_t rs } else { + // create black list cpus redhawk::affinity::CpuList blcpus; - try { - //blcpus = gpp::affinity::get_cpu_list( "cpu", affinity.blacklist_cpus ); - blcpus.resize(bl_cpus.size()); - std::copy( bl_cpus.begin(), bl_cpus.end(), blcpus.begin() ); - } - catch( redhawk::affinity::AffinityFailed &ex) { - LOG_ERROR(GPP_i, "Unable to process blacklist cpu specification reason:" << ex.what() ); - throw; - } + blcpus.resize(bl_cpus.size()); + std::copy( bl_cpus.begin(), bl_cpus.end(), blcpus.begin() ); // // Same flow as ExecutableDevice::set_resource_affinity // try { if ( redhawk::affinity::has_affinity( options ) ) { - LOG_DEBUG(GPP_i, "Has Affinity Options....GPP/Resource:" << label() << "/" << rsc_name); + RH_DEBUG(redhawk::affinity::get_affinity_logger(), "Has Affinity Options....GPP/Resource:" << label() << "/" << rsc_name); if ( redhawk::affinity::is_disabled() ) { - LOG_WARN(GPP_i, "Resource has affinity directives but processing disabled, ExecDevice/Resource:" << - label() << "/" << rsc_name); + RH_WARN(redhawk::affinity::get_affinity_logger(), "Resource has affinity directives but processing disabled, ExecDevice/Resource:" << + label() << "/" << rsc_name); } else { - LOG_DEBUG(GPP_i, "Calling set resource affinity.... GPP/Resource:" << - label() << "/" << rsc_name); - redhawk::affinity::set_affinity( options, rsc_pid, blcpus ); + RH_DEBUG(redhawk::affinity::get_affinity_logger(), "Calling set resource affinity.... GPP/Resource: " << label() << "/" << rsc_name); + redhawk::affinity::AffinityDirectives spec = redhawk::affinity::convert_properties( options ); + gpp::affinity::set_affinity( spec, rsc_pid, blcpus ); } } else { - LOG_TRACE(GPP_i, "No Affinity Options Found....GPP/Resource:" << label() << "/" << rsc_name); + RH_TRACE(redhawk::affinity::get_affinity_logger(), "No Affinity Options Found....GPP/Resource: " << label() << "/" << rsc_name); } + } catch( redhawk::affinity::AffinityFailed &e) { - LOG_WARN(GPP_i, "AFFINITY REQUEST FAILED: " << e.what() ); + RH_WARN(redhawk::affinity::get_affinity_logger(), "AFFINITY REQUEST FAILED: " << e.what() ); throw; } @@ -620,35 +1820,8 @@ void GPP_i::set_resource_affinity( const CF::Properties& options, const pid_t rs } - int GPP_i::serviceFunction() { - - // Check if any children died.... - fd_set readfds; - FD_ZERO(&readfds); - FD_SET(sig_fd, &readfds); - struct timeval tv = {0, 50}; - struct signalfd_siginfo si; - ssize_t s; - - if ( sig_fd > -1 ) { - // don't care about writefds and exceptfds: - select(sig_fd+1, &readfds, NULL, NULL, &tv); - if (FD_ISSET(sig_fd, &readfds)) { - LOG_TRACE(GPP_i, "Checking for signals from SIGNALFD......" << sig_fd); - s = read(sig_fd, &si, sizeof(struct signalfd_siginfo)); - if (s != sizeof(struct signalfd_siginfo)){ - LOG_ERROR(GPP_i, "SIGCHLD handling error ..."); - } - - if ( si.ssi_signo == SIGCHLD) { - LOG_TRACE(GPP_i, "Child died , pid .................................." << si.ssi_pid); - sigchld_handler(si.ssi_signo); - } - } - } - boost::posix_time::ptime now = boost::posix_time::microsec_clock::local_time(); boost::posix_time::time_duration dur = now -time_mark; if ( dur.total_milliseconds() < threshold_cycle_time ) { @@ -657,68 +1830,108 @@ int GPP_i::serviceFunction() time_mark = now; - // - // update any threshold limits that are based on the current system state - // - establishModifiedThresholds(); - // update data model for the GPP try { std::for_each( data_model.begin(), data_model.end(), boost::bind( &Updateable::update, _1 ) ); std::for_each( execPartitions.begin(), execPartitions.end(), boost::bind( &exec_socket::update, _1 ) ); - calculateSystemMemoryLoading(); } catch( const boost::thread_resource_error& e ){ std::stringstream errstr; errstr << "Error acquiring lock (errno=" << e.native_error() << " msg=\"" << e.what() << "\")"; LOG_ERROR(GPP_i, __FUNCTION__ << ": " << errstr.str() ); - return NOOP; } + // + // update state that affect device usage state + // + update(); + if ( execPartitions.size() ) { // dump execute partition status... ExecPartitionList::iterator iter = execPartitions.begin(); std::ostringstream ss; ss << boost::format("%-6s %-4s %-7s %-7s %-7s ") % "SOCKET" % "CPUS" % "USER" % "SYSTEM" % "IDLE"; - LOG_DEBUG(GPP_i, ss.str() ); + LOG_TRACE(GPP_i, ss.str() ); ss.clear(); ss.str(""); for ( ; iter != execPartitions.end(); iter++ ) { ss << boost::format("%-6d %-4d %-7.2f %-7.2f %-7.2f ") % iter->id % iter->stats.get_ncpus() % iter->stats.get_user_percent() % iter->stats.get_system_percent() % iter->stats.get_idle_percent() ; - LOG_DEBUG(GPP_i, ss.str() ); + LOG_TRACE(GPP_i, ss.str() ); ss.clear(); ss.str(""); } } + // update monitors to see if thresholds are exceeded + std::for_each( threshold_monitors.begin(), threshold_monitors.end(), boost::bind( &Updateable::update, _1 ) ); + for( size_t i=0; iupdate(); LOG_TRACE(GPP_i, __FUNCTION__ << ": resource_id=" << threshold_monitors[i]->get_resource_id() << " threshold=" << threshold_monitors[i]->get_threshold() << " measured=" << threshold_monitors[i]->get_measured()); } - // update monitors to see if thresholds are exceeded - std::for_each( threshold_monitors.begin(), threshold_monitors.end(), boost::bind( &Updateable::update, _1 ) ); - // update device usages state for the GPP updateUsageState(); - + return NORMAL; } +void GPP_i::_set_vlan_property() +{ + mcastnicVLANs.clear(); + // grab nic_metrics for the specified interface + if ( mcastnicInterface != "" ) { + std::vector::iterator nic = nic_metrics.begin(); + for ( ; nic != nic_metrics.end(); nic++ ) { + // found match + if ( nic->interface == mcastnicInterface ) { + std::vector values; + boost::split( values, nic->vlans, boost::is_any_of(std::string(",")), boost::algorithm::token_compress_on ); + for ( size_t i=0; i< values.size(); i++){ + mcastnicVLANs.push_back( atoi(values[i].c_str()) ); + } + break; + } + } + } + + +} + // // // Property Callback Methods // // + +void GPP_i::_component_output_changed(const std::string *oldValue, const std::string *newValue) +{ + if( newValue ) { + if ( *newValue == "" ) { + _componentOutputLog=""; + _handle_io_redirects = false; + return; + } + + _componentOutputLog =__ExpandEnvVars(componentOutputLog); + _handle_io_redirects = true; + } + else { + _componentOutputLog=""; + _handle_io_redirects = false; + } + +} + + void GPP_i::reservedChanged(const float *oldValue, const float *newValue) { if( newValue ) { reserved_capacity_per_component = *newValue; - idle_capacity_modifier = 100.0 * reserved_capacity_per_component/((float)this->processor_cores); + idle_capacity_modifier = 100.0 * reserved_capacity_per_component/((float)processor_cores); ExecPartitionList::iterator iter = execPartitions.begin(); for( ; iter != execPartitions.end(); iter++ ) { @@ -728,6 +1941,43 @@ void GPP_i::reservedChanged(const float *oldValue, const float *newValue) } +void GPP_i::mcastnicThreshold_changed(const CORBA::Long *oldvalue, const CORBA::Long *newvalue) { + + if( newvalue ) { + int threshold = *newvalue; + if ( threshold >= 0 && threshold <= 100 ) { + double origIngressThreshold = mcastnicIngressThresholdValue; + double origEgressThreshold = mcastnicIngressThresholdValue; + mcastnicThreshold = threshold; + mcastnicIngressThresholdValue = mcastnicIngressTotal * ( mcastnicThreshold / 100.0) ; + mcastnicEgressThresholdValue = mcastnicEgressTotal * ( mcastnicThreshold / 100.0) ; + + if ( mcastnicIngressThresholdValue > origIngressThreshold ) { + // add extra to capacity + mcastnicIngressCapacity += mcastnicIngressThresholdValue -origIngressThreshold; + mcastnicIngressFree = mcastnicIngressCapacity; + } + else if ( mcastnicIngressThresholdValue < mcastnicIngressCapacity ){ + mcastnicIngressCapacity = mcastnicIngressThresholdValue; + mcastnicIngressFree = mcastnicIngressCapacity; + } + + if ( mcastnicEgressThresholdValue > origEgressThreshold ) { + // add extra to capacity + mcastnicEgressCapacity += mcastnicEgressThresholdValue-origEgressThreshold; + mcastnicEgressFree = mcastnicEgressCapacity; + } + else if ( mcastnicEgressThresholdValue < mcastnicEgressCapacity ){ + mcastnicEgressCapacity = mcastnicEgressThresholdValue; + mcastnicEgressFree = mcastnicEgressCapacity; + } + + } + } + +} + + void GPP_i::_affinity_changed( const affinity_struct *ovp, const affinity_struct *nvp ) { if ( ovp && nvp && *ovp == *nvp ) return; @@ -800,16 +2050,16 @@ void GPP_i::_affinity_changed( const affinity_struct *ovp, const affinity_struct if ( std::count( bl_cpus.begin(), bl_cpus.end(), cpus[i] ) == 0 ) wl_cpus.push_back( cpus[i] ); } + // apply changes to member variable + affinity = nv; RH_NL_DEBUG("GPP", "Affinity Force Override, force_override=" << nv.force_override); RH_NL_INFO("GPP", "Affinity Disable State, disabled=" << nv.disabled); - if ( nv.disabled ) { + if ( nv.disabled || gpp::affinity::check_numa() == false ) { RH_NL_INFO("GPP", "Disabling affinity processing requests."); - redhawk::affinity::set_affinity_state( nv.disabled ); + affinity.disabled=true; + redhawk::affinity::set_affinity_state(affinity.disabled); } - // apply changes to member variable - affinity = nv; - _set_processor_monitor_list( wl_cpus ); // reset idle idle capcity monitor... idle threshold gets calculated during each loop of svc func. @@ -832,10 +2082,158 @@ void GPP_i::_affinity_changed( const affinity_struct *ovp, const affinity_struct // Allocation Callback Methods // // +bool GPP_i::allocate_mcastegress_capacity(const CORBA::Long &value) +{ + boost::mutex::scoped_lock lock(propertySetAccess); + std::string except_msg("Invalid allocation"); + bool retval=false; + LOG_DEBUG(GPP_i, __FUNCTION__ << ": Allocating mcastegress allocation " << value); + + if ( mcastnicInterface == "" ) { + std::string msg = "mcastnicEgressCapacity request failed because no mcastnicInterface has been configured"; + LOG_DEBUG(GPP_i, __FUNCTION__ << msg ); + throw CF::Device::InvalidState(msg.c_str()); + return retval; + } + + // see if calculated capacity and measured capacity is avaliable + if ( value > mcastnicEgressCapacity ) { + std::ostringstream os; + os << "mcastnicEgressCapacity request: " << value << " failed because of insufficent capacity available, current: " << mcastnicEgressCapacity; + std::string msg = os.str(); + LOG_DEBUG(GPP_i, __FUNCTION__ << msg ); + CF::Properties errprops; + errprops.length(1); + errprops[0].id = "mcastnicEgressCapacity"; + errprops[0].value <<= (CORBA::Long)value; + throw CF::Device::InvalidCapacity(msg.c_str(), errprops); + } + + // adjust property + retval= true; + mcastnicEgressCapacity = mcastnicEgressCapacity - value; + mcastnicEgressFree = mcastnicEgressCapacity; + return retval; +} + + +void GPP_i::deallocate_mcastegress_capacity(const CORBA::Long &value) +{ + boost::mutex::scoped_lock lock(propertySetAccess); + LOG_DEBUG(GPP_i, __FUNCTION__ << ": Deallocating mcastegress allocation " << value); + + mcastnicEgressCapacity = value + mcastnicEgressCapacity; + if ( mcastnicEgressCapacity > mcastnicEgressThresholdValue ) { + mcastnicEgressCapacity = mcastnicEgressThresholdValue; + } + + mcastnicEgressFree = mcastnicEgressCapacity; +} + +bool GPP_i::allocate_reservation_request(const redhawk__reservation_request_struct &value) +{ + if (isBusy()) { + return false; + } + LOG_DEBUG(GPP_i, __FUNCTION__ << ": allocating reservation_request allocation "); + { + WriteLock rlock(pidLock); + if (applicationReservations.find(value.obj_id) != applicationReservations.end()){ + LOG_INFO(GPP_i, __FUNCTION__ << ": Cannot make multiple reservations against the same application: "<first == value.obj_id) { + applicationReservations.erase(app_it); + break; + } + } +} + + + +bool GPP_i::allocate_mcastingress_capacity(const CORBA::Long &value) +{ + boost::mutex::scoped_lock lock(propertySetAccess); + std::string except_msg("Invalid allocation"); + bool retval=false; + LOG_DEBUG(GPP_i, __FUNCTION__ << ": Allocating mcastingress allocation " << value); + + if ( mcastnicInterface == "" ) { + std::string msg = "mcastnicIngressCapacity request failed because no mcastnicInterface has been configured" ; + LOG_DEBUG(GPP_i, __FUNCTION__ << msg ); + throw CF::Device::InvalidState(msg.c_str()); + } + + // see if calculated capacity and measured capacity is avaliable + if ( value > mcastnicIngressCapacity ) { + std::ostringstream os; + os << "mcastnicIngressCapacity request: " << value << " failed because of insufficent capacity available, current: " << mcastnicIngressCapacity; + std::string msg = os.str(); + LOG_DEBUG(GPP_i, __FUNCTION__ << msg ); + CF::Properties errprops; + errprops.length(1); + errprops[0].id = "mcastnicIngressCapacity"; + errprops[0].value <<= (CORBA::Long)value; + throw CF::Device::InvalidCapacity(msg.c_str(), errprops); + } + + // adjust property + retval=true; + mcastnicIngressCapacity = mcastnicIngressCapacity - value; + mcastnicIngressFree = mcastnicIngressCapacity; + + return retval; +} + + +void GPP_i::deallocate_mcastingress_capacity(const CORBA::Long &value) +{ + boost::mutex::scoped_lock lock(propertySetAccess); + LOG_DEBUG(GPP_i, __FUNCTION__ << ": Deallocating mcastingress deallocation " << value); + + mcastnicIngressCapacity = value + mcastnicIngressCapacity; + if ( mcastnicIngressCapacity > mcastnicIngressThresholdValue ) { + mcastnicIngressCapacity = mcastnicIngressThresholdValue; + } + + mcastnicIngressFree = mcastnicIngressCapacity; +} + + bool GPP_i::allocateCapacity_nic_allocation(const nic_allocation_struct &alloc) { - boost::mutex::scoped_lock lock(pidLock); + WriteLock wlock(nicLock); std::string except_msg("Invalid allocation"); bool success=false; LOG_TRACE(GPP_i, __FUNCTION__ << ": Allocating nic_allocation (identifier=" << alloc.identifier << ")"); @@ -889,7 +2287,7 @@ bool GPP_i::allocateCapacity_nic_allocation(const nic_allocation_struct &alloc) void GPP_i::deallocateCapacity_nic_allocation(const nic_allocation_struct &alloc) { - boost::mutex::scoped_lock lock(pidLock); + WriteLock wlock(nicLock); LOG_TRACE(GPP_i, __FUNCTION__ << ": Deallocating nic_allocation (identifier=" << alloc.identifier << ")"); try { LOG_DEBUG(GPP_i, __FUNCTION__ << ": { identifier: \"" << alloc.identifier << "\", data_rate: " << alloc.data_rate << ", data_size: " << alloc.data_size << ", multicast_support: \"" << alloc.multicast_support << "\", ip_addressable: \"" << alloc.ip_addressable << "\", interface: \"" << alloc.interface << "\" }"); @@ -929,20 +2327,29 @@ void GPP_i::deallocate_diskCapacity(const double &value) { return; } -bool GPP_i::allocate_memCapacity(const int64_t &value) { +bool GPP_i::allocate_memCapacity(const CORBA::LongLong &value) { if (isBusy()) { return false; } - - // get current available free memory from system - if ( system_monitor->get_mem_free() < (uint64_t)value ) + LOG_DEBUG(GPP_i, "allocate memory (REQUEST) value: " << value << " memCapacity: " << memCapacity << " memFree:" << memFree ); + if ( value > memCapacity or value > memCapacityThreshold ) return false; + memCapacity -= value; + LOG_DEBUG(GPP_i, "allocate memory (SUCCESS) value: " << value << " memCapacity: " << memCapacity << " memFree:" << memFree ); return true; } -void GPP_i::deallocate_memCapacity(const int64_t &value) { +void GPP_i::deallocate_memCapacity(const CORBA::LongLong &value) { + LOG_DEBUG(GPP_i, "deallocate memory (REQUEST) value: " << value << " memCapacity: " << memCapacity << " memFree:" << memFree ); + memCapacity += value; + LOG_DEBUG(GPP_i, "deallocate memory (SUCCESS) value: " << value << " memCapacity: " << memCapacity << " memFree:" << memFree ); + if ( memCapacity > memCapacityThreshold ) { + memCapacity = memCapacityThreshold; + } + updateThresholdMonitors(); + updateUsageState(); return; } @@ -953,17 +2360,58 @@ bool GPP_i::allocate_loadCapacity(const double &value) { if (isBusy()) { return false; } + + // get current system load and calculated reservation load + if ( reserved_capacity_per_component == 0.0 ) { + + LOG_DEBUG(GPP_i, "allocate load capacity, (REQUEST) value: " << value << " loadCapacity: " << loadCapacity << " loadFree:" << loadFree ); + // get system monitor report... + double load_threshold = modified_thresholds.load_avg; + double sys_load = system_monitor->get_loadavg(); + if ( sys_load + value > load_threshold ) { + LOG_WARN(GPP_i, "Allocate load capacity would exceed measured system load, current loadavg: " << sys_load << " requested: " << value << " threshold: " << load_threshold ); + } - if ( (loadCapacity_counter - value ) < 0.0 ) - return false; - - loadCapacity_counter -= value; + // perform classic load capacity + if ( value > loadCapacity ) { + std::ostringstream os; + os << " Allocate load capacity failed due to insufficient capacity, available capacity:" << loadCapacity << " requested capacity: " << value; + std::string msg = os.str(); + LOG_DEBUG(GPP_i, msg ); + CF::Properties errprops; + errprops.length(1); + errprops[0].id = "DCE:72c1c4a9-2bcf-49c5-bafd-ae2c1d567056 (loadCapacity)"; + errprops[0].value <<= (CORBA::Long)value; + throw CF::Device::InsufficientCapacity(errprops, msg.c_str()); + } + + loadCapacity -= value; + LOG_DEBUG(GPP_i, "allocate load capacity, (SUCCESS) value: " << value << " loadCapacity: " << loadCapacity << " loadFree:" << loadFree ); + } + else { + // manage load capacity handled via reservation + LOG_WARN(GPP_i, "Allocate load capacity allowed, GPP using component reservations for managing load capacity." ); + + loadCapacity -= value; + if ( loadCapacity < 0.0 ) { + loadCapacity = 0.0; + } + + LOG_DEBUG(GPP_i, "allocate load capacity, (SUCCESS) value: " << value << " loadCapacity: " << loadCapacity << " loadFree:" << loadFree ); + + } + updateUsageState(); return true; } void GPP_i::deallocate_loadCapacity(const double &value) { - loadCapacity_counter += value; + LOG_DEBUG(GPP_i, "deallocate load capacity, (REQUEST) value: " << value << " loadCapacity: " << loadCapacity << " loadFree:" << loadFree ); + loadCapacity += value; + if ( loadCapacity > loadFree ) { + loadCapacity = loadFree; + } + LOG_DEBUG(GPP_i, "deallocate load capacity, (SUCCESS) value: " << value << " loadCapacity: " << loadCapacity << " loadFree:" << loadFree ); updateThresholdMonitors(); updateUsageState(); return; @@ -995,7 +2443,7 @@ void GPP_i::sendChildNotification(const std::string &comp_id, const std::string void GPP_i::updateThresholdMonitors() { - boost::mutex::scoped_lock lock(pidLock); + WriteLock wlock(monitorLock); MonitorSequence::iterator iter=threshold_monitors.begin(); for( ; iter != threshold_monitors.end(); iter++ ) { ThresholdMonitorPtr monitor=*iter; @@ -1004,135 +2452,472 @@ void GPP_i::updateThresholdMonitors() } } - -void GPP_i::establishModifiedThresholds() +void GPP_i::update() { - boost::mutex::scoped_lock lock(pidLock); - this->modified_thresholds.cpu_idle = this->thresholds.cpu_idle + (this->idle_capacity_modifier * this->reservations.size()) + this->loadCapacity_counter; - LOG_TRACE(GPP_i, __FUNCTION__ << "ModifyThreshold : " << std::endl << - " modified_threshold=" << modified_thresholds.cpu_idle << std::endl << + // establish what the actual load is per floor_reservation + // if the actual load -per is less than the reservation, compute the different and add the difference to the cpu_idle + // read the clock from the system (start) + + int64_t user=0, system=0; + ProcStat::GetTicks( system, user); + int64_t f_start_total = system; + int64_t f_use_start_total = user; + float reservation_set = 0; + size_t nres=0; + int64_t usage=0; + + { + WriteLock rlock(pidLock); + + this->update_grp_child_pids(); + + ProcessList::iterator i=this->pids.begin(); + for ( ; i!=pids.end(); i++) { + + if ( !i->terminated ) { + + // update pstat usage for each process + usage = i->get_pstat_usage(); + + if ( !i->app_started ) { + if ( applicationReservations.find(i->appName) != applicationReservations.end()) { + if (applicationReservations[i->appName].reservation.find("cpucores") != applicationReservations[i->appName].reservation.end()) { + continue; + } + } + nres++; + if ( i->reservation == -1) { + reservation_set += idle_capacity_modifier; + } else { + reservation_set += 100.0 * i->reservation/((float)processor_cores); + } + } + } + } + } + LOG_TRACE(GPP_i, __FUNCTION__ << " Completed first pass, record pstats for nproc: " << nres << " res_set " << reservation_set ); + + // set number reservations that are not started + n_reservations = nres; + + // wait a little bit + usleep(500000); + + + user=0, system=0; + ProcStat::GetTicks( system, user); + int64_t f_end_total = system; + int64_t f_use_end_total = user; + float f_total = (float)(f_end_total-f_start_total); + if ( f_total <= 0.0 ) { + LOG_TRACE(GPP_i, __FUNCTION__ << std::endl<< " System Ticks end/start " << f_end_total << "/" << f_start_total << std::endl ); + f_total=1.0; + } + float inverse_load_per_core = ((float)processor_cores)/(f_total); + float aggregate_usage = 0; + float non_specialized_aggregate_usage = 0; + double percent_core; + + ReadLock rlock(pidLock); + ProcessList::iterator i=this->pids.begin(); + int usage_out=0; + for (ApplicationReservationMap::iterator app_it=applicationReservations.begin(); app_it!=applicationReservations.end(); app_it++) { + app_it->second.usage = 0; + } + for ( ; i!=pids.end(); i++, usage_out++) { + + usage = 0; + percent_core =0; + if ( !i->terminated ) { + + // get delta from last pstat + usage = i->get_pstat_usage(); + + percent_core = (double)usage * inverse_load_per_core; + i->core_usage = percent_core; + double res = i->reservation; + +#if 0 + // debug assist + if ( !(usage_out % 500) || usage < 0 || percent_core < 0.0 ) { + uint64_t u, p2, p1; + u = i->get_pstat_usage(p2,p1); + LOG_INFO(GPP_i, __FUNCTION__ << std::endl<< "PROC SPEC PID: " << i->pid << std::endl << + " usage " << usage << std::endl << + " u " << usage << std::endl << + " p2 " << p2 << std::endl << + " p1 " << p1 << std::endl << + " percent_core: " << percent_core << std::endl << + " reservation: " << i->reservation << std::endl ); + } +#endif + + if ( applicationReservations.find(i->appName) != applicationReservations.end()) { + if (applicationReservations[i->appName].reservation.find("cpucores") != applicationReservations[i->appName].reservation.end()) { + applicationReservations[i->appName].usage += percent_core; + } + } + + if ( i->app_started ) { + + // if component is not using enough the add difference between minimum and current load + if ( percent_core < res ) { + reservation_set += 100.00 * ( res - percent_core)/((double)processor_cores); + } + // for components with non specific + if ( res == -1.0 ) { + non_specialized_aggregate_usage += percent_core / inverse_load_per_core; + } + else { + aggregate_usage += percent_core / inverse_load_per_core; + } + } + } + } + + for (ApplicationReservationMap::iterator app_it=applicationReservations.begin(); app_it!=applicationReservations.end(); app_it++) { + if (app_it->second.reservation.find("cpucores") != app_it->second.reservation.end()) { + bool found_app = false; + for ( ProcessList::iterator _pid_it=this->pids.begin();_pid_it!=pids.end(); _pid_it++) { + if (applicationReservations.find(_pid_it->appName) != applicationReservations.end()) { + found_app = true; + break; + } + } + if (not found_app) { + if (app_it->second.reservation["cpucores"] == -1) { + reservation_set += idle_capacity_modifier; + } else { + reservation_set += 100.0 * app_it->second.reservation["cpucores"]/((float)processor_cores); + } + } else { + if (app_it->second.usage < app_it->second.reservation["cpucores"]) { + reservation_set += 100.00 * ( app_it->second.reservation["cpucores"] - app_it->second.usage)/((double)processor_cores); + } + } + } + } + + LOG_TRACE(GPP_i, __FUNCTION__ << " Completed SECOND pass, record pstats for processes" ); + + aggregate_usage *= inverse_load_per_core; + non_specialized_aggregate_usage *= inverse_load_per_core; + modified_thresholds.cpu_idle = __thresholds.cpu_idle + reservation_set; + utilization[0].component_load = aggregate_usage + non_specialized_aggregate_usage; + float estimate_total = (f_use_end_total-f_use_start_total) * inverse_load_per_core; + utilization[0].system_load = (utilization[0].component_load > estimate_total) ? utilization[0].component_load : estimate_total; // for very light loads, sometimes there is a measurement mismatch because of timing + utilization[0].subscribed = (reservation_set * (float)processor_cores) / 100.0 + utilization[0].component_load; + utilization[0].maximum = processor_cores-(__thresholds.cpu_idle/100.0) * processor_cores; + + LOG_DEBUG(GPP_i, __FUNCTION__ << " LOAD and IDLE : " << std::endl << + " modified_threshold(req+res)=" << modified_thresholds.cpu_idle << std::endl << " system: idle: " << system_monitor->get_idle_percent() << std::endl << " idle avg: " << system_monitor->get_idle_average() << std::endl << - " threshold: " << thresholds.cpu_idle << std::endl << - " modifier: " << idle_capacity_modifier << std::endl << - " reservations: " << reservations.size() << std::endl << - " loadCapacity_counter: " << loadCapacity_counter ); -} + " threshold(req): " << __thresholds.cpu_idle << std::endl << + " idle modifier: " << idle_capacity_modifier << std::endl << + " reserved_cap_per_component: " << reserved_capacity_per_component << std::endl << + " number of reservations: " << n_reservations << std::endl << + " processes: " << pids.size() << std::endl << + " loadCapacity: " << loadCapacity << std::endl << + " loadTotal: " << loadTotal << std::endl << + " loadFree(Modified): " << loadFree <getReport(); + LOG_TRACE(GPP_i, __FUNCTION__ << " SysInfo Load : " << std::endl << + " one: " << rpt.load.one_min << std::endl << + " five: " << rpt.load.five_min << std::endl << + " fifteen: " << rpt.load.fifteen_min << std::endl ); + + loadAverage.onemin = rpt.load.one_min; + loadAverage.fivemin = rpt.load.five_min; + loadAverage.fifteenmin = rpt.load.fifteen_min; + + memFree = rpt.virtual_memory_free / mem_free_units; + LOG_TRACE(GPP_i, __FUNCTION__ << "Memory : " << std::endl << + " sys_monitor.vit_total: " << rpt.virtual_memory_total << std::endl << + " sys_monitor.vit_free: " << rpt.virtual_memory_free << std::endl << + " sys_monitor.mem_total: " << rpt.physical_memory_total << std::endl << + " sys_monitor.mem_free: " << rpt.physical_memory_free << std::endl << + " memFree: " << memFree << std::endl << + " memCapacity: " << memCapacity << std::endl << + " memCapacityThreshold: " << memCapacityThreshold << std::endl << + " memInitCapacityPercent: " << memInitCapacityPercent << std::endl ); -void GPP_i::calculateSystemMemoryLoading() { - LOG_TRACE(GPP_i, __FUNCTION__ << ": memCapacity=" << memCapacity << " sys_monitor.get_mem_free=" << system_monitor->get_mem_free() ); - memCapacity = system_monitor->get_mem_free(); + // + // transfer limits to properties + // + const Limits::Contents &sys_rpt =rpt.sys_limits; + sys_limits.current_threads = sys_rpt.threads; + sys_limits.max_threads = sys_rpt.threads_limit; + sys_limits.current_open_files = sys_rpt.files; + sys_limits.max_open_files = sys_rpt.files_limit; + process_limits->update_state(); + const Limits::Contents &pid_rpt = process_limits->get(); + gpp_limits.current_threads = pid_rpt.threads; + gpp_limits.max_threads = pid_rpt.threads_limit; + gpp_limits.current_open_files = pid_rpt.files; + gpp_limits.max_open_files = pid_rpt.files_limit; } -void GPP_i::sigchld_handler(int sig) +int GPP_i::sigchld_handler(int sig) { - int status; - pid_t child_pid; - - while( (child_pid = waitpid(-1, &status, WNOHANG)) > 0 ) - { - try { - component_description retval; - if ( devicePtr) { - retval = devicePtr->getComponentDescription(child_pid); - sendChildNotification(retval.identifier, retval.appName); + // Check if any children died.... + fd_set readfds; + FD_ZERO(&readfds); + FD_SET(sig_fd, &readfds); + struct timeval tv = {0, 50}; + struct signalfd_siginfo si; + ssize_t s; + uint32_t cnt=1; + + if ( sig_fd > -1 ) { + // don't care about writefds and exceptfds: + while (true) { + FD_ZERO(&readfds); + FD_SET(sig_fd, &readfds); + select(sig_fd+1, &readfds, NULL, NULL, &tv); + if (FD_ISSET(sig_fd, &readfds)) { + LOG_TRACE(GPP_i, " Checking for signals from SIGNALFD(" << sig_fd << ") cnt:" << cnt++ ); + s = read(sig_fd, &si, sizeof(struct signalfd_siginfo)); + LOG_TRACE(GPP_i, " RETURN from SIGNALFD(" << sig_fd << ") cnt/ret:" << cnt << "/" << s ); + if (s != sizeof(struct signalfd_siginfo)){ + LOG_ERROR(GPP_i, "SIGCHLD handling error ..."); + break; } + + // + // for sigchld and signalfd + // if there are many SIGCHLD events that occur at that same time, the kernel + // can compress the event into a single process id...there for we need to + // try and waitpid for any process that have died. The process id + // reported might not require waitpid, so try and clean up outside the waitpid loop + // + // If a child dies, try to clean up tracking state for the resource. The _component_cleanup + // will issue a notification event message for non domain terminated resources.. ie. segfaults.. + // + if ( si.ssi_signo == SIGCHLD) { + LOG_TRACE(GPP_i, "Child died , pid .................................." << si.ssi_pid); + int status; + pid_t child_pid; + bool reap=false; + while( (child_pid = waitpid(-1, &status, WNOHANG)) > 0 ) { + LOG_TRACE(GPP_i, "WAITPID died , pid .................................." << child_pid); + if ( (uint)child_pid == si.ssi_pid ) reap=true; + _component_cleanup( child_pid, status ); + } + if ( !reap ) { + _component_cleanup( si.ssi_pid, status ); + } + } + else { + LOG_TRACE(GPP_i, "read from signalfd --> signo:" << si.ssi_signo); + } + } + else { break; - } catch ( ... ) { - try { - sendChildNotification("Unknown", "Unknown"); - } catch ( ... ) { + } + } + } + + //LOG_TRACE(GPP_i, "sigchld_handler RETURN.........loop cnt:" << cnt); + return NOOP; +} + + +int GPP_i::redirected_io_handler() +{ + // check if we should be handling io redirects + if ( !_handle_io_redirects || redirectedFds.size() == 0 ) { + return NOOP; + } + + // check we have a log file + if ( _componentOutputLog == "" ) { + LOG_DEBUG(GPP_i, " Component IO redirect ON but no file specified. "); + return NOOP; + } + + LOG_DEBUG(GPP_i, " Locking For Redirect Processing............. "); + ReadLock lock(fdsLock); + + int redirect_file = open(_componentOutputLog.c_str(), O_RDWR | O_CREAT , S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH ); + if ( redirect_file != -1 ) { + if ( lseek(redirect_file, 0, SEEK_END) == -1 ) { + LOG_DEBUG(GPP_i, " Unable to SEEK To file end, file: " << _componentOutputLog); + } + } + else { + LOG_TRACE(GPP_i, " Unable to open up componentOutputLog, fallback to /dev/null tried log: " << _componentOutputLog); + redirect_file = open("/dev/null", O_RDWR, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH ); + } + + size_t size = 0; + uint64_t cnt = 0; + uint64_t fopens = 0; + uint64_t fcloses = 0; + uint64_t nbytes = 0; + size_t result=0; + int rd_fd =0; + ProcessFds::iterator fd = redirectedFds.begin(); + for ( ; fd != redirectedFds.end() && _handle_io_redirects ; fd++ ) { + + // set default redirect to be master + rd_fd=redirect_file; + + // check if our pid is vaid + if ( fd->pid > 0 and fd->cout > -1 ) { + + // open up a specific redirect file + if ( fd->fname != "" && fd->fname != _componentOutputLog ) { + LOG_TRACE(GPP_i, " OPEN FILE - PID: " << fd->pid << " fname " << fd->fname); + rd_fd = open(fd->fname.c_str(), O_RDWR | O_CREAT , S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH ); + if ( rd_fd == -1 ) { + LOG_ERROR(GPP_i, " Unable to open component output log: " << fd->fname); + rd_fd = redirect_file; + } + else { + fopens++; + if ( lseek(rd_fd, 0, SEEK_END) == -1 ) { + LOG_DEBUG(GPP_i, " Unable to SEEK To file end, file: " << fd->fname); + } + } + } + + fd_set readfds; + FD_ZERO(&readfds); + FD_SET(fd->cout, &readfds); + struct timeval tv = {0, 50}; + select(fd->cout+1, &readfds, NULL, NULL, &tv); + if (FD_ISSET(fd->cout, &readfds)) { + + result=0; + size = 0; + if (ioctl (fd->cout, FIONREAD, &size) == -1) { + LOG_ERROR(GPP_i, "(redirected IO) Error requesting how much to read, PID: " << fd->pid << " FD:" << fd->cout ); + close(fd->cout); + fd->cout = -1; + } + if ( fd->cout != -1 && rd_fd != -1 ) { + LOG_TRACE(GPP_i, " SPLICE DATA From Child to Output SIZE " << size << "...... PID: " << fd->pid << " FD:" << fd->cout ); + result = splice( fd->cout, NULL, rd_fd, NULL, size,0 ); + LOG_TRACE(GPP_i, " SPLICE DATA From Child to Output RES:" << result << "... PID: " << fd->pid << " FD:" << fd->cout ); + } + if ( (int64_t)result == -1 ) { + LOG_ERROR(GPP_i, "(redirected IO) Error during transfer to redirected file, PID: " << fd->pid << " FD:" << fd->cout ); + close(fd->cout); + fd->cout = -1; + } + else { + nbytes += result; + cnt++; } } + } - - if( child_pid == -1 && errno != ECHILD ) - { - // Error - perror("waitpid"); + + /// close our per component redirected io file if we opened one + if ( rd_fd != -1 && rd_fd != redirect_file ) { + fcloses++; + close(rd_fd); } + } + + // close file while we wait + if ( redirect_file ) close(redirect_file); + LOG_DEBUG(GPP_i, " IO REDIRECT, NPROCS: "<< redirectedFds.size() << " OPEN/CLOSE " << fopens << "/" << fcloses <<" PROCESSED PROCS/Bytes " << cnt << "/" << nbytes ); + return NOOP; } + std::vector GPP_i::getPids() { - boost::mutex::scoped_lock lock(pidLock); + ReadLock lock(pidLock); std::vector keys; - for (ProcessMap::iterator it=pids.begin();it!=pids.end();it++) { - keys.push_back(it->first); + for (ProcessList::iterator it=pids.begin();it!=pids.end();it++) { + keys.push_back(it->pid); } return keys; } -void GPP_i::addPid(int pid, std::string appName, std::string identifier) +void GPP_i::addProcess(int pid, const std::string &appName, const std::string &identifier, const float req_reservation=1.0) { - boost::mutex::scoped_lock lock(pidLock); - if (pids.find(pid) == pids.end()) { - component_description tmp; - tmp.appName = appName; - tmp.identifier = identifier; - pids[pid] = tmp; - } + WriteLock lock(pidLock); + ProcessList:: iterator result = std::find_if( pids.begin(), pids.end(), std::bind2nd( FindPid(), pid ) ); + if ( result != pids.end() ) return; + + LOG_DEBUG(GPP_i, "START Adding Process/RES: " << pid << "/" << req_reservation << " APP:" << appName ); + component_description tmp; + tmp.appName = appName; + tmp.pid = pid; + tmp.identifier = identifier; + tmp.reservation = req_reservation; + tmp.core_usage = 0; + tmp.parent = this; + pids.push_front( tmp ); + if (applicationReservations.find(appName) != applicationReservations.end()) { + applicationReservations[appName].component_pids.push_back(pid); + } + LOG_DEBUG(GPP_i, "END Adding Process/RES: " << pid << "/" << req_reservation << " APP:" << appName ); } GPP_i::component_description GPP_i::getComponentDescription(int pid) { - boost::mutex::scoped_lock lock(pidLock); - ProcessMap::iterator it=pids.find(pid); + ReadLock lock(pidLock); + ProcessList:: iterator it = std::find_if( pids.begin(), pids.end(), std::bind2nd( FindPid(), pid ) ); if (it == pids.end()) throw std::invalid_argument("pid not found"); - return it->second; -} - -void GPP_i::removePid(int pid) -{ - boost::mutex::scoped_lock lock(pidLock); - ProcessMap::iterator it=pids.find(pid); - if (it == pids.end()) - return; - pids.erase(it); + return *it; } -void GPP_i::addReservation( const component_description &component) +void GPP_i::markPidTerminated( const int pid) { - boost::mutex::scoped_lock lock(pidLock); - this->reservations.push_back(component); + ReadLock lock(pidLock); + ProcessList:: iterator it = std::find_if( pids.begin(), pids.end(), std::bind2nd( FindPid(), pid ) ); + if (it == pids.end()) return; + LOG_DEBUG(GPP_i, " Mark For Termination: " << it->pid << " APP:" << it->appName ); + it->app_started= false; + it->terminated = true; } -void GPP_i::removeReservation( const component_description &component) +void GPP_i::removeProcess(int pid) { - boost::mutex::scoped_lock lock(pidLock); - ProcessList::iterator it = std::find(this->reservations.begin(), this->reservations.end(), component); - if (it != this->reservations.end()) { - this->reservations.erase(it); - } - it = std::find(this->tabled_reservations.begin(), this->tabled_reservations.end(), component); - if (it != this->tabled_reservations.end()) { - this->tabled_reservations.erase(it); - } -} -void GPP_i::tableReservation( const component_description &component) -{ - ProcessList::iterator it = std::find(this->reservations.begin(), this->reservations.end(), component); - if (it != this->reservations.end()) { - this->tabled_reservations.push_back(*it); - this->reservations.erase(it); + { + WriteLock wlock(pidLock); + ProcessList:: iterator result = std::find_if( pids.begin(), pids.end(), std::bind2nd( FindPid(), pid ) ); + if ( result != pids.end() ) { + LOG_DEBUG(GPP_i, "Monitor Process: REMOVE Process: " << result->pid << " app: " << result->appName ); + pids.erase(result); } -} + } -void GPP_i::restoreReservation( const component_description &component) -{ - ProcessList::iterator it = std::find(this->tabled_reservations.begin(), this->tabled_reservations.end(), component); - if (it != this->tabled_reservations.end()) { - this->reservations.push_back(*it); - this->tabled_reservations.erase(it); + { + WriteLock wlock(fdsLock); + ProcessFds::iterator i=std::find_if( redirectedFds.begin(), redirectedFds.end(), std::bind2nd( FindRedirect(), pid ) ); + if ( i != redirectedFds.end() ) { + i->close(); + LOG_DEBUG(GPP_i, "Redirectio IO ..REMOVE Redirected pid:" << pid ); + redirectedFds.erase(i); } + } + } - int GPP_i::_apply_affinity( const affinity_struct &nv, const pid_t rsc_pid, const char *rsc_name ) { @@ -1170,7 +2955,7 @@ int GPP_i::_apply_affinity( const pid_t rsc_pid, // apply affinity changes to the process try { - if ( redhawk::affinity::set_affinity( pol, rsc_pid, blcpus) != 0 ) { + if ( gpp::affinity::set_affinity( pol, rsc_pid, blcpus) != 0 ) { RH_NL_WARN("GPP", "Unable to set affinity for process, pid/name: " << rsc_pid << "/" << rsc_name ); } } @@ -1216,8 +3001,8 @@ bool GPP_i::_check_exec_partition( const std::string &iface ){ if ( (uint32_t)soc < execPartitions.size() ) { const exec_socket &ep = execPartitions[soc]; // get modified idle threshold value - double m_idle_thresh = ep.idle_threshold + ( ep.idle_cap_mod * reservations.size()) + - (float)loadCapacity_counter/(float)ep.cpus.size(); + double m_idle_thresh = ep.idle_threshold + ( ep.idle_cap_mod * n_reservations) + + (float)loadCapacity/(float)ep.cpus.size(); RH_NL_DEBUG("GPP", " Checking Execution Partition for an NIC interface iface/socket " << iface << "/" << soc << ") IDLE: actual/avg/threshold limit/modified " << ep.get_idle_percent() << "/" << ep.get_idle_average() << "/" << ep.idle_threshold << "/" << m_idle_thresh ); if ( ep.get_idle_percent() > m_idle_thresh ) { @@ -1239,8 +3024,8 @@ int GPP_i::_get_deploy_on_partition() { ExecPartitionList::iterator iter = execPartitions.begin(); for( ; iter != execPartitions.end(); iter++ ) { // get modified idle threshold value - double m_idle_thresh = iter->idle_threshold + ( iter->idle_cap_mod * reservations.size()) + - (float)loadCapacity_counter/(float)iter->cpus.size(); + double m_idle_thresh = iter->idle_threshold + ( iter->idle_cap_mod * n_reservations) + + (float)loadCapacity/(float)iter->cpus.size(); RH_NL_DEBUG("GPP", " Looking for execute partition (processor socket:" << iter->id << ") IDLE: actual/avg/threshold limit/modified " << iter->get_idle_percent() << "/" << iter->get_idle_average() << "/" << iter->idle_threshold << "/" << m_idle_thresh ); if ( iter->get_idle_percent() > m_idle_thresh ) { diff --git a/redhawk/src/testing/sdr/dev/devices/GPP/cpp/GPP.h b/redhawk/src/testing/sdr/dev/devices/GPP/cpp/GPP.h index bbc688d8c..d50b84e68 100644 --- a/redhawk/src/testing/sdr/dev/devices/GPP/cpp/GPP.h +++ b/redhawk/src/testing/sdr/dev/devices/GPP/cpp/GPP.h @@ -22,6 +22,8 @@ #include "GPP_base.h" #include +#include +#include #include "utils/Updateable.h" #include "reports/ThresholdMonitor.h" @@ -30,6 +32,7 @@ #include "statistics/CpuUsageStats.h" #include "reports/SystemMonitorReporting.h" #include "reports/CpuThresholdMonitor.h" +#include "reports/NicThroughputThresholdMonitor.h" #include "NicFacade.h" #include "ossie/Events.h" @@ -37,10 +40,27 @@ class ThresholdMonitor; class NicFacade; +#if BOOST_FILESYSTEM_VERSION < 3 +#define BOOST_PATH_STRING(x) (x) +#else +#define BOOST_PATH_STRING(x) (x).string() +#endif + +typedef boost::shared_mutex Lock; +typedef boost::unique_lock< Lock > WriteLock; +typedef boost::shared_lock< Lock > ReadLock; + + + class GPP_i : public GPP_base { - ENABLE_LOGGING + ENABLE_LOGGING; + + public: + static std::string format_up_time(unsigned long secondsUp); + + public: GPP_i(char *devMgr_ior, char *id, char *lbl, char *sftwrPrfl); GPP_i(char *devMgr_ior, char *id, char *lbl, char *sftwrPrfl, char *compDev); @@ -50,9 +70,7 @@ class GPP_i : public GPP_base int serviceFunction(); void initializeNetworkMonitor(); - void initializeMemoryMonitor(); - void initializeCpuMonitor(); - void addThresholdMonitor( ThresholdMonitor* threshold_monitor ); + void initializeResourceMonitors(); void send_threshold_event(const threshold_event_struct& message); void initialize() throw (CF::LifeCycle::InitializeError, CORBA::SystemException); @@ -60,182 +78,326 @@ class GPP_i : public GPP_base void deallocate_loadCapacity(const double &value); bool allocate_diskCapacity(const double &value); void deallocate_diskCapacity(const double &value); - bool allocate_memCapacity(const int64_t &value); - void deallocate_memCapacity(const int64_t &value); + bool allocate_memCapacity(const CORBA::LongLong &value); + void deallocate_memCapacity(const CORBA::LongLong &value); + bool allocate_reservation_request(const redhawk__reservation_request_struct &value); + void deallocate_reservation_request(const redhawk__reservation_request_struct &value); + bool allocate_mcastegress_capacity(const CORBA::Long &value); + void deallocate_mcastegress_capacity(const CORBA::Long &value); + bool allocate_mcastingress_capacity(const CORBA::Long &value); + void deallocate_mcastingress_capacity(const CORBA::Long &value); + + CF::ExecutableDevice::ProcessID_Type execute ( const char* name, + const CF::Properties& options, + const CF::Properties& parameters) + throw (CORBA::SystemException, CF::Device::InvalidState, CF::ExecutableDevice::InvalidFunction, + CF::ExecutableDevice::InvalidParameters, CF::ExecutableDevice::InvalidOptions, + CF::InvalidFileName, CF::ExecutableDevice::ExecuteFail); + + CF::ExecutableDevice::ProcessID_Type do_execute (const char* name, const CF::Properties& options, + const CF::Properties& parameters, + const std::vector prepend_args) + throw (CF::ExecutableDevice::ExecuteFail, + CF::InvalidFileName, CF::ExecutableDevice::InvalidOptions, + CF::ExecutableDevice::InvalidParameters, + CF::ExecutableDevice::InvalidFunction, CF::Device::InvalidState, + CORBA::SystemException); + - CF::ExecutableDevice::ProcessID_Type execute (const char* name, const CF::Properties& options, const CF::Properties& parameters) - throw (CORBA::SystemException, CF::Device::InvalidState, CF::ExecutableDevice::InvalidFunction, - CF::ExecutableDevice::InvalidParameters, CF::ExecutableDevice::InvalidOptions, - CF::InvalidFileName, CF::ExecutableDevice::ExecuteFail); void terminate (CF::ExecutableDevice::ProcessID_Type processId) throw (CORBA::SystemException, CF::ExecutableDevice::InvalidProcess, CF::Device::InvalidState); void updateThresholdMonitors(); - void calculateSystemMemoryLoading(); void sendChildNotification(const std::string &comp_id, const std::string &app_id); bool allocateCapacity_nic_allocation(const nic_allocation_struct &value); void deallocateCapacity_nic_allocation(const nic_allocation_struct &value); void deallocateCapacity (const CF::Properties& capacities) throw (CF::Device::InvalidState, CF::Device::InvalidCapacity, CORBA::SystemException); CORBA::Boolean allocateCapacity (const CF::Properties& capacities) throw (CF::Device::InvalidState, CF::Device::InvalidCapacity, CF::Device::InsufficientCapacity, CORBA::SystemException); void releaseObject() throw (CORBA::SystemException, CF::LifeCycle::ReleaseError); + + void postConstruction( std::string &softwareProfile, std::string ®istrar_ior, const std::string &idm_channel_ior="", const std::string &nic="", const int sigfd=-1 ); + int sigchld_handler( int sig ); - protected: - struct component_description { - std::string appName; - std::string identifier; - }; - - struct LoadCapacity { - float max; - float measured; - float allocated; + int redirected_io_handler( ); + + std::vector get_component_monitor(); + + struct proc_values { + float mem_rss; + CORBA::ULong num_threads; + int pgrpid; }; - - // - // base execution unit for partitioning a host system - // - struct exec_socket : public Updateable { - int id; - CpuUsageStats::CpuList cpus; - CpuUsageStats stats; - LoadCapacity load_capacity; - double idle_threshold; - double idle_cap_mod; - - exec_socket() : idle_threshold(0.0), idle_cap_mod(0.0) {}; - - void update() { - stats.compute_statistics(); - }; - - double get_idle_percent() const { - return stats.get_idle_percent(); - } - - double get_idle_average() const { - return stats.get_idle_average(); - } - - bool is_available() const { - return stats.get_idle_percent() > idle_threshold ; - }; + + struct grp_values : proc_values { + int num_processes; + std::vector pids; + }; + + void update_grp_child_pids(); + std::map parsed_stat; + std::map grp_children; + + struct proc_redirect { + int pid; + int cout; + int cerr; + std::string fname; + proc_redirect( int _pid, int _cout, int _cerr=-1 ); + proc_redirect( const std::string &fname, int _pid, int _cout, int _cerr=-1 ); + void close(); }; - - typedef std::vector< exec_socket > ExecPartitionList; - - - friend bool operator==( const component_description &, - const component_description & ); - - std::vector getPids(); - component_description getComponentDescription(int pid); - void set_resource_affinity( const CF::Properties& options, - const pid_t rsc_pid, - const char *rsc_name, - const std::vector &bl); + struct component_description { + static const int pstat_history_len=5; + int pid; + std::string appName; + std::string identifier; + bool app_started; + float reservation; + float core_usage; + bool terminated; + uint64_t pstat_history[pstat_history_len]; + uint8_t pstat_idx; + std::vector pids; + GPP_i *parent; + + component_description(); + component_description( const std::string &appId); + void add_history( int64_t ptime ); + void add_history(); + int64_t get_pstat_usage( const bool refresh=true ); + int64_t get_pstat_usage( uint64_t &p2, uint64_t &p1 ); + int64_t get_process_time(); + }; + struct application_reservation { + std::vector component_pids; + std::map reservation; + float usage; + }; - void process_ODM(const CORBA::Any &data); - void updateUsageState(); + void constructor(); - typedef boost::shared_ptr ThresholdMonitorPtr; - typedef std::vector< uint32_t > CpuList; - typedef std::vector< boost::shared_ptr > UpdateableSequence; - typedef std::vector > StateSequence; - typedef std::vector > StatisticsSequence; - typedef std::vector > ReportingSequence; - typedef std::vector< ThresholdMonitorPtr > MonitorSequence; - typedef boost::shared_ptr SystemMonitorPtr; - typedef std::map ProcessMap; - typedef std::vector< component_description > ProcessList; + protected: - void addPid(int pid, std::string appName, std::string identifier); - void removePid(int pid); - void addReservation(const component_description &component); - void removeReservation(const component_description &component); - void tableReservation(const component_description &component); - void restoreReservation(const component_description &component); - void reservedChanged(const float *oldValue, const float *newValue); - void establishModifiedThresholds(); - void sigchld_handler( int sig ); + + struct LoadCapacity { + float max; + float measured; + float allocated; + }; - ProcessList reservations; - ProcessList tabled_reservations; - ProcessMap pids; - boost::mutex pidLock; + // + // base execution unit for partitioning a host system + // + struct exec_socket : public Updateable { + int id; + CpuUsageStats::CpuList cpus; + CpuUsageStats stats; + LoadCapacity load_capacity; // future + double idle_threshold; + double idle_cap_mod; + + exec_socket() : idle_threshold(0.0), idle_cap_mod(0.0) {}; + + void update() { + stats.compute_statistics(); + }; + + double get_idle_percent() const { + return stats.get_idle_percent(); + } + + double get_idle_average() const { + return stats.get_idle_average(); + } + + bool is_available() const { + return stats.get_idle_percent() > idle_threshold ; + }; + }; - NicFacadePtr nic_facade; - MonitorSequence threshold_monitors; - SystemMonitorPtr system_monitor; - ExecPartitionList execPartitions; - double loadCapacity_counter; + typedef std::vector< exec_socket > ExecPartitionList; + + + friend bool operator==( const component_description &, + const component_description & ); + + std::vector getPids(); + component_description getComponentDescription(int pid); + void markPidTerminated(const int pid ); + + + void set_resource_affinity( const CF::Properties& options, + const pid_t rsc_pid, + const char *rsc_name, + const std::vector &bl= std::vector(0) ); + + + void process_ODM(const CORBA::Any &data); + + void updateUsageState(); + void setShadowThresholds(const thresholds_struct &newVals ); + + typedef boost::shared_ptr NicMonitorPtr; + typedef boost::shared_ptr ThresholdMonitorPtr; + typedef std::vector< uint32_t > CpuList; + typedef std::vector< boost::shared_ptr > UpdateableSequence; + typedef std::vector > StateSequence; + typedef std::vector > StatisticsSequence; + typedef std::vector > ReportingSequence; + typedef std::vector< ThresholdMonitorPtr > MonitorSequence; + typedef std::vector< NicMonitorPtr > NicMonitorSequence; + typedef boost::shared_ptr SystemMonitorPtr; + typedef std::map ProcessMap; + typedef std::deque< component_description > ProcessList; + typedef std::deque< proc_redirect > ProcessFds; + typedef std::map ApplicationReservationMap; + + void addProcess(int pid, + const std::string &appName, + const std::string &identifier, + const float req_reservation ); + void removeProcess(int pid ); + void addThresholdMonitor( ThresholdMonitorPtr threshold_monitor ); + void reservedChanged(const float *oldValue, const float *newValue); + void mcastnicThreshold_changed(const CORBA::Long *oldValue, const CORBA::Long *newValue); + void thresholds_changed(const thresholds_struct *oldValue, const thresholds_struct *newValue); + void update(); + + ProcessList pids; + size_t n_reservations; + Lock pidLock; + Lock fdsLock; + ProcessFds redirectedFds; + bool _handle_io_redirects; + std::string _componentOutputLog; + + Lock nicLock; + NicFacadePtr nic_facade; + MonitorSequence threshold_monitors; + NicMonitorSequence nic_monitors; + SystemMonitorPtr system_monitor; + ProcessLimitsPtr process_limits; + ExecPartitionList execPartitions; + ApplicationReservationMap applicationReservations; - UpdateableSequence data_model; - thresholds_struct modified_thresholds; - float idle_capacity_modifier; - CpuList wl_cpus; // list of allowable cpus to run on .... empty == all, derived from affnity blacklist property and host machine - CpuList bl_cpus; // list of blacklist cpus to avoid - - std::string binary_location; // path to this program. + Lock monitorLock; + UpdateableSequence data_model; + thresholds_struct __thresholds; + thresholds_struct modified_thresholds; + uint64_t thresh_mem_free_units; + uint64_t mem_free_units; + uint64_t mem_cap_units; + int64_t memCapacityThreshold; + double memInitCapacityPercent; + uint64_t memInitVirtFree; + float idle_capacity_modifier; + CpuList wl_cpus; // list of allowable cpus to run on .... empty == all, derived from affnity blacklist property and host machine + CpuList bl_cpus; // list of blacklist cpus to avoid + double mcastnicIngressThresholdValue; + double mcastnicEgressThresholdValue; + + std::string binary_location; // path to this program. + + boost::posix_time::ptime time_mark; // time marker for update + redhawk::events::SubscriberPtr odm_consumer; // interface that receives ODM_Channel events + redhawk::events::ManagerPtr mymgr; // interface to manage event channel access + + std::string _busy_reason; + boost::posix_time::ptime _busy_timestamp; // time when busy reason was initially set + boost::posix_time::ptime _busy_mark; // track message output + + private: + + // + // set the busy reason property for the GPP.. + // + void _resetReason(); + void _setReason( const std::string &reason, const std::string &event, const bool enable_timestamp = true ); + + bool _component_cleanup( const int pid, const int exit_status ); + + // + // setup execution partitions for launching components + // + int _setupExecPartitions( const CpuList &blacklist ); + + // + // apply specific affinity settings to a pid + // + int _apply_affinity( const pid_t rsc_pid, + const char *rsc_name, + const std::string &affinity_class, + const std::string &affinity_value, + const CpuList &bl_cpus ); - boost::posix_time::ptime time_mark; // time marker for update - redhawk::events::SubscriberPtr odm_consumer; // interface that receives ODM_Channel events - redhawk::events::ManagerPtr mymgr; // interface to manage event channel access - - - private: - - // - // setup execution partitions for launching components - // - int _setupExecPartitions( const CpuList &blacklist ); - - // - // apply specific affinity settings to a pid - // - int _apply_affinity( const pid_t rsc_pid, - const char *rsc_name, - const std::string &affinity_class, - const std::string &affinity_value, - const CpuList &bl_cpus ); + // + // apply affinity settings for affinity struct property + // + int _apply_affinity( const affinity_struct &affinity, const pid_t rsc_pid, const char *rsc_name ); + + // + // get the next available partition to use for luanching resources + // + int _get_deploy_on_partition(); + + // + // Check if execution partition for a NIC interface has enough processing capacity + // + bool _check_exec_partition( const std::string &iface ); + + // + // Callback when affinity processing structure is changed + // + void _affinity_changed(const affinity_struct *ov, const affinity_struct *nv ); + + // + // Callback when componentOutputLog is changed + // + void _component_output_changed(const std::string *ov, const std::string *nv ); + + // + // Set vlan list attribute + // + void _set_vlan_property(); + + // + // Determine list of CPUs that are monitored + // + void _set_processor_monitor_list( const CpuList &cl ); + + // + // expand special characters in consoleOutputLog + // + std::string _expand_parameters( const std::string &path ); + + // + // Common method called by all CTORs + // + void _init(); - // - // apply affinity settings for affinity struct property - // - int _apply_affinity( const affinity_struct &affinity, const pid_t rsc_pid, const char *rsc_name ); - - // - // get the next available partition to use for luanching resources - // - int _get_deploy_on_partition(); - - // - // Check if execution partition for a NIC interface has enough processing capacity - // - bool _check_exec_partition( const std::string &iface ); - - // - // Callback when affinity processing structure is changed - // - void _affinity_changed(const affinity_struct *ov, const affinity_struct *nv ); - - // - // Determine list of CPUs that are monitored - // - void _set_processor_monitor_list( const CpuList &cl ); - - // - // Common method called by all CTORs - // - void _init(); - -}; + // + // check file and thread limits for the process and system + // + bool _check_limits( const thresholds_struct &threshold); + + // + // check threshold limits for nic interfaces to determine busy state + // + bool _check_nic_thresholds(); + + std::string user_id; + int limit_check_count; + + ossie::ProcessThread _signalThread; + ossie::ProcessThread _redirectedIO; + }; #endif // GPP_IMPL_H diff --git a/redhawk/src/testing/sdr/dev/devices/GPP/cpp/GPP_base.cpp b/redhawk/src/testing/sdr/dev/devices/GPP/cpp/GPP_base.cpp index 78a94f830..eec942b0b 100644 --- a/redhawk/src/testing/sdr/dev/devices/GPP/cpp/GPP_base.cpp +++ b/redhawk/src/testing/sdr/dev/devices/GPP/cpp/GPP_base.cpp @@ -33,36 +33,40 @@ GPP_base::GPP_base(char *devMgr_ior, char *id, char *lbl, char *sftwrPrfl) : ExecutableDevice_impl(devMgr_ior, id, lbl, sftwrPrfl), ThreadedComponent() { - construct(); + construct(); } GPP_base::GPP_base(char *devMgr_ior, char *id, char *lbl, char *sftwrPrfl, char *compDev) : ExecutableDevice_impl(devMgr_ior, id, lbl, sftwrPrfl, compDev), ThreadedComponent() { - construct(); + construct(); } GPP_base::GPP_base(char *devMgr_ior, char *id, char *lbl, char *sftwrPrfl, CF::Properties capacities) : ExecutableDevice_impl(devMgr_ior, id, lbl, sftwrPrfl, capacities), ThreadedComponent() { - construct(); + construct(); } GPP_base::GPP_base(char *devMgr_ior, char *id, char *lbl, char *sftwrPrfl, CF::Properties capacities, char *compDev) : ExecutableDevice_impl(devMgr_ior, id, lbl, sftwrPrfl, capacities, compDev), ThreadedComponent() { - construct(); + construct(); } GPP_base::~GPP_base() { - delete propEvent; - propEvent = 0; - delete MessageEvent_out; - MessageEvent_out = 0; + if (propEvent) { + delete propEvent; + propEvent = 0; + } + if ( MessageEvent_out ) { + delete MessageEvent_out; + MessageEvent_out = 0; + } } void GPP_base::construct() @@ -118,15 +122,15 @@ void GPP_base::loadProperties() "readonly", "", "eq", - "allocation,configure"); + "property,allocation,configure"); addProperty(device_model, "DCE:0f99b2e4-9903-4631-9846-ff349d18ecfb", "device_model", "readonly", - "", + "REDHAWK GPP", "eq", - "allocation,configure"); + "property,allocation,configure"); addProperty(processor_name, "DCE:fefb9c66-d14a-438d-ad59-2cfd1adb272b", @@ -134,7 +138,7 @@ void GPP_base::loadProperties() "readonly", "", "eq", - "allocation,configure"); + "property,allocation,configure"); addProperty(os_name, "DCE:4a23ad60-0b25-4121-a630-68803a498f75", @@ -142,7 +146,7 @@ void GPP_base::loadProperties() "readonly", "", "eq", - "allocation,configure"); + "property,allocation,configure"); addProperty(os_version, "DCE:0f3a9a37-a342-43d8-9b7f-78dc6da74192", @@ -150,7 +154,7 @@ void GPP_base::loadProperties() "readonly", "", "eq", - "allocation,configure"); + "property,allocation,configure"); addProperty(hostName, "DCE:9190eb70-bd1e-4556-87ee-5a259dcfee39", @@ -158,7 +162,7 @@ void GPP_base::loadProperties() "readonly", "", "external", - "configure,event"); + "property,configure,event"); addProperty(useScreen, false, @@ -169,65 +173,94 @@ void GPP_base::loadProperties() "external", "execparam"); - addProperty(loadCapacity, - "DCE:72c1c4a9-2bcf-49c5-bafd-ae2c1d567056", - "loadCapacity", + addProperty(componentOutputLog, + "DCE:c80f6c5a-e3ea-4f57-b0aa-46b7efac3176", + "componentOutputLog", "readwrite", "", "external", - "allocation"); + "property"); - addProperty(mcastnicIngressCapacity, - "DCE:506102d6-04a9-4532-9420-a323d818ddec", - "mcastnicIngressCapacity", + addProperty(mcastnicInterface, + "", + "DCE:4e416acc-3144-47eb-9e38-97f1d24f7700", + "mcastnicInterface", + "readwrite", + "", + "external", + "execparam"); + + addProperty(mcastnicIngressTotal, + 0, + "DCE:5a41c2d3-5b68-4530-b0c4-ae98c26c77ec", + "mcastnicIngressTotal", "readwrite", "Mb/s", "external", - "allocation"); + "execparam"); - addProperty(memCapacity, - "DCE:8dcef419-b440-4bcf-b893-cab79b6024fb", - "memCapacity", + addProperty(mcastnicEgressTotal, + 0, + "DCE:442d5014-2284-4f46-86ae-ce17e0749da0", + "mcastnicEgressTotal", "readwrite", - "MiB", + "Mb/s", "external", - "allocation"); + "execparam"); - addProperty(loadCapacityPerCore, - 1.0, - "DCE:3bf07b37-0c00-4e2a-8275-52bd4e391f07", - "loadCapacityPerCore", + addProperty(mcastnicIngressCapacity, + 0, + "DCE:506102d6-04a9-4532-9420-a323d818ddec", + "mcastnicIngressCapacity", "readwrite", - "", - "gt", - "allocation,execparam"); + "Mb/s", + "external", + "allocation,event"); - addProperty(reserved_capacity_per_component, - 0.25, - "reserved_capacity_per_component", - "", + addProperty(mcastnicEgressCapacity, + 0, + "DCE:eb08e43f-11c7-45a0-8750-edff439c8b24", + "mcastnicEgressCapacity", "readwrite", - "", + "Mb/s", "external", - "configure"); + "allocation,event"); - addProperty(processor_cores, - "processor_cores", - "", + addProperty(mcastnicIngressFree, + 0, + "DCE:0b57a27a-8fa2-412b-b0ae-010618b8f40e", + "mcastnicIngressFree", "readonly", - "", + "Mb/s", "external", - "configure"); + "configure,event"); - addProperty(loadThreshold, + addProperty(mcastnicEgressFree, + 0, + "DCE:9b5bbdcb-1894-4b95-847c-787f121c05ae", + "mcastnicEgressFree", + "readonly", + "Mb/s", + "external", + "configure,event"); + + addProperty(mcastnicThreshold, 80, - "DCE:22a60339-b66e-4309-91ae-e9bfed6f0490", - "loadThreshold", + "DCE:89be90ae-6a83-4399-a87d-5f4ae30ef7b1", + "mcastnicThreshold", "readwrite", "%", "external", "configure,event"); + addProperty(mcastnicVLANs, + "DCE:65544aad-4c73-451f-93de-d4d76984025a", + "mcastnicVLANs", + "readwrite", + "", + "external", + "allocation"); + // Set the sequence with its initial values nic_interfaces.push_back("e.*"); addProperty(nic_interfaces, @@ -237,7 +270,7 @@ void GPP_base::loadProperties() "readwrite", "", "external", - "configure"); + "configure,property"); addProperty(available_nic_interfaces, "available_nic_interfaces", @@ -265,6 +298,47 @@ void GPP_base::loadProperties() "external", "configure"); + addProperty(nic_allocation_status, + "nic_allocation_status", + "", + "readonly", + "", + "external", + "configure"); + + addProperty(nic_metrics, + "nic_metrics", + "", + "readonly", + "", + "external", + "configure"); + + addProperty(networkMonitor, + "networkMonitor", + "", + "readonly", + "", + "external", + "configure"); + + addProperty(component_monitor, + "component_monitor", + "", + "readonly", + "", + "external", + "property"); + + addProperty(affinity, + affinity_struct(), + "affinity", + "", + "readwrite", + "", + "external", + "property"); + addProperty(threshold_event, threshold_event_struct(), "threshold_event", @@ -274,6 +348,30 @@ void GPP_base::loadProperties() "external", "message"); + addProperty(busy_reason, + "busy_reason", + "", + "readonly", + "", + "external", + "property"); + + addProperty(cacheDirectory, + "cacheDirectory", + "", + "readonly", + "", + "external", + "property"); + + addProperty(workingDirectory, + "workingDirectory", + "", + "readonly", + "", + "external", + "property"); + addProperty(thresholds, thresholds_struct(), "thresholds", @@ -281,26 +379,45 @@ void GPP_base::loadProperties() "readwrite", "", "external", - "property,configure"); + "property"); - addProperty(nic_allocation_status, - "nic_allocation_status", + addProperty(threshold_cycle_time, + 500, + "threshold_cycle_time", + "threshold_cycle_time", + "readwrite", + "milliseconds", + "external", + "property"); + + addProperty(gpp_limits, + ulimit_struct(), + "gpp_limits", "", "readonly", "", "external", - "configure"); + "property"); - addProperty(nic_metrics, - "nic_metrics", + addProperty(sys_limits, + sys_limits_struct(), + "sys_limits", "", "readonly", "", "external", - "configure"); + "property"); - addProperty(networkMonitor, - "networkMonitor", + addProperty(utilization, + "utilization", + "", + "readonly", + "", + "external", + "property"); + + addProperty(processor_cores, + "processor_cores", "", "readonly", "", @@ -315,24 +432,91 @@ void GPP_base::loadProperties() "external", "configure"); - addProperty(affinity, - affinity_struct(), - "affinity", + addProperty(memFree, + "DCE:6565bffd-cb09-4927-9385-2ecac68035c7", + "memFree", + "readonly", + "MiB", + "external", + "configure,event"); + + addProperty(memCapacity, + "DCE:8dcef419-b440-4bcf-b893-cab79b6024fb", + "memCapacity", + "readwrite", + "MiB", + "external", + "allocation,event"); + + addProperty(reserved_capacity_per_component, + 0.1, + "reserved_capacity_per_component", + "reserved_capacity_per_component", + "readwrite", "", + "external", + "configure"); + + addProperty(loadTotal, + "DCE:28b23bc8-e4c0-421b-9c52-415a24715209", + "loadTotal", + "readonly", + "", + "external", + "configure"); + + addProperty(loadThreshold, + 80, + "DCE:22a60339-b66e-4309-91ae-e9bfed6f0490", + "loadThreshold", + "readwrite", + "%", + "external", + "configure,event"); + + addProperty(loadCapacityPerCore, + 1.0, + "DCE:3bf07b37-0c00-4e2a-8275-52bd4e391f07", + "loadCapacityPerCore", "readwrite", "", + "gt", + "allocation,execparam"); + + addProperty(loadFree, + "DCE:6c000787-6fea-4765-8686-2e051e6c24b0", + "loadFree", + "readonly", + "", "external", - "configure,property"); + "configure,event"); + addProperty(loadCapacity, + "DCE:72c1c4a9-2bcf-49c5-bafd-ae2c1d567056", + "loadCapacity", + "readwrite", + "", + "external", + "allocation,event"); - addProperty(threshold_cycle_time, - 500, - "threshold_cycle_time", - "threshold_cycle_time", + addProperty(loadAverage, + loadAverage_struct(), + "DCE:9da85ebc-6503-48e7-af36-b77c7ad0c2b4", + "loadAverage", + "readonly", + "", + "external", + "property"); + + addProperty(redhawk__reservation_request, + redhawk__reservation_request_struct(), + "redhawk::reservation_request", + "", "readwrite", - "milliseconds", + "", "external", - "property,configure"); + "allocation"); + } diff --git a/redhawk/src/testing/sdr/dev/devices/GPP/cpp/GPP_base.h b/redhawk/src/testing/sdr/dev/devices/GPP/cpp/GPP_base.h index 40e4bce27..3ffa5910d 100644 --- a/redhawk/src/testing/sdr/dev/devices/GPP/cpp/GPP_base.h +++ b/redhawk/src/testing/sdr/dev/devices/GPP/cpp/GPP_base.h @@ -53,30 +53,74 @@ class GPP_base : public ExecutableDevice_impl, protected ThreadedComponent std::string os_name; std::string os_version; std::string hostName; + std::string componentOutputLog; bool useScreen; - double loadCapacity; - CORBA::Long mcastnicIngressCapacity; - CORBA::LongLong memCapacity; - double loadCapacityPerCore; - float reserved_capacity_per_component; - short processor_cores; - CORBA::Long loadThreshold; + advanced_struct advanced; + std::vector nic_interfaces; std::vector available_nic_interfaces; nic_allocation_struct nic_allocation; - advanced_struct advanced; - threshold_event_struct threshold_event; - thresholds_struct thresholds; + std::string mcastnicInterface; + CORBA::Long mcastnicIngressTotal; + CORBA::Long mcastnicEgressTotal; + CORBA::Long mcastnicIngressCapacity; + CORBA::Long mcastnicEgressCapacity; + CORBA::Long mcastnicIngressFree; + CORBA::Long mcastnicEgressFree; + CORBA::Long mcastnicThreshold; + std::vector mcastnicVLANs; std::vector nic_allocation_status; std::vector nic_metrics; std::vector networkMonitor; + std::vector component_monitor; + + // reporting struct when a threshold is broke + threshold_event_struct threshold_event; + // threshold items to watch + thresholds_struct thresholds; + /// Property to annotate why the system is busy + std::string busy_reason; + /// Property to select a cache directory other than the default + std::string cacheDirectory; + /// Property to select a working directory other than the default + std::string workingDirectory; + // time between cycles to refresh threshold metrics + CORBA::ULong threshold_cycle_time; + // ulimits for the GPP process + ulimit_struct gpp_limits; + // ulimits for the system as a whole + sys_limits_struct sys_limits; + /// Property: memFree + CORBA::LongLong memFree; + /// Property: memCapacity + CORBA::LongLong memCapacity; + /// Property: loadTotal + double loadTotal; + /// Property: loadThreshold + CORBA::Long loadThreshold; + /// Property: loadCapacityPerCore + double loadCapacityPerCore; + /// Property: loadFree + double loadFree; + /// Property: loadCapacity + double loadCapacity; + /// Property: loadAverage + loadAverage_struct loadAverage; + /// Property: reserved capacity per core for reservation schema + float reserved_capacity_per_component; + /// Property processor_cores - number of cores the machine supports + short processor_cores; + /// Property: redhawk__reservation_request + redhawk__reservation_request_struct redhawk__reservation_request; + /// Property processor_monitor_list - list of the cores we are watching.. std::string processor_monitor_list; + // Property affinity - controls affinity processing for the GPP affinity_struct affinity; - CORBA::ULong threshold_cycle_time; // Ports PropertyEventSupplier *propEvent; MessageSupplierPort *MessageEvent_out; + std::vector utilization; private: void construct(); diff --git a/redhawk/src/testing/sdr/dev/devices/GPP/cpp/Makefile.am b/redhawk/src/testing/sdr/dev/devices/GPP/cpp/Makefile.am index 5573f79be..fdf619c16 100644 --- a/redhawk/src/testing/sdr/dev/devices/GPP/cpp/Makefile.am +++ b/redhawk/src/testing/sdr/dev/devices/GPP/cpp/Makefile.am @@ -42,6 +42,8 @@ reports/SystemMonitorReporting.cpp \ reports/SystemMonitorReporting.h \ reports/CpuThresholdMonitor.cpp \ reports/CpuThresholdMonitor.h \ +parsers/PidProcStatParser.cpp \ +parsers/PidProcStatParser.h \ parsers/ProcStatFileParser.cpp \ parsers/ProcStatFileParser.h \ parsers/ProcStatParser.cpp \ @@ -50,6 +52,8 @@ parsers/ProcMeminfoParser.cpp \ parsers/ProcMeminfoParser.h \ states/NicState.cpp \ states/NicState.h \ +states/Limits.cpp \ +states/Limits.h \ states/State.h \ states/CpuState.cpp \ states/CpuState.h \ @@ -65,6 +69,8 @@ statistics/NicAccumulator.cpp \ statistics/NicAccumulator.h \ statistics/Statistics.h \ struct_props.h \ +utils/popen.cpp \ +utils/popen.h \ utils/affinity.cpp \ utils/affinity.h \ utils/CmdlineExecutor.cpp \ @@ -80,4 +86,4 @@ utils/ReferenceWrapper.h \ utils/SymlinkReader.cpp \ utils/SymlinkReader.h GPP_CXXFLAGS = -Wall $(BOOST_CPPFLAGS) -I$(CFDIR)/include -I$(CFDIR)/include/ossie -GPP_LDADD = $(BOOST_REGEX_LIB) $(BOOST_SYSTEM_LIB) $(BOOST_FILESYSTEM_LIB) $(BOOST_THREAD_LIB) $(OMNIDYNAMIC_LIBS) $(OMNICOS_LIBS) $(CFDIR)/framework/libossiecf.la $(CFDIR)/framework/idl/libossieidl.la +GPP_LDADD = $(BOOST_REGEX_LIB) $(BOOST_SYSTEM_LIB) $(BOOST_FILESYSTEM_LIB) $(BOOST_THREAD_LIB) -lboost_iostreams $(OMNIDYNAMIC_LIBS) $(OMNICOS_LIBS) $(CFDIR)/framework/libossiecf.la $(CFDIR)/framework/idl/libossieidl.la diff --git a/redhawk/src/testing/sdr/dev/devices/GPP/cpp/NicFacade.cpp b/redhawk/src/testing/sdr/dev/devices/GPP/cpp/NicFacade.cpp index c82c10457..ec81374b0 100644 --- a/redhawk/src/testing/sdr/dev/devices/GPP/cpp/NicFacade.cpp +++ b/redhawk/src/testing/sdr/dev/devices/GPP/cpp/NicFacade.cpp @@ -28,6 +28,7 @@ #include #include +#include #if BOOST_FILESYSTEM_VERSION < 3 #define BOOST_PATH_STRING(x) (x) @@ -97,6 +98,12 @@ NicFacade::poll_nic_interfaces() const tmp << BOOST_PATH_STRING(iter->path()); boost::filesystem::path test_file( tmp.str() + "/statistics/rx_bytes" ); + std::string operstate = tmp.str()+"/operstate"; + std::ifstream fp(operstate.c_str()); + std::string _state; + std::getline(fp, _state); + if (_state==std::string("down")) continue; + if(boost::filesystem::is_regular_file(test_file)) { interfaces.push_back( BOOST_PATH_STRING(iter->path().filename()) ); @@ -320,6 +327,18 @@ NicFacade::get_devices() const return devices; } +std::vector +NicFacade::get_filtered_devices() const +{ + std::vector devices; + NicStates::const_iterator i; + for( i=filtered_nic_states_.begin(); i!=filtered_nic_states_.end(); ++i ) + { + devices.push_back(i->first); + } + return devices; +} + float NicFacade::get_throughput_by_device( const std::string& device ) const { diff --git a/redhawk/src/testing/sdr/dev/devices/GPP/cpp/NicFacade.h b/redhawk/src/testing/sdr/dev/devices/GPP/cpp/NicFacade.h index 30adb77b2..6c6ce4ca2 100644 --- a/redhawk/src/testing/sdr/dev/devices/GPP/cpp/NicFacade.h +++ b/redhawk/src/testing/sdr/dev/devices/GPP/cpp/NicFacade.h @@ -58,6 +58,7 @@ class NicFacade : public Reporting void report(); std::vector get_devices() const; + std::vector get_filtered_devices() const; float get_throughput_by_device( const std::string& device ) const; double get_throughput_by_device_bps( const std::string& device ) const; diff --git a/redhawk/src/testing/sdr/dev/devices/GPP/cpp/affinity_struct.h b/redhawk/src/testing/sdr/dev/devices/GPP/cpp/affinity_struct.h index 33b5f6ef4..8278b0006 100644 --- a/redhawk/src/testing/sdr/dev/devices/GPP/cpp/affinity_struct.h +++ b/redhawk/src/testing/sdr/dev/devices/GPP/cpp/affinity_struct.h @@ -2,14 +2,14 @@ * This file is protected by Copyright. Please refer to the COPYRIGHT file * distributed with this source distribution. * - * This file is part of REDHAWK core. + * This file is part of REDHAWK GPP. * - * REDHAWK core is free software: you can redistribute it and/or modify it + * REDHAWK GPP is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your * option) any later version. * - * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * REDHAWK GPP is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * for more details. diff --git a/redhawk/src/testing/sdr/dev/devices/GPP/cpp/main.cpp b/redhawk/src/testing/sdr/dev/devices/GPP/cpp/main.cpp index 5b8eb3450..daa55b31d 100644 --- a/redhawk/src/testing/sdr/dev/devices/GPP/cpp/main.cpp +++ b/redhawk/src/testing/sdr/dev/devices/GPP/cpp/main.cpp @@ -2,14 +2,14 @@ * This file is protected by Copyright. Please refer to the COPYRIGHT file * distributed with this source distribution. * - * This file is part of REDHAWK core. + * This file is part of REDHAWK GPP. * - * REDHAWK core is free software: you can redistribute it and/or modify it + * REDHAWK GPP is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your * option) any later version. * - * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * REDHAWK GPP is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * for more details. @@ -36,11 +36,11 @@ void signal_catcher(int sig) } int main(int argc, char* argv[]) { - // // Install signal handler for processing SIGCHLD through // signal file descriptor to avoid whitelist/blacklist function calls // + // add command line arg, to setup signalfd in start_device std::vector gpp_argv(argv, argv+argc); gpp_argv.push_back("USESIGFD"); @@ -50,6 +50,7 @@ int main(int argc, char* argv[]) } struct sigaction sa; + sigemptyset(&sa.sa_mask); sa.sa_handler = signal_catcher; sa.sa_flags = 0; devicePtr = 0; diff --git a/redhawk/src/testing/sdr/dev/devices/GPP/cpp/parsers/ProcMeminfoParser.cpp b/redhawk/src/testing/sdr/dev/devices/GPP/cpp/parsers/ProcMeminfoParser.cpp index 36abbf2f3..781fedf12 100644 --- a/redhawk/src/testing/sdr/dev/devices/GPP/cpp/parsers/ProcMeminfoParser.cpp +++ b/redhawk/src/testing/sdr/dev/devices/GPP/cpp/parsers/ProcMeminfoParser.cpp @@ -89,14 +89,13 @@ void ProcMeminfoParser::parse( ProcMeminfo::Contents & data ) if ( values.size() >= 3 ) { std::string units(values[2]); boost::to_upper(units); - if ( units == "KB" ) unit_m = 1e3; - if ( units == "MB" ) unit_m = 1e6; - if ( units == "GB" ) unit_m = 1e9; - if ( units == "TB" ) unit_m = 1e12; + if ( units == "KB" ) unit_m = 1024; + if ( units == "MB" ) unit_m = 1024*1024; + if ( units == "GB" ) unit_m = 1024*1024*1024; + if ( units == "TB" ) unit_m = (uint64_t)1024*1024*1024*1024; } metric = metric * unit_m; - data[key]=metric; } diff --git a/redhawk/src/testing/sdr/dev/devices/GPP/cpp/parsers/ProcStatParser.cpp b/redhawk/src/testing/sdr/dev/devices/GPP/cpp/parsers/ProcStatParser.cpp index 5a439750c..5a03062c9 100644 --- a/redhawk/src/testing/sdr/dev/devices/GPP/cpp/parsers/ProcStatParser.cpp +++ b/redhawk/src/testing/sdr/dev/devices/GPP/cpp/parsers/ProcStatParser.cpp @@ -27,7 +27,6 @@ #include "ProcStatParser.h" #include "ParserExceptions.h" - #ifdef DEBUG_ON #define DEBUG(x) x #else diff --git a/redhawk/src/testing/sdr/dev/devices/GPP/cpp/reports/FreeMemoryThresholdMonitor.cpp b/redhawk/src/testing/sdr/dev/devices/GPP/cpp/reports/FreeMemoryThresholdMonitor.cpp index f025dc5f3..e2cff7770 100644 --- a/redhawk/src/testing/sdr/dev/devices/GPP/cpp/reports/FreeMemoryThresholdMonitor.cpp +++ b/redhawk/src/testing/sdr/dev/devices/GPP/cpp/reports/FreeMemoryThresholdMonitor.cpp @@ -2,14 +2,14 @@ * This file is protected by Copyright. Please refer to the COPYRIGHT file * distributed with this source distribution. * - * This file is part of REDHAWK core. + * This file is part of REDHAWK GPP. * - * REDHAWK core is free software: you can redistribute it and/or modify it + * REDHAWK GPP is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your * option) any later version. * - * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * REDHAWK GPP is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * for more details. @@ -21,7 +21,7 @@ #include "utils/ReferenceWrapper.h" FreeMemoryThresholdMonitor::FreeMemoryThresholdMonitor( const std::string& source_id, QueryFunction threshold, QueryFunction measured ): -GenericThresholdMonitor(source_id, GetResourceId(), GetMessageClass(), threshold, measured ) +GenericThresholdMonitor(source_id, GetResourceId(), GetMessageClass(), threshold, measured ) { } diff --git a/redhawk/src/testing/sdr/dev/devices/GPP/cpp/reports/FreeMemoryThresholdMonitor.h b/redhawk/src/testing/sdr/dev/devices/GPP/cpp/reports/FreeMemoryThresholdMonitor.h index 9af3eef0e..46498ee9e 100644 --- a/redhawk/src/testing/sdr/dev/devices/GPP/cpp/reports/FreeMemoryThresholdMonitor.h +++ b/redhawk/src/testing/sdr/dev/devices/GPP/cpp/reports/FreeMemoryThresholdMonitor.h @@ -2,14 +2,14 @@ * This file is protected by Copyright. Please refer to the COPYRIGHT file * distributed with this source distribution. * - * This file is part of REDHAWK core. + * This file is part of REDHAWK GPP. * - * REDHAWK core is free software: you can redistribute it and/or modify it + * REDHAWK GPP is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your * option) any later version. * - * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * REDHAWK GPP is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * for more details. @@ -19,42 +19,16 @@ */ #ifndef FREE_MEMORY_THRESHOLD_MONITOR_H_ #define FREE_MEMORY_THRESHOLD_MONITOR_H_ -#include #include "ThresholdMonitor.h" -template< class REFERENCE_TYPE, class RETURN_TYPE=REFERENCE_TYPE, class ctype=uint64_t, class CFUNC=std::divides< RETURN_TYPE > > -class ConversionWrapper - { - public: - typedef REFERENCE_TYPE type; - typedef RETURN_TYPE result_type; - typedef void argument_type; - typedef CFUNC opfunc; - - explicit ConversionWrapper( type& ref, ctype cf=1048576, const opfunc &func=std::divides< result_type >() ): - ref_(ref), func_(func), unit_conversion_(cf) - {}; - - result_type operator()() const { - return func_( static_cast(ref_), (result_type)unit_conversion_ ); - }; - - type& get() const { return ref_; }; - - private: - type &ref_; - opfunc func_; - ctype unit_conversion_; - - }; - -class FreeMemoryThresholdMonitor : public GenericThresholdMonitor +class FreeMemoryThresholdMonitor : public GenericThresholdMonitor { public: - FreeMemoryThresholdMonitor( const std::string& source_id, QueryFunction threshold, QueryFunction measured ) ; - static std::string GetResourceId(){ return "physical_ram"; } - static std::string GetMessageClass(){ return "MEMORY_FREE"; } + FreeMemoryThresholdMonitor( const std::string& source_id, QueryFunction threshold, QueryFunction measured ) ; + + static std::string GetResourceId(){ return "physical_ram"; } + static std::string GetMessageClass(){ return "MEMORY_FREE"; } }; diff --git a/redhawk/src/testing/sdr/dev/devices/GPP/cpp/reports/NicThroughputThresholdMonitor.cpp b/redhawk/src/testing/sdr/dev/devices/GPP/cpp/reports/NicThroughputThresholdMonitor.cpp index 4c8203f20..4b297dc67 100644 --- a/redhawk/src/testing/sdr/dev/devices/GPP/cpp/reports/NicThroughputThresholdMonitor.cpp +++ b/redhawk/src/testing/sdr/dev/devices/GPP/cpp/reports/NicThroughputThresholdMonitor.cpp @@ -21,6 +21,6 @@ #include "../utils/ReferenceWrapper.h" NicThroughputThresholdMonitor::NicThroughputThresholdMonitor( const std::string& source_id, const std::string& resource_id, NicThroughputThresholdMonitor::QueryFunction threshold, NicThroughputThresholdMonitor::QueryFunction measured ): -GenericThresholdMonitor >(source_id, resource_id, GetMessageClass(), threshold, measured ) +GenericThresholdMonitor >(source_id, resource_id, GetMessageClass(), threshold, measured ) { } diff --git a/redhawk/src/testing/sdr/dev/devices/GPP/cpp/reports/NicThroughputThresholdMonitor.h b/redhawk/src/testing/sdr/dev/devices/GPP/cpp/reports/NicThroughputThresholdMonitor.h index c6a209e25..9928980bf 100644 --- a/redhawk/src/testing/sdr/dev/devices/GPP/cpp/reports/NicThroughputThresholdMonitor.h +++ b/redhawk/src/testing/sdr/dev/devices/GPP/cpp/reports/NicThroughputThresholdMonitor.h @@ -22,7 +22,7 @@ #include "ThresholdMonitor.h" -class NicThroughputThresholdMonitor : public GenericThresholdMonitor > +class NicThroughputThresholdMonitor : public GenericThresholdMonitor > { public: NicThroughputThresholdMonitor( const std::string& source_id, const std::string& resource_id, QueryFunction threshold, QueryFunction measured ); diff --git a/redhawk/src/testing/sdr/dev/devices/GPP/cpp/reports/SystemMonitorReporting.cpp b/redhawk/src/testing/sdr/dev/devices/GPP/cpp/reports/SystemMonitorReporting.cpp index f8aba55d0..c17aea267 100644 --- a/redhawk/src/testing/sdr/dev/devices/GPP/cpp/reports/SystemMonitorReporting.cpp +++ b/redhawk/src/testing/sdr/dev/devices/GPP/cpp/reports/SystemMonitorReporting.cpp @@ -27,10 +27,20 @@ static const size_t BYTES_PER_MEGABYTE = 1024*1024; +SystemMonitor::SystemMonitor( const CpuList & cpu_list, const int nhistory ): + cpu_usage_stats_( new CpuUsageStats(cpu_list,nhistory) ), + mem_usage_state_(new ProcMeminfo()), + sys_limit_state_(new SysLimits()) +{ + report(); +} + SystemMonitor::SystemMonitor( const CpuStatsPtr & cpu_usage_stats, - const MemInfoPtr &mem_usage_state ) : + const MemInfoPtr &mem_usage_state, + const SysLimitsPtr &sys_limit ) : cpu_usage_stats_(cpu_usage_stats), - mem_usage_state_(mem_usage_state) + mem_usage_state_(mem_usage_state), + sys_limit_state_(sys_limit) { report(); } @@ -44,66 +54,72 @@ double SystemMonitor::get_idle_average() const { } uint64_t SystemMonitor::get_mem_free() const { - return report_.physical_memory_free; + return report_.virtual_memory_free; +} + +uint64_t SystemMonitor::get_phys_free() const { + return report_.physical_memory_free; +} + +uint64_t SystemMonitor::get_all_usage() const { + return report_.all_usage; +} + +uint64_t SystemMonitor::get_user_usage() const { + return report_.user_usage; +} + +double SystemMonitor::get_loadavg() const { + return report_.load.one_min; } const SystemMonitor::Report &SystemMonitor::getReport() const { return report_; } +const SystemMonitor::CpuStatsPtr SystemMonitor::getCpuStats() const { + return cpu_usage_stats_; +} + void SystemMonitor::report() { - cpu_usage_stats_->update(); - mem_usage_state_->update(); + struct sysinfo info; + sysinfo(&info); + try { - ProcMeminfo::Counter total_memory = mem_usage_state_->getMetric("CommitLimit"); - ProcMeminfo::Counter committed_memory = mem_usage_state_->getMetric("Committed_AS"); - report_.physical_memory_free = (double)(total_memory - committed_memory); + cpu_usage_stats_->update(); + mem_usage_state_->update(); + sys_limit_state_->update(); + const ProcMeminfo::Contents &mem_stats = mem_usage_state_->get(); + report_.virtual_memory_total = mem_stats.at("MemTotal")+ mem_stats.at("SwapTotal"); + report_.virtual_memory_free = mem_stats.at("MemFree") + mem_stats.at("SwapFree"); + report_.physical_memory_total = mem_stats.at("MemTotal"); + report_.physical_memory_free = mem_stats.at("MemFree"); } - catch (...) { - struct sysinfo info; - sysinfo(&info); - //report_.physical_memory_free = info.freeram / BYTES_PER_MEGABYTE * info.mem_unit; - report_.physical_memory_free = info.freeram / BYTES_PER_MEGABYTE * info.mem_unit; + catch(...){ + report_.virtual_memory_total = (info.totalram+info.totalswap) * info.mem_unit; + report_.virtual_memory_free = (info.freeram+info.freeswap) * info.mem_unit; + report_.physical_memory_total = info.totalram * info.mem_unit; + report_.physical_memory_free = info.freeram * info.mem_unit; } - //reporting_data_.virtual_memory_total = (info.totalram+info.totalswap) / BYTES_PER_MEGABYTE * info.mem_unit; - //reporting_data_.virtual_memory_free = (info.freeram+info.freeswap) / BYTES_PER_MEGABYTE * info.mem_unit; - //reporting_data_.virtual_memory_used = reporting_data_.virtual_memory_total-reporting_data_.virtual_memory_free; - //reporting_data_.virtual_memory_percent = (double)reporting_data_.virtual_memory_used / (double)reporting_data_.virtual_memory_total * 100.; - //reporting_data_.physical_memory_total = info.totalram / BYTES_PER_MEGABYTE * info.mem_unit; - //reporting_data_.physical_memory_free = info.freeram / BYTES_PER_MEGABYTE * info.mem_unit; - //reporting_data_.physical_memory_used = reporting_data_.physical_memory_total-reporting_data_.physical_memory_free; - //reporting_data_.physical_memory_percent = (double)reporting_data_.physical_memory_used / (double)reporting_data_.physical_memory_total * 100.; - //reporting_data_.user_cpu_percent = cpu_usage_accumulator_->get_user_percent(); - //reporting_data_.system_cpu_percent = cpu_usage_accumulator_->get_system_percent(); - report_.idle_cpu_percent = cpu_usage_stats_->get_idle_percent(); - //reporting_data_.cpu_percent = 100.0 - reporting_data_.idle_cpu_percent; - //reporting_data_.up_time = info.uptime; - //reporting_data_.up_time_string = format_up_time(reporting_data_.up_time); - //reporting_data_.last_update_time = time(NULL); -} - -std::string -SystemMonitor::format_up_time(unsigned long secondsUp) const -{ - std::stringstream formattedUptime; - int days; - int hours; - int minutes; - int seconds; - - int leftover; - - days = (int) secondsUp / (60 * 60 * 24); - leftover = (int) secondsUp - (days * (60 * 60 * 24) ); - hours = (int) leftover / (60 * 60); - leftover = leftover - (hours * (60 * 60) ); - minutes = (int) leftover / 60; - seconds = leftover - (minutes * 60); - - formattedUptime << days << "d " << hours << "h " << minutes << "m " << seconds << "s"; - - return formattedUptime.str(); + report_.virtual_memory_used = report_.virtual_memory_total-report_.virtual_memory_free; + report_.physical_memory_used = report_.physical_memory_total-report_.physical_memory_free; + report_.virtual_memory_percent = (double)report_.virtual_memory_used / (double)report_.virtual_memory_total * 100.; + report_.physical_memory_percent = (double)report_.physical_memory_used / (double)report_.physical_memory_total * 100.; + report_.user_cpu_percent = cpu_usage_stats_->get_user_percent(); + report_.system_cpu_percent = cpu_usage_stats_->get_system_percent(); + report_.idle_cpu_percent = cpu_usage_stats_->get_idle_percent(); + report_.cpu_percent = 100.0 - report_.idle_cpu_percent; + report_.up_time = info.uptime; + report_.last_update_time = time(NULL); + report_.idle_cpu_percent = cpu_usage_stats_->get_idle_percent(); + report_.all_usage = cpu_usage_stats_->get_all_usage(); + report_.user_usage = cpu_usage_stats_->get_user_usage(); + report_.sys_limits = sys_limit_state_->get(); + report_.load.one_min = info.loads[0] * 1.0/(1< #include #include "Reporting.h" -#include "statistics/Statistics.h" +#include "statistics/CpuUsageStats.h" #include "states/ProcMeminfo.h" - +#include "states/Limits.h" class SystemMonitor : public Reporting { public: - typedef boost::shared_ptr< CpuStatistics > CpuStatsPtr; + typedef boost::shared_ptr< CpuUsageStats > CpuStatsPtr; typedef boost::shared_ptr< ProcMeminfo > MemInfoPtr; + typedef CpuUsageStats::CpuList CpuList; + + struct loadavg { + double one_min; + double five_min; + double fifteen_min; + }; struct Report { - uint64_t physical_memory_free; - double idle_cpu_percent; + uint64_t virtual_memory_total; + uint64_t virtual_memory_used; + uint64_t virtual_memory_free; + double virtual_memory_percent; + uint64_t physical_memory_total; + uint64_t physical_memory_used; + uint64_t physical_memory_free; + double physical_memory_percent; + uint64_t all_usage; + uint64_t user_usage; + double cpu_percent; + double user_cpu_percent; + double system_cpu_percent; + double idle_cpu_percent; + double up_time; + Limits::Contents sys_limits; + double last_update_time; + loadavg load; }; + +public: + SystemMonitor( const CpuList &cpu_list, const int nhistory=5 ); -public: SystemMonitor( const CpuStatsPtr & cpu_usage_stats, - const MemInfoPtr & mem_usage_state ); + const MemInfoPtr & mem_usage_state, + const SysLimitsPtr& sys_limit ); double get_idle_percent() const; double get_idle_average() const; uint64_t get_mem_free() const; + uint64_t get_phys_free() const; + uint64_t get_all_usage() const; + uint64_t get_user_usage() const; + double get_loadavg() const; const Report &getReport() const; void report(); + const CpuStatsPtr getCpuStats() const; private: - std::string format_up_time(unsigned long secondsUp) const; - -private: - CpuStatsPtr cpu_usage_stats_; - MemInfoPtr mem_usage_state_; - Report report_; + CpuStatsPtr cpu_usage_stats_; + MemInfoPtr mem_usage_state_; + SysLimitsPtr sys_limit_state_; + Report report_; }; diff --git a/redhawk/src/testing/sdr/dev/devices/GPP/cpp/reports/ThresholdMonitor.h b/redhawk/src/testing/sdr/dev/devices/GPP/cpp/reports/ThresholdMonitor.h index caf75e76b..422ba8fb9 100644 --- a/redhawk/src/testing/sdr/dev/devices/GPP/cpp/reports/ThresholdMonitor.h +++ b/redhawk/src/testing/sdr/dev/devices/GPP/cpp/reports/ThresholdMonitor.h @@ -28,9 +28,9 @@ #include "utils/Updateable.h" #include "utils/EventDispatcher.h" #include "Reporting.h" +#include "utils/ConversionWrapper.h" #include "struct_props.h" -//class ThresholdMonitor : public Reporting, public EventDispatcherMixin class ThresholdMonitor : public Updateable, public EventDispatcherMixin { public: diff --git a/redhawk/src/testing/sdr/dev/devices/GPP/cpp/states/ProcMeminfo.h b/redhawk/src/testing/sdr/dev/devices/GPP/cpp/states/ProcMeminfo.h index 9f56e1788..1712fa53b 100644 --- a/redhawk/src/testing/sdr/dev/devices/GPP/cpp/states/ProcMeminfo.h +++ b/redhawk/src/testing/sdr/dev/devices/GPP/cpp/states/ProcMeminfo.h @@ -42,7 +42,7 @@ class ProcMeminfo : public State virtual ~ProcMeminfo(); - // update content state by processing /proc/stat + // update content state by processing /proc/meminfo void update_state(); // return contents of file diff --git a/redhawk/src/testing/sdr/dev/devices/GPP/cpp/states/ProcStat.cpp b/redhawk/src/testing/sdr/dev/devices/GPP/cpp/states/ProcStat.cpp index db1441d44..1a754277d 100644 --- a/redhawk/src/testing/sdr/dev/devices/GPP/cpp/states/ProcStat.cpp +++ b/redhawk/src/testing/sdr/dev/devices/GPP/cpp/states/ProcStat.cpp @@ -17,6 +17,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see http://www.gnu.org/licenses/. */ +#include #include "ProcStat.h" #include "parsers/ProcStatParser.h" @@ -44,4 +45,26 @@ ProcStat::get() const } +static void __readone(FILE *input, int64_t *x) { fscanf(input, "%lld ",(long long *) x); } +static void __readstr(FILE *input, char *x) { fscanf(input, "%s ", x);} +int ProcStat::GetTicks( int64_t &r_sys, int64_t &r_user ) { + + char cpu[512]; + int retval=-1; + int64_t user, nice, sys, idle, iowait, irq, softirq; + FILE *input=fopen("/proc/stat", "r"); + if( !input ) return retval; + __readstr(input,cpu); + __readone(input,&user); + __readone(input,&nice); + __readone(input,&sys); + __readone(input,&idle); + __readone(input,&iowait); + __readone(input,&irq); + __readone(input,&softirq); + fclose(input); + r_sys = user+nice+sys+idle; + r_user = user+nice+sys; + return 0; +} diff --git a/redhawk/src/testing/sdr/dev/devices/GPP/cpp/states/ProcStat.h b/redhawk/src/testing/sdr/dev/devices/GPP/cpp/states/ProcStat.h index 0e3657662..1d13631c8 100644 --- a/redhawk/src/testing/sdr/dev/devices/GPP/cpp/states/ProcStat.h +++ b/redhawk/src/testing/sdr/dev/devices/GPP/cpp/states/ProcStat.h @@ -79,6 +79,7 @@ class ProcStat : public State }; + static int GetTicks( int64_t &sys, int64_t &user ); // init file and read in baseline stats ProcStat(); diff --git a/redhawk/src/testing/sdr/dev/devices/GPP/cpp/statistics/CpuUsageStats.cpp b/redhawk/src/testing/sdr/dev/devices/GPP/cpp/statistics/CpuUsageStats.cpp index 27931537e..fae14b0ab 100644 --- a/redhawk/src/testing/sdr/dev/devices/GPP/cpp/statistics/CpuUsageStats.cpp +++ b/redhawk/src/testing/sdr/dev/devices/GPP/cpp/statistics/CpuUsageStats.cpp @@ -56,6 +56,18 @@ CpuUsageStats::CpuUsageStats(const CpuList &cpus, const int nhistory ): _update_stats(); } + +CpuUsageStats::CpuUsageStats(const CpuUsageStats &src ) +{ + prev_cpus_stat_ = src.prev_cpus_stat_; + current_cpus_stat_ = src.current_cpus_stat_; + proc_stat_ = src.proc_stat_; + cpus_ = src.cpus_; + metrics_ = src.metrics_; + average_ = src.average_; + history_db_ = src.history_db_; +} + double CpuUsageStats::get_user_percent() const { return metrics_[ ProcStat::CPU_JIFFIES_USER ]; @@ -87,6 +99,17 @@ double CpuUsageStats::get_idle_average() const return average_[ ProcStat::CPU_JIFFIES_IDLE ]; } +uint64_t CpuUsageStats::get_all_usage() const +{ + return cpus_all_itv; +} + +uint64_t CpuUsageStats::get_user_usage() const +{ + return cpus_user_itv; + return 0; +} + void CpuUsageStats::compute_statistics() @@ -96,6 +119,8 @@ void CpuUsageStats::compute_statistics() // sum up all jiffies for all required cpus or all Accumulator cpus_itv = _get_interval_total(); + cpus_all_itv = cpus_itv; + cpus_user_itv =_get_user_total(); std::fill( metrics_.begin(),metrics_.end(), 0 ); std::fill( average_.begin(),average_.end(), 0 ); @@ -134,6 +159,20 @@ CpuUsageStats::Accumulator CpuUsageStats::_get_interval_total() const return 0; } +CpuUsageStats::Accumulator CpuUsageStats::_get_user_total() const +{ + if( !prev_cpus_stat_.empty() ) { + uint64_t scc; + uint64_t scp; + scc = _sum_jiffie_list( current_cpus_stat_, ProcStat::CPU_JIFFIES_SYSTEM ); + scp = _sum_jiffie_list( prev_cpus_stat_, ProcStat::CPU_JIFFIES_SYSTEM ); + DEBUG(std::cout << " _get_user_total scc/scp/diff " << scc << "/" << scp << "/" << scc - scp << std::endl); + return scc - scp; + } + else + return 0; +} + void CpuUsageStats::_update_stats() { proc_stat_.update_state(); @@ -163,7 +202,7 @@ CpuUsageStats::Accumulator CpuUsageStats::_sum_jiffies(const ProcStat::CpuStats { uint64_t accum=0; - // filter out cpus that were identified... if list == 0 then do not filer any + // filter out cpus that were identified... if list == 0 then do not filter any if ( cpus_.size() == 0 ) { ProcStat::CpuStats::const_iterator iter = cpu_stats.begin(); for ( int i=0; iter != cpu_stats.end(); i++, iter++ ) { @@ -185,6 +224,33 @@ CpuUsageStats::Accumulator CpuUsageStats::_sum_jiffies(const ProcStat::CpuStats return accum; } +CpuUsageStats::Accumulator CpuUsageStats::_sum_jiffie_list(const ProcStat::CpuStats& cpu_stats, + const ProcStat::CpuJiffiesField &jiffie_max ) const +{ + + uint64_t accum=0; + // filter out cpus that were identified... if list == 0 then do not filter any + if ( cpus_.size() == 0 ) { + ProcStat::CpuStats::const_iterator iter = cpu_stats.begin(); + for ( int i=0; iter != cpu_stats.end(); i++, iter++ ) { + accum += std::accumulate( (*iter).jiffies.begin(), (*iter).jiffies.begin()+jiffie_max, 0 ); // skip guest counters... + DEBUG(std::cout << " _sum_jiffies cpu/accum: " << i << "/" << accum << std::endl); + } + } + else { + // filter out cpus that were identified... + for( uint32_t i=0; i < cpus_.size(); i++ ) { + if ( cpus_[i] < cpu_stats.size() ) { + int cpu_idx = cpus_[i]; + accum += std::accumulate( cpu_stats[cpu_idx].jiffies.begin(), cpu_stats[cpu_idx].jiffies.begin()+jiffie_max, 0); // skip guest counters... + } + } + } + + DEBUG(std::cout << " _sum_jiffies accum: " << accum << std::endl); + return accum; +} + CpuUsageStats::Accumulator CpuUsageStats::_sum_jiffie_field( const ProcStat::CpuStats& cpu_stats, const ProcStat::CpuJiffiesField &jiffie ) const diff --git a/redhawk/src/testing/sdr/dev/devices/GPP/cpp/statistics/CpuUsageStats.h b/redhawk/src/testing/sdr/dev/devices/GPP/cpp/statistics/CpuUsageStats.h index adedec966..8ebf99164 100644 --- a/redhawk/src/testing/sdr/dev/devices/GPP/cpp/statistics/CpuUsageStats.h +++ b/redhawk/src/testing/sdr/dev/devices/GPP/cpp/statistics/CpuUsageStats.h @@ -48,6 +48,7 @@ class CpuUsageStats : public CpuStatistics //CpuUsageStats( ); CpuUsageStats( const int nhistory=5 ); CpuUsageStats( const CpuList &cpus, const int nhistory=5 ); + CpuUsageStats( const CpuUsageStats &src ); virtual ~CpuUsageStats() {} @@ -60,15 +61,20 @@ class CpuUsageStats : public CpuStatistics virtual double get_user_average() const; virtual double get_system_average() const; virtual double get_idle_average() const; + uint64_t get_all_usage() const; + uint64_t get_user_usage() const; protected: typedef ProcStat::Jiffie Accumulator; virtual Accumulator _get_interval_total() const; + virtual Accumulator _get_user_total() const; virtual double _calc_metric( const ProcStat::CpuJiffiesField & jiffie, const Accumulator itv ) const; virtual double _calc_average( const ProcStat::CpuJiffiesField & jiffie ) const; virtual Accumulator _sum_jiffies( const ProcStat::CpuStats & cpu_stats ) const; + virtual Accumulator _sum_jiffie_list( const ProcStat::CpuStats & cpu_stats, + const ProcStat::CpuJiffiesField & jiffie_max ) const; virtual Accumulator _sum_jiffie_field( const ProcStat::CpuStats& cpu_stats, const ProcStat::CpuJiffiesField & jiffie ) const; bool _accum_cpu( const uint32_t cpu_id ) const; @@ -82,6 +88,8 @@ class CpuUsageStats : public CpuStatistics MetricsList metrics_; MetricsList average_; MetricsHistory history_db_; + Accumulator cpus_all_itv; + Accumulator cpus_user_itv; }; diff --git a/redhawk/src/testing/sdr/dev/devices/GPP/cpp/struct_props.h b/redhawk/src/testing/sdr/dev/devices/GPP/cpp/struct_props.h index d56e6a456..b0e1c3f85 100644 --- a/redhawk/src/testing/sdr/dev/devices/GPP/cpp/struct_props.h +++ b/redhawk/src/testing/sdr/dev/devices/GPP/cpp/struct_props.h @@ -145,6 +145,65 @@ inline bool operator!= (const nic_allocation_struct& s1, const nic_allocation_st return !(s1==s2); }; +struct redhawk__reservation_request_struct { + redhawk__reservation_request_struct () + { + } + + static std::string getId() { + return std::string("redhawk::reservation_request"); + } + + static const char* getFormat() { + return "s[s][s]"; + } + + std::string obj_id; + std::vector kinds; + std::vector values; +}; + +inline bool operator>>= (const CORBA::Any& a, redhawk__reservation_request_struct& s) { + CF::Properties* temp; + if (!(a >>= temp)) return false; + const redhawk::PropertyMap& props = redhawk::PropertyMap::cast(*temp); + if (props.contains("redhawk::reservation_request::obj_id")) { + if (!(props["redhawk::reservation_request::obj_id"] >>= s.obj_id)) return false; + } + if (props.contains("redhawk::reservation_request::kinds")) { + if (!(props["redhawk::reservation_request::kinds"] >>= s.kinds)) return false; + } + if (props.contains("redhawk::reservation_request::values")) { + if (!(props["redhawk::reservation_request::values"] >>= s.values)) return false; + } + return true; +} + +inline void operator<<= (CORBA::Any& a, const redhawk__reservation_request_struct& s) { + redhawk::PropertyMap props; + + props["redhawk::reservation_request::obj_id"] = s.obj_id; + + props["redhawk::reservation_request::kinds"] = s.kinds; + + props["redhawk::reservation_request::values"] = s.values; + a <<= props; +} + +inline bool operator== (const redhawk__reservation_request_struct& s1, const redhawk__reservation_request_struct& s2) { + if (s1.obj_id!=s2.obj_id) + return false; + if (s1.kinds!=s2.kinds) + return false; + if (s1.values!=s2.values) + return false; + return true; +} + +inline bool operator!= (const redhawk__reservation_request_struct& s1, const redhawk__reservation_request_struct& s2) { + return !(s1==s2); +} + struct advanced_struct { advanced_struct () { @@ -331,81 +390,100 @@ inline bool operator!= (const threshold_event_struct& s1, const threshold_event_ return !(s1==s2); }; + struct thresholds_struct { thresholds_struct () { + ignore=false; cpu_idle = 10; - mem_free = 100; + load_avg = 80; + mem_free = 100LL; nic_usage = 900; + files_available = 3; + threads = 3; }; static std::string getId() { return std::string("thresholds"); }; + bool ignore; float cpu_idle; + float load_avg; CORBA::LongLong mem_free; CORBA::Long nic_usage; + float files_available; + float threads; }; inline bool operator>>= (const CORBA::Any& a, thresholds_struct& s) { CF::Properties* temp; if (!(a >>= temp)) return false; - CF::Properties& props = *temp; - for (unsigned int idx = 0; idx < props.length(); idx++) { - if (!strcmp("cpu_idle", props[idx].id)) { - if (!(props[idx].value >>= s.cpu_idle)) { - CORBA::TypeCode_var typecode = props[idx].value.type(); - if (typecode->kind() != CORBA::tk_null) { - return false; - } - } - } - else if (!strcmp("mem_free", props[idx].id)) { - if (!(props[idx].value >>= s.mem_free)) { - CORBA::TypeCode_var typecode = props[idx].value.type(); - if (typecode->kind() != CORBA::tk_null) { - return false; - } - } - } - else if (!strcmp("nic_usage", props[idx].id)) { - if (!(props[idx].value >>= s.nic_usage)) { - CORBA::TypeCode_var typecode = props[idx].value.type(); - if (typecode->kind() != CORBA::tk_null) { - return false; - } - } - } + const redhawk::PropertyMap& props = redhawk::PropertyMap::cast(*temp); + if (props.contains("ignore")) { + if (!(props["ignore"] >>= s.ignore)) return false; + } + if (props.contains("cpu_idle")) { + if (!(props["cpu_idle"] >>= s.cpu_idle)) return false; + } + if (props.contains("load_avg")) { + if (!(props["load_avg"] >>= s.load_avg)) return false; + } + if (props.contains("mem_free")) { + if (!(props["mem_free"] >>= s.mem_free)) return false; + } + if (props.contains("nic_usage")) { + if (!(props["nic_usage"] >>= s.nic_usage)) return false; + } + if (props.contains("files_available")) { + if (!(props["files_available"] >>= s.files_available)) return false; + } + if (props.contains("threads")) { + if (!(props["threads"] >>= s.threads)) return false; } return true; -}; +} inline void operator<<= (CORBA::Any& a, const thresholds_struct& s) { - CF::Properties props; - props.length(3); - props[0].id = CORBA::string_dup("cpu_idle"); - props[0].value <<= s.cpu_idle; - props[1].id = CORBA::string_dup("mem_free"); - props[1].value <<= s.mem_free; - props[2].id = CORBA::string_dup("nic_usage"); - props[2].value <<= s.nic_usage; + redhawk::PropertyMap props; + + props["ignore"] = s.ignore; + + props["cpu_idle"] = s.cpu_idle; + + props["load_avg"] = s.load_avg; + + props["mem_free"] = s.mem_free; + + props["nic_usage"] = s.nic_usage; + + props["files_available"] = s.files_available; + + props["threads"] = s.threads; a <<= props; -}; +} inline bool operator== (const thresholds_struct& s1, const thresholds_struct& s2) { + if (s1.ignore!=s2.ignore) + return false; if (s1.cpu_idle!=s2.cpu_idle) return false; + if (s1.load_avg!=s2.load_avg) + return false; if (s1.mem_free!=s2.mem_free) return false; if (s1.nic_usage!=s2.nic_usage) return false; + if (s1.files_available!=s2.files_available) + return false; + if (s1.threads!=s2.threads) + return false; return true; -}; +} inline bool operator!= (const thresholds_struct& s1, const thresholds_struct& s2) { return !(s1==s2); -}; +} struct nic_allocation_status_struct_struct { nic_allocation_status_struct_struct () @@ -1034,4 +1112,357 @@ inline bool operator!= (const interfaces_struct& s1, const interfaces_struct& s2 return !(s1==s2); }; +struct ulimit_struct { + ulimit_struct () + { + }; + + static std::string getId() { + return std::string("ulimit"); + }; + + CORBA::Long current_threads; + CORBA::Long max_threads; + CORBA::Long current_open_files; + CORBA::Long max_open_files; +}; + +inline bool operator>>= (const CORBA::Any& a, ulimit_struct& s) { + CF::Properties* temp; + if (!(a >>= temp)) return false; + const redhawk::PropertyMap& props = redhawk::PropertyMap::cast(*temp); + if (props.contains("current_threads")) { + if (!(props["current_threads"] >>= s.current_threads)) return false; + } + if (props.contains("max_threads")) { + if (!(props["max_threads"] >>= s.max_threads)) return false; + } + if (props.contains("current_open_files")) { + if (!(props["current_open_files"] >>= s.current_open_files)) return false; + } + if (props.contains("max_open_files")) { + if (!(props["max_open_files"] >>= s.max_open_files)) return false; + } + return true; +} + +inline void operator<<= (CORBA::Any& a, const ulimit_struct& s) { + redhawk::PropertyMap props; + + props["current_threads"] = s.current_threads; + + props["max_threads"] = s.max_threads; + + props["current_open_files"] = s.current_open_files; + + props["max_open_files"] = s.max_open_files; + a <<= props; +} + +inline bool operator== (const ulimit_struct& s1, const ulimit_struct& s2) { + if (s1.current_threads!=s2.current_threads) + return false; + if (s1.max_threads!=s2.max_threads) + return false; + if (s1.current_open_files!=s2.current_open_files) + return false; + if (s1.max_open_files!=s2.max_open_files) + return false; + return true; +} + +inline bool operator!= (const ulimit_struct& s1, const ulimit_struct& s2) { + return !(s1==s2); +} + +struct utilization_entry_struct { + utilization_entry_struct () + { + }; + + static std::string getId() { + return std::string("utilization_entry"); + }; + + std::string description; + float component_load; + float system_load; + float subscribed; + float maximum; +}; + +inline bool operator>>= (const CORBA::Any& a, utilization_entry_struct& s) { + CF::Properties* temp; + if (!(a >>= temp)) return false; + const redhawk::PropertyMap& props = redhawk::PropertyMap::cast(*temp); + if (props.contains("description")) { + if (!(props["description"] >>= s.description)) return false; + } + if (props.contains("component_load")) { + if (!(props["component_load"] >>= s.component_load)) return false; + } + if (props.contains("system_load")) { + if (!(props["system_load"] >>= s.system_load)) return false; + } + if (props.contains("subscribed")) { + if (!(props["subscribed"] >>= s.subscribed)) return false; + } + if (props.contains("maximum")) { + if (!(props["maximum"] >>= s.maximum)) return false; + } + return true; +} + +inline void operator<<= (CORBA::Any& a, const utilization_entry_struct& s) { + redhawk::PropertyMap props; + + props["description"] = s.description; + + props["component_load"] = s.component_load; + + props["system_load"] = s.system_load; + + props["subscribed"] = s.subscribed; + + props["maximum"] = s.maximum; + a <<= props; +} + +inline bool operator== (const utilization_entry_struct& s1, const utilization_entry_struct& s2) { + if (s1.description!=s2.description) + return false; + if (s1.component_load!=s2.component_load) + return false; + if (s1.system_load!=s2.system_load) + return false; + if (s1.subscribed!=s2.subscribed) + return false; + if (s1.maximum!=s2.maximum) + return false; + return true; +} + +inline bool operator!= (const utilization_entry_struct& s1, const utilization_entry_struct& s2) { + return !(s1==s2); +} +struct loadAverage_struct { + loadAverage_struct () + { + }; + + static std::string getId() { + return std::string("DCE:9da85ebc-6503-48e7-af36-b77c7ad0c2b4"); + }; + + double onemin; + double fivemin; + double fifteenmin; +}; + +inline bool operator>>= (const CORBA::Any& a, loadAverage_struct& s) { + CF::Properties* temp; + if (!(a >>= temp)) return false; + const redhawk::PropertyMap& props = redhawk::PropertyMap::cast(*temp); + if (props.contains("onemin")) { + if (!(props["onemin"] >>= s.onemin)) return false; + } + if (props.contains("fivemin")) { + if (!(props["fivemin"] >>= s.fivemin)) return false; + } + if (props.contains("fifteenmin")) { + if (!(props["fifteenmin"] >>= s.fifteenmin)) return false; + } + return true; +} + +inline void operator<<= (CORBA::Any& a, const loadAverage_struct& s) { + redhawk::PropertyMap props; + + props["onemin"] = s.onemin; + + props["fivemin"] = s.fivemin; + + props["fifteenmin"] = s.fifteenmin; + a <<= props; +} + +inline bool operator== (const loadAverage_struct& s1, const loadAverage_struct& s2) { + if (s1.onemin!=s2.onemin) + return false; + if (s1.fivemin!=s2.fivemin) + return false; + if (s1.fifteenmin!=s2.fifteenmin) + return false; + return true; +} + +inline bool operator!= (const loadAverage_struct& s1, const loadAverage_struct& s2) { + return !(s1==s2); +} + +struct component_monitor_struct { + component_monitor_struct () + { + }; + + static std::string getId() { + return std::string("component_monitor::component_monitor"); + }; + + std::string component_id; + std::string waveform_id; + unsigned short pid; + float cores; + float mem_rss; + float mem_percent; + CORBA::ULong num_processes; + CORBA::ULong num_threads; + CORBA::ULong num_files; +}; + +inline bool operator>>= (const CORBA::Any& a, component_monitor_struct& s) { + CF::Properties* temp; + if (!(a >>= temp)) return false; + const redhawk::PropertyMap& props = redhawk::PropertyMap::cast(*temp); + if (props.contains("component_monitor::component_monitor::component_id")) { + if (!(props["component_monitor::component_monitor::component_id"] >>= s.component_id)) return false; + } + if (props.contains("component_monitor::component_monitor::waveform_id")) { + if (!(props["component_monitor::component_monitor::waveform_id"] >>= s.waveform_id)) return false; + } + if (props.contains("component_monitor::component_monitor::pid")) { + if (!(props["component_monitor::component_monitor::pid"] >>= s.pid)) return false; + } + if (props.contains("component_monitor::component_monitor::cores")) { + if (!(props["component_monitor::component_monitor::cores"] >>= s.cores)) return false; + } + if (props.contains("component_monitor::component_monitor::mem_rss")) { + if (!(props["component_monitor::component_monitor::mem_rss"] >>= s.mem_rss)) return false; + } + if (props.contains("component_monitor::component_monitor::mem_percent")) { + if (!(props["component_monitor::component_monitor::mem_percent"] >>= s.mem_percent)) return false; + } + if (props.contains("component_monitor::component_monitor::num_processes")) { + if (!(props["component_monitor::component_monitor::num_processes"] >>= s.num_processes)) return false; + } + if (props.contains("component_monitor::component_monitor::num_threads")) { + if (!(props["component_monitor::component_monitor::num_threads"] >>= s.num_threads)) return false; + } + if (props.contains("component_monitor::component_monitor::num_files")) { + if (!(props["component_monitor::component_monitor::num_files"] >>= s.num_files)) return false; + } + return true; +} + +inline void operator<<= (CORBA::Any& a, const component_monitor_struct& s) { + redhawk::PropertyMap props; + + props["component_monitor::component_monitor::component_id"] = s.component_id; + + props["component_monitor::component_monitor::waveform_id"] = s.waveform_id; + + props["component_monitor::component_monitor::pid"] = s.pid; + + props["component_monitor::component_monitor::cores"] = s.cores; + + props["component_monitor::component_monitor::mem_rss"] = s.mem_rss; + + props["component_monitor::component_monitor::mem_percent"] = s.mem_percent; + + props["component_monitor::component_monitor::num_processes"] = s.num_processes; + + props["component_monitor::component_monitor::num_threads"] = s.num_threads; + + props["component_monitor::component_monitor::num_files"] = s.num_files; + a <<= props; +} + +inline bool operator== (const component_monitor_struct& s1, const component_monitor_struct& s2) { + if (s1.component_id!=s2.component_id) + return false; + if (s1.waveform_id!=s2.waveform_id) + return false; + if (s1.pid!=s2.pid) + return false; + if (s1.cores!=s2.cores) + return false; + if (s1.mem_rss!=s2.mem_rss) + return false; + if (s1.mem_percent!=s2.mem_percent) + return false; + if (s1.num_processes!=s2.num_processes) + return false; + if (s1.num_threads!=s2.num_threads) + return false; + if (s1.num_files!=s2.num_files) + return false; + return true; +} + +inline bool operator!= (const component_monitor_struct& s1, const component_monitor_struct& s2) { + return !(s1==s2); +} +struct sys_limits_struct { + sys_limits_struct () + { + }; + + static std::string getId() { + return std::string("sys_limits"); + }; + + CORBA::Long current_threads; + CORBA::Long max_threads; + CORBA::Long current_open_files; + CORBA::Long max_open_files; +}; + +inline bool operator>>= (const CORBA::Any& a, sys_limits_struct& s) { + CF::Properties* temp; + if (!(a >>= temp)) return false; + const redhawk::PropertyMap& props = redhawk::PropertyMap::cast(*temp); + if (props.contains("sys_limits::current_threads")) { + if (!(props["sys_limits::current_threads"] >>= s.current_threads)) return false; + } + if (props.contains("sys_limits::max_threads")) { + if (!(props["sys_limits::max_threads"] >>= s.max_threads)) return false; + } + if (props.contains("sys_limits::current_open_files")) { + if (!(props["sys_limits::current_open_files"] >>= s.current_open_files)) return false; + } + if (props.contains("sys_limits::max_open_files")) { + if (!(props["sys_limits::max_open_files"] >>= s.max_open_files)) return false; + } + return true; +} + +inline void operator<<= (CORBA::Any& a, const sys_limits_struct& s) { + redhawk::PropertyMap props; + + props["sys_limits::current_threads"] = s.current_threads; + + props["sys_limits::max_threads"] = s.max_threads; + + props["sys_limits::current_open_files"] = s.current_open_files; + + props["sys_limits::max_open_files"] = s.max_open_files; + a <<= props; +} + +inline bool operator== (const sys_limits_struct& s1, const sys_limits_struct& s2) { + if (s1.current_threads!=s2.current_threads) + return false; + if (s1.max_threads!=s2.max_threads) + return false; + if (s1.current_open_files!=s2.current_open_files) + return false; + if (s1.max_open_files!=s2.max_open_files) + return false; + return true; +} + +inline bool operator!= (const sys_limits_struct& s1, const sys_limits_struct& s2) { + return !(s1==s2); +} + #endif // STRUCTPROPS_H diff --git a/redhawk/src/testing/sdr/dev/devices/GPP/cpp/utils/affinity.cpp b/redhawk/src/testing/sdr/dev/devices/GPP/cpp/utils/affinity.cpp index 280b9b68c..c5709bc31 100644 --- a/redhawk/src/testing/sdr/dev/devices/GPP/cpp/utils/affinity.cpp +++ b/redhawk/src/testing/sdr/dev/devices/GPP/cpp/utils/affinity.cpp @@ -2,14 +2,14 @@ * This file is protected by Copyright. Please refer to the COPYRIGHT file * distributed with this source distribution. * - * This file is part of REDHAWK core. + * This file is part of REDHAWK GPP. * - * REDHAWK core is free software: you can redistribute it and/or modify it + * REDHAWK GPP is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your * option) any later version. * - * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT + * REDHAWK GPP is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * for more details. @@ -24,6 +24,7 @@ #include #include #include +#include #ifdef HAVE_LIBNUMA #include #endif @@ -41,7 +42,7 @@ namespace gpp { namespace affinity { - bool check_numa() { + bool check_numa() { #ifdef HAVE_LIBNUMA return (numa_available() != -1); #else @@ -49,6 +50,7 @@ namespace gpp { #endif } + const std::string get_cgroup_root() { return redhawk::affinity::get_cgroup_root(); } @@ -58,7 +60,11 @@ namespace gpp { } bool is_disabled() { - return redhawk::affinity::is_disabled(); + return redhawk::affinity::is_disabled() || ( check_numa() == false ) ; + } + + rh_logger::LoggerPtr get_affinity_logger() { + return redhawk::affinity::get_affinity_logger(); } void set_nic_promotion( const bool onoff ) { @@ -83,14 +89,14 @@ namespace gpp { std::string pintr("/proc/interrupts"); std::ifstream in(pintr.c_str(), std::ifstream::in ); if ( in.fail() ) { - RH_NL_ERROR("gpp::affinity", "Unable to access /proc/interrupts"); + RH_ERROR(get_affinity_logger(), "Unable to access /proc/interrupts"); return cpus; } std::string line; while( std::getline( in, line ) ) { // check if the device is our interface - RH_NL_TRACE("gpp::affinity", "Processing /proc/interrupts.... line:" << line); + RH_TRACE(get_affinity_logger(), "Processing /proc/interrupts.... line:" << line); if ( line.rfind(iface) != std::string::npos ) { std::istringstream iss(line); int parts=0; @@ -99,13 +105,18 @@ namespace gpp { iss>>tok; // skip interrupt number and iface if ( parts > 0 and tok != iface ) { - std::istringstream iss(tok); - int icnt; - iss >> icnt; - if ( icnt > 0 ) { - RH_NL_TRACE("gpp::affinity", "identify cpus: Adding CPU : " << parts-1); - cpus.push_back(parts-1); - } + int icnt=0; + try { + icnt=boost::lexical_cast(tok); + RH_TRACE(get_affinity_logger(), "identify cpus: CPU : " << parts-1 << " nic interrupts:" << icnt); + if ( icnt > 0 ) { + RH_TRACE(get_affinity_logger(), "identify cpus: Adding CPU : " << parts-1); + cpus.push_back(parts-1); + } + } + catch(...){ + RH_TRACE(get_affinity_logger(), "Invalid Token: tok:" << tok); + } } parts++; }while(iss); @@ -115,7 +126,7 @@ namespace gpp { redhawk::affinity::CpuList::iterator citer=cpus.begin(); for (; citer != cpus.end(); citer++) { - RH_NL_DEBUG("gpp::affinity", "identified CPUS iface/cpu ...:" << iface << "/" << *citer); + RH_DEBUG(get_affinity_logger(), "identified CPUS iface/cpu ...:" << iface << "/" << *citer); } return cpus; @@ -134,11 +145,11 @@ namespace gpp { #ifdef HAVE_LIBNUMA int soc=-1; for( int i=0; i < (int)cpulist.size();i++ ) { - RH_NL_DEBUG("gpp::affinity", "Finding (processor socket) for NIC:" << iface << " socket :" << numa_node_of_cpu(cpulist[i]) ); + RH_DEBUG(get_affinity_logger(), "Finding (processor socket) for NIC:" << iface << " socket :" << numa_node_of_cpu(cpulist[i]) ); if ( std::count( bl.begin(), bl.end(), cpulist[i] ) != 0 ) continue; soc = numa_node_of_cpu(cpulist[i]); if ( soc != psoc && psoc != -1 && !findFirst ) { - RH_NL_WARN("gpp::affinity", "More than 1 socket servicing NIC:" << iface); + RH_WARN(get_affinity_logger(), "More than 1 socket servicing NIC:" << iface); psoc=-1; break; } @@ -156,6 +167,7 @@ namespace gpp { return retval; + } @@ -168,10 +180,6 @@ namespace gpp { } #ifdef HAVE_LIBNUMA - if ( numa_available() == -1 ) { - return cpu_list; - } - if ( list_type == "socket" || list_type == "node" ) { std::string nodestr = context; struct bitmask *node_mask = numa_parse_nodestring((char *)nodestr.c_str()); @@ -231,222 +239,218 @@ namespace gpp { redhawk::affinity::CpuList::const_iterator citer=blacklist.begin(); for (; citer != blacklist.end(); citer++) { - RH_NL_DEBUG("gpp::affinity", "BlackList ...:" << *citer); + RH_DEBUG(get_affinity_logger(), "BlackList ...:" << *citer); } redhawk::affinity::AffinityDirectives::const_iterator piter = spec.begin(); for ( int cnt=0; piter != spec.end(); piter++, cnt++ ) { redhawk::affinity::AffinityDirective affinity_spec = *piter; - RH_NL_DEBUG("gpp::affinity", " cnt:" << cnt << " Processing Affinity pid: " << pid << " " << affinity_spec.first << ":" << affinity_spec.second ); + RH_DEBUG(get_affinity_logger(), " cnt:" << cnt << " Processing Affinity pid: " << pid << " " << affinity_spec.first << ":" << affinity_spec.second ); #ifdef HAVE_LIBNUMA - if ( numa_available() == -1 ) { - RH_NL_WARN("gpp::affinity", "Missing affinity support from Redhawk libraries, ... ignoring numa affinity based requests "); - } - else { - // nic -- Determine cpu list by interrupts assigned for the specified NIC - if ( affinity_spec.first == "nic" ) { - std::string iface = affinity_spec.second; - // Determine cpu list by interrupts assigned for the specified NIC - redhawk::affinity::CpuList cpulist = identify_cpus(iface); + // nic -- Determine cpu list by interrupts assigned for the specified NIC + if ( affinity_spec.first == "nic" ) { + std::string iface = affinity_spec.second; + // Determine cpu list by interrupts assigned for the specified NIC + redhawk::affinity::CpuList cpulist = identify_cpus(iface); - // if no cpus identified then issue warning - if ( cpulist.size() > 0 ) { - - // check if black list is specified... if not then use numa node based affinity - if ( blacklist.size() == 0 && getpid() == pid ) { // are we the same process, then use node binding method - bitmask *node_mask = numa_allocate_nodemask(); - if ( !node_mask ) { - throw redhawk::affinity::AffinityFailed("Unable to allocate node mask"); - } - - for( int i=0; i < (int)cpulist.size();i++ ) { - RH_NL_DEBUG("gpp::affinity", "Setting NIC (processor socket select) available sockets :" << numa_node_of_cpu(cpulist[i]) ); - numa_bitmask_setbit(node_mask, numa_node_of_cpu(cpulist[i]) ); - } - - RH_NL_DEBUG("gpp::affinity", "Setting NIC (processor socket select) affinity constraint: :" << iface ); - numa_bind(node_mask); - numa_bitmask_free(node_mask); - } - else { - - int cpus=0; - for( int i=0; i < (int)cpulist.size();i++ ) { - // check if cpu id is not in blacklist - if ( std::count( blacklist.begin(), blacklist.end(), cpulist[i] ) == 0 ) cpus++; - } - - // - // For nic based affinity and blacklisted cpus... - // - // Find all the cpus that service interrupts for the specified interfaces - // - // if interface is serviced by a single cpu and promote to socket flag is on - // get list of cpus for the processor socket servicing the interface... - // apply blacklist - // specify affinity with remaining cpu list - // - // if interface is serviced by single cpu and blacklisted, and promote to socket flag is on - // get list of cpus for the processor socket servicing the interface... - // apply blacklist - // specify affinity with remaining cpu list - // - // otherwise ... - // from the list of cpus for the interface, apply blacklist then apply as affinity - // - if ( (cpulist.size() == 1 && get_nic_promotion() ) || ( cpus == 0 && get_nic_promotion() ) ) { - int cpuid = cpulist[0]; - std::ostringstream os; - os << numa_node_of_cpu( cpuid ); - redhawk::affinity::CpuList tlist = get_cpu_list( "socket", os.str() ); - RH_NL_INFO("gpp::affinity", "Promoting NIC affinity to PID:" << pid << " SOCKET:" << os.str() ); - cpulist.clear(); - for( int i=0; i < (int)tlist.size();i++ ) { - if ( tlist[i] == cpuid ) continue; - cpulist.push_back( tlist[i] ); - } - } + // if no cpus identified then issue warning + if ( cpulist.size() > 0 ) { + + // check if black list is specified... if not then use numa node based affinity + if ( blacklist.size() == 0 && getpid() == pid ) { // are we the same process, then use node binding method + bitmask *node_mask = numa_allocate_nodemask(); + if ( !node_mask ) { + throw redhawk::affinity::AffinityFailed("Unable to allocate node mask"); + } + + for( int i=0; i < (int)cpulist.size();i++ ) { + RH_DEBUG(get_affinity_logger(), "Setting NIC (processor socket select) available sockets :" << numa_node_of_cpu(cpulist[i]) ); + numa_bitmask_setbit(node_mask, numa_node_of_cpu(cpulist[i]) ); + } + + RH_DEBUG(get_affinity_logger(), "Setting NIC (processor socket select) affinity constraint: :" << iface ); + numa_bind(node_mask); + numa_bitmask_free(node_mask); + } + else { + + int cpus=0; + for( int i=0; i < (int)cpulist.size();i++ ) { + // check if cpu id is not in blacklist + if ( std::count( blacklist.begin(), blacklist.end(), cpulist[i] ) == 0 ) cpus++; + } + + // + // For nic based affinity and blacklisted cpus... + // + // Find all the cpus that service interrupts for the specified interfaces + // + // if interface is serviced by a single cpu and promote to socket flag is on + // get list of cpus for the processor socket servicing the interface... + // apply blacklist + // specify affinity with remaining cpu list + // + // if interface is serviced by single cpu and blacklisted, and promote to socket flag is on + // get list of cpus for the processor socket servicing the interface... + // apply blacklist + // specify affinity with remaining cpu list + // + // otherwise ... + // from the list of cpus for the interface, apply blacklist then apply as affinity + // + if ( (cpulist.size() == 1 && get_nic_promotion() ) || ( cpus == 0 && get_nic_promotion() ) ) { + int cpuid = cpulist[0]; + std::ostringstream os; + os << numa_node_of_cpu( cpuid ); + redhawk::affinity::CpuList tlist = get_cpu_list( "socket", os.str() ); + RH_INFO(get_affinity_logger(), "Promoting NIC affinity to PID:" << pid << " SOCKET:" << os.str() ); + cpulist.clear(); + for( int i=0; i < (int)tlist.size();i++ ) { + if ( tlist[i] == cpuid ) continue; + cpulist.push_back( tlist[i] ); + } + } - cpus=0; - for( int i=0; i < (int)cpulist.size();i++ ) { - // check if cpu id is not in blacklist - if ( std::count( blacklist.begin(), blacklist.end(), cpulist[i] ) == 0 ) cpus++; - } + cpus=0; + for( int i=0; i < (int)cpulist.size();i++ ) { + // check if cpu id is not in blacklist + if ( std::count( blacklist.begin(), blacklist.end(), cpulist[i] ) == 0 ) cpus++; + } - if ( cpus > 0 ) { // use cpulist to bind process - bitmask *cpu_mask = numa_allocate_cpumask(); - if ( !cpu_mask ) { - throw redhawk::affinity::AffinityFailed("Unable to allocate node mask"); - } - - for( int i=0; i < (int)cpulist.size();i++ ) { - // check if cpu id is blacklisted - if ( std::count( blacklist.begin(), blacklist.end(), cpulist[i] ) == 0 ) { - RH_NL_DEBUG("gpp::affinity", "Setting NIC (cpu select) available :" << cpulist[i] ); - numa_bitmask_setbit(cpu_mask, cpulist[i]); - } - } - - RH_NL_DEBUG("gpp::affinity", "Setting NIC (cpu select) affinity constraint: :" << iface ); - if ( numa_sched_setaffinity( pid, cpu_mask) ) { - std::ostringstream e; - e << "Binding to NIC with cpu affinity, nic=" << iface; - throw redhawk::affinity::AffinityFailed(e.str()); - } - numa_bitmask_free(cpu_mask); - } - else { - RH_NL_WARN("gpp::affinity", "Setting NIC (cpu select), no cpu available all blacklisted :" << iface ); - std::ostringstream e; - e << "Binding to NIC, no cpus available all blacklisted :" << iface; - throw redhawk::affinity::AffinityFailed(e.str()); - } - } + if ( cpus > 0 ) { // use cpulist to bind process + bitmask *cpu_mask = numa_allocate_cpumask(); + if ( !cpu_mask ) { + throw redhawk::affinity::AffinityFailed("Unable to allocate node mask"); } - else { - RH_NL_WARN("gpp::affinity", "Setting NIC, unable to set directive:" << iface ); - std::ostringstream e; - e << "Binding to NIC, unable to set directive, cannot determine processor socket or cpu list from interrupt mapping, directive:" << iface; - throw redhawk::affinity::AffinityFailed(e.str()); + + for( int i=0; i < (int)cpulist.size();i++ ) { + // check if cpu id is blacklisted + if ( std::count( blacklist.begin(), blacklist.end(), cpulist[i] ) == 0 ) { + RH_DEBUG(get_affinity_logger(), "Setting NIC (cpu select) available :" << cpulist[i] ); + numa_bitmask_setbit(cpu_mask, cpulist[i]); + } } - } - // socket -- assign via processor socket - if ( affinity_spec.first == "socket" ) { - std::string nodestr = affinity_spec.second; - struct bitmask *node_mask = numa_parse_nodestring((char *)nodestr.c_str()); - if ( !node_mask ) { - throw redhawk::affinity::AffinityFailed("Processor socket affinity failed, unable to parse: " + nodestr); + RH_DEBUG(get_affinity_logger(), "Setting NIC (cpu select) affinity constraint: :" << iface ); + if ( numa_sched_setaffinity( pid, cpu_mask) ) { + std::ostringstream e; + e << "Binding to NIC with cpu affinity, nic=" << iface; + throw redhawk::affinity::AffinityFailed(e.str()); } + numa_bitmask_free(cpu_mask); + } + else { + RH_WARN(get_affinity_logger(), "Setting NIC (cpu select), no cpu available all blacklisted :" << iface ); + std::ostringstream e; + e << "Binding to NIC, no cpus available all blacklisted :" << iface; + throw redhawk::affinity::AffinityFailed(e.str()); + } + } + } + else { + RH_WARN(get_affinity_logger(), "Setting NIC, unable to set directive:" << iface ); + std::ostringstream e; + e << "Binding to NIC, unable to set directive, cannot determine processor socket or cpu list from interrupt mapping, directive:" << iface; + throw redhawk::affinity::AffinityFailed(e.str()); + } + } + + // socket -- assign via processor socket + if ( affinity_spec.first == "socket" ) { + std::string nodestr = affinity_spec.second; + struct bitmask *node_mask = numa_parse_nodestring((char *)nodestr.c_str()); + if ( !node_mask ) { + throw redhawk::affinity::AffinityFailed("Processor socket affinity failed, unable to parse: " + nodestr); + } - // plain node binding if no cpus are listed. - if ( blacklist.size() == 0 ) { - // bind to node... let system scheduler do its magic - RH_NL_DEBUG("gpp::affinity", "Setting PROCESSOR SOCKET affinity to constraint :" << nodestr ); - numa_bind( node_mask ); - } - else { // remove blacklisted cpus from node binding - bitmask *cpu_mask = numa_allocate_cpumask(); - if ( !cpu_mask ) { - throw redhawk::affinity::AffinityFailed("Unable to allocate cpu mask"); - } - - // check if node is active, if so then get a cpu id - int nbytes = numa_bitmask_nbytes(node_mask); - for (int i=0; i < nbytes*8; i++ ){ - if ( numa_bitmask_isbitset( node_mask, i ) ) { - numa_node_to_cpus( i, cpu_mask ); - } - } - - // check if cpu id is blacklisted - redhawk::affinity::CpuList::const_iterator biter = blacklist.begin(); - for ( ; biter != blacklist.end() ; biter++ ) { - RH_NL_DEBUG("gpp::affinity", "Setting PROCESSOR SOCKET (cpu select) blacklist :" << *biter ); - numa_bitmask_clearbit(cpu_mask, *biter); - } + // plain node binding if no cpus are listed. + if ( blacklist.size() == 0 ) { + // bind to node... let system scheduler do its magic + RH_DEBUG(get_affinity_logger(), "Setting PROCESSOR SOCKET affinity to constraint :" << nodestr ); + numa_bind( node_mask ); + } + else { // remove blacklisted cpus from node binding + bitmask *cpu_mask = numa_allocate_cpumask(); + if ( !cpu_mask ) { + throw redhawk::affinity::AffinityFailed("Unable to allocate cpu mask"); + } + + // check if node is active, if so then get a cpu id + int nbytes = numa_bitmask_nbytes(node_mask); + for (int i=0; i < nbytes*8; i++ ){ + if ( numa_bitmask_isbitset( node_mask, i ) ) { + numa_node_to_cpus( i, cpu_mask ); + } + } + + // check if cpu id is blacklisted + redhawk::affinity::CpuList::const_iterator biter = blacklist.begin(); + for ( ; biter != blacklist.end() ; biter++ ) { + RH_DEBUG(get_affinity_logger(), "Setting PROCESSOR SOCKET (cpu select) blacklist :" << *biter ); + numa_bitmask_clearbit(cpu_mask, *biter); + } #if 0 - { - // TEST for sched_setaffinity to resolve that not all threads are being confined to cpu set - cpu_set_t cset; - CPU_ZERO(&cset); - int nbytes = numa_bitmask_nbytes(cpu_mask); - for (int i=0; i < nbytes*8; i++ ){ - if ( numa_bitmask_isbitset( cpu_mask, i ) ) { - RH_NL_DEBUG("gpp::affinity", "PTHREAD setting affinity to cpu :" << i ); - CPU_SET(i,&cset); - } - } - - //if ( !pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cset) ) {y - if ( !sched_setaffinity(pid, sizeof(cpu_set_t), &cset) ) { - RH_NL_ERROR("gpp::affinity", "Setting PROCESSOR SOCKET (cpu select), unable to set processor affinity"); - } - - - } + { + // TEST for sched_setaffinity to resolve that not all threads are being confined to cpu set + cpu_set_t cset; + CPU_ZERO(&cset); + int nbytes = numa_bitmask_nbytes(cpu_mask); + for (int i=0; i < nbytes*8; i++ ){ + if ( numa_bitmask_isbitset( cpu_mask, i ) ) { + RH_DEBUG(get_affinity_logger(), "PTHREAD setting affinity to cpu :" << i ); + CPU_SET(i,&cset); + } + } + + //if ( !pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cset) ) {y + if ( !sched_setaffinity(pid, sizeof(cpu_set_t), &cset) ) { + RH_ERROR(get_affinity_logger(), "Setting PROCESSOR SOCKET (cpu select), unable to set processor affinity"); + } + + + } #endif - RH_NL_DEBUG("gpp::affinity", "Setting PROCESSOR SOCKET (cpu select) affinity, pid/constraint:" << pid << "/" << nodestr ); - if ( numa_sched_setaffinity( pid, cpu_mask) ) { - std::ostringstream e; - e << "Binding to PROCESSOR SOCKET with blacklisted cpus, socket=" << nodestr; - throw redhawk::affinity::AffinityFailed(e.str()); - } - numa_bitmask_free(cpu_mask); - } + RH_DEBUG(get_affinity_logger(), "Setting PROCESSOR SOCKET (cpu select) affinity, pid/constraint:" << pid << "/" << nodestr ); + if ( numa_sched_setaffinity( pid, cpu_mask) ) { + std::ostringstream e; + e << "Binding to PROCESSOR SOCKET with blacklisted cpus, socket=" << nodestr; + throw redhawk::affinity::AffinityFailed(e.str()); + } + numa_bitmask_free(cpu_mask); + } - numa_bitmask_free(node_mask); + numa_bitmask_free(node_mask); - } + } - // cpu -- assign via cpu id - if ( affinity_spec.first == "cpu" ) { - std::string cpustr = affinity_spec.second; - struct bitmask *cpu_mask = numa_parse_cpustring((char*)cpustr.c_str()); - if ( !cpu_mask ) { - throw redhawk::affinity::AffinityFailed("CPU affinity failed, unable to parse: <" + cpustr + ">" ); - } - - // apply black list - redhawk::affinity::CpuList::const_iterator biter = blacklist.begin(); - for ( ; biter != blacklist.end() ; biter++ ) { - RH_NL_DEBUG("gpp::affinity", "Setting CPU affinity, blacklist :" << *biter ); - numa_bitmask_clearbit(cpu_mask, *biter); - } + // cpu -- assign via cpu id + if ( affinity_spec.first == "cpu" ) { + std::string cpustr = affinity_spec.second; + struct bitmask *cpu_mask = numa_parse_cpustring((char*)cpustr.c_str()); + if ( !cpu_mask ) { + throw redhawk::affinity::AffinityFailed("CPU affinity failed, unable to parse: <" + cpustr + ">" ); + } - RH_NL_DEBUG("gpp::affinity", "Setting CPU affinity to constraint :" << cpustr ); - if ( numa_sched_setaffinity( pid, cpu_mask ) ) { - std::ostringstream e; - e << "Binding to CPU: " << cpustr; - throw redhawk::affinity::AffinityFailed(e.str()); - } + // apply black list + redhawk::affinity::CpuList::const_iterator biter = blacklist.begin(); + for ( ; biter != blacklist.end() ; biter++ ) { + RH_DEBUG(get_affinity_logger(), "Setting CPU affinity, blacklist :" << *biter ); + numa_bitmask_clearbit(cpu_mask, *biter); + } + + RH_DEBUG(get_affinity_logger(), "Setting CPU affinity to constraint :" << cpustr ); + if ( numa_sched_setaffinity( pid, cpu_mask ) ) { + std::ostringstream e; + e << "Binding to CPU: " << cpustr; + throw redhawk::affinity::AffinityFailed(e.str()); + } - } } + #else - RH_NL_WARN("gpp::affinity", "Missing affinity support from Redhawk libraries, ... ignoring numa affinity based requests "); + RH_WARN(get_affinity_logger(), "Missing affinity support from Redhawk libraries, ... ignoring numa affinity based requests "); #endif // cpuset -- assign via cpuset @@ -463,7 +467,7 @@ namespace gpp { } os << pid << std::endl; os.close(); - RH_NL_DEBUG("gpp::affinity", "Setting CPUSET affinity to constraint :" << cpuset_name ); + RH_DEBUG(get_affinity_logger(), "Setting CPUSET affinity to constraint :" << cpuset_name ); } // cgroup - assign to cgroup @@ -480,7 +484,7 @@ namespace gpp { } os << pid << std::endl; os.close(); - RH_NL_DEBUG("gpp::affinity", "Setting CGROUP affinity to constraint :" << cgroup_name ); + RH_DEBUG(get_affinity_logger(), "Setting CGROUP affinity to constraint :" << cgroup_name ); } } diff --git a/redhawk/src/testing/sdr/dev/devices/GPP/cpp/utils/affinity.h b/redhawk/src/testing/sdr/dev/devices/GPP/cpp/utils/affinity.h index ea4c063ce..274ca6134 100644 --- a/redhawk/src/testing/sdr/dev/devices/GPP/cpp/utils/affinity.h +++ b/redhawk/src/testing/sdr/dev/devices/GPP/cpp/utils/affinity.h @@ -35,6 +35,8 @@ namespace gpp namespace affinity { + bool check_numa(); + /** Find the socket assocated with a particular network interface diff --git a/redhawk/src/testing/sdr/dom/components/busycomp/busycomp.prf.xml b/redhawk/src/testing/sdr/dom/components/busycomp/busycomp.prf.xml new file mode 100644 index 000000000..8f537d89f --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/busycomp/busycomp.prf.xml @@ -0,0 +1,3 @@ + + + diff --git a/redhawk/src/testing/sdr/dom/components/busycomp/busycomp.scd.xml b/redhawk/src/testing/sdr/dom/components/busycomp/busycomp.scd.xml new file mode 100644 index 000000000..df94ceaf5 --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/busycomp/busycomp.scd.xml @@ -0,0 +1,45 @@ + + + + 2.2 + + resource + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/redhawk/src/testing/sdr/dom/components/busycomp/busycomp.spd.xml b/redhawk/src/testing/sdr/dom/components/busycomp/busycomp.spd.xml new file mode 100644 index 000000000..1b850f0c2 --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/busycomp/busycomp.spd.xml @@ -0,0 +1,27 @@ + + + + + + null + + + + + + + + + The implementation contains descriptive information about the template for a software resource. + + + cpp/busycomp.so + + + + + + + + + diff --git a/redhawk/src/testing/sdr/dom/components/busycomp/cpp/Makefile.am b/redhawk/src/testing/sdr/dom/components/busycomp/cpp/Makefile.am new file mode 100644 index 000000000..2094e060a --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/busycomp/cpp/Makefile.am @@ -0,0 +1,58 @@ +# +# This file is protected by Copyright. Please refer to the COPYRIGHT file +# distributed with this source distribution. +# +# This file is part of REDHAWK core. +# +# REDHAWK core is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation, either version 3 of the License, or (at your option) any +# later version. +# +# REDHAWK core is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +# details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/. +# +ossieName = busycomp +libdir = $(prefix)/dom/components/busycomp/cpp +lib_LTLIBRARIES = busycomp.la + +.PHONY: convenience-link clean-convenience-link + +install: + +all-local : convenience-link +clean-local : clean-convenience-link + +convenience-link : busycomp.la + @ln -fs .libs/busycomp.so + +clean-convenience-link: + @rm -f busycomp.so + +distclean-local: + rm -rf m4 + rm -f config.* + rm -rf autom4te.cache + rm -f acinclude.m4 + rm -f aclocal.m4 + rm -f configure + rm -f depcomp + rm -f install-sh + rm -f ltmain.sh + rm -f Makefile.in + rm -f missing + rm -rf .deps + + +# Sources, libraries and library directories are auto-included from a file +# generated by the REDHAWK IDE. You can remove/modify the following lines if +# you wish to manually control these options. +busycomp_la_SOURCES = main.cpp busycomp.cpp busycomp_base.cpp +busycomp_la_LIBADD = $(SOFTPKG_LIBS) $(PROJECTDEPS_LIBS) $(BOOST_LDFLAGS) $(BOOST_THREAD_LIB) $(BOOST_REGEX_LIB) $(BOOST_SYSTEM_LIB) $(INTERFACEDEPS_LIBS) $(redhawk_LDADD_auto) +busycomp_la_CXXFLAGS = -Wall $(SOFTPKG_CFLAGS) $(PROJECTDEPS_CFLAGS) $(BOOST_CPPFLAGS) $(INTERFACEDEPS_CFLAGS) $(redhawk_INCLUDES_auto) +busycomp_la_LDFLAGS = -shared -module -export-dynamic -export-symbols-regex 'make_component' -avoid-version $(redhawk_LDFLAGS_auto) diff --git a/redhawk/src/testing/sdr/dom/components/busycomp/cpp/busycomp.cpp b/redhawk/src/testing/sdr/dom/components/busycomp/cpp/busycomp.cpp new file mode 100644 index 000000000..3d56e38db --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/busycomp/cpp/busycomp.cpp @@ -0,0 +1,249 @@ +/************************************************************************** + + This is the component code. This file contains the child class where + custom functionality can be added to the component. Custom + functionality to the base class can be extended here. Access to + the ports can also be done from this class + +**************************************************************************/ + +#include "busycomp.h" + +PREPARE_LOGGING(busycomp_i) + +busycomp_i::busycomp_i(const char *uuid, const char *label) : + busycomp_base(uuid, label) +{ + // Avoid placing constructor code here. Instead, use the "constructor" function. + +} + +busycomp_i::~busycomp_i() +{ +} + +void busycomp_i::constructor() +{ + /*********************************************************************************** + This is the RH constructor. All properties are properly initialized before this function is called + ***********************************************************************************/ +} + +/*********************************************************************************************** + + Basic functionality: + + The service function is called by the serviceThread object (of type ProcessThread). + This call happens immediately after the previous call if the return value for + the previous call was NORMAL. + If the return value for the previous call was NOOP, then the serviceThread waits + an amount of time defined in the serviceThread's constructor. + + SRI: + To create a StreamSRI object, use the following code: + std::string stream_id = "testStream"; + BULKIO::StreamSRI sri = bulkio::sri::create(stream_id); + + Time: + To create a PrecisionUTCTime object, use the following code: + BULKIO::PrecisionUTCTime tstamp = bulkio::time::utils::now(); + + + Ports: + + Data is passed to the serviceFunction through by reading from input streams + (BulkIO only). The input stream class is a port-specific class, so each port + implementing the BulkIO interface will have its own type-specific input stream. + UDP multicast (dataSDDS and dataVITA49) ports do not support streams. + + The input stream from which to read can be requested with the getCurrentStream() + method. The optional argument to getCurrentStream() is a floating point number that + specifies the time to wait in seconds. A zero value is non-blocking. A negative value + is blocking. Constants have been defined for these values, bulkio::Const::BLOCKING and + bulkio::Const::NON_BLOCKING. + + More advanced uses of input streams are possible; refer to the REDHAWK documentation + for more details. + + Input streams return data blocks that automatically manage the memory for the data + and include the SRI that was in effect at the time the data was received. It is not + necessary to delete the block; it will be cleaned up when it goes out of scope. + + To send data using a BulkIO interface, create an output stream and write the + data to it. When done with the output stream, the close() method sends and end-of- + stream flag and cleans up. + + NOTE: If you have a BULKIO dataSDDS or dataVITA49 port, you must manually call + "port->updateStats()" to update the port statistics when appropriate. + + Example: + // This example assumes that the component has two ports: + // An input (provides) port of type bulkio::InShortPort called dataShort_in + // An output (uses) port of type bulkio::OutFloatPort called dataFloat_out + // The mapping between the port and the class is found + // in the component base class header file + + bulkio::InShortStream inputStream = dataShort_in->getCurrentStream(); + if (!inputStream) { // No streams are available + return NOOP; + } + + // Get the output stream, creating it if it doesn't exist yet + bulkio::OutFloatStream outputStream = dataFloat_out->getStream(inputStream.streamID()); + if (!outputStream) { + outputStream = dataFloat_out->createStream(inputStream.sri()); + } + + bulkio::ShortDataBlock block = inputStream.read(); + if (!block) { // No data available + // Propagate end-of-stream + if (inputStream.eos()) { + outputStream.close(); + } + return NOOP; + } + + if (block.sriChanged()) { + // Update output SRI + outputStream.sri(block.sri()); + } + + // Get read-only access to the input data + redhawk::shared_buffer inputData = block.buffer(); + + // Acquire a new buffer to hold the output data + redhawk::buffer outputData(inputData.size()); + + // Transform input data into output data + for (size_t index = 0; index < inputData.size(); ++index) { + outputData[index] = (float) inputData[index]; + } + + // Write to the output stream; outputData must not be modified after + // this method call + outputStream.write(outputData, block.getStartTime()); + + return NORMAL; + + If working with complex data (i.e., the "mode" on the SRI is set to + true), the data block's complex() method will return true. Data blocks + provide a cxbuffer() method that returns a complex interpretation of the + buffer without making a copy: + + if (block.complex()) { + redhawk::shared_buffer > inData = block.cxbuffer(); + redhawk::buffer > outData(inData.size()); + for (size_t index = 0; index < inData.size(); ++index) { + outData[index] = inData[index]; + } + outputStream.write(outData, block.getStartTime()); + } + + Interactions with non-BULKIO ports are left up to the component developer's discretion + + Messages: + + To receive a message, you need (1) an input port of type MessageEvent, (2) a message prototype described + as a structure property of kind message, (3) a callback to service the message, and (4) to register the callback + with the input port. + + Assuming a property of type message is declared called "my_msg", an input port called "msg_input" is declared of + type MessageEvent, create the following code: + + void busycomp_i::my_message_callback(const std::string& id, const my_msg_struct &msg){ + } + + Register the message callback onto the input port with the following form: + this->msg_input->registerMessage("my_msg", this, &busycomp_i::my_message_callback); + + To send a message, you need to (1) create a message structure, (2) a message prototype described + as a structure property of kind message, and (3) send the message over the port. + + Assuming a property of type message is declared called "my_msg", an output port called "msg_output" is declared of + type MessageEvent, create the following code: + + ::my_msg_struct msg_out; + this->msg_output->sendMessage(msg_out); + + Accessing the Application and Domain Manager: + + Both the Application hosting this Component and the Domain Manager hosting + the Application are available to the Component. + + To access the Domain Manager: + CF::DomainManager_ptr dommgr = this->getDomainManager()->getRef(); + To access the Application: + CF::Application_ptr app = this->getApplication()->getRef(); + + Properties: + + Properties are accessed directly as member variables. For example, if the + property name is "baudRate", it may be accessed within member functions as + "baudRate". Unnamed properties are given the property id as its name. + Property types are mapped to the nearest C++ type, (e.g. "string" becomes + "std::string"). All generated properties are declared in the base class + (busycomp_base). + + Simple sequence properties are mapped to "std::vector" of the simple type. + Struct properties, if used, are mapped to C++ structs defined in the + generated file "struct_props.h". Field names are taken from the name in + the properties file; if no name is given, a generated name of the form + "field_n" is used, where "n" is the ordinal number of the field. + + Example: + // This example makes use of the following Properties: + // - A float value called scaleValue + // - A boolean called scaleInput + + if (scaleInput) { + dataOut[i] = dataIn[i] * scaleValue; + } else { + dataOut[i] = dataIn[i]; + } + + Callback methods can be associated with a property so that the methods are + called each time the property value changes. This is done by calling + addPropertyListener(, this, &busycomp_i::) + in the constructor. + + The callback method receives two arguments, the old and new values, and + should return nothing (void). The arguments can be passed by value, + receiving a copy (preferred for primitive types), or by const reference + (preferred for strings, structs and vectors). + + Example: + // This example makes use of the following Properties: + // - A float value called scaleValue + // - A struct property called status + + //Add to busycomp.cpp + busycomp_i::busycomp_i(const char *uuid, const char *label) : + busycomp_base(uuid, label) + { + addPropertyListener(scaleValue, this, &busycomp_i::scaleChanged); + addPropertyListener(status, this, &busycomp_i::statusChanged); + } + + void busycomp_i::scaleChanged(float oldValue, float newValue) + { + LOG_DEBUG(busycomp_i, "scaleValue changed from" << oldValue << " to " << newValue); + } + + void busycomp_i::statusChanged(const status_struct& oldValue, const status_struct& newValue) + { + LOG_DEBUG(busycomp_i, "status changed"); + } + + //Add to busycomp.h + void scaleChanged(float oldValue, float newValue); + void statusChanged(const status_struct& oldValue, const status_struct& newValue); + + +************************************************************************************************/ +int busycomp_i::serviceFunction() +{ + LOG_DEBUG(busycomp_i, "serviceFunction() example log message"); + + return NORMAL; +} + diff --git a/redhawk/src/testing/sdr/dom/components/busycomp/cpp/busycomp.h b/redhawk/src/testing/sdr/dom/components/busycomp/cpp/busycomp.h new file mode 100644 index 000000000..f5cf1396e --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/busycomp/cpp/busycomp.h @@ -0,0 +1,18 @@ +#ifndef BUSYCOMP_I_IMPL_H +#define BUSYCOMP_I_IMPL_H + +#include "busycomp_base.h" + +class busycomp_i : public busycomp_base +{ + ENABLE_LOGGING + public: + busycomp_i(const char *uuid, const char *label); + ~busycomp_i(); + + void constructor(); + + int serviceFunction(); +}; + +#endif // BUSYCOMP_I_IMPL_H diff --git a/redhawk/src/testing/sdr/dom/components/busycomp/cpp/busycomp_base.cpp b/redhawk/src/testing/sdr/dom/components/busycomp/cpp/busycomp_base.cpp new file mode 100644 index 000000000..bc3ffb71c --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/busycomp/cpp/busycomp_base.cpp @@ -0,0 +1,60 @@ +#include "busycomp_base.h" + +/******************************************************************************************* + + AUTO-GENERATED CODE. DO NOT MODIFY + + The following class functions are for the base class for the component class. To + customize any of these functions, do not modify them here. Instead, overload them + on the child class + +******************************************************************************************/ + +busycomp_base::busycomp_base(const char *uuid, const char *label) : + Component(uuid, label), + ThreadedComponent() +{ + setThreadName(label); + + loadProperties(); +} + +busycomp_base::~busycomp_base() +{ +} + +/******************************************************************************************* + Framework-level functions + These functions are generally called by the framework to perform housekeeping. +*******************************************************************************************/ +void busycomp_base::start() throw (CORBA::SystemException, CF::Resource::StartError) +{ + Component::start(); + ThreadedComponent::startThread(); +} + +void busycomp_base::stop() throw (CORBA::SystemException, CF::Resource::StopError) +{ + Component::stop(); + if (!ThreadedComponent::stopThread()) { + throw CF::Resource::StopError(CF::CF_NOTSET, "Processing thread did not die"); + } +} + +void busycomp_base::releaseObject() throw (CORBA::SystemException, CF::LifeCycle::ReleaseError) +{ + // This function clears the component running condition so main shuts down everything + try { + stop(); + } catch (CF::Resource::StopError& ex) { + // TODO - this should probably be logged instead of ignored + } + + Component::releaseObject(); +} + +void busycomp_base::loadProperties() +{ +} + + diff --git a/redhawk/src/testing/sdr/dom/components/busycomp/cpp/busycomp_base.h b/redhawk/src/testing/sdr/dom/components/busycomp/cpp/busycomp_base.h new file mode 100644 index 000000000..1d6a69421 --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/busycomp/cpp/busycomp_base.h @@ -0,0 +1,27 @@ +#ifndef BUSYCOMP_BASE_IMPL_BASE_H +#define BUSYCOMP_BASE_IMPL_BASE_H + +#include +#include +#include + + +class busycomp_base : public Component, protected ThreadedComponent +{ + public: + busycomp_base(const char *uuid, const char *label); + ~busycomp_base(); + + void start() throw (CF::Resource::StartError, CORBA::SystemException); + + void stop() throw (CF::Resource::StopError, CORBA::SystemException); + + void releaseObject() throw (CF::LifeCycle::ReleaseError, CORBA::SystemException); + + void loadProperties(); + + protected: + + private: +}; +#endif // BUSYCOMP_BASE_IMPL_BASE_H diff --git a/redhawk/src/testing/sdr/dom/components/busycomp/cpp/main.cpp b/redhawk/src/testing/sdr/dom/components/busycomp/cpp/main.cpp new file mode 100644 index 000000000..17391581a --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/busycomp/cpp/main.cpp @@ -0,0 +1,11 @@ +#include +#include "ossie/ossieSupport.h" + +#include "busycomp.h" +extern "C" { + Resource_impl* make_component(const std::string& uuid, const std::string& identifier) + { + return new busycomp_i(uuid.c_str(), identifier.c_str()); + } +} + diff --git a/redhawk/src/testing/sdr/dom/waveforms/busycomp_w/busycomp_w.sad.xml b/redhawk/src/testing/sdr/dom/waveforms/busycomp_w/busycomp_w.sad.xml new file mode 100644 index 000000000..d8eb080cc --- /dev/null +++ b/redhawk/src/testing/sdr/dom/waveforms/busycomp_w/busycomp_w.sad.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + busycomp_1 + + + + + + + + + busycomp_2 + + + + + + + + + msg_through_1 + + + + + + + + + + diff --git a/redhawk/src/testing/tests/test_04_ApplicationMetrics.py b/redhawk/src/testing/tests/test_04_ApplicationMetrics.py new file mode 100644 index 000000000..997a7e0a0 --- /dev/null +++ b/redhawk/src/testing/tests/test_04_ApplicationMetrics.py @@ -0,0 +1,192 @@ +# +# This file is protected by Copyright. Please refer to the COPYRIGHT file +# distributed with this source distribution. +# +# This file is part of REDHAWK core. +# +# REDHAWK core is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation, either version 3 of the License, or (at your option) any +# later version. +# +# REDHAWK core is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +# details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/. +# + +import unittest, time +from _unitTestHelpers import scatest +from ossie.cf import CF, ExtendedCF +from omniORB import any, CORBA +from ossie import properties +from ossie.utils import redhawk +import traceback + +class ApplicationMetrics(scatest.CorbaTestCase): + def setUp(self): + self._app = None + + def tearDown(self): + if self._app: + self._app.ref.stop() + self._app.ref.releaseObject() + + # Do all application shutdown before calling the base class tearDown, + # or failures will probably occur. + scatest.CorbaTestCase.tearDown(self) + + def test_AppAllMetrics(self): + domBooter, self._domMgr = self.launchDomainManager() + dommgr = redhawk.attach(self._domMgr.name) + plainBooter, self._plainnode = self.launchDeviceManager("/nodes/test_GPP_node/DeviceManager.dcd.xml") + dommgr.devices[0].threshold_cycle_time = 100 + + self.assertNotEqual(self._domMgr, None) + self.assertNotEqual(self._plainnode, None) + + time.sleep(1) + + self._app = dommgr.createApplication('/waveforms/busycomp_w/busycomp_w.sad.xml', 'busycomp_w', [], []) + self.assertNotEqual(self._app, None) + time.sleep(1) + self.assertRaises(CF.Application.InvalidMetric, self._app.metrics, ['utilization'], []) + + bc=self._app.metrics(['busycomp_1'], [])[0].value._v + value = -1 + for _val in bc: + if _val.id == 'cores': + value = _val.value._v + self.assertTrue(value<0.1) + bc=self._app.metrics(['busycomp_2'], [])[0].value._v + value = -1 + for _val in bc: + if _val.id == 'cores': + value = _val.value._v + self.assertTrue(value<0.1) + bc=self._app.metrics(['msg_through_1'], [])[0].value._v + value = -1 + for _val in bc: + if _val.id == 'cores': + value = _val.value._v + self.assertTrue(value<0.1) + + self._app.start() + for comp in self._app.comps: + if comp.name == 'msg_through': + comp.stop() + break + time.sleep(2) + + bc=self._app.metrics(['busycomp_1'], [])[0].value._v + value = -1 + for _val in bc: + if _val.id == 'cores': + value = _val.value._v + self.assertAlmostEquals(value, 2, places=1) + + bc=self._app.metrics(['busycomp_2'], [])[0].value._v + value = -1 + for _val in bc: + if _val.id == 'cores': + value = _val.value._v + self.assertAlmostEquals(value, 2, places=1) + bc=self._app.metrics(['msg_through_1'], [])[0].value._v + value = -1 + for _val in bc: + if _val.id == 'cores': + value = _val.value._v + self.assertTrue(value<0.1) + + bc = self._app.metrics([], []) + util_total = {} + moving_total = {} + for _i in bc: + if _i.id == 'busycomp_2': + continue + if _i.id == 'application utilization': + for v in _i.value._v: + if v.id == 'valid': + continue + util_total[v.id] = v.value._v + continue + for v in _i.value._v: + if v.id == 'componenthost': + continue + if v.id == 'valid': + continue + if moving_total.has_key(v.id): + moving_total[v.id] += v.value._v + else: + moving_total[v.id] = v.value._v + for key in util_total: + self.assertEquals(util_total[key],moving_total[key]) + + def test_AppIndividualMetrics(self): + domBooter, self._domMgr = self.launchDomainManager() + dommgr = redhawk.attach(self._domMgr.name) + plainBooter, self._plainnode = self.launchDeviceManager("/nodes/test_GPP_node/DeviceManager.dcd.xml") + dommgr.devices[0].threshold_cycle_time = 100 + + self.assertNotEqual(self._domMgr, None) + self.assertNotEqual(self._plainnode, None) + + time.sleep(1) + + self._app = dommgr.createApplication('/waveforms/busycomp_w/busycomp_w.sad.xml', 'busycomp_w', [], []) + self.assertNotEqual(self._app, None) + time.sleep(1) + self.assertRaises(CF.Application.InvalidMetric, self._app.metrics, ['utilization'], []) + + bc=self._app.metrics([], ['memory']) + self.assertEquals(len(bc), 4) + self.assertEquals(len(bc[0].value._v), 1) + self.assertEquals(bc[0].value._v[0].id, 'memory') + self.assertEquals(bc[3].value._v[0].id, 'memory') + bc=self._app.metrics(['busycomp_1'], ['memory']) + self.assertEquals(len(bc), 1) + self.assertEquals(bc[0].id, 'busycomp_1') + self.assertEquals(len(bc[0].value._v), 1) + self.assertEquals(bc[0].value._v[0].id, 'memory') + bc=self._app.metrics(['application utilization'], ['memory']) + self.assertEquals(len(bc), 1) + self.assertEquals(bc[0].id, 'application utilization') + self.assertEquals(len(bc[0].value._v), 1) + self.assertEquals(bc[0].value._v[0].id, 'memory') + bc=self._app.metrics(['msg_through_1','busycomp_1'], ['memory']) + self.assertEquals(len(bc), 2) + self.assertEquals(bc[0].id, 'msg_through_1') + self.assertEquals(len(bc[0].value._v), 1) + self.assertEquals(bc[0].value._v[0].id, 'memory') + self.assertEquals(bc[1].id, 'busycomp_1') + self.assertEquals(len(bc[1].value._v), 1) + self.assertEquals(bc[1].value._v[0].id, 'memory') + + bc=self._app.metrics([], ['cores', 'memory']) + self.assertEquals(len(bc), 4) + self.assertEquals(len(bc[0].value._v), 2) + self.assertEquals(bc[0].value._v[0].id, 'cores') + self.assertEquals(bc[0].value._v[1].id, 'memory') + self.assertEquals(bc[3].value._v[0].id, 'cores') + self.assertEquals(bc[3].value._v[1].id, 'memory') + bc=self._app.metrics(['busycomp_1'], ['cores', 'memory']) + self.assertEquals(len(bc), 1) + self.assertEquals(bc[0].id, 'busycomp_1') + self.assertEquals(len(bc[0].value._v), 2) + self.assertEquals(bc[0].value._v[0].id, 'cores') + self.assertEquals(bc[0].value._v[1].id, 'memory') + bc=self._app.metrics(['msg_through_1','busycomp_1'], ['cores', 'memory']) + self.assertEquals(len(bc), 2) + self.assertEquals(bc[0].id, 'msg_through_1') + self.assertEquals(len(bc[0].value._v), 2) + self.assertEquals(bc[0].value._v[0].id, 'cores') + self.assertEquals(bc[0].value._v[1].id, 'memory') + self.assertEquals(bc[1].id, 'busycomp_1') + self.assertEquals(len(bc[1].value._v), 2) + self.assertEquals(bc[1].value._v[0].id, 'cores') + self.assertEquals(bc[1].value._v[1].id, 'memory') + + self.assertRaises(CF.Application.InvalidMetric, self._app.metrics, [], ['cord', 'memory']) From 992c45d7b7e25f177b044acaf907a41a389e4ee8 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Mon, 24 Jul 2017 12:09:06 -0400 Subject: [PATCH 0851/1644] Refs CF-1751. Commit source files for updated GPP in core testing --- .../GPP/cpp/parsers/PidProcStatParser.cpp | 90 +++++++ .../GPP/cpp/parsers/PidProcStatParser.h | 79 ++++++ .../sdr/dev/devices/GPP/cpp/states/Limits.cpp | 231 ++++++++++++++++++ .../sdr/dev/devices/GPP/cpp/states/Limits.h | 105 ++++++++ .../devices/GPP/cpp/utils/ConversionWrapper.h | 58 +++++ .../sdr/dev/devices/GPP/cpp/utils/popen.cpp | 61 +++++ .../sdr/dev/devices/GPP/cpp/utils/popen.h | 31 +++ 7 files changed, 655 insertions(+) create mode 100644 redhawk/src/testing/sdr/dev/devices/GPP/cpp/parsers/PidProcStatParser.cpp create mode 100644 redhawk/src/testing/sdr/dev/devices/GPP/cpp/parsers/PidProcStatParser.h create mode 100644 redhawk/src/testing/sdr/dev/devices/GPP/cpp/states/Limits.cpp create mode 100644 redhawk/src/testing/sdr/dev/devices/GPP/cpp/states/Limits.h create mode 100644 redhawk/src/testing/sdr/dev/devices/GPP/cpp/utils/ConversionWrapper.h create mode 100644 redhawk/src/testing/sdr/dev/devices/GPP/cpp/utils/popen.cpp create mode 100644 redhawk/src/testing/sdr/dev/devices/GPP/cpp/utils/popen.h diff --git a/redhawk/src/testing/sdr/dev/devices/GPP/cpp/parsers/PidProcStatParser.cpp b/redhawk/src/testing/sdr/dev/devices/GPP/cpp/parsers/PidProcStatParser.cpp new file mode 100644 index 000000000..9c6da5cb7 --- /dev/null +++ b/redhawk/src/testing/sdr/dev/devices/GPP/cpp/parsers/PidProcStatParser.cpp @@ -0,0 +1,90 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK GPP. + * + * REDHAWK GPP is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK GPP is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ +#include +#include +#include +#include +#include +#include + +#include "PidProcStatParser.h" +#include "ParserExceptions.h" + +#ifdef DEBUG_ON +#define DEBUG(x) x +#else +#define DEBUG(x) +#endif + + +PidProcStatParser::PidProcStatParser( const int pid) : + _pid(pid) +{ + } + +PidProcStatParser::~PidProcStatParser() +{ +} + +void PidProcStatParser::readone(FILE *input, int64_t *x) { fscanf(input, "%lld ", (long long *) x); } +void PidProcStatParser::readunsigned(FILE *input, uint64_t *x) { fscanf(input, "%llu ",(unsigned long long *) x); } +void PidProcStatParser::readstr(FILE *input, char *x) { fscanf(input, "%s ", x);} +void PidProcStatParser::readchar(FILE *input, char *x) { fscanf(input, "%c ", x);} + +const PidProcStatParser::Contents & PidProcStatParser::get() { return _data; }; + +int PidProcStatParser::parse( Contents & data ) +{ + char tcomm[PATH_MAX]; + char state; + int retval=-1; + std::stringstream ss; + ss<<"/proc/"<<_pid<<"/stat"; + FILE *input=fopen(ss.str().c_str(), "r"); + if( !input ) return retval; + readone(input,&data.pid); + readstr(input,tcomm); + data.comm = tcomm; + readchar(input,&state); + data.state = state; + readone(input,&data.ppid); + readone(input,&data.pgrp); + readone(input,&data.session); + readone(input,&data.tty_nr); + readone(input,&data.tty_pgrp); + readone(input,&data.flags); + readone(input,&data.min_flt); + readone(input,&data.cmin_flt); + readone(input,&data.maj_flt); + readone(input,&data.cmaj_flt); + readone(input,&data.utime); + readone(input,&data.stime); + readone(input,&data.cutime); + readone(input,&data.cstime); + fclose(input); + + return 0; +} + + +int PidProcStatParser::parse() { + return parse(_data); +} + diff --git a/redhawk/src/testing/sdr/dev/devices/GPP/cpp/parsers/PidProcStatParser.h b/redhawk/src/testing/sdr/dev/devices/GPP/cpp/parsers/PidProcStatParser.h new file mode 100644 index 000000000..3eec53a1e --- /dev/null +++ b/redhawk/src/testing/sdr/dev/devices/GPP/cpp/parsers/PidProcStatParser.h @@ -0,0 +1,79 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK GPP. + * + * REDHAWK GPP is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK GPP is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ +#ifndef _PIDPROCSTATPARSER_H_ +#define _PIDPROCSTATPARSER_H_ +#include +#include +#include +#include + +class PidProcStatParser { + + public: + + struct Contents { + int64_t pid; + std::string comm; + char state; + int64_t ppid; + int64_t pgrp; + int64_t session; + int64_t tty_nr; + int64_t tty_pgrp; + int64_t flags; + int64_t min_flt; + int64_t cmin_flt; + int64_t maj_flt; + int64_t cmaj_flt; + int64_t utime; + int64_t stime; + int64_t cutime; + int64_t cstime; + }; + +public: + + PidProcStatParser(); + + PidProcStatParser( const int pid ); + + virtual ~PidProcStatParser(); + + int parse(); + int parse( Contents &data ); + const Contents &get(); + inline int64_t get_ticks() { + return _data.utime + _data.stime + _data.cutime + _data.cstime; + } + +private: + + inline void readone(FILE *input, int64_t *x); + inline void readunsigned(FILE *input, uint64_t *x); + inline void readstr(FILE *input, char *x); + inline void readchar(FILE *input, char *x); + + int _pid; + Contents _data; +}; + + + +#endif diff --git a/redhawk/src/testing/sdr/dev/devices/GPP/cpp/states/Limits.cpp b/redhawk/src/testing/sdr/dev/devices/GPP/cpp/states/Limits.cpp new file mode 100644 index 000000000..e420d3d24 --- /dev/null +++ b/redhawk/src/testing/sdr/dev/devices/GPP/cpp/states/Limits.cpp @@ -0,0 +1,231 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK GPP. + * + * REDHAWK GPP is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK GPP is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "Limits.h" +#include "utils/popen.h" + +#if BOOST_FILESYSTEM_VERSION < 3 +#define BOOST_PATH_STRING(x) (x) +#else +#define BOOST_PATH_STRING(x) (x).string() +#endif + +#ifdef DEBUG_ON +#define DEBUG(x) std::cout << x << std::endl +#else +#define DEBUG(x) +#endif + + +const Limits::Contents& +Limits::get() const +{ + return contents; +} + +Limits::Limits() +{ +} + +Limits::~Limits() +{ +} + + + +SysLimits::SysLimits() +{ +} + +SysLimits::~SysLimits() +{ +} + +void SysLimits::update_state() +{ + Contents tmp; + + // grab current file handles + std::string fname; + try{ + fname = "/proc/sys/fs/file-nr"; + std::ifstream file_nr(fname.c_str(), std::ifstream::in); + if ( !file_nr.good()) throw std::ifstream::failure("unable to open " + fname ); + std::string line; + while ( std::getline( file_nr, line ) ) { + std::vector values; + boost::split( values, line, boost::is_any_of(std::string(" \t")), boost::algorithm::token_compress_on ); + DEBUG(" values: " << values.size() << " file-nr line: " << line ); + + if ( values.size() > 2 ) { + try { + tmp.files = boost::lexical_cast( values[0] ); + tmp.files_limit = boost::lexical_cast( values[2] ); + } + catch( boost::bad_lexical_cast ){ + } + } + } + } + catch( ... ) { + } + + try{ + fname = "/proc/sys/kernel/threads-max"; + std::ifstream sys_threads_max(fname.c_str(), std::ifstream::in); + if ( !sys_threads_max.good()) throw std::ifstream::failure("unable to open " + fname ); + std::string line; + while ( std::getline( sys_threads_max, line ) ) { + std::vector values; + boost::split( values, line, boost::is_any_of(std::string(" \t")), boost::algorithm::token_compress_on ); + DEBUG( " sys-kernel-threads-max line: " << line ); + + if ( values.size() > 0 ) { + try { + tmp.threads_limit = boost::lexical_cast( values[0] ); + } + catch( boost::bad_lexical_cast ){ + } + } + } + } + catch( ... ) { + } + + try { + std::string line = utils::popen("ps -eo nlwp | tail -n +2 | awk '{ num_threads += $1 } END { print num_threads }' ", true); + if ( line != "ERROR" ) { + std::vector values; + boost::split(values, line, boost::is_any_of(std::string(" \t")), boost::algorithm::token_compress_on ); + DEBUG(" system active threads: " << line); + if ( values.size() > 0 ) { + try { + tmp.threads = boost::lexical_cast( values[0] ); + } + catch( boost::bad_lexical_cast ){ + } + } + } + + } + catch( ... ) { + } + + DEBUG( " SYSTEM: threads/max " << tmp.threads << "/" << tmp.threads_limit ); + DEBUG( " SYSTEM: files/max " << tmp.files << "/" << tmp.files_limit ); + contents = tmp; +} + + +ProcessLimits::ProcessLimits( const int in_pid) : + pid(in_pid) +{ + if (in_pid<0) pid=getpid(); +} + +ProcessLimits::~ProcessLimits() +{ +} + +void ProcessLimits::update_state() +{ + Contents tmp; + + if ( pid < 0 ) pid = getpid(); + + struct rlimit limit; + if (getrlimit(RLIMIT_NPROC, &limit) == 0) { + tmp.threads_limit = limit.rlim_cur; + } + if (getrlimit(RLIMIT_NOFILE, &limit) == 0) { + tmp.files_limit = limit.rlim_cur; + } + + // + std::ostringstream ppath; + ppath << "/proc/"< values; + boost::split( values, line, boost::is_any_of(std::string(" ")), boost::algorithm::token_compress_on ); + DEBUG( " line: " << line ); + + if ( values.size() > 1 && boost::starts_with( values[0], "Threads:" ) ) { + try { + tmp.threads = boost::lexical_cast( values[1] ); + } + catch( boost::bad_lexical_cast ){ + } + } + } + } + } + + if ( !tmp.threads ) { + std::stringstream subpath; + subpath<< BOOST_PATH_STRING(pid_dir)<<"/task/"; + boost::filesystem::path subPath(subpath.str()); + if (boost::filesystem::exists(subPath)) { + for (boost::filesystem::directory_iterator sub_dir_iter(subPath); + sub_dir_iter!= boost::filesystem::directory_iterator();++sub_dir_iter) { + tmp.threads++; + } + } + } + + std::stringstream subfilepath; + subfilepath<< BOOST_PATH_STRING(pid_dir)<<"/fd/"; + boost::filesystem::path subFilePath(subfilepath.str()); + if (boost::filesystem::exists(subFilePath)) { + for (boost::filesystem::directory_iterator sub_dir_iter(subFilePath); + sub_dir_iter!= boost::filesystem::directory_iterator();++sub_dir_iter) { + tmp.files++; + } + } + + DEBUG( " Process: threads/max " << tmp.threads << "/" << tmp.threads_limit ); + DEBUG( " Process: files/max " << tmp.files << "/" << tmp.files_limit ); + + contents = tmp; +} + + + + + diff --git a/redhawk/src/testing/sdr/dev/devices/GPP/cpp/states/Limits.h b/redhawk/src/testing/sdr/dev/devices/GPP/cpp/states/Limits.h new file mode 100644 index 000000000..dcc5cfc84 --- /dev/null +++ b/redhawk/src/testing/sdr/dev/devices/GPP/cpp/states/Limits.h @@ -0,0 +1,105 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK GPP. + * + * REDHAWK GPP is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK GPP is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ +#ifndef _LIMIT_H_ +#define _LIMIT_H_ +#include +#include +#include +#include +#include +#include "states/State.h" + +class Limits; +typedef boost::shared_ptr LimitsPtr; + +class SysLimits; +typedef boost::shared_ptr SysLimitsPtr; + +class ProcessLimits; +typedef boost::shared_ptr ProcessLimitsPtr; + + +class Limits : public State +{ + + public: + struct Contents { + Contents() : threads(0), threads_limit(-1), files(0), files_limit(-1) {}; + int64_t threads; + int64_t threads_limit; + int64_t files; + int64_t files_limit; + }; + + + // init file and read in baseline stats + Limits(); + + virtual ~Limits(); + + //virtual void update_state(); + + // return contents of file + const Contents &get() const; + + protected: + + Contents contents; + + private: + +}; + + + +class SysLimits : public Limits +{ + + public: + // init file and read in baseline stats + SysLimits(); + + virtual ~SysLimits(); + + void update_state(); + +}; + + + +class ProcessLimits : public Limits +{ + + public: + // init file and read in baseline stats + ProcessLimits(const int pid=-1); + + virtual ~ProcessLimits(); + + void update_state(); + + protected: + + int pid; + +}; + + +#endif // __SYSLIMIT_H__ diff --git a/redhawk/src/testing/sdr/dev/devices/GPP/cpp/utils/ConversionWrapper.h b/redhawk/src/testing/sdr/dev/devices/GPP/cpp/utils/ConversionWrapper.h new file mode 100644 index 000000000..32524181c --- /dev/null +++ b/redhawk/src/testing/sdr/dev/devices/GPP/cpp/utils/ConversionWrapper.h @@ -0,0 +1,58 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK GPP. + * + * REDHAWK GPP is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK GPP is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +#ifndef CONV_WRAPPER_H_ +#define CONV_WRAPPER_H_ +#include +#include +template< class REFERENCE_TYPE, class RETURN_TYPE=REFERENCE_TYPE, class ctype=uint64_t, class CFUNC=std::multiplies< RETURN_TYPE > > +class ConversionWrapper + { + public: + typedef REFERENCE_TYPE type; + typedef RETURN_TYPE result_type; + typedef void argument_type; + typedef CFUNC opfunc; + + explicit ConversionWrapper( type& ref, ctype cf=1048576, const opfunc &func=std::multiplies< result_type >() ): + ref_(ref), func_(func), unit_conversion_(cf) + {}; + + result_type operator()() const { + return func_( static_cast(ref_), (result_type)unit_conversion_ ); + // debug +#if 0 + result_type ret; + ret = func_( static_cast(ref_), (result_type)unit_conversion_ ); + std::cout << " ConversionWrapper: value/cf/result " << ref_ << "/" << unit_conversion_ << "/" << ret << std::endl; + return ret; +#endif + }; + + type& get() const { return ref_; }; + + private: + type &ref_; + opfunc func_; + ctype unit_conversion_; + + }; + +#endif diff --git a/redhawk/src/testing/sdr/dev/devices/GPP/cpp/utils/popen.cpp b/redhawk/src/testing/sdr/dev/devices/GPP/cpp/utils/popen.cpp new file mode 100644 index 000000000..7e1b90b97 --- /dev/null +++ b/redhawk/src/testing/sdr/dev/devices/GPP/cpp/utils/popen.cpp @@ -0,0 +1,61 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK GPP. + * + * REDHAWK GPP is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK GPP is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef DEBUG_ON +#define DEBUG(x) x +#else +#define DEBUG(x) +#endif + +namespace utils { + + std::string popen(const std::string &cmd, const bool first_or_last) { + DEBUG(std::cout << "CMD:" << cmd << std::endl); + FILE* pipe = ::popen(cmd.c_str(), "r"); + if (!pipe) return "ERROR"; + // make sure to popen and it succeeds +#if BOOST_VERSION > 104300 + boost::iostreams::file_descriptor_source pipe_src(fileno(pipe), boost::iostreams::never_close_handle ); +#else + boost::iostreams::file_descriptor_source pipe_src(fileno(pipe) ); +#endif + boost::iostreams::stream stream(pipe_src); + stream.set_auto_close(false); // https://svn.boost.org/trac/boost/ticket/3517 + std::string line; + while(std::getline(stream,line)) { + if ( first_or_last ) break; + DEBUG(std::cout << "LINE-> " + line + " length: " << line.length() << std::endl); + } + pclose(pipe); + return line; + } + + +}; diff --git a/redhawk/src/testing/sdr/dev/devices/GPP/cpp/utils/popen.h b/redhawk/src/testing/sdr/dev/devices/GPP/cpp/utils/popen.h new file mode 100644 index 000000000..0b82b1ed8 --- /dev/null +++ b/redhawk/src/testing/sdr/dev/devices/GPP/cpp/utils/popen.h @@ -0,0 +1,31 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK GPP. + * + * REDHAWK GPP is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK GPP is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ +#ifndef _UTILS_POPEN_H_ +#define _UTILS_POPEN_H_ +#include + +namespace utils { + + std::string popen(const std::string &cmd, const bool first_or_last); + +}; + +#endif + From 241c20e26b8e011a3f2f1b385dfaa292b2c01331 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Mon, 24 Jul 2017 12:09:52 -0400 Subject: [PATCH 0852/1644] Refs CF-1751. Different initializer for PropertyMap use in Application --- redhawk/src/control/sdr/dommgr/Application_impl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/redhawk/src/control/sdr/dommgr/Application_impl.cpp b/redhawk/src/control/sdr/dommgr/Application_impl.cpp index 12c6549d5..6c16566c4 100644 --- a/redhawk/src/control/sdr/dommgr/Application_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/Application_impl.cpp @@ -1322,7 +1322,7 @@ redhawk::PropertyMap Application_impl::measureComponent(redhawk::ApplicationComp retval["valid"] = false; redhawk::PropertyMap query; if (measuredDevices.find(component.getAssignedDevice()->identifier) == measuredDevices.end()) { - query["component_monitor"] = NULL; + query["component_monitor"] = redhawk::Value(); try { (*_dev)->device->query(query); } catch ( ... ) { From 6dfa84e1e23aa9476b72851624edfd353544aad4 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Mon, 24 Jul 2017 12:18:31 -0400 Subject: [PATCH 0853/1644] Refs CF-1751. Use CORBA Python mapping from omniORB 4.1 --- redhawk/src/testing/tests/test_04_ApplicationMetrics.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/redhawk/src/testing/tests/test_04_ApplicationMetrics.py b/redhawk/src/testing/tests/test_04_ApplicationMetrics.py index 997a7e0a0..fe5128ed4 100644 --- a/redhawk/src/testing/tests/test_04_ApplicationMetrics.py +++ b/redhawk/src/testing/tests/test_04_ApplicationMetrics.py @@ -41,7 +41,7 @@ def tearDown(self): def test_AppAllMetrics(self): domBooter, self._domMgr = self.launchDomainManager() - dommgr = redhawk.attach(self._domMgr.name) + dommgr = redhawk.attach(self._domMgr._get_name()) plainBooter, self._plainnode = self.launchDeviceManager("/nodes/test_GPP_node/DeviceManager.dcd.xml") dommgr.devices[0].threshold_cycle_time = 100 @@ -127,7 +127,7 @@ def test_AppAllMetrics(self): def test_AppIndividualMetrics(self): domBooter, self._domMgr = self.launchDomainManager() - dommgr = redhawk.attach(self._domMgr.name) + dommgr = redhawk.attach(self._domMgr._get_name()) plainBooter, self._plainnode = self.launchDeviceManager("/nodes/test_GPP_node/DeviceManager.dcd.xml") dommgr.devices[0].threshold_cycle_time = 100 From 3c1afb3d450486dfa71309c3844dceb0a41a3719 Mon Sep 17 00:00:00 2001 From: 8530 <8530@vm-131.vsi-corp.com> Date: Wed, 26 Jul 2017 12:36:59 -0400 Subject: [PATCH 0854/1644] changed return types for RFSource output ports to use frontend:: definitions, CF-1560 --- .../cpp/fei_exception_through.cpp | 40 ++- .../tests/fei_exc_src/python/fei_exc_src.py | 40 +++ .../tests/test_fei_exception_through.py | 14 +- frontendInterfaces/libsrc/Makefile.am | 1 + .../libsrc/cpp/fe_port_impl.cpp | 274 ++++++++++++++++++ frontendInterfaces/libsrc/cpp/fe_port_impl.h | 208 +------------ .../libsrc/cpp/fe_rfsource_port_impl.cpp | 38 ++- .../libsrc/cpp/fe_rfsource_port_impl.h | 8 +- 8 files changed, 394 insertions(+), 229 deletions(-) create mode 100644 frontendInterfaces/libsrc/cpp/fe_port_impl.cpp diff --git a/codegenTesting/sdr/dev/devices/fei_exception_through/cpp/fei_exception_through.cpp b/codegenTesting/sdr/dev/devices/fei_exception_through/cpp/fei_exception_through.cpp index 4cb0a00f2..afd732425 100644 --- a/codegenTesting/sdr/dev/devices/fei_exception_through/cpp/fei_exception_through.cpp +++ b/codegenTesting/sdr/dev/devices/fei_exception_through/cpp/fei_exception_through.cpp @@ -313,6 +313,23 @@ void fei_exception_through_i::constructor() int fei_exception_through_i::serviceFunction() { LOG_DEBUG(fei_exception_through_i, "serviceFunction() example log message"); + + // test out RFSource output port... + if ( RFSource_out ) { + frontend::RFInfoPktSequence ret =get_available_rf_inputs(""); + if ( ret.size() == 10 ) { + frontend::RFInfoPktSequence::iterator i = ret.begin(); + int cnt=0; + // check freqs.. 0 == 100, 1 == 200 ... + for (; i != ret.end(); i++, cnt++ ) { + double freq=(cnt+1)*100.0; + if ( freq != i->rf_center_freq ) { + LOG_ERROR(fei_exception_through_i, "Match was bad, index = " << cnt); + } + } + + } + } return NOOP; } @@ -517,35 +534,26 @@ void fei_exception_through_i::set_rfinfo_pkt(const std::string& port_name, const std::vector fei_exception_through_i::get_available_rf_inputs(const std::string& port_name) { - std::vector inputs; - FRONTEND::RFInfoPktSequence_var _inputs = this->RFSource_out->available_rf_inputs(); - for (unsigned int i=0; i<_inputs->length(); i++) { - inputs.push_back(frontend::returnRFInfoPkt(_inputs[i])); - } - return inputs; + return this->RFSource_out->available_rf_inputs(); + } void fei_exception_through_i::set_available_rf_inputs(const std::string& port_name, const std::vector &inputs) { - FRONTEND::RFInfoPktSequence_var _inputs = new FRONTEND::RFInfoPktSequence(); - _inputs->length(inputs.size()); - for (unsigned int i=0; iRFSource_out->available_rf_inputs(_inputs); + this->RFSource_out->available_rf_inputs(inputs); } frontend::RFInfoPkt fei_exception_through_i::get_current_rf_input(const std::string& port_name) { frontend::RFInfoPkt pkt; - pkt = frontend::returnRFInfoPkt(*this->RFSource_out->current_rf_input()); + frontend::RFInfoPkt *_ret=0; + _ret = this->RFSource_out->current_rf_input(); + if ( _ret ) { pkt = *_ret; delete _ret; } return pkt; } void fei_exception_through_i::set_current_rf_input(const std::string& port_name, const frontend::RFInfoPkt &pkt) { - FRONTEND::RFInfoPkt_var _pkt = frontend::returnRFInfoPkt(pkt); - this->RFSource_out->current_rf_input(_pkt); + this->RFSource_out->current_rf_input(pkt); } diff --git a/codegenTesting/sdr/dev/devices/fei_exception_through/tests/fei_exc_src/python/fei_exc_src.py b/codegenTesting/sdr/dev/devices/fei_exception_through/tests/fei_exc_src/python/fei_exc_src.py index 0c8ac37aa..334e8a248 100755 --- a/codegenTesting/sdr/dev/devices/fei_exception_through/tests/fei_exc_src/python/fei_exc_src.py +++ b/codegenTesting/sdr/dev/devices/fei_exception_through/tests/fei_exc_src/python/fei_exc_src.py @@ -53,6 +53,8 @@ def constructor(self): """ # TODO add customization here. self.setNumChannels(1, "RX_DIGITIZER"); + self.rf_info_list=None + self.rf_idx=0 def process(self): """ @@ -375,6 +377,44 @@ def get_current_rf_input(self,port_name): def set_current_rf_input(self, port_name, pkt): pass + + ''' + ************************************************************* + Functions servicing the RFInfo port(s) + - port_name is the port over which the call was received + ************************************************************* + ''' + def make_rfinfo(self,freq): + _antennainfo = FRONTEND.AntennaInfo('','','','') + _freqrange = FRONTEND.FreqRange(0,0,[]) + _feedinfo = FRONTEND.FeedInfo('','',_freqrange) + _sensorinfo = FRONTEND.SensorInfo('','','',_antennainfo,_feedinfo) + _rfcapabilities = FRONTEND.RFCapabilities(_freqrange,_freqrange) + _rfinfopkt = FRONTEND.RFInfoPkt('',0.0,0.0,0.0,False,_sensorinfo,[],_rfcapabilities,[]) + _rfinfopkt.rf_center_freq=freq; + _rfinfopkt.rf_bandwidth=freq/2.0; + return _rfinfopkt + + def get_available_rf_inputs(self,port_name): + if not self.rf_info_list: + self.rf_info_list=[] + for x in range(10): + rf=self.make_rfinfo(( (x+1)*100.0)) + self.rf_info_list.append( rf ) + + return self.rf_info_list + + def set_available_rf_inputs(self,port_name, inputs): + pass + + def get_current_rf_input(self,port_name): + _ret=self.rf_info_list[ self.rf_idx ] + self.rf_idx = ( self.rf_idx + 1) % size(self.rf_info_list) + return _ret + + def set_current_rf_input(self, port_name, pkt): + pass + if __name__ == '__main__': logging.getLogger().setLevel(logging.INFO) diff --git a/codegenTesting/sdr/dev/devices/fei_exception_through/tests/test_fei_exception_through.py b/codegenTesting/sdr/dev/devices/fei_exception_through/tests/test_fei_exception_through.py index 652ca50a3..90681bd1d 100644 --- a/codegenTesting/sdr/dev/devices/fei_exception_through/tests/test_fei_exception_through.py +++ b/codegenTesting/sdr/dev/devices/fei_exception_through/tests/test_fei_exception_through.py @@ -79,7 +79,7 @@ def tearDown(self): def testAllocation(self): frontend_alloc = frontend.createTunerAllocation(returnDict=False) retval = self.comp.allocateCapacity([frontend_alloc]) - self.assertEquals(retval, False) + self.assertEquals(retval, True) def testBasicBehavior(self): self.assertEquals(self.got_logmsg, False) @@ -188,5 +188,17 @@ def testBasicBehavior(self): self.assertRaises(exception, RFInfo_in.ref._get_rfinfo_pkt) self.assertRaises(exception, RFInfo_in.ref._set_rfinfo_pkt, _rfinfopkt) + + def test_RFSource_Out(self): + self.assertEquals(self.got_logmsg, False) + ####################################################################### + # Make sure start and stop can be called without throwing exceptions + exc_src = sb.launch('./build/fei_exception_through/tests/fei_exc_src/fei_exc_src.spd.xml') + self.comp.connect(exc_src,usesPortName='RFSource_out') + self.comp.start(); + self.comp.stop(); + sb.release() + + if __name__ == "__main__": ossie.utils.testing.main() # By default tests all implementations diff --git a/frontendInterfaces/libsrc/Makefile.am b/frontendInterfaces/libsrc/Makefile.am index 349c1d3e7..778a2149b 100644 --- a/frontendInterfaces/libsrc/Makefile.am +++ b/frontendInterfaces/libsrc/Makefile.am @@ -36,6 +36,7 @@ libfrontend_@FRONTEND_API_VERSION@_la_LDFLAGS = -version-info $(FRONTEND_SO_VERS libfrontend_@FRONTEND_API_VERSION@_la_LIBADD = $(BULKIO_LIBS) $(OSSIE_LIBS) $(top_builddir)/libfrontendInterfaces.la libfrontend_@FRONTEND_API_VERSION@_la_SOURCES = \ + cpp/fe_port_impl.cpp \ cpp/fe_rfsource_port_impl.cpp \ cpp/fe_tuner_device.cpp diff --git a/frontendInterfaces/libsrc/cpp/fe_port_impl.cpp b/frontendInterfaces/libsrc/cpp/fe_port_impl.cpp new file mode 100644 index 000000000..fd367e707 --- /dev/null +++ b/frontendInterfaces/libsrc/cpp/fe_port_impl.cpp @@ -0,0 +1,274 @@ +/* + * This file is protected by Copyright. Please refer to the COPYRIGHT file + * distributed with this source distribution. + * + * This file is part of REDHAWK frontendInterfaces. + * + * REDHAWK frontendInterfaces is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * REDHAWK frontendInterfaces is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ +#include "fe_port_impl.h" + + +namespace frontend { + + + FRONTEND::RFInfoPkt getRFInfoPkt(const RFInfoPkt &val) { + FRONTEND::RFInfoPkt tmpVal; + tmpVal.rf_flow_id = CORBA::string_dup(val.rf_flow_id.c_str()); + tmpVal.rf_center_freq = val.rf_center_freq; + tmpVal.rf_bandwidth = val.rf_bandwidth; + tmpVal.if_center_freq = val.if_center_freq; + tmpVal.spectrum_inverted = val.spectrum_inverted; + tmpVal.sensor.collector = CORBA::string_dup(val.sensor.collector.c_str()); + tmpVal.sensor.mission = CORBA::string_dup(val.sensor.mission.c_str()); + tmpVal.sensor.rx = CORBA::string_dup(val.sensor.rx.c_str()); + tmpVal.sensor.antenna.description = CORBA::string_dup(val.sensor.antenna.description.c_str()); + tmpVal.sensor.antenna.name = CORBA::string_dup(val.sensor.antenna.name.c_str()); + tmpVal.sensor.antenna.size = CORBA::string_dup(val.sensor.antenna.size.c_str()); + tmpVal.sensor.antenna.type = CORBA::string_dup(val.sensor.antenna.type.c_str()); + tmpVal.sensor.feed.name = CORBA::string_dup(val.sensor.feed.name.c_str()); + tmpVal.sensor.feed.polarization = CORBA::string_dup(val.sensor.feed.polarization.c_str()); + tmpVal.sensor.feed.freq_range.max_val = val.sensor.feed.freq_range.max_val; + tmpVal.sensor.feed.freq_range.min_val = val.sensor.feed.freq_range.min_val; + tmpVal.sensor.feed.freq_range.values.length(val.sensor.feed.freq_range.values.size()); + for (unsigned int i=0; irf_flow_id = CORBA::string_dup(val.rf_flow_id.c_str()); + tmpVal->rf_center_freq = val.rf_center_freq; + tmpVal->rf_bandwidth = val.rf_bandwidth; + tmpVal->if_center_freq = val.if_center_freq; + tmpVal->spectrum_inverted = val.spectrum_inverted; + tmpVal->sensor.collector = CORBA::string_dup(val.sensor.collector.c_str()); + tmpVal->sensor.mission = CORBA::string_dup(val.sensor.mission.c_str()); + tmpVal->sensor.rx = CORBA::string_dup(val.sensor.rx.c_str()); + tmpVal->sensor.antenna.description = CORBA::string_dup(val.sensor.antenna.description.c_str()); + tmpVal->sensor.antenna.name = CORBA::string_dup(val.sensor.antenna.name.c_str()); + tmpVal->sensor.antenna.size = CORBA::string_dup(val.sensor.antenna.size.c_str()); + tmpVal->sensor.antenna.type = CORBA::string_dup(val.sensor.antenna.type.c_str()); + tmpVal->sensor.feed.name = CORBA::string_dup(val.sensor.feed.name.c_str()); + tmpVal->sensor.feed.polarization = CORBA::string_dup(val.sensor.feed.polarization.c_str()); + tmpVal->sensor.feed.freq_range.max_val = val.sensor.feed.freq_range.max_val; + tmpVal->sensor.feed.freq_range.min_val = val.sensor.feed.freq_range.min_val; + tmpVal->sensor.feed.freq_range.values.length(val.sensor.feed.freq_range.values.size()); + for (unsigned int i=0; isensor.feed.freq_range.values[i] = val.sensor.feed.freq_range.values[i]; + } + tmpVal->ext_path_delays.length(val.ext_path_delays.size()); + for (unsigned int i=0; iext_path_delays[i].freq = val.ext_path_delays[i].freq; + tmpVal->ext_path_delays[i].delay_ns = val.ext_path_delays[i].delay_ns; + } + tmpVal->capabilities.freq_range.min_val = val.capabilities.freq_range.min_val; + tmpVal->capabilities.freq_range.max_val = val.capabilities.freq_range.max_val; + tmpVal->capabilities.bw_range.min_val = val.capabilities.bw_range.min_val; + tmpVal->capabilities.bw_range.max_val = val.capabilities.bw_range.max_val; + tmpVal->additional_info = val.additional_info; + return tmpVal; + }; + RFInfoPkt returnRFInfoPkt(const FRONTEND::RFInfoPkt &tmpVal) { + RFInfoPkt val; + val.rf_flow_id = ossie::corba::returnString(tmpVal.rf_flow_id); + val.rf_center_freq = tmpVal.rf_center_freq; + val.rf_bandwidth = tmpVal.rf_bandwidth; + val.if_center_freq = tmpVal.if_center_freq; + val.spectrum_inverted = tmpVal.spectrum_inverted; + val.sensor.collector = ossie::corba::returnString(tmpVal.sensor.collector); + val.sensor.mission = ossie::corba::returnString(tmpVal.sensor.mission); + val.sensor.rx = ossie::corba::returnString(tmpVal.sensor.rx); + val.sensor.antenna.description = ossie::corba::returnString(tmpVal.sensor.antenna.description); + val.sensor.antenna.name = ossie::corba::returnString(tmpVal.sensor.antenna.name); + val.sensor.antenna.size = ossie::corba::returnString(tmpVal.sensor.antenna.size); + val.sensor.antenna.type = ossie::corba::returnString(tmpVal.sensor.antenna.type); + val.sensor.feed.name = ossie::corba::returnString(tmpVal.sensor.feed.name); + val.sensor.feed.polarization = ossie::corba::returnString(tmpVal.sensor.feed.polarization); + val.sensor.feed.freq_range.max_val = tmpVal.sensor.feed.freq_range.max_val; + val.sensor.feed.freq_range.min_val = tmpVal.sensor.feed.freq_range.min_val; + val.sensor.feed.freq_range.values.resize(tmpVal.sensor.feed.freq_range.values.length()); + for (unsigned int i=0; isource_id = CORBA::string_dup(val.source_id.c_str()); + tmpVal->rf_flow_id = CORBA::string_dup(val.rf_flow_id.c_str()); + tmpVal->mode = CORBA::string_dup(val.mode.c_str()); + tmpVal->fom = val.fom; + tmpVal->tfom = val.tfom; + tmpVal->datumID = val.datumID; + tmpVal->time_offset = val.time_offset; + tmpVal->freq_offset = val.freq_offset; + tmpVal->time_variance = val.time_variance; + tmpVal->freq_variance = val.freq_variance; + tmpVal->satellite_count = val.satellite_count; + tmpVal->snr = val.snr; + tmpVal->status_message = CORBA::string_dup(val.status_message.c_str()); + tmpVal->timestamp = val.timestamp; + tmpVal->additional_info = val.additional_info; + return tmpVal; + }; + frontend::GPSInfo returnGPSInfo(const FRONTEND::GPSInfo &tmpVal) { + frontend::GPSInfo val; + val.source_id = ossie::corba::returnString(tmpVal.source_id); + val.rf_flow_id = ossie::corba::returnString(tmpVal.rf_flow_id); + val.mode = ossie::corba::returnString(tmpVal.mode); + val.fom = tmpVal.fom; + val.tfom = tmpVal.tfom; + val.datumID = tmpVal.datumID; + val.time_offset = tmpVal.time_offset; + val.freq_offset = tmpVal.freq_offset; + val.time_variance = tmpVal.time_variance; + val.freq_variance = tmpVal.freq_variance; + val.satellite_count = tmpVal.satellite_count; + val.snr = tmpVal.snr; + val.status_message = ossie::corba::returnString(tmpVal.status_message); + val.timestamp = tmpVal.timestamp; + val.additional_info = tmpVal.additional_info; + return val; + }; + + FRONTEND::GpsTimePos* returnGpsTimePos(const frontend::GpsTimePos &val) { + FRONTEND::GpsTimePos* tmpVal = new FRONTEND::GpsTimePos(); + tmpVal->position.valid = val.position.valid; + tmpVal->position.datum = CORBA::string_dup(val.position.datum.c_str()); + tmpVal->position.lat = val.position.lat; + tmpVal->position.lon = val.position.lon; + tmpVal->position.alt = val.position.alt; + tmpVal->timestamp = val.timestamp; + return tmpVal; + }; + frontend::GpsTimePos returnGpsTimePos(const FRONTEND::GpsTimePos &tmpVal) { + frontend::GpsTimePos val; + val.position.valid = tmpVal.position.valid; + val.position.datum = ossie::corba::returnString(tmpVal.position.datum); + val.position.lat = tmpVal.position.lat; + val.position.lon = tmpVal.position.lon; + val.position.alt = tmpVal.position.alt; + val.timestamp = tmpVal.timestamp; + return val; + }; + FRONTEND::NavigationPacket* returnNavigationPacket(const frontend::NavigationPacket &val) { + FRONTEND::NavigationPacket* tmpVal = new FRONTEND::NavigationPacket(); + tmpVal->source_id = CORBA::string_dup(val.source_id.c_str()); + tmpVal->rf_flow_id = CORBA::string_dup(val.rf_flow_id.c_str()); + tmpVal->position.valid = val.position.valid; + tmpVal->position.datum = CORBA::string_dup(val.position.datum.c_str()); + tmpVal->position.lat = val.position.lat; + tmpVal->position.lon = val.position.lon; + tmpVal->position.alt = val.position.alt; + tmpVal->cposition.valid = val.cposition.valid; + tmpVal->cposition.datum = CORBA::string_dup(val.cposition.datum.c_str()); + tmpVal->cposition.x = val.cposition.x; + tmpVal->cposition.y = val.cposition.y; + tmpVal->cposition.z = val.cposition.z; + tmpVal->velocity.valid = val.velocity.valid; + tmpVal->velocity.datum = CORBA::string_dup(val.velocity.datum.c_str()); + tmpVal->velocity.coordinate_system = CORBA::string_dup(val.velocity.coordinate_system.c_str()); + tmpVal->velocity.x = val.velocity.x; + tmpVal->velocity.y = val.velocity.y; + tmpVal->velocity.z = val.velocity.z; + tmpVal->acceleration.valid = val.acceleration.valid; + tmpVal->acceleration.datum = CORBA::string_dup(val.acceleration.datum.c_str()); + tmpVal->acceleration.coordinate_system = CORBA::string_dup(val.acceleration.coordinate_system.c_str()); + tmpVal->acceleration.x = val.acceleration.x; + tmpVal->acceleration.y = val.acceleration.y; + tmpVal->acceleration.z = val.acceleration.z; + tmpVal->attitude.valid = val.attitude.valid; + tmpVal->attitude.pitch = val.attitude.pitch; + tmpVal->attitude.yaw = val.attitude.yaw; + tmpVal->attitude.roll = val.attitude.roll; + tmpVal->timestamp = val.timestamp; + tmpVal->additional_info = val.additional_info; + return tmpVal; + }; + frontend::NavigationPacket returnNavigationPacket(const FRONTEND::NavigationPacket &tmpVal) { + frontend::NavigationPacket val; + val.source_id = ossie::corba::returnString(tmpVal.source_id); + val.rf_flow_id = ossie::corba::returnString(tmpVal.rf_flow_id); + val.position.valid = tmpVal.position.valid; + val.position.datum = ossie::corba::returnString(tmpVal.position.datum); + val.position.lat = tmpVal.position.lat; + val.position.lon = tmpVal.position.lon; + val.position.alt = tmpVal.position.alt; + val.cposition.valid = tmpVal.cposition.valid; + val.cposition.datum = ossie::corba::returnString(tmpVal.cposition.datum); + val.cposition.x = tmpVal.cposition.x; + val.cposition.y = tmpVal.cposition.y; + val.cposition.z = tmpVal.cposition.z; + val.velocity.valid = tmpVal.velocity.valid; + val.velocity.datum = ossie::corba::returnString(tmpVal.velocity.datum); + val.velocity.coordinate_system = ossie::corba::returnString(tmpVal.velocity.coordinate_system); + val.velocity.x = tmpVal.velocity.x; + val.velocity.y = tmpVal.velocity.y; + val.velocity.z = tmpVal.velocity.z; + val.acceleration.valid = tmpVal.acceleration.valid; + val.acceleration.datum = ossie::corba::returnString(tmpVal.acceleration.datum); + val.acceleration.coordinate_system = ossie::corba::returnString(tmpVal.acceleration.coordinate_system); + val.acceleration.x = tmpVal.acceleration.x; + val.acceleration.y = tmpVal.acceleration.y; + val.acceleration.z = tmpVal.acceleration.z; + val.attitude.valid = tmpVal.attitude.valid; + val.attitude.pitch = tmpVal.attitude.pitch; + val.attitude.yaw = tmpVal.attitude.yaw; + val.attitude.roll = tmpVal.attitude.roll; + val.timestamp = tmpVal.timestamp; + val.additional_info = tmpVal.additional_info; + return val; + }; + + void copyRFInfoPktSequence(const RFInfoPktSequence &src, FRONTEND::RFInfoPktSequence* &dest) { + RFInfoPktSequence::const_iterator i=src.begin(); + for( ; i != src.end(); i++ ) { + ossie::corba::push_back( dest, getRFInfoPkt(*i) ); + } + } + + void copyRFInfoPktSequence(const FRONTEND::RFInfoPktSequence &src, RFInfoPktSequence &dest ) { + for( unsigned int i=0 ; i != src.length(); i++ ) { + dest.push_back( returnRFInfoPkt( src[i] )); + } + } + + +} // end of frontend namespace + diff --git a/frontendInterfaces/libsrc/cpp/fe_port_impl.h b/frontendInterfaces/libsrc/cpp/fe_port_impl.h index 82aa110eb..d2ef88e66 100644 --- a/frontendInterfaces/libsrc/cpp/fe_port_impl.h +++ b/frontendInterfaces/libsrc/cpp/fe_port_impl.h @@ -55,202 +55,18 @@ namespace frontend { }; // END FROM bulkio_p.h - inline FRONTEND::RFInfoPkt* returnRFInfoPkt(const RFInfoPkt &val) { - FRONTEND::RFInfoPkt* tmpVal = new FRONTEND::RFInfoPkt(); - tmpVal->rf_flow_id = CORBA::string_dup(val.rf_flow_id.c_str()); - tmpVal->rf_center_freq = val.rf_center_freq; - tmpVal->rf_bandwidth = val.rf_bandwidth; - tmpVal->if_center_freq = val.if_center_freq; - tmpVal->spectrum_inverted = val.spectrum_inverted; - tmpVal->sensor.collector = CORBA::string_dup(val.sensor.collector.c_str()); - tmpVal->sensor.mission = CORBA::string_dup(val.sensor.mission.c_str()); - tmpVal->sensor.rx = CORBA::string_dup(val.sensor.rx.c_str()); - tmpVal->sensor.antenna.description = CORBA::string_dup(val.sensor.antenna.description.c_str()); - tmpVal->sensor.antenna.name = CORBA::string_dup(val.sensor.antenna.name.c_str()); - tmpVal->sensor.antenna.size = CORBA::string_dup(val.sensor.antenna.size.c_str()); - tmpVal->sensor.antenna.type = CORBA::string_dup(val.sensor.antenna.type.c_str()); - tmpVal->sensor.feed.name = CORBA::string_dup(val.sensor.feed.name.c_str()); - tmpVal->sensor.feed.polarization = CORBA::string_dup(val.sensor.feed.polarization.c_str()); - tmpVal->sensor.feed.freq_range.max_val = val.sensor.feed.freq_range.max_val; - tmpVal->sensor.feed.freq_range.min_val = val.sensor.feed.freq_range.min_val; - tmpVal->sensor.feed.freq_range.values.length(val.sensor.feed.freq_range.values.size()); - for (unsigned int i=0; isensor.feed.freq_range.values[i] = val.sensor.feed.freq_range.values[i]; - } - tmpVal->ext_path_delays.length(val.ext_path_delays.size()); - for (unsigned int i=0; iext_path_delays[i].freq = val.ext_path_delays[i].freq; - tmpVal->ext_path_delays[i].delay_ns = val.ext_path_delays[i].delay_ns; - } - tmpVal->capabilities.freq_range.min_val = val.capabilities.freq_range.min_val; - tmpVal->capabilities.freq_range.max_val = val.capabilities.freq_range.max_val; - tmpVal->capabilities.bw_range.min_val = val.capabilities.bw_range.min_val; - tmpVal->capabilities.bw_range.max_val = val.capabilities.bw_range.max_val; - tmpVal->additional_info = val.additional_info; - return tmpVal; - }; - inline RFInfoPkt returnRFInfoPkt(const FRONTEND::RFInfoPkt &tmpVal) { - RFInfoPkt val; - val.rf_flow_id = ossie::corba::returnString(tmpVal.rf_flow_id); - val.rf_center_freq = tmpVal.rf_center_freq; - val.rf_bandwidth = tmpVal.rf_bandwidth; - val.if_center_freq = tmpVal.if_center_freq; - val.spectrum_inverted = tmpVal.spectrum_inverted; - val.sensor.collector = ossie::corba::returnString(tmpVal.sensor.collector); - val.sensor.mission = ossie::corba::returnString(tmpVal.sensor.mission); - val.sensor.rx = ossie::corba::returnString(tmpVal.sensor.rx); - val.sensor.antenna.description = ossie::corba::returnString(tmpVal.sensor.antenna.description); - val.sensor.antenna.name = ossie::corba::returnString(tmpVal.sensor.antenna.name); - val.sensor.antenna.size = ossie::corba::returnString(tmpVal.sensor.antenna.size); - val.sensor.antenna.type = ossie::corba::returnString(tmpVal.sensor.antenna.type); - val.sensor.feed.name = ossie::corba::returnString(tmpVal.sensor.feed.name); - val.sensor.feed.polarization = ossie::corba::returnString(tmpVal.sensor.feed.polarization); - val.sensor.feed.freq_range.max_val = tmpVal.sensor.feed.freq_range.max_val; - val.sensor.feed.freq_range.min_val = tmpVal.sensor.feed.freq_range.min_val; - val.sensor.feed.freq_range.values.resize(tmpVal.sensor.feed.freq_range.values.length()); - for (unsigned int i=0; isource_id = CORBA::string_dup(val.source_id.c_str()); - tmpVal->rf_flow_id = CORBA::string_dup(val.rf_flow_id.c_str()); - tmpVal->mode = CORBA::string_dup(val.mode.c_str()); - tmpVal->fom = val.fom; - tmpVal->tfom = val.tfom; - tmpVal->datumID = val.datumID; - tmpVal->time_offset = val.time_offset; - tmpVal->freq_offset = val.freq_offset; - tmpVal->time_variance = val.time_variance; - tmpVal->freq_variance = val.freq_variance; - tmpVal->satellite_count = val.satellite_count; - tmpVal->snr = val.snr; - tmpVal->status_message = CORBA::string_dup(val.status_message.c_str()); - tmpVal->timestamp = val.timestamp; - tmpVal->additional_info = val.additional_info; - return tmpVal; - }; - inline frontend::GPSInfo returnGPSInfo(const FRONTEND::GPSInfo &tmpVal) { - frontend::GPSInfo val; - val.source_id = ossie::corba::returnString(tmpVal.source_id); - val.rf_flow_id = ossie::corba::returnString(tmpVal.rf_flow_id); - val.mode = ossie::corba::returnString(tmpVal.mode); - val.fom = tmpVal.fom; - val.tfom = tmpVal.tfom; - val.datumID = tmpVal.datumID; - val.time_offset = tmpVal.time_offset; - val.freq_offset = tmpVal.freq_offset; - val.time_variance = tmpVal.time_variance; - val.freq_variance = tmpVal.freq_variance; - val.satellite_count = tmpVal.satellite_count; - val.snr = tmpVal.snr; - val.status_message = ossie::corba::returnString(tmpVal.status_message); - val.timestamp = tmpVal.timestamp; - val.additional_info = tmpVal.additional_info; - return val; - }; - - inline FRONTEND::GpsTimePos* returnGpsTimePos(const frontend::GpsTimePos &val) { - FRONTEND::GpsTimePos* tmpVal = new FRONTEND::GpsTimePos(); - tmpVal->position.valid = val.position.valid; - tmpVal->position.datum = CORBA::string_dup(val.position.datum.c_str()); - tmpVal->position.lat = val.position.lat; - tmpVal->position.lon = val.position.lon; - tmpVal->position.alt = val.position.alt; - tmpVal->timestamp = val.timestamp; - return tmpVal; - }; - inline frontend::GpsTimePos returnGpsTimePos(const FRONTEND::GpsTimePos &tmpVal) { - frontend::GpsTimePos val; - val.position.valid = tmpVal.position.valid; - val.position.datum = ossie::corba::returnString(tmpVal.position.datum); - val.position.lat = tmpVal.position.lat; - val.position.lon = tmpVal.position.lon; - val.position.alt = tmpVal.position.alt; - val.timestamp = tmpVal.timestamp; - return val; - }; - inline FRONTEND::NavigationPacket* returnNavigationPacket(const frontend::NavigationPacket &val) { - FRONTEND::NavigationPacket* tmpVal = new FRONTEND::NavigationPacket(); - tmpVal->source_id = CORBA::string_dup(val.source_id.c_str()); - tmpVal->rf_flow_id = CORBA::string_dup(val.rf_flow_id.c_str()); - tmpVal->position.valid = val.position.valid; - tmpVal->position.datum = CORBA::string_dup(val.position.datum.c_str()); - tmpVal->position.lat = val.position.lat; - tmpVal->position.lon = val.position.lon; - tmpVal->position.alt = val.position.alt; - tmpVal->cposition.valid = val.cposition.valid; - tmpVal->cposition.datum = CORBA::string_dup(val.cposition.datum.c_str()); - tmpVal->cposition.x = val.cposition.x; - tmpVal->cposition.y = val.cposition.y; - tmpVal->cposition.z = val.cposition.z; - tmpVal->velocity.valid = val.velocity.valid; - tmpVal->velocity.datum = CORBA::string_dup(val.velocity.datum.c_str()); - tmpVal->velocity.coordinate_system = CORBA::string_dup(val.velocity.coordinate_system.c_str()); - tmpVal->velocity.x = val.velocity.x; - tmpVal->velocity.y = val.velocity.y; - tmpVal->velocity.z = val.velocity.z; - tmpVal->acceleration.valid = val.acceleration.valid; - tmpVal->acceleration.datum = CORBA::string_dup(val.acceleration.datum.c_str()); - tmpVal->acceleration.coordinate_system = CORBA::string_dup(val.acceleration.coordinate_system.c_str()); - tmpVal->acceleration.x = val.acceleration.x; - tmpVal->acceleration.y = val.acceleration.y; - tmpVal->acceleration.z = val.acceleration.z; - tmpVal->attitude.valid = val.attitude.valid; - tmpVal->attitude.pitch = val.attitude.pitch; - tmpVal->attitude.yaw = val.attitude.yaw; - tmpVal->attitude.roll = val.attitude.roll; - tmpVal->timestamp = val.timestamp; - tmpVal->additional_info = val.additional_info; - return tmpVal; - }; - inline frontend::NavigationPacket returnNavigationPacket(const FRONTEND::NavigationPacket &tmpVal) { - frontend::NavigationPacket val; - val.source_id = ossie::corba::returnString(tmpVal.source_id); - val.rf_flow_id = ossie::corba::returnString(tmpVal.rf_flow_id); - val.position.valid = tmpVal.position.valid; - val.position.datum = ossie::corba::returnString(tmpVal.position.datum); - val.position.lat = tmpVal.position.lat; - val.position.lon = tmpVal.position.lon; - val.position.alt = tmpVal.position.alt; - val.cposition.valid = tmpVal.cposition.valid; - val.cposition.datum = ossie::corba::returnString(tmpVal.cposition.datum); - val.cposition.x = tmpVal.cposition.x; - val.cposition.y = tmpVal.cposition.y; - val.cposition.z = tmpVal.cposition.z; - val.velocity.valid = tmpVal.velocity.valid; - val.velocity.datum = ossie::corba::returnString(tmpVal.velocity.datum); - val.velocity.coordinate_system = ossie::corba::returnString(tmpVal.velocity.coordinate_system); - val.velocity.x = tmpVal.velocity.x; - val.velocity.y = tmpVal.velocity.y; - val.velocity.z = tmpVal.velocity.z; - val.acceleration.valid = tmpVal.acceleration.valid; - val.acceleration.datum = ossie::corba::returnString(tmpVal.acceleration.datum); - val.acceleration.coordinate_system = ossie::corba::returnString(tmpVal.acceleration.coordinate_system); - val.acceleration.x = tmpVal.acceleration.x; - val.acceleration.y = tmpVal.acceleration.y; - val.acceleration.z = tmpVal.acceleration.z; - val.attitude.valid = tmpVal.attitude.valid; - val.attitude.pitch = tmpVal.attitude.pitch; - val.attitude.yaw = tmpVal.attitude.yaw; - val.attitude.roll = tmpVal.attitude.roll; - val.timestamp = tmpVal.timestamp; - val.additional_info = tmpVal.additional_info; - return val; - }; + FRONTEND::RFInfoPkt getRFInfoPkt(const RFInfoPkt &val); + FRONTEND::RFInfoPkt* returnRFInfoPkt(const RFInfoPkt &val); + RFInfoPkt returnRFInfoPkt(const FRONTEND::RFInfoPkt &tmpVal); + FRONTEND::GPSInfo* returnGPSInfo(const frontend::GPSInfo &val); + frontend::GPSInfo returnGPSInfo(const FRONTEND::GPSInfo &tmpVal); + FRONTEND::GpsTimePos* returnGpsTimePos(const frontend::GpsTimePos &val); + frontend::GpsTimePos returnGpsTimePos(const FRONTEND::GpsTimePos &tmpVal); + FRONTEND::NavigationPacket* returnNavigationPacket(const frontend::NavigationPacket &val); + frontend::NavigationPacket returnNavigationPacket(const FRONTEND::NavigationPacket &tmpVal); + void copyRFInfoPktSequence(const RFInfoPktSequence &src, FRONTEND::RFInfoPktSequence* &dest); + void copyRFInfoPktSequence(const FRONTEND::RFInfoPktSequence &src, RFInfoPktSequence &dest ); + // ---------------------------------------------------------------------------------------- // OutFrontendPort declaration // ---------------------------------------------------------------------------------------- diff --git a/frontendInterfaces/libsrc/cpp/fe_rfsource_port_impl.cpp b/frontendInterfaces/libsrc/cpp/fe_rfsource_port_impl.cpp index 80f91b903..f05fe9624 100644 --- a/frontendInterfaces/libsrc/cpp/fe_rfsource_port_impl.cpp +++ b/frontendInterfaces/libsrc/cpp/fe_rfsource_port_impl.cpp @@ -34,62 +34,76 @@ namespace frontend { { } - FRONTEND::RFInfoPktSequence* OutRFSourcePort::available_rf_inputs() + RFInfoPktSequence OutRFSourcePort::available_rf_inputs() { - FRONTEND::RFInfoPktSequence_var retval = new FRONTEND::RFInfoPktSequence(); + FRONTEND::RFInfoPktSequence_var _retval; + RFInfoPktSequence retval; std::vector < std::pair < FRONTEND::RFSource_var, std::string > >::iterator i; boost::mutex::scoped_lock lock(updatingPortsLock); // don't want to process while command information is coming in if (active) { for (i = outConnections.begin(); i != outConnections.end(); ++i) { - retval = ((*i).first)->available_rf_inputs(); + try { + _retval = ((*i).first)->available_rf_inputs(); + }catch(...){ + // should handle errors + } } + frontend::copyRFInfoPktSequence(_retval.in(), retval); } - return retval._retn(); + return retval; } - void OutRFSourcePort::available_rf_inputs(const FRONTEND::RFInfoPktSequence& data) + void OutRFSourcePort::available_rf_inputs(const RFInfoPktSequence& data) { std::vector < std::pair < FRONTEND::RFSource_var, std::string > >::iterator i; boost::mutex::scoped_lock lock(updatingPortsLock); // don't want to process while command information is coming in if (active) { + FRONTEND::RFInfoPktSequence_var _data = new FRONTEND::RFInfoPktSequence(); + frontend::copyRFInfoPktSequence(data, _data.out()); for (i = outConnections.begin(); i != outConnections.end(); ++i) { - ((*i).first)->available_rf_inputs(data); + ((*i).first)->available_rf_inputs(_data); } } return; } - FRONTEND::RFInfoPkt* OutRFSourcePort::current_rf_input() + RFInfoPkt *OutRFSourcePort::current_rf_input() { - FRONTEND::RFInfoPkt_var retval = new FRONTEND::RFInfoPkt(); + FRONTEND::RFInfoPkt_var _retval; + RFInfoPkt *retval = 0; std::vector < std::pair < FRONTEND::RFSource_var, std::string > >::iterator i; boost::mutex::scoped_lock lock(updatingPortsLock); // don't want to process while command information is coming in if (active) { for (i = outConnections.begin(); i != outConnections.end(); ++i) { - retval = ((*i).first)->current_rf_input(); + _retval = ((*i).first)->current_rf_input(); } + + RFInfoPkt __retval; + __retval = frontend::returnRFInfoPkt(_retval); + retval= new RFInfoPkt(__retval); } - return retval._retn(); + return retval; } - void OutRFSourcePort::current_rf_input(const FRONTEND::RFInfoPkt& data) + void OutRFSourcePort::current_rf_input(const RFInfoPkt& data) { std::vector < std::pair < FRONTEND::RFSource_var, std::string > >::iterator i; boost::mutex::scoped_lock lock(updatingPortsLock); // don't want to process while command information is coming in if (active) { + FRONTEND::RFInfoPkt_var _data = frontend::returnRFInfoPkt(data); for (i = outConnections.begin(); i != outConnections.end(); ++i) { - ((*i).first)->current_rf_input(data); + ((*i).first)->current_rf_input(_data); } } diff --git a/frontendInterfaces/libsrc/cpp/fe_rfsource_port_impl.h b/frontendInterfaces/libsrc/cpp/fe_rfsource_port_impl.h index bdf8189ed..05c91ab5d 100644 --- a/frontendInterfaces/libsrc/cpp/fe_rfsource_port_impl.h +++ b/frontendInterfaces/libsrc/cpp/fe_rfsource_port_impl.h @@ -102,10 +102,10 @@ namespace frontend { OutRFSourcePort(std::string port_name); ~OutRFSourcePort(); - FRONTEND::RFInfoPktSequence* available_rf_inputs(); - void available_rf_inputs(const FRONTEND::RFInfoPktSequence& data); - FRONTEND::RFInfoPkt* current_rf_input(); - void current_rf_input(const FRONTEND::RFInfoPkt& data);; + frontend::RFInfoPktSequence available_rf_inputs(); + void available_rf_inputs(const RFInfoPktSequence& data); + frontend::RFInfoPkt *current_rf_input(); + void current_rf_input(const RFInfoPkt& data);; }; } // end of frontend namespace From 1df18469aec2544e57576c87af498393ad30f1c9 Mon Sep 17 00:00:00 2001 From: 8530 <8530@vm-131.vsi-corp.com> Date: Mon, 19 Jun 2017 10:40:51 -0400 Subject: [PATCH 0855/1644] fix issue from change in import statement, CF-1780 --- .../base/framework/python/ossie/utils/sb/io_helpers.py | 2 +- redhawk/src/testing/tests/test_13_TestSB.py | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py b/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py index d234eddb3..f497604b0 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py +++ b/redhawk/src/base/framework/python/ossie/utils/sb/io_helpers.py @@ -1149,7 +1149,7 @@ def __init__(self): Helper to handle the generation of SDDS metadata forwarding """ _SourceBase.__init__(self, bytesPerPush = 0, dataFormat='sdds', formats=['sdds']) - self._src = _bulkio_data_helpers.SDDSSource() + self._src = bulkio_data_helpers.SDDSSource() self._blocking = True self._streamdefs = {} diff --git a/redhawk/src/testing/tests/test_13_TestSB.py b/redhawk/src/testing/tests/test_13_TestSB.py index 567e79b19..f3f4fd194 100644 --- a/redhawk/src/testing/tests/test_13_TestSB.py +++ b/redhawk/src/testing/tests/test_13_TestSB.py @@ -1584,6 +1584,14 @@ def test_NotSharedComponent(self): self.assertNotEqual(int(comp1.pid), int(comp2.pid)) +class Test_DataSDDSSource(unittest.TestCase): + + def test_CreateSDDSSource(self): + source = sb.DataSourceSDDS() + self.assertNotEquals(source, None) + + + class BulkioTest(unittest.TestCase): XMLDATA = """ From 554f0a8fa0cc3ca0dfd1b4156ad78892d9b75c8c Mon Sep 17 00:00:00 2001 From: 8530 <8530@vm-131.vsi-corp.com> Date: Fri, 28 Jul 2017 13:44:47 -0400 Subject: [PATCH 0856/1644] fix issue when tracking changes --- .../src/base/framework/python/ossie/utils/sdds/sdds_analyzer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/sdds/sdds_analyzer.py b/redhawk/src/base/framework/python/ossie/utils/sdds/sdds_analyzer.py index ff0a8b590..e709653ce 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sdds/sdds_analyzer.py +++ b/redhawk/src/base/framework/python/ossie/utils/sdds/sdds_analyzer.py @@ -31,7 +31,7 @@ class SDDSAnalyzer(object): __len__ - returns the number of packets """ - _VAILID_VAL_='+' + _VALID_VAL_='+' _TRACK_OK_='-' _TRACK_ERROR_='***' From f357f70a97ef9a1aba475f2136d7e4dbd4e4fcdf Mon Sep 17 00:00:00 2001 From: 8530 <8530@vm-131.vsi-corp.com> Date: Fri, 28 Jul 2017 15:23:44 -0400 Subject: [PATCH 0857/1644] fix pkt_end check when dumping packets --- .../python/ossie/utils/sdds/sdds_analyzer.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/redhawk/src/base/framework/python/ossie/utils/sdds/sdds_analyzer.py b/redhawk/src/base/framework/python/ossie/utils/sdds/sdds_analyzer.py index e709653ce..991eb8623 100644 --- a/redhawk/src/base/framework/python/ossie/utils/sdds/sdds_analyzer.py +++ b/redhawk/src/base/framework/python/ossie/utils/sdds/sdds_analyzer.py @@ -60,6 +60,8 @@ def dumpRawPackets(self, pkt_start=0, pkt_end=None, row_width=80, bytes_per_grou pkt_end = self.npkts_ if pkt_len: pkt_end = self.npkts_ + else: + pkt_end = pkt_end + 1 if pkt_len == None: pkt_len = self.pkt_len_ genf=self._gen_hex_dump( self.raw_data_, pkt_start, pkt_len, row_width, bytes_per_group ) @@ -77,7 +79,10 @@ def dumpRawPackets(self, pkt_start=0, pkt_end=None, row_width=80, bytes_per_grou def dumpPackets(self, pkt_start=0, pkt_end=None, payload_start=0, payload_end=40, raw_payload=False, header_only=False, use_pager=True ): genf=self._gen_packet( self.raw_data_, pkt_start ) - if pkt_end == None: pkt_end = self.npkts_ + if pkt_end == None: + pkt_end = self.npkts_ + else: + pkt_end = pkt_end + 1 res = StringIO() for i, pkt in enumerate(genf,pkt_start): if i < pkt_end: @@ -180,7 +185,10 @@ def trackChanges(self, pkt_start=0, pkt_end=None, repeat_header=20, use_pager=Tr def getPacketIterator(self, pkt_start=0, pkt_end=None ): genf=self._gen_packet( self.raw_data_, pkt_start ) - if pkt_end == None: pkt_end = self.npkts_ + if pkt_end == None: + pkt_end = self.npkts_ + else: + pkt_end +=1 for i, pkt in enumerate(genf,pkt_start): if i < pkt_end: yield i,pkt From d2242e4ebb3e43853c657dc84f34e0fbdb4289ea Mon Sep 17 00:00:00 2001 From: Max Robert Date: Fri, 28 Jul 2017 16:03:09 -0400 Subject: [PATCH 0858/1644] Refs CF-1586. Added fei-aware connect functionality to the sandbox --- .../libsrc/python/output_ports.py | 3 + .../sdr/dev/devices/fei_src/.fei_src.wavedev | 6 + .../sdr/dev/devices/fei_src/.md5sums | 2 + .../sdr/dev/devices/fei_src/fei_src.prf.xml | 102 +++++ .../sdr/dev/devices/fei_src/fei_src.scd.xml | 73 ++++ .../sdr/dev/devices/fei_src/fei_src.spd.xml | 25 ++ .../sdr/dev/devices/fei_src/python/.md5sums | 6 + .../sdr/dev/devices/fei_src/python/fei_src.py | 383 ++++++++++++++++++ .../sdr/dev/devices/fei_src/tests/.md5sums | 1 + .../dev/devices/fei_src/tests/test_fei_src.py | 121 ++++++ .../python/ossie/utils/model/__init__.py | 39 +- .../testing/tests/test_15_LoggingConfig.py | 29 ++ 12 files changed, 789 insertions(+), 1 deletion(-) create mode 100644 codegenTesting/sdr/dev/devices/fei_src/.fei_src.wavedev create mode 100644 codegenTesting/sdr/dev/devices/fei_src/.md5sums create mode 100644 codegenTesting/sdr/dev/devices/fei_src/fei_src.prf.xml create mode 100644 codegenTesting/sdr/dev/devices/fei_src/fei_src.scd.xml create mode 100644 codegenTesting/sdr/dev/devices/fei_src/fei_src.spd.xml create mode 100644 codegenTesting/sdr/dev/devices/fei_src/python/.md5sums create mode 100755 codegenTesting/sdr/dev/devices/fei_src/python/fei_src.py create mode 100644 codegenTesting/sdr/dev/devices/fei_src/tests/.md5sums create mode 100644 codegenTesting/sdr/dev/devices/fei_src/tests/test_fei_src.py diff --git a/bulkioInterfaces/libsrc/python/output_ports.py b/bulkioInterfaces/libsrc/python/output_ports.py index a1b1454bd..42194d62b 100644 --- a/bulkioInterfaces/libsrc/python/output_ports.py +++ b/bulkioInterfaces/libsrc/python/output_ports.py @@ -363,6 +363,9 @@ def _pushPacket(self, data, T, EOS, streamID): for connId, port in self.outConnections.items(): try: if port != None: + if connId not in self.sriDict[streamID].connections and len(data) == 0: + # connection is being closed but no data was ever sent, so ignore + continue if connId not in self.sriDict[streamID].connections: port.pushSRI(self.sriDict[streamID].sri) self.sriDict[streamID].connections.add(connId) diff --git a/codegenTesting/sdr/dev/devices/fei_src/.fei_src.wavedev b/codegenTesting/sdr/dev/devices/fei_src/.fei_src.wavedev new file mode 100644 index 000000000..d1ea167e5 --- /dev/null +++ b/codegenTesting/sdr/dev/devices/fei_src/.fei_src.wavedev @@ -0,0 +1,6 @@ + + + + + + diff --git a/codegenTesting/sdr/dev/devices/fei_src/.md5sums b/codegenTesting/sdr/dev/devices/fei_src/.md5sums new file mode 100644 index 000000000..169d75b51 --- /dev/null +++ b/codegenTesting/sdr/dev/devices/fei_src/.md5sums @@ -0,0 +1,2 @@ +f6f2a29cc59001538ca0f857cc33799d fei_src.spec +7e35e10f3e5ecc313d95333317184d9f build.sh diff --git a/codegenTesting/sdr/dev/devices/fei_src/fei_src.prf.xml b/codegenTesting/sdr/dev/devices/fei_src/fei_src.prf.xml new file mode 100644 index 000000000..4fc24f7e2 --- /dev/null +++ b/codegenTesting/sdr/dev/devices/fei_src/fei_src.prf.xml @@ -0,0 +1,102 @@ + + + + + This specifies the device kind + FRONTEND::TUNER + + + + + This specifies the specific device + + + + + Status of each tuner, including entries for both allocated and un-allocated tuners. Each entry represents a single tuner. + + + Comma separated list of current Allocation IDs. + + + Current bandwidth in Hz + Hz + + + Current center frequency in Hz. + Hz + + + Indicates if tuner is enabled, in reference to the output state of the tuner. + + + Unique ID that specifies a group of Device. + + + Specifies a certain RF flow to allocate against. + + + Current sample rate in samples per second. + sps + + + Example Tuner Types: TX, RX, CHANNELIZER, DDC, RX_DIGITIZER, RX_DIGTIZIER_CHANNELIZER + + + + + + Frontend Interfaces v2 listener allocation structure + + + + + + Frontend Interfaces v2 main allocation structure + + Example Tuner Types: TX, RX, CHANNELIZER, DDC, RX_DIGITIZER, RX_DIGTIZIER_CHANNELIZER + + + The allocation_id set by the caller. Used by the caller to reference the allocation uniquely + + + Requested center frequency + Hz + + + Requested bandwidth (+/- the tolerance) + Hz + + + Allowable Percent above requested bandwidth (ie - 100 would be up to twice) + percent + + + Requested sample rate (+/- the tolerance). This can be ignored for such devices as analog tuners + Hz + + + Allowable Percent above requested sample rate (ie - 100 would be up to twice) + percent + + + True: Has control over the device to make changes +False: Does not need control and can just attach to any currently tasked device that satisfies the parameters (essentually a listener) + + + Unique identifier that specifies the group a device must be in. Must match group_id on the device + + + Optional. Specifies the RF flow of a specific input source to allocate against. If left empty, it will match all FrontEnd devices. + + + + + + + + + + + + diff --git a/codegenTesting/sdr/dev/devices/fei_src/fei_src.scd.xml b/codegenTesting/sdr/dev/devices/fei_src/fei_src.scd.xml new file mode 100644 index 000000000..fa312e702 --- /dev/null +++ b/codegenTesting/sdr/dev/devices/fei_src/fei_src.scd.xml @@ -0,0 +1,73 @@ + + + + 2.2 + + device + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/codegenTesting/sdr/dev/devices/fei_src/fei_src.spd.xml b/codegenTesting/sdr/dev/devices/fei_src/fei_src.spd.xml new file mode 100644 index 000000000..14c6529dc --- /dev/null +++ b/codegenTesting/sdr/dev/devices/fei_src/fei_src.spd.xml @@ -0,0 +1,25 @@ + + + + + + null + + + + + + + + + The implementation contains descriptive information about the template for a software resource. + + + python/fei_src.py + + + + + + + diff --git a/codegenTesting/sdr/dev/devices/fei_src/python/.md5sums b/codegenTesting/sdr/dev/devices/fei_src/python/.md5sums new file mode 100644 index 000000000..4b6c40b00 --- /dev/null +++ b/codegenTesting/sdr/dev/devices/fei_src/python/.md5sums @@ -0,0 +1,6 @@ +8bfcd22353c3a57fee561ad86ee2a56b reconf +158196b688b5b0360e37ef98481028a1 fei_src.py +144eaa191497c9563235f7a811f7076e fei_src_base.py +2eddc7677137b4c8c6a0100cc06b7a6f configure.ac +fbb2dec4590f0c6f0855de1d8e5329f2 Makefile.am +fcb710dca24448d72c477de9580f395a Makefile.am.ide diff --git a/codegenTesting/sdr/dev/devices/fei_src/python/fei_src.py b/codegenTesting/sdr/dev/devices/fei_src/python/fei_src.py new file mode 100755 index 000000000..025f8e016 --- /dev/null +++ b/codegenTesting/sdr/dev/devices/fei_src/python/fei_src.py @@ -0,0 +1,383 @@ +#!/usr/bin/env python +# +# +# AUTO-GENERATED +# +# Source: fei_src.spd.xml +from ossie.device import start_device +import logging + +from fei_src_base import * + +class fei_src_i(fei_src_base): + """""" + def constructor(self): + """ + This is called by the framework immediately after your device registers with the system. + + In general, you should add customization here and not in the __init__ constructor. If you have + a custom port implementation you can override the specific implementation here with a statement + similar to the following: + self.some_port = MyPortImplementation() + + For a tuner device, the structure frontend_tuner_status needs to match the number + of tuners that this device controls and what kind of device it is. + The options for devices are: TX, RX, RX_DIGITIZER, CHANNELIZER, DDC, RC_DIGITIZER_CHANNELIZER + + For example, if this device has 5 physical + tuners, 3 RX_DIGITIZER and 2 CHANNELIZER, then the code in the construct function + should look like this: + + self.addChannels(3, "RX_DIGITIZER"); + self.addChannels(2, "CHANNELIZER"); + + The incoming request for tuning contains a string describing the requested tuner + type. The string for the request must match the string in the tuner status. + """ + # TODO add customization here. + self.addChannels(1, "RX_DIGITIZER"); + self._stream_started = False + self._H = None + self.data_count = 0 + + def process(self): + """ + Basic functionality: + + The process method should process a single "chunk" of data and then return. This method + will be called from the processing thread again, and again, and again until it returns + FINISH or stop() is called on the device. If no work is performed, then return NOOP. + + StreamSRI: + To create a StreamSRI object, use the following code (this generates a normalized SRI that does not flush the queue when full): + sri = bulkio.sri.create("my_stream_id") + + To create a StreamSRI object based on tuner status structure index 'idx' and collector center frequency of 100: + sri = frontend.sri.create("my_stream_id", self.frontend_tuner_status[idx], self._id, collector_frequency=100) + + PrecisionUTCTime: + To create a PrecisionUTCTime object, use the following code: + tstamp = bulkio.timestamp.now() + + Ports: + + Each port instance is accessed through members of the following form: self.port_ + + Data is obtained in the process function through the getPacket call (BULKIO only) on a + provides port member instance. The optional argument is a timeout value, in seconds. + A zero value is non-blocking, while a negative value is blocking. Constants have been + defined for these values, bulkio.const.BLOCKING and bulkio.const.NON_BLOCKING. If no + timeout is given, it defaults to non-blocking. + + The return value is a named tuple with the following fields: + - dataBuffer + - T + - EOS + - streamID + - SRI + - sriChanged + - inputQueueFlushed + If no data is available due to a timeout, all fields are None. + + To send data, call the appropriate function in the port directly. In the case of BULKIO, + convenience functions have been added in the port classes that aid in output. + + Interactions with non-BULKIO ports are left up to the device developer's discretion. + + Messages: + + To receive a message, you need (1) an input port of type MessageEvent, (2) a message prototype described + as a structure property of kind message, (3) a callback to service the message, and (4) to register the callback + with the input port. + + Assuming a property of type message is declared called "my_msg", an input port called "msg_input" is declared of + type MessageEvent, create the following code: + + def msg_callback(self, msg_id, msg_value): + print msg_id, msg_value + + Register the message callback onto the input port with the following form: + self.port_input.registerMessage("my_msg", fei_src_i.MyMsg, self.msg_callback) + + To send a message, you need to (1) create a message structure, and (2) send the message over the port. + + Assuming a property of type message is declared called "my_msg", an output port called "msg_output" is declared of + type MessageEvent, create the following code: + + msg_out = fei_src_i.MyMsg() + this.port_msg_output.sendMessage(msg_out) + + Accessing the Application and Domain Manager: + + Both the Application hosting this Component and the Domain Manager hosting + the Application are available to the Component. + + To access the Domain Manager: + dommgr = self.getDomainManager().getRef(); + To access the Application: + app = self.getApplication().getRef(); + Properties: + + Properties are accessed directly as member variables. If the property name is baudRate, + then accessing it (for reading or writing) is achieved in the following way: self.baudRate. + + To implement a change callback notification for a property, create a callback function with the following form: + + def mycallback(self, id, old_value, new_value): + pass + + where id is the property id, old_value is the previous value, and new_value is the updated value. + + The callback is then registered on the component as: + self.addPropertyChangeListener('baudRate', self.mycallback) + + Allocation: + + Allocation callbacks are available to customize a Device's response to an allocation request. + Callback allocation/deallocation functions are registered using the setAllocationImpl function, + usually in the initialize() function + For example, allocation property "my_alloc" can be registered with allocation function + my_alloc_fn and deallocation function my_dealloc_fn as follows: + + self.setAllocationImpl("my_alloc", self.my_alloc_fn, self.my_dealloc_fn) + + def my_alloc_fn(self, value): + # perform logic + return True # successful allocation + + def my_dealloc_fn(self, value): + # perform logic + pass + + Example: + + # This example assumes that the device has two ports: + # - A provides (input) port of type bulkio.InShortPort called dataShort_in + # - A uses (output) port of type bulkio.OutFloatPort called dataFloat_out + # The mapping between the port and the class if found in the device + # base class. + # This example also makes use of the following Properties: + # - A float value called amplitude + # - A boolean called increaseAmplitude + + packet = self.port_dataShort_in.getPacket() + + if packet.dataBuffer is None: + return NOOP + + outData = range(len(packet.dataBuffer)) + for i in range(len(packet.dataBuffer)): + if self.increaseAmplitude: + outData[i] = float(packet.dataBuffer[i]) * self.amplitude + else: + outData[i] = float(packet.dataBuffer[i]) + + # NOTE: You must make at least one valid pushSRI call + if packet.sriChanged: + self.port_dataFloat_out.pushSRI(packet.SRI); + + self.port_dataFloat_out.pushPacket(outData, packet.T, packet.EOS, packet.streamID) + return NORMAL + + """ + # TODO fill in your code here + if self.frontend_tuner_status[0].enabled: + if self.data_count == 5: + return NOOP + if not self._stream_started: + #push sri + self._H = bulkio.sri.create("my_data") + self.port_dataFloat_out.pushPacket([1.0,2.0,3.0,4.0,5.0], bulkio.timestamp.now(), False, "my_data") + self.data_count += 1 + else: + if self._H: + self.port_dataFloat_out.pushPacket([], bulkio.timestamp.now(), True, "my_data") + self._H = None + self.data_count = 0 + self._log.debug("process() example log message") + return NOOP + + ''' + ************************************************************* + Functions supporting tuning allocation + *************************************************************''' + def deviceEnable(self, fts, tuner_id): + ''' + ************************************************************ + modify fts, which corresponds to self.frontend_tuner_status[tuner_id] + Make sure to set the 'enabled' member of fts to indicate that tuner as enabled + ************************************************************''' + #print "deviceEnable(): Enable the given tuner *********" + fts.enabled = True + return + + def deviceDisable(self,fts, tuner_id): + ''' + ************************************************************ + modify fts, which corresponds to self.frontend_tuner_status[tuner_id] + Make sure to reset the 'enabled' member of fts to indicate that tuner as disabled + ************************************************************''' + #print "deviceDisable(): Disable the given tuner *********" + fts.enabled = False + return + + def deviceSetTuning(self,request, fts, tuner_id): + ''' + ************************************************************ + modify fts, which corresponds to self.frontend_tuner_status[tuner_id] + + The bandwidth, center frequency, and sampling rate that the hardware was actually tuned + to needs to populate fts (to make sure that it meets the tolerance requirement. For example, + if the tuned values match the requested values, the code would look like this: + + fts.bandwidth = request.bandwidth + fts.center_frequency = request.center_frequency + fts.sample_rate = request.sample_rate + + return True if the tuning succeeded, and False if it failed + ************************************************************''' + #print "deviceSetTuning(): Evaluate whether or not a tuner is added *********" + fts.bandwidth = request.bandwidth + fts.center_frequency = request.center_frequency + fts.sample_rate = request.sample_rate + self.matchAllocationIdToStreamId(request.allocation_id, "my_data", self.port_dataFloat_out.name) + return True + + def deviceDeleteTuning(self, fts, tuner_id): + ''' + ************************************************************ + modify fts, which corresponds to self.frontend_tuner_status[tuner_id] + return True if the tune deletion succeeded, and False if it failed + ************************************************************''' + #print "deviceDeleteTuning(): Deallocate an allocated tuner *********" + return True + + ''' + ************************************************************* + Functions servicing the tuner control port + *************************************************************''' + def getTunerType(self,allocation_id): + idx = self.getTunerMapping(allocation_id) + if idx < 0: raise FRONTEND.FrontendException("Invalid allocation id") + return self.frontend_tuner_status[idx].tuner_type + + def getTunerDeviceControl(self,allocation_id): + idx = self.getTunerMapping(allocation_id) + if idx < 0: raise FRONTEND.FrontendException("Invalid allocation id") + if self.getControlAllocationId(idx) == allocation_id: + return True + return False + + def getTunerGroupId(self,allocation_id): + idx = self.getTunerMapping(allocation_id) + if idx < 0: raise FRONTEND.FrontendException("Invalid allocation id") + return self.frontend_tuner_status[idx].group_id + + def getTunerRfFlowId(self,allocation_id): + idx = self.getTunerMapping(allocation_id) + if idx < 0: raise FRONTEND.FrontendException("Invalid allocation id") + return self.frontend_tuner_status[idx].rf_flow_id + + + def setTunerCenterFrequency(self,allocation_id, freq): + idx = self.getTunerMapping(allocation_id) + if idx < 0: raise FRONTEND.FrontendException("Invalid allocation id") + if allocation_id != self.getControlAllocationId(idx): + raise FRONTEND.FrontendException(("ID "+str(allocation_id)+" does not have authorization to modify the tuner")) + if freq<0: raise FRONTEND.BadParameterException("Center frequency cannot be less than 0") + # set hardware to new value. Raise an exception if it's not possible + self.frontend_tuner_status[idx].center_frequency = freq + + def getTunerCenterFrequency(self,allocation_id): + idx = self.getTunerMapping(allocation_id) + if idx < 0: raise FRONTEND.FrontendException("Invalid allocation id") + return self.frontend_tuner_status[idx].center_frequency + + def setTunerBandwidth(self,allocation_id, bw): + idx = self.getTunerMapping(allocation_id) + if idx < 0: raise FRONTEND.FrontendException("Invalid allocation id") + if allocation_id != self.getControlAllocationId(idx): + raise FRONTEND.FrontendException(("ID "+str(allocation_id)+" does not have authorization to modify the tuner")) + if bw<0: raise FRONTEND.BadParameterException("Bandwidth cannot be less than 0") + # set hardware to new value. Raise an exception if it's not possible + self.frontend_tuner_status[idx].bandwidth = bw + + def getTunerBandwidth(self,allocation_id): + idx = self.getTunerMapping(allocation_id) + if idx < 0: raise FRONTEND.FrontendException("Invalid allocation id") + return self.frontend_tuner_status[idx].bandwidth + + def setTunerAgcEnable(self,allocation_id, enable): + raise FRONTEND.NotSupportedException("setTunerAgcEnable not supported") + + def getTunerAgcEnable(self,allocation_id): + raise FRONTEND.NotSupportedException("getTunerAgcEnable not supported") + + def setTunerGain(self,allocation_id, gain): + raise FRONTEND.NotSupportedException("setTunerGain not supported") + + def getTunerGain(self,allocation_id): + raise FRONTEND.NotSupportedException("getTunerGain not supported") + + def setTunerReferenceSource(self,allocation_id, source): + raise FRONTEND.NotSupportedException("setTunerReferenceSource not supported") + + def getTunerReferenceSource(self,allocation_id): + raise FRONTEND.NotSupportedException("getTunerReferenceSource not supported") + + def setTunerEnable(self,allocation_id, enable): + idx = self.getTunerMapping(allocation_id) + if idx < 0: raise FRONTEND.FrontendException("Invalid allocation id") + if allocation_id != self.getControlAllocationId(idx): + raise FRONTEND.FrontendException(("ID "+str(allocation_id)+" does not have authorization to modify the tuner")) + # set hardware to new value. Raise an exception if it's not possible + self.frontend_tuner_status[idx].enabled = enable + + def getTunerEnable(self,allocation_id): + idx = self.getTunerMapping(allocation_id) + if idx < 0: raise FRONTEND.FrontendException("Invalid allocation id") + return self.frontend_tuner_status[idx].enabled + + + def setTunerOutputSampleRate(self,allocation_id, sr): + idx = self.getTunerMapping(allocation_id) + if idx < 0: raise FRONTEND.FrontendException("Invalid allocation id") + if allocation_id != self.getControlAllocationId(idx): + raise FRONTEND.FrontendException(("ID "+str(allocation_id)+" does not have authorization to modify the tuner")) + if sr<0: raise FRONTEND.BadParameterException("Sample rate cannot be less than 0") + # set hardware to new value. Raise an exception if it's not possible + self.frontend_tuner_status[idx].sample_rate = sr + + def getTunerOutputSampleRate(self,allocation_id): + idx = self.getTunerMapping(allocation_id) + if idx < 0: raise FRONTEND.FrontendException("Invalid allocation id") + return self.frontend_tuner_status[idx].sample_rate + + ''' + ************************************************************* + Functions servicing the RFInfo port(s) + - port_name is the port over which the call was received + *************************************************************''' + def get_rf_flow_id(self,port_name): + return "" + + def set_rf_flow_id(self,port_name, _id): + pass + + def get_rfinfo_pkt(self,port_name): + _antennainfo=FRONTEND.AntennaInfo('','','','') + _freqrange=FRONTEND.FreqRange(0,0,[]) + _feedinfo=FRONTEND.FeedInfo('','',_freqrange) + _sensorinfo=FRONTEND.SensorInfo('','','',_antennainfo,_feedinfo) + _rfcapabilities=FRONTEND.RFCapabilities(_freqrange,_freqrange) + _rfinfopkt=FRONTEND.RFInfoPkt('',0.0,0.0,0.0,False,_sensorinfo,[],_rfcapabilities,[]) + return _rfinfopkt + + def set_rfinfo_pkt(self,port_name, pkt): + pass + +if __name__ == '__main__': + logging.getLogger().setLevel(logging.INFO) + logging.debug("Starting Device") + start_device(fei_src_i) + diff --git a/codegenTesting/sdr/dev/devices/fei_src/tests/.md5sums b/codegenTesting/sdr/dev/devices/fei_src/tests/.md5sums new file mode 100644 index 000000000..52dadc04f --- /dev/null +++ b/codegenTesting/sdr/dev/devices/fei_src/tests/.md5sums @@ -0,0 +1 @@ +d9b9023c886e7b54bb6bbd8caac4a25b test_fei_src.py diff --git a/codegenTesting/sdr/dev/devices/fei_src/tests/test_fei_src.py b/codegenTesting/sdr/dev/devices/fei_src/tests/test_fei_src.py new file mode 100644 index 000000000..ec4c96524 --- /dev/null +++ b/codegenTesting/sdr/dev/devices/fei_src/tests/test_fei_src.py @@ -0,0 +1,121 @@ +#!/usr/bin/env python + +import ossie.utils.testing +from ossie.utils import sb +import time, frontend + +class DeviceTests(ossie.utils.testing.RHTestCase): + # Path to the SPD file, relative to this file. This must be set in order to + # launch the device. + SPD_FILE = '../fei_src.spd.xml' + + # setUp is run before every function preceded by "test" is executed + # tearDown is run after every function preceded by "test" is executed + + # self.comp is a device using the sandbox API + # to create a data source, the package sb contains data sources like DataSource or FileSource + # to create a data sink, there are sinks like DataSink and FileSink + # to connect the component to get data from a file, process it, and write the output to a file, use the following syntax: + # src = sb.FileSource('myfile.dat') + # snk = sb.DataSink() + # src.connect(self.comp) + # self.comp.connect(snk) + # sb.start() + # + # components/sources/sinks need to be started. Individual components or elements can be started + # src.start() + # self.comp.start() + # + # every component/elements in the sandbox can be started + # sb.start() + + def setUp(self): + # Launch the device, using the selected implementation + self.comp = sb.launch(self.spd_file, impl=self.impl) + + def tearDown(self): + # Clean up all sandbox artifacts created during test + sb.release() + + def testDefinedConnectionId(self): + ####################################################################### + # Make sure start and stop can be called without throwing exceptions + alloc=frontend.createTunerAllocation() + snk_1 = sb.DataSink() + snk_2 = sb.DataSink() + self.comp.allocateCapacity(alloc) + self.comp.connect(snk_1, connectionId='some_connection') + tuner_status = self.comp.frontend_tuner_status[0] + alloc_id = alloc['FRONTEND::tuner_allocation']['FRONTEND::tuner_allocation::allocation_id'] + self.assertEquals(tuner_status.allocation_id_csv, alloc_id) + self.comp.connect(snk_2, connectionId=alloc_id) + self.assertEquals(len(self.comp.connectionTable), 1) + self.assertEquals(tuner_status.allocation_id_csv, alloc_id) + self.comp.start() + time.sleep(0.1) + time.sleep(0.25) + self.comp.deallocateCapacity(alloc) + time.sleep(0.1) + stream_1 = snk_1.getCurrentStream() + self.assertEquals(stream_1, None) + stream_2 = snk_2.getCurrentStream() + self.assertEquals(stream_2.streamID(), 'my_data') + self.assertEquals(len(stream_2.read().data()), 25) + self.assertEquals(len(self.comp.connectionTable), 0) + self.comp.stop() + + def testConnectBehavior(self): + ####################################################################### + # Make sure start and stop can be called without throwing exceptions + alloc=frontend.createTunerAllocation() + snk_1 = sb.DataSink() + snk_2 = sb.DataSink() + self.comp.allocateCapacity(alloc) + self.comp.connect(snk_1, connectionId='some_connection') + tuner_status = self.comp.frontend_tuner_status[0] + alloc_id = alloc['FRONTEND::tuner_allocation']['FRONTEND::tuner_allocation::allocation_id'] + self.assertEquals(tuner_status.allocation_id_csv, alloc_id) + self.comp.connect(snk_2) + self.assertEquals(len(self.comp.connectionTable), 2) + alloc_id = alloc_id + ',' + self.comp.connectionTable[1].connection_id + self.assertEquals(tuner_status.allocation_id_csv, alloc_id) + self.comp.start() + time.sleep(0.1) + time.sleep(0.25) + self.comp.deallocateCapacity(alloc) + time.sleep(0.1) + stream_1 = snk_1.getCurrentStream() + self.assertEquals(stream_1, None) + stream_2 = snk_2.getCurrentStream() + self.assertEquals(stream_2.streamID(), 'my_data') + self.assertEquals(len(stream_2.read().data()), 25) + self.assertEquals(len(self.comp.connectionTable), 0) + self.comp.stop() + + def testDisconnectBehavior(self): + ####################################################################### + # Make sure start and stop can be called without throwing exceptions + alloc=frontend.createTunerAllocation() + snk_1 = sb.DataSink() + snk_2 = sb.DataSink() + self.comp.allocateCapacity(alloc) + self.comp.connect(snk_1, connectionId='some_connection') + tuner_status = self.comp.frontend_tuner_status[0] + alloc_id = alloc['FRONTEND::tuner_allocation']['FRONTEND::tuner_allocation::allocation_id'] + self.assertEquals(tuner_status.allocation_id_csv, alloc_id) + self.comp.connect(snk_2) + self.comp.start() + time.sleep(0.1) + time.sleep(0.25) + self.comp.disconnect(snk_2) + time.sleep(0.1) + stream_1 = snk_1.getCurrentStream() + self.assertEquals(stream_1, None) + stream_2 = snk_2.getCurrentStream() + self.assertEquals(stream_2.streamID(), 'my_data') + self.assertEquals(len(stream_2.read().data()), 25) + self.assertEquals(tuner_status.allocation_id_csv, alloc_id) + self.comp.stop() + +if __name__ == "__main__": + ossie.utils.testing.main() # By default tests all implementations diff --git a/redhawk/src/base/framework/python/ossie/utils/model/__init__.py b/redhawk/src/base/framework/python/ossie/utils/model/__init__.py index 359a9feb2..aea076839 100644 --- a/redhawk/src/base/framework/python/ossie/utils/model/__init__.py +++ b/redhawk/src/base/framework/python/ossie/utils/model/__init__.py @@ -198,6 +198,7 @@ class PortSupplier(object): def __init__(self): self._providesPortDict = {} self._usesPortDict = {} + self._listener_allocations = {} def _showPorts(self, ports, destfile=None): localdef_dest = False @@ -312,9 +313,27 @@ def connect(self, providesComponent, providesPortName=None, usesPortName=None, c to find a matching port automatically. If there are multiple possible matches, a uses-side or provides-side port name may be necessary to resolve the ambiguity """ + + properties = [] + if hasattr(self, '_properties'): + properties = [p for p in self._properties if 'property' in p.kinds or 'configure' in p.kinds or 'execparam' in p.kinds] + tuner_status = None + valid_tuners = [] + for prop in properties: + if prop.id == 'FRONTEND::tuner_status': + tuner_status = prop + break + if tuner_status: + if not connectionId: + valid_tuners = [] + for tuner_idx in range(len(tuner_status)): + if not tuner_status[tuner_idx].enabled: + continue + valid_tuners.append(tuner_idx) + if not connectionId: connectionId = str(_uuidgen()) - + if isinstance(providesComponent, PortSupplier): log.trace('Provides side is PortSupplier') # Remote side supports multiple ports. @@ -401,6 +420,21 @@ def connect(self, providesComponent, providesPortName=None, usesPortName=None, c log.trace("Provides endpoint '%s' has interface '%s'", providesEndpoint.getName(), providesEndpoint.getInterface()) usesPortRef = usesEndpoint.getReference() providesPortRef = providesEndpoint.getReference() + if ':BULKIO/' in usesEndpoint.getInterface(): + if len(valid_tuners) == 1: + allocation_id = tuner_status[valid_tuners[0]].allocation_id_csv.split(',')[0] + while True: + connectionId = str(_uuidgen()) + if not self._listener_allocations.has_key(connectionId): + break + import frontend + listen_alloc = frontend.createTunerListenerAllocation(allocation_id, connectionId) + retalloc = self.allocateCapacity(listen_alloc) + if not retalloc: + raise RuntimeError, "Unable to create a listener for allocation "+allocation_id+" on device "+usesEndpoint.getName() + self._listener_allocations[connectionId] = listen_alloc + elif len(valid_tuners) > 1: + raise RuntimeError, "More than one valid tuner allocation exists on the frontend interfaces device, so the ambiguity cannot be resolved. Please provide the connection id for the desired allocation" usesPortRef.connectPort(providesPortRef, connectionId) ConnectionManager.instance().registerConnection(connectionId, usesEndpoint, providesEndpoint) @@ -416,6 +450,9 @@ def disconnect(self, providesComponent): usesPortRef.disconnectPort(connectionId) except: pass + if self._listener_allocations.has_key(connectionId): + self.deallocateCapacity(self._listener_allocations[connectionId]) + self._listener_allocations.pop(connectionId) if isinstance(providesComponent, PortSupplier): providesComponent._disconnected(connectionId) manager.unregisterConnection(connectionId, uses) diff --git a/redhawk/src/testing/tests/test_15_LoggingConfig.py b/redhawk/src/testing/tests/test_15_LoggingConfig.py index 4ece4832a..2d1270ebb 100644 --- a/redhawk/src/testing/tests/test_15_LoggingConfig.py +++ b/redhawk/src/testing/tests/test_15_LoggingConfig.py @@ -29,12 +29,41 @@ from ossie.utils import sb import os +@contextlib.contextmanager +def stdout_redirect(where): + sys.stdout = where + try: + yield where + finally: + sys.stdout = sys.__stdout__ + @scatest.requireLog4cxx class CppLoggingConfig(scatest.CorbaTestCase): def setUp(self): self.cname = "TestLoggingAPI" self.comp = sb.launch(self.cname) + def _try_config_test(self, logcfg, epattern, foundTest=None ): + + with stdout_redirect(cStringIO.StringIO()) as new_stdout: + ossie.utils.log4py.config.strConfig(logcfg,None) + + new_stdout.seek(0) + found = [] + epats=[] + if type(epattern) == str: + epats.append(epattern) + else: + epats = epattern + if foundTest == None: + foundTest = len(epats)*[True] + for x in new_stdout.readlines(): + for epat in epats: + m=re.search( epat, x ) + if m : + found.append( True ) + + self.assertEqual(found, foundTest ) def tearDown(self): self.comp.releaseObject() From cdded05261f4e7b8f0872590e441101d89d4bd02 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Tue, 1 Aug 2017 17:06:55 -0400 Subject: [PATCH 0859/1644] Refs CCB-27. Moved elements to required only with the scanner --- frontendInterfaces/idl/redhawk/FRONTEND/TunerControl.idl | 1 + 1 file changed, 1 insertion(+) diff --git a/frontendInterfaces/idl/redhawk/FRONTEND/TunerControl.idl b/frontendInterfaces/idl/redhawk/FRONTEND/TunerControl.idl index 8b5fe4a05..070698d83 100644 --- a/frontendInterfaces/idl/redhawk/FRONTEND/TunerControl.idl +++ b/frontendInterfaces/idl/redhawk/FRONTEND/TunerControl.idl @@ -67,6 +67,7 @@ module FRONTEND { - group_id || FRONTEND::tuner_status::group_id || string || Unique identifier that specifies a group of device. - rf_flow_id || FRONTEND::tuner_status::rf_flow_id || string || Specifies a certain RF flow to allocate against. - enabled || FRONTEND::tuner_status::enabled || boolean || True is tuner is enabled. Can be allocated but disabled + If the tuner_type is of type RX_SCANNER_DIGITIZER, the following optional fields are required as part of FRONTEND::tuner_status: - scan_mode_enabled || FRONTEND::tuner_status::scan_mode_enabled || boolean || True is scan mode is enabled. False is Manual Tune is enabled - supports_scan || FRONTEND::tuner_status::supports_scan || boolean || True if scan is supported From 5ed87988a5562a5c586ffde7515fc9264c1a9d1e Mon Sep 17 00:00:00 2001 From: Max Robert Date: Tue, 1 Aug 2017 17:06:55 -0400 Subject: [PATCH 0860/1644] Refs CF-1593. Reconcile merge conflict --- .../idl/redhawk/FRONTEND/TunerControl.idl | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/frontendInterfaces/idl/redhawk/FRONTEND/TunerControl.idl b/frontendInterfaces/idl/redhawk/FRONTEND/TunerControl.idl index 181411afc..8246773d8 100644 --- a/frontendInterfaces/idl/redhawk/FRONTEND/TunerControl.idl +++ b/frontendInterfaces/idl/redhawk/FRONTEND/TunerControl.idl @@ -29,7 +29,7 @@ module FRONTEND { /** Mandated Structures and Ports: ------------------------------ - Frontend mandates three property structures outside of normal REDHAWK properties of "device_kind" and "device_model" : + Frontend mandates four property structures outside of normal REDHAWK properties of "device_kind" and "device_model" : (1) FRONTEND::tuner_allocation - allocation structure to acquire capability on a tuner based off tuner settings. Name || ID || Type || Description - tuner_type || FRONTEND::tuner_allocation::tuner_type || string || Example Tuner Types: TX, RX, CHANNELIZER, DDC, RX_DIGITIZER, RX_DIGITIZER_CHANNELIZER, RX_SCANNER_DIGITIZER @@ -67,8 +67,9 @@ module FRONTEND { - group_id || FRONTEND::tuner_status::group_id || string || Unique identifier that specifies a group of device. - rf_flow_id || FRONTEND::tuner_status::rf_flow_id || string || Specifies a certain RF flow to allocate against. - enabled || FRONTEND::tuner_status::enabled || boolean || True is tuner is enabled. Can be allocated but disabled - - mode_enabled || FRONTEND::tuner_status::scan_mode_enabled || boolean || True is scan mode is enabled. False is Manual Tune is enabled - - supports_scan || FRONTEND::tuner_status::supports_scan || boolean || True if scan allocated + If the tuner_type is of type RX_SCANNER_DIGITIZER, the following optional fields are required as part of FRONTEND::tuner_status: + - scan_mode_enabled || FRONTEND::tuner_status::scan_mode_enabled || boolean || True is scan mode is enabled. False is Manual Tune is enabled + - supports_scan || FRONTEND::tuner_status::supports_scan || boolean || True if scan is supported Usual port additions include a input (provides) port for the tuner control as well as an output (uses) BULKIO data port that follows the naming convention [interface]_[in/out]. Examples include dataShort_out, dataSDDS_out, dataOctet_in, and DigitalTuner_in. @@ -84,7 +85,8 @@ module FRONTEND { - CHANNELIZER: Accepts digitized wideband and provides DDC's (allocation against a channelizer ensures that the input port is not shared) - DDC: Digital Down Converter. Channel that is extracted from a wider bandwidth (ie - Channelizer). Similar to a RX_DIGITIZER but often much cheaper. - RX_DIGITIZER_CHANNELIZER: RX_DIGITIZER and CHANNELIZER combo. The reason they are combined is because they are a single device that cannot operate - independetly (ie - RX_DIGITIZER can not output full-rate or the CHANNELIZER can not accept external input) + independetly (ie - RX_DIGITIZER can not output full-rate or the CHANNELIZER can not accept external input) + - RX_SCANNER_DIGITIZER: Frequency scanning digitizer From 60b7eb28902926ceebf4bbb23682c5bd14fcdd01 Mon Sep 17 00:00:00 2001 From: Ryan Bauman Date: Wed, 2 Aug 2017 12:41:23 -0400 Subject: [PATCH 0861/1644] RELENG-690 - bump rpm release for rc3 --- GPP/GPP.spec | 2 +- bulkioInterfaces/bulkioInterfaces.spec | 2 +- burstioInterfaces/burstioInterfaces.spec | 2 +- frontendInterfaces/frontendInterfaces.spec | 2 +- redhawk-codegen/redhawk-codegen.spec | 2 +- redhawk/src/releng/redhawk.spec | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/GPP/GPP.spec b/GPP/GPP.spec index e695ec463..2a773b138 100644 --- a/GPP/GPP.spec +++ b/GPP/GPP.spec @@ -32,7 +32,7 @@ Prefix: %{_prefix} Name: GPP Version: 2.1.1 -Release: 2%{?dist} +Release: 3%{?dist} Summary: REDHAWK GPP Group: Applications/Engineering diff --git a/bulkioInterfaces/bulkioInterfaces.spec b/bulkioInterfaces/bulkioInterfaces.spec index 17c325cc7..b674f59c3 100644 --- a/bulkioInterfaces/bulkioInterfaces.spec +++ b/bulkioInterfaces/bulkioInterfaces.spec @@ -29,7 +29,7 @@ Prefix: %{_prefix} Name: bulkioInterfaces Version: 2.1.1 -Release: 2%{?dist} +Release: 3%{?dist} Summary: The bulkio library for REDHAWK Group: Applications/Engineering diff --git a/burstioInterfaces/burstioInterfaces.spec b/burstioInterfaces/burstioInterfaces.spec index 6df8fd2c9..7f8d1c8b4 100644 --- a/burstioInterfaces/burstioInterfaces.spec +++ b/burstioInterfaces/burstioInterfaces.spec @@ -29,7 +29,7 @@ Prefix: %{_prefix} Name: burstioInterfaces Version: 2.1.1 -Release: 2%{?dist} +Release: 3%{?dist} Summary: BURSTIO interfaces for REDHAWK Group: Applications/Engineering diff --git a/frontendInterfaces/frontendInterfaces.spec b/frontendInterfaces/frontendInterfaces.spec index f6852be5c..a3784a3df 100644 --- a/frontendInterfaces/frontendInterfaces.spec +++ b/frontendInterfaces/frontendInterfaces.spec @@ -35,7 +35,7 @@ Prefix: %{_prefix} Summary: The frontend library for REDHAWK Name: frontendInterfaces Version: 2.4.1 -Release: 2%{?dist} +Release: 3%{?dist} License: LGPLv3+ Group: REDHAWK/Interfaces Source: %{name}-%{version}.tar.gz diff --git a/redhawk-codegen/redhawk-codegen.spec b/redhawk-codegen/redhawk-codegen.spec index 65c5c5ec4..3d72f4051 100644 --- a/redhawk-codegen/redhawk-codegen.spec +++ b/redhawk-codegen/redhawk-codegen.spec @@ -24,7 +24,7 @@ Prefix: %{_prefix} Name: redhawk-codegen Version: 2.1.1 -Release: 2%{?dist} +Release: 3%{?dist} Summary: Redhawk Code Generators Group: Applications/Engineering diff --git a/redhawk/src/releng/redhawk.spec b/redhawk/src/releng/redhawk.spec index 01471b591..a5d86c90b 100644 --- a/redhawk/src/releng/redhawk.spec +++ b/redhawk/src/releng/redhawk.spec @@ -27,7 +27,7 @@ Prefix: %{_sysconfdir} Name: redhawk Version: 2.1.1 -Release: 2%{?dist} +Release: 3%{?dist} Summary: REDHAWK is a Software Defined Radio framework Group: Applications/Engineering From 667316d50265829c4775a55d15578749ac985eea Mon Sep 17 00:00:00 2001 From: 8530 <8530@vm-131.vsi-corp.com> Date: Thu, 3 Aug 2017 10:26:06 -0400 Subject: [PATCH 0862/1644] fix issue with failed unit test, CF-1754 --- redhawk/src/control/sdr/dommgr/main.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/redhawk/src/control/sdr/dommgr/main.cpp b/redhawk/src/control/sdr/dommgr/main.cpp index 978dbaa5f..a5fea01ba 100644 --- a/redhawk/src/control/sdr/dommgr/main.cpp +++ b/redhawk/src/control/sdr/dommgr/main.cpp @@ -220,9 +220,7 @@ int old_main(int argc, char* argv[]) return(EXIT_FAILURE); } - std::ostringstream os; - os << domainName << "/" << domainName; - dpath= os.str(); + dpath= domRootPath.string(); // setup logging context for a component resource std::string logcfg_uri = logfile_uri; From 8b457b6b3b2b7aa90945712f580f020f7a27287d Mon Sep 17 00:00:00 2001 From: Ryan Bauman Date: Mon, 7 Aug 2017 16:19:22 -0400 Subject: [PATCH 0863/1644] RELENG-695 - bump rpm release for rc4 --- GPP/GPP.spec | 2 +- bulkioInterfaces/bulkioInterfaces.spec | 2 +- burstioInterfaces/burstioInterfaces.spec | 2 +- frontendInterfaces/frontendInterfaces.spec | 2 +- redhawk-codegen/redhawk-codegen.spec | 2 +- redhawk/src/releng/redhawk.spec | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/GPP/GPP.spec b/GPP/GPP.spec index 2a773b138..8952fa067 100644 --- a/GPP/GPP.spec +++ b/GPP/GPP.spec @@ -32,7 +32,7 @@ Prefix: %{_prefix} Name: GPP Version: 2.1.1 -Release: 3%{?dist} +Release: 4%{?dist} Summary: REDHAWK GPP Group: Applications/Engineering diff --git a/bulkioInterfaces/bulkioInterfaces.spec b/bulkioInterfaces/bulkioInterfaces.spec index b674f59c3..15f142d42 100644 --- a/bulkioInterfaces/bulkioInterfaces.spec +++ b/bulkioInterfaces/bulkioInterfaces.spec @@ -29,7 +29,7 @@ Prefix: %{_prefix} Name: bulkioInterfaces Version: 2.1.1 -Release: 3%{?dist} +Release: 4%{?dist} Summary: The bulkio library for REDHAWK Group: Applications/Engineering diff --git a/burstioInterfaces/burstioInterfaces.spec b/burstioInterfaces/burstioInterfaces.spec index 7f8d1c8b4..bfc97b7b5 100644 --- a/burstioInterfaces/burstioInterfaces.spec +++ b/burstioInterfaces/burstioInterfaces.spec @@ -29,7 +29,7 @@ Prefix: %{_prefix} Name: burstioInterfaces Version: 2.1.1 -Release: 3%{?dist} +Release: 4%{?dist} Summary: BURSTIO interfaces for REDHAWK Group: Applications/Engineering diff --git a/frontendInterfaces/frontendInterfaces.spec b/frontendInterfaces/frontendInterfaces.spec index a3784a3df..7b28db501 100644 --- a/frontendInterfaces/frontendInterfaces.spec +++ b/frontendInterfaces/frontendInterfaces.spec @@ -35,7 +35,7 @@ Prefix: %{_prefix} Summary: The frontend library for REDHAWK Name: frontendInterfaces Version: 2.4.1 -Release: 3%{?dist} +Release: 4%{?dist} License: LGPLv3+ Group: REDHAWK/Interfaces Source: %{name}-%{version}.tar.gz diff --git a/redhawk-codegen/redhawk-codegen.spec b/redhawk-codegen/redhawk-codegen.spec index 3d72f4051..bff8db86c 100644 --- a/redhawk-codegen/redhawk-codegen.spec +++ b/redhawk-codegen/redhawk-codegen.spec @@ -24,7 +24,7 @@ Prefix: %{_prefix} Name: redhawk-codegen Version: 2.1.1 -Release: 3%{?dist} +Release: 4%{?dist} Summary: Redhawk Code Generators Group: Applications/Engineering diff --git a/redhawk/src/releng/redhawk.spec b/redhawk/src/releng/redhawk.spec index a5d86c90b..5cd1c6ad0 100644 --- a/redhawk/src/releng/redhawk.spec +++ b/redhawk/src/releng/redhawk.spec @@ -27,7 +27,7 @@ Prefix: %{_sysconfdir} Name: redhawk Version: 2.1.1 -Release: 3%{?dist} +Release: 4%{?dist} Summary: REDHAWK is a Software Defined Radio framework Group: Applications/Engineering From afa4497d8f16eab1752fd632b2bf228f2220f992 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Wed, 9 Aug 2017 11:12:35 -0400 Subject: [PATCH 0864/1644] CF-1832 Refactor BulkIO C++ output stream tests to bring them more in line with 2.0 Added a nested typedef to input and output streams that allows other code to determine the template parameter, which is used to determine the input stub class in the tests. --- .../cpp/include/bulkio/bulkio_in_port.h | 3 + .../cpp/include/bulkio/bulkio_out_port.h | 3 + .../testing/tests/cpp/OutStreamTest.cpp | 137 +++++++++--------- .../libsrc/testing/tests/cpp/OutStreamTest.h | 17 ++- 4 files changed, 84 insertions(+), 76 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/include/bulkio/bulkio_in_port.h b/bulkioInterfaces/libsrc/cpp/include/bulkio/bulkio_in_port.h index 44ca00b00..a562d165b 100644 --- a/bulkioInterfaces/libsrc/cpp/include/bulkio/bulkio_in_port.h +++ b/bulkioInterfaces/libsrc/cpp/include/bulkio/bulkio_in_port.h @@ -66,6 +66,9 @@ namespace bulkio { class InPort : public CorbaTraits::POAType, public Port_Provides_base_impl { public: + // The CORBA interface of this port (nested typedef for template parameter) + typedef PortType CorbaType; + // Transport Sequence Type use to during push packet typedef typename CorbaTraits::SequenceType PortSequenceType; diff --git a/bulkioInterfaces/libsrc/cpp/include/bulkio/bulkio_out_port.h b/bulkioInterfaces/libsrc/cpp/include/bulkio/bulkio_out_port.h index ae988552d..5a9ea3111 100644 --- a/bulkioInterfaces/libsrc/cpp/include/bulkio/bulkio_out_port.h +++ b/bulkioInterfaces/libsrc/cpp/include/bulkio/bulkio_out_port.h @@ -74,6 +74,9 @@ namespace bulkio { { public: + // The CORBA interface of this port (nested typedef for template parameter) + typedef PortType CorbaType; + // // Port Variable Definition // diff --git a/bulkioInterfaces/libsrc/testing/tests/cpp/OutStreamTest.cpp b/bulkioInterfaces/libsrc/testing/tests/cpp/OutStreamTest.cpp index 827df8345..3fb498342 100644 --- a/bulkioInterfaces/libsrc/testing/tests/cpp/OutStreamTest.cpp +++ b/bulkioInterfaces/libsrc/testing/tests/cpp/OutStreamTest.cpp @@ -23,23 +23,23 @@ #include #include "bulkio.h" -template -void OutStreamTest::setUp() +template +void OutStreamTest::setUp() { ossie::corba::CorbaInit(0,0); std::string name = "data" + getPortName() + "_out"; - port = new OutPort(name); + port = new Port(name); - stub = new InPortStub(); + stub = new InPortStub(); PortableServer::ObjectId_var oid = ossie::corba::RootPOA()->activate_object(stub); CORBA::Object_var objref = stub->_this(); port->connectPort(objref, "test_connection"); } -template -void OutStreamTest::tearDown() +template +void OutStreamTest::tearDown() { port->disconnectPort("test_connection"); @@ -53,10 +53,11 @@ void OutStreamTest::tearDown() // Ignore CORBA exceptions } stub->_remove_ref(); + stub = 0; } -template -void OutStreamTest::testOperators() +template +void OutStreamTest::testOperators() { StreamType null_stream; CPPUNIT_ASSERT(!null_stream); @@ -86,8 +87,8 @@ void OutStreamTest::testOperators() CPPUNIT_ASSERT(other_stream != good_stream); } -template -void OutStreamTest::testBasicWrite() +template +void OutStreamTest::testBasicWrite() { StreamType stream = port->createStream("test_basic_write"); CPPUNIT_ASSERT(stub->packets.empty()); @@ -101,8 +102,8 @@ void OutStreamTest::testBasicWrite() CPPUNIT_ASSERT_EQUAL(stream.streamID(), stub->packets[0].streamID); } -template -void OutStreamTest::testSriFields() +template +void OutStreamTest::testSriFields() { BULKIO::StreamSRI sri = bulkio::sri::create("test_sri"); sri.xstart = -2.5; @@ -135,8 +136,8 @@ void OutStreamTest::testSriFields() CPPUNIT_ASSERT_EQUAL((CORBA::Long) 100, stream.getKeyword("number").toLong()); } -template -void OutStreamTest::testSriUpdate() +template +void OutStreamTest::testSriUpdate() { // Create initial stream; all changes should be queued up for the first // write @@ -188,8 +189,8 @@ void OutStreamTest::testSriUpdate() CPPUNIT_ASSERT(bulkio::sri::DefaultComparator(stream.sri(), stub->H.back())); } -template -void OutStreamTest::testKeywords() +template +void OutStreamTest::testKeywords() { StreamType stream = port->createStream("test_keywords"); _writeSinglePacket(stream, 1); @@ -245,8 +246,8 @@ void OutStreamTest::testKeywords() } } -template -void OutStreamTest::testSendEosOnClose() +template +void OutStreamTest::testSendEosOnClose() { StreamType stream = port->createStream("close_eos"); @@ -264,9 +265,9 @@ void OutStreamTest::testSendEosOnClose() CPPUNIT_ASSERT(stub->packets.back().EOS); } -template -void OutStreamTest::_writeSinglePacket(StreamType& stream, size_t size, - const BULKIO::PrecisionUTCTime& time) +template +void OutStreamTest::_writeSinglePacket(StreamType& stream, size_t size, + const BULKIO::PrecisionUTCTime& time) { typedef typename StreamType::ScalarType ScalarType; std::vector buffer; @@ -274,16 +275,16 @@ void OutStreamTest::_writeSinglePacket(StreamType& stream, siz stream.write(buffer, time); } -template -bool OutStreamTest::_checkLastTimestamp(const BULKIO::PrecisionUTCTime& time) +template +bool OutStreamTest::_checkLastTimestamp(const BULKIO::PrecisionUTCTime& time) { return (time == stub->packets.back().T); } // Specialization for dataFile, which uses std::string template <> -void OutStreamTest::_writeSinglePacket(StreamType& stream, size_t size, - const BULKIO::PrecisionUTCTime& time) +void OutStreamTest::_writeSinglePacket(StreamType& stream, size_t size, + const BULKIO::PrecisionUTCTime& time) { std::string url(size, 'F'); stream.write(url, time); @@ -292,23 +293,23 @@ void OutStreamTest::_writeSinglePacket(Str // Specializations for dataXML, which uses std::string and does not include a // timestamp template <> -void OutStreamTest::_writeSinglePacket(StreamType& stream, size_t size, - const BULKIO::PrecisionUTCTime& /*unused*/) +void OutStreamTest::_writeSinglePacket(StreamType& stream, size_t size, + const BULKIO::PrecisionUTCTime& /*unused*/) { std::string xml(size, 'X'); stream.write(xml); } template <> -bool OutStreamTest::_checkLastTimestamp(const BULKIO::PrecisionUTCTime& /*unused*/) +bool OutStreamTest::_checkLastTimestamp(const BULKIO::PrecisionUTCTime& /*unused*/) { // dataXML has no time stamp, so the check should always succeed return true; } -template -void BufferedOutStreamTest::testBufferedWrite() +template +void BufferedOutStreamTest::testBufferedWrite() { // Initial state is unbuffered; turn on buffering StreamType stream = port->createStream("test_buffered_write"); @@ -349,8 +350,8 @@ void BufferedOutStreamTest::testBufferedWrite() CPPUNIT_ASSERT(stub->packets.size() == 3); } -template -void BufferedOutStreamTest::testWriteSkipBuffer() +template +void BufferedOutStreamTest::testWriteSkipBuffer() { // Turn on buffering StreamType stream = port->createStream("test_skip_buffer"); @@ -376,8 +377,8 @@ void BufferedOutStreamTest::testWriteSkipBuffer() CPPUNIT_ASSERT_EQUAL(stream.bufferSize(), (size_t) stub->packets.back().data.length()); } -template -void BufferedOutStreamTest::testFlush() +template +void BufferedOutStreamTest::testFlush() { // Turn on buffering StreamType stream = port->createStream("test_flush"); @@ -397,8 +398,8 @@ void BufferedOutStreamTest::testFlush() CPPUNIT_ASSERT_EQUAL(buffer.size(), (size_t) stub->packets.back().data.length()); } -template -void BufferedOutStreamTest::testFlushOnClose() +template +void BufferedOutStreamTest::testFlushOnClose() { StreamType stream = port->createStream("test_flush_close"); stream.setBufferSize(64); @@ -416,8 +417,8 @@ void BufferedOutStreamTest::testFlushOnClose() CPPUNIT_ASSERT(stub->packets.size() == 1); } -template -void BufferedOutStreamTest::testFlushOnSriChange() +template +void BufferedOutStreamTest::testFlushOnSriChange() { // Start with known values for important stream metadata StreamType stream = port->createStream("test_flush_sri"); @@ -476,8 +477,8 @@ void BufferedOutStreamTest::testFlushOnSriChange() CPPUNIT_ASSERT(stub->H.back().blocking); } -template -void BufferedOutStreamTest::testFlushOnBufferSizeChange() +template +void BufferedOutStreamTest::testFlushOnBufferSizeChange() { StreamType stream = port->createStream("test_flush_buffer_size"); stream.setBufferSize(64); @@ -515,31 +516,31 @@ void BufferedOutStreamTest::testFlushOnBufferSizeChange() CPPUNIT_ASSERT_MESSAGE("Disabling buffering did not flush", stub->packets.size() == 3); } -template -void BufferedOutStreamTest::testWriteTimestampsReal() +template +void BufferedOutStreamTest::testWriteTimestampsReal() { StreamType stream = port->createStream("write_timestamps_real"); _writeTimestampsImpl(stream, false); } -template -void BufferedOutStreamTest::testWriteTimestampsComplex() +template +void BufferedOutStreamTest::testWriteTimestampsComplex() { StreamType stream = port->createStream("write_timestamps_complex"); stream.complex(true); _writeTimestampsImpl(stream, true); } -template -void BufferedOutStreamTest::testWriteTimestampsMixed() +template +void BufferedOutStreamTest::testWriteTimestampsMixed() { StreamType stream = port->createStream("write_timestamps_mixed"); stream.complex(true); _writeTimestampsImpl(stream, false); } -template -void BufferedOutStreamTest::_writeTimestampsImpl(StreamType& stream, bool complexData) +template +void BufferedOutStreamTest::_writeTimestampsImpl(StreamType& stream, bool complexData) { // Generate a ramp using the scalar type; if the data needs to be pushed as // complex, it will be reintepreted there @@ -591,30 +592,30 @@ void BufferedOutStreamTest::_writeTimestampsImpl(StreamType& s CPPUNIT_ASSERT_EQUAL_MESSAGE("Final packet size is incorrect", scalars_received, scalars.size()); } -#define CREATE_TEST_IMPL(TESTCLASS,PORT,NAME,BASE,CORBA) \ - class TESTCLASS : public BASE \ +#define CREATE_TEST_IMPL(TESTCLASS,PORT,NAME,BASE) \ + class TESTCLASS : public BASE \ { \ - typedef BASE TestBase; \ + typedef BASE TestBase; \ CPPUNIT_TEST_SUB_SUITE(TESTCLASS, TestBase); \ CPPUNIT_TEST_SUITE_END(); \ virtual std::string getPortName() const { return #NAME; }; \ }; \ CPPUNIT_TEST_SUITE_REGISTRATION(TESTCLASS); -#define CREATE_TEST(x,BASE,y) CREATE_TEST_IMPL(Out##x##StreamTest,bulkio::Out##x##Port,x,BASE,y) -#define CREATE_BASIC_TEST(x,y) CREATE_TEST(x,OutStreamTest,y) -#define CREATE_BUFFERED_TEST(x,y) CREATE_TEST(x,BufferedOutStreamTest,y) - -CREATE_BUFFERED_TEST(Octet,BULKIO::dataOctet); -CREATE_BUFFERED_TEST(Char,BULKIO::dataChar); -CREATE_BUFFERED_TEST(Short,BULKIO::dataShort); -CREATE_BUFFERED_TEST(UShort,BULKIO::dataUshort); -CREATE_BUFFERED_TEST(Long,BULKIO::dataLong); -CREATE_BUFFERED_TEST(ULong,BULKIO::dataUlong); -CREATE_BUFFERED_TEST(LongLong,BULKIO::dataLongLong); -CREATE_BUFFERED_TEST(ULongLong,BULKIO::dataUlongLong); -CREATE_BUFFERED_TEST(Float,BULKIO::dataFloat); -CREATE_BUFFERED_TEST(Double,BULKIO::dataDouble); - -CREATE_BASIC_TEST(XML,BULKIO::dataXML); -CREATE_BASIC_TEST(File,BULKIO::dataFile); +#define CREATE_TEST(x,BASE) CREATE_TEST_IMPL(Out##x##StreamTest,bulkio::Out##x##Port,x,BASE) +#define CREATE_BASIC_TEST(x) CREATE_TEST(x,OutStreamTest) +#define CREATE_BUFFERED_TEST(x) CREATE_TEST(x,BufferedOutStreamTest) + +CREATE_BUFFERED_TEST(Octet); +CREATE_BUFFERED_TEST(Char); +CREATE_BUFFERED_TEST(Short); +CREATE_BUFFERED_TEST(UShort); +CREATE_BUFFERED_TEST(Long); +CREATE_BUFFERED_TEST(ULong); +CREATE_BUFFERED_TEST(LongLong); +CREATE_BUFFERED_TEST(ULongLong); +CREATE_BUFFERED_TEST(Float); +CREATE_BUFFERED_TEST(Double); + +CREATE_BASIC_TEST(XML); +CREATE_BASIC_TEST(File); diff --git a/bulkioInterfaces/libsrc/testing/tests/cpp/OutStreamTest.h b/bulkioInterfaces/libsrc/testing/tests/cpp/OutStreamTest.h index a8c9dfe4e..dcc8bc81b 100644 --- a/bulkioInterfaces/libsrc/testing/tests/cpp/OutStreamTest.h +++ b/bulkioInterfaces/libsrc/testing/tests/cpp/OutStreamTest.h @@ -25,7 +25,7 @@ #include "InPortStub.h" -template +template class OutStreamTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(OutStreamTest); @@ -53,7 +53,8 @@ class OutStreamTest : public CppUnit::TestFixture void testSendEosOnClose(); protected: - typedef typename OutPort::StreamType StreamType; + typedef typename Port::StreamType StreamType; + typedef typename Port::CorbaType CorbaType; virtual std::string getPortName() const = 0; void _writeSinglePacket(StreamType& stream, size_t size, @@ -61,14 +62,14 @@ class OutStreamTest : public CppUnit::TestFixture bool _checkLastTimestamp(const BULKIO::PrecisionUTCTime& time); - OutPort* port; - InPortStub* stub; + Port* port; + InPortStub* stub; }; -template -class BufferedOutStreamTest : public OutStreamTest +template +class BufferedOutStreamTest : public OutStreamTest { - typedef OutStreamTest TestBase; + typedef OutStreamTest TestBase; CPPUNIT_TEST_SUB_SUITE(BufferedOutStreamTest, TestBase); CPPUNIT_TEST(testBufferedWrite); CPPUNIT_TEST(testWriteSkipBuffer); @@ -95,7 +96,7 @@ class BufferedOutStreamTest : public OutStreamTest void testWriteTimestampsMixed(); private: - typedef typename OutPort::StreamType StreamType; + typedef typename Port::StreamType StreamType; typedef typename StreamType::ScalarType ScalarType; typedef typename StreamType::ComplexType ComplexType; From 81266b5e5bd18d01cfdf1b5bc7a8ee23eb0fc044 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Thu, 17 Aug 2017 11:53:30 -0400 Subject: [PATCH 0865/1644] Refs CF-1815. Configurable stop timeout --- redhawk/src/base/framework/Device_impl.cpp | 2 - .../control/include/ossie/SoftwareAssembly.h | 19 +++ .../src/control/parser/SoftwareAssembly.cpp | 5 + .../control/parser/internal/sad-parser.cpp | 8 + .../src/control/parser/internal/sad-pimpl.cpp | 54 ++++++ .../src/control/parser/internal/sad-pimpl.h | 38 +++++ redhawk/src/control/parser/internal/sad.map | 2 + .../sdr/dommgr/ApplicationComponent.cpp | 5 +- .../control/sdr/dommgr/ApplicationComponent.h | 4 +- .../sdr/dommgr/ApplicationFactory_impl.cpp | 69 +++++++- .../control/sdr/dommgr/Application_impl.cpp | 21 ++- .../src/control/sdr/dommgr/Application_impl.h | 10 +- .../control/sdr/dommgr/DomainManager_impl.cpp | 2 + .../control/sdr/dommgr/FakeApplication.cpp | 7 + .../src/control/sdr/dommgr/FakeApplication.h | 4 + .../src/control/sdr/dommgr/PersistenceStore.h | 1 + redhawk/src/control/sdr/dommgr/createHelper.h | 3 + .../src/idl/ossie/CF/WellKnownProperties.idl | 3 +- redhawk/src/idl/ossie/CF/cf.idl | 2 + .../hanging_stop/hanging_stop.prf.xml | 3 + .../hanging_stop/hanging_stop.scd.xml | 45 +++++ .../hanging_stop/hanging_stop.spd.xml | 25 +++ .../hanging_stop/python/hanging_stop.py | 160 ++++++++++++++++++ .../hanging_stop/python/hanging_stop_base.py | 61 +++++++ .../components/slow_stop/python/slow_stop.py | 156 +++++++++++++++++ .../slow_stop/python/slow_stop_base.py | 72 ++++++++ .../components/slow_stop/slow_stop.prf.xml | 3 + .../components/slow_stop/slow_stop.scd.xml | 45 +++++ .../components/slow_stop/slow_stop.spd.xml | 25 +++ .../cpp_comp_aware_w/cpp_comp_aware_w.sad.xml | 45 +++++ .../tests/test_04_ApplicationFactory.py | 134 ++++++++++++++- .../tests/test_04_ApplicationRegistrar.py | 22 +++ redhawk/src/xml/dtd/softwareassembly.dtd | 8 + redhawk/src/xml/xsd/sad.xsd | 10 ++ 34 files changed, 1052 insertions(+), 21 deletions(-) create mode 100644 redhawk/src/testing/sdr/dom/components/hanging_stop/hanging_stop.prf.xml create mode 100644 redhawk/src/testing/sdr/dom/components/hanging_stop/hanging_stop.scd.xml create mode 100644 redhawk/src/testing/sdr/dom/components/hanging_stop/hanging_stop.spd.xml create mode 100755 redhawk/src/testing/sdr/dom/components/hanging_stop/python/hanging_stop.py create mode 100644 redhawk/src/testing/sdr/dom/components/hanging_stop/python/hanging_stop_base.py create mode 100755 redhawk/src/testing/sdr/dom/components/slow_stop/python/slow_stop.py create mode 100644 redhawk/src/testing/sdr/dom/components/slow_stop/python/slow_stop_base.py create mode 100644 redhawk/src/testing/sdr/dom/components/slow_stop/slow_stop.prf.xml create mode 100644 redhawk/src/testing/sdr/dom/components/slow_stop/slow_stop.scd.xml create mode 100644 redhawk/src/testing/sdr/dom/components/slow_stop/slow_stop.spd.xml create mode 100644 redhawk/src/testing/sdr/dom/waveforms/cpp_comp_aware_w/cpp_comp_aware_w.sad.xml diff --git a/redhawk/src/base/framework/Device_impl.cpp b/redhawk/src/base/framework/Device_impl.cpp index d9ca2c8e4..f8e2a2108 100644 --- a/redhawk/src/base/framework/Device_impl.cpp +++ b/redhawk/src/base/framework/Device_impl.cpp @@ -548,7 +548,6 @@ void Device_impl::deallocateCapacityLegacy (const CF::Properties& capacities) CF::Properties invalidProps; bool totalCap = true; /* Flag to check remaining extra capacity to allocate */ - bool foundProperty; /* Flag to indicate if the requested property was found */ AnyComparisonType compResult; { @@ -561,7 +560,6 @@ void Device_impl::deallocateCapacityLegacy (const CF::Properties& capacities) SCOPED_LOCK(propertySetAccess); /* Look in propertySet for the properties requested */ for (unsigned i = 0; i < capacities.length (); i++) { - foundProperty = false; CF::DataType request = capacities[i]; std::string pid = (const char*)capacities[i].id; PropertyInterface *property = getPropertyFromId(pid); diff --git a/redhawk/src/control/include/ossie/SoftwareAssembly.h b/redhawk/src/control/include/ossie/SoftwareAssembly.h index 416684e6d..b43cbdfe4 100644 --- a/redhawk/src/control/include/ossie/SoftwareAssembly.h +++ b/redhawk/src/control/include/ossie/SoftwareAssembly.h @@ -140,6 +140,22 @@ namespace ossie { } }; + class Option { + public: + std::string name; + std::string value; + + const std::string& getName() const + { + return name; + } + + const std::string& getValue() const + { + return value; + } + }; + class SAD { public: std::string id; @@ -150,6 +166,7 @@ namespace ossie { std::vector componentfiles; std::vector externalports; std::vector externalproperties; + std::vector options; std::vector usesdevice; }; @@ -183,6 +200,8 @@ namespace ossie { const std::vector& getExternalProperties() const; + const std::vector& getOptions() const; + const std::vector& getUsesDevices() const; const ComponentInstantiation* getComponentInstantiation(const std::string& refid) const; diff --git a/redhawk/src/control/parser/SoftwareAssembly.cpp b/redhawk/src/control/parser/SoftwareAssembly.cpp index e4f18adb6..6d6ec5cca 100644 --- a/redhawk/src/control/parser/SoftwareAssembly.cpp +++ b/redhawk/src/control/parser/SoftwareAssembly.cpp @@ -179,6 +179,11 @@ const std::vector& SoftwareAssembly::getExternalProp return _sad->externalproperties; } +const std::vector& SoftwareAssembly::getOptions() const { + assert(_sad.get() != 0); + return _sad->options; +} + const std::vector& SoftwareAssembly::getUsesDevices() const { assert(_sad.get() != 0); return _sad->usesdevice; diff --git a/redhawk/src/control/parser/internal/sad-parser.cpp b/redhawk/src/control/parser/internal/sad-parser.cpp index e48090b5a..0e65aef98 100644 --- a/redhawk/src/control/parser/internal/sad-parser.cpp +++ b/redhawk/src/control/parser/internal/sad-parser.cpp @@ -66,6 +66,8 @@ ossie::internalparser::parseSAD(std::istream& input) throw (ossie::parser_error) ::sad::port_pimpl port_p; ::sad::externalproperties_pimpl externalproperties_p; ::sad::property_pimpl property_p; + ::sad::options_pimpl options_p; + ::sad::option_pimpl option_p; ::sad::usesdevicedependencies_pimpl usesdevicedependencies_p; ::sad::usesdevice_pimpl usesdevice_p; ::sad::propertyref_pimpl propertyref_p; @@ -86,6 +88,7 @@ ossie::internalparser::parseSAD(std::istream& input) throw (ossie::parser_error) connections_p, externalports_p, externalproperties_p, + options_p, usesdevicedependencies_p, string_p, string_p, @@ -236,6 +239,11 @@ ossie::internalparser::parseSAD(std::istream& input) throw (ossie::parser_error) string_p, string_p); + options_p.parsers (option_p); + + option_p.parsers (string_p, + string_p); + usesdevicedependencies_p.parsers (usesdevice_p); usesdevice_p.parsers (propertyref_p, diff --git a/redhawk/src/control/parser/internal/sad-pimpl.cpp b/redhawk/src/control/parser/internal/sad-pimpl.cpp index 5aef1a951..cf763d818 100644 --- a/redhawk/src/control/parser/internal/sad-pimpl.cpp +++ b/redhawk/src/control/parser/internal/sad-pimpl.cpp @@ -85,6 +85,12 @@ namespace sad _sad->externalproperties.swap(externalproperties); } + void softwareassembly_pimpl:: + options (::std::vector& options) + { + _sad->options.swap(options); + } + void softwareassembly_pimpl:: usesdevicedependencies (::std::vector& usesdevices) { @@ -1405,6 +1411,54 @@ namespace sad return *property; } + // options_pimpl + // + + void options_pimpl:: + pre () + { + extOptions.clear(); + } + + void options_pimpl:: + option (const ossie::SoftwareAssembly::Option& option) + { + extOptions.push_back(option); + } + + ::std::vector& options_pimpl:: + post_options () + { + return extOptions; + } + + // option_pimpl + // + + void option_pimpl:: + pre () + { + option.reset(new ossie::SoftwareAssembly::Option()); + } + + void option_pimpl:: + name(const ::std::string& name) + { + option->name = name; + } + + void option_pimpl:: + value(const ::std::string& value) + { + option->value = value; + } + + ::ossie::SoftwareAssembly::Option option_pimpl:: + post_option () + { + return *option; + } + // usesdevicedependencies_pimpl // diff --git a/redhawk/src/control/parser/internal/sad-pimpl.h b/redhawk/src/control/parser/internal/sad-pimpl.h index c55c0a9c4..104f6e11d 100644 --- a/redhawk/src/control/parser/internal/sad-pimpl.h +++ b/redhawk/src/control/parser/internal/sad-pimpl.h @@ -58,6 +58,9 @@ namespace sad virtual void externalproperties (::std::vector&); + virtual void + options (::std::vector&); + virtual void usesdevicedependencies (::std::vector&); @@ -925,6 +928,41 @@ namespace sad std::auto_ptr property; }; + class options_pimpl: public virtual options_pskel + { + public: + virtual void + pre (); + + virtual void + option (const ossie::SoftwareAssembly::Option&); + + virtual ::std::vector& + post_options (); + + private: + std::vector extOptions; + }; + + class option_pimpl: public virtual option_pskel + { + public: + virtual void + pre (); + + virtual void + name (const ::std::string&); + + virtual void + value (const ::std::string&); + + virtual ::ossie::SoftwareAssembly::Option + post_option (); + + private: + std::auto_ptr option; + }; + class usesdevicedependencies_pimpl: public virtual usesdevicedependencies_pskel { public: diff --git a/redhawk/src/control/parser/internal/sad.map b/redhawk/src/control/parser/internal/sad.map index 1d4877a76..c26934912 100644 --- a/redhawk/src/control/parser/internal/sad.map +++ b/redhawk/src/control/parser/internal/sad.map @@ -60,6 +60,8 @@ namespace urn:mil:jpeojtrs:sca:sad { supportedidentifier "::std::string"; externalproperties "::std::vector &"; property "ossie::SoftwareAssembly::Property"; + options "::std::vector &"; + option "ossie::SoftwareAssembly::Option"; usesdevicedependencies "::std::vector &"; usesdevice "ossie::UsesDevice"; propertyref "ossie::PropertyRef"; diff --git a/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp b/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp index 3885e96ff..4209d8656 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationComponent.cpp @@ -200,9 +200,10 @@ void ApplicationComponent::start() } } -bool ApplicationComponent::stop() +bool ApplicationComponent::stop(float timeout) { - const unsigned long timeout = 3; // seconds + if (timeout < 0) + timeout = 0; omniORB::setClientCallTimeout(_resource, timeout * 1000); try { _resource->stop(); diff --git a/redhawk/src/control/sdr/dommgr/ApplicationComponent.h b/redhawk/src/control/sdr/dommgr/ApplicationComponent.h index 9b1265e87..2e1164e45 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationComponent.h +++ b/redhawk/src/control/sdr/dommgr/ApplicationComponent.h @@ -29,6 +29,8 @@ #include "PersistenceStore.h" +#define DEFAULT_STOP_TIMEOUT 3 + namespace redhawk { class ApplicationComponent { @@ -79,7 +81,7 @@ namespace redhawk { const std::vector& getChildren() const; void start(); - bool stop(); + bool stop(float timeout); void releaseObject(); void terminate(); diff --git a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp index dc24ea562..647aaa302 100644 --- a/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/ApplicationFactory_impl.cpp @@ -738,6 +738,24 @@ std::vector createHelper::_getFailedUsesDevices(const std::vector_aware = true; + } else if ((option.value == "false") || (option.value == "False") || (option.value == "FALSE") || (option.value == "0")) { + this->_aware = false; + } + } else if (option.name == "STOP_TIMEOUT") { + this->_stopTimeout = strtof(option.value.c_str(), NULL); + } + } +} + void createHelper::setUpExternalPorts(redhawk::ApplicationDeployment& appDeployment, Application_impl* application) { @@ -934,17 +952,53 @@ CF::Application_ptr createHelper::create ( { TRACE_ENTER(ApplicationFactory_impl); - bool aware_application = true; - CF::Properties modifiedInitConfiguration; + checkOptions(); + /////////////////////////////////////////////////////////////////// // Check to see if this is an aware application and // check to see if a different GPP reservation setting is defined const std::string aware_app_property_id(ExtendedCF::WKP::AWARE_APPLICATION); + const std::string aware_app_deprecated_property_id("AWARE_APPLICATION"); + const std::string stop_timeout_property_id(ExtendedCF::WKP::STOP_TIMEOUT); for (unsigned int initCount = 0; initCount < initConfiguration.length(); initCount++) { - if (std::string(initConfiguration[initCount].id) == aware_app_property_id) { - initConfiguration[initCount].value >>= aware_application; + std::string stringId(initConfiguration[initCount].id); + if ((stringId == aware_app_property_id) or (stringId == aware_app_deprecated_property_id)) { + initConfiguration[initCount].value >>= this->_aware; + modifiedInitConfiguration.length(initConfiguration.length()-1); + for (unsigned int rem_idx=0; rem_idx>= short_to) { + this->_stopTimeout = short_to; + } else if (initConfiguration[initCount].value >>= long_to) { + this->_stopTimeout = long_to; + } else if (initConfiguration[initCount].value >>= ushort_to) { + this->_stopTimeout = ushort_to; + } else if (initConfiguration[initCount].value >>= ulong_to) { + this->_stopTimeout = ulong_to; + } else if (initConfiguration[initCount].value >>= double_to) { + this->_stopTimeout = (float)double_to; + } else if (initConfiguration[initCount].value >>= float_to) { + this->_stopTimeout = float_to; + } else { + throw std::logic_error("Option STOP_TIMEOUT must be a number"); + } modifiedInitConfiguration.length(initConfiguration.length()-1); for (unsigned int rem_idx=0; rem_idx_aware, + this->_stopTimeout, _domainContext); _appFact._domainManager->addPendingApplication(_application); @@ -2495,7 +2550,9 @@ createHelper::createHelper ( _domainContext(domainContext), _profileCache(_appFact._fileMgr), _isComplete(false), - _application(0) + _application(0), + _stopTimeout(DEFAULT_STOP_TIMEOUT), + _aware(true) { } diff --git a/redhawk/src/control/sdr/dommgr/Application_impl.cpp b/redhawk/src/control/sdr/dommgr/Application_impl.cpp index 6c16566c4..c45c44162 100644 --- a/redhawk/src/control/sdr/dommgr/Application_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/Application_impl.cpp @@ -111,7 +111,8 @@ namespace { Application_impl::Application_impl (const std::string& id, const std::string& name, const std::string& profile, DomainManager_impl* domainManager, const std::string& waveformContextName, - CosNaming::NamingContext_ptr waveformContext, bool aware, CosNaming::NamingContext_ptr DomainContext) : + CosNaming::NamingContext_ptr waveformContext, bool aware, + float stopTimeout, CosNaming::NamingContext_ptr DomainContext) : _assemblyController(0), _identifier(id), _sadProfile(profile), @@ -121,6 +122,7 @@ Application_impl::Application_impl (const std::string& id, const std::string& na _waveformContext(CosNaming::NamingContext::_duplicate(waveformContext)), _started(false), _isAware(aware), + _stopTimeout(stopTimeout), _fakeProxy(0), _domainContext(CosNaming::NamingContext::_duplicate(DomainContext)), _releaseAlreadyCalled(false) @@ -270,10 +272,10 @@ throw (CORBA::SystemException, CF::Resource::StopError) return; } } - this->local_stop(); + this->local_stop(this->_stopTimeout); } -void Application_impl::local_stop () +void Application_impl::local_stop (float timeout) throw (CORBA::SystemException, CF::Resource::StopError) { if (!_assemblyController && _startOrder.empty()) { @@ -284,14 +286,14 @@ throw (CORBA::SystemException, CF::Resource::StopError) // Stop the components in the reverse order they were started BOOST_REVERSE_FOREACH(redhawk::ApplicationComponent* component, _startOrder) { LOG_TRACE(Application_impl, "Calling stop for " << component->getIdentifier()); - if (!component->stop()) { + if (!component->stop(timeout)) { failures++; } } if (_assemblyController) { LOG_TRACE(Application_impl, "Calling stop on assembly controller"); - if (!_assemblyController->stop()) { + if (!_assemblyController->stop(timeout)) { failures++; } } @@ -314,6 +316,13 @@ throw (CORBA::SystemException, CF::Resource::StopError) } } +CORBA::Float Application_impl::stopTimeout () throw (CORBA::SystemException) { + return this->_stopTimeout; +} + +void Application_impl::stopTimeout (CORBA::Float timeout) throw (CORBA::SystemException) { + this->_stopTimeout = timeout; +} void Application_impl::initializeProperties (const CF::Properties& configProperties) throw (CF::PropertySet::PartialConfiguration, CF::PropertySet::InvalidConfiguration, CORBA::SystemException) @@ -901,7 +910,7 @@ throw (CORBA::SystemException, CF::LifeCycle::ReleaseError) // Stop all components on the application try { - this->local_stop(); + this->local_stop(DEFAULT_STOP_TIMEOUT); } catch ( ... ) { // error happened while stopping. Ignore the error and continue tear-down LOG_TRACE(Application_impl, "Error occurred while stopping the application during tear-down. Ignoring the error and continuing") diff --git a/redhawk/src/control/sdr/dommgr/Application_impl.h b/redhawk/src/control/sdr/dommgr/Application_impl.h index 6db3281ee..e0d47cdf0 100644 --- a/redhawk/src/control/sdr/dommgr/Application_impl.h +++ b/redhawk/src/control/sdr/dommgr/Application_impl.h @@ -51,7 +51,8 @@ class Application_impl : public virtual POA_CF::Application, public Logging_impl Application_impl (const std::string& id, const std::string& name, const std::string& profile, DomainManager_impl* domainManager, const std::string& waveformContextName, - CosNaming::NamingContext_ptr waveformContext, bool aware, CosNaming::NamingContext_ptr DomainContext); + CosNaming::NamingContext_ptr waveformContext, bool aware, + float stopTimeout, CosNaming::NamingContext_ptr DomainContext); void populateApplication (const CF::DeviceAssignmentSequence& deviceAssignments, std::vector& connections, @@ -71,7 +72,7 @@ class Application_impl : public virtual POA_CF::Application, public Logging_impl void stop () throw (CF::Resource::StopError, CORBA::SystemException); - void local_stop () + void local_stop (float timeout) throw (CF::Resource::StopError, CORBA::SystemException); // The core framework provides an implementation for this method. @@ -120,6 +121,10 @@ class Application_impl : public virtual POA_CF::Application, public Logging_impl bool aware () throw (CORBA::SystemException); + CORBA::Float stopTimeout () throw (CORBA::SystemException); + + void stopTimeout (CORBA::Float timeout) throw (CORBA::SystemException); + CF::DeviceAssignmentSequence * componentDevices () throw (CORBA::SystemException); @@ -208,6 +213,7 @@ class Application_impl : public virtual POA_CF::Application, public Logging_impl CosNaming::NamingContext_var _waveformContext; bool _started; const bool _isAware; + float _stopTimeout; FakeApplication* _fakeProxy; ApplicationRegistrar_impl* _registrar; diff --git a/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp b/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp index 8f5a96285..527b44bc8 100644 --- a/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp +++ b/redhawk/src/control/sdr/dommgr/DomainManager_impl.cpp @@ -2669,6 +2669,7 @@ Application_impl* DomainManager_impl::_restoreApplication(ossie::ApplicationNode node.contextName, node.context, node.aware_application, + node.stop_timeout, CosNaming::NamingContext::_nil()); LOG_TRACE(DomainManager_impl, "Restored " << node.connections.size() << " connections"); @@ -2768,6 +2769,7 @@ void DomainManager_impl::_persistApplication(Application_impl* application) appNode.allocationIDs = application->_allocationIDs; appNode.connections = application->_connections; appNode.aware_application = application->_isAware; + appNode.stop_timeout = application->_stopTimeout; appNode.ports = application->_ports; appNode.properties = application->_properties; diff --git a/redhawk/src/control/sdr/dommgr/FakeApplication.cpp b/redhawk/src/control/sdr/dommgr/FakeApplication.cpp index bb1e4a540..d3b2fc05a 100644 --- a/redhawk/src/control/sdr/dommgr/FakeApplication.cpp +++ b/redhawk/src/control/sdr/dommgr/FakeApplication.cpp @@ -122,6 +122,13 @@ bool FakeApplication::aware () return false; } +CORBA::Float FakeApplication::stopTimeout () throw (CORBA::SystemException) { + return -1; +} + +void FakeApplication::stopTimeout (CORBA::Float timeout) throw (CORBA::SystemException) { +} + CF::DeviceAssignmentSequence * FakeApplication::componentDevices () { return new CF::DeviceAssignmentSequence(); diff --git a/redhawk/src/control/sdr/dommgr/FakeApplication.h b/redhawk/src/control/sdr/dommgr/FakeApplication.h index 95279b2ee..9b33669a2 100644 --- a/redhawk/src/control/sdr/dommgr/FakeApplication.h +++ b/redhawk/src/control/sdr/dommgr/FakeApplication.h @@ -68,6 +68,10 @@ class FakeApplication : public virtual POA_CF::Application, public Logging_impl bool aware (); + CORBA::Float stopTimeout () throw (CORBA::SystemException); + + void stopTimeout (CORBA::Float timeout) throw (CORBA::SystemException); + CF::DeviceAssignmentSequence * componentDevices (); CF::Application::ComponentElementSequence * componentImplementations (); CF::Application::ComponentElementSequence * componentNamingContexts (); diff --git a/redhawk/src/control/sdr/dommgr/PersistenceStore.h b/redhawk/src/control/sdr/dommgr/PersistenceStore.h index a462131df..091df265f 100644 --- a/redhawk/src/control/sdr/dommgr/PersistenceStore.h +++ b/redhawk/src/control/sdr/dommgr/PersistenceStore.h @@ -149,6 +149,7 @@ namespace ossie { std::map ports; std::map > properties; bool aware_application; + float stop_timeout; }; class ServiceNode { diff --git a/redhawk/src/control/sdr/dommgr/createHelper.h b/redhawk/src/control/sdr/dommgr/createHelper.h index a3b9ed503..d10ae18fe 100644 --- a/redhawk/src/control/sdr/dommgr/createHelper.h +++ b/redhawk/src/control/sdr/dommgr/createHelper.h @@ -108,6 +108,7 @@ class createHelper const std::map& specialized_reservations); void _resolveAssemblyController(redhawk::ApplicationDeployment& appDeployment); void _validateDAS(redhawk::ApplicationDeployment& appDeployment, const DeviceAssignmentMap& deviceAssignments); + void checkOptions(); void setUpExternalPorts(redhawk::ApplicationDeployment& appDeployment, Application_impl* application); void setUpExternalProperties(redhawk::ApplicationDeployment& appDeployment, Application_impl* application); std::vector overloadReservations(const ossie::SoftwareAssembly::HostCollocation& collocation, @@ -201,5 +202,7 @@ class createHelper bool _isComplete; void _cleanupFailedCreate(); Application_impl* _application; + float _stopTimeout; + bool _aware; }; #endif diff --git a/redhawk/src/idl/ossie/CF/WellKnownProperties.idl b/redhawk/src/idl/ossie/CF/WellKnownProperties.idl index 3dfdd9af8..2d3937f33 100644 --- a/redhawk/src/idl/ossie/CF/WellKnownProperties.idl +++ b/redhawk/src/idl/ossie/CF/WellKnownProperties.idl @@ -28,7 +28,8 @@ module ExtendedCF { const string OS_NAME = "DCE:4a23ad60-0b25-4121-a630-68803a498f75"; const string OS_VERSION = "DCE:0f3a9a37-a342-43d8-9b7f-78dc6da74192"; const string PROCESSOR_NAME = "DCE:fefb9c66-d14a-438d-ad59-2cfd1adb272b"; - const string AWARE_APPLICATION = "AWARE_APPLICATION"; + const string AWARE_APPLICATION = "RH::AWARE_APPLICATION"; + const string STOP_TIMEOUT = "RH::STOP_TIMEOUT"; }; }; #endif diff --git a/redhawk/src/idl/ossie/CF/cf.idl b/redhawk/src/idl/ossie/CF/cf.idl index 44a8c180b..e00078cc1 100644 --- a/redhawk/src/idl/ossie/CF/cf.idl +++ b/redhawk/src/idl/ossie/CF/cf.idl @@ -1040,6 +1040,8 @@ module CF { /*readonly attribute ApplicationRegistrar appReg;*/ /* This boolean attribute contains the aware state of Application. This attribute shows whether the Components in the Application are given a pointer to the Application and Domain Manager. */ readonly attribute boolean aware; + /* This readwrite float attribute is the stop timeout for the Application. This is how long the framework will wait on each component when stop is called (not during releaseObject). */ + attribute float stopTimeout; exception InvalidMetric { CF::StringSequence components; CF::StringSequence attributes; diff --git a/redhawk/src/testing/sdr/dom/components/hanging_stop/hanging_stop.prf.xml b/redhawk/src/testing/sdr/dom/components/hanging_stop/hanging_stop.prf.xml new file mode 100644 index 000000000..8f537d89f --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/hanging_stop/hanging_stop.prf.xml @@ -0,0 +1,3 @@ + + + diff --git a/redhawk/src/testing/sdr/dom/components/hanging_stop/hanging_stop.scd.xml b/redhawk/src/testing/sdr/dom/components/hanging_stop/hanging_stop.scd.xml new file mode 100644 index 000000000..df94ceaf5 --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/hanging_stop/hanging_stop.scd.xml @@ -0,0 +1,45 @@ + + + + 2.2 + + resource + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/redhawk/src/testing/sdr/dom/components/hanging_stop/hanging_stop.spd.xml b/redhawk/src/testing/sdr/dom/components/hanging_stop/hanging_stop.spd.xml new file mode 100644 index 000000000..1a55435f8 --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/hanging_stop/hanging_stop.spd.xml @@ -0,0 +1,25 @@ + + + + + + null + + + + + + + + + The implementation contains descriptive information about the template for a software resource. + + + python/hanging_stop.py + + + + + + + diff --git a/redhawk/src/testing/sdr/dom/components/hanging_stop/python/hanging_stop.py b/redhawk/src/testing/sdr/dom/components/hanging_stop/python/hanging_stop.py new file mode 100755 index 000000000..b80fe93b1 --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/hanging_stop/python/hanging_stop.py @@ -0,0 +1,160 @@ +#!/usr/bin/env python +# +# +# AUTO-GENERATED +# +# Source: hanging_stop.spd.xml +from ossie.resource import start_component +import logging + +from hanging_stop_base import * + +class hanging_stop_i(hanging_stop_base): + """""" + def constructor(self): + """ + This is called by the framework immediately after your component registers with the system. + + In general, you should add customization here and not in the __init__ constructor. If you have + a custom port implementation you can override the specific implementation here with a statement + similar to the following: + self.some_port = MyPortImplementation() + + """ + # TODO add customization here. + + def stop(self): + while True: + time.sleep(0.1) + + def process(self): + """ + Basic functionality: + + The process method should process a single "chunk" of data and then return. This method + will be called from the processing thread again, and again, and again until it returns + FINISH or stop() is called on the component. If no work is performed, then return NOOP. + + StreamSRI: + To create a StreamSRI object, use the following code (this generates a normalized SRI that does not flush the queue when full): + sri = bulkio.sri.create("my_stream_id") + + PrecisionUTCTime: + To create a PrecisionUTCTime object, use the following code: + tstamp = bulkio.timestamp.now() + + Ports: + + Each port instance is accessed through members of the following form: self.port_ + + Data is obtained in the process function through the getPacket call (BULKIO only) on a + provides port member instance. The optional argument is a timeout value, in seconds. + A zero value is non-blocking, while a negative value is blocking. Constants have been + defined for these values, bulkio.const.BLOCKING and bulkio.const.NON_BLOCKING. If no + timeout is given, it defaults to non-blocking. + + The return value is a named tuple with the following fields: + - dataBuffer + - T + - EOS + - streamID + - SRI + - sriChanged + - inputQueueFlushed + If no data is available due to a timeout, all fields are None. + + To send data, call the appropriate function in the port directly. In the case of BULKIO, + convenience functions have been added in the port classes that aid in output. + + Interactions with non-BULKIO ports are left up to the component developer's discretion. + + Messages: + + To receive a message, you need (1) an input port of type MessageEvent, (2) a message prototype described + as a structure property of kind message, (3) a callback to service the message, and (4) to register the callback + with the input port. + + Assuming a property of type message is declared called "my_msg", an input port called "msg_input" is declared of + type MessageEvent, create the following code: + + def msg_callback(self, msg_id, msg_value): + print msg_id, msg_value + + Register the message callback onto the input port with the following form: + self.port_input.registerMessage("my_msg", hanging_stop_i.MyMsg, self.msg_callback) + + To send a message, you need to (1) create a message structure, and (2) send the message over the port. + + Assuming a property of type message is declared called "my_msg", an output port called "msg_output" is declared of + type MessageEvent, create the following code: + + msg_out = hanging_stop_i.MyMsg() + this.port_msg_output.sendMessage(msg_out) + + Accessing the Device Manager and Domain Manager: + + Both the Device Manager hosting this Device and the Domain Manager hosting + the Device Manager are available to the Device. + + To access the Domain Manager: + dommgr = self.getDomainManager().getRef(); + To access the Device Manager: + devmgr = self.getDeviceManager().getRef(); + Properties: + + Properties are accessed directly as member variables. If the property name is baudRate, + then accessing it (for reading or writing) is achieved in the following way: self.baudRate. + + To implement a change callback notification for a property, create a callback function with the following form: + + def mycallback(self, id, old_value, new_value): + pass + + where id is the property id, old_value is the previous value, and new_value is the updated value. + + The callback is then registered on the component as: + self.addPropertyChangeListener('baudRate', self.mycallback) + + + Example: + + # This example assumes that the component has two ports: + # - A provides (input) port of type bulkio.InShortPort called dataShort_in + # - A uses (output) port of type bulkio.OutFloatPort called dataFloat_out + # The mapping between the port and the class if found in the component + # base class. + # This example also makes use of the following Properties: + # - A float value called amplitude + # - A boolean called increaseAmplitude + + packet = self.port_dataShort_in.getPacket() + + if packet.dataBuffer is None: + return NOOP + + outData = range(len(packet.dataBuffer)) + for i in range(len(packet.dataBuffer)): + if self.increaseAmplitude: + outData[i] = float(packet.dataBuffer[i]) * self.amplitude + else: + outData[i] = float(packet.dataBuffer[i]) + + # NOTE: You must make at least one valid pushSRI call + if packet.sriChanged: + self.port_dataFloat_out.pushSRI(packet.SRI); + + self.port_dataFloat_out.pushPacket(outData, packet.T, packet.EOS, packet.streamID) + return NORMAL + + """ + + # TODO fill in your code here + self._log.debug("process() example log message") + return NOOP + + +if __name__ == '__main__': + logging.getLogger().setLevel(logging.INFO) + logging.debug("Starting Component") + start_component(hanging_stop_i) + diff --git a/redhawk/src/testing/sdr/dom/components/hanging_stop/python/hanging_stop_base.py b/redhawk/src/testing/sdr/dom/components/hanging_stop/python/hanging_stop_base.py new file mode 100644 index 000000000..99bc6f672 --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/hanging_stop/python/hanging_stop_base.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python +# +# AUTO-GENERATED CODE. DO NOT MODIFY! +# +# Source: hanging_stop.spd.xml +from ossie.cf import CF +from ossie.cf import CF__POA +from ossie.utils import uuid + +from ossie.component import Component +from ossie.threadedcomponent import * + +import Queue, copy, time, threading + +class hanging_stop_base(CF__POA.Resource, Component, ThreadedComponent): + # These values can be altered in the __init__ of your derived class + + PAUSE = 0.0125 # The amount of time to sleep if process return NOOP + TIMEOUT = 5.0 # The amount of time to wait for the process thread to die when stop() is called + DEFAULT_QUEUE_SIZE = 100 # The number of BulkIO packets that can be in the queue before pushPacket will block + + def __init__(self, identifier, execparams): + loggerName = (execparams['NAME_BINDING'].replace('/', '.')).rsplit("_", 1)[0] + Component.__init__(self, identifier, execparams, loggerName=loggerName) + ThreadedComponent.__init__(self) + + # self.auto_start is deprecated and is only kept for API compatibility + # with 1.7.X and 1.8.0 components. This variable may be removed + # in future releases + self.auto_start = False + # Instantiate the default implementations for all ports on this component + + def start(self): + Component.start(self) + ThreadedComponent.startThread(self, pause=self.PAUSE) + + def stop(self): + Component.stop(self) + if not ThreadedComponent.stopThread(self, self.TIMEOUT): + raise CF.Resource.StopError(CF.CF_NOTSET, "Processing thread did not die") + + def releaseObject(self): + try: + self.stop() + except Exception: + self._log.exception("Error stopping") + Component.releaseObject(self) + + ###################################################################### + # PORTS + # + # DO NOT ADD NEW PORTS HERE. You can add ports in your derived class, in the SCD xml file, + # or via the IDE. + + ###################################################################### + # PROPERTIES + # + # DO NOT ADD NEW PROPERTIES HERE. You can add properties in your derived class, in the PRF xml file + # or by using the IDE. + + diff --git a/redhawk/src/testing/sdr/dom/components/slow_stop/python/slow_stop.py b/redhawk/src/testing/sdr/dom/components/slow_stop/python/slow_stop.py new file mode 100755 index 000000000..f09c114ae --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/slow_stop/python/slow_stop.py @@ -0,0 +1,156 @@ +#!/usr/bin/env python +# +# +# AUTO-GENERATED +# +# Source: slow_stop.spd.xml +from ossie.resource import start_component +import logging + +from slow_stop_base import * + +class slow_stop_i(slow_stop_base): + """""" + def constructor(self): + """ + This is called by the framework immediately after your component registers with the system. + + In general, you should add customization here and not in the __init__ constructor. If you have + a custom port implementation you can override the specific implementation here with a statement + similar to the following: + self.some_port = MyPortImplementation() + + """ + # TODO add customization here. + + def process(self): + """ + Basic functionality: + + The process method should process a single "chunk" of data and then return. This method + will be called from the processing thread again, and again, and again until it returns + FINISH or stop() is called on the component. If no work is performed, then return NOOP. + + StreamSRI: + To create a StreamSRI object, use the following code (this generates a normalized SRI that does not flush the queue when full): + sri = bulkio.sri.create("my_stream_id") + + PrecisionUTCTime: + To create a PrecisionUTCTime object, use the following code: + tstamp = bulkio.timestamp.now() + + Ports: + + Each port instance is accessed through members of the following form: self.port_ + + Data is obtained in the process function through the getPacket call (BULKIO only) on a + provides port member instance. The optional argument is a timeout value, in seconds. + A zero value is non-blocking, while a negative value is blocking. Constants have been + defined for these values, bulkio.const.BLOCKING and bulkio.const.NON_BLOCKING. If no + timeout is given, it defaults to non-blocking. + + The return value is a named tuple with the following fields: + - dataBuffer + - T + - EOS + - streamID + - SRI + - sriChanged + - inputQueueFlushed + If no data is available due to a timeout, all fields are None. + + To send data, call the appropriate function in the port directly. In the case of BULKIO, + convenience functions have been added in the port classes that aid in output. + + Interactions with non-BULKIO ports are left up to the component developer's discretion. + + Messages: + + To receive a message, you need (1) an input port of type MessageEvent, (2) a message prototype described + as a structure property of kind message, (3) a callback to service the message, and (4) to register the callback + with the input port. + + Assuming a property of type message is declared called "my_msg", an input port called "msg_input" is declared of + type MessageEvent, create the following code: + + def msg_callback(self, msg_id, msg_value): + print msg_id, msg_value + + Register the message callback onto the input port with the following form: + self.port_input.registerMessage("my_msg", slow_stop_i.MyMsg, self.msg_callback) + + To send a message, you need to (1) create a message structure, and (2) send the message over the port. + + Assuming a property of type message is declared called "my_msg", an output port called "msg_output" is declared of + type MessageEvent, create the following code: + + msg_out = slow_stop_i.MyMsg() + this.port_msg_output.sendMessage(msg_out) + + Accessing the Device Manager and Domain Manager: + + Both the Device Manager hosting this Device and the Domain Manager hosting + the Device Manager are available to the Device. + + To access the Domain Manager: + dommgr = self.getDomainManager().getRef(); + To access the Device Manager: + devmgr = self.getDeviceManager().getRef(); + Properties: + + Properties are accessed directly as member variables. If the property name is baudRate, + then accessing it (for reading or writing) is achieved in the following way: self.baudRate. + + To implement a change callback notification for a property, create a callback function with the following form: + + def mycallback(self, id, old_value, new_value): + pass + + where id is the property id, old_value is the previous value, and new_value is the updated value. + + The callback is then registered on the component as: + self.addPropertyChangeListener('baudRate', self.mycallback) + + + Example: + + # This example assumes that the component has two ports: + # - A provides (input) port of type bulkio.InShortPort called dataShort_in + # - A uses (output) port of type bulkio.OutFloatPort called dataFloat_out + # The mapping between the port and the class if found in the component + # base class. + # This example also makes use of the following Properties: + # - A float value called amplitude + # - A boolean called increaseAmplitude + + packet = self.port_dataShort_in.getPacket() + + if packet.dataBuffer is None: + return NOOP + + outData = range(len(packet.dataBuffer)) + for i in range(len(packet.dataBuffer)): + if self.increaseAmplitude: + outData[i] = float(packet.dataBuffer[i]) * self.amplitude + else: + outData[i] = float(packet.dataBuffer[i]) + + # NOTE: You must make at least one valid pushSRI call + if packet.sriChanged: + self.port_dataFloat_out.pushSRI(packet.SRI); + + self.port_dataFloat_out.pushPacket(outData, packet.T, packet.EOS, packet.streamID) + return NORMAL + + """ + + # TODO fill in your code here + self._log.debug("process() example log message") + return NOOP + + +if __name__ == '__main__': + logging.getLogger().setLevel(logging.INFO) + logging.debug("Starting Component") + start_component(slow_stop_i) + diff --git a/redhawk/src/testing/sdr/dom/components/slow_stop/python/slow_stop_base.py b/redhawk/src/testing/sdr/dom/components/slow_stop/python/slow_stop_base.py new file mode 100644 index 000000000..880a4d9b4 --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/slow_stop/python/slow_stop_base.py @@ -0,0 +1,72 @@ +#!/usr/bin/env python +# +# AUTO-GENERATED CODE. DO NOT MODIFY! +# +# Source: slow_stop.spd.xml +from ossie.cf import CF +from ossie.cf import CF__POA +from ossie.utils import uuid + +from ossie.component import Component +from ossie.threadedcomponent import * + +import Queue, copy, time, threading + +class slow_stop_base(CF__POA.Resource, Component, ThreadedComponent): + # These values can be altered in the __init__ of your derived class + + PAUSE = 0.0125 # The amount of time to sleep if process return NOOP + TIMEOUT = 5.0 # The amount of time to wait for the process thread to die when stop() is called + DEFAULT_QUEUE_SIZE = 100 # The number of BulkIO packets that can be in the queue before pushPacket will block + + def __init__(self, identifier, execparams): + loggerName = (execparams['NAME_BINDING'].replace('/', '.')).rsplit("_", 1)[0] + Component.__init__(self, identifier, execparams, loggerName=loggerName) + ThreadedComponent.__init__(self) + + # self.auto_start is deprecated and is only kept for API compatibility + # with 1.7.X and 1.8.0 components. This variable may be removed + # in future releases + self.auto_start = False + # Instantiate the default implementations for all ports on this component + + def start(self): + Component.start(self) + ThreadedComponent.startThread(self, pause=self.PAUSE) + + def stop(self): + begin_time = time.time() + curr_time = time.time() + while (curr_time-begin_time < 5): + time.sleep(0.1) + curr_time = time.time() + try: + Component.stop(self) + if not ThreadedComponent.stopThread(self, self.TIMEOUT): + raise CF.Resource.StopError(CF.CF_NOTSET, "Processing thread did not die") + except: + pass + + def releaseObject(self): + try: + self.stop() + except Exception: + self._log.exception("Error stopping") + try: + Component.releaseObject(self) + except: + pass + + ###################################################################### + # PORTS + # + # DO NOT ADD NEW PORTS HERE. You can add ports in your derived class, in the SCD xml file, + # or via the IDE. + + ###################################################################### + # PROPERTIES + # + # DO NOT ADD NEW PROPERTIES HERE. You can add properties in your derived class, in the PRF xml file + # or by using the IDE. + + diff --git a/redhawk/src/testing/sdr/dom/components/slow_stop/slow_stop.prf.xml b/redhawk/src/testing/sdr/dom/components/slow_stop/slow_stop.prf.xml new file mode 100644 index 000000000..8f537d89f --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/slow_stop/slow_stop.prf.xml @@ -0,0 +1,3 @@ + + + diff --git a/redhawk/src/testing/sdr/dom/components/slow_stop/slow_stop.scd.xml b/redhawk/src/testing/sdr/dom/components/slow_stop/slow_stop.scd.xml new file mode 100644 index 000000000..df94ceaf5 --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/slow_stop/slow_stop.scd.xml @@ -0,0 +1,45 @@ + + + + 2.2 + + resource + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/redhawk/src/testing/sdr/dom/components/slow_stop/slow_stop.spd.xml b/redhawk/src/testing/sdr/dom/components/slow_stop/slow_stop.spd.xml new file mode 100644 index 000000000..cc1b4303e --- /dev/null +++ b/redhawk/src/testing/sdr/dom/components/slow_stop/slow_stop.spd.xml @@ -0,0 +1,25 @@ + + + + + + null + + + + + + + + + The implementation contains descriptive information about the template for a software resource. + + + python/slow_stop.py + + + + + + + diff --git a/redhawk/src/testing/sdr/dom/waveforms/cpp_comp_aware_w/cpp_comp_aware_w.sad.xml b/redhawk/src/testing/sdr/dom/waveforms/cpp_comp_aware_w/cpp_comp_aware_w.sad.xml new file mode 100644 index 000000000..5e88c0b6c --- /dev/null +++ b/redhawk/src/testing/sdr/dom/waveforms/cpp_comp_aware_w/cpp_comp_aware_w.sad.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + cpp_comp_1 + + + + + + + + + + + + diff --git a/redhawk/src/testing/tests/test_04_ApplicationFactory.py b/redhawk/src/testing/tests/test_04_ApplicationFactory.py index 235da1e37..4ca68c177 100644 --- a/redhawk/src/testing/tests/test_04_ApplicationFactory.py +++ b/redhawk/src/testing/tests/test_04_ApplicationFactory.py @@ -24,7 +24,7 @@ from xml.dom import minidom from omniORB import CORBA, URI, any import omniORB -from ossie.cf import CF, CF__POA +from ossie.cf import CF, CF__POA, ExtendedCF import commands from ossie.utils import redhawk from ossie import properties @@ -2742,6 +2742,138 @@ def test_StopAllComponents(self): comp.componentObject.configure(props) app.releaseObject() + def test_StopTimeout(self): + nb, domMgr = self.launchDomainManager(debug=self.debuglevel) + self.assertNotEqual(domMgr, None) + + nb, devMgr = self.launchDeviceManager('/nodes/test_BasicTestDevice_node/DeviceManager.dcd.xml', debug=self.debuglevel) + self.assertNotEqual(devMgr, None) + + # Create the application, which is pre-configured such that the last + # component in the start order (and hence, first in stop) will fail on + # stop(). + app = domMgr.createApplication('/waveforms/long_stop/long_stop.sad.xml', 'long_stop', [], []) + app.start() + begin_stop = time.time() + try: + app.stop() + except: + pass + end_stop = time.time() + stop_time = end_stop-begin_stop + app.releaseObject() + end_release = time.time() + release_time = end_release-end_stop + self.assertTrue(16<=stop_time<=17) + self.assertTrue(20<=release_time<=21) + + def test_StopTimeoutBuiltinDefault(self): + nb, domMgr = self.launchDomainManager(debug=self.debuglevel) + self.assertNotEqual(domMgr, None) + + nb, devMgr = self.launchDeviceManager('/nodes/test_BasicTestDevice_node/DeviceManager.dcd.xml', debug=self.debuglevel) + self.assertNotEqual(devMgr, None) + + # Create the application, which is pre-configured such that the last + # component in the start order (and hence, first in stop) will fail on + # stop(). + app = domMgr.createApplication('/waveforms/long_stop_builtin_def/long_stop_builtin_def.sad.xml', 'long_stop', [], []) + app.start() + begin_stop = time.time() + try: + app.stop() + except: + pass + end_stop = time.time() + stop_time = end_stop-begin_stop + app.releaseObject() + end_release = time.time() + release_time = end_release-end_stop + self.assertTrue(6<=stop_time<=7) + self.assertTrue(20<=release_time<=21) + + def test_StopTimeoutLiveOverride(self): + nb, domMgr = self.launchDomainManager(debug=self.debuglevel) + self.assertNotEqual(domMgr, None) + + nb, devMgr = self.launchDeviceManager('/nodes/test_BasicTestDevice_node/DeviceManager.dcd.xml', debug=self.debuglevel) + self.assertNotEqual(devMgr, None) + + # Create the application, which is pre-configured such that the last + # component in the start order (and hence, first in stop) will fail on + # stop(). + initconfig = [CF.DataType(id=ExtendedCF.WKP.STOP_TIMEOUT, value=any.to_any(4))] + app = domMgr.createApplication('/waveforms/long_stop/long_stop.sad.xml', 'long_stop', initconfig, []) + app.start() + begin_stop = time.time() + try: + app.stop() + except: + pass + end_stop = time.time() + stop_time = end_stop-begin_stop + app.releaseObject() + end_release = time.time() + release_time = end_release-end_stop + self.assertTrue(8<=stop_time<=9) + self.assertTrue(20<=release_time<=21) + + def test_StopTimeoutChange(self): + nb, domMgr = self.launchDomainManager(debug=self.debuglevel) + self.assertNotEqual(domMgr, None) + + nb, devMgr = self.launchDeviceManager('/nodes/test_BasicTestDevice_node/DeviceManager.dcd.xml', debug=self.debuglevel) + self.assertNotEqual(devMgr, None) + + # Create the application, which is pre-configured such that the last + # component in the start order (and hence, first in stop) will fail on + # stop(). + initconfig = [CF.DataType(id=ExtendedCF.WKP.STOP_TIMEOUT, value=any.to_any(4))] + app = domMgr.createApplication('/waveforms/long_stop/long_stop.sad.xml', 'long_stop', initconfig, []) + app.start() + curr_stoptimeout = app._get_stopTimeout() + self.assertEquals(curr_stoptimeout, 4.0) + app._set_stopTimeout(5) + begin_stop = time.time() + try: + app.stop() + except: + pass + end_stop = time.time() + stop_time = end_stop-begin_stop + app.releaseObject() + end_release = time.time() + release_time = end_release-end_stop + self.assertTrue(10<=stop_time<=11) + self.assertTrue(20<=release_time<=21) + + def test_StopTimeoutIndefinite(self): + nb, domMgr = self.launchDomainManager(debug=self.debuglevel) + self.assertNotEqual(domMgr, None) + + nb, devMgr = self.launchDeviceManager('/nodes/test_BasicTestDevice_node/DeviceManager.dcd.xml', debug=self.debuglevel) + self.assertNotEqual(devMgr, None) + + # Create the application, which is pre-configured such that the last + # component in the start order (and hence, first in stop) will fail on + # stop(). + app = domMgr.createApplication('/waveforms/slow_stop_w/slow_stop_w.sad.xml', 'slow_stop', [], []) + app.start() + curr_stoptimeout = app._get_stopTimeout() + self.assertEquals(curr_stoptimeout, -1) + begin_stop = time.time() + try: + app.stop() + except: + pass + end_stop = time.time() + stop_time = end_stop-begin_stop + app.releaseObject() + end_release = time.time() + release_time = end_release-end_stop + self.assertTrue(5<=stop_time<=6) + self.assertTrue(8<=release_time<=9) + def _test_ValgrindCppDevice(self, appFact, valgrind): # Clear the device cache to prevent false positives deviceCacheDir = os.path.join(scatest.getSdrCache(), ".ExecutableDevice_node", "ExecutableDevice1") diff --git a/redhawk/src/testing/tests/test_04_ApplicationRegistrar.py b/redhawk/src/testing/tests/test_04_ApplicationRegistrar.py index 26949930e..81b162f42 100644 --- a/redhawk/src/testing/tests/test_04_ApplicationRegistrar.py +++ b/redhawk/src/testing/tests/test_04_ApplicationRegistrar.py @@ -350,6 +350,28 @@ def test_cppCompUnaware(self): app.releaseObject() self.assertEqual(len(domMgr._get_applications()), 0) + def test_cppCompWaveformOverride(self): + nodebooter, domMgr = self.launchDomainManager() + self.assertNotEqual(domMgr, None) + nodebooter, devMgr = self.launchDeviceManager("/nodes/test_GPP_node/DeviceManager.dcd.xml") + self.assertNotEqual(devMgr, None) + + domMgr.installApplication("/waveforms/cpp_comp_aware_w/cpp_comp_aware_w.sad.xml") + self.assertEqual(len(domMgr._get_applicationFactories()), 1) + appFact = domMgr._get_applicationFactories()[0] + + app = appFact.create(appFact._get_name(), [], []) + self.assertEqual(len(domMgr._get_applications()), 1) + app_id = app._get_registeredComponents()[0].componentObject.query([CF.DataType(id='app_id',value=any.to_any(None))])[0].value._v + number_components = app._get_registeredComponents()[0].componentObject.query([CF.DataType(id='number_components',value=any.to_any(None))])[0].value._v + dom_id = app._get_registeredComponents()[0].componentObject.query([CF.DataType(id='dom_id',value=any.to_any(None))])[0].value._v + self.assertEqual(app_id, app._get_identifier()) + self.assertEqual(number_components, 0) + self.assertEqual(dom_id, "") + self.assertEqual(app._get_aware(), False) + app.releaseObject() + self.assertEqual(len(domMgr._get_applications()), 0) + def test_pyCompUnaware(self): nodebooter, domMgr = self.launchDomainManager() self.assertNotEqual(domMgr, None) diff --git a/redhawk/src/xml/dtd/softwareassembly.dtd b/redhawk/src/xml/dtd/softwareassembly.dtd index 6323a718b..641729ea3 100644 --- a/redhawk/src/xml/dtd/softwareassembly.dtd +++ b/redhawk/src/xml/dtd/softwareassembly.dtd @@ -26,6 +26,7 @@ with this program. If not, see http://www.gnu.org/licenses/. , connections? , externalports? , externalproperties? + , settings? , usesdevicedependencies? )> + + + diff --git a/redhawk/src/xml/xsd/sad.xsd b/redhawk/src/xml/xsd/sad.xsd index bb8985f87..b9fc4247b 100644 --- a/redhawk/src/xml/xsd/sad.xsd +++ b/redhawk/src/xml/xsd/sad.xsd @@ -35,6 +35,7 @@ with this program. If not, see http://www.gnu.org/licenses/. + @@ -327,6 +328,15 @@ with this program. If not, see http://www.gnu.org/licenses/. + + + + + + + + + From be17950d154384073a6a53fcae1471b51f4b040a Mon Sep 17 00:00:00 2001 From: Max Robert Date: Thu, 17 Aug 2017 12:10:00 -0400 Subject: [PATCH 0866/1644] Refs CF-1815. Corrected error in dtd --- redhawk/src/xml/dtd/softwareassembly.dtd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/redhawk/src/xml/dtd/softwareassembly.dtd b/redhawk/src/xml/dtd/softwareassembly.dtd index 641729ea3..d528dde43 100644 --- a/redhawk/src/xml/dtd/softwareassembly.dtd +++ b/redhawk/src/xml/dtd/softwareassembly.dtd @@ -26,7 +26,7 @@ with this program. If not, see http://www.gnu.org/licenses/. , connections? , externalports? , externalproperties? - , settings? + , options? , usesdevicedependencies? )> Date: Thu, 17 Aug 2017 14:51:11 -0400 Subject: [PATCH 0867/1644] Refs CF-1827. Fixed typo in comments --- frontendInterfaces/idl/redhawk/FRONTEND/TunerControl.idl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontendInterfaces/idl/redhawk/FRONTEND/TunerControl.idl b/frontendInterfaces/idl/redhawk/FRONTEND/TunerControl.idl index 3320b057f..2dc1db298 100644 --- a/frontendInterfaces/idl/redhawk/FRONTEND/TunerControl.idl +++ b/frontendInterfaces/idl/redhawk/FRONTEND/TunerControl.idl @@ -213,14 +213,14 @@ module FRONTEND { The scan_mode property in the tuner_allocation structure is used for device allocation. If scan_mode is set to "Scan" and the device has the capability, it will be allocated. The scan_rate property is also available in the - tuner_allocation structure. It is used as a allocation property if the user specifies a desired rate for the scan + tuner_allocation structure. It is used as an allocation property if the user specifies a desired rate for the scan operation. It is an optional allocation parameter. Tuner SCAN Mode allows the tuner to internally perform a scan where the tuner itself retunes to cover the desired spectrum. There are two types of automated scans: Span scan and discrete frequency scan, and a single non-automated scan: Manual (the way devices normally operate). The scan_mode_type value determines the scan type. If the only scanning that the device allows is manual, then the device does not support scanning. A Span scan is created using a series of start/stop frequencies. A Discrete Frequency Scan is created from a series of discrete - frequencies. Each of these are inputs are used to create a series of center tune frequencies. Based on the selected bandwidth, + frequencies. Each of these inputs are used to create a series of center tune frequencies. Based on the selected bandwidth, the tuner scan generates as a series of center frequency retunes to cover the spectrum between the start/stop frequencies or discrete frequencies. From e275272d859794325d68ae00e43591699d209c1a Mon Sep 17 00:00:00 2001 From: Max Robert Date: Thu, 17 Aug 2017 15:00:11 -0400 Subject: [PATCH 0868/1644] Refs CF-1827. Further updates to comments --- frontendInterfaces/idl/redhawk/FRONTEND/TunerControl.idl | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/frontendInterfaces/idl/redhawk/FRONTEND/TunerControl.idl b/frontendInterfaces/idl/redhawk/FRONTEND/TunerControl.idl index 2dc1db298..873d3ff76 100644 --- a/frontendInterfaces/idl/redhawk/FRONTEND/TunerControl.idl +++ b/frontendInterfaces/idl/redhawk/FRONTEND/TunerControl.idl @@ -224,10 +224,9 @@ module FRONTEND { the tuner scan generates as a series of center frequency retunes to cover the spectrum between the start/stop frequencies or discrete frequencies. - If the scan_mode_enable is toggled from "OFF" to "ON", the tuner will begin to generate retunes for each center tune frequency - that was generated to cover the spectrum. It will then tune, dwell for a specific number of samples based on the dwell setting - and then move to the next center frequency. It is imperative to guarantee accurate data that the tuner not output samples until - the tuner settling time has been internally accounted for. + If the scan_mode_enabled reflects whether the tuner is currently scanning through a plan that was generated to cover the spectrum. + It will then tune, dwell for a specific number of samples based on the dwell setting and then move to the next center frequency. + No output samples should be generated until the tuner settling time has been internally accounted for. The start_time allows for synchronous sampling between multiple tuners. From b6347301db6c67222e7b2f49ea93a9245c30d6d6 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Fri, 25 Aug 2017 13:55:31 -0400 Subject: [PATCH 0869/1644] Refs CF-1815. Added missing waveform file --- .../dom/waveforms/long_stop/long_stop.sad.xml | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 redhawk/src/testing/sdr/dom/waveforms/long_stop/long_stop.sad.xml diff --git a/redhawk/src/testing/sdr/dom/waveforms/long_stop/long_stop.sad.xml b/redhawk/src/testing/sdr/dom/waveforms/long_stop/long_stop.sad.xml new file mode 100644 index 000000000..8b881cd8c --- /dev/null +++ b/redhawk/src/testing/sdr/dom/waveforms/long_stop/long_stop.sad.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + hanging_stop_1 + + + + + + + + + hanging_stop_2 + + + + + + + + + + + + From 0ce74a95efee25223d3e56593451a9550aa95d04 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Mon, 28 Aug 2017 11:58:50 -0400 Subject: [PATCH 0870/1644] Update 2.0.7 references to 2.1.2 --- .gitlab-ci.yml | 2 +- bulkioInterfaces/libsrc/pom.xml | 2 +- bulkioInterfaces/pom.xml | 2 +- burstioInterfaces/pom.xml | 2 +- burstioInterfaces/src/java/pom.xml | 2 +- frontendInterfaces/libsrc/pom.xml | 2 +- frontendInterfaces/pom.xml | 2 +- pom.xml | 2 +- redhawk/src/base/framework/java/ossie/pom.xml | 2 +- redhawk/src/base/framework/java/pom.xml | 2 +- redhawk/src/omnijni/pom.xml | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 57d6836d3..a5158c271 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -2,7 +2,7 @@ variables: rpm_release: "0.$CI_PIPELINE_ID" specfile: $project.spec other_repos: $yum_repo_url/redhawk-dependencies - redhawk_version: '2.0.7' + redhawk_version: '2.1.2' stages: - package-redhawk-codegen diff --git a/bulkioInterfaces/libsrc/pom.xml b/bulkioInterfaces/libsrc/pom.xml index 1da8f4eb6..8fa3edc4e 100644 --- a/bulkioInterfaces/libsrc/pom.xml +++ b/bulkioInterfaces/libsrc/pom.xml @@ -4,7 +4,7 @@ redhawk.coreframework parent - 2.0.7-SNAPSHOT + 2.1.2-SNAPSHOT ../../pom.xml bulkio diff --git a/bulkioInterfaces/pom.xml b/bulkioInterfaces/pom.xml index 14d27f927..4b8b532cc 100644 --- a/bulkioInterfaces/pom.xml +++ b/bulkioInterfaces/pom.xml @@ -4,7 +4,7 @@ redhawk.coreframework parent - 2.0.7-SNAPSHOT + 2.1.2-SNAPSHOT ../pom.xml bulkio-interfaces diff --git a/burstioInterfaces/pom.xml b/burstioInterfaces/pom.xml index c3b8864a1..4e3486a9f 100644 --- a/burstioInterfaces/pom.xml +++ b/burstioInterfaces/pom.xml @@ -4,7 +4,7 @@ redhawk.coreframework parent - 2.0.7-SNAPSHOT + 2.1.2-SNAPSHOT ../pom.xml burstio-interfaces diff --git a/burstioInterfaces/src/java/pom.xml b/burstioInterfaces/src/java/pom.xml index 334158de6..980d157cf 100644 --- a/burstioInterfaces/src/java/pom.xml +++ b/burstioInterfaces/src/java/pom.xml @@ -4,7 +4,7 @@ redhawk.coreframework parent - 2.0.7-SNAPSHOT + 2.1.2-SNAPSHOT ../../../pom.xml burstio diff --git a/frontendInterfaces/libsrc/pom.xml b/frontendInterfaces/libsrc/pom.xml index a09b33f64..0678a6cc5 100644 --- a/frontendInterfaces/libsrc/pom.xml +++ b/frontendInterfaces/libsrc/pom.xml @@ -4,7 +4,7 @@ redhawk.coreframework parent - 2.0.7-SNAPSHOT + 2.1.2-SNAPSHOT ../../pom.xml frontend diff --git a/frontendInterfaces/pom.xml b/frontendInterfaces/pom.xml index 2a2406943..f2c4f4a29 100644 --- a/frontendInterfaces/pom.xml +++ b/frontendInterfaces/pom.xml @@ -4,7 +4,7 @@ redhawk.coreframework parent - 2.0.7-SNAPSHOT + 2.1.2-SNAPSHOT ../pom.xml frontend-interfaces diff --git a/pom.xml b/pom.xml index 5288212b5..73584de3e 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 redhawk.coreframework parent - 2.0.7-SNAPSHOT + 2.1.2-SNAPSHOT pom Used to add maven coordinates to jars produced via make and generate source jar and other artifacts. diff --git a/redhawk/src/base/framework/java/ossie/pom.xml b/redhawk/src/base/framework/java/ossie/pom.xml index e0a589b47..cd1a55252 100644 --- a/redhawk/src/base/framework/java/ossie/pom.xml +++ b/redhawk/src/base/framework/java/ossie/pom.xml @@ -4,7 +4,7 @@ redhawk.coreframework parent - 2.0.7-SNAPSHOT + 2.1.2-SNAPSHOT ../../../../../../pom.xml ossie diff --git a/redhawk/src/base/framework/java/pom.xml b/redhawk/src/base/framework/java/pom.xml index cffd7ae0b..eeb3f3fcc 100644 --- a/redhawk/src/base/framework/java/pom.xml +++ b/redhawk/src/base/framework/java/pom.xml @@ -4,7 +4,7 @@ redhawk.coreframework parent - 2.0.7-SNAPSHOT + 2.1.2-SNAPSHOT ../../../../../pom.xml cf-interfaces diff --git a/redhawk/src/omnijni/pom.xml b/redhawk/src/omnijni/pom.xml index 8ff29c182..b408b4f67 100644 --- a/redhawk/src/omnijni/pom.xml +++ b/redhawk/src/omnijni/pom.xml @@ -4,7 +4,7 @@ redhawk.coreframework parent - 2.0.7-SNAPSHOT + 2.1.2-SNAPSHOT ../../../pom.xml omnijni From 04b9e5b8584bb8f82aaba8a60f2b461c3e000d14 Mon Sep 17 00:00:00 2001 From: Ryan Bauman Date: Mon, 28 Aug 2017 13:10:56 -0400 Subject: [PATCH 0871/1644] RELENG-716 - correct burstio package name in configure.ac --- burstioInterfaces/configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/burstioInterfaces/configure.ac b/burstioInterfaces/configure.ac index 9711b0e65..ac8f1d450 100644 --- a/burstioInterfaces/configure.ac +++ b/burstioInterfaces/configure.ac @@ -18,7 +18,7 @@ # along with this program. If not, see http://www.gnu.org/licenses/. # -AC_INIT(burstioInterfaces, 2.1.2) +AC_INIT(burstio, 2.1.2) AC_CONFIG_SRCDIR([src/cpp/Makefile.am]) AC_CONFIG_MACRO_DIR([m4]) From 95326f9ff336d8cdd46bda4eb8190b248a9ad389 Mon Sep 17 00:00:00 2001 From: Ryan Bauman Date: Mon, 28 Aug 2017 14:53:18 -0400 Subject: [PATCH 0872/1644] RELENG-717 - use version specific buildenv --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 24b31fc62..6b4f38ad4 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -259,7 +259,7 @@ frontend:el7: mvn:deploy: stage: package-redhawk-codegen - image: ${docker_registry}redhawk/buildenv:2.0-el7 + image: ${docker_registry}redhawk/buildenv:2.1-el7 variables: OSSIEHOME: /usr/local/redhawk/core SDRROOT: /var/redhawk/sdr From 61f8c834392d36b264ab43e5bc1ac3b008e072f3 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 29 Aug 2017 08:59:39 -0400 Subject: [PATCH 0873/1644] Make internal BulkIO input stream SRI change propagation clearer --- bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp index 378d2dff6..75195411f 100644 --- a/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp +++ b/bulkioInterfaces/libsrc/cpp/bulkio_in_stream.cpp @@ -523,18 +523,13 @@ class BufferedInputStream::Impl : public Base::Impl { // Allocate empty data block and propagate the SRI change and input queue // flush flags - DataBlockType _tblk(*this); - this->_setBlockFlags(_tblk, front); - if (_tblk.sriChanged()) { + DataBlockType data(front.SRI); + this->_setBlockFlags(data, front); + if (front.sriChanged) { + // Update the stream metadata StreamDescriptor::operator=(front.SRI); } - // set data block's sri - DataBlockType data(*this); - // assign back any state changes from _setBlockFlags - data.sriChangeFlags(_tblk.sriChangeFlags()); - data.inputQueueFlushed(_tblk.inputQueueFlushed()); - // Clear flags from packet, since they've been reported front.sriChanged = false; front.inputQueueFlushed = false; From 9b49a9a83c3b146b0f89d958f07fa75ba3f981d0 Mon Sep 17 00:00:00 2001 From: "Justin A. Irwin" Date: Tue, 29 Aug 2017 16:36:09 -0400 Subject: [PATCH 0874/1644] Fix failing tests --- redhawk/src/testing/tests/test_15_LoggingConfig.py | 1 + 1 file changed, 1 insertion(+) diff --git a/redhawk/src/testing/tests/test_15_LoggingConfig.py b/redhawk/src/testing/tests/test_15_LoggingConfig.py index 2d1270ebb..cef422717 100644 --- a/redhawk/src/testing/tests/test_15_LoggingConfig.py +++ b/redhawk/src/testing/tests/test_15_LoggingConfig.py @@ -28,6 +28,7 @@ import CosEventChannelAdmin from ossie.utils import sb import os +import contextlib @contextlib.contextmanager def stdout_redirect(where): From 6c85d62753b36b79d3bcdb43dfbf86d1dd114e75 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Thu, 31 Aug 2017 13:56:06 -0400 Subject: [PATCH 0875/1644] Refs CF-496. Added start order to Devices/services in a node --- .../ossie/DeviceManagerConfiguration.h | 2 +- .../control/parser/internal/dcd-parser.cpp | 1 + .../src/control/parser/internal/dcd-pimpl.cpp | 8 + .../src/control/parser/internal/dcd-pimpl.h | 3 + .../devmgr/DeviceManager_DeployerSupport.cpp | 3 - .../control/sdr/devmgr/DeviceManager_impl.cpp | 96 +++ .../control/sdr/devmgr/DeviceManager_impl.h | 5 + redhawk/src/testing/devmgr_config.cfg | 6 + .../dev_startorder/dev_startorder.prf.xml | 24 + .../dev_startorder/dev_startorder.scd.xml | 51 ++ .../dev_startorder/dev_startorder.spd.xml | 25 + .../dev_startorder/python/dev_startorder.py | 200 +++++++ .../python/dev_startorder_base.py | 519 ++++++++++++++++ .../devmgr_startorder/DeviceManager.dcd.xml | 66 ++ .../svc_startorder/python/svc_startorder.py | 565 ++++++++++++++++++ .../svc_startorder/svc_startorder.scd.xml | 47 ++ .../svc_startorder/svc_startorder.spd.xml | 22 + .../testing/tests/test_03_DeviceLifeCycle.py | 73 ++- redhawk/src/xml/dtd/deviceconfiguration.dtd | 3 +- redhawk/src/xml/xsd/dcd.xsd | 1 + 20 files changed, 1714 insertions(+), 6 deletions(-) create mode 100644 redhawk/src/testing/devmgr_config.cfg create mode 100644 redhawk/src/testing/sdr/dev/devices/dev_startorder/dev_startorder.prf.xml create mode 100644 redhawk/src/testing/sdr/dev/devices/dev_startorder/dev_startorder.scd.xml create mode 100644 redhawk/src/testing/sdr/dev/devices/dev_startorder/dev_startorder.spd.xml create mode 100755 redhawk/src/testing/sdr/dev/devices/dev_startorder/python/dev_startorder.py create mode 100644 redhawk/src/testing/sdr/dev/devices/dev_startorder/python/dev_startorder_base.py create mode 100644 redhawk/src/testing/sdr/dev/nodes/devmgr_startorder/DeviceManager.dcd.xml create mode 100755 redhawk/src/testing/sdr/dev/services/svc_startorder/python/svc_startorder.py create mode 100644 redhawk/src/testing/sdr/dev/services/svc_startorder/svc_startorder.scd.xml create mode 100644 redhawk/src/testing/sdr/dev/services/svc_startorder/svc_startorder.spd.xml diff --git a/redhawk/src/control/include/ossie/DeviceManagerConfiguration.h b/redhawk/src/control/include/ossie/DeviceManagerConfiguration.h index 72283803d..ff836f8ef 100644 --- a/redhawk/src/control/include/ossie/DeviceManagerConfiguration.h +++ b/redhawk/src/control/include/ossie/DeviceManagerConfiguration.h @@ -106,7 +106,7 @@ namespace ossie { const char* getDeviceManagerSoftPkg() const; const char* getDomainManagerName() const; - + const std::vector& getComponentFiles(); const std::vector& getComponentPlacements(); diff --git a/redhawk/src/control/parser/internal/dcd-parser.cpp b/redhawk/src/control/parser/internal/dcd-parser.cpp index 526b8b735..5b136a79a 100644 --- a/redhawk/src/control/parser/internal/dcd-parser.cpp +++ b/redhawk/src/control/parser/internal/dcd-parser.cpp @@ -113,6 +113,7 @@ ossie::internalparser::parseDCD(std::istream& input) throw (ossie::parser_error) affinity_p, loggingconfig_p, deployerrequires_p, + string_p, string_p); affinity_p.parsers (simpleref_p, diff --git a/redhawk/src/control/parser/internal/dcd-pimpl.cpp b/redhawk/src/control/parser/internal/dcd-pimpl.cpp index 32099b7c9..deba8ad25 100644 --- a/redhawk/src/control/parser/internal/dcd-pimpl.cpp +++ b/redhawk/src/control/parser/internal/dcd-pimpl.cpp @@ -383,6 +383,14 @@ const ::ossie::ComponentFile &componentfile_pimpl:: componentInstantiation = ossie::ComponentInstantiation(); } + void componentinstantiation_pimpl:: + startorder (const ::std::string& startorder) + { + // We have to parse the string into an integer here, rather than declaring + // startorder as an integer in the schema, for backwards compatibility. + componentInstantiation.startOrder = atoi(startorder.c_str()); + } + void componentinstantiation_pimpl:: usagename (const ::std::string& usagename) { diff --git a/redhawk/src/control/parser/internal/dcd-pimpl.h b/redhawk/src/control/parser/internal/dcd-pimpl.h index a75dc5559..3bcd0104a 100644 --- a/redhawk/src/control/parser/internal/dcd-pimpl.h +++ b/redhawk/src/control/parser/internal/dcd-pimpl.h @@ -265,6 +265,9 @@ namespace dcd virtual void id (const ::std::string&); + virtual void + startorder (const ::std::string&); + virtual void affinity (const ossie::ComponentInstantiation::AffinityProperties& ); diff --git a/redhawk/src/control/sdr/devmgr/DeviceManager_DeployerSupport.cpp b/redhawk/src/control/sdr/devmgr/DeviceManager_DeployerSupport.cpp index 64b937b1e..ddcc55dd7 100644 --- a/redhawk/src/control/sdr/devmgr/DeviceManager_DeployerSupport.cpp +++ b/redhawk/src/control/sdr/devmgr/DeviceManager_DeployerSupport.cpp @@ -793,7 +793,6 @@ void DeviceManager_impl::do_load ( CF::FileSystem_ptr fs, // check if directory fs::path workpath(workingFileName); - bool isDir=false; try { if (!fs::exists (workpath)) { std::ostringstream emsg; @@ -801,8 +800,6 @@ void DeviceManager_impl::do_load ( CF::FileSystem_ptr fs, LOG_ERROR(DeviceManager_impl, emsg.str()); throw std::runtime_error(emsg.str().c_str()); } - - if ( fs::is_directory(workpath) ) { isDir=true; } } catch(...){ std::ostringstream emsg; diff --git a/redhawk/src/control/sdr/devmgr/DeviceManager_impl.cpp b/redhawk/src/control/sdr/devmgr/DeviceManager_impl.cpp index 72ecd3570..d0d68cef7 100644 --- a/redhawk/src/control/sdr/devmgr/DeviceManager_impl.cpp +++ b/redhawk/src/control/sdr/devmgr/DeviceManager_impl.cpp @@ -1524,6 +1524,8 @@ throw (CORBA::SystemException, CF::InvalidObjectReference) // due to a lack of threads (which would result in blocking // the mutex lock, which would prevent shutdown from killing // this). + bool allregistered = false; + { boost::recursive_mutex::scoped_lock lock(registeredDevicesmutex); //Get properties from SPD @@ -1672,6 +1674,11 @@ throw (CORBA::SystemException, CF::InvalidObjectReference) } LOG_TRACE(DeviceManager_impl, "Done registering device " << deviceLabel); + allregistered = verifyAllRegistered(); + } + if (allregistered) { + startOrder(); + } //The registerDevice operation shall write a FAILURE_ALARM log record to a //DomainManagers Log, upon unsuccessful registration of a Device to the DeviceManagers @@ -1749,6 +1756,40 @@ void DeviceManager_impl::deleteFileSystems() _fileSys = CF::FileSystem::_nil(); } +void DeviceManager_impl::stopOrder() +{ + unsigned long timeout = 3; // seconds; + for (std::vector >::reverse_iterator item=start_order.rbegin(); item!=start_order.rend();++item) { + bool started = false; + for(DeviceList::iterator _dev=_registeredDevices.begin(); _dev!=_registeredDevices.end(); ++_dev) { + if ((*_dev)->identifier == item->first) { + try { + omniORB::setClientCallTimeout((*_dev)->device, timeout * 1000); + (*_dev)->device->stop(); + } catch ( ... ) { + } + started = true; + break; + } + } + if (started) + continue; + for(ServiceList::iterator _svc=_registeredServices.begin(); _svc!=_registeredServices.end(); ++_svc) { + if ((*_svc)->identifier == item->first) { + try { + CF::Resource_ptr res = CF::Resource::_narrow((*_svc)->service); + if (not CORBA::is_nil(res)) { + omniORB::setClientCallTimeout(res, timeout * 1000); + res->stop(); + } + } catch ( ... ) { + } + break; + } + } + } +} + void DeviceManager_impl::shutdown () throw (CORBA::SystemException) @@ -1766,6 +1807,8 @@ throw (CORBA::SystemException) _adminState = DEVMGR_SHUTTING_DOWN; + stopOrder(); + // SR:501 // The shutdown operation shall unregister the DeviceManager from the DomainManager. // Although unclear, a failure here should NOT prevent us from trying to clean up @@ -1833,6 +1876,8 @@ DeviceManager_impl::registerService (CORBA::Object_ptr registeringService, const char* name) throw (CORBA::SystemException, CF::InvalidObjectReference) { + bool allregistered = false; + { boost::recursive_mutex::scoped_lock lock(registeredDevicesmutex); LOG_INFO(DeviceManager_impl, "Registering service " << name) @@ -1886,6 +1931,11 @@ throw (CORBA::SystemException, CF::InvalidObjectReference) throw; } } + allregistered = verifyAllRegistered(); + } + if (allregistered) { + startOrder(); + } //The registerService operation shall write a FAILURE_ALARM log record, upon unsuccessful //registration of a Service to the DeviceManagers registeredServices. @@ -2236,6 +2286,52 @@ void DeviceManager_impl::local_unregisterDevice(CF::Device_ptr device, const std } +bool DeviceManager_impl::verifyAllRegistered() { + if (_pendingDevices.empty() and _pendingServices.empty()) + return true; + return false; +} + +void DeviceManager_impl::startOrder() +{ + const std::vector& componentPlacements = node_dcd.getComponentPlacements(); + for(std::vector::const_iterator cP = componentPlacements.begin(); cP!=componentPlacements.end(); cP++) { + if (cP->getInstantiations()[0].startOrder.isSet()) { + int cP_order = *(cP->getInstantiations()[0].startOrder.get()); + std::string cP_id(cP->getInstantiations()[0].getID()); + std::vector >::iterator _o=start_order.begin(); + for ( ; _o!=start_order.end(); _o++) { + if (_o->second >= cP_order) { + start_order.insert(_o, std::make_pair(cP_id, cP_order)); + break; + } + } + if (_o == start_order.end()) + start_order.push_back(std::make_pair(cP_id, cP_order)); + } + } + for (std::vector >::iterator item=start_order.begin(); item!=start_order.end();item++) { + bool started = false; + for(DeviceList::iterator _dev=_registeredDevices.begin(); _dev!=_registeredDevices.end(); _dev++) { + if ((*_dev)->identifier == item->first) { + (*_dev)->device->start(); + started = true; + break; + } + } + if (started) + continue; + for(ServiceList::iterator _svc=_registeredServices.begin(); _svc!=_registeredServices.end(); _svc++) { + if ((*_svc)->identifier == item->first) { + CF::Resource_ptr res = CF::Resource::_narrow((*_svc)->service); + if (not CORBA::is_nil(res)) + res->start(); + break; + } + } + } +} + /* * increment the registered services sequences along with the id and table tables */ diff --git a/redhawk/src/control/sdr/devmgr/DeviceManager_impl.h b/redhawk/src/control/sdr/devmgr/DeviceManager_impl.h index 991d8213a..8b1e22035 100644 --- a/redhawk/src/control/sdr/devmgr/DeviceManager_impl.h +++ b/redhawk/src/control/sdr/devmgr/DeviceManager_impl.h @@ -341,6 +341,11 @@ class DeviceManager_impl: void clean_registeredDevices(); void clean_registeredServices(); void clean_externalServices(); + bool verifyAllRegistered(); + + std::vector > start_order; + void startOrder(); + void stopOrder(); void local_unregisterService(CORBA::Object_ptr service, const std::string& name); void local_unregisterDevice(CF::Device_ptr device, const std::string& name); diff --git a/redhawk/src/testing/devmgr_config.cfg b/redhawk/src/testing/devmgr_config.cfg new file mode 100644 index 000000000..b2dc5171f --- /dev/null +++ b/redhawk/src/testing/devmgr_config.cfg @@ -0,0 +1,6 @@ +log4j.rootLogger=TRACE,FILE +# Direct log messages to FILE +log4j.appender.FILE=org.apache.log4j.FileAppender +log4j.appender.FILE.File=../foo/bar/test.log +log4j.appender.FILE.layout=org.apache.log4j.PatternLayout +log4j.appender.FILE.layout.ConversionPattern=%d{ISO8601}: %p:%c - %m [%F:%L]%n diff --git a/redhawk/src/testing/sdr/dev/devices/dev_startorder/dev_startorder.prf.xml b/redhawk/src/testing/sdr/dev/devices/dev_startorder/dev_startorder.prf.xml new file mode 100644 index 000000000..12d9530e7 --- /dev/null +++ b/redhawk/src/testing/sdr/dev/devices/dev_startorder/dev_startorder.prf.xml @@ -0,0 +1,24 @@ + + + + + This specifies the device kind + + + + + This specifies the specific device + + + + + + + + + + + + + + diff --git a/redhawk/src/testing/sdr/dev/devices/dev_startorder/dev_startorder.scd.xml b/redhawk/src/testing/sdr/dev/devices/dev_startorder/dev_startorder.scd.xml new file mode 100644 index 000000000..af10e8551 --- /dev/null +++ b/redhawk/src/testing/sdr/dev/devices/dev_startorder/dev_startorder.scd.xml @@ -0,0 +1,51 @@ + + + + 2.2 + + device + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/redhawk/src/testing/sdr/dev/devices/dev_startorder/dev_startorder.spd.xml b/redhawk/src/testing/sdr/dev/devices/dev_startorder/dev_startorder.spd.xml new file mode 100644 index 000000000..c38c59fe7 --- /dev/null +++ b/redhawk/src/testing/sdr/dev/devices/dev_startorder/dev_startorder.spd.xml @@ -0,0 +1,25 @@ + + + + + + null + + + + + + + + + The implementation contains descriptive information about the template for a software resource. + + + python/dev_startorder.py + + + + + + + diff --git a/redhawk/src/testing/sdr/dev/devices/dev_startorder/python/dev_startorder.py b/redhawk/src/testing/sdr/dev/devices/dev_startorder/python/dev_startorder.py new file mode 100755 index 000000000..0ec51e037 --- /dev/null +++ b/redhawk/src/testing/sdr/dev/devices/dev_startorder/python/dev_startorder.py @@ -0,0 +1,200 @@ +#!/usr/bin/env python +# +# +# AUTO-GENERATED +# +# Source: dev_startorder.spd.xml +from ossie.device import start_device +from omniORB import any +import logging +from ossie.cf import CF + +from dev_startorder_base import * + +class dev_startorder_i(dev_startorder_base): + """""" + def constructor(self): + """ + This is called by the framework immediately after your device registers with the system. + + In general, you should add customization here and not in the __init__ constructor. If you have + a custom port implementation you can override the specific implementation here with a statement + similar to the following: + self.some_port = MyPortImplementation() + + """ + # TODO add customization here. + self.stopped = False + + def start(self): + self._log.info("starting "+self._id) + if self._id == 'devmgr_startorder:dev_startorder_2': + svc = self.getDeviceManager().ref.registeredServices[0] + if len(self.port_output._get_connections())==0: + self.port_output.connectPort(svc.serviceObject, 'service_connection') + val = CF.DataType(id='start_from', value=any.to_any(self.start_from+","+self._id)) + self.port_output.configure([val]) + + def stop(self): + if not self.stopped: + self._log.info("stopping "+self._id) + self.stopped = True + + def updateUsageState(self): + """ + This is called automatically after allocateCapacity or deallocateCapacity are called. + Your implementation should determine the current state of the device: + self._usageState = CF.Device.IDLE # not in use + self._usageState = CF.Device.ACTIVE # in use, with capacity remaining for allocation + self._usageState = CF.Device.BUSY # in use, with no capacity remaining for allocation + """ + return NOOP + + def process(self): + """ + Basic functionality: + + The process method should process a single "chunk" of data and then return. This method + will be called from the processing thread again, and again, and again until it returns + FINISH or stop() is called on the device. If no work is performed, then return NOOP. + + StreamSRI: + To create a StreamSRI object, use the following code (this generates a normalized SRI that does not flush the queue when full): + sri = bulkio.sri.create("my_stream_id") + + PrecisionUTCTime: + To create a PrecisionUTCTime object, use the following code: + tstamp = bulkio.timestamp.now() + + Ports: + + Each port instance is accessed through members of the following form: self.port_ + + Data is obtained in the process function through the getPacket call (BULKIO only) on a + provides port member instance. The optional argument is a timeout value, in seconds. + A zero value is non-blocking, while a negative value is blocking. Constants have been + defined for these values, bulkio.const.BLOCKING and bulkio.const.NON_BLOCKING. If no + timeout is given, it defaults to non-blocking. + + The return value is a named tuple with the following fields: + - dataBuffer + - T + - EOS + - streamID + - SRI + - sriChanged + - inputQueueFlushed + If no data is available due to a timeout, all fields are None. + + To send data, call the appropriate function in the port directly. In the case of BULKIO, + convenience functions have been added in the port classes that aid in output. + + Interactions with non-BULKIO ports are left up to the device developer's discretion. + + Messages: + + To receive a message, you need (1) an input port of type MessageEvent, (2) a message prototype described + as a structure property of kind message, (3) a callback to service the message, and (4) to register the callback + with the input port. + + Assuming a property of type message is declared called "my_msg", an input port called "msg_input" is declared of + type MessageEvent, create the following code: + + def msg_callback(self, msg_id, msg_value): + print msg_id, msg_value + + Register the message callback onto the input port with the following form: + self.port_input.registerMessage("my_msg", dev_startorder_i.MyMsg, self.msg_callback) + + To send a message, you need to (1) create a message structure, and (2) send the message over the port. + + Assuming a property of type message is declared called "my_msg", an output port called "msg_output" is declared of + type MessageEvent, create the following code: + + msg_out = dev_startorder_i.MyMsg() + this.port_msg_output.sendMessage(msg_out) + + Accessing the Application and Domain Manager: + + Both the Application hosting this Component and the Domain Manager hosting + the Application are available to the Component. + + To access the Domain Manager: + dommgr = self.getDomainManager().getRef(); + To access the Application: + app = self.getApplication().getRef(); + Properties: + + Properties are accessed directly as member variables. If the property name is baudRate, + then accessing it (for reading or writing) is achieved in the following way: self.baudRate. + + To implement a change callback notification for a property, create a callback function with the following form: + + def mycallback(self, id, old_value, new_value): + pass + + where id is the property id, old_value is the previous value, and new_value is the updated value. + + The callback is then registered on the component as: + self.addPropertyChangeListener('baudRate', self.mycallback) + + Allocation: + + Allocation callbacks are available to customize a Device's response to an allocation request. + Callback allocation/deallocation functions are registered using the setAllocationImpl function, + usually in the initialize() function + For example, allocation property "my_alloc" can be registered with allocation function + my_alloc_fn and deallocation function my_dealloc_fn as follows: + + self.setAllocationImpl("my_alloc", self.my_alloc_fn, self.my_dealloc_fn) + + def my_alloc_fn(self, value): + # perform logic + return True # successful allocation + + def my_dealloc_fn(self, value): + # perform logic + pass + + Example: + + # This example assumes that the device has two ports: + # - A provides (input) port of type bulkio.InShortPort called dataShort_in + # - A uses (output) port of type bulkio.OutFloatPort called dataFloat_out + # The mapping between the port and the class if found in the device + # base class. + # This example also makes use of the following Properties: + # - A float value called amplitude + # - A boolean called increaseAmplitude + + packet = self.port_dataShort_in.getPacket() + + if packet.dataBuffer is None: + return NOOP + + outData = range(len(packet.dataBuffer)) + for i in range(len(packet.dataBuffer)): + if self.increaseAmplitude: + outData[i] = float(packet.dataBuffer[i]) * self.amplitude + else: + outData[i] = float(packet.dataBuffer[i]) + + # NOTE: You must make at least one valid pushSRI call + if packet.sriChanged: + self.port_dataFloat_out.pushSRI(packet.SRI); + + self.port_dataFloat_out.pushPacket(outData, packet.T, packet.EOS, packet.streamID) + return NORMAL + + """ + + # TODO fill in your code here + self._log.debug("process() example log message") + return NOOP + + +if __name__ == '__main__': + logging.getLogger().setLevel(logging.INFO) + logging.debug("Starting Device") + start_device(dev_startorder_i) + diff --git a/redhawk/src/testing/sdr/dev/devices/dev_startorder/python/dev_startorder_base.py b/redhawk/src/testing/sdr/dev/devices/dev_startorder/python/dev_startorder_base.py new file mode 100644 index 000000000..19809b92f --- /dev/null +++ b/redhawk/src/testing/sdr/dev/devices/dev_startorder/python/dev_startorder_base.py @@ -0,0 +1,519 @@ +#!/usr/bin/env python +# +# AUTO-GENERATED CODE. DO NOT MODIFY! +# +# Source: dev_startorder.spd.xml +from ossie.cf import CF +from ossie.cf import CF__POA +from ossie.utils import uuid + +from ossie.device import Device +from ossie.threadedcomponent import * +from ossie.properties import simple_property + +import Queue, copy, time, threading +from ossie.resource import usesport, providesport +from ossie.cf import ExtendedCF +from ossie.cf import ExtendedCF__POA + +class dev_startorder_base(CF__POA.Device, Device, ThreadedComponent): + # These values can be altered in the __init__ of your derived class + + PAUSE = 0.0125 # The amount of time to sleep if process return NOOP + TIMEOUT = 5.0 # The amount of time to wait for the process thread to die when stop() is called + DEFAULT_QUEUE_SIZE = 100 # The number of BulkIO packets that can be in the queue before pushPacket will block + + def __init__(self, devmgr, uuid, label, softwareProfile, compositeDevice, execparams): + Device.__init__(self, devmgr, uuid, label, softwareProfile, compositeDevice, execparams) + ThreadedComponent.__init__(self) + + # self.auto_start is deprecated and is only kept for API compatibility + # with 1.7.X and 1.8.0 devices. This variable may be removed + # in future releases + self.auto_start = False + # Instantiate the default implementations for all ports on this device + self.port_output = PortCFResourceOut_i(self, "output") + + def start(self): + Device.start(self) + ThreadedComponent.startThread(self, pause=self.PAUSE) + + def stop(self): + Device.stop(self) + if not ThreadedComponent.stopThread(self, self.TIMEOUT): + raise CF.Resource.StopError(CF.CF_NOTSET, "Processing thread did not die") + + def releaseObject(self): + try: + self.stop() + except Exception: + self._log.exception("Error stopping") + Device.releaseObject(self) + + ###################################################################### + # PORTS + # + # DO NOT ADD NEW PORTS HERE. You can add ports in your derived class, in the SCD xml file, + # or via the IDE. + + # 'CF/Resource' port + class PortCFResourceOut(ExtendedCF__POA.QueryablePort): + """This class is a port template for the PortCFResourceOut_i port and + should not be instantiated nor modified. + + The expectation is that the specific port implementation will extend + from this class instead of the base CORBA class ExtendedCF__POA.QueryablePort. + """ + pass + + port_output = usesport(name="output", + repid="IDL:CF/Resource:1.0", + type_="control") + + ###################################################################### + # PROPERTIES + # + # DO NOT ADD NEW PROPERTIES HERE. You can add properties in your derived class, in the PRF xml file + # or by using the IDE. + device_kind = simple_property(id_="DCE:cdc5ee18-7ceb-4ae6-bf4c-31f983179b4d", + name="device_kind", + type_="string", + mode="readonly", + action="eq", + kinds=("allocation",), + description="""This specifies the device kind""") + + + device_model = simple_property(id_="DCE:0f99b2e4-9903-4631-9846-ff349d18ecfb", + name="device_model", + type_="string", + mode="readonly", + action="eq", + kinds=("allocation",), + description=""" This specifies the specific device""") + + + start_from = simple_property(id_="start_from", + type_="string", + defvalue="", + mode="readwrite", + action="external", + kinds=("property",)) + + + stop_from = simple_property(id_="stop_from", + type_="string", + defvalue="", + mode="readwrite", + action="external", + kinds=("property",)) + + + +'''uses port(s)''' + +class PortCFResourceOut_i(dev_startorder_base.PortCFResourceOut): + def __init__(self, parent, name): + self.parent = parent + self.name = name + self.outConnections = {} + self.port_lock = threading.Lock() + + def connectPort(self, connection, connectionId): + self.port_lock.acquire() + try: + port = connection._narrow(CF.Resource) + self.outConnections[str(connectionId)] = port + finally: + self.port_lock.release() + + def disconnectPort(self, connectionId): + self.port_lock.acquire() + try: + self.outConnections.pop(str(connectionId), None) + finally: + self.port_lock.release() + + def _get_connections(self): + self.port_lock.acquire() + try: + return [ExtendedCF.UsesConnection(name, port) for name, port in self.outConnections.iteritems()] + finally: + self.port_lock.release() + + def initialize(self): + self.port_lock.acquire() + + try: + for connId, port in self.outConnections.items(): + if port != None: + try: + port.initialize() + except Exception: + self.parent._log.exception("The call to initialize failed on port %s connection %s instance %s", self.name, connId, port) + raise + finally: + self.port_lock.release() + + def releaseObject(self): + self.port_lock.acquire() + + try: + for connId, port in self.outConnections.items(): + if port != None: + try: + port.releaseObject() + except Exception: + self.parent._log.exception("The call to releaseObject failed on port %s connection %s instance %s", self.name, connId, port) + raise + finally: + self.port_lock.release() + + def runTest(self, testid, testValues): + retVal = None + self.port_lock.acquire() + + try: + for connId, port in self.outConnections.items(): + if port != None: + try: + retVal = port.runTest(testid, testValues) + except Exception: + self.parent._log.exception("The call to runTest failed on port %s connection %s instance %s", self.name, connId, port) + raise + finally: + self.port_lock.release() + + return retVal + + def configure(self, configProperties): + self.port_lock.acquire() + + try: + for connId, port in self.outConnections.items(): + if port != None: + try: + port.configure(configProperties) + except Exception: + self.parent._log.exception("The call to configure failed on port %s connection %s instance %s", self.name, connId, port) + raise + finally: + self.port_lock.release() + + def query(self, configProperties): + retVal = None + self.port_lock.acquire() + + try: + for connId, port in self.outConnections.items(): + if port != None: + try: + retVal = port.query(configProperties) + except Exception: + self.parent._log.exception("The call to query failed on port %s connection %s instance %s", self.name, connId, port) + raise + finally: + self.port_lock.release() + + return retVal + + def initializeProperties(self, initialProperties): + self.port_lock.acquire() + + try: + for connId, port in self.outConnections.items(): + if port != None: + try: + port.initializeProperties(initialProperties) + except Exception: + self.parent._log.exception("The call to initializeProperties failed on port %s connection %s instance %s", self.name, connId, port) + raise + finally: + self.port_lock.release() + + def registerPropertyListener(self, obj, prop_ids, interval): + retVal = "" + self.port_lock.acquire() + + try: + for connId, port in self.outConnections.items(): + if port != None: + try: + retVal = port.registerPropertyListener(obj, prop_ids, interval) + except Exception: + self.parent._log.exception("The call to registerPropertyListener failed on port %s connection %s instance %s", self.name, connId, port) + raise + finally: + self.port_lock.release() + + return retVal + + def unregisterPropertyListener(self, id): + self.port_lock.acquire() + + try: + for connId, port in self.outConnections.items(): + if port != None: + try: + port.unregisterPropertyListener(id) + except Exception: + self.parent._log.exception("The call to unregisterPropertyListener failed on port %s connection %s instance %s", self.name, connId, port) + raise + finally: + self.port_lock.release() + + def getPort(self, name): + retVal = None + self.port_lock.acquire() + + try: + for connId, port in self.outConnections.items(): + if port != None: + try: + retVal = port.getPort(name) + except Exception: + self.parent._log.exception("The call to getPort failed on port %s connection %s instance %s", self.name, connId, port) + raise + finally: + self.port_lock.release() + + return retVal + + def getPortSet(self): + retVal = None + self.port_lock.acquire() + + try: + for connId, port in self.outConnections.items(): + if port != None: + try: + retVal = port.getPortSet() + except Exception: + self.parent._log.exception("The call to getPortSet failed on port %s connection %s instance %s", self.name, connId, port) + raise + finally: + self.port_lock.release() + + return retVal + + def retrieve_records(self, howMany, startingRecord): + retVal = [] + self.port_lock.acquire() + + try: + for connId, port in self.outConnections.items(): + if port != None: + try: + retVal = port.retrieve_records(howMany, startingRecord) + except Exception: + self.parent._log.exception("The call to retrieve_records failed on port %s connection %s instance %s", self.name, connId, port) + raise + finally: + self.port_lock.release() + + return retVal + + def retrieve_records_by_date(self, howMany, to_timeStamp): + retVal = [] + self.port_lock.acquire() + + try: + for connId, port in self.outConnections.items(): + if port != None: + try: + retVal = port.retrieve_records_by_date(howMany, to_timeStamp) + except Exception: + self.parent._log.exception("The call to retrieve_records_by_date failed on port %s connection %s instance %s", self.name, connId, port) + raise + finally: + self.port_lock.release() + + return retVal + + def retrieve_records_from_date(self, howMany, from_timeStamp): + retVal = [] + self.port_lock.acquire() + + try: + for connId, port in self.outConnections.items(): + if port != None: + try: + retVal = port.retrieve_records_from_date(howMany, from_timeStamp) + except Exception: + self.parent._log.exception("The call to retrieve_records_from_date failed on port %s connection %s instance %s", self.name, connId, port) + raise + finally: + self.port_lock.release() + + return retVal + + def setLogLevel(self, logger_id, newLevel): + self.port_lock.acquire() + + try: + for connId, port in self.outConnections.items(): + if port != None: + try: + port.setLogLevel(logger_id, newLevel) + except Exception: + self.parent._log.exception("The call to setLogLevel failed on port %s connection %s instance %s", self.name, connId, port) + raise + finally: + self.port_lock.release() + + def getLogConfig(self): + retVal = "" + self.port_lock.acquire() + + try: + for connId, port in self.outConnections.items(): + if port != None: + try: + retVal = port.getLogConfig() + except Exception: + self.parent._log.exception("The call to getLogConfig failed on port %s connection %s instance %s", self.name, connId, port) + raise + finally: + self.port_lock.release() + + return retVal + + def setLogConfig(self, config_contents): + self.port_lock.acquire() + + try: + for connId, port in self.outConnections.items(): + if port != None: + try: + port.setLogConfig(config_contents) + except Exception: + self.parent._log.exception("The call to setLogConfig failed on port %s connection %s instance %s", self.name, connId, port) + raise + finally: + self.port_lock.release() + + def setLogConfigURL(self, config_url): + self.port_lock.acquire() + + try: + for connId, port in self.outConnections.items(): + if port != None: + try: + port.setLogConfigURL(config_url) + except Exception: + self.parent._log.exception("The call to setLogConfigURL failed on port %s connection %s instance %s", self.name, connId, port) + raise + finally: + self.port_lock.release() + + def start(self): + self.port_lock.acquire() + + try: + for connId, port in self.outConnections.items(): + if port != None: + try: + port.start() + except Exception: + self.parent._log.exception("The call to start failed on port %s connection %s instance %s", self.name, connId, port) + raise + finally: + self.port_lock.release() + + def stop(self): + self.port_lock.acquire() + + try: + for connId, port in self.outConnections.items(): + if port != None: + try: + port.stop() + except Exception: + self.parent._log.exception("The call to stop failed on port %s connection %s instance %s", self.name, connId, port) + raise + finally: + self.port_lock.release() + + def _get_log_level(self): + retVal = None + self.port_lock.acquire() + + try: + for connId, port in self.outConnections.items(): + if port != None: + try: + retVal = port._get_log_level() + except Exception: + self.parent._log.exception("The call to _get_log_level failed on port %s connection %s instance %s", self.name, connId, port) + raise + finally: + self.port_lock.release() + + return retVal + + def _set_log_level(self, data): + self.port_lock.acquire() + + try: + for connId, port in self.outConnections.items(): + if port != None: + try: + port._set_log_level(data) + except Exception: + self.parent._log.exception("The call to _set_log_level failed on port %s connection %s instance %s", self.name, connId, port) + raise + finally: + self.port_lock.release() + + def _get_identifier(self): + retVal = "" + self.port_lock.acquire() + + try: + for connId, port in self.outConnections.items(): + if port != None: + try: + retVal = port._get_identifier() + except Exception: + self.parent._log.exception("The call to _get_identifier failed on port %s connection %s instance %s", self.name, connId, port) + raise + finally: + self.port_lock.release() + + return retVal + + def _get_started(self): + retVal = None + self.port_lock.acquire() + + try: + for connId, port in self.outConnections.items(): + if port != None: + try: + retVal = port._get_started() + except Exception: + self.parent._log.exception("The call to _get_started failed on port %s connection %s instance %s", self.name, connId, port) + raise + finally: + self.port_lock.release() + + return retVal + + def _get_softwareProfile(self): + retVal = "" + self.port_lock.acquire() + + try: + for connId, port in self.outConnections.items(): + if port != None: + try: + retVal = port._get_softwareProfile() + except Exception: + self.parent._log.exception("The call to _get_softwareProfile failed on port %s connection %s instance %s", self.name, connId, port) + raise + finally: + self.port_lock.release() + + return retVal + + diff --git a/redhawk/src/testing/sdr/dev/nodes/devmgr_startorder/DeviceManager.dcd.xml b/redhawk/src/testing/sdr/dev/nodes/devmgr_startorder/DeviceManager.dcd.xml new file mode 100644 index 000000000..25ae2cbdd --- /dev/null +++ b/redhawk/src/testing/sdr/dev/nodes/devmgr_startorder/DeviceManager.dcd.xml @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + dev_startorder_1 + + + + + + dev_startorder_2 + + + + + + svc_startorder_1 + + + + + + dev_startorder_3 + + + + + + + output + + + + IDL:CF/Resource:1.0 + + + + + + output + + + + IDL:CF/Resource:1.0 + + + + + + + + diff --git a/redhawk/src/testing/sdr/dev/services/svc_startorder/python/svc_startorder.py b/redhawk/src/testing/sdr/dev/services/svc_startorder/python/svc_startorder.py new file mode 100755 index 000000000..64ebc8c0c --- /dev/null +++ b/redhawk/src/testing/sdr/dev/services/svc_startorder/python/svc_startorder.py @@ -0,0 +1,565 @@ +#!/usr/bin/env python +# +# AUTO-GENERATED +# +# Source: svc_startorder.spd.xml + +import sys, signal, copy, os +import logging + +from ossie.cf import CF, CF__POA #@UnusedImport +from ossie.service import start_service +from omniORB import CORBA, URI, PortableServer, any +import Queue, copy, time, threading +from ossie.properties import simple_property + +from ossie.cf import CF +from ossie.cf import CF__POA +from ossie.cf import ExtendedCF +from ossie.cf import ExtendedCF__POA +from ossie.resource import usesport, providesport + +class svc_startorder(CF__POA.Resource): + + class PortCFResourceOut(ExtendedCF__POA.QueryablePort): + """This class is a port template for the PortCFResourceOut_i port and + should not be instantiated nor modified. + + The expectation is that the specific port implementation will extend + from this class instead of the base CORBA class ExtendedCF__POA.QueryablePort. + """ + pass + + port_output = usesport(name="output", + repid="IDL:CF/Resource:1.0", + type_="control") + + def __init__(self, name="svc_startorder", execparams={}): + self.name = name + self._log = logging.getLogger(self.name) + self.port_output = PortCFResourceOut_i(self, "output") + self._start_from = "" + self._stop_from = "" + + def terminateService(self): + pass + + def initialize(self): + # TODO + pass + + def releaseObject(self): + # TODO + pass + + def runTest(self, testid, testValues): + # TODO + pass + + def configure(self, configProperties): + for _prop in configProperties: + if _prop.id == 'start_from': + self._start_from = _prop.value._v + if _prop.id == 'stop_from': + self._stop_from = _prop.value._v + + def query(self, configProperties): + retval = [] + if len(configProperties) == 0: + retval.append(CF.DataType(id='start_from',value=any.to_any(self._start_from))) + retval.append(CF.DataType(id='stop_from',value=any.to_any(self._stop_from))) + elif len(configProperties) == 1: + if configProperties[0].id == 'start_from': + retval.append(CF.DataType(id='start_from',value=any.to_any(self._start_from))) + if configProperties[0].id == 'stop_from': + retval.append(CF.DataType(id='stop_from',value=any.to_any(self._stop_from))) + return retval + + def initializeProperties(self, initialProperties): + # TODO + pass + + def registerPropertyListener(self, obj, prop_ids, interval): + # TODO + pass + + def unregisterPropertyListener(self, id): + # TODO + pass + + def getPort(self, name): + if name == 'output': + return self.port_output._this() + + def getPortSet(self): + # TODO + pass + + def retrieve_records(self, howMany, startingRecord): + # TODO + pass + + def retrieve_records_by_date(self, howMany, to_timeStamp): + # TODO + pass + + def retrieve_records_from_date(self, howMany, from_timeStamp): + # TODO + pass + + def setLogLevel(self, logger_id, newLevel): + # TODO + pass + + def getLogConfig(self): + # TODO + pass + + def setLogConfig(self, config_contents): + # TODO + pass + + def setLogConfigURL(self, config_url): + # TODO + pass + + def start(self): + self._log.info("starting "+self.name) + devs = self.getDeviceManager().ref.registeredDevices + for dev in devs: + if dev._get_label() == 'dev_startorder_1': + if len(self.port_output._get_connections())==0: + self.port_output.connectPort(dev, 'service_connection') + val = CF.DataType(id='start_from', value=any.to_any(self._start_from+','+self.name)) + self.port_output.configure([val]) + + def stop(self): + self._log.info("stopping "+self.name) + + def _get_log_level(self): + # TODO + pass + + def _set_log_level(self, data): + # TODO + pass + + def _get_identifier(self): + # TODO + pass + + def _get_started(self): + # TODO + pass + + def _get_softwareProfile(self): + # TODO + pass + +class PortCFResourceOut_i(svc_startorder.PortCFResourceOut): + def __init__(self, parent, name): + self.parent = parent + self.name = name + self.outConnections = {} + self.port_lock = threading.Lock() + + def connectPort(self, connection, connectionId): + self.port_lock.acquire() + try: + port = connection._narrow(CF.Resource) + self.outConnections[str(connectionId)] = port + finally: + self.port_lock.release() + + def disconnectPort(self, connectionId): + self.port_lock.acquire() + try: + self.outConnections.pop(str(connectionId), None) + finally: + self.port_lock.release() + + def _get_connections(self): + self.port_lock.acquire() + try: + return [ExtendedCF.UsesConnection(name, port) for name, port in self.outConnections.iteritems()] + finally: + self.port_lock.release() + + def initialize(self): + self.port_lock.acquire() + + try: + for connId, port in self.outConnections.items(): + if port != None: + try: + port.initialize() + except Exception: + self.parent._log.exception("The call to initialize failed on port %s connection %s instance %s", self.name, connId, port) + raise + finally: + self.port_lock.release() + + def releaseObject(self): + self.port_lock.acquire() + + try: + for connId, port in self.outConnections.items(): + if port != None: + try: + port.releaseObject() + except Exception: + self.parent._log.exception("The call to releaseObject failed on port %s connection %s instance %s", self.name, connId, port) + raise + finally: + self.port_lock.release() + + def runTest(self, testid, testValues): + retVal = None + self.port_lock.acquire() + + try: + for connId, port in self.outConnections.items(): + if port != None: + try: + retVal = port.runTest(testid, testValues) + except Exception: + self.parent._log.exception("The call to runTest failed on port %s connection %s instance %s", self.name, connId, port) + raise + finally: + self.port_lock.release() + + return retVal + + def configure(self, configProperties): + self.port_lock.acquire() + + try: + for connId, port in self.outConnections.items(): + if port != None: + try: + port.configure(configProperties) + except Exception: + self.parent._log.exception("The call to configure failed on port %s connection %s instance %s", self.name, connId, port) + raise + finally: + self.port_lock.release() + + def query(self, configProperties): + retVal = None + self.port_lock.acquire() + + try: + for connId, port in self.outConnections.items(): + if port != None: + try: + retVal = port.query(configProperties) + except Exception: + self.parent._log.exception("The call to query failed on port %s connection %s instance %s", self.name, connId, port) + raise + finally: + self.port_lock.release() + + return retVal + + def initializeProperties(self, initialProperties): + self.port_lock.acquire() + + try: + for connId, port in self.outConnections.items(): + if port != None: + try: + port.initializeProperties(initialProperties) + except Exception: + self.parent._log.exception("The call to initializeProperties failed on port %s connection %s instance %s", self.name, connId, port) + raise + finally: + self.port_lock.release() + + def registerPropertyListener(self, obj, prop_ids, interval): + retVal = "" + self.port_lock.acquire() + + try: + for connId, port in self.outConnections.items(): + if port != None: + try: + retVal = port.registerPropertyListener(obj, prop_ids, interval) + except Exception: + self.parent._log.exception("The call to registerPropertyListener failed on port %s connection %s instance %s", self.name, connId, port) + raise + finally: + self.port_lock.release() + + return retVal + + def unregisterPropertyListener(self, id): + self.port_lock.acquire() + + try: + for connId, port in self.outConnections.items(): + if port != None: + try: + port.unregisterPropertyListener(id) + except Exception: + self.parent._log.exception("The call to unregisterPropertyListener failed on port %s connection %s instance %s", self.name, connId, port) + raise + finally: + self.port_lock.release() + + def getPort(self, name): + retVal = None + self.port_lock.acquire() + + try: + for connId, port in self.outConnections.items(): + if port != None: + try: + retVal = port.getPort(name) + except Exception: + self.parent._log.exception("The call to getPort failed on port %s connection %s instance %s", self.name, connId, port) + raise + finally: + self.port_lock.release() + + return retVal + + def getPortSet(self): + retVal = None + self.port_lock.acquire() + + try: + for connId, port in self.outConnections.items(): + if port != None: + try: + retVal = port.getPortSet() + except Exception: + self.parent._log.exception("The call to getPortSet failed on port %s connection %s instance %s", self.name, connId, port) + raise + finally: + self.port_lock.release() + + return retVal + + def retrieve_records(self, howMany, startingRecord): + retVal = [] + self.port_lock.acquire() + + try: + for connId, port in self.outConnections.items(): + if port != None: + try: + retVal = port.retrieve_records(howMany, startingRecord) + except Exception: + self.parent._log.exception("The call to retrieve_records failed on port %s connection %s instance %s", self.name, connId, port) + raise + finally: + self.port_lock.release() + + return retVal + + def retrieve_records_by_date(self, howMany, to_timeStamp): + retVal = [] + self.port_lock.acquire() + + try: + for connId, port in self.outConnections.items(): + if port != None: + try: + retVal = port.retrieve_records_by_date(howMany, to_timeStamp) + except Exception: + self.parent._log.exception("The call to retrieve_records_by_date failed on port %s connection %s instance %s", self.name, connId, port) + raise + finally: + self.port_lock.release() + + return retVal + + def retrieve_records_from_date(self, howMany, from_timeStamp): + retVal = [] + self.port_lock.acquire() + + try: + for connId, port in self.outConnections.items(): + if port != None: + try: + retVal = port.retrieve_records_from_date(howMany, from_timeStamp) + except Exception: + self.parent._log.exception("The call to retrieve_records_from_date failed on port %s connection %s instance %s", self.name, connId, port) + raise + finally: + self.port_lock.release() + + return retVal + + def setLogLevel(self, logger_id, newLevel): + self.port_lock.acquire() + + try: + for connId, port in self.outConnections.items(): + if port != None: + try: + port.setLogLevel(logger_id, newLevel) + except Exception: + self.parent._log.exception("The call to setLogLevel failed on port %s connection %s instance %s", self.name, connId, port) + raise + finally: + self.port_lock.release() + + def getLogConfig(self): + retVal = "" + self.port_lock.acquire() + + try: + for connId, port in self.outConnections.items(): + if port != None: + try: + retVal = port.getLogConfig() + except Exception: + self.parent._log.exception("The call to getLogConfig failed on port %s connection %s instance %s", self.name, connId, port) + raise + finally: + self.port_lock.release() + + return retVal + + def setLogConfig(self, config_contents): + self.port_lock.acquire() + + try: + for connId, port in self.outConnections.items(): + if port != None: + try: + port.setLogConfig(config_contents) + except Exception: + self.parent._log.exception("The call to setLogConfig failed on port %s connection %s instance %s", self.name, connId, port) + raise + finally: + self.port_lock.release() + + def setLogConfigURL(self, config_url): + self.port_lock.acquire() + + try: + for connId, port in self.outConnections.items(): + if port != None: + try: + port.setLogConfigURL(config_url) + except Exception: + self.parent._log.exception("The call to setLogConfigURL failed on port %s connection %s instance %s", self.name, connId, port) + raise + finally: + self.port_lock.release() + + def start(self): + self.port_lock.acquire() + + try: + for connId, port in self.outConnections.items(): + if port != None: + try: + port.start() + except Exception: + self.parent._log.exception("The call to start failed on port %s connection %s instance %s", self.name, connId, port) + raise + finally: + self.port_lock.release() + + def stop(self): + self.port_lock.acquire() + + try: + for connId, port in self.outConnections.items(): + if port != None: + try: + port.stop() + except Exception: + self.parent._log.exception("The call to stop failed on port %s connection %s instance %s", self.name, connId, port) + raise + finally: + self.port_lock.release() + + def _get_log_level(self): + retVal = None + self.port_lock.acquire() + + try: + for connId, port in self.outConnections.items(): + if port != None: + try: + retVal = port._get_log_level() + except Exception: + self.parent._log.exception("The call to _get_log_level failed on port %s connection %s instance %s", self.name, connId, port) + raise + finally: + self.port_lock.release() + + return retVal + + def _set_log_level(self, data): + self.port_lock.acquire() + + try: + for connId, port in self.outConnections.items(): + if port != None: + try: + port._set_log_level(data) + except Exception: + self.parent._log.exception("The call to _set_log_level failed on port %s connection %s instance %s", self.name, connId, port) + raise + finally: + self.port_lock.release() + + def _get_identifier(self): + retVal = "" + self.port_lock.acquire() + + try: + for connId, port in self.outConnections.items(): + if port != None: + try: + retVal = port._get_identifier() + except Exception: + self.parent._log.exception("The call to _get_identifier failed on port %s connection %s instance %s", self.name, connId, port) + raise + finally: + self.port_lock.release() + + return retVal + + def _get_started(self): + retVal = None + self.port_lock.acquire() + + try: + for connId, port in self.outConnections.items(): + if port != None: + try: + retVal = port._get_started() + except Exception: + self.parent._log.exception("The call to _get_started failed on port %s connection %s instance %s", self.name, connId, port) + raise + finally: + self.port_lock.release() + + return retVal + + def _get_softwareProfile(self): + retVal = "" + self.port_lock.acquire() + + try: + for connId, port in self.outConnections.items(): + if port != None: + try: + retVal = port._get_softwareProfile() + except Exception: + self.parent._log.exception("The call to _get_softwareProfile failed on port %s connection %s instance %s", self.name, connId, port) + raise + finally: + self.port_lock.release() + + return retVal + + +if __name__ == '__main__': + start_service(svc_startorder, thread_policy=PortableServer.SINGLE_THREAD_MODEL) diff --git a/redhawk/src/testing/sdr/dev/services/svc_startorder/svc_startorder.scd.xml b/redhawk/src/testing/sdr/dev/services/svc_startorder/svc_startorder.scd.xml new file mode 100644 index 000000000..5c9b84efe --- /dev/null +++ b/redhawk/src/testing/sdr/dev/services/svc_startorder/svc_startorder.scd.xml @@ -0,0 +1,47 @@ + + + + 2.2 + + service + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/redhawk/src/testing/sdr/dev/services/svc_startorder/svc_startorder.spd.xml b/redhawk/src/testing/sdr/dev/services/svc_startorder/svc_startorder.spd.xml new file mode 100644 index 000000000..d5de930b3 --- /dev/null +++ b/redhawk/src/testing/sdr/dev/services/svc_startorder/svc_startorder.spd.xml @@ -0,0 +1,22 @@ + + + + + + null + + + + + + The implementation contains descriptive information about the template for a software resource. + + + python/svc_startorder.py + + + + + + + diff --git a/redhawk/src/testing/tests/test_03_DeviceLifeCycle.py b/redhawk/src/testing/tests/test_03_DeviceLifeCycle.py index 229d9b292..00edcbf5b 100644 --- a/redhawk/src/testing/tests/test_03_DeviceLifeCycle.py +++ b/redhawk/src/testing/tests/test_03_DeviceLifeCycle.py @@ -21,6 +21,9 @@ import unittest, os from _unitTestHelpers import scatest from test_01_DeviceManager import killChildProcesses +from ossie.utils import redhawk +from ossie.cf import CF +from omniORB import any as _any import time class DeviceLifeCycleTest(scatest.CorbaTestCase): @@ -46,7 +49,75 @@ def test_DeviceLifeCycle(self): def test_DeviceLifeCycleNoKill(self): pass - + +class DeviceStartorder(scatest.CorbaTestCase): + def setUp(self): + domBooter, domMgr = self.launchDomainManager() + devBooter, devMgr = self.launchDeviceManager("/nodes/devmgr_startorder/DeviceManager.dcd.xml", loggingURI='file://'+os.getcwd()+'/devmgr_config.cfg') + + def test_DeviceStarted(self): + rhdom = redhawk.attach(scatest.getTestDomainName()) + startfrom = {} + q=CF.DataType(id='start_from',value=_any.to_any(None)) + for dev in rhdom.devMgrs[0].devs: + startfrom[dev._id] = dev.query([q])[0].value._v + for svc in rhdom.devMgrs[0].services: + startfrom[svc._id] = svc.query([q])[0].value._v + self.assertEquals(startfrom['devmgr_startorder:dev_startorder_1'], ',devmgr_startorder:dev_startorder_2,svc_startorder_1') + self.assertEquals(startfrom['devmgr_startorder:dev_startorder_2'], ',devmgr_startorder:dev_startorder_2,svc_startorder_1,devmgr_startorder:dev_startorder_1') + self.assertEquals(startfrom['devmgr_startorder:dev_startorder_3'], '') + self.assertEquals(startfrom['devmgr_startorder:svc_startorder_1'], ',devmgr_startorder:dev_startorder_2') + + rhdom.devMgrs[0].shutdown() + + fp = None + try: + fp = open('sdr/cache/.devmgr_startorder/foo/bar/test.log','r') + except: + pass + if fp != None: + log_contents = fp.read() + fp.close() + try: + os.remove('foo/bar/test.log') + except: + pass + try: + os.rmdir('foo/bar') + except: + pass + try: + os.rmdir('foo') + except: + pass + try: + os.remove('sdr/cache/.devmgr_startorder/foo/bar/test.log') + except: + pass + try: + os.rmdir('sdr/cache/.devmgr_startorder/foo/bar') + except: + pass + try: + os.rmdir('sdr/cache/.devmgr_startorder/foo') + except: + pass + start_dev_1 = log_contents.find('starting devmgr_startorder:dev_startorder_1') + start_dev_2 = log_contents.find('starting devmgr_startorder:dev_startorder_2') + start_dev_3 = log_contents.find('starting devmgr_startorder:dev_startorder_3') + start_svc = log_contents.find('starting svc_startorder_1') + stop_dev_1 = log_contents.find('stopping devmgr_startorder:dev_startorder_1') + stop_dev_2 = log_contents.find('stopping devmgr_startorder:dev_startorder_2') + stop_dev_3 = log_contents.find('stopping devmgr_startorder:dev_startorder_3') + stop_svc = log_contents.find('stopping svc_startorder_1') + + self.assertTrue(start_dev_2 + id ID #REQUIRED + startorder CDATA #IMPLIED> diff --git a/redhawk/src/xml/xsd/dcd.xsd b/redhawk/src/xml/xsd/dcd.xsd index 94d6ede83..63dd13f0d 100644 --- a/redhawk/src/xml/xsd/dcd.xsd +++ b/redhawk/src/xml/xsd/dcd.xsd @@ -199,6 +199,7 @@ usagename element needs to be unique for each service type. The componentinstantiation‘s id attribute is a DCE UUID that uniquely identifier the component. + From b88b4ca7c0bdd895a3e38390b4d5aa8ca852b503 Mon Sep 17 00:00:00 2001 From: Max Robert Date: Thu, 31 Aug 2017 14:06:46 -0400 Subject: [PATCH 0876/1644] Refs CF-1815. Added missing files --- .../long_stop_builtin_def.sad.xml | 51 +++++++++++++++++++ .../waveforms/slow_stop_w/slow_stop_w.sad.xml | 45 ++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 redhawk/src/testing/sdr/dom/waveforms/long_stop_builtin_def/long_stop_builtin_def.sad.xml create mode 100644 redhawk/src/testing/sdr/dom/waveforms/slow_stop_w/slow_stop_w.sad.xml diff --git a/redhawk/src/testing/sdr/dom/waveforms/long_stop_builtin_def/long_stop_builtin_def.sad.xml b/redhawk/src/testing/sdr/dom/waveforms/long_stop_builtin_def/long_stop_builtin_def.sad.xml new file mode 100644 index 000000000..16f4be7a6 --- /dev/null +++ b/redhawk/src/testing/sdr/dom/waveforms/long_stop_builtin_def/long_stop_builtin_def.sad.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + hanging_stop_1 + + + + + + + + + hanging_stop_2 + + + + + + + + + + diff --git a/redhawk/src/testing/sdr/dom/waveforms/slow_stop_w/slow_stop_w.sad.xml b/redhawk/src/testing/sdr/dom/waveforms/slow_stop_w/slow_stop_w.sad.xml new file mode 100644 index 000000000..173c31cc5 --- /dev/null +++ b/redhawk/src/testing/sdr/dom/waveforms/slow_stop_w/slow_stop_w.sad.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + slow_stop_1 + + + + + + + + + + + + From 5bb815aa009287ee9c6df57301254ef28859c4a5 Mon Sep 17 00:00:00 2001 From: 8530 <8530@vm-131.vsi-corp.com> Date: Thu, 10 Aug 2017 18:26:50 -0400 Subject: [PATCH 0877/1644] initial release of init scripts for redhawk services, CF-1808, CF-1809, CF-1810 --- redhawk/src/etc/Makefile.am | 66 +- redhawk/src/etc/redhawk/cron.d/redhawk | 16 + .../src/etc/redhawk/domains.d/example.domains | 44 + .../etc/redhawk/init.d/conditional_overrides | 70 + .../src/etc/redhawk/init.d/domain.defaults | 43 + redhawk/src/etc/redhawk/init.d/functions | 1388 +++++++++++++++++ redhawk/src/etc/redhawk/init.d/node.defaults | 45 + redhawk/src/etc/redhawk/init.d/omni-clean | 54 + .../init.d/redhawk-device-mgr@.service | 20 + .../etc/redhawk/init.d/redhawk-device-mgrs | 286 ++++ .../init.d/redhawk-device-mgrs.service | 17 + .../init.d/redhawk-domain-mgr@.service | 16 + .../etc/redhawk/init.d/redhawk-domain-mgrs | 290 ++++ .../init.d/redhawk-domain-mgrs.service | 16 + .../etc/redhawk/init.d/redhawk-service-config | 8 + .../etc/redhawk/init.d/redhawk-service-list | 8 + .../etc/redhawk/init.d/redhawk-service-start | 8 + .../etc/redhawk/init.d/redhawk-service-status | 10 + .../etc/redhawk/init.d/redhawk-service-stop | 31 + .../src/etc/redhawk/init.d/redhawk-waveform | 157 ++ .../redhawk/init.d/redhawk-waveform@.service | 18 + .../src/etc/redhawk/init.d/redhawk-waveforms | 339 ++++ .../redhawk/init.d/redhawk-waveforms.service | 18 + .../src/etc/redhawk/init.d/redhawk-wf-control | 627 ++++++++ redhawk/src/etc/redhawk/init.d/rundir | 7 + redhawk/src/etc/redhawk/init.d/set-env | 9 + redhawk/src/etc/redhawk/init.d/svc-functions | 1141 ++++++++++++++ .../src/etc/redhawk/init.d/waveform.defaults | 37 + .../logging/default.logging.properties | 67 + .../logging/example.logging.properties | 73 + .../src/etc/redhawk/logging/logrotate.redhawk | 9 + redhawk/src/etc/redhawk/nodes.d/example.nodes | 44 + redhawk/src/etc/redhawk/redhawk-release | 1 + redhawk/src/etc/redhawk/rh.cond.cfg | 7 + .../security/limits.d/99-redhawk-limits.conf | 38 + redhawk/src/etc/redhawk/sysctl.d/sysctl.conf | 39 + .../etc/redhawk/waveforms.d/example.waveforms | 40 + redhawk/src/releng/redhawk-services.spec | 233 +++ redhawk/src/releng/redhawk.spec | 177 ++- 39 files changed, 5514 insertions(+), 3 deletions(-) create mode 100644 redhawk/src/etc/redhawk/cron.d/redhawk create mode 100644 redhawk/src/etc/redhawk/domains.d/example.domains create mode 100644 redhawk/src/etc/redhawk/init.d/conditional_overrides create mode 100644 redhawk/src/etc/redhawk/init.d/domain.defaults create mode 100644 redhawk/src/etc/redhawk/init.d/functions create mode 100644 redhawk/src/etc/redhawk/init.d/node.defaults create mode 100755 redhawk/src/etc/redhawk/init.d/omni-clean create mode 100755 redhawk/src/etc/redhawk/init.d/redhawk-device-mgr@.service create mode 100755 redhawk/src/etc/redhawk/init.d/redhawk-device-mgrs create mode 100755 redhawk/src/etc/redhawk/init.d/redhawk-device-mgrs.service create mode 100755 redhawk/src/etc/redhawk/init.d/redhawk-domain-mgr@.service create mode 100755 redhawk/src/etc/redhawk/init.d/redhawk-domain-mgrs create mode 100755 redhawk/src/etc/redhawk/init.d/redhawk-domain-mgrs.service create mode 100755 redhawk/src/etc/redhawk/init.d/redhawk-service-config create mode 100755 redhawk/src/etc/redhawk/init.d/redhawk-service-list create mode 100755 redhawk/src/etc/redhawk/init.d/redhawk-service-start create mode 100755 redhawk/src/etc/redhawk/init.d/redhawk-service-status create mode 100755 redhawk/src/etc/redhawk/init.d/redhawk-service-stop create mode 100755 redhawk/src/etc/redhawk/init.d/redhawk-waveform create mode 100755 redhawk/src/etc/redhawk/init.d/redhawk-waveform@.service create mode 100755 redhawk/src/etc/redhawk/init.d/redhawk-waveforms create mode 100755 redhawk/src/etc/redhawk/init.d/redhawk-waveforms.service create mode 100755 redhawk/src/etc/redhawk/init.d/redhawk-wf-control create mode 100755 redhawk/src/etc/redhawk/init.d/rundir create mode 100755 redhawk/src/etc/redhawk/init.d/set-env create mode 100644 redhawk/src/etc/redhawk/init.d/svc-functions create mode 100644 redhawk/src/etc/redhawk/init.d/waveform.defaults create mode 100755 redhawk/src/etc/redhawk/logging/default.logging.properties create mode 100755 redhawk/src/etc/redhawk/logging/example.logging.properties create mode 100755 redhawk/src/etc/redhawk/logging/logrotate.redhawk create mode 100644 redhawk/src/etc/redhawk/nodes.d/example.nodes create mode 100644 redhawk/src/etc/redhawk/redhawk-release create mode 100644 redhawk/src/etc/redhawk/rh.cond.cfg create mode 100644 redhawk/src/etc/redhawk/security/limits.d/99-redhawk-limits.conf create mode 100644 redhawk/src/etc/redhawk/sysctl.d/sysctl.conf create mode 100644 redhawk/src/etc/redhawk/waveforms.d/example.waveforms create mode 100644 redhawk/src/releng/redhawk-services.spec diff --git a/redhawk/src/etc/Makefile.am b/redhawk/src/etc/Makefile.am index ba2deb89c..bb9fb879e 100644 --- a/redhawk/src/etc/Makefile.am +++ b/redhawk/src/etc/Makefile.am @@ -33,6 +33,70 @@ profiled_DATA = profile.d/redhawk.sh \ profile.d/redhawk-sdrroot.sh \ profile.d/redhawk-sdrroot.csh +rh_etc_dir = $(sysconfdir)/redhawk +cron_dir = $(rh_etc_dir)/cron.d +domains_dir = $(rh_etc_dir)/domains.d +init_dir = $(rh_etc_dir)/init.d +logging_dir = $(rh_etc_dir)/logging +nodes_dir = $(rh_etc_dir)/nodes.d +limits_dir = $(rh_etc_dir)/security/limits.d +sysctl_dir = $(rh_etc_dir)/sysctl.d +waveforms_dir = $(rh_etc_dir)/waveforms.d + +rh_etc__DATA = \ +redhawk/redhawk-release \ +redhawk/rh.cond.cfg + +cron__DATA = \ +redhawk/cron.d/redhawk + +domains__DATA = \ +redhawk/domains.d/example.domains + +init__DATA = \ +redhawk/init.d/conditional_overrides \ +redhawk/init.d/redhawk-device-mgr@.service \ +redhawk/init.d/domain.defaults \ +redhawk/init.d/functions \ +redhawk/init.d/node.defaults \ +redhawk/init.d/omni-clean \ +redhawk/init.d/redhawk-device-mgrs.service \ +redhawk/init.d/redhawk-device-mgrs \ +redhawk/init.d/set-env \ +redhawk/init.d/redhawk-domain-mgr@.service \ +redhawk/init.d/redhawk-domain-mgrs \ +redhawk/init.d/redhawk-domain-mgrs.service \ +redhawk/init.d/redhawk-service-config \ +redhawk/init.d/redhawk-service-list \ +redhawk/init.d/redhawk-service-start \ +redhawk/init.d/redhawk-service-status \ +redhawk/init.d/redhawk-service-stop \ +redhawk/init.d/redhawk-waveform \ +redhawk/init.d/redhawk-waveform@.service \ +redhawk/init.d/redhawk-waveforms \ +redhawk/init.d/redhawk-waveforms.service \ +redhawk/init.d/redhawk-wf-control \ +redhawk/init.d/rundir \ +redhawk/init.d/svc-functions \ +redhawk/init.d/waveform.defaults + +logging__DATA = \ +redhawk/logging/default.logging.properties \ +redhawk/logging/example.logging.properties \ +redhawk/logging/logrotate.redhawk + +nodes__DATA = \ +redhawk/nodes.d/example.nodes + +limits__DATA = \ +redhawk/security/limits.d/99-redhawk-limits.conf + +sysctl__DATA = \ +redhawk/sysctl.d/sysctl.conf + +waveforms__DATA = \ +redhawk/waveforms.d/example.waveforms + lib = lib${gr_libdir_suffix} edit = $(SED) \ -e 's|@prefix[@]|$(prefix)|g' \ @@ -50,5 +114,5 @@ profile.d/redhawk.csh: profile.d/redhawk.csh.in profile.d/redhawk-sdrroot.sh: profile.d/redhawk-sdrroot.sh.in profile.d/redhawk-sdrroot.csh: profile.d/redhawk-sdrroot.csh.in -DISTCLEANFILES = $(ldsoconfd_DATA) $(profiled_DATA) +DISTCLEANFILES = $(ldsoconfd_DATA) $(profiled_DATA) $(rh_etc__DATA) $(cron__DATA) $(domains__DATA) $(init__DATA) $(logging__DATA) $(nodes__DATA) $(limits__DATA) $(sysctl__DATA) $(waveforms__DATA) diff --git a/redhawk/src/etc/redhawk/cron.d/redhawk b/redhawk/src/etc/redhawk/cron.d/redhawk new file mode 100644 index 000000000..e7467f45d --- /dev/null +++ b/redhawk/src/etc/redhawk/cron.d/redhawk @@ -0,0 +1,16 @@ +# Example of job definition: +# .---------------- minute (0 - 59) +# | .------------- hour (0 - 23) +# | | .---------- day of month (1 - 31) +# | | | .------- month (1 - 12) OR jan,feb,mar,apr ... +# | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat +# | | | | | +# * * * * * user-name command to be executed +# +# clean up possible stale unix pipes +# */15 * * * * root /usr/sbin/tmpwatch -uaf 36 /tmp/omni-* +# +# Run logrotate +MAILTO=root +# +*/5 * * * * root /usr/sbin/logrotate /etc/redhawk/logging/logrotate.redhawk diff --git a/redhawk/src/etc/redhawk/domains.d/example.domains b/redhawk/src/etc/redhawk/domains.d/example.domains new file mode 100644 index 000000000..8b79941f5 --- /dev/null +++ b/redhawk/src/etc/redhawk/domains.d/example.domains @@ -0,0 +1,44 @@ +#[domain name] +#DOMAIN_NAME= [NO DEFAULT] # required name of your domain +#DMD_PATH= # [$SDRROOT/dom/domain/DomainManager.dmd.xml] or path to DMD file +#BINDAPPS = [0] # optional Application binding: 0 - Bind to NamingService , 1 - Bind using Domain +#FORCE_REBIND = [0] # optional 1 - force rebind Domain in NamingService, 0 - do not rebind +#PERSISTENCE: [db url] # optional enables persistance with path to persistance database +#USE_LOGCFG: [0] # optional enable use of libossielog.so to resolve LOGGING_CONFIG_URI + +#LOGCFG= [default defaults.logging.properties ] # optional file name in /etc/redhawk/logging or path to log configuration file +#DEBUG_LEVEL= [3] # optional 5=TRACE,4=DEBUG,3=INFO,2=WARN,1=ERROR,0=FATAL numbers or name + +#SDRROOT= [$SDRROOT] # optional if blank uses $SDRROOT, fallback /var/redhawk/sdr +#OSSIEHOME= [$OSSIEHOME] # optional if blank uses $OMNIHOME, fallback /usr/local/redhawk +#LD_LIBRARY_PATH: # optional setup LD_LIBRARY_PATH before execution +#PYTHONPATH: # optional setup PYTHON_PATH before execution +#ORB_CFG: # optional path to omniORB configuration file +#ORB_ENDPOINT: # optional Sets the endpoint for the DomainManager servant +#ORB_INITREF: # optional pass to ORBInitRef N=V + +#ENABLED= [1] # optional - 0/1 enable or disable this entry +#COND_CFG= # optional configuration file passed to customizeable override enable method. default to /etc/redhawk/rh.cond.cfg + +#USER= [redhawk] # optional - runas user +#GROUP= [redhawk] # optional - runas group + +#NICELEVEL: # optional - cmd line args to pass to nice when running process +#AFFINITY: # optional - cmd line args to pass to numaclt when running process +#ULIMIT: # optional - cmd line args to pass to ulimit before running process +#CORE_FILES: # optional - 1 enable core files, 0 use ulimit settings + +#PERMISSIONS_START_ONLY=[1] # optional - control if start_pre_script is run as root or run userb +#ENVIRONMENT: # optional - Additional environment variables VAR=VALUE VAR=VALUE +#RUN_DIR: # optional - change directory before running scripts and service +#OUTPUT_REDIRECT: # optional - stderr stdout +#OUTPUT: # optional - [dommgr.domain_name.log] path to file that will capture output redirect +#OUTPUT_PREFIX: # optional - [dommgr] prefix for output redirect +#START_PRE_SCRIPT: # optional - script run before process [source]